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
@@ -8,6 +8,7 @@ import { describe, it, expect } from "vitest";
8
8
  import {
9
9
  percentile,
10
10
  summarize,
11
+ sampleRssDefault,
11
12
  sumSubtreeRss,
12
13
  sumSubtreeRssFromWmicCsv,
13
14
  } from "../benchmark.js";
@@ -86,3 +87,63 @@ describe("sumSubtreeRssFromWmicCsv", () => {
86
87
  expect(sumSubtreeRssFromWmicCsv("garbage\r\n", 100)).toBeNull();
87
88
  });
88
89
  });
90
+
91
+ describe("sampleRssDefault", () => {
92
+ it("routes the POSIX process snapshot through the Broker contract", async () => {
93
+ const calls = [];
94
+ const execFileSync = (...args) => {
95
+ calls.push(args);
96
+ return "100 1 1024\n200 100 512\n400 1 9999\n";
97
+ };
98
+
99
+ await expect(
100
+ sampleRssDefault(100, { execFileSync, platform: "linux" }),
101
+ ).resolves.toBe(2);
102
+ expect(calls).toEqual([
103
+ [
104
+ "ps",
105
+ ["-o", "pid=,ppid=,rss="],
106
+ expect.objectContaining({
107
+ origin: "lsp:benchmark-rss",
108
+ policy: "allow",
109
+ scope: "lsp",
110
+ shell: false,
111
+ }),
112
+ ],
113
+ ]);
114
+ });
115
+
116
+ it("routes the Windows process snapshot through literal argv", async () => {
117
+ const calls = [];
118
+ const execFileSync = (...args) => {
119
+ calls.push(args);
120
+ return [
121
+ "Node,ParentProcessId,ProcessId,WorkingSetSize",
122
+ "HOST,1,100,1048576",
123
+ "HOST,100,200,1048576",
124
+ ].join("\r\n");
125
+ };
126
+
127
+ await expect(
128
+ sampleRssDefault(100, { execFileSync, platform: "win32" }),
129
+ ).resolves.toBe(2);
130
+ expect(calls).toEqual([
131
+ [
132
+ "wmic",
133
+ [
134
+ "process",
135
+ "get",
136
+ "ProcessId,ParentProcessId,WorkingSetSize",
137
+ "/format:csv",
138
+ ],
139
+ expect.objectContaining({
140
+ origin: "lsp:benchmark-rss",
141
+ policy: "allow",
142
+ scope: "lsp",
143
+ shell: false,
144
+ windowsHide: true,
145
+ }),
146
+ ],
147
+ ]);
148
+ });
149
+ });
@@ -87,7 +87,12 @@ describe("LSPClient handshake", () => {
87
87
  expect(_deps.spawn).toHaveBeenCalledWith(
88
88
  "fake-lsp",
89
89
  ["--stdio"],
90
- expect.objectContaining({ shell: false }),
90
+ expect.objectContaining({
91
+ origin: "lsp:server",
92
+ policy: "allow",
93
+ scope: "lsp",
94
+ shell: false,
95
+ }),
91
96
  );
92
97
  });
93
98
 
@@ -12,11 +12,13 @@
12
12
  */
13
13
 
14
14
  import { CodeIntelligence } from "./code-intelligence.js";
15
+ import executionBroker from "../process-execution-broker/index.js";
15
16
 
16
17
  /** now() in fractional milliseconds — injectable for deterministic tests. */
17
18
  export const _deps = {
18
19
  now: () => Number(process.hrtime.bigint() / 1000n) / 1000,
19
20
  sampleRss: sampleRssDefault,
21
+ execFileSync: (...args) => executionBroker.execFileSync(...args),
20
22
  };
21
23
 
22
24
  /** p-th percentile (0..100) of an UNSORTED sample via linear interpolation. */
@@ -167,10 +169,12 @@ async function captureServerInfo(ci) {
167
169
  * lies. We sum the whole subtree. Returns null if it can't be read (never throws
168
170
  * — memory is a bonus metric, not load-bearing).
169
171
  */
170
- async function sampleRssDefault(pid) {
171
- const { execFileSync } = await import("child_process");
172
+ export async function sampleRssDefault(
173
+ pid,
174
+ { execFileSync = _deps.execFileSync, platform = process.platform } = {},
175
+ ) {
172
176
  try {
173
- if (process.platform === "win32") {
177
+ if (platform === "win32") {
174
178
  // One snapshot of every process → parent map → sum the subtree at `pid`.
175
179
  const csv = execFileSync(
176
180
  "wmic",
@@ -180,7 +184,15 @@ async function sampleRssDefault(pid) {
180
184
  "ProcessId,ParentProcessId,WorkingSetSize",
181
185
  "/format:csv",
182
186
  ],
183
- { encoding: "utf8", windowsHide: true, maxBuffer: 16 * 1024 * 1024 },
187
+ {
188
+ encoding: "utf8",
189
+ windowsHide: true,
190
+ maxBuffer: 16 * 1024 * 1024,
191
+ origin: "lsp:benchmark-rss",
192
+ policy: "allow",
193
+ scope: "lsp",
194
+ shell: false,
195
+ },
184
196
  );
185
197
  const bytes = sumSubtreeRssFromWmicCsv(csv, pid);
186
198
  return bytes != null ? Math.round(bytes / (1024 * 1024)) : null;
@@ -188,6 +200,10 @@ async function sampleRssDefault(pid) {
188
200
  // POSIX: not wrapped, so the pid is the real server. Sum pid + children.
189
201
  const out = execFileSync("ps", ["-o", "pid=,ppid=,rss="], {
190
202
  encoding: "utf8",
203
+ origin: "lsp:benchmark-rss",
204
+ policy: "allow",
205
+ scope: "lsp",
206
+ shell: false,
191
207
  });
192
208
  const rows = out
193
209
  .trim()
@@ -13,7 +13,6 @@
13
13
  * does not intercept this file). Nothing here is language-specific.
14
14
  */
15
15
 
16
- import { spawn as nodeSpawn } from "child_process";
17
16
  import { EventEmitter } from "events";
18
17
  import { encodeMessage, MessageBuffer } from "./jsonrpc-stream.js";
19
18
  import { executionBroker } from "../process-execution-broker/index.js";
@@ -22,7 +21,9 @@ const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
22
21
  const DEFAULT_INIT_TIMEOUT_MS = 30_000;
23
22
 
24
23
  // Injectable so unit tests can supply a fake child process.
25
- export const _deps = { spawn: nodeSpawn };
24
+ export const _deps = {
25
+ spawn: (...args) => executionBroker.spawn(...args),
26
+ };
26
27
 
27
28
  export class LSPClient extends EventEmitter {
28
29
  /**
@@ -88,10 +89,11 @@ export class LSPClient extends EventEmitter {
88
89
  shell: false,
89
90
  windowsHide: true,
90
91
  windowsVerbatimArguments: spawnSpec.windowsVerbatimArguments,
92
+ origin: this.origin || "lsp:server",
93
+ policy: "allow",
94
+ scope: "lsp",
91
95
  ...(this.origin
92
96
  ? {
93
- origin: this.origin,
94
- policy: "allow",
95
97
  pluginId: this.pluginId,
96
98
  pluginVersion: this.pluginVersion,
97
99
  pluginSource: this.pluginSource,
@@ -14,11 +14,9 @@
14
14
 
15
15
  import fs from "fs";
16
16
  import path from "path";
17
- import { execFileSync } from "child_process";
18
17
 
19
18
  export const _deps = {
20
19
  existsSync: fs.existsSync,
21
- execFileSync,
22
20
  };
23
21
 
24
22
  // Extension → LSP languageId. Kept small and explicit; unknown extensions get
@@ -244,10 +244,11 @@ export function resolveOperationApproval(pending, resolution, opts = {}) {
244
244
  * fs/RNG — so it is fully unit-testable and serializable alongside a session.
245
245
  */
246
246
  export class OperationApprovalRegistry {
247
- constructor({ clock } = {}) {
247
+ constructor({ clock, store = null } = {}) {
248
248
  this._byFingerprint = new Map(); // fingerprint -> pending record
249
249
  this._activeByLogicalKey = new Map(); // logical key -> active fingerprint
250
250
  this._clock = typeof clock === "function" ? clock : null;
251
+ this._store = store;
251
252
  }
252
253
 
253
254
  _now() {
@@ -260,10 +261,40 @@ export class OperationApprovalRegistry {
260
261
  * can resolve.
261
262
  * @returns {{fingerprint:string, shortId:string, summary:string}}
262
263
  */
263
- issue(desc = {}) {
264
+ issue(desc = {}, opts = {}) {
264
265
  const fingerprint = computeOperationFingerprint(desc);
265
266
  const logicalKey = operationDescriptorKey(desc);
266
267
 
268
+ if (this._store) {
269
+ const card = this._store.issueRequest({
270
+ requestId: opts.requestId,
271
+ descriptor: desc,
272
+ binding: opts.binding,
273
+ now: opts.now !== undefined ? opts.now : this._now(),
274
+ });
275
+ this._byFingerprint.set(card.fingerprint, {
276
+ fingerprint: card.fingerprint,
277
+ logicalKey,
278
+ requestId: card.requestId,
279
+ binding: opts.binding,
280
+ sessionId: desc.session ?? null,
281
+ revision: card.revision,
282
+ status: card.status,
283
+ });
284
+ this._activeByLogicalKey.set(logicalKey, card.fingerprint);
285
+ return card;
286
+ }
287
+
288
+ // Reissuing the exact same card must never reset a resolved record.
289
+ const exact = this._byFingerprint.get(fingerprint);
290
+ if (exact) {
291
+ return {
292
+ fingerprint,
293
+ shortId: shortOperationId(fingerprint),
294
+ summary: summarizeOperation(desc),
295
+ };
296
+ }
297
+
267
298
  const priorFp = this._activeByLogicalKey.get(logicalKey);
268
299
  if (priorFp && priorFp !== fingerprint) {
269
300
  const prior = this._byFingerprint.get(priorFp);
@@ -296,6 +327,37 @@ export class OperationApprovalRegistry {
296
327
  * @returns {{ok:boolean, reason:(string|null)}}
297
328
  */
298
329
  resolve(fingerprint, opts = {}) {
330
+ if (this._store) {
331
+ const cached = this._byFingerprint.get(fingerprint);
332
+ const requestId = opts.requestId ?? cached?.requestId;
333
+ if (!requestId) {
334
+ return { ok: false, approved: false, reason: "unknown" };
335
+ }
336
+ try {
337
+ const verdict = this._store.resolveRequest(requestId, {
338
+ fingerprint: opts.fingerprint,
339
+ binding: opts.binding,
340
+ sessionId: opts.sessionId,
341
+ decision: opts.decision,
342
+ authority: opts.authority,
343
+ expectedRevision: opts.expectedRevision,
344
+ now: opts.now !== undefined ? opts.now : this._now(),
345
+ });
346
+ if (verdict.ok && cached) {
347
+ cached.status = verdict.approved ? "resolved" : "rejected";
348
+ cached.revision = verdict.revision;
349
+ }
350
+ return verdict;
351
+ } catch (error) {
352
+ return {
353
+ ok: false,
354
+ approved: false,
355
+ reason: "state-unavailable",
356
+ errorCode: error?.code || "CC_APPROVAL_STATE_UNKNOWN",
357
+ };
358
+ }
359
+ }
360
+
299
361
  const pending = this._byFingerprint.get(fingerprint);
300
362
  if (!pending) return { ok: false, reason: "unknown" };
301
363
  const now = opts.now !== undefined ? intOrNull(opts.now) : this._now();
@@ -304,9 +366,52 @@ export class OperationApprovalRegistry {
304
366
  return verdict;
305
367
  }
306
368
 
369
+ /**
370
+ * Persist a timeout/close transition. It can only reduce authority.
371
+ */
372
+ cancel(fingerprint, opts = {}) {
373
+ if (this._store) {
374
+ const cached = this._byFingerprint.get(fingerprint);
375
+ const requestId = opts.requestId ?? cached?.requestId;
376
+ if (!requestId) {
377
+ return { ok: false, approved: false, reason: "unknown" };
378
+ }
379
+ try {
380
+ const verdict = this._store.cancelRequest(requestId, {
381
+ expectedRevision: opts.expectedRevision ?? cached?.revision,
382
+ reason: opts.reason,
383
+ now: opts.now !== undefined ? opts.now : this._now(),
384
+ });
385
+ if (verdict.ok && cached) {
386
+ cached.status =
387
+ verdict.reason === "expired" ? "expired" : "cancelled";
388
+ cached.revision = verdict.revision;
389
+ }
390
+ return verdict;
391
+ } catch (error) {
392
+ return {
393
+ ok: false,
394
+ approved: false,
395
+ reason: "state-unavailable",
396
+ errorCode: error?.code || "CC_APPROVAL_STATE_UNKNOWN",
397
+ };
398
+ }
399
+ }
400
+
401
+ const pending = this._byFingerprint.get(fingerprint);
402
+ if (!pending) return { ok: false, reason: "unknown" };
403
+ if (pending.resolved) return { ok: false, reason: "duplicate" };
404
+ pending.resolved = true;
405
+ return { ok: true, approved: false, reason: opts.reason || "cancelled" };
406
+ }
407
+
307
408
  /** A read-only view of a pending card (or null). */
308
409
  get(fingerprint) {
309
410
  const p = this._byFingerprint.get(fingerprint);
411
+ if (this._store && p?.requestId) {
412
+ const durable = this._store.getRequest(p.requestId);
413
+ return durable ? { ...durable } : null;
414
+ }
310
415
  return p ? { ...p } : null;
311
416
  }
312
417
  }
@@ -22,15 +22,17 @@
22
22
  */
23
23
 
24
24
  import { EventEmitter } from "events";
25
- import { execSync } from "child_process";
26
25
  import crypto from "crypto";
27
26
  import { AgentRouter } from "./agent-router.js";
28
27
  import { NotificationManager } from "./notifiers/index.js";
29
28
  import { createChatFn } from "./cowork-adapter.js";
30
29
  import { firstBalancedJson } from "./json-schema-output.js";
30
+ import executionBroker from "./process-execution-broker/index.js";
31
31
 
32
32
  /* ---------- _deps injection (Vitest CJS mock pattern) ---------- */
33
- export const _deps = { execSync };
33
+ export const _deps = {
34
+ execSync: (...args) => executionBroker.execSync(...args),
35
+ };
34
36
 
35
37
  // ─── Task statuses ────────────────────────────────────────────────
36
38
  export const TASK_STATUS = {
@@ -389,6 +391,10 @@ export class Orchestrator extends EventEmitter {
389
391
  // re-dispatch). Give CI output generous headroom.
390
392
  maxBuffer: 64 * 1024 * 1024,
391
393
  stdio: "pipe",
394
+ origin: "orchestrator:ci",
395
+ policy: "allow",
396
+ scope: "orchestrator",
397
+ shell: true,
392
398
  });
393
399
  return {
394
400
  pass: true,
@@ -27,7 +27,11 @@
27
27
  import fs from "node:fs";
28
28
  import os from "node:os";
29
29
  import path from "node:path";
30
- import { spawn } from "node:child_process";
30
+ import executionBroker from "../process-execution-broker/index.js";
31
+
32
+ export const _deps = {
33
+ spawn: (...args) => executionBroker.spawn(...args),
34
+ };
31
35
 
32
36
  /**
33
37
  * @param {object} ctx
@@ -55,7 +59,7 @@ export async function scheduleReplace(ctx) {
55
59
  dryRun = false,
56
60
  platform = process.platform === "win32" ? "win32" : "posix",
57
61
  parentPid = process.pid,
58
- spawnImpl = spawn,
62
+ spawnImpl = _deps.spawn,
59
63
  } = ctx;
60
64
 
61
65
  if (!newExePath || typeof newExePath !== "string") {
@@ -92,6 +96,10 @@ export async function scheduleReplace(ctx) {
92
96
  // Detach so the sidecar survives our process exit. `windowsHide: true`
93
97
  // keeps the cmd window from flashing — the replace itself is silent.
94
98
  const child = spawnImpl("cmd.exe", ["/c", sidecarPath], {
99
+ origin: "packer:update-sidecar",
100
+ scope: "pack-update",
101
+ policy: "allow",
102
+ shell: false,
95
103
  detached: true,
96
104
  stdio: "ignore",
97
105
  windowsHide: true,
@@ -123,6 +131,10 @@ export async function scheduleReplace(ctx) {
123
131
 
124
132
  if (restart) {
125
133
  const child = spawnImpl(targetExePath, process.argv.slice(2), {
134
+ origin: "packer:update-restart",
135
+ scope: "pack-update",
136
+ policy: "allow",
137
+ shell: false,
126
138
  detached: true,
127
139
  stdio: "ignore",
128
140
  });
@@ -19,11 +19,15 @@
19
19
  * Called from `runPack()` as Phase 8 when `cliOpts.smokeTest !== false`.
20
20
  */
21
21
 
22
- import { spawn } from "node:child_process";
23
22
  import { createConnection } from "node:net";
24
23
  import http from "node:http";
25
24
  import path from "node:path";
26
25
  import { PackError, EXIT } from "./errors.js";
26
+ import executionBroker from "../process-execution-broker/index.js";
27
+
28
+ export const _deps = {
29
+ spawn: (...args) => executionBroker.spawn(...args),
30
+ };
27
31
 
28
32
  const DEFAULT_BOOT_TIMEOUT_MS = 45_000;
29
33
  const DEFAULT_PROBE_TIMEOUT_MS = 5_000;
@@ -80,7 +84,10 @@ export async function smokeTestExe(ctx) {
80
84
  // artifacts are always .exe so this only kicks in during tests that use
81
85
  // a shim — kept here so the smoke-runner is self-testable.
82
86
  const needsShell = /\.(cmd|bat|sh)$/i.test(exePath);
83
- const child = spawn(exePath, ["ui", "--no-open"], {
87
+ const child = _deps.spawn(exePath, ["ui", "--no-open"], {
88
+ origin: "packer:smoke-launch",
89
+ scope: "pack",
90
+ policy: "allow",
84
91
  env,
85
92
  stdio: ["ignore", "pipe", "pipe"],
86
93
  windowsHide: true,
@@ -116,9 +123,15 @@ export async function smokeTestExe(ctx) {
116
123
  // unrelated process tree that inherited the number (on CI: another
117
124
  // vitest worker or a test's helper child).
118
125
  if (child.exitCode !== null || child.signalCode !== null) return;
119
- spawn("taskkill", ["/F", "/T", "/PID", String(child.pid)], {
120
- stdio: "ignore",
121
- }).unref();
126
+ _deps
127
+ .spawn("taskkill", ["/F", "/T", "/PID", String(child.pid)], {
128
+ origin: "packer:smoke-taskkill",
129
+ scope: "pack",
130
+ policy: "allow",
131
+ shell: false,
132
+ stdio: "ignore",
133
+ })
134
+ .unref();
122
135
  } else if (child.pid) {
123
136
  // Negative pid → the whole process group from the detached spawn above,
124
137
  // so a shell:true wrapper's exec'd/forked `node` grandchild dies too
package/src/lib/paths.js CHANGED
@@ -5,7 +5,7 @@ import { CONFIG_DIR_NAME } from "../constants.js";
5
5
  import { getPlatform } from "./platform.js";
6
6
 
7
7
  export function getHomeDir() {
8
- return join(homedir(), CONFIG_DIR_NAME);
8
+ return process.env.CHAINLESSCHAIN_HOME || join(homedir(), CONFIG_DIR_NAME);
9
9
  }
10
10
 
11
11
  export function getBinDir() {
@@ -0,0 +1,124 @@
1
+ const DEDICATED_COLLECTOR_METHODS = Object.freeze({
2
+ "social-bilibili": "bilibiliAdbSync",
3
+ "social-weibo": "weiboAdbSync",
4
+ "social-douyin": "douyinAdbSync",
5
+ "social-xiaohongshu": "xhsAdbSync",
6
+ "social-toutiao": "toutiaoAdbSync",
7
+ "social-kuaishou": "kuaishouAdbSync",
8
+ });
9
+
10
+ function emptyFailureReport(report, error) {
11
+ return {
12
+ adapter: report?.adapter || "unknown",
13
+ status: "error",
14
+ rawCount: 0,
15
+ archivedRawCount: 0,
16
+ archiveFailureCount: 0,
17
+ entityCounts: {
18
+ events: 0,
19
+ persons: 0,
20
+ places: 0,
21
+ items: 0,
22
+ topics: 0,
23
+ },
24
+ invalidCount: 0,
25
+ kgTripleCount: 0,
26
+ ragDocCount: 0,
27
+ durationMs: 0,
28
+ error,
29
+ watermark: null,
30
+ watermarkDeferred: false,
31
+ checkpointCommitted: false,
32
+ pageBudget: null,
33
+ nextPageBudget: null,
34
+ scanDeferredCount: 0,
35
+ watermarkLookbackMs: 0,
36
+ collectionSinceWatermark: null,
37
+ attemptCount: 0,
38
+ retryCount: 0,
39
+ totalRetryDelayMs: 0,
40
+ retryExhausted: false,
41
+ retryAfterMs: null,
42
+ rateLimitReason: null,
43
+ rateLimitRemainingMinute: null,
44
+ rateLimitRemainingDay: null,
45
+ sourceRequestCount: 0,
46
+ sourceRequestThrottleMs: 0,
47
+ sourceRequestRateLimitRemainingMinute: null,
48
+ sourceRequestRateLimitRemainingDay: null,
49
+ };
50
+ }
51
+
52
+ function emit(hub, event) {
53
+ const listener = hub?.registry?.onSyncEvent;
54
+ if (typeof listener !== "function") return;
55
+ try {
56
+ listener(event);
57
+ } catch (_error) {
58
+ // Collection results must not depend on a progress listener.
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Replace Registry `DEDICATED_COLLECTOR_REQUIRED` skips with host-level ADB
64
+ * collector results. The Registry stays host-agnostic; CLI/WS shells own the
65
+ * cookie extraction, signing bridges, and rooted-device collectors.
66
+ */
67
+ export async function runDedicatedBatchCollectors(hub, reports) {
68
+ if (!Array.isArray(reports)) return reports;
69
+ const resolved = [...reports];
70
+
71
+ for (let index = 0; index < resolved.length; index += 1) {
72
+ const skipped = resolved[index];
73
+ if (
74
+ skipped?.status !== "skipped" ||
75
+ skipped?.skipReason !== "DEDICATED_COLLECTOR_REQUIRED"
76
+ ) {
77
+ continue;
78
+ }
79
+
80
+ const methodName = DEDICATED_COLLECTOR_METHODS[skipped.adapter];
81
+ const collect = methodName && hub?.[methodName];
82
+ if (typeof collect !== "function") continue;
83
+
84
+ emit(hub, {
85
+ kind: "sync.batch.dedicated.start",
86
+ adapter: skipped.adapter,
87
+ phase: "collecting",
88
+ });
89
+
90
+ let result;
91
+ try {
92
+ result = await collect.call(hub, {});
93
+ } catch (error) {
94
+ result = {
95
+ ok: false,
96
+ reason: "COLLECTOR_THREW",
97
+ message: error?.message || String(error),
98
+ };
99
+ }
100
+
101
+ if (result?.ok === true && result.report?.status === "ok") {
102
+ resolved[index] = result.report;
103
+ } else {
104
+ const reason = result?.reason || "DEDICATED_COLLECTOR_FAILED";
105
+ const message =
106
+ result?.message ||
107
+ result?.report?.error ||
108
+ "dedicated collector returned no successful SyncReport";
109
+ resolved[index] = emptyFailureReport(skipped, `${reason}: ${message}`);
110
+ }
111
+
112
+ emit(hub, {
113
+ kind: "sync.batch.dedicated.done",
114
+ adapter: skipped.adapter,
115
+ phase: resolved[index].status,
116
+ status: resolved[index].status,
117
+ error: resolved[index].error || null,
118
+ });
119
+ }
120
+
121
+ return resolved;
122
+ }
123
+
124
+ export { DEDICATED_COLLECTOR_METHODS };