chainlesschain 0.163.5 → 0.163.7

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 (236) hide show
  1. package/completions/_cc +1 -1
  2. package/completions/cc.bash +1 -1
  3. package/completions/cc.fish +1 -1
  4. package/completions/cc.ps1 +1 -1
  5. package/package.json +1 -1
  6. package/src/assets/web-panel/assets/{AIOps-Cv2EE1Zy.js → AIOps-axqQfwv8.js} +1 -1
  7. package/src/assets/web-panel/assets/{ActionButton-CcpxMLuW.js → ActionButton-DV-Ro0By.js} +1 -1
  8. package/src/assets/web-panel/assets/{Analytics-DE8mJoMI.js → Analytics-Bt72WEVu.js} +3 -3
  9. package/src/assets/web-panel/assets/{AppLayout-DKn9dk9L.js → AppLayout-BtepG55E.js} +5 -5
  10. package/src/assets/web-panel/assets/{Artifacts-Cp3mG3Py.js → Artifacts-B7KaJ7S_.js} +1 -1
  11. package/src/assets/web-panel/assets/{Audit-zvsQfF2C.js → Audit-FNFaUg7A.js} +1 -1
  12. package/src/assets/web-panel/assets/{BackgroundAgents-Bi85SsjN.js → BackgroundAgents-DFb6J2wQ.js} +1 -1
  13. package/src/assets/web-panel/assets/{Backup-Cw47Dj6s.js → Backup-CC7YBhyj.js} +1 -1
  14. package/src/assets/web-panel/assets/{BaseInput-C5Ip2afH.js → BaseInput-RkgTNVtj.js} +1 -1
  15. package/src/assets/web-panel/assets/{Chat-C0iAFkJv.js → Chat-hHEmGZy-.js} +5 -5
  16. package/src/assets/web-panel/assets/{ChatBubbleRenderer-BV9Wv7wO.js → ChatBubbleRenderer-CAP9YhHv.js} +1 -1
  17. package/src/assets/web-panel/assets/{Checkbox-3KZZCiAF.js → Checkbox-z5wXOQP1.js} +1 -1
  18. package/src/assets/web-panel/assets/{Codegen-C8OMbBAz.js → Codegen-DVaDJnxy.js} +1 -1
  19. package/src/assets/web-panel/assets/{Col-B-MB84LJ.js → Col-CJmaRDR5.js} +1 -1
  20. package/src/assets/web-panel/assets/{Community-DpR7Dxao.js → Community-DF29_2bI.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compact-CyDtz0OS.js → Compact-DtkQkBzn.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compliance-5tiRa2An.js → Compliance-xoHDxp7I.js} +1 -1
  23. package/src/assets/web-panel/assets/{Cowork-DnQaKZ5x.js → Cowork-BUm-R7ht.js} +4 -4
  24. package/src/assets/web-panel/assets/{Cron-BaWfoEDf.js → Cron-Cgl14ZkB.js} +2 -2
  25. package/src/assets/web-panel/assets/{Crosschain-Bu0HoHhb.js → Crosschain-BNcbmoqh.js} +1 -1
  26. package/src/assets/web-panel/assets/{DID-31zk8upX.js → DID-Bwja0Zo9.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dashboard-BmVne-e2.js → Dashboard-Bk5XjEdJ.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dropdown-B4PkoOWd.js → Dropdown-Ci36Oitq.js} +1 -1
  29. package/src/assets/web-panel/assets/{EmailListRenderer-BZ6tyFtI.js → EmailListRenderer--U04ZN4q.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Osozn4Ds.js → FamilyGuardDashboard-B2gNPR2s.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-DaH8TOAP.js → Federation-C4KghYn7.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-tbU0uwis.js → FormItemContext-QL7x_Q_0.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-Df8LQBrL.js → GenericCardRenderer-F3Ryltwm.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-DsMB6-14.js → Git-2HassK5k.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-BnH0dZzd.js → Governance-DoBIp7oe.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-DhnN1N_P.js → Inference--W01QhZ-.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-DnNshAgn.js → KnowledgeGraph-DmvwqGpT.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-BmBFX3_N.js → Logs-BBJ4yAel.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-DCslfQU3.js → MarkdownRenderer-BLCZMzhJ.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-CPEgWDc3.js → Marketplace-D5lNngSI.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-C36qjgF9.js → McpTools-CkEVOMKH.js} +5 -5
  42. package/src/assets/web-panel/assets/{Memory-tNHvrgqN.js → Memory-B1Ow1xVE.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-Xaf6cKjc.js → MobileBridge-SgYbUfb6.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-D2E5TTeO.js → MobileProjects-BWdOvQAj.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-D4AJ2dwV.js → Mtc-DcTXSSma.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-Df-gtn2_.js → MtcAudit-Dt3WG4oj.js} +4 -4
  47. package/src/assets/web-panel/assets/{Multisig-DTCHLWld.js → Multisig-B9B38UZx.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-DruZ_1Jb.js → NLProgramming-B0S4GGvG.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-Dx3pdGDs.js → Notes-DZ5U58Ng.js} +4 -4
  50. package/src/assets/web-panel/assets/{NotificationSettings-Bi3L69oL.js → NotificationSettings-PjL5ZW34.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-BHY33m7C.js → OrderTableRenderer-DrAX2ESt.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-BG2ZVEV-.js → Organization-Cv1GYs-c.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-Viwtg4Mn.js → Overflow-Bbkp_PL3.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-Clm_yc1Z.js → P2P-BD8QUgoZ.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-NKmmDiOw.js → PdhVaultBrowser-BO-2PeaB.js} +5 -5
  56. package/src/assets/web-panel/assets/{Permissions-DIL8u9Nk.js → Permissions-D_OPVa02.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-B-jM4wt-.js → PersonalDataHub-mh-pEmaB.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-627I__H5.js → Pipeline-6JC2EDdb.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-2DN2qrkW.js → Privacy-CUshzUAG.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-CN4wC0sF.js → ProjectInit-Cs2Aalri.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-K35vsh5H.js → ProjectSettings-1ak49tcj.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-B_wQadhX.js → Projects-BV4oApsm.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-MckaQUhQ.js → Providers-CXXxvafH.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-BS3mtA_O.js → QrScannerModal-PTcDsF58.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-BHp_nofL.js → QuickAsk-CDwucrJw.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-DlmnPuZj.js → Recommend-CJlLVRXR.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-tsyFbvpy.js → RemoteSession-DlN-ETsO.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-Ba1iWv2D.js → Reputation-DI23LR6m.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-NnlGC--f.js → Row-Cl7UQMrM.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-CjThSIRv.js → RssFeed-CexHNfh8.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-CojUyC5x.js → Search-BneBWvRN.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-c-sxeJEc.js → Security-DX7Phgrp.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-CtcKEEmF.js → Services-BWXO8Mte.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-CIBBXflN.js → Skeleton-DCyOjKPJ.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-D1XOOK9n.js → Skills-CXqERsTB.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-hRfEp5Sn.js → Sla-bhbrbz8E.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-Dexb1f_6.js → SpeechSettings-3IPU0HBZ.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-BJsSFGYy.js → SyncSettings-DBNTQLbM.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-CfSZ8A1L.js → Tasks-quP0bkN-.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-idDf47W-.js → Templates-BouWmgho.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-C-UsX6w6.js → Tenant-qv0D9s7z.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-BgJtX5n1.js → Terminal-BxvbE8BB.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-DP0BLKTl.js → TimelineRenderer-D-IeLnJ2.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-LwCzqETp.js → Tokens-CFMKKyVG.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-D_9tVch0.js → Trigger-L8as3UuJ.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-BH2UlEWh.js → Trust-MxmA4VZG.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-CIpD0nYb.js → UkeySign-C0VvJYRi.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-9ShhYxK_.js → VideoEditing-Bf5QZj8N.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-C7afGNIG.js → Wallet-BIJ9riRz.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-bUKn6i5R.js → WebAuthn-B8p9Mhkw.js} +4 -4
  91. package/src/assets/web-panel/assets/{WorkflowEditor-CxgQaGyp.js → WorkflowEditor-BVsuaPen.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-DMVkmJwx.js → chat-BfkjoKpV.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-CDzQh5nS.js → colors-DeAlsWK8.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-C51kEF4D.js → compact-item-Cs97bz5j.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-BTk9bXBn.js → createContext-BqbG60LH.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-CMje33rb.js → hasIn-i_RY0b1X.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DpcrFxMI.js → index-0-agYlWL.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BW4F5YDF.js → index-79V_zv1s.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DRG-aqOs.js → index-B-3tEpTc.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BCRvG9lq.js → index-B-JVTrpr.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DgivOKHA.js → index-B1CbOH1i.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BzCkNylB.js → index-B5UkyA3c.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-x53Vf7la.js → index-BESLFt4q.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CCLj9hcD.js → index-BOVkf1K3.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CypsfcEq.js → index-BYUVuwKt.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BtlEqHLP.js → index-BcUXAB2s.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Ld_4mFmC.js → index-BkBi5TmC.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DqU9njjT.js → index-Bm7lLR4c.js} +1 -1
  110. package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +1 -0
  111. package/src/assets/web-panel/assets/{index-CwGPwjUu.js → index-BuLQobzW.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-C5IWTMVl.js → index-CE2VtTlp.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DJfnCuMq.js → index-CED2PL_y.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-hg_emBsi.js → index-CG3PRyAL.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-togc_uYn.js → index-CIG8fQ2_.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-C4rQCS8T.js → index-COdGA-8n.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-0Auljb10.js → index-CeWoNHau.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Cd0hmPxD.js → index-Cf3WCLmy.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BXQBPLyE.js → index-CgsqdnRV.js} +1 -1
  120. package/src/assets/web-panel/assets/index-ChVT0p9u.js +1 -0
  121. package/src/assets/web-panel/assets/{index-h31MwrME.js → index-D2B4VPyP.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-C1oZReaY.js → index-D9evtvg2.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CfC-piWZ.js → index-DUUrv141.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-D9rC-fGW.js → index-DiSkx4UB.js} +3 -3
  125. package/src/assets/web-panel/assets/{index-CvSeVzqe.js → index-Dk2qouAz.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CtM8OT_7.js → index-Dk7-v4hP.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BBz9LIMS.js → index-DmbfhJUP.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BAfY7m7i.js → index-DqBgBpgp.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BVePe_Rf.js → index-PT_5sBMA.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CDLkNkLj.js → index-U4f5izHz.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BTlsE8Df.js → index-YXgLng0K.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BeEaAEIp.js → index-ZxO_-E8a.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-B0-zMtKA.js → index-dIHr4B_u.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-C1oZQmAA.js → index-gyFpvL7l.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-DRLQyp2A.js → index-s1opAL-M.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-OS-vfbTA.js → index-yObj1O4n.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-vrA8K-ac.js → initDefaultProps-C9h9yKL3.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-ByEzwIAl.js → motion-BvmLsPdu.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-Ck4AWjw-.js → move-CoL4ekU1.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-6p0l9SrB.js → mtc-parser-C4pMy6xV.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-B1CUPQ6R.js → omit-DPuJfNxx.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-B1STg1iW.js → pickAttrs-D0KEeaK2.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-DTTllkBV.js → placementArrow-BpkyINxt.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-AIrrCfBb.js → responsiveObserve-DQI_wOq8.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-C_fPMjdR.js → slide-DYfdDiRg.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-D5ow2yIP.js → statusUtils-B5dtvb0D.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-Dy3hEA--.js → styleChecker-CF310mSj.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-WfzcfSh4.js → useFlexGapSupport-D1Qp4BLp.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-CKSejfas.js → useFs-C7_iyvJK.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-od3zpPBN.js → usePersonalDataHub-DZUt_fIm.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-DRD_2DFA.js → vnode-D3dsi0lZ.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-DmNrEtgf.js → zoom-WdbOlvdQ.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +5 -5
  155. package/src/command-manifest.json +1 -1
  156. package/src/commands/agenda.js +76 -4
  157. package/src/commands/agent.js +90 -1
  158. package/src/commands/automation.js +462 -3
  159. package/src/commands/background-session.js +102 -1
  160. package/src/commands/chat.js +11 -2
  161. package/src/commands/compact.js +106 -23
  162. package/src/commands/cowork.js +6 -1
  163. package/src/commands/loop.js +187 -38
  164. package/src/commands/routine.js +12 -5
  165. package/src/commands/scheduler-daemon.js +807 -0
  166. package/src/commands/session-observability.js +305 -0
  167. package/src/commands/session.js +38 -0
  168. package/src/data/changelog.json +28 -2
  169. package/src/gateways/ws/ws-agent-handler.js +439 -5
  170. package/src/harness/jsonl-session-store.js +463 -125
  171. package/src/harness/prompt-compressor.js +86 -13
  172. package/src/harness/provider-backed-compaction.js +100 -27
  173. package/src/lib/advisor-runtime.js +3 -1
  174. package/src/lib/agent-schedule-store.js +737 -47
  175. package/src/lib/agent-team/team-adjudication.js +40 -1
  176. package/src/lib/automation-center-routines.js +363 -0
  177. package/src/lib/automation-center.js +435 -0
  178. package/src/lib/automation-engine.js +568 -19
  179. package/src/lib/automation-execution-authority.js +736 -0
  180. package/src/lib/background-agent-supervisor.js +871 -215
  181. package/src/lib/background-command-argv.js +24 -0
  182. package/src/lib/background-interaction-journal.js +361 -52
  183. package/src/lib/background-interaction-resolver.js +32 -0
  184. package/src/lib/background-launch-profile.js +2 -0
  185. package/src/lib/background-needs-input-incident.js +221 -0
  186. package/src/lib/causal-observability.js +2661 -0
  187. package/src/lib/chat-session-admission.js +76 -0
  188. package/src/lib/cost-budget.js +5 -7
  189. package/src/lib/cowork/ab-comparator-cli.js +11 -0
  190. package/src/lib/cowork/debate-review-cli.js +12 -0
  191. package/src/lib/cowork-adapter.js +159 -38
  192. package/src/lib/cowork-cron.js +673 -19
  193. package/src/lib/cowork-observe.js +5 -1
  194. package/src/lib/cowork-task-runner.js +112 -17
  195. package/src/lib/delivery-coordinator.js +142 -0
  196. package/src/lib/direct-model-usage.js +121 -0
  197. package/src/lib/file-lines.js +183 -47
  198. package/src/lib/llm-pricing.js +12 -17
  199. package/src/lib/loop.js +62 -3
  200. package/src/lib/permission-engine.js +14 -7
  201. package/src/lib/public-ide-capability-manifest.js +2 -0
  202. package/src/lib/routine-store.js +546 -86
  203. package/src/lib/runtime-usage-ledger.js +182 -0
  204. package/src/lib/scheduler-kernel/agenda-adapter.js +604 -29
  205. package/src/lib/scheduler-kernel/authority-resolver.js +163 -0
  206. package/src/lib/scheduler-kernel/automation-adapter.js +994 -0
  207. package/src/lib/scheduler-kernel/automation-event-adapter.js +757 -0
  208. package/src/lib/scheduler-kernel/contract.js +11 -3
  209. package/src/lib/scheduler-kernel/cowork-cron-adapter.js +343 -15
  210. package/src/lib/scheduler-kernel/loop-adapter.js +913 -0
  211. package/src/lib/scheduler-kernel/migration-admin.js +346 -0
  212. package/src/lib/scheduler-kernel/migration-rollback-admin.js +932 -0
  213. package/src/lib/scheduler-kernel/routine-adapter.js +691 -22
  214. package/src/lib/scheduler-kernel/runtime.js +63 -1
  215. package/src/lib/scheduler-kernel/service.js +328 -0
  216. package/src/lib/scheduler-kernel/source-locator-path.js +142 -0
  217. package/src/lib/scheduler-kernel/store.js +3439 -206
  218. package/src/lib/session-host-lease.js +171 -2
  219. package/src/lib/session-host-snapshot.js +14 -3
  220. package/src/lib/session-persistence-failure.js +1 -0
  221. package/src/lib/session-tail.js +179 -34
  222. package/src/lib/session-transcript-structure.js +96 -0
  223. package/src/lib/sub-agent-context.js +328 -22
  224. package/src/lib/ws-agent-handler.js +4 -1
  225. package/src/repl/agent-repl.js +732 -91
  226. package/src/repl/chat-repl.js +5 -1
  227. package/src/runtime/agent-core.js +1274 -208
  228. package/src/runtime/coding-agent-contract-shared.cjs +5 -0
  229. package/src/runtime/fallback-model.js +5 -0
  230. package/src/runtime/headless-runner.js +324 -82
  231. package/src/runtime/headless-stream.js +232 -26
  232. package/src/runtime/policies/agent-policy.js +4 -0
  233. package/src/workers/background-agent-worker.js +468 -98
  234. package/src/assets/web-panel/assets/devWarning-CdwPwYj8.js +0 -1
  235. package/src/assets/web-panel/assets/index-BEeOdfEe.js +0 -1
  236. package/src/assets/web-panel/assets/index-BTe0TOu6.js +0 -1
@@ -4,8 +4,30 @@
4
4
  */
5
5
 
6
6
  import chalk from "chalk";
7
+ import {
8
+ inspectAutomationExecutionAuthority,
9
+ setAutomationExecutionBudget,
10
+ } from "../lib/automation-execution-authority.js";
11
+ import {
12
+ buildAutomationCenterProjection,
13
+ runAutomationCenterAction,
14
+ } from "../lib/automation-center.js";
15
+ import {
16
+ createAutomationCenterRoutine,
17
+ editAutomationCenterRoutine,
18
+ runAutomationCenterRoutineAction,
19
+ } from "../lib/automation-center-routines.js";
7
20
  import { logger } from "../lib/logger.js";
8
21
  import { parseJsonOption } from "../lib/parse-json-option.js";
22
+ import { AutomationSchedulerBridge } from "../lib/scheduler-kernel/automation-adapter.js";
23
+ import { AutomationEventDispatcher } from "../lib/scheduler-kernel/automation-event-adapter.js";
24
+ import { openSchedulerStore } from "../lib/scheduler-kernel/store.js";
25
+ import {
26
+ RoutineSchedulerBridge,
27
+ routineBridgeRunId,
28
+ } from "../lib/scheduler-kernel/routine-adapter.js";
29
+ import { RoutineStore } from "../lib/routine-store.js";
30
+ import { defaultRunAgent } from "./routine.js";
9
31
  import { bootstrap, shutdown } from "../runtime/bootstrap.js";
10
32
  import {
11
33
  ensureAutomationTables,
@@ -68,8 +90,56 @@ import {
68
90
  } from "../lib/automation-engine.js";
69
91
 
70
92
  function _dbFromCtx(cmd) {
71
- const root = cmd?.parent?.parent ?? cmd?.parent;
72
- return root?._db;
93
+ let current = cmd;
94
+ while (current) {
95
+ if (current._db) return current._db;
96
+ current = current.parent;
97
+ }
98
+ return null;
99
+ }
100
+
101
+ async function readBoundedJsonStdin(options, maximum = 80 * 1024) {
102
+ if (options?.jsonStdin !== true) {
103
+ throw new Error("--json-stdin is required for routine definitions");
104
+ }
105
+ let serialized = "";
106
+ for await (const chunk of process.stdin) {
107
+ serialized += chunk;
108
+ if (Buffer.byteLength(serialized, "utf8") > maximum) {
109
+ throw new Error(`routine definition exceeds ${maximum} UTF-8 bytes`);
110
+ }
111
+ }
112
+ let parsed;
113
+ try {
114
+ parsed = JSON.parse(serialized);
115
+ } catch {
116
+ throw new Error("routine definition stdin must be valid JSON");
117
+ }
118
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
119
+ throw new Error("routine definition stdin must be a JSON object");
120
+ }
121
+ return parsed;
122
+ }
123
+
124
+ async function triggerCenterRoutine(store, routine) {
125
+ const schedulerStore = openSchedulerStore();
126
+ try {
127
+ const bridge = new RoutineSchedulerBridge({
128
+ routineStore: store,
129
+ schedulerStore,
130
+ runAgent: defaultRunAgent,
131
+ });
132
+ const fired = await bridge.trigger(routine);
133
+ const runId = routineBridgeRunId(fired);
134
+ if (!runId) {
135
+ throw new Error(
136
+ `routine occurrence did not execute: ${fired.result?.status || "unknown"}`,
137
+ );
138
+ }
139
+ return store.getRun(runId) || { runId, status: "unknown" };
140
+ } finally {
141
+ schedulerStore.close();
142
+ }
73
143
  }
74
144
 
75
145
  async function _prepare(cmd) {
@@ -84,6 +154,129 @@ async function _prepare(cmd) {
84
154
  return db;
85
155
  }
86
156
 
157
+ export async function runAutomationScheduled(db, options = {}, _deps = {}) {
158
+ const log = _deps.log || ((message) => console.log(message));
159
+ let schedulerStore = _deps.schedulerStore;
160
+ const ownsSchedulerStore = schedulerStore == null;
161
+ try {
162
+ schedulerStore ||= openSchedulerStore();
163
+ const bridge = new AutomationSchedulerBridge({
164
+ db,
165
+ schedulerStore,
166
+ now: _deps.now || Date.now,
167
+ ...(_deps.ownerId === undefined ? {} : { ownerId: _deps.ownerId }),
168
+ ...(options.leaseMs === undefined
169
+ ? {}
170
+ : { leaseMs: Number(options.leaseMs) }),
171
+ });
172
+ const results = await bridge.runDue({ signal: _deps.signal });
173
+ const summary = results.map((entry) => ({
174
+ flow: entry.flow,
175
+ occurrence: entry.occurrence,
176
+ status: entry.result?.status ?? "unknown",
177
+ recovered: entry.recovered === true,
178
+ deduplicated: entry.deduplicated === true,
179
+ executionId:
180
+ typeof entry.result?.result?.id === "string"
181
+ ? entry.result.result.id
182
+ : null,
183
+ error: entry.result?.error ?? null,
184
+ }));
185
+ if (options.json) {
186
+ log(
187
+ JSON.stringify({ due: summary.length, executions: summary }, null, 2),
188
+ );
189
+ } else if (summary.length === 0) {
190
+ log(chalk.gray("Nothing due."));
191
+ } else {
192
+ for (const entry of summary) {
193
+ const color = entry.status === "succeeded" ? chalk.green : chalk.red;
194
+ log(
195
+ color(
196
+ `${entry.flow} → ${entry.status}${entry.executionId ? ` (${entry.executionId})` : ""}`,
197
+ ),
198
+ );
199
+ }
200
+ }
201
+ return summary.some(
202
+ (entry) =>
203
+ entry.status !== "succeeded" &&
204
+ entry.status !== "idle" &&
205
+ entry.status !== "busy",
206
+ )
207
+ ? 1
208
+ : 0;
209
+ } finally {
210
+ if (ownsSchedulerStore) schedulerStore?.close();
211
+ }
212
+ }
213
+
214
+ export async function runAutomationChannelEvent(db, options = {}, _deps = {}) {
215
+ const log = _deps.log || ((message) => console.log(message));
216
+ let schedulerStore = _deps.schedulerStore;
217
+ const ownsSchedulerStore = schedulerStore == null;
218
+ try {
219
+ schedulerStore ||= openSchedulerStore();
220
+ const dispatcher = new AutomationEventDispatcher({
221
+ db,
222
+ schedulerStore,
223
+ now: _deps.now || Date.now,
224
+ ...(_deps.ownerId === undefined ? {} : { ownerId: _deps.ownerId }),
225
+ ...(options.leaseMs === undefined
226
+ ? {}
227
+ : { leaseMs: Number(options.leaseMs) }),
228
+ });
229
+ const result = await dispatcher.dispatch(
230
+ {
231
+ id: options.eventId,
232
+ type: "channel.event",
233
+ origin: options.origin,
234
+ sender: options.sender || null,
235
+ text: options.text,
236
+ meta: options.meta || {},
237
+ producedAt:
238
+ options.producedAt === undefined
239
+ ? Number((_deps.now || Date.now)())
240
+ : Number(options.producedAt),
241
+ },
242
+ { signal: _deps.signal },
243
+ );
244
+ const summary = {
245
+ eventId: result.eventId,
246
+ matched: result.matched,
247
+ rejected: result.rejected,
248
+ executions: result.results.map((entry) => ({
249
+ flowId: entry.flowId,
250
+ triggerId: entry.triggerId,
251
+ occurrenceId: entry.occurrenceId,
252
+ deduplicated: entry.deduplicated,
253
+ status: entry.result?.status || "unknown",
254
+ executionId: entry.result?.result?.id || null,
255
+ error: entry.result?.error || null,
256
+ })),
257
+ };
258
+ if (options.json) {
259
+ log(JSON.stringify(summary, null, 2));
260
+ } else if (summary.matched === 0) {
261
+ log(
262
+ chalk.gray(`No scoped automation trigger matched ${summary.eventId}.`),
263
+ );
264
+ } else {
265
+ for (const entry of summary.executions) {
266
+ const color = entry.status === "succeeded" ? chalk.green : chalk.red;
267
+ log(
268
+ color(
269
+ `${entry.triggerId} → ${entry.status}${entry.executionId ? ` (${entry.executionId})` : ""}`,
270
+ ),
271
+ );
272
+ }
273
+ }
274
+ return summary;
275
+ } finally {
276
+ if (ownsSchedulerStore) schedulerStore?.close();
277
+ }
278
+ }
279
+
87
280
  export function registerAutomationCommand(program) {
88
281
  const make = (name) => {
89
282
  const cmd = program
@@ -92,7 +285,12 @@ export function registerAutomationCommand(program) {
92
285
  "Workflow automation engine — 12 SaaS connectors + triggers (Phase 96)",
93
286
  )
94
287
  .hook("preAction", async (thisCommand, actionCommand) => {
95
- if (actionCommand && actionCommand.name().endsWith("-v2")) return;
288
+ if (
289
+ actionCommand &&
290
+ (actionCommand.name().endsWith("-v2") ||
291
+ actionCommand.name().startsWith("center-routine-"))
292
+ )
293
+ return;
96
294
  const db = await _prepare(thisCommand);
97
295
  thisCommand._db = db;
98
296
  });
@@ -241,6 +439,140 @@ function _wire(root) {
241
439
  }
242
440
  });
243
441
 
442
+ root
443
+ .command("center-projection")
444
+ .description("Emit the versioned Automation Center projection for IDEs")
445
+ .option("-l, --limit <n>", "Maximum flows", "100")
446
+ .option("--json", "Output as JSON")
447
+ .action(async (opts, cmd) => {
448
+ const db = _dbFromCtx(cmd);
449
+ try {
450
+ const projection = buildAutomationCenterProjection(db, {
451
+ limit: Number(opts.limit),
452
+ });
453
+ if (opts.json) console.log(JSON.stringify(projection, null, 2));
454
+ else {
455
+ logger.info(
456
+ `${projection.summary.total} items (${projection.summary.flows} flows, ${projection.summary.routines} routines), ${projection.summary.needsAttention} need attention`,
457
+ );
458
+ for (const flow of projection.items) {
459
+ logger.log(
460
+ ` ${chalk.cyan(flow.id)} ${flow.kind.padEnd(7)} ${flow.status.padEnd(8)} ${flow.name} preflight=${flow.security.state}`,
461
+ );
462
+ }
463
+ }
464
+ } catch (e) {
465
+ logger.error(e.message);
466
+ process.exitCode = 1;
467
+ } finally {
468
+ await shutdown();
469
+ }
470
+ });
471
+
472
+ root
473
+ .command("center-routine-create")
474
+ .description("Create a revision-gated Routine from JSON stdin")
475
+ .requiredOption(
476
+ "--expected-revision <revision>",
477
+ "Exact Routine catalog revision shown by center-projection",
478
+ )
479
+ .requiredOption("--json-stdin", "Read the Routine definition from stdin")
480
+ .option("--json", "Output as JSON")
481
+ .action(async (opts) => {
482
+ try {
483
+ const result = createAutomationCenterRoutine(new RoutineStore(), {
484
+ expectedRevision: opts.expectedRevision,
485
+ definition: await readBoundedJsonStdin(opts),
486
+ });
487
+ if (opts.json) console.log(JSON.stringify(result, null, 2));
488
+ else logger.success(`Created routine ${result.routineId}`);
489
+ } catch (e) {
490
+ logger.error(e.message);
491
+ process.exitCode = 1;
492
+ } finally {
493
+ await shutdown();
494
+ }
495
+ });
496
+
497
+ root
498
+ .command("center-routine-edit <routineId>")
499
+ .description("Edit a revision-gated Routine from JSON stdin")
500
+ .requiredOption(
501
+ "--expected-revision <revision>",
502
+ "Exact Routine item revision shown by center-projection",
503
+ )
504
+ .requiredOption("--json-stdin", "Read the Routine definition from stdin")
505
+ .option("--json", "Output as JSON")
506
+ .action(async (routineId, opts) => {
507
+ try {
508
+ const result = editAutomationCenterRoutine(new RoutineStore(), {
509
+ routineId,
510
+ expectedRevision: opts.expectedRevision,
511
+ definition: await readBoundedJsonStdin(opts),
512
+ });
513
+ if (opts.json) console.log(JSON.stringify(result, null, 2));
514
+ else logger.success(`Edited routine ${result.routineId}`);
515
+ } catch (e) {
516
+ logger.error(e.message);
517
+ process.exitCode = 1;
518
+ } finally {
519
+ await shutdown();
520
+ }
521
+ });
522
+
523
+ root
524
+ .command("center-routine-action <routineId> <action>")
525
+ .description("Run a revision-gated Routine action")
526
+ .requiredOption(
527
+ "--expected-revision <revision>",
528
+ "Exact Routine item revision shown by center-projection",
529
+ )
530
+ .option("--json", "Output as JSON")
531
+ .action(async (routineId, action, opts) => {
532
+ try {
533
+ const store = new RoutineStore();
534
+ const result = await runAutomationCenterRoutineAction(store, {
535
+ routineId,
536
+ action,
537
+ expectedRevision: opts.expectedRevision,
538
+ triggerRoutine: (routine) => triggerCenterRoutine(store, routine),
539
+ });
540
+ if (opts.json) console.log(JSON.stringify(result, null, 2));
541
+ else logger.success(`${routineId} ${action} completed`);
542
+ } catch (e) {
543
+ logger.error(e.message);
544
+ process.exitCode = 1;
545
+ } finally {
546
+ await shutdown();
547
+ }
548
+ });
549
+
550
+ root
551
+ .command("center-action <flowId> <action>")
552
+ .description("Run a revision-gated Automation Center action")
553
+ .requiredOption(
554
+ "--expected-revision <revision>",
555
+ "Exact flow revision shown by center-projection",
556
+ )
557
+ .option("--json", "Output as JSON")
558
+ .action(async (flowId, action, opts, cmd) => {
559
+ const db = _dbFromCtx(cmd);
560
+ try {
561
+ const result = runAutomationCenterAction(db, {
562
+ flowId,
563
+ action,
564
+ expectedRevision: opts.expectedRevision,
565
+ });
566
+ if (opts.json) console.log(JSON.stringify(result, null, 2));
567
+ else logger.success(`${flowId} ${action} completed`);
568
+ } catch (e) {
569
+ logger.error(e.message);
570
+ process.exitCode = 1;
571
+ } finally {
572
+ await shutdown();
573
+ }
574
+ });
575
+
244
576
  root
245
577
  .command("show <flowId>")
246
578
  .description("Show flow detail")
@@ -360,6 +692,94 @@ function _wire(root) {
360
692
  }
361
693
  });
362
694
 
695
+ root
696
+ .command("run-scheduled")
697
+ .description("Run due cron flows through the durable scheduler kernel")
698
+ .option("--json", "Output as JSON")
699
+ .option("--lease-ms <ms>", "Scheduler execution lease in milliseconds")
700
+ .action(async (opts, cmd) => {
701
+ const db = _dbFromCtx(cmd);
702
+ try {
703
+ const code = await runAutomationScheduled(db, opts);
704
+ if (code !== 0) process.exitCode = code;
705
+ } catch (e) {
706
+ logger.error(e.message);
707
+ process.exitCode = 1;
708
+ } finally {
709
+ await shutdown();
710
+ }
711
+ });
712
+
713
+ root
714
+ .command("set-execution-budget <flowId>")
715
+ .description("Set the durable unattended-execution budget for a flow")
716
+ .requiredOption("--window-ms <ms>", "Fixed budget window in milliseconds")
717
+ .requiredOption("--max-runs <n>", "Maximum executions per window")
718
+ .requiredOption(
719
+ "--max-action-steps <n>",
720
+ "Maximum connector action steps per window",
721
+ )
722
+ .option("--json", "Output as JSON")
723
+ .action(async (flowId, opts, cmd) => {
724
+ const db = _dbFromCtx(cmd);
725
+ try {
726
+ const budget = setAutomationExecutionBudget(db, flowId, {
727
+ windowMs: Number(opts.windowMs),
728
+ maxRuns: Number(opts.maxRuns),
729
+ maxActionSteps: Number(opts.maxActionSteps),
730
+ });
731
+ if (opts.json) console.log(JSON.stringify(budget, null, 2));
732
+ else {
733
+ logger.success(`Execution budget set for ${flowId}`);
734
+ logger.log(
735
+ ` revision=${budget.revision} window=${budget.windowMs}ms runs=${budget.maxRuns} actionSteps=${budget.maxActionSteps}`,
736
+ );
737
+ }
738
+ } catch (e) {
739
+ logger.error(e.message);
740
+ process.exitCode = 1;
741
+ } finally {
742
+ await shutdown();
743
+ }
744
+ });
745
+
746
+ root
747
+ .command("execution-preflight <flowId>")
748
+ .description(
749
+ "Check live RBAC connector permissions and durable budget availability",
750
+ )
751
+ .option("--json", "Output as JSON")
752
+ .action(async (flowId, opts, cmd) => {
753
+ const db = _dbFromCtx(cmd);
754
+ try {
755
+ const flow = getFlow(db, flowId);
756
+ if (!flow) throw new Error(`Flow not found: ${flowId}`);
757
+ const result = inspectAutomationExecutionAuthority(db, flow);
758
+ if (opts.json) console.log(JSON.stringify(result, null, 2));
759
+ else {
760
+ const color = result.ready ? chalk.green : chalk.red;
761
+ logger.log(
762
+ color(`Execution preflight: ${result.ready ? "READY" : "DENIED"}`),
763
+ );
764
+ logger.log(` principal: ${result.snapshot.principalId}`);
765
+ for (const permission of result.permissions) {
766
+ logger.log(
767
+ ` ${permission.allowed ? "ALLOW" : "DENY "} ${permission.permission}`,
768
+ );
769
+ }
770
+ logger.log(
771
+ ` remaining: runs=${result.window.remainingRuns} actionSteps=${result.window.remainingActionSteps}`,
772
+ );
773
+ }
774
+ if (!result.ready) process.exitCode = 1;
775
+ } catch (e) {
776
+ logger.error(e.message);
777
+ process.exitCode = 1;
778
+ } finally {
779
+ await shutdown();
780
+ }
781
+ });
782
+
363
783
  root
364
784
  .command("share <flowId>")
365
785
  .description("Record flow share to another org")
@@ -530,6 +950,45 @@ function _wire(root) {
530
950
  }
531
951
  });
532
952
 
953
+ root
954
+ .command("dispatch-channel-event")
955
+ .description(
956
+ "Dispatch one durable, scope-checked webhook or Telegram event",
957
+ )
958
+ .requiredOption(
959
+ "--event-id <id>",
960
+ "Stable source event id for deduplication",
961
+ )
962
+ .requiredOption("--origin <origin>", "Event origin (webhook|telegram)")
963
+ .requiredOption("--text <text>", "Inbound event text")
964
+ .option("--sender <id>", "Inbound sender id")
965
+ .option("--meta <json>", "Bounded event metadata as JSON")
966
+ .option("--produced-at <ms>", "Trusted source event epoch milliseconds")
967
+ .option("--lease-ms <ms>", "Scheduler execution lease milliseconds")
968
+ .option("--json", "Output as JSON")
969
+ .action(async (opts, cmd) => {
970
+ const db = _dbFromCtx(cmd);
971
+ try {
972
+ const summary = await runAutomationChannelEvent(db, {
973
+ ...opts,
974
+ meta: parseJsonOption(opts.meta, "--meta") || {},
975
+ });
976
+ if (
977
+ summary.rejected.length > 0 ||
978
+ summary.executions.some(
979
+ (entry) => !["succeeded", "busy"].includes(entry.status),
980
+ )
981
+ ) {
982
+ process.exitCode = 1;
983
+ }
984
+ } catch (e) {
985
+ logger.error(e.message);
986
+ process.exitCode = 1;
987
+ } finally {
988
+ await shutdown();
989
+ }
990
+ });
991
+
533
992
  // ─── Execution ────────────────────────────────────────────
534
993
 
535
994
  root
@@ -9,6 +9,7 @@ import {
9
9
  } from "../lib/collaboration-run-store.js";
10
10
  import { readSessionHostResumeState } from "../lib/session-host-snapshot.js";
11
11
  import executionBroker from "../lib/process-execution-broker/index.js";
12
+ import { registerSchedulerDaemonCommands } from "./scheduler-daemon.js";
12
13
 
13
14
  export function buildBackgroundDispatchArgs(prompt) {
14
15
  return ["agent", "--bg", `--print=${prompt}`];
@@ -100,6 +101,21 @@ export function formatBackgroundAgentDetails(
100
101
  );
101
102
  }
102
103
  if (session.phase) lines.push(` phase: ${session.phase}`);
104
+ if (session.pendingQuestion) {
105
+ const prompt = String(
106
+ session.pendingQuestion.prompt || session.pendingQuestion.question || "",
107
+ )
108
+ .replace(/\s+/gu, " ")
109
+ .trim()
110
+ .slice(0, 240);
111
+ lines.push(` needsInput: ${prompt || "question pending"}`);
112
+ }
113
+ if (session.needsInputIncident) {
114
+ const incident = session.needsInputIncident;
115
+ lines.push(
116
+ ` needsInputIncident: ${incident.incidentId || "-"} status=${incident.status || "?"} notification=${incident.notification?.status || "?"}`,
117
+ );
118
+ }
103
119
  if (session.pr?.number) {
104
120
  lines.push(
105
121
  ` pr: #${session.pr.number}${session.pr.state ? ` ${session.pr.state}` : ""}${session.pr.url ? ` ${session.pr.url}` : ""}`,
@@ -120,6 +136,19 @@ export function formatBackgroundAgentDetails(
120
136
  lines.push("", "Commands:");
121
137
  lines.push(` cc attach ${session.id}`);
122
138
  lines.push(` cc logs ${session.id} -n 100`);
139
+ if (
140
+ ["failed", "unconfigured"].includes(
141
+ session.needsInputIncident?.notification?.status,
142
+ )
143
+ ) {
144
+ lines.push(` cc daemon notify-needs-input ${session.id}`);
145
+ } else if (
146
+ ["delivering", "outcome_unknown", "partial"].includes(
147
+ session.needsInputIncident?.notification?.status,
148
+ )
149
+ ) {
150
+ lines.push(` cc daemon notify-needs-input ${session.id} --force`);
151
+ }
123
152
  if (session.status === "running") {
124
153
  lines.push(` cc daemon stop ${session.id}`);
125
154
  }
@@ -275,6 +304,49 @@ export async function replyBackgroundAgent(id, prompt, dependencies = {}) {
275
304
  }
276
305
  }
277
306
 
307
+ export async function retryBackgroundNeedsInputNotification(
308
+ id,
309
+ options = {},
310
+ dependencies = {},
311
+ ) {
312
+ const sessionId = String(id || "").trim();
313
+ if (!sessionId) throw new Error("background agent id is required");
314
+ const supervisor = dependencies.supervisor || (await loadSupervisor());
315
+ const state = supervisor.readBackgroundAgentState(sessionId);
316
+ if (!state) throw new Error(`Background agent not found: ${sessionId}`);
317
+ if (!state.needsInputIncident) {
318
+ throw new Error(
319
+ `Background agent ${sessionId} has no needs-input incident`,
320
+ );
321
+ }
322
+ const result = await supervisor.deliverBackgroundNeedsInputNotification(
323
+ sessionId,
324
+ {
325
+ retry: true,
326
+ force: options.force === true,
327
+ ...(dependencies.notify ? { notify: dependencies.notify } : {}),
328
+ },
329
+ );
330
+ if (!result.applied) {
331
+ const error = new Error(
332
+ result.reason === "delivery_in_progress"
333
+ ? `Needs-input notification is already being delivered for ${sessionId}`
334
+ : result.reason === "delivery_not_retryable"
335
+ ? `Needs-input notification for ${sessionId} is not safely retryable; use --force only after accepting possible duplicate delivery`
336
+ : `Background agent ${sessionId} no longer has a pending needs-input incident`,
337
+ );
338
+ error.code = "BACKGROUND_NEEDS_INPUT_NOTIFICATION_NOT_RETRYABLE";
339
+ error.reason = result.reason;
340
+ throw error;
341
+ }
342
+ return {
343
+ id: sessionId,
344
+ incidentId: result.incident?.incidentId || null,
345
+ incidentStatus: result.incident?.status || null,
346
+ notification: result.incident?.notification || null,
347
+ };
348
+ }
349
+
278
350
  export const LOG_TRUNCATION_NOTICE =
279
351
  "--- log truncated/rotated, resuming from tail ---";
280
352
  const TRUNCATION_RESUME_TAIL_BYTES = 4096;
@@ -825,7 +897,36 @@ export function registerBackgroundSessionCommands(program) {
825
897
 
826
898
  const daemon = program
827
899
  .command("daemon")
828
- .description("Inspect and stop background agent supervisor sessions");
900
+ .description("Manage background agent and scheduler services");
901
+
902
+ registerSchedulerDaemonCommands(daemon);
903
+
904
+ daemon
905
+ .command("notify-needs-input <id>")
906
+ .description(
907
+ "Retry a durable needs-input notification for a background run",
908
+ )
909
+ .option(
910
+ "--force",
911
+ "Retry an ambiguous or already-delivered notification (may duplicate)",
912
+ )
913
+ .option("--json", "Output as JSON")
914
+ .action(async (id, options) => {
915
+ try {
916
+ const result = await retryBackgroundNeedsInputNotification(id, options);
917
+ if (options.json) console.log(JSON.stringify(result, null, 2));
918
+ else {
919
+ logger.log(
920
+ chalk.green(
921
+ `Needs-input notification ${result.notification?.status || "settled"} for ${id}`,
922
+ ),
923
+ );
924
+ }
925
+ } catch (error) {
926
+ logger.error(chalk.red(error.message));
927
+ process.exitCode = 1;
928
+ }
929
+ });
829
930
 
830
931
  daemon
831
932
  .command("status")
@@ -4,8 +4,16 @@
4
4
  */
5
5
 
6
6
  import { createAgentRuntimeFactory } from "../runtime/runtime-factory.js";
7
+ import { assertChatSessionUsageAdmission } from "../lib/chat-session-admission.js";
7
8
 
8
- export function registerChatCommand(program) {
9
+ export { assertChatSessionUsageAdmission } from "../lib/chat-session-admission.js";
10
+
11
+ export function registerChatCommand(program, dependencies = {}) {
12
+ const createRuntimeFactory =
13
+ dependencies.createAgentRuntimeFactory || createAgentRuntimeFactory;
14
+ const assertUsageAdmission =
15
+ dependencies.assertChatSessionUsageAdmission ||
16
+ assertChatSessionUsageAdmission;
9
17
  program
10
18
  .command("chat")
11
19
  .description("Start an interactive AI chat session")
@@ -22,7 +30,8 @@ export function registerChatCommand(program) {
22
30
  )
23
31
  .option("--session <id>", "Resume a previous session (agent mode)")
24
32
  .action(async (options) => {
25
- const factory = createAgentRuntimeFactory();
33
+ if (!options.agent) assertUsageAdmission(options.session);
34
+ const factory = createRuntimeFactory();
26
35
  const runtimeOptions = {
27
36
  model: options.model,
28
37
  provider: options.provider,