chainlesschain 0.162.175 → 0.162.177

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 (311) hide show
  1. package/package.json +10 -10
  2. package/src/assets/web-panel/assets/{AIOps-DherW0Rh.js → AIOps-DT-VPWuN.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-CDGfqt2Y.js → ActionButton-DyOreOVN.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-BYhkzdgD.js → Analytics-DslNsKux.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-cEKk1cpb.js → AppLayout-BNJJAYME.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-_aXR3WWc.js → Artifacts-DoaAtEcY.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-CYAf-gY7.js → Audit-DPG3WdJ9.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-D4Q20phR.js → BackgroundAgents-C_JO6R5G.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-Cq0Tyk58.js → Backup-Cv3BooyX.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-CPj_CdAv.js → BaseInput-D2uQXWu-.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-BQ-Qq0es.js → Chat-B4Vczyf3.js} +4 -4
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-DE6reP99.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-rke6l3yg.js → Checkbox-qTgk4VeP.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-DiacrIPq.js → Codegen-DlLWcIzj.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-Cx3BY-Up.js → Col-DNO73qp7.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DfmWiQy8.js → Community-vRDNpc4j.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-DdQnpxy5.js → Compact-CEWtIXni.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-lzliOH_r.js → Compliance-KgYC9Fxi.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-CYx4Un5k.js → Cowork-zj5wvkpT.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-BGDcPFlo.js → Cron-BLDoCozU.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-0_X5g2ri.js → Crosschain-BYnff4VY.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-C0PEf3Eu.js → DID-C75VFsVm.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-DULQjQ58.js → Dashboard-C4Gutni2.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-DGRHRbW6.js → Dropdown-B5dbO4Kx.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-ChX8XPwB.js → EmailListRenderer-BDipZtHJ.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Dyq6IBNu.js → FamilyGuardDashboard-DmIzt8jj.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-DH1NfAL2.js → Federation-D9QOS-uW.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-BN1I_uNi.js → FormItemContext-B47HRwAm.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-Dq_2UYpe.js → GenericCardRenderer-3R4mXmgV.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-BAy1yvI2.js → Git-DrNXZf1C.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-Db6Q2iSy.js → Governance-BGd7JR98.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-0ub6yHcr.js → Inference-D-2he1ed.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DtLetM36.js → KnowledgeGraph-C0sHIbK5.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-Bcoy7CUd.js → Logs-DiBQO-jL.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-BfEMFAXf.js → MarkdownRenderer-DL_5eV2D.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-tt2rzwRR.js → Marketplace-VR59OdrC.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-BhOgX-MU.js → McpTools-DrPzwSd3.js} +3 -3
  38. package/src/assets/web-panel/assets/{Memory-BJUxeWBL.js → Memory-CBgKALwQ.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-BwUY2G9w.js → MobileBridge-pQ9Tn-Mn.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-BLRfHhqi.js → MobileProjects-mASB6jyj.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-B2WMboOm.js → Mtc-DTMgE7HC.js} +2 -2
  42. package/src/assets/web-panel/assets/{MtcAudit-8pNEXO63.js → MtcAudit-CwTnCtiL.js} +2 -2
  43. package/src/assets/web-panel/assets/{Multisig-C1wm5a_1.js → Multisig-ngm6WU8f.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-C1QpKF7g.js → NLProgramming-4YO4Qww9.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-CiQUcxFu.js → Notes-DP1k45mF.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-BblDPJ_x.js → NotificationSettings-r2H8yPKb.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-DRjYcPtb.js → OrderTableRenderer-CoM_Zw0J.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-Dp3VKB0X.js → Organization-DrO7jRWS.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-Czx161m9.js → Overflow-Cnwu4i4t.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-ClFi6wOs.js → P2P-zi-cDwA_.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-CRweW0lz.js → PdhVaultBrowser-DBEryDv7.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-BzcRoqTn.js → Permissions-lqXK2C3x.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-ChGTpNMd.js → PersonalDataHub-b63T3HJM.js} +2 -2
  54. package/src/assets/web-panel/assets/{Pipeline-BMOOpKWA.js → Pipeline-Kep5KAGW.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-D0AZHObH.js → Privacy-CHdvOAh1.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-yYFlZ6Ja.js → ProjectInit-BhKfdwe9.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-DJNVuMQs.js → ProjectSettings-Yavk9K8A.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-Br0rBWH1.js → Projects-CN8E_5Mq.js} +1 -1
  59. package/src/assets/web-panel/assets/Providers-Bfym6SQn.js +1 -0
  60. package/src/assets/web-panel/assets/{QrScannerModal-81NZOitV.js → QrScannerModal-CLSQcrlR.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-Dic2lCbJ.js → QuickAsk-VPa2WKQN.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-Dh9iwViE.js → Recommend-CGXR8jVU.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-Bq9VYEFy.js → RemoteSession-C_20YfMB.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-CxFZ-NbJ.js → Reputation-awZh68UV.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-BVSLcaX2.js → Row-Ctb4oiYN.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-BbC-5DOH.js → RssFeed-D3sdjvUV.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-BfjZ1GCr.js → Search-C-zfA4kT.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-CVjhOV5r.js → Security-D9XlmHA3.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-D45u-Aqe.js → Services-C3UKnr41.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-WkGoK4he.js → Skeleton-BQxagZfF.js} +1 -1
  71. package/src/assets/web-panel/assets/Skills-q6eb6KPZ.js +1 -0
  72. package/src/assets/web-panel/assets/{Sla-Bf4QTF3E.js → Sla-DveENvek.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-DVpZdbMN.js → SpeechSettings-BFjXLNgF.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-DEEojoMS.js → SyncSettings-BpHgbaP9.js} +2 -2
  75. package/src/assets/web-panel/assets/Tasks-DvepRb8-.js +1 -0
  76. package/src/assets/web-panel/assets/{Templates-Bzl-9wY5.js → Templates-DEiaoyve.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-0khxUOB8.js → Tenant-ITg774nY.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-DWGYhAYU.js → Terminal-D3ZBcvnb.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-B0Y4LONc.js → TimelineRenderer-BsLU6JjU.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-DEE07SFh.js → Tokens-Cb5Pquc9.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-BM7xvA5z.js → Trigger-Dwfy-m9N.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-Dv3ijvvZ.js → Trust-CnlSRGG0.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-B1-enmMt.js → UkeySign-Y4TlvKVo.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-DYiIPByd.js → VideoEditing-BpKLtTTO.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-D-y374BQ.js → Wallet-LLBzIq8x.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-HBDjcUhi.js → WebAuthn-BeSRiusP.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-sKn4qTID.js → WorkflowEditor-BK_l1tXO.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-TVYhaBXj.js → chat-DYd-X7Wg.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-DMADxY9v.js → colors-C9uip71j.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-OftcHpO_.js → compact-item-JBrfjUP6.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-DW1zVUSN.js → createContext-D03fbuiq.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-B8LQ8leS.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-CaUathNp.js → hasIn-DLQOR6l-.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-Cmdv6Dev.js → index-5YN7F5bO.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-iDmgT2Dg.js → index-6GuLRpBQ.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-77kgkUgY.js → index-B0X76LjX.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CM8W07sc.js → index-B46YcgsV.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-C9JoaYSs.js → index-BNCdRmWf.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CpDtN0dl.js → index-BYv-LWdy.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CZXYI5LU.js → index-Ba-Ps_AJ.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DWVZ3T0t.js → index-BcBZwlnG.js} +1 -1
  102. package/src/assets/web-panel/assets/{index--5UvwqH_.js → index-BdH9l8wl.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BBNg08cD.js → index-BfOs_bmg.js} +3 -3
  104. package/src/assets/web-panel/assets/index-Bh8BPtqR.js +1 -0
  105. package/src/assets/web-panel/assets/{index-s-EnkUCn.js → index-BnQgRjsm.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Lr0MO-GU.js → index-BpYKLrUT.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-B-19mFhn.js → index-BuNFCZCx.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CeCIYYG7.js → index-ByHO3SqZ.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-hXq7QRA_.js → index-C2zmOsyD.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-8YelceUU.js → index-CChQBM1d.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-B52Ztt8Q.js → index-CChaISMb.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DKjqFpYa.js → index-CILVyK3b.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DAfT3EMd.js → index-CL0ixCxk.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-sm1sGIxW.js → index-CS63r8h3.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DHi634g9.js → index-CVZWiUE_.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BEzLLVYd.js → index-Ce0Bf1YF.js} +1 -1
  117. package/src/assets/web-panel/assets/index-CeVrHLzZ.js +1 -0
  118. package/src/assets/web-panel/assets/{index-pSVCBsG4.js → index-Ck17i0OD.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-GUKz4Pv9.js → index-Cpn19c9k.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CKNdnJRo.js → index-CqWk1FLG.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-Bg-7FpaL.js → index-CwoDpKzW.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DYwwUKDg.js → index-D-1SqEpQ.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DZdT8nio.js → index-D4UY5Z60.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-BvRw4Fna.js → index-D8KvuDz0.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-kdMl_0zL.js → index-DNMAAUVk.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CK-p7Hji.js → index-DYLZY4uh.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DXcqvWBp.js → index-DaokIHt3.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BFVbDpqg.js → index-Q7mmL6w4.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BJ1PjRY3.js → index-SO6lgMg0.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BSp1Ofvx.js → index-iahNhZwm.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BupSWDcl.js → index-l08afIbV.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-D63QVAiJ.js → index-rIxxfdTN.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-DdcKTlQR.js → initDefaultProps-CG9z1c6w.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-CL-hTBQj.js → motion-B1Ky7Zff.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-qYSAkxNG.js → move-DME8X2P1.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-ZwRSZtRP.js → mtc-parser-cuJYSWB7.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-Bld-8ftI.js → omit-UI_EE0uZ.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-DGHs-a9Z.js → pickAttrs-BIoE_Z_V.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-DRQPMyI5.js → placementArrow-B48-9HKN.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-C5MJG_Yo.js → responsiveObserve-D7x_GDgD.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-VZ-fpZCD.js → slide-DjzC5_7m.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-9ocfCyHk.js → statusUtils-C6BIymhh.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-B6QAwAN5.js → styleChecker-B4dGrdD9.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-Bq1twor3.js → useFlexGapSupport-Bken4aNE.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-DKZq96tz.js → useFs-BMlqECqv.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-D0RmRVXf.js → usePersonalDataHub-DLdrfmMa.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-D6kEj_tt.js → vnode-CKJQmxa0.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-2yfasoQf.js → zoom-CaZunuau.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/auth/npm-auth.js +30 -5
  151. package/src/commands/agenda.js +83 -5
  152. package/src/commands/agent.js +42 -4
  153. package/src/commands/background-session.js +11 -4
  154. package/src/commands/batch.js +79 -27
  155. package/src/commands/changelog.js +15 -4
  156. package/src/commands/config.js +70 -5
  157. package/src/commands/context.js +36 -2
  158. package/src/commands/eval.js +21 -6
  159. package/src/commands/hook.js +2 -2
  160. package/src/commands/hub.js +19 -1
  161. package/src/commands/loop.js +9 -2
  162. package/src/commands/memory.js +21 -6
  163. package/src/commands/permissions.js +57 -1
  164. package/src/commands/plugin.js +2 -0
  165. package/src/commands/review.js +23 -11
  166. package/src/commands/routine.js +31 -8
  167. package/src/commands/session.js +11 -3
  168. package/src/commands/skill.js +2 -0
  169. package/src/commands/statusline.js +3 -3
  170. package/src/commands/team.js +20 -7
  171. package/src/commands/update.js +65 -10
  172. package/src/data/changelog.json +293 -51
  173. package/src/gateways/terminal/PtyManager.js +8 -1
  174. package/src/gateways/ws/message-dispatcher.js +3 -0
  175. package/src/gateways/ws/session-protocol.js +26 -0
  176. package/src/gateways/ws/ws-agent-handler.js +107 -69
  177. package/src/gateways/ws/ws-server.js +74 -2
  178. package/src/harness/background-task-manager.js +18 -6
  179. package/src/harness/background-task-worker.js +11 -18
  180. package/src/harness/jsonl-session-store.js +13 -6
  181. package/src/harness/mcp-client.js +195 -2
  182. package/src/harness/worktree-isolator.js +18 -21
  183. package/src/lib/__tests__/personal-data-hub-aichat-wizard.test.js +15 -0
  184. package/src/lib/agent-coordinator.js +4 -0
  185. package/src/lib/agent-core.js +5 -0
  186. package/src/lib/agent-ipc-bus.js +44 -5
  187. package/src/lib/agent-sandbox.js +16 -2
  188. package/src/lib/agent-schedule-store.js +55 -0
  189. package/src/lib/agent-team/team-worktree.js +28 -6
  190. package/src/lib/agent-tool-admission.js +104 -0
  191. package/src/lib/agent-worktree.js +20 -19
  192. package/src/lib/api-key-helper.js +10 -2
  193. package/src/lib/async-hook-supervisor.cjs +135 -15
  194. package/src/lib/async-hook-supervisor.js +47 -0
  195. package/src/lib/background-agent-supervisor.js +35 -12
  196. package/src/lib/background-task-manager.js +5 -1
  197. package/src/lib/changelog.js +76 -11
  198. package/src/lib/channels/channel-manager.js +6 -0
  199. package/src/lib/channels/telegram-channel.js +11 -1
  200. package/src/lib/channels/webhook-channel.js +15 -3
  201. package/src/lib/checkpoint-store.js +10 -2
  202. package/src/lib/chrome-connector.js +6 -2
  203. package/src/lib/claude-code-bridge.js +24 -8
  204. package/src/lib/cli-anything-bridge.js +82 -25
  205. package/src/lib/cloud/bundle.js +12 -2
  206. package/src/lib/code-review.js +32 -8
  207. package/src/lib/computer-use/control-backend.js +18 -3
  208. package/src/lib/context-breakdown.js +46 -0
  209. package/src/lib/context-source-ledger.js +43 -0
  210. package/src/lib/diff-review-follow-up.js +154 -0
  211. package/src/lib/doctor-checkup.js +18 -6
  212. package/src/lib/downloader.js +17 -3
  213. package/src/lib/ensure-utf8.js +11 -3
  214. package/src/lib/eval/tasks.js +25 -31
  215. package/src/lib/event-runtime-producer.js +58 -0
  216. package/src/lib/event-runtime-store.js +354 -0
  217. package/src/lib/event-runtime-worker.js +109 -0
  218. package/src/lib/execution-backend.js +72 -21
  219. package/src/lib/git-integration.js +19 -4
  220. package/src/lib/hook-manager.js +6 -15
  221. package/src/lib/hook-runner.cjs +88 -8
  222. package/src/lib/hook-runner.js +55 -0
  223. package/src/lib/hooks-v2-producers.js +15 -0
  224. package/src/lib/hooks-v2-runtime.js +70 -21
  225. package/src/lib/host-adb-bridge.js +129 -24
  226. package/src/lib/ide-context.js +128 -1
  227. package/src/lib/interaction-adapter.js +39 -0
  228. package/src/lib/json-schema-validate.js +190 -36
  229. package/src/lib/lan-pairing-preflight.js +13 -2
  230. package/src/lib/lsp/__tests__/benchmark.test.js +61 -0
  231. package/src/lib/lsp/__tests__/lsp-client.test.js +6 -1
  232. package/src/lib/lsp/__tests__/lsp-server-registry.test.js +18 -0
  233. package/src/lib/lsp/benchmark.js +20 -4
  234. package/src/lib/lsp/lsp-client.js +22 -3
  235. package/src/lib/lsp/lsp-manager.js +4 -0
  236. package/src/lib/lsp/lsp-server-registry.js +11 -2
  237. package/src/lib/mcp-oauth.js +8 -2
  238. package/src/lib/npm-invocation.js +29 -0
  239. package/src/lib/orchestrator.js +8 -2
  240. package/src/lib/packer/pack-update-applier.js +14 -2
  241. package/src/lib/packer/pkg-runner.js +13 -2
  242. package/src/lib/packer/precheck.js +33 -16
  243. package/src/lib/packer/smoke-runner.js +18 -5
  244. package/src/lib/packer/web-panel-builder.js +16 -2
  245. package/src/lib/paths.js +1 -1
  246. package/src/lib/permission-rules.cjs +5 -1
  247. package/src/lib/personal-data-hub-aichat-wizard.js +22 -6
  248. package/src/lib/personal-data-hub-wiring.js +27 -3
  249. package/src/lib/plan-mode.js +204 -11
  250. package/src/lib/plugin-monitor-supervisor.js +48 -6
  251. package/src/lib/plugin-runtime/bin.js +45 -0
  252. package/src/lib/plugin-runtime/hooks.js +14 -1
  253. package/src/lib/plugin-runtime/install.js +11 -3
  254. package/src/lib/plugin-runtime/lsp.js +3 -0
  255. package/src/lib/plugin-runtime/mcp.js +8 -1
  256. package/src/lib/plugin-runtime/monitors.js +4 -0
  257. package/src/lib/plugin-runtime/plugin-options.js +74 -7
  258. package/src/lib/plugin-runtime/signature.js +45 -0
  259. package/src/lib/pr-create.js +21 -8
  260. package/src/lib/pr-link-ledger.js +15 -3
  261. package/src/lib/process-execution-broker/credential-agent.js +23 -3
  262. package/src/lib/process-execution-broker/index.js +315 -38
  263. package/src/lib/process-execution-broker/patch-child-process.js +2 -3
  264. package/src/lib/process-manager.js +18 -3
  265. package/src/lib/publish-workspace.js +14 -6
  266. package/src/lib/repl-bang-memorize.js +10 -2
  267. package/src/lib/repl-goal.js +19 -2
  268. package/src/lib/secret-store.js +159 -0
  269. package/src/lib/service-manager.js +64 -29
  270. package/src/lib/settings-hook-events.cjs +74 -9
  271. package/src/lib/settings-hook-events.js +20 -0
  272. package/src/lib/settings-hooks.cjs +4 -0
  273. package/src/lib/side-effect-ledger.js +22 -0
  274. package/src/lib/skill-packs/generator.js +18 -9
  275. package/src/lib/skill-process-broker.js +71 -0
  276. package/src/lib/slash-commands.js +10 -2
  277. package/src/lib/status-line.cjs +28 -7
  278. package/src/lib/status-line.js +33 -0
  279. package/src/lib/sub-agent-context.js +5 -0
  280. package/src/lib/sub-agent-profiles.js +4 -0
  281. package/src/lib/turn-context.js +14 -8
  282. package/src/lib/unattended-action-policy.js +83 -0
  283. package/src/lib/update-notice.js +6 -2
  284. package/src/lib/with-file-lock.js +7 -0
  285. package/src/lib/ws-server.js +1 -0
  286. package/src/repl/agent-repl.js +60 -23
  287. package/src/repl/clipboard-copy.js +8 -2
  288. package/src/repl/pr-comments.js +30 -7
  289. package/src/runtime/agent-core.js +554 -118
  290. package/src/runtime/agent-runtime.js +1 -0
  291. package/src/runtime/coding-agent-contract-shared.cjs +52 -0
  292. package/src/runtime/coding-agent-policy.cjs +20 -0
  293. package/src/runtime/diagnostics.js +73 -8
  294. package/src/runtime/headless-runner.js +88 -10
  295. package/src/runtime/headless-stream.js +343 -21
  296. package/src/runtime/mcp-config.js +16 -1
  297. package/src/runtime/session-slash-commands.js +506 -0
  298. package/src/skills/video-editing/extractors/audio-extractor.js +13 -5
  299. package/src/skills/video-editing/extractors/video-extractor.js +13 -3
  300. package/src/skills/video-editing/media-process.js +20 -0
  301. package/src/skills/video-editing/render/audio-mix.js +13 -3
  302. package/src/skills/video-editing/render/ffmpeg-concat.js +7 -2
  303. package/src/skills/video-editing/render/ffmpeg-extract.js +7 -2
  304. package/src/workers/background-agent-worker.js +6 -2
  305. package/src/assets/web-panel/assets/ChatBubbleRenderer-Ci97vNTs.js +0 -1
  306. package/src/assets/web-panel/assets/Providers-zZRhNtSu.js +0 -1
  307. package/src/assets/web-panel/assets/Skills-D_jvQZcj.js +0 -1
  308. package/src/assets/web-panel/assets/Tasks-DFwxpLIk.js +0 -1
  309. package/src/assets/web-panel/assets/devWarning-CLOk6rdE.js +0 -1
  310. package/src/assets/web-panel/assets/index-CSgUfMTM.js +0 -1
  311. package/src/assets/web-panel/assets/index-DliSZvAP.js +0 -1
@@ -11,15 +11,22 @@
11
11
  import fs from "fs";
12
12
  import path from "path";
13
13
  import { fileURLToPath } from "url";
14
- import { spawn, spawnSync } from "child_process";
15
14
  import { runEvalSuite } from "../lib/eval/runner.js";
16
15
  import { getSuite } from "../lib/eval/tasks.js";
16
+ import executionBroker from "../lib/process-execution-broker/index.js";
17
17
  import {
18
18
  TelemetryRecorder,
19
19
  formatTelemetry,
20
20
  } from "../lib/telemetry/span-recorder.js";
21
21
  import { computeTrend, formatTrend } from "../lib/eval/trend.js";
22
22
 
23
+ export const _deps = {
24
+ platform: process.platform,
25
+ kill: process.kill.bind(process),
26
+ spawn: executionBroker.spawn.bind(executionBroker),
27
+ spawnSync: executionBroker.spawnSync.bind(executionBroker),
28
+ };
29
+
23
30
  /** Append a run summary as one JSONL line to the history file. */
24
31
  function appendHistory(file, record) {
25
32
  fs.appendFileSync(file, JSON.stringify(record) + "\n", "utf8");
@@ -55,18 +62,22 @@ const BIN = path.resolve(__dirname, "..", "..", "bin", "chainlesschain.js");
55
62
  */
56
63
  function killAgentTree(child) {
57
64
  if (!child || !child.pid) return;
58
- if (process.platform === "win32") {
65
+ if (_deps.platform === "win32") {
59
66
  try {
60
- spawnSync("taskkill", ["/PID", String(child.pid), "/T", "/F"], {
67
+ _deps.spawnSync("taskkill", ["/PID", String(child.pid), "/T", "/F"], {
61
68
  windowsHide: true,
62
69
  timeout: 10000,
70
+ origin: "eval:agent-tree-kill",
71
+ policy: "allow",
72
+ scope: "eval",
73
+ shell: false,
63
74
  });
64
75
  } catch {
65
76
  /* fall through to the direct kill below */
66
77
  }
67
78
  } else {
68
79
  try {
69
- process.kill(-child.pid, "SIGKILL"); // negative pid = process group
80
+ _deps.kill(-child.pid, "SIGKILL"); // negative pid = process group
70
81
  return;
71
82
  } catch {
72
83
  /* not a group leader / already gone — fall through */
@@ -105,12 +116,16 @@ function makeHeadlessRunAgent(opts = {}) {
105
116
  if (opts.model) args.push("--model", opts.model);
106
117
  if (opts.provider) args.push("--provider", opts.provider);
107
118
  }
108
- const child = spawn(process.execPath, args, {
119
+ const child = _deps.spawn(process.execPath, args, {
109
120
  cwd,
110
121
  env: { ...process.env, CLAUDECODE: "1" },
111
122
  windowsHide: true,
112
123
  // Own process group on POSIX so a timeout can reap the whole tree.
113
- detached: process.platform !== "win32",
124
+ detached: _deps.platform !== "win32",
125
+ origin: "eval:agent-run",
126
+ policy: "allow",
127
+ scope: "eval",
128
+ shell: false,
114
129
  });
115
130
  let out = "";
116
131
  let err = "";
@@ -173,7 +173,7 @@ export function registerHookCommand(program) {
173
173
  return;
174
174
  }
175
175
 
176
- const { runHooks } = await import("../lib/hook-runner.cjs");
176
+ const { runHooks } = await import("../lib/hook-runner.js");
177
177
  const outcome = runHooks(matched, payload, {
178
178
  cwd: process.cwd(),
179
179
  event,
@@ -283,7 +283,7 @@ export function registerHookCommand(program) {
283
283
  // observe-only + --run: re-collect and execute the matching hooks.
284
284
  const { loadHooks, collectHooks } =
285
285
  await import("../lib/settings-hooks.cjs");
286
- const { runHooks } = await import("../lib/hook-runner.cjs");
286
+ const { runHooks } = await import("../lib/hook-runner.js");
287
287
  const { hooks } = loadHooks({ cwd: process.cwd() });
288
288
  const matched = collectHooks(
289
289
  hooks,
@@ -531,6 +531,12 @@ async function cmdSyncAdapter(name, options) {
531
531
  // sources (wechat-pc), --db-path as an explicit alias for the DB file.
532
532
  if (options.key) opts.key = String(options.key);
533
533
  if (options.dbPath) opts.dbPath = String(options.dbPath);
534
+ // WhatsApp public-backup ADB path. `--key` accepts the crypt15 64-hex
535
+ // root key or a crypt14/encrypted_backup.key file path. Device selection
536
+ // follows --serial, then ADB_SERIAL, then the single connected device.
537
+ if (options.serial) opts.serial = String(options.serial);
538
+ if (options.whatsappBusiness) opts.business = true;
539
+ if (options.remotePath) opts.remotePath = String(options.remotePath);
534
540
  // QQ NT (qq-pc): the SQLCipher passphrase from qq-win-db-key (ASCII, e.g.
535
541
  // "5{sww#,6aq=)8=A@"). Routes qq-pc through the decrypt+parse sidecar.
536
542
  if (options.passphrase) opts.passphrase = String(options.passphrase);
@@ -3013,7 +3019,19 @@ export function registerHubCommand(program) {
3013
3019
  )
3014
3020
  .option(
3015
3021
  "--key <hex>",
3016
- "SQLCipher key (64-hex) for encrypted local DBs (e.g. wechat-pc)",
3022
+ "Encryption key: SQLCipher 64-hex, WhatsApp crypt15 64-hex, or WhatsApp key-file path",
3023
+ )
3024
+ .option(
3025
+ "--serial <adb-serial>",
3026
+ "Android device serial for ADB-backed adapters (otherwise ADB_SERIAL or the single connected device)",
3027
+ )
3028
+ .option(
3029
+ "--whatsapp-business",
3030
+ "Pull the WhatsApp Business public backup instead of the personal app backup",
3031
+ )
3032
+ .option(
3033
+ "--remote-path <android-path>",
3034
+ "Explicit WhatsApp msgstore backup path inside an allowed public Databases directory",
3017
3035
  )
3018
3036
  .option(
3019
3037
  "--passphrase <key>",
@@ -23,10 +23,10 @@
23
23
  * only builds the concrete iteration (spawn + tee output) and wires SIGINT.
24
24
  */
25
25
 
26
- import { spawn } from "node:child_process";
27
26
  import { fileURLToPath } from "node:url";
28
27
  import chalk from "chalk";
29
28
  import { logger } from "../lib/logger.js";
29
+ import executionBroker from "../lib/process-execution-broker/index.js";
30
30
  import {
31
31
  runLoop,
32
32
  parseDuration,
@@ -42,6 +42,10 @@ import {
42
42
  sessionExists,
43
43
  } from "../harness/jsonl-session-store.js";
44
44
 
45
+ export const _deps = {
46
+ spawn: executionBroker.spawn.bind(executionBroker),
47
+ };
48
+
45
49
  /**
46
50
  * Appended to the prompt under `--dynamic` so the model can self-pace: it ends
47
51
  * its reply with at most one control directive the loop parses (parseLoopDirectives).
@@ -66,10 +70,13 @@ const BIN_PATH = fileURLToPath(
66
70
  */
67
71
  function spawnIteration(cmd, args, { shell, onChild, capture }) {
68
72
  return new Promise((resolve) => {
69
- const child = spawn(cmd, args, {
73
+ const child = _deps.spawn(cmd, args, {
70
74
  shell,
71
75
  stdio: capture ? ["inherit", "pipe", "pipe"] : "inherit",
72
76
  env: process.env,
77
+ origin: "loop:iteration",
78
+ policy: "allow",
79
+ scope: "loop",
73
80
  });
74
81
  if (onChild) onChild(child);
75
82
 
@@ -4,8 +4,11 @@
4
4
  */
5
5
 
6
6
  import chalk from "chalk";
7
+ import path from "node:path";
7
8
  import { logger } from "../lib/logger.js";
8
9
  import { bootstrap, shutdown } from "../runtime/bootstrap.js";
10
+ import { parseEditorCommand } from "./config.js";
11
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
9
12
  import {
10
13
  getMemoryDir,
11
14
  addMemory,
@@ -50,6 +53,22 @@ import {
50
53
  getMemoryManagerStatsV2,
51
54
  } from "../lib/memory-manager.js";
52
55
 
56
+ export const _deps = {
57
+ execFileSync: (...args) => executionBroker.execFileSync(...args),
58
+ };
59
+
60
+ export function openMemoryEditor(editor, filePath, deps = _deps) {
61
+ const [file, ...editorArgs] = parseEditorCommand(editor);
62
+ if (!file) throw new Error("EDITOR command is empty");
63
+ return deps.execFileSync(file, [...editorArgs, filePath], {
64
+ stdio: "inherit",
65
+ origin: "memory:editor",
66
+ policy: "allow",
67
+ scope: "memory",
68
+ shell: false,
69
+ });
70
+ }
71
+
53
72
  export function registerMemoryCommand(program) {
54
73
  const memory = program
55
74
  .command("memory")
@@ -596,17 +615,13 @@ export function registerMemoryCommand(program) {
596
615
  const content = getMemoryFile(memoryDir);
597
616
 
598
617
  if (options.edit) {
599
- const { execSync } = await import("child_process");
600
618
  const editor =
601
619
  process.env.EDITOR ||
602
620
  process.env.VISUAL ||
603
621
  (process.platform === "win32" ? "notepad" : "nano");
604
- const filePath = `${memoryDir}/MEMORY.md`;
622
+ const filePath = path.join(memoryDir, "MEMORY.md");
605
623
  try {
606
- // Escape any `"` in the path so it can't break out of the quoted
607
- // arg (editor stays unquoted so `$EDITOR` values with args work).
608
- const safePath = filePath.replace(/"/g, '\\"');
609
- execSync(`${editor} "${safePath}"`, { stdio: "inherit" });
624
+ openMemoryEditor(editor, filePath);
610
625
  logger.success("Memory file updated");
611
626
  } catch {
612
627
  logger.error(
@@ -5,6 +5,7 @@
5
5
  * cc permissions list [--json] merged ruleset + source file
6
6
  * cc permissions test <tool> <args...> dry-run: which rule decides?
7
7
  * cc permissions add <allow|ask|deny> <rule> append a rule to a settings file
8
+ * cc permissions allow|ask|deny <rule> convenience aliases for add
8
9
  * [--local | --user] (default target: project)
9
10
  *
10
11
  * The ruleset is loaded by settings-loader (user < project < local < env) and
@@ -23,7 +24,7 @@ const KIND_COLOR = {
23
24
  };
24
25
 
25
26
  const RUNTIME_ADVISORY =
26
- "advisory/not enforced: this command edits and dry-runs settings rules; the Agent runtime still has separate ApprovalGate/managed-policy wiring.";
27
+ "settings rules are enforced by the Agent Core when loaded into the active runtime; managed host policy and ApprovalGate still apply.";
27
28
 
28
29
  function printRuntimeAdvisory() {
29
30
  logger.log(chalk.yellow(RUNTIME_ADVISORY));
@@ -48,6 +49,48 @@ function buildArgs(tool, positional, rulesMod) {
48
49
  return {};
49
50
  }
50
51
 
52
+ async function persistPermissionRule(decision, rule, options, operation = "add") {
53
+ try {
54
+ const kind = String(decision || "").toLowerCase();
55
+ if (!["allow", "ask", "deny"].includes(kind)) {
56
+ logger.error(
57
+ chalk.red(`decision must be allow | ask | deny (got "${decision}")`),
58
+ );
59
+ process.exitCode = 1;
60
+ return;
61
+ }
62
+ const rulesMod = await import("../lib/permission-rules.cjs");
63
+ const mod = rulesMod.default || rulesMod;
64
+ if (!mod.parseRule(rule)) {
65
+ logger.error(
66
+ chalk.red(
67
+ `not a valid rule: "${rule}" (expected Tool or Tool(pattern), e.g. Bash(rm:*))`,
68
+ ),
69
+ );
70
+ process.exitCode = 1;
71
+ return;
72
+ }
73
+ const scope = options.user ? "user" : options.local ? "local" : "project";
74
+ const { addRule } = await import("../lib/settings-loader.cjs");
75
+ const { file, added } = addRule({
76
+ cwd: process.cwd(),
77
+ kind,
78
+ rule,
79
+ scope,
80
+ });
81
+ if (!added) {
82
+ logger.log(chalk.gray(`already present in ${file}: ${kind} ${rule}`));
83
+ return;
84
+ }
85
+ logger.log(
86
+ `${KIND_COLOR[kind].bold("✓ " + kind)} ${rule} ${chalk.gray("→ " + file)}`,
87
+ );
88
+ } catch (err) {
89
+ logger.error(chalk.red(`permissions ${operation} failed: ${err.message}`));
90
+ process.exitCode = 1;
91
+ }
92
+ }
93
+
51
94
  export function registerPermissionsCommand(program) {
52
95
  const cmd = program
53
96
  .command("permissions")
@@ -336,4 +379,17 @@ export function registerPermissionsCommand(program) {
336
379
  process.exitCode = 1;
337
380
  }
338
381
  });
382
+
383
+ // Explicit decision commands make the management surface easier to script
384
+ // and match the common `allow <rule>` / `deny <rule>` workflow.
385
+ for (const decision of ["allow", "ask", "deny"]) {
386
+ cmd
387
+ .command(`${decision} <rule>`)
388
+ .description(`Append an ${decision} permission rule`)
389
+ .option("--local", "Write to .claude/settings.local.json")
390
+ .option("--user", "Write to ~/.claude/settings.json")
391
+ .action(async (rule, options) => {
392
+ await persistPermissionRule(decision, rule, options, decision);
393
+ });
394
+ }
339
395
  }
@@ -1314,6 +1314,7 @@ export function registerPluginCommand(program) {
1314
1314
  const scope = options.scope === "project" ? "project" : "user";
1315
1315
  const current = optsMod.loadPluginOptionValues(name, scope, {
1316
1316
  cwd: process.cwd(),
1317
+ schema,
1317
1318
  });
1318
1319
  for (const pair of options.set) {
1319
1320
  const eq = pair.indexOf("=");
@@ -1326,6 +1327,7 @@ export function registerPluginCommand(program) {
1326
1327
  }
1327
1328
  optsMod.setPluginOptionValues(name, current, scope, {
1328
1329
  cwd: process.cwd(),
1330
+ schema,
1329
1331
  });
1330
1332
  logger.success(`Set option(s) for ${name} at ${scope} scope`);
1331
1333
  }
@@ -28,18 +28,22 @@
28
28
  * .chainlesschain/config.json `llm` exactly like `cc agent` / `cc ask`.
29
29
  */
30
30
 
31
- import { spawnSync } from "node:child_process";
32
31
  import fs from "node:fs";
33
32
  import path from "node:path";
34
33
  import chalk from "chalk";
35
34
  import { logger } from "../lib/logger.js";
36
35
  import { firstBalancedJson } from "../lib/json-schema-output.js";
36
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
37
37
  import {
38
38
  dedupeFindings,
39
39
  buildReviewReport,
40
40
  findingKey,
41
41
  } from "../lib/review-pipeline.js";
42
42
 
43
+ export const _deps = {
44
+ spawnSync: (...args) => executionBroker.spawnSync(...args),
45
+ };
46
+
43
47
  /** Diffs larger than this are truncated before going to the model. */
44
48
  const MAX_DIFF_CHARS = 200_000;
45
49
  /** Per-untracked-file and total caps when inlining brand-new files. */
@@ -52,12 +56,16 @@ const VALID_EFFORTS = Object.freeze(["low", "medium", "high"]);
52
56
  * Run git with an argv array (no shell → no quoting hazards). UTF-8 in/out.
53
57
  * Returns trimmed stdout; throws with git's stderr on failure.
54
58
  */
55
- function gitCli(args, { cwd } = {}) {
56
- const res = spawnSync("git", args, {
59
+ export function gitCli(args, { cwd } = {}) {
60
+ const res = _deps.spawnSync("git", args, {
57
61
  cwd,
58
62
  encoding: "utf-8",
59
63
  windowsHide: true,
60
64
  maxBuffer: 256 * 1024 * 1024,
65
+ origin: "review:command-git",
66
+ policy: "allow",
67
+ scope: "review",
68
+ shell: false,
61
69
  });
62
70
  if (res.error) throw res.error;
63
71
  if (res.status !== 0) {
@@ -86,28 +94,28 @@ function isGitRepo(cwd, git = gitCli) {
86
94
  */
87
95
  export function resolveDiffArgs(opts = {}, stat = false) {
88
96
  const { staged, base, range, paths } = opts;
89
- let args;
97
+ const args = ["diff"];
98
+ if (stat) args.push("--stat");
90
99
  let scope;
91
100
  let label;
92
101
  if (range) {
93
- args = ["diff", range];
102
+ args.push("--end-of-options", range);
94
103
  scope = "range";
95
104
  label = `range ${range}`;
96
105
  } else if (base) {
97
106
  // three-dot: changes on HEAD since it diverged from <base> (PR-style).
98
- args = ["diff", `${base}...HEAD`];
107
+ args.push("--end-of-options", `${base}...HEAD`);
99
108
  scope = "base";
100
109
  label = `${base}...HEAD`;
101
110
  } else if (staged) {
102
- args = ["diff", "--cached"];
111
+ args.push("--cached");
103
112
  scope = "staged";
104
113
  label = "staged changes";
105
114
  } else {
106
- args = ["diff", "HEAD"];
115
+ args.push("HEAD");
107
116
  scope = "working";
108
117
  label = "working tree vs HEAD";
109
118
  }
110
- if (stat) args.push("--stat");
111
119
  const cleanPaths = Array.isArray(paths) ? paths.filter(Boolean) : [];
112
120
  if (cleanPaths.length) args.push("--", ...cleanPaths);
113
121
  return { args, scope, label };
@@ -361,13 +369,17 @@ function collectReviewDiff(scopeOpts, { cwd, git, includeUntracked }) {
361
369
  }
362
370
 
363
371
  /** Run `gh` with an argv array (no shell). UTF-8 in/out; throws on failure. */
364
- function ghCli(args, { cwd, input } = {}) {
365
- const res = spawnSync("gh", args, {
372
+ export function ghCli(args, { cwd, input } = {}) {
373
+ const res = _deps.spawnSync("gh", args, {
366
374
  cwd,
367
375
  input,
368
376
  encoding: "utf-8",
369
377
  windowsHide: true,
370
378
  maxBuffer: 64 * 1024 * 1024,
379
+ origin: "review:command-gh",
380
+ policy: "allow",
381
+ scope: "review",
382
+ shell: false,
371
383
  });
372
384
  if (res.error) throw res.error;
373
385
  if (res.status !== 0) {
@@ -13,11 +13,16 @@
13
13
  * agenda wakeup), exactly like `cc agenda run`.
14
14
  */
15
15
 
16
- import { spawn, execFile } from "node:child_process";
17
16
  import { readFileSync, existsSync } from "node:fs";
18
17
  import { fileURLToPath } from "node:url";
19
18
  import chalk from "chalk";
20
19
  import { logger } from "../lib/logger.js";
20
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
21
+
22
+ export const _deps = {
23
+ spawn: (...args) => executionBroker.spawn(...args),
24
+ execFile: (...args) => executionBroker.execFile(...args),
25
+ };
21
26
 
22
27
  const BIN_PATH = fileURLToPath(
23
28
  new URL("../../bin/chainlesschain.js", import.meta.url),
@@ -29,12 +34,18 @@ async function loadStore() {
29
34
  }
30
35
 
31
36
  /** Production runner: `cc agent -p <prompt> --output-format json`. */
32
- function defaultRunAgent({ prompt }) {
37
+ export function defaultRunAgent({ prompt }) {
33
38
  return new Promise((resolve) => {
34
- const child = spawn(
39
+ const child = _deps.spawn(
35
40
  process.execPath,
36
- [BIN_PATH, "agent", "-p", prompt, "--output-format", "json"],
37
- { windowsHide: true },
41
+ [BIN_PATH, "agent", "--output-format", "json"],
42
+ {
43
+ windowsHide: true,
44
+ origin: "routine:agent",
45
+ policy: "allow",
46
+ scope: "routine",
47
+ shell: false,
48
+ },
38
49
  );
39
50
  let out = "";
40
51
  let err = "";
@@ -42,6 +53,10 @@ function defaultRunAgent({ prompt }) {
42
53
  child.stderr?.setEncoding("utf8");
43
54
  child.stdout?.on("data", (d) => (out += d));
44
55
  child.stderr?.on("data", (d) => (err += d));
56
+ if (child.stdin) {
57
+ child.stdin.on("error", () => {});
58
+ child.stdin.end(prompt);
59
+ }
45
60
  child.on("error", (error) =>
46
61
  resolve({ exitCode: -1, output: `spawn error: ${error.message}` }),
47
62
  );
@@ -70,12 +85,20 @@ function defaultRunAgent({ prompt }) {
70
85
  }
71
86
 
72
87
  /** Production github events fetch via gh CLI. */
73
- function defaultFetchEvents(repo) {
88
+ export function defaultFetchEvents(repo) {
74
89
  return new Promise((resolve) => {
75
- execFile(
90
+ _deps.execFile(
76
91
  "gh",
77
92
  ["api", `repos/${repo}/events`, "--paginate=false"],
78
- { encoding: "utf8", timeout: 8000, windowsHide: true },
93
+ {
94
+ encoding: "utf8",
95
+ timeout: 8000,
96
+ windowsHide: true,
97
+ origin: "routine:github-events",
98
+ policy: "allow",
99
+ scope: "routine",
100
+ shell: false,
101
+ },
79
102
  (err, stdout) => {
80
103
  if (err) return resolve([]);
81
104
  try {
@@ -61,6 +61,11 @@ import {
61
61
  listWorkflowSessions,
62
62
  readWorkflowSession,
63
63
  } from "../lib/workflow-state-reader.js";
64
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
65
+
66
+ export const _deps = {
67
+ execFileSync: (...args) => executionBroker.execFileSync(...args),
68
+ };
64
69
 
65
70
  // DB sessions store `updated_at` as SQLite datetime('now') → "YYYY-MM-DD
66
71
  // HH:MM:SS" (UTC, space at index 10); JSONL sessions store toISOString() →
@@ -149,8 +154,7 @@ export function mapGhPrToSignals(gh = {}) {
149
154
  * mapped signals, or throws (caller degrades to a "pass --checks-file" hint).
150
155
  * 8s timeout, stderr suppressed — a missing / unauthenticated gh just fails.
151
156
  */
152
- async function fetchPrSignalsViaGh(target) {
153
- const { execFileSync } = await import("node:child_process");
157
+ export async function fetchPrSignalsViaGh(target) {
154
158
  const args = [
155
159
  "pr",
156
160
  "view",
@@ -159,10 +163,14 @@ async function fetchPrSignalsViaGh(target) {
159
163
  "number,state,headRefName,headRefOid,reviewDecision,statusCheckRollup",
160
164
  ];
161
165
  if (target.repo) args.push("--repo", String(target.repo));
162
- const out = execFileSync("gh", args, {
166
+ const out = _deps.execFileSync("gh", args, {
163
167
  encoding: "utf-8",
164
168
  timeout: 8000,
165
169
  stdio: ["ignore", "pipe", "ignore"],
170
+ origin: "session:pr-status",
171
+ policy: "allow",
172
+ scope: "pr",
173
+ shell: false,
166
174
  });
167
175
  return mapGhPrToSignals(JSON.parse(out));
168
176
  }
@@ -10,6 +10,7 @@ import chalk from "chalk";
10
10
  import ora from "ora";
11
11
  import fs from "fs";
12
12
  import path from "path";
13
+ import { createSkillProcessBroker } from "../lib/skill-process-broker.js";
13
14
  import { logger } from "../lib/logger.js";
14
15
  import {
15
16
  CLISkillLoader,
@@ -368,6 +369,7 @@ export function registerSkillCommand(program) {
368
369
  projectRoot: process.cwd(),
369
370
  workspacePath: process.cwd(),
370
371
  workspaceRoot: process.cwd(),
372
+ processBroker: createSkillProcessBroker(s),
371
373
  };
372
374
 
373
375
  const result = await handler.execute(task, context, s);
@@ -27,12 +27,12 @@ export function registerStatuslineCommand(program) {
27
27
  .action(async (options) => {
28
28
  try {
29
29
  const { loadStatusLineConfig, buildContext, renderStatusLine } =
30
- await import("../lib/status-line.cjs");
30
+ await import("../lib/status-line.js");
31
31
  const cfg = loadStatusLineConfig({ cwd: process.cwd() });
32
32
  if (!cfg) {
33
33
  logger.log(
34
34
  chalk.gray(
35
- 'No statusLine configured. Add to .claude/settings.json:\n' +
35
+ "No statusLine configured. Add to .claude/settings.json:\n" +
36
36
  ' { "statusLine": { "type": "command", "command": "./status.sh" } }',
37
37
  ),
38
38
  );
@@ -73,7 +73,7 @@ export function registerStatuslineCommand(program) {
73
73
  .option("--json", "Output as JSON")
74
74
  .action(async (options) => {
75
75
  try {
76
- const { loadStatusLineConfig } = await import("../lib/status-line.cjs");
76
+ const { loadStatusLineConfig } = await import("../lib/status-line.js");
77
77
  const cfg = loadStatusLineConfig({ cwd: process.cwd() });
78
78
  if (options.json) {
79
79
  console.log(JSON.stringify(cfg, null, 2));
@@ -18,12 +18,16 @@
18
18
  import fs from "fs";
19
19
  import path from "path";
20
20
  import { fileURLToPath } from "url";
21
- import { spawn } from "child_process";
22
21
  import { TaskLeaseRegistry } from "../lib/agent-team/task-lease.js";
23
22
  import { TeamRunner } from "../lib/agent-team/team-runner.js";
24
23
  import { TeamWorktreeCoordinator } from "../lib/agent-team/team-worktree.js";
25
24
  import { TeamBudget } from "../lib/agent-team/team-budget.js";
26
25
  import { TeamMailbox } from "../lib/agent-team/team-mailbox.js";
26
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
27
+
28
+ export const _deps = {
29
+ spawn: (...args) => executionBroker.spawn(...args),
30
+ };
27
31
 
28
32
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
29
33
  const BIN = path.resolve(__dirname, "..", "..", "bin", "chainlesschain.js");
@@ -94,17 +98,20 @@ function planWaves(reg) {
94
98
  }
95
99
 
96
100
  /** Real executor: run a task's shell `command`, success = exit 0. */
97
- function makeShellRunTask(logger) {
101
+ export function makeShellRunTask(logger) {
98
102
  return function runTask({ task }) {
99
103
  const command = task.metadata?.command || task?.command;
100
104
  if (!command) {
101
105
  throw new Error(`task "${task.key}" has no \`command\` to --exec`);
102
106
  }
103
107
  return new Promise((resolve, reject) => {
104
- const child = spawn(command, {
108
+ const child = _deps.spawn(command, [], {
105
109
  cwd: process.cwd(),
106
110
  shell: true,
107
111
  env: process.env,
112
+ origin: "team:shell",
113
+ policy: "allow",
114
+ scope: "team",
108
115
  });
109
116
  let err = "";
110
117
  child.stderr?.on("data", (d) => (err += d.toString("utf8")));
@@ -118,26 +125,32 @@ function makeShellRunTask(logger) {
118
125
  }
119
126
 
120
127
  /** Spawn a headless `cc agent -p` for one prompt in `cwd`; resolve on exit 0. */
121
- function spawnAgent(prompt, cwd, opts = {}) {
128
+ export function spawnAgent(prompt, cwd, opts = {}) {
122
129
  return new Promise((resolve, reject) => {
123
130
  const args = [
124
131
  BIN,
125
132
  "agent",
126
- "-p",
127
- prompt,
128
133
  "--permission-mode",
129
134
  opts.permissionMode || "acceptEdits",
130
135
  "--output-format",
131
136
  "text",
132
137
  ];
133
138
  if (opts.model) args.push("--model", opts.model);
134
- const child = spawn(process.execPath, args, {
139
+ const child = _deps.spawn(process.execPath, args, {
135
140
  cwd,
136
141
  env: { ...process.env, CLAUDECODE: "1" },
137
142
  windowsHide: true,
143
+ origin: "team:agent",
144
+ policy: "allow",
145
+ scope: "team",
146
+ shell: false,
138
147
  });
139
148
  let err = "";
140
149
  child.stderr?.on("data", (d) => (err += d.toString("utf8")));
150
+ if (child.stdin) {
151
+ child.stdin.on("error", () => {});
152
+ child.stdin.end(prompt);
153
+ }
141
154
  child.on("error", (e) => reject(new Error(e.message)));
142
155
  child.on("close", (code) =>
143
156
  code === 0