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
@@ -91,6 +91,41 @@ export function compareSemver(a, b) {
91
91
  return 0;
92
92
  }
93
93
 
94
+ /**
95
+ * Whether a parsed changelog documents an exact CLI package version.
96
+ *
97
+ * A product block can cover more than one CLI release (notably the root
98
+ * `Unreleased` block), so check both its primary `cliVersion` and the complete
99
+ * `cliVersions` set. This is also the publish-time stale-artifact guard.
100
+ */
101
+ export function hasCliVersion(releases, version) {
102
+ if (!version || !Array.isArray(releases)) return false;
103
+ return releases.some(
104
+ (release) =>
105
+ release?.cliVersion === version ||
106
+ (Array.isArray(release?.cliVersions) &&
107
+ release.cliVersions.includes(version)),
108
+ );
109
+ }
110
+
111
+ /** Highest exact CLI version documented by the parsed release list. */
112
+ export function latestCliVersion(releases) {
113
+ if (!Array.isArray(releases)) return null;
114
+ const versions = releases.flatMap((release) => {
115
+ const covered = Array.isArray(release?.cliVersions)
116
+ ? release.cliVersions
117
+ : [];
118
+ return release?.cliVersion ? [...covered, release.cliVersion] : covered;
119
+ });
120
+ return versions.length === 0
121
+ ? null
122
+ : versions.reduce(
123
+ (latest, version) =>
124
+ compareSemver(version, latest) > 0 ? version : latest,
125
+ versions[0],
126
+ );
127
+ }
128
+
94
129
  /**
95
130
  * Parse a raw CHANGELOG.md string into CLI-focused release entries.
96
131
  *
@@ -135,6 +170,28 @@ export function parseChangelog(md) {
135
170
  const sections = extractCliSections(block.lines, block.header);
136
171
  if (!sections) continue;
137
172
 
173
+ // The root changelog keeps multiple still-unreleased CLI versions as
174
+ // sibling `###` sections. Treating the whole `## [Unreleased]` block as
175
+ // one record collapses many CLI releases into a single entry and makes
176
+ // `-n 5` mean five product blocks instead of five CLI versions.
177
+ if (parsed.version.toLowerCase() === "unreleased") {
178
+ for (const section of sections) {
179
+ const sectionText = `${section.heading}\n${section.body}`;
180
+ const sectionVersions = extractCliVersions(sectionText);
181
+ if (!sectionVersions.primary) continue;
182
+ const dateMatch = sectionText.match(/\b(\d{4}-\d{2}-\d{2})\b/);
183
+ releases.push({
184
+ productVersion: null,
185
+ cliVersion: sectionVersions.primary,
186
+ cliVersions: sectionVersions.all.sort(compareSemver),
187
+ date: dateMatch ? dateMatch[1] : null,
188
+ title: "",
189
+ sections: [section],
190
+ });
191
+ }
192
+ continue;
193
+ }
194
+
138
195
  releases.push({
139
196
  productVersion: parsed.version,
140
197
  cliVersion: primary,
@@ -225,24 +282,32 @@ function extractCliSections(bodyLines, header) {
225
282
  *
226
283
  * @returns {{ source: string, releases: Array }}
227
284
  */
228
- export function loadChangelog() {
285
+ export function loadChangelog({
286
+ fsApi = fs,
287
+ pathApi = path,
288
+ dirname = __dirname,
289
+ } = {}) {
229
290
  const changelogCandidates = [
230
- path.join(__dirname, "..", "..", "CHANGELOG.md"), // packages/cli/CHANGELOG.md
231
- path.join(__dirname, "..", "..", "..", "..", "CHANGELOG.md"), // repo root
291
+ pathApi.join(dirname, "..", "..", "CHANGELOG.md"), // packages/cli/CHANGELOG.md
292
+ pathApi.join(dirname, "..", "..", "..", "..", "CHANGELOG.md"), // repo root
232
293
  ];
233
294
  for (const p of changelogCandidates) {
234
- if (fs.existsSync(p)) {
235
- return {
236
- source: "CHANGELOG.md",
237
- releases: parseChangelog(fs.readFileSync(p, "utf-8")),
238
- };
295
+ if (fsApi.existsSync(p)) {
296
+ const releases = parseChangelog(fsApi.readFileSync(p, "utf-8"));
297
+ // A parent-level CHANGELOG can exist in a global Node.js installation
298
+ // (for example C:\\nvm4w\\nodejs\\CHANGELOG.md). Do not treat an
299
+ // unrelated, successfully-read file with zero CLI releases as the
300
+ // authoritative source; continue to the bundled artifact instead.
301
+ if (releases.length > 0) {
302
+ return { source: "CHANGELOG.md", releases };
303
+ }
239
304
  }
240
305
  }
241
306
  // Installed npm package: CHANGELOG.md isn't shipped, use the bundled artifact.
242
- const jsonPath = path.join(__dirname, "..", "data", "changelog.json");
243
- if (fs.existsSync(jsonPath)) {
307
+ const jsonPath = pathApi.join(dirname, "..", "data", "changelog.json");
308
+ if (fsApi.existsSync(jsonPath)) {
244
309
  try {
245
- const data = JSON.parse(fs.readFileSync(jsonPath, "utf-8"));
310
+ const data = JSON.parse(fsApi.readFileSync(jsonPath, "utf-8"));
246
311
  if (Array.isArray(data.releases)) return data;
247
312
  } catch {
248
313
  /* fall through to empty */
@@ -20,6 +20,7 @@ import {
20
20
  canApprove,
21
21
  describeAuthorityChain,
22
22
  } from "../agent-authority.js";
23
+ import { EventRuntimeStore } from "../event-runtime-store.js";
23
24
 
24
25
  export const CHANNEL_KINDS = ["webhook", "telegram"];
25
26
 
@@ -120,6 +121,9 @@ export async function startChannels(specsInput, opts = {}) {
120
121
  const config = opts.config || {};
121
122
  const log = opts.log || ((msg) => logger.info(msg));
122
123
  const deps = opts.deps || {};
124
+ const eventRuntimeStore =
125
+ opts.eventRuntimeStore ||
126
+ (process.env.CC_EVENT_RUNTIME_DURABLE === "1" ? new EventRuntimeStore() : null);
123
127
  // Every inbound event is stamped with its channel authority (`steer`, never
124
128
  // `approve`) before the caller's handler sees it — so a channel message can
125
129
  // never be mistaken for a user approval no matter what it contains.
@@ -149,6 +153,7 @@ export async function startChannels(specsInput, opts = {}) {
149
153
  port: spec.arg ? Number(spec.arg) : cfg.port,
150
154
  onEvent,
151
155
  log,
156
+ eventRuntimeStore,
152
157
  });
153
158
  started.push({ kind: "webhook", describe: handle.describe, ...handle });
154
159
  } else if (spec.kind === "telegram") {
@@ -161,6 +166,7 @@ export async function startChannels(specsInput, opts = {}) {
161
166
  ...cfg,
162
167
  onEvent,
163
168
  log,
169
+ eventRuntimeStore,
164
170
  });
165
171
  started.push({
166
172
  kind: "telegram",
@@ -13,6 +13,7 @@
13
13
 
14
14
  const POLL_TIMEOUT_S = 25;
15
15
  const ERROR_BACKOFF_MS = 5000;
16
+ import { EventRuntimeProducer } from "../event-runtime-producer.js";
16
17
 
17
18
  export async function startTelegramChannel(options = {}) {
18
19
  const {
@@ -27,7 +28,11 @@ export async function startTelegramChannel(options = {}) {
27
28
  // failures) can never turn the loop into a microtask chain that starves
28
29
  // the event loop (timers, stop()) entirely.
29
30
  pollPauseMs = 50,
31
+ eventRuntimeStore = null,
30
32
  } = options;
33
+ const runtimeProducer = eventRuntimeStore
34
+ ? new EventRuntimeProducer({ store: eventRuntimeStore })
35
+ : null;
31
36
 
32
37
  if (!botToken) {
33
38
  throw new Error(
@@ -65,12 +70,17 @@ export async function startTelegramChannel(options = {}) {
65
70
  if (!chatId || !text) continue;
66
71
  if (!allowed.has(String(chatId))) continue; // fail closed
67
72
  try {
68
- onEvent?.({
73
+ const event = {
69
74
  channel: "telegram",
70
75
  sender: String(chatId),
71
76
  text,
72
77
  meta: { updateId: update.update_id },
78
+ };
79
+ runtimeProducer?.publish(event, {
80
+ origin: "telegram",
81
+ id: `telegram:${update.update_id}`,
73
82
  });
83
+ onEvent?.(event);
74
84
  } catch {
75
85
  /* downstream owns its failures */
76
86
  }
@@ -17,6 +17,7 @@
17
17
 
18
18
  import { createServer } from "node:http";
19
19
  import { randomBytes, timingSafeEqual } from "node:crypto";
20
+ import { EventRuntimeProducer } from "../event-runtime-producer.js";
20
21
 
21
22
  const MAX_BODY_BYTES = 64 * 1024;
22
23
 
@@ -34,7 +35,11 @@ export async function startWebhookChannel(options = {}) {
34
35
  allowlist,
35
36
  onEvent,
36
37
  log = () => {},
38
+ eventRuntimeStore = null,
37
39
  } = options;
40
+ const runtimeProducer = eventRuntimeStore
41
+ ? new EventRuntimeProducer({ store: eventRuntimeStore })
42
+ : null;
38
43
 
39
44
  const isLoopback =
40
45
  host === "127.0.0.1" || host === "::1" || host === "localhost";
@@ -92,8 +97,7 @@ export async function startWebhookChannel(options = {}) {
92
97
  return respond(403, { error: "sender not in allowlist" });
93
98
  }
94
99
  }
95
- try {
96
- onEvent?.({
100
+ const event = {
97
101
  channel: "webhook",
98
102
  sender,
99
103
  text,
@@ -101,9 +105,17 @@ export async function startWebhookChannel(options = {}) {
101
105
  payload.meta && typeof payload.meta === "object"
102
106
  ? payload.meta
103
107
  : undefined,
108
+ };
109
+ try {
110
+ runtimeProducer?.publish(event, {
111
+ origin: "webhook",
112
+ id: payload.event_id || payload.eventId || null,
104
113
  });
114
+ onEvent?.(event);
105
115
  } catch {
106
- /* the session queue owns downstream failures */
116
+ // A configured durable runtime is the recovery boundary. Refuse the
117
+ // request rather than acknowledging an event that was not persisted.
118
+ if (runtimeProducer) return respond(503, { error: "event persistence unavailable" });
107
119
  }
108
120
  respond(202, { ok: true });
109
121
  });
@@ -18,9 +18,13 @@
18
18
  * is. When it is not, callers should fall back / report unavailable.
19
19
  */
20
20
 
21
- import { spawnSync } from "node:child_process";
22
21
  import { rmSync } from "node:fs";
23
22
  import path from "node:path";
23
+ import executionBroker from "./process-execution-broker/index.js";
24
+
25
+ export const _deps = {
26
+ spawnSync: (...args) => executionBroker.spawnSync(...args),
27
+ };
24
28
 
25
29
  const REF_NS = "refs/cc-checkpoints";
26
30
  // Deterministic identity for shadow commits so `git commit-tree` never trips on
@@ -41,7 +45,11 @@ const CHECKPOINT_IDENTITY = Object.freeze({
41
45
  * @throws {Error} with git's stderr when the command fails
42
46
  */
43
47
  function git(args, { cwd, env, input } = {}) {
44
- const res = spawnSync("git", args, {
48
+ const res = _deps.spawnSync("git", args, {
49
+ origin: "checkpoint:git",
50
+ scope: "checkpoint",
51
+ policy: "allow",
52
+ shell: false,
45
53
  cwd,
46
54
  input,
47
55
  encoding: "utf-8",
@@ -26,11 +26,11 @@
26
26
  * Chrome when done. This is the same trade Claude-Code's Chrome connector
27
27
  * makes.
28
28
  */
29
- import { spawn } from "child_process";
30
29
  import fs from "fs";
31
30
  import os from "os";
32
31
  import path from "path";
33
32
  import http from "http";
33
+ import executionBroker from "./process-execution-broker/index.js";
34
34
 
35
35
  export const DEFAULT_CDP_PORT = 9222;
36
36
 
@@ -69,7 +69,7 @@ export const DEFAULT_DOM_CAP = 150000;
69
69
 
70
70
  const _deps = {
71
71
  fs,
72
- spawn,
72
+ spawn: executionBroker.spawn.bind(executionBroker),
73
73
  homedir: () => os.homedir(),
74
74
  platform: () => process.platform,
75
75
  env: () => process.env,
@@ -215,6 +215,10 @@ export function launchChrome(opts = {}) {
215
215
  detached: true,
216
216
  stdio: "ignore",
217
217
  windowsHide: false,
218
+ origin: "chrome-connector:launch",
219
+ policy: "allow",
220
+ scope: "browser",
221
+ shell: false,
218
222
  });
219
223
  child.unref();
220
224
  return { ok: true, executable, args, pid: child.pid };
@@ -13,11 +13,14 @@
13
13
  * ], { cwd: "/path/to/project" });
14
14
  */
15
15
 
16
- import { spawn, execSync } from "child_process";
17
16
  import { EventEmitter } from "events";
17
+ import executionBroker from "./process-execution-broker/index.js";
18
18
 
19
19
  /* ---------- _deps injection (Vitest CJS mock pattern) ---------- */
20
- export const _deps = { spawn, execSync };
20
+ export const _deps = {
21
+ spawn: executionBroker.spawn.bind(executionBroker),
22
+ execSync: executionBroker.execSync.bind(executionBroker),
23
+ };
21
24
 
22
25
  // ─── Agent status constants ───────────────────────────────────────
23
26
 
@@ -36,6 +39,19 @@ export const AGENT_STATUS = {
36
39
  // only thing _parseStreamJson needs — is at the end.
37
40
  export const MAX_AGENT_OUTPUT_BYTES = 32 * 1024 * 1024;
38
41
 
42
+ function detectCliVersion(command) {
43
+ return _deps
44
+ .execSync(`${command} --version`, {
45
+ encoding: "utf-8",
46
+ timeout: 5000,
47
+ origin: `claude-code-bridge:detect-${command}`,
48
+ policy: "allow",
49
+ scope: "orchestrator",
50
+ shell: true,
51
+ })
52
+ .trim();
53
+ }
54
+
39
55
  // ─── Detection ───────────────────────────────────────────────────
40
56
 
41
57
  /**
@@ -44,9 +60,7 @@ export const MAX_AGENT_OUTPUT_BYTES = 32 * 1024 * 1024;
44
60
  */
45
61
  export function detectClaudeCode() {
46
62
  try {
47
- const version = _deps
48
- .execSync("claude --version", { encoding: "utf-8", timeout: 5000 })
49
- .trim();
63
+ const version = detectCliVersion("claude");
50
64
  return { found: true, version };
51
65
  } catch (_err) {
52
66
  return { found: false };
@@ -59,9 +73,7 @@ export function detectClaudeCode() {
59
73
  */
60
74
  export function detectCodex() {
61
75
  try {
62
- const version = _deps
63
- .execSync("codex --version", { encoding: "utf-8", timeout: 5000 })
64
- .trim();
76
+ const version = detectCliVersion("codex");
65
77
  return { found: true, version };
66
78
  } catch (_err) {
67
79
  return { found: false };
@@ -152,6 +164,10 @@ export class ClaudeCodeAgent extends EventEmitter {
152
164
  cwd,
153
165
  env: { ...process.env },
154
166
  windowsHide: true,
167
+ origin: "claude-code-bridge:agent",
168
+ policy: "allow",
169
+ scope: "orchestrator",
170
+ shell: false,
155
171
  });
156
172
  this._proc = proc;
157
173
 
@@ -8,13 +8,27 @@
8
8
  * that the existing 4-layer skill-loader picks up automatically.
9
9
  */
10
10
 
11
- import { execSync } from "child_process";
12
11
  import fs from "fs";
13
12
  import path from "path";
14
13
  import { getElectronUserDataDir } from "./paths.js";
14
+ import executionBroker from "./process-execution-broker/index.js";
15
15
 
16
16
  /* ---------- _deps injection (Vitest CJS mock pattern) ---------- */
17
- export const _deps = { execSync, fs, path };
17
+ export const _deps = {
18
+ execFileSync: executionBroker.execFileSync.bind(executionBroker),
19
+ fs,
20
+ path,
21
+ };
22
+
23
+ function execCliAnything(file, args, options, origin) {
24
+ return _deps.execFileSync(file, args, {
25
+ ...options,
26
+ origin,
27
+ policy: "allow",
28
+ scope: "cli-anything",
29
+ shell: false,
30
+ });
31
+ }
18
32
 
19
33
  /* ----------------------------------------------------------------
20
34
  * Database helpers
@@ -55,13 +69,16 @@ export function detectPython() {
55
69
 
56
70
  for (const cmd of candidates) {
57
71
  try {
58
- const ver = _deps
59
- .execSync(`${cmd} --version`, {
72
+ const ver = execCliAnything(
73
+ cmd,
74
+ ["--version"],
75
+ {
60
76
  encoding: "utf-8",
61
77
  timeout: 10000,
62
78
  stdio: ["pipe", "pipe", "pipe"],
63
- })
64
- .trim();
79
+ },
80
+ "cli-anything:detect-python",
81
+ ).trim();
65
82
  const match = ver.match(/Python\s+([\d.]+)/i);
66
83
  if (match) {
67
84
  return { found: true, command: cmd, version: match[1] };
@@ -82,11 +99,16 @@ export function detectCliAnything() {
82
99
  if (!py.found) return { installed: false };
83
100
 
84
101
  try {
85
- const out = _deps.execSync(`${py.command} -m pip show cli-anything`, {
86
- encoding: "utf-8",
87
- timeout: 15000,
88
- stdio: ["pipe", "pipe", "pipe"],
89
- });
102
+ const out = execCliAnything(
103
+ py.command,
104
+ ["-m", "pip", "show", "cli-anything"],
105
+ {
106
+ encoding: "utf-8",
107
+ timeout: 15000,
108
+ stdio: ["pipe", "pipe", "pipe"],
109
+ },
110
+ "cli-anything:detect-package",
111
+ );
90
112
  const verMatch = out.match(/Version:\s*([\d.]+)/i);
91
113
  return {
92
114
  installed: true,
@@ -102,11 +124,16 @@ export function detectCliAnything() {
102
124
  * Install CLI-Anything via pip.
103
125
  */
104
126
  export function installCliAnything(pythonCmd) {
105
- _deps.execSync(`${pythonCmd} -m pip install cli-anything`, {
106
- encoding: "utf-8",
107
- timeout: 120000,
108
- stdio: "inherit",
109
- });
127
+ execCliAnything(
128
+ pythonCmd,
129
+ ["-m", "pip", "install", "cli-anything"],
130
+ {
131
+ encoding: "utf-8",
132
+ timeout: 120000,
133
+ stdio: "inherit",
134
+ },
135
+ "cli-anything:install",
136
+ );
110
137
  }
111
138
 
112
139
  /* ----------------------------------------------------------------
@@ -152,11 +179,16 @@ export function scanPathForTools() {
152
179
  export function parseToolHelp(command) {
153
180
  let helpText;
154
181
  try {
155
- helpText = _deps.execSync(`${command} --help`, {
156
- encoding: "utf-8",
157
- timeout: 15000,
158
- stdio: ["pipe", "pipe", "pipe"],
159
- });
182
+ helpText = execCliAnything(
183
+ command,
184
+ ["--help"],
185
+ {
186
+ encoding: "utf-8",
187
+ timeout: 15000,
188
+ stdio: ["pipe", "pipe", "pipe"],
189
+ },
190
+ "cli-anything:tool-help",
191
+ );
160
192
  } catch (err) {
161
193
  const raw = err.stdout || err.stderr || "";
162
194
  helpText = typeof raw === "string" ? raw : raw.toString("utf-8");
@@ -252,19 +284,44 @@ Pass the subcommand and arguments as plain text input:
252
284
  */
253
285
  export function _generateHandlerJs(name, command) {
254
286
  return `"use strict";
255
- const { execSync } = require("child_process");
287
+ const CLI_COMMAND = ${JSON.stringify(command)};
288
+
289
+ function parseArgs(input) {
290
+ const args = [];
291
+ let current = "";
292
+ let inSingle = false;
293
+ let inDouble = false;
294
+ for (const ch of input.trim()) {
295
+ if (ch === "'" && !inDouble) { inSingle = !inSingle; continue; }
296
+ if (ch === '"' && !inSingle) { inDouble = !inDouble; continue; }
297
+ if (/\\s/.test(ch) && !inSingle && !inDouble) {
298
+ if (current) { args.push(current); current = ""; }
299
+ continue;
300
+ }
301
+ current += ch;
302
+ }
303
+ if (inSingle || inDouble) return null;
304
+ if (current) args.push(current);
305
+ return args;
306
+ }
256
307
 
257
308
  module.exports = {
258
309
  async execute(task, context) {
259
310
  const input = (task?.params?.input || task?.action || "").trim();
260
311
  if (!input) return { success: false, error: "No input provided" };
261
- // Security: input is interpolated into a shell command, so reject shell
262
- // metacharacters to prevent command injection from untrusted skill input.
312
+ // Keep the historical shell-character guard for generated-handler
313
+ // compatibility even though the Broker now receives literal argv.
263
314
  if (/[;&|\`$<>()\\n\\r]/.test(input)) {
264
315
  return { success: false, error: "Input contains unsafe shell characters; refused." };
265
316
  }
317
+ const args = parseArgs(input);
318
+ if (!args) return { success: false, error: "Input contains an unmatched quote; refused." };
319
+ const processBroker = context?.processBroker;
320
+ if (!processBroker || typeof processBroker.runFileSync !== "function") {
321
+ return { success: false, error: "Process Broker unavailable for skill execution." };
322
+ }
266
323
  try {
267
- const output = execSync(\`${command} \${input}\`, {
324
+ const output = processBroker.runFileSync(CLI_COMMAND, args, {
268
325
  encoding: "utf-8",
269
326
  timeout: 60000,
270
327
  cwd: context?.projectRoot || process.cwd(),
@@ -7,13 +7,23 @@
7
7
  * a repo.
8
8
  */
9
9
 
10
- import { execFileSync } from "node:child_process";
11
10
  import { writeFileSync, mkdtempSync } from "node:fs";
12
11
  import { readFileSync, rmSync } from "node:fs";
13
12
  import { join } from "node:path";
14
13
  import { tmpdir } from "node:os";
14
+ import { executionBroker } from "../process-execution-broker/index.js";
15
15
 
16
- export const _deps = { execFileSync };
16
+ function brokerExecFileSync(file, args, options) {
17
+ return executionBroker.execFileSync(file, args, {
18
+ ...options,
19
+ origin: "cloud:git",
20
+ policy: "allow",
21
+ scope: "cloud",
22
+ shell: false,
23
+ });
24
+ }
25
+
26
+ export const _deps = { execFileSync: brokerExecFileSync };
17
27
 
18
28
  function git(args, cwd, deps = _deps) {
19
29
  return deps
@@ -4,8 +4,37 @@
4
4
  * @module lib/code-review
5
5
  */
6
6
 
7
- import { execSync } from "child_process";
8
7
  import { logger } from "./logger.js";
8
+ import { executionBroker } from "./process-execution-broker/index.js";
9
+
10
+ export const _deps = {
11
+ execFileSync: (...args) => executionBroker.execFileSync(...args),
12
+ };
13
+
14
+ export function buildGitDiffArgs(
15
+ target = "--staged",
16
+ { nameOnly = false } = {},
17
+ ) {
18
+ const args = ["diff"];
19
+ if (nameOnly) args.push("--name-only");
20
+ if (target === "--staged" || target === "--cached") {
21
+ args.push(target);
22
+ } else {
23
+ args.push("--end-of-options", String(target), "--");
24
+ }
25
+ return args;
26
+ }
27
+
28
+ function gitDiff(target, options = {}) {
29
+ return _deps.execFileSync("git", buildGitDiffArgs(target, options), {
30
+ encoding: "utf8",
31
+ maxBuffer: 10 * 1024 * 1024,
32
+ origin: "review:git-diff",
33
+ policy: "allow",
34
+ scope: "review",
35
+ shell: false,
36
+ });
37
+ }
9
38
 
10
39
  /**
11
40
  * Get git diff for review
@@ -14,10 +43,7 @@ import { logger } from "./logger.js";
14
43
  */
15
44
  export function getGitDiff(target = "--staged") {
16
45
  try {
17
- return execSync(`git diff ${target}`, {
18
- encoding: "utf8",
19
- maxBuffer: 10 * 1024 * 1024,
20
- });
46
+ return gitDiff(target);
21
47
  } catch (err) {
22
48
  logger.error(`Failed to get git diff: ${err.message}`);
23
49
  return "";
@@ -31,9 +57,7 @@ export function getGitDiff(target = "--staged") {
31
57
  */
32
58
  export function getChangedFiles(target = "--staged") {
33
59
  try {
34
- const output = execSync(`git diff ${target} --name-only`, {
35
- encoding: "utf8",
36
- });
60
+ const output = gitDiff(target, { nameOnly: true });
37
61
  return output.trim().split("\n").filter(Boolean);
38
62
  } catch (err) {
39
63
  logger.error(`Failed to get changed files: ${err.message}`);
@@ -7,16 +7,27 @@
7
7
  * project's U-Key/hardware posture.
8
8
  */
9
9
 
10
- import { spawnSync } from "node:child_process";
10
+ import executionBroker from "../process-execution-broker/index.js";
11
11
 
12
- export const _deps = { spawnSync, platform: () => process.platform };
12
+ export const _deps = {
13
+ spawnSync: (...args) => executionBroker.spawnSync(...args),
14
+ platform: () => process.platform,
15
+ };
13
16
 
14
17
  /** Run a PowerShell script, returning { ok, stdout, stderr }. */
15
18
  function runPowerShell(script, deps = _deps) {
16
19
  const res = deps.spawnSync(
17
20
  "powershell.exe",
18
21
  ["-NoProfile", "-NonInteractive", "-Command", script],
19
- { encoding: "utf-8", windowsHide: true, maxBuffer: 16 * 1024 * 1024 },
22
+ {
23
+ encoding: "utf-8",
24
+ windowsHide: true,
25
+ maxBuffer: 16 * 1024 * 1024,
26
+ origin: "computer-use:powershell",
27
+ scope: "computer-use",
28
+ policy: "allow",
29
+ shell: false,
30
+ },
20
31
  );
21
32
  if (res.error) return { ok: false, stdout: "", stderr: res.error.message };
22
33
  return {
@@ -140,6 +151,10 @@ export function createWindowsBackend(deps = _deps) {
140
151
  windowsHide: false,
141
152
  detached: true,
142
153
  stdio: "ignore",
154
+ origin: "computer-use:app-launch",
155
+ scope: "computer-use",
156
+ policy: "allow",
157
+ shell: false,
143
158
  });
144
159
  return res.error
145
160
  ? { ok: false, error: res.error.message }