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
@@ -57,6 +57,41 @@ export function breakdownInstructionSources(files, estimateTokens, cwd) {
57
57
  return { sources, total };
58
58
  }
59
59
 
60
+ /** Attribute the exact MCP tool schemas admitted to a persisted run. */
61
+ export function breakdownMcpSchemas(definitions, estimateTokens) {
62
+ const est = typeof estimateTokens === "function" ? estimateTokens : () => 0;
63
+ const list = Array.isArray(definitions) ? definitions : [];
64
+ const sources = list
65
+ .map((definition) => {
66
+ const fn = definition?.function || definition || {};
67
+ const name = String(fn.name || definition?.name || "mcp");
68
+ const schema = fn.parameters || definition?.inputSchema || {};
69
+ return {
70
+ source: name.split("__")[1] || name,
71
+ tool: name,
72
+ tokens: est(JSON.stringify({ description: fn.description || "", parameters: schema })),
73
+ };
74
+ })
75
+ .filter((row) => row.tokens > 0);
76
+ return { sources, total: sources.reduce((sum, row) => sum + row.tokens, 0) };
77
+ }
78
+
79
+ /** Attribute Skill bodies that were actually injected into the system prompt. */
80
+ export function breakdownSkillSources(skills, estimateTokens) {
81
+ const est = typeof estimateTokens === "function" ? estimateTokens : () => 0;
82
+ const list = Array.isArray(skills) ? skills : [];
83
+ const sources = list
84
+ .map((skill) => ({
85
+ source: skill?.source || "skill",
86
+ skill: String(skill?.id || skill?.displayName || "skill"),
87
+ tokens: est(
88
+ `## Persona: ${skill?.displayName || skill?.id || "skill"}\n${skill?.body || ""}`,
89
+ ),
90
+ }))
91
+ .filter((row) => row.tokens > 0);
92
+ return { sources, total: sources.reduce((sum, row) => sum + row.tokens, 0) };
93
+ }
94
+
60
95
  // role bucket key → { label, kind } for the ranked source list.
61
96
  const MESSAGE_SOURCE_ROWS = [
62
97
  ["system", "system messages", "message"],
@@ -84,6 +119,7 @@ export function rankContextSources({
84
119
  instructionTotal = 0,
85
120
  buckets = {},
86
121
  counts = {},
122
+ extraSources = [],
87
123
  } = {}) {
88
124
  const rows = [];
89
125
  if (instructionTotal > 0) {
@@ -105,6 +141,16 @@ export function rankContextSources({
105
141
  });
106
142
  }
107
143
  }
144
+ for (const row of Array.isArray(extraSources) ? extraSources : []) {
145
+ if (!row || !(row.tokens > 0)) continue;
146
+ rows.push({
147
+ kind: row.kind || "runtime",
148
+ source: row.source || "runtime",
149
+ tokens: row.tokens,
150
+ count: row.count ?? null,
151
+ tool: row.tool || null,
152
+ });
153
+ }
108
154
  const total = rows.reduce((s, x) => s + x.tokens, 0);
109
155
  // Stable sort: tokens desc, then source name for deterministic ties.
110
156
  rows.sort((a, b) => b.tokens - a.tokens || a.source.localeCompare(b.source));
@@ -43,6 +43,7 @@ class ContextSourceLedger {
43
43
  const entryId = entry.entryId || crypto.randomUUID();
44
44
  const full = {
45
45
  entryId,
46
+ traceId: entry.traceId || null,
46
47
  sessionId: entry.sessionId || "unknown",
47
48
  turnId: entry.turnId || "unknown",
48
49
  sourceType: entry.sourceType || "unknown",
@@ -69,6 +70,48 @@ class ContextSourceLedger {
69
70
  return entryId;
70
71
  }
71
72
 
73
+ /** Compatibility adapter for runtime provenance producers. */
74
+ recordRead(entry = {}) {
75
+ return this.record({
76
+ sessionId: entry.sessionId,
77
+ turnId: entry.turnId,
78
+ sourceType: entry.sourceType || entry.source || "unknown",
79
+ sourceId: entry.sourceId || entry.span || "unknown",
80
+ permissionMode: entry.permissionMode || "agent",
81
+ confidence: entry.confidence,
82
+ summary: entry.summary || entry.content,
83
+ metadata: entry.metadata,
84
+ tokenCount: entry.tokenCount ?? entry.tokens ?? 0,
85
+ traceId: entry.traceId,
86
+ });
87
+ }
88
+
89
+ /** Return a flat, read-only provenance snapshot for diagnostics/export. */
90
+ getProvenance({ sessionId, turnId } = {}) {
91
+ let entries = Array.from(this._entries.values());
92
+ if (sessionId) entries = entries.filter((e) => e.sessionId === sessionId);
93
+ if (turnId) entries = entries.filter((e) => e.turnId === turnId);
94
+ return entries.map((entry) => ({ ...entry, tags: [...entry.tags] }));
95
+ }
96
+
97
+ /** Aggregate token usage by source type. */
98
+ getTokenBreakdown() {
99
+ const bySource = {};
100
+ let total = 0;
101
+ for (const entry of this._entries.values()) {
102
+ total += entry.tokenCount;
103
+ bySource[entry.sourceType] = (bySource[entry.sourceType] || 0) + entry.tokenCount;
104
+ }
105
+ return { total, bySource };
106
+ }
107
+
108
+ /** Clear the in-memory ledger (test/runtime lifecycle boundary). */
109
+ clear() {
110
+ this._entries.clear();
111
+ this._byTurn.clear();
112
+ this._bySession.clear();
113
+ }
114
+
72
115
  /**
73
116
  * Get all context entries for a given turn
74
117
  * @param {string} turnId
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Correlate an IDE Diff "Request changes" decision with the next review of the
3
+ * same file. The tracker writes only bounded review metadata into the existing
4
+ * side-effect ledger; model text and file content are never copied.
5
+ */
6
+
7
+ const MAX_ID = 256;
8
+ const MAX_PATH = 2048;
9
+ const MAX_REASON = 256;
10
+ const VALID_OUTCOMES = new Set(["accepted", "rejected", "changes-requested"]);
11
+
12
+ function bounded(value, max) {
13
+ if (value == null) return null;
14
+ const text = String(value).slice(0, max);
15
+ return text || null;
16
+ }
17
+
18
+ function reviewKey(audit) {
19
+ const path = bounded(audit?.path, MAX_PATH);
20
+ if (!path) return null;
21
+ return `${bounded(audit?.sessionId, MAX_ID) || ""}\0${path}`;
22
+ }
23
+
24
+ function pendingFollowUp(audit) {
25
+ return {
26
+ status: "pending",
27
+ requestedAt: bounded(audit?.createdAt, 64),
28
+ };
29
+ }
30
+
31
+ function reviewedFollowUp(audit) {
32
+ const outcome = VALID_OUTCOMES.has(audit?.outcome)
33
+ ? audit.outcome
34
+ : "rejected";
35
+ return {
36
+ status: outcome,
37
+ reviewId: bounded(audit?.reviewId, 64),
38
+ turnId: bounded(audit?.turnId, MAX_ID),
39
+ toolUseId: bounded(audit?.toolUseId, MAX_ID),
40
+ operation: bounded(audit?.operation, 16) || "modify",
41
+ targetPath:
42
+ audit?.operation === "rename"
43
+ ? bounded(audit?.targetPath, MAX_PATH)
44
+ : null,
45
+ written: audit?.written === true,
46
+ completedAt: bounded(audit?.createdAt, 64),
47
+ };
48
+ }
49
+
50
+ function terminalFollowUp(status, { turnId = null, reason = null } = {}) {
51
+ return {
52
+ status,
53
+ turnId: bounded(turnId, MAX_ID),
54
+ reason: bounded(reason, MAX_REASON),
55
+ };
56
+ }
57
+
58
+ /**
59
+ * Ledger-facing tracker. `ledger` only needs `list()` and `annotate()` methods,
60
+ * which keeps the correlation logic independently testable.
61
+ */
62
+ export class DiffReviewFollowUpTracker {
63
+ constructor(ledger = null) {
64
+ this._pending = new Map();
65
+ if (ledger) this.hydrate(ledger);
66
+ }
67
+
68
+ /** Restore only explicitly-pending v1 records after a process/session resume. */
69
+ hydrate(ledger) {
70
+ this._pending.clear();
71
+ for (const op of ledger?.list?.() || []) {
72
+ const audit = op?.meta?.diffReview;
73
+ if (
74
+ audit?.schema !== "cc-diff-review/v1" ||
75
+ audit?.outcome !== "changes-requested" ||
76
+ audit?.followUp?.status !== "pending"
77
+ ) {
78
+ continue;
79
+ }
80
+ const key = reviewKey(audit);
81
+ if (key) this._pending.set(key, { opId: op.opId, audit });
82
+ }
83
+ return this;
84
+ }
85
+
86
+ /**
87
+ * Attach the current audit and, when applicable, resolve the preceding
88
+ * Request Changes record for the same trusted session/path.
89
+ */
90
+ observe(ledger, opId, audit) {
91
+ if (!ledger?.annotate || !opId || audit?.schema !== "cc-diff-review/v1") {
92
+ return [];
93
+ }
94
+ const updates = [];
95
+ const key = reviewKey(audit);
96
+ const prior = key ? this._pending.get(key) : null;
97
+ let currentAudit = audit;
98
+ if (prior && prior.opId !== opId) {
99
+ const followUp = reviewedFollowUp(audit);
100
+ ledger.annotate(prior.opId, {
101
+ diffReview: { ...prior.audit, followUp },
102
+ });
103
+ this._pending.delete(key);
104
+ currentAudit = {
105
+ ...audit,
106
+ followUpOfReviewId: bounded(prior.audit.reviewId, 64),
107
+ };
108
+ updates.push({
109
+ reviewId: prior.audit.reviewId || null,
110
+ followUp,
111
+ });
112
+ }
113
+
114
+ if (audit.outcome === "changes-requested" && key) {
115
+ currentAudit = { ...currentAudit, followUp: pendingFollowUp(audit) };
116
+ this._pending.set(key, { opId, audit: currentAudit });
117
+ }
118
+ ledger.annotate(opId, { diffReview: currentAudit });
119
+ return updates;
120
+ }
121
+
122
+ /**
123
+ * Settle every still-pending request when the agent run ends without another
124
+ * Diff proposal. Returns updates so callers can decide whether persistence is
125
+ * necessary.
126
+ */
127
+ complete(
128
+ ledger,
129
+ {
130
+ status = "completed-without-reproposal",
131
+ turnId = null,
132
+ reason = null,
133
+ } = {},
134
+ ) {
135
+ if (!ledger?.annotate || this._pending.size === 0) return [];
136
+ const updates = [];
137
+ for (const pending of this._pending.values()) {
138
+ const followUp = terminalFollowUp(status, { turnId, reason });
139
+ ledger.annotate(pending.opId, {
140
+ diffReview: { ...pending.audit, followUp },
141
+ });
142
+ updates.push({
143
+ reviewId: pending.audit.reviewId || null,
144
+ followUp,
145
+ });
146
+ }
147
+ this._pending.clear();
148
+ return updates;
149
+ }
150
+
151
+ get pendingCount() {
152
+ return this._pending.size;
153
+ }
154
+ }
@@ -23,9 +23,9 @@ import {
23
23
  statSync,
24
24
  rmSync,
25
25
  } from "node:fs";
26
- import { execSync, spawnSync } from "node:child_process";
27
26
  import { join, basename } from "node:path";
28
27
  import { getHomeDir, getConfigPath } from "./paths.js";
28
+ import executionBroker from "./process-execution-broker/index.js";
29
29
  import {
30
30
  languageIdForFile,
31
31
  resolveServer,
@@ -59,8 +59,8 @@ export const _deps = {
59
59
  readFileSync,
60
60
  statSync,
61
61
  rmSync,
62
- execSync,
63
- spawnSync,
62
+ execFileSync: (...args) => executionBroker.execFileSync(...args),
63
+ spawnSync: (...args) => executionBroker.spawnSync(...args),
64
64
  now: () => Date.now(),
65
65
  };
66
66
 
@@ -549,10 +549,14 @@ async function worktreeSection(opts, deps) {
549
549
  try {
550
550
  const inRepo = (() => {
551
551
  try {
552
- deps.execSync("git rev-parse --is-inside-work-tree", {
552
+ deps.execFileSync("git", ["rev-parse", "--is-inside-work-tree"], {
553
553
  cwd,
554
554
  encoding: "utf-8",
555
555
  stdio: ["ignore", "pipe", "ignore"],
556
+ origin: "doctor:git-worktree",
557
+ policy: "allow",
558
+ scope: "diagnostics",
559
+ shell: false,
556
560
  });
557
561
  return true;
558
562
  } catch {
@@ -570,10 +574,14 @@ async function worktreeSection(opts, deps) {
570
574
  );
571
575
  } else {
572
576
  const out =
573
- deps.execSync("git worktree prune --dry-run -v", {
577
+ deps.execFileSync("git", ["worktree", "prune", "--dry-run", "-v"], {
574
578
  cwd,
575
579
  encoding: "utf-8",
576
580
  stdio: ["ignore", "pipe", "ignore"],
581
+ origin: "doctor:git-worktree",
582
+ policy: "allow",
583
+ scope: "diagnostics",
584
+ shell: false,
577
585
  }) || "";
578
586
  const prunable = out.split("\n").filter((l) => l.trim()).length;
579
587
  if (prunable > 0) {
@@ -1138,10 +1146,14 @@ export async function runCheckupFixes(sections, opts = {}) {
1138
1146
  detail: `removed ${removed} file(s)`,
1139
1147
  });
1140
1148
  } else if (fix.id === "git-worktree-prune") {
1141
- deps.execSync("git worktree prune", {
1149
+ deps.execFileSync("git", ["worktree", "prune"], {
1142
1150
  cwd: opts.cwd || process.cwd(),
1143
1151
  encoding: "utf-8",
1144
1152
  stdio: ["ignore", "pipe", "ignore"],
1153
+ origin: "doctor:git-worktree-fix",
1154
+ policy: "allow",
1155
+ scope: "diagnostics",
1156
+ shell: false,
1145
1157
  });
1146
1158
  results.push({
1147
1159
  id: fix.id,
@@ -7,12 +7,16 @@ import {
7
7
  } from "node:fs";
8
8
  import { join } from "node:path";
9
9
  import { pipeline } from "node:stream/promises";
10
- import { execFileSync } from "node:child_process";
11
10
  import ora from "ora";
12
11
  import { GITHUB_RELEASES_URL } from "../constants.js";
13
12
  import { getBinDir, ensureDir } from "./paths.js";
14
13
  import { getPlatform, getArch } from "./platform.js";
15
14
  import logger from "./logger.js";
15
+ import { executionBroker } from "./process-execution-broker/index.js";
16
+
17
+ function brokerExecFileSync(file, args, options) {
18
+ return executionBroker.execFileSync(file, args, options);
19
+ }
16
20
 
17
21
  // Platform-specific asset matching patterns
18
22
  const ASSET_PATTERNS = {
@@ -211,7 +215,7 @@ async function fetchRelease(url) {
211
215
  export function extractZip(
212
216
  zipPath,
213
217
  destDir,
214
- { execFileImpl = execFileSync, platform = getPlatform() } = {},
218
+ { execFileImpl = brokerExecFileSync, platform = getPlatform() } = {},
215
219
  ) {
216
220
  // Never interpolate the paths into a shell string — `zipPath`/`destDir` derive
217
221
  // from the (remote) release asset name, so a `"`/`$()`/`'` in a path would be a
@@ -229,10 +233,20 @@ export function extractZip(
229
233
  {
230
234
  stdio: "ignore",
231
235
  env: { ...process.env, CC_ZIP_SRC: zipPath, CC_ZIP_DEST: destDir },
236
+ origin: "update:archive-extract",
237
+ policy: "allow",
238
+ scope: "update",
239
+ shell: false,
232
240
  },
233
241
  );
234
242
  } else {
235
- execFileImpl("unzip", ["-o", zipPath, "-d", destDir], { stdio: "ignore" });
243
+ execFileImpl("unzip", ["-o", zipPath, "-d", destDir], {
244
+ stdio: "ignore",
245
+ origin: "update:archive-extract",
246
+ policy: "allow",
247
+ scope: "update",
248
+ shell: false,
249
+ });
236
250
  }
237
251
  }
238
252
 
@@ -7,11 +7,13 @@
7
7
  * Node.js streams to use UTF-8 encoding.
8
8
  */
9
9
 
10
- import { execSync } from "child_process";
10
+ import { executionBroker } from "./process-execution-broker/index.js";
11
11
 
12
12
  // Injectable so tests can assert whether the (expensive) chcp spawn happened
13
13
  // without actually spawning cmd.exe. See cli-dev.md `_deps` pattern.
14
- export const _deps = { execSync };
14
+ export const _deps = {
15
+ execFileSync: (...args) => executionBroker.execFileSync(...args),
16
+ };
15
17
 
16
18
  /**
17
19
  * Call this as early as possible in the process entry point.
@@ -34,7 +36,13 @@ export function ensureUtf8() {
34
36
  Boolean(process.stderr && process.stderr.isTTY);
35
37
  if (consoleAttached || process.env.CC_FORCE_CHCP === "1") {
36
38
  try {
37
- _deps.execSync("chcp 65001", { stdio: "ignore" });
39
+ _deps.execFileSync("cmd.exe", ["/d", "/s", "/c", "chcp 65001"], {
40
+ stdio: "ignore",
41
+ origin: "runtime:utf8-console",
42
+ policy: "allow",
43
+ scope: "runtime",
44
+ shell: false,
45
+ });
38
46
  } catch (_err) {
39
47
  // Ignore - may fail in non-interactive environments
40
48
  }
@@ -11,7 +11,24 @@
11
11
 
12
12
  import fs from "fs";
13
13
  import path from "path";
14
- import { execFileSync } from "node:child_process";
14
+ import executionBroker from "../process-execution-broker/index.js";
15
+
16
+ export const _deps = {
17
+ execFileSync: (...args) => executionBroker.execFileSync(...args),
18
+ };
19
+
20
+ function runTaskCheck(dir, script, options = {}) {
21
+ return _deps.execFileSync(process.execPath, [script], {
22
+ cwd: dir,
23
+ timeout: 10000,
24
+ stdio: ["ignore", "pipe", "pipe"],
25
+ ...options,
26
+ origin: "eval:task-check",
27
+ policy: "allow",
28
+ scope: "eval",
29
+ shell: false,
30
+ });
31
+ }
15
32
 
16
33
  function read(dir, rel) {
17
34
  try {
@@ -97,11 +114,8 @@ export const BUILTIN_TASKS = [
97
114
  // Objective check: it must parse AND print OK. Re-run in a child so we
98
115
  // score the actual behavior, not a heuristic on the source.
99
116
  try {
100
- const out = execFileSync(process.execPath, ["bug.js"], {
101
- cwd: dir,
117
+ const out = runTaskCheck(dir, "bug.js", {
102
118
  encoding: "utf8",
103
- timeout: 10000,
104
- stdio: ["ignore", "pipe", "pipe"], // capture stderr, don't inherit
105
119
  });
106
120
  return out.trim() === "OK"
107
121
  ? { pass: true, detail: "node bug.js prints OK" }
@@ -186,11 +200,8 @@ export const BUILTIN_TASKS = [
186
200
  };
187
201
  }
188
202
  try {
189
- const out = execFileSync(process.execPath, ["run-checks.mjs"], {
190
- cwd: dir,
203
+ const out = runTaskCheck(dir, "run-checks.mjs", {
191
204
  encoding: "utf8",
192
- timeout: 10000,
193
- stdio: ["ignore", "pipe", "pipe"],
194
205
  });
195
206
  return out.includes("ALL OK")
196
207
  ? { pass: true, detail: "test suite passes" }
@@ -243,11 +254,8 @@ export const BUILTIN_TASKS = [
243
254
  }
244
255
  // Behavior must be preserved: run main.js and check the output.
245
256
  try {
246
- const out = execFileSync(process.execPath, ["main.js"], {
247
- cwd: dir,
257
+ const out = runTaskCheck(dir, "main.js", {
248
258
  encoding: "utf8",
249
- timeout: 10000,
250
- stdio: ["ignore", "pipe", "pipe"],
251
259
  });
252
260
  return out.trim() === "6"
253
261
  ? { pass: true, detail: "renamed + behavior preserved" }
@@ -290,12 +298,7 @@ export const BUILTIN_TASKS = [
290
298
  if (read(dir, "verify.mjs") == null) {
291
299
  return { pass: false, detail: "verify.mjs not created" };
292
300
  }
293
- const run = () =>
294
- execFileSync(process.execPath, ["verify.mjs"], {
295
- cwd: dir,
296
- timeout: 10000,
297
- stdio: ["ignore", "pipe", "pipe"],
298
- });
301
+ const run = () => runTaskCheck(dir, "verify.mjs");
299
302
  // 1) The verifier must PASS against the correct implementation.
300
303
  try {
301
304
  run();
@@ -383,11 +386,8 @@ export const BUILTIN_TASKS = [
383
386
  };
384
387
  }
385
388
  try {
386
- const out = execFileSync(process.execPath, ["app.mjs"], {
387
- cwd: dir,
389
+ const out = runTaskCheck(dir, "app.mjs", {
388
390
  encoding: "utf8",
389
- timeout: 10000,
390
- stdio: ["ignore", "pipe", "pipe"],
391
391
  }).trim();
392
392
  return out === "Hello, Ada!\nHello, Bob!!!"
393
393
  ? { pass: true, detail: "signature migrated + callers updated" }
@@ -525,11 +525,8 @@ export const BUILTIN_TASKS = [
525
525
  };
526
526
  }
527
527
  try {
528
- const out = execFileSync(process.execPath, ["build.mjs"], {
529
- cwd: dir,
528
+ const out = runTaskCheck(dir, "build.mjs", {
530
529
  encoding: "utf8",
531
- timeout: 10000,
532
- stdio: ["ignore", "pipe", "pipe"],
533
530
  });
534
531
  return out.includes("BUILD OK")
535
532
  ? { pass: true, detail: "build links + passes" }
@@ -620,11 +617,8 @@ export const BUILTIN_TASKS = [
620
617
  return { pass: false, detail: "app.mjs does not use the new toTitle" };
621
618
  }
622
619
  try {
623
- const out = execFileSync(process.execPath, ["run.mjs"], {
624
- cwd: dir,
620
+ const out = runTaskCheck(dir, "run.mjs", {
625
621
  encoding: "utf8",
626
- timeout: 10000,
627
- stdio: ["ignore", "pipe", "pipe"],
628
622
  });
629
623
  return out.trim() === "OK"
630
624
  ? { pass: true, detail: "adapted to new API + manifest bumped" }
@@ -0,0 +1,58 @@
1
+ /** Canonical producer boundary for durable Event Runtime events. */
2
+
3
+ import { EventEmitter } from "node:events";
4
+ import { eventId } from "./event-runtime-store.js";
5
+
6
+ const ALLOWED_ORIGINS = new Set([
7
+ "agenda",
8
+ "monitor",
9
+ "webhook",
10
+ "telegram",
11
+ "mcp",
12
+ "hook",
13
+ "agent-ipc",
14
+ "system",
15
+ ]);
16
+
17
+ function normalizeOrigin(origin) {
18
+ const value = String(origin || "system").trim().toLowerCase();
19
+ if (!ALLOWED_ORIGINS.has(value)) throw new Error(`unsupported event origin: ${value}`);
20
+ return value;
21
+ }
22
+
23
+ /**
24
+ * Publish an event with an immutable producer envelope. The store remains the
25
+ * source of truth; the optional emitter is only a low-latency notification.
26
+ */
27
+ export class EventRuntimeProducer extends EventEmitter {
28
+ constructor({ store, emitter = null, now = () => Date.now() } = {}) {
29
+ super();
30
+ if (!store || typeof store.enqueue !== "function") {
31
+ throw new Error("EventRuntimeProducer requires a durable EventRuntimeStore");
32
+ }
33
+ this.store = store;
34
+ this.emitter = emitter;
35
+ this._now = now;
36
+ }
37
+
38
+ publish(event, { origin = "system", queue = "inbox", id = null, metadata = null } = {}) {
39
+ if (queue !== "inbox" && queue !== "outbox") throw new Error(`unsupported event queue: ${queue}`);
40
+ const producer = normalizeOrigin(origin);
41
+ const base = {
42
+ ...(event && typeof event === "object" ? event : { value: event }),
43
+ origin: producer,
44
+ };
45
+ const payload = { ...base, producedAt: this._now(), authority: "system" };
46
+ const record = this.store.enqueue(queue, payload, {
47
+ id: id || eventId(base),
48
+ metadata: { ...(metadata || {}), producer: producer },
49
+ });
50
+ if (!record.duplicate) {
51
+ this.emit("published", record);
52
+ this.emitter?.emit?.("event-runtime:published", record);
53
+ }
54
+ return record;
55
+ }
56
+ }
57
+
58
+ export { ALLOWED_ORIGINS };