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
@@ -18,7 +18,6 @@
18
18
  * stop; else re-arm for the next interval
19
19
  */
20
20
 
21
- import { spawn, execSync } from "node:child_process";
22
21
  import { readFileSync, statSync } from "node:fs";
23
22
  import { fileURLToPath } from "node:url";
24
23
  import chalk from "chalk";
@@ -27,6 +26,12 @@ import { sendAgentNotification } from "../lib/agent-notify.js";
27
26
  import { nextWakeupAt, partitionSchedule } from "../lib/schedule-planner.js";
28
27
  import { monitorEventEnvelope, capEventPayload } from "../lib/monitor-event.js";
29
28
  import { unattendedDisallowedTools } from "../lib/unattended-action-policy.js";
29
+ import executionBroker from "../lib/process-execution-broker/index.js";
30
+
31
+ export const _processDeps = {
32
+ spawn: (...args) => executionBroker.spawn(...args),
33
+ execSync: (...args) => executionBroker.execSync(...args),
34
+ };
30
35
 
31
36
  const BIN_PATH = fileURLToPath(
32
37
  new URL("../../bin/chainlesschain.js", import.meta.url),
@@ -53,8 +58,14 @@ export function registerAgendaCommand(program) {
53
58
  .description("Fire every entry that is due now")
54
59
  .option("--dry-run", "Show what would fire without running anything")
55
60
  .option("--json", "Machine-readable JSON output")
61
+ .option(
62
+ "--watch <seconds>",
63
+ "Keep running as a resident scheduler and poll at this interval",
64
+ )
56
65
  .action(async (options) => {
57
- process.exitCode = await runAgendaRun(options);
66
+ process.exitCode = options.watch
67
+ ? await runAgendaDaemon(options)
68
+ : await runAgendaRun(options);
58
69
  });
59
70
 
60
71
  cmd
@@ -219,7 +230,11 @@ export async function runAgendaRun(options = {}, _deps = {}) {
219
230
  const retired = options.dryRun
220
231
  ? partitionSchedule(store.list(), { now }).expired
221
232
  : store.retireExpired(now);
222
- const due = store.due(null, now);
233
+ const due = options.dryRun
234
+ ? store.due(null, now)
235
+ : typeof store.claimDue === "function"
236
+ ? store.claimDue(now, options.leaseMs)
237
+ : store.due(null, now);
223
238
  const actions = [];
224
239
 
225
240
  for (const entry of due) {
@@ -337,6 +352,7 @@ export async function runAgendaRun(options = {}, _deps = {}) {
337
352
  }
338
353
  }
339
354
  } catch (err) {
355
+ store.releaseClaim?.(entry.id);
340
356
  actions.push({
341
357
  id: entry.id,
342
358
  kind: entry.kind,
@@ -373,6 +389,52 @@ export async function runAgendaRun(options = {}, _deps = {}) {
373
389
  return actions.some((a) => a.action === "error") ? 1 : 0;
374
390
  }
375
391
 
392
+ /**
393
+ * Resident scheduler loop for `cc agenda run --watch <seconds>`.
394
+ *
395
+ * The store remains the source of truth: every tick re-reads durable entries,
396
+ * retires expired work, and claims due entries through the same lease path as
397
+ * one-shot execution. A signal or injected AbortSignal stops after the current
398
+ * tick; `maxTicks` is intentionally supported for deterministic tests.
399
+ */
400
+ export async function runAgendaDaemon(options = {}, _deps = {}) {
401
+ const intervalSeconds = Number(options.watch);
402
+ const intervalMs = Math.max(
403
+ 250,
404
+ Number.isFinite(intervalSeconds) && intervalSeconds > 0
405
+ ? intervalSeconds * 1000
406
+ : 60000,
407
+ );
408
+ const signal = options.signal || _deps.signal || null;
409
+ const runOnce = _deps.runOnce || ((next) => runAgendaRun(next, _deps));
410
+ const sleep =
411
+ _deps.sleep || ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
412
+ let stopped = Boolean(signal?.aborted);
413
+ let lastCode = 0;
414
+ let ticks = 0;
415
+ const stop = () => {
416
+ stopped = true;
417
+ };
418
+ const onAbort = () => stop();
419
+ signal?.addEventListener?.("abort", onAbort, { once: true });
420
+ const onSignal = () => stop();
421
+ process.once("SIGINT", onSignal);
422
+ process.once("SIGTERM", onSignal);
423
+ try {
424
+ while (!stopped) {
425
+ lastCode = Math.max(lastCode, await runOnce({ ...options, watch: null }));
426
+ ticks += 1;
427
+ if (Number.isFinite(_deps.maxTicks) && ticks >= _deps.maxTicks) break;
428
+ await sleep(intervalMs);
429
+ }
430
+ } finally {
431
+ signal?.removeEventListener?.("abort", onAbort);
432
+ process.removeListener("SIGINT", onSignal);
433
+ process.removeListener("SIGTERM", onSignal);
434
+ }
435
+ return lastCode;
436
+ }
437
+
376
438
  // ─── default effectful deps (overridable in tests) ─────────────────────────
377
439
 
378
440
  /**
@@ -397,6 +459,14 @@ export function buildAgentArgs(prompt, policy = null) {
397
459
  if (disallow.length > 0) {
398
460
  args.push("--disallowed-tools", disallow.join(","));
399
461
  }
462
+ args.push("--unattended");
463
+ if (
464
+ policy &&
465
+ Array.isArray(policy.unattendedAllowlist) &&
466
+ policy.unattendedAllowlist.length > 0
467
+ ) {
468
+ args.push("--unattended-allow", policy.unattendedAllowlist.join(","));
469
+ }
400
470
  if (policy && typeof policy === "object") {
401
471
  if (
402
472
  typeof policy.permissionMode === "string" &&
@@ -432,13 +502,17 @@ export function buildAgentArgs(prompt, policy = null) {
432
502
 
433
503
  function defaultSpawnAgent(prompt, policy = null) {
434
504
  return new Promise((resolve, reject) => {
435
- const child = spawn(
505
+ const child = _processDeps.spawn(
436
506
  process.execPath,
437
507
  [BIN_PATH, ...buildAgentArgs(prompt, policy)],
438
508
  {
439
509
  stdio: "ignore",
440
510
  detached: false,
441
511
  env: process.env,
512
+ origin: "agenda:agent-run",
513
+ policy: "allow",
514
+ scope: "agenda",
515
+ shell: false,
442
516
  },
443
517
  );
444
518
  child.on("error", reject);
@@ -452,10 +526,14 @@ function defaultSpawnAgent(prompt, policy = null) {
452
526
 
453
527
  function defaultRunCommand(command) {
454
528
  try {
455
- return execSync(command, {
529
+ return _processDeps.execSync(command, {
456
530
  encoding: "utf-8",
457
531
  stdio: ["ignore", "pipe", "pipe"],
458
532
  timeout: 60000,
533
+ origin: "agenda:monitor-command",
534
+ policy: "allow",
535
+ scope: "agenda",
536
+ shell: true,
459
537
  });
460
538
  } catch (err) {
461
539
  // A non-zero exit still yields output we want to match against.
@@ -195,6 +195,14 @@ export function registerAgentCommand(program) {
195
195
  "--worktree",
196
196
  "Run this session in a fresh git worktree (isolated branch; auto-removed when the session changes nothing)",
197
197
  )
198
+ .option(
199
+ "--unattended",
200
+ "Enable fail-closed shell action policy for scheduled/event-driven runs",
201
+ )
202
+ .option(
203
+ "--unattended-allow <classes>",
204
+ "Comma-separated action classes explicitly allowed for unattended shell runs",
205
+ )
198
206
  .option(
199
207
  "--sandbox [image]",
200
208
  "Run shell commands in an ephemeral Docker sandbox (network disabled by default)",
@@ -422,6 +430,21 @@ export function registerAgentCommand(program) {
422
430
  console.log(JSON.stringify(buildAgentCapabilities(), null, 2));
423
431
  return;
424
432
  }
433
+ let toolAdmission = null;
434
+ if (process.env.CC_TOOL_ADMISSION) {
435
+ try {
436
+ const { parseToolAdmissionConfig } =
437
+ await import("../lib/agent-tool-admission.js");
438
+ toolAdmission = parseToolAdmissionConfig(
439
+ process.env.CC_TOOL_ADMISSION,
440
+ );
441
+ } catch (error) {
442
+ process.stderr.write(
443
+ `CC_TOOL_ADMISSION: ${error.message}; refusing an ungoverned session.\n`,
444
+ );
445
+ process.exit(6);
446
+ }
447
+ }
425
448
  // CC_API_KEY env fallback for --api-key: lets callers (IDE plugins,
426
449
  // scripts) pass the key via the environment instead of argv, where it
427
450
  // is visible to every local process (/proc/<pid>/cmdline, Win32_Process).
@@ -536,7 +559,7 @@ export function registerAgentCommand(program) {
536
559
  _worktreeSettingsHooks =
537
560
  loadHooks({ cwd: _worktree.repoRoot }).hooks || null;
538
561
  const { runWorktreeCreateHooks, dispatchAsyncHooks } =
539
- await import("../lib/settings-hook-events.cjs");
562
+ await import("../lib/settings-hook-events.js");
540
563
  runWorktreeCreateHooks(_worktreeSettingsHooks, {
541
564
  worktreePath: _worktree.path,
542
565
  branch: _worktree.branch,
@@ -545,7 +568,7 @@ export function registerAgentCommand(program) {
545
568
  });
546
569
  if (!_worktreeAsyncSupervisor) {
547
570
  const { AsyncHookSupervisor } =
548
- await import("../lib/async-hook-supervisor.cjs");
571
+ await import("../lib/async-hook-supervisor.js");
549
572
  _worktreeAsyncSupervisor = new AsyncHookSupervisor({
550
573
  persistStats: true,
551
574
  });
@@ -606,7 +629,7 @@ export function registerAgentCommand(program) {
606
629
  if (_worktreeSettingsHooks) {
607
630
  try {
608
631
  const { runWorktreeRemoveHooks, dispatchAsyncHooks } =
609
- await import("../lib/settings-hook-events.cjs");
632
+ await import("../lib/settings-hook-events.js");
610
633
  runWorktreeRemoveHooks(_worktreeSettingsHooks, {
611
634
  worktreePath: _worktree.path,
612
635
  branch: _worktree.branch,
@@ -754,6 +777,16 @@ export function registerAgentCommand(program) {
754
777
  await import("../lib/settings-loader.cjs");
755
778
  const sc = loadSettingsConfig({
756
779
  cwd: process.cwd(),
780
+ unattendedActionPolicy: options.unattended
781
+ ? {
782
+ unattended: true,
783
+ allowlist: String(options.unattendedAllow || "")
784
+ .split(",")
785
+ .map((value) => value.trim())
786
+ .filter(Boolean),
787
+ trigger: { trusted: true },
788
+ }
789
+ : null,
757
790
  settingsFile: options.settings || null,
758
791
  });
759
792
  for (const [k, v] of Object.entries(sc.env || {})) {
@@ -997,7 +1030,11 @@ export function registerAgentCommand(program) {
997
1030
  jsonSchema: options.jsonSchema || null,
998
1031
  });
999
1032
  } catch (err) {
1000
- process.stderr.write(`Error: ${err.message}\n`);
1033
+ process.stderr.write(
1034
+ process.env.CC_DEBUG && err?.stack
1035
+ ? `${err.stack}\n`
1036
+ : `Error: ${err.message}\n`,
1037
+ );
1001
1038
  await _finishWorktree();
1002
1039
  process.exit(1);
1003
1040
  }
@@ -1168,6 +1205,7 @@ export function registerAgentCommand(program) {
1168
1205
  baseUrl: visionLlm.baseUrl || options.baseUrl,
1169
1206
  apiKey: visionLlm.apiKey || options.apiKey,
1170
1207
  sessionId: options.session,
1208
+ toolAdmission,
1171
1209
  // A resolved --session/--continue/--resume id means "replay this
1172
1210
  // conversation and persist the new turns"; the runner loads prior
1173
1211
  // history when the id already exists and creates it otherwise.
@@ -2,6 +2,7 @@ import { existsSync, readFileSync } from "node:fs";
2
2
  import chalk from "chalk";
3
3
  import { logger } from "../lib/logger.js";
4
4
  import { readPrLinkLedger } from "../lib/pr-link-ledger.js";
5
+ import executionBroker from "../lib/process-execution-broker/index.js";
5
6
 
6
7
  function formatAge(ms) {
7
8
  const n = Math.max(0, Math.round(Number(ms || 0) / 1000));
@@ -460,7 +461,6 @@ async function runDashboardView(options = {}) {
460
461
 
461
462
  const { runBgDashboard } = await import("../repl/bg-dashboard.js");
462
463
  const { fileURLToPath } = await import("node:url");
463
- const { spawn } = await import("node:child_process");
464
464
  const BIN_PATH = fileURLToPath(
465
465
  new URL("../../bin/chainlesschain.js", import.meta.url),
466
466
  );
@@ -524,10 +524,18 @@ async function runDashboardView(options = {}) {
524
524
  await followBackgroundAgent(session.id, { lines: 40 });
525
525
  },
526
526
  dispatchAgent: async (text) => {
527
- const child = spawn(
527
+ const child = executionBroker.spawn(
528
528
  process.execPath,
529
529
  [BIN_PATH, "agent", "--bg", "-p", text],
530
- { detached: true, stdio: "ignore", windowsHide: true },
530
+ {
531
+ detached: true,
532
+ stdio: "ignore",
533
+ windowsHide: true,
534
+ origin: "background-session:dispatch",
535
+ policy: "allow",
536
+ scope: "background-session",
537
+ shell: false,
538
+ },
531
539
  );
532
540
  child.unref();
533
541
  return null; // id is minted by the launcher; the next refresh shows it
@@ -794,4 +802,3 @@ export function registerBackgroundSessionCommands(program) {
794
802
  }
795
803
  });
796
804
  }
797
-
@@ -19,8 +19,6 @@
19
19
  import fs from "fs";
20
20
  import path from "path";
21
21
  import { fileURLToPath } from "url";
22
- import { spawn } from "child_process";
23
- import { execFileSync } from "child_process";
24
22
  import chalk from "chalk";
25
23
  import { logger } from "../lib/logger.js";
26
24
  import { runBatch } from "../lib/agent-batch.js";
@@ -31,6 +29,12 @@ import {
31
29
  mergeWorktree,
32
30
  } from "../harness/worktree-isolator.js";
33
31
  import { findProjectRoot } from "../lib/project-detector.js";
32
+ import executionBroker from "../lib/process-execution-broker/index.js";
33
+
34
+ export const _processDeps = {
35
+ spawn: executionBroker.spawn.bind(executionBroker),
36
+ execFileSync: executionBroker.execFileSync.bind(executionBroker),
37
+ };
34
38
 
35
39
  const BIN = path.resolve(
36
40
  path.dirname(fileURLToPath(import.meta.url)),
@@ -183,6 +187,26 @@ function sanitize(key) {
183
187
  return String(key).replace(/[^a-zA-Z0-9._-]/g, "-");
184
188
  }
185
189
 
190
+ function spawnBatchProcess(command, args, options, origin) {
191
+ return _processDeps.spawn(command, args, {
192
+ ...options,
193
+ origin,
194
+ policy: "allow",
195
+ scope: "batch",
196
+ });
197
+ }
198
+
199
+ function runBatchGit(args, cwd, options, origin) {
200
+ return _processDeps.execFileSync("git", args, {
201
+ ...options,
202
+ cwd,
203
+ origin,
204
+ policy: "allow",
205
+ scope: "batch",
206
+ shell: false,
207
+ });
208
+ }
209
+
186
210
  function spawnAgent(prompt, cwd, opts = {}) {
187
211
  return new Promise((resolve, reject) => {
188
212
  const args = [
@@ -196,11 +220,17 @@ function spawnAgent(prompt, cwd, opts = {}) {
196
220
  "text",
197
221
  ];
198
222
  if (opts.model) args.push("--model", opts.model);
199
- const child = spawn(process.execPath, args, {
200
- cwd,
201
- env: { ...process.env, CLAUDECODE: "1" },
202
- windowsHide: true,
203
- });
223
+ const child = spawnBatchProcess(
224
+ process.execPath,
225
+ args,
226
+ {
227
+ cwd,
228
+ env: { ...process.env, CLAUDECODE: "1" },
229
+ windowsHide: true,
230
+ shell: false,
231
+ },
232
+ "batch:agent-run",
233
+ );
204
234
  let err = "";
205
235
  child.stderr?.on("data", (d) => (err += d.toString("utf8")));
206
236
  child.on("error", (e) => reject(new Error(e.message)));
@@ -214,12 +244,17 @@ function spawnAgent(prompt, cwd, opts = {}) {
214
244
 
215
245
  function runTestCommand(command, cwd) {
216
246
  return new Promise((resolve, reject) => {
217
- const child = spawn(command, {
218
- cwd,
219
- shell: true,
220
- env: process.env,
221
- windowsHide: true,
222
- });
247
+ const child = spawnBatchProcess(
248
+ command,
249
+ [],
250
+ {
251
+ cwd,
252
+ shell: true,
253
+ env: process.env,
254
+ windowsHide: true,
255
+ },
256
+ "batch:test-command",
257
+ );
223
258
  let err = "";
224
259
  child.stderr?.on("data", (d) => (err += d.toString("utf8")));
225
260
  child.on("error", (e) => reject(new Error(e.message)));
@@ -234,11 +269,13 @@ function runTestCommand(command, cwd) {
234
269
  /** `git add -A` staged numstat totals for a worktree. */
235
270
  function gitDiffStat(cwd) {
236
271
  try {
237
- execFileSync("git", ["add", "-A"], { cwd, stdio: "ignore" });
238
- const out = execFileSync("git", ["diff", "--cached", "--numstat"], {
272
+ runBatchGit(["add", "-A"], cwd, { stdio: "ignore" }, "batch:git-diff");
273
+ const out = runBatchGit(
274
+ ["diff", "--cached", "--numstat"],
239
275
  cwd,
240
- encoding: "utf8",
241
- });
276
+ { encoding: "utf8" },
277
+ "batch:git-diff",
278
+ );
242
279
  let insertions = 0;
243
280
  let deletions = 0;
244
281
  let filesChanged = 0;
@@ -258,11 +295,13 @@ function gitDiffStat(cwd) {
258
295
 
259
296
  function gitCommitAll(cwd, message) {
260
297
  try {
261
- execFileSync("git", ["add", "-A"], { cwd, stdio: "ignore" });
262
- execFileSync("git", ["commit", "-m", message, "--no-verify"], {
298
+ runBatchGit(["add", "-A"], cwd, { stdio: "ignore" }, "batch:git-commit");
299
+ runBatchGit(
300
+ ["commit", "-m", message, "--no-verify"],
263
301
  cwd,
264
- stdio: "ignore",
265
- });
302
+ { stdio: "ignore" },
303
+ "batch:git-commit",
304
+ );
266
305
  return true;
267
306
  } catch {
268
307
  return false; // nothing to commit / commit failed
@@ -289,11 +328,17 @@ async function decomposeGoal(goal, parts, opts = {}) {
289
328
  "plan",
290
329
  ];
291
330
  if (opts.model) args.push("--model", opts.model);
292
- const child = spawn(process.execPath, args, {
293
- cwd: opts.repoDir || process.cwd(),
294
- env: { ...process.env, CLAUDECODE: "1" },
295
- windowsHide: true,
296
- });
331
+ const child = spawnBatchProcess(
332
+ process.execPath,
333
+ args,
334
+ {
335
+ cwd: opts.repoDir || process.cwd(),
336
+ env: { ...process.env, CLAUDECODE: "1" },
337
+ windowsHide: true,
338
+ shell: false,
339
+ },
340
+ "batch:decompose",
341
+ );
297
342
  let out = "";
298
343
  let err = "";
299
344
  child.stdout?.on("data", (d) => (out += d.toString("utf8")));
@@ -342,4 +387,11 @@ function formatEvent(ev) {
342
387
  }
343
388
  }
344
389
 
345
- export const _internal = { decomposeGoal, gitDiffStat, DECOMPOSE_SCHEMA };
390
+ export const _internal = {
391
+ decomposeGoal,
392
+ gitDiffStat,
393
+ gitCommitAll,
394
+ runTestCommand,
395
+ spawnAgent,
396
+ DECOMPOSE_SCHEMA,
397
+ };
@@ -1,6 +1,6 @@
1
1
  import chalk from "chalk";
2
2
  import { VERSION } from "../constants.js";
3
- import { loadChangelog } from "../lib/changelog.js";
3
+ import { latestCliVersion, loadChangelog } from "../lib/changelog.js";
4
4
  import logger from "../lib/logger.js";
5
5
 
6
6
  /**
@@ -82,10 +82,21 @@ export function registerChangelogCommand(program) {
82
82
  .action((version, options) => {
83
83
  const data = loadChangelog();
84
84
  const releases = data.releases || [];
85
+ const jsonPayload = (selected) =>
86
+ JSON.stringify(
87
+ {
88
+ ...data,
89
+ installedVersion: VERSION,
90
+ latestDocumentedVersion: latestCliVersion(releases),
91
+ releases: selected,
92
+ },
93
+ null,
94
+ 2,
95
+ );
85
96
 
86
97
  if (releases.length === 0) {
87
98
  if (options.json) {
88
- logger.log(JSON.stringify({ releases: [] }, null, 2));
99
+ logger.log(jsonPayload([]));
89
100
  } else {
90
101
  logger.warn("No changelog data is bundled with this build.");
91
102
  }
@@ -97,7 +108,7 @@ export function registerChangelogCommand(program) {
97
108
  selected = matchVersion(releases, version);
98
109
  if (selected.length === 0) {
99
110
  if (options.json) {
100
- logger.log(JSON.stringify({ releases: [] }, null, 2));
111
+ logger.log(jsonPayload([]));
101
112
  } else {
102
113
  logger.warn(`No CLI release notes found for "${version}".`);
103
114
  logger.info(
@@ -114,7 +125,7 @@ export function registerChangelogCommand(program) {
114
125
  }
115
126
 
116
127
  if (options.json) {
117
- logger.log(JSON.stringify({ ...data, releases: selected }, null, 2));
128
+ logger.log(jsonPayload(selected));
118
129
  return;
119
130
  }
120
131
 
@@ -9,6 +9,75 @@ import {
9
9
  import { getConfigPath } from "../lib/paths.js";
10
10
  import logger from "../lib/logger.js";
11
11
  import { listFeatures, setFeature, getFlagInfo } from "../lib/feature-flags.js";
12
+ import { executionBroker } from "../lib/process-execution-broker/index.js";
13
+
14
+ export const _deps = {
15
+ spawnSync: (...args) => executionBroker.spawnSync(...args),
16
+ };
17
+
18
+ /** Parse the conventional $EDITOR string without invoking a shell. */
19
+ export function parseEditorCommand(value) {
20
+ const input = String(value || "").trim();
21
+ if (!input) return [];
22
+ const tokens = [];
23
+ let token = "";
24
+ let quote = null;
25
+ let started = false;
26
+ for (let index = 0; index < input.length; index += 1) {
27
+ const char = input[index];
28
+ if (quote) {
29
+ if (char === quote) {
30
+ quote = null;
31
+ started = true;
32
+ } else if (char === "\\" && input[index + 1] === quote) {
33
+ token += quote;
34
+ index += 1;
35
+ } else {
36
+ token += char;
37
+ }
38
+ continue;
39
+ }
40
+ if (char === '"' || char === "'") {
41
+ quote = char;
42
+ started = true;
43
+ continue;
44
+ }
45
+ if (/\s/.test(char)) {
46
+ if (started || token) {
47
+ tokens.push(token);
48
+ token = "";
49
+ started = false;
50
+ }
51
+ continue;
52
+ }
53
+ if (
54
+ char === "\\" &&
55
+ (input[index + 1] === '"' || input[index + 1] === "'")
56
+ ) {
57
+ token += input[index + 1];
58
+ index += 1;
59
+ started = true;
60
+ continue;
61
+ }
62
+ token += char;
63
+ started = true;
64
+ }
65
+ if (quote) throw new Error("EDITOR contains an unterminated quote");
66
+ if (started || token) tokens.push(token);
67
+ return tokens;
68
+ }
69
+
70
+ export function openConfigEditor(editor, configPath, deps = _deps) {
71
+ const [file, ...editorArgs] = parseEditorCommand(editor);
72
+ if (!file) throw new Error("EDITOR command is empty");
73
+ return deps.spawnSync(file, [...editorArgs, configPath], {
74
+ stdio: "inherit",
75
+ origin: "config:editor",
76
+ policy: "allow",
77
+ scope: "config",
78
+ shell: false,
79
+ });
80
+ }
12
81
 
13
82
  export function registerConfigCommand(program) {
14
83
  const cmd = program
@@ -109,12 +178,8 @@ export function registerConfigCommand(program) {
109
178
  process.env.EDITOR ||
110
179
  process.env.VISUAL ||
111
180
  (process.platform === "win32" ? "notepad" : "vi");
112
- const { execSync } = await import("node:child_process");
113
181
  try {
114
- // Escape any `"` in the path so it can't break out of the quoted arg
115
- // (editor stays unquoted so `$EDITOR` values with args still work).
116
- const safePath = configPath.replace(/"/g, '\\"');
117
- execSync(`${editor} "${safePath}"`, { stdio: "inherit" });
182
+ openConfigEditor(editor, configPath);
118
183
  } catch (err) {
119
184
  logger.error(`Failed to open editor: ${err.message}`);
120
185
  logger.info(`Config file is at: ${configPath}`);
@@ -100,12 +100,17 @@ export function registerContextCommand(program) {
100
100
  // different window.
101
101
  let recordedModel = "";
102
102
  let recordedProvider = "";
103
+ let recordedContextSources = null;
103
104
  try {
104
- const start = (readEvents(sessionId) || []).find(
105
+ const sessionEvents = readEvents(sessionId) || [];
106
+ const start = sessionEvents.find(
105
107
  (e) => e.type === "session_start",
106
108
  );
107
109
  recordedModel = start?.data?.model || "";
108
110
  recordedProvider = start?.data?.provider || "";
111
+ recordedContextSources = [...sessionEvents]
112
+ .reverse()
113
+ .find((e) => e.type === "context_sources")?.data || null;
109
114
  } catch {
110
115
  // header optional — fall through to flags/defaults
111
116
  }
@@ -129,7 +134,12 @@ export function registerContextCommand(program) {
129
134
  try {
130
135
  const { loadProjectInstructions } =
131
136
  await import("../lib/project-instructions.js");
132
- const { breakdownInstructionSources, rankContextSources } =
137
+ const {
138
+ breakdownInstructionSources,
139
+ breakdownMcpSchemas,
140
+ breakdownSkillSources,
141
+ rankContextSources,
142
+ } =
133
143
  await import("../lib/context-breakdown.js");
134
144
  const cwd = process.cwd();
135
145
  let instructionExcludes;
@@ -151,15 +161,37 @@ export function registerContextCommand(program) {
151
161
  estimateTokens,
152
162
  cwd,
153
163
  );
164
+ const mcp = breakdownMcpSchemas(
165
+ recordedContextSources?.mcp || [],
166
+ estimateTokens,
167
+ );
168
+ const skills = breakdownSkillSources(
169
+ recordedContextSources?.skills || [],
170
+ estimateTokens,
171
+ );
154
172
  const ranked = rankContextSources({
155
173
  instructionTotal: instr.total,
156
174
  buckets,
157
175
  counts,
176
+ extraSources: [
177
+ ...mcp.sources.map((source) => ({
178
+ ...source,
179
+ kind: "mcp_schema",
180
+ })),
181
+ ...skills.sources.map((source) => ({
182
+ ...source,
183
+ kind: "skill",
184
+ })),
185
+ ],
158
186
  });
159
187
  sourceReport = {
160
188
  cwd,
161
189
  instructions: instr.sources,
162
190
  instructionTokens: instr.total,
191
+ mcpSchemas: mcp.sources,
192
+ mcpSchemaTokens: mcp.total,
193
+ skills: skills.sources,
194
+ skillTokens: skills.total,
163
195
  ranked: ranked.sources,
164
196
  combinedTotal: ranked.total,
165
197
  };
@@ -189,6 +221,8 @@ export function registerContextCommand(program) {
189
221
  sources: sourceReport.ranked,
190
222
  instructions: sourceReport.instructions,
191
223
  instructionTokens: sourceReport.instructionTokens,
224
+ mcpSchemas: sourceReport.mcpSchemas,
225
+ mcpSchemaTokens: sourceReport.mcpSchemaTokens,
192
226
  combinedTotal: sourceReport.combinedTotal,
193
227
  cwd: sourceReport.cwd,
194
228
  }