chainlesschain 0.162.188 → 0.162.193

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 (337) hide show
  1. package/README.md +61 -11
  2. package/bin/chainlesschain.js +7 -52
  3. package/completions/_cc +209 -0
  4. package/completions/cc.bash +18 -0
  5. package/completions/cc.fish +13 -0
  6. package/completions/cc.ps1 +226 -0
  7. package/package.json +10 -2
  8. package/src/assets/web-panel/assets/{AIOps-Brr1LVcE.js → AIOps-DBLkaTje.js} +1 -1
  9. package/src/assets/web-panel/assets/{ActionButton-DQU74DKG.js → ActionButton-BAy-Qebo.js} +1 -1
  10. package/src/assets/web-panel/assets/{Analytics-CYp9178y.js → Analytics-Dfb1Mlau.js} +3 -3
  11. package/src/assets/web-panel/assets/{AppLayout-DW4SCYsW.js → AppLayout-BbFkN8m0.js} +5 -5
  12. package/src/assets/web-panel/assets/{Artifacts-CYlD_ed1.js → Artifacts-kM4-cEEH.js} +1 -1
  13. package/src/assets/web-panel/assets/{Audit-CWl1rZOi.js → Audit-BSQfYWf3.js} +1 -1
  14. package/src/assets/web-panel/assets/{BackgroundAgents-BOR-LPsa.js → BackgroundAgents-CWDbI_fG.js} +1 -1
  15. package/src/assets/web-panel/assets/{Backup-DLpG7j1X.js → Backup-BxLPbq_Q.js} +1 -1
  16. package/src/assets/web-panel/assets/{BaseInput-B35K9wdr.js → BaseInput-DuIbdrp6.js} +1 -1
  17. package/src/assets/web-panel/assets/{Chat-CwUJb9gB.js → Chat-NEmjGahU.js} +5 -5
  18. package/src/assets/web-panel/assets/{ChatBubbleRenderer-1v6aMS1m.js → ChatBubbleRenderer-DfJEo-5_.js} +1 -1
  19. package/src/assets/web-panel/assets/{Checkbox-pi3-tPNW.js → Checkbox-CaoeG3Ns.js} +1 -1
  20. package/src/assets/web-panel/assets/{Codegen-FyNF35eL.js → Codegen-BFf_g3xY.js} +1 -1
  21. package/src/assets/web-panel/assets/{Col-tGt_JDEr.js → Col-CNOd8mdQ.js} +1 -1
  22. package/src/assets/web-panel/assets/{Community-CC7LonQX.js → Community-BhpDqz-i.js} +1 -1
  23. package/src/assets/web-panel/assets/{Compact-BGXrHHjE.js → Compact-CQ42T7Z6.js} +1 -1
  24. package/src/assets/web-panel/assets/{Compliance-DSW0TBZ8.js → Compliance-DI5PcLMN.js} +1 -1
  25. package/src/assets/web-panel/assets/{Cowork-Bhk7rbvE.js → Cowork-wYYZe0wR.js} +3 -3
  26. package/src/assets/web-panel/assets/{Cron-DxyiQ2NZ.js → Cron-Dlq03DD_.js} +2 -2
  27. package/src/assets/web-panel/assets/{Crosschain-B2ZkxHok.js → Crosschain-BzqS8PP3.js} +1 -1
  28. package/src/assets/web-panel/assets/{DID-yOJV99eJ.js → DID-It55Yem7.js} +2 -2
  29. package/src/assets/web-panel/assets/{Dashboard-CKsttz7D.js → Dashboard-9HkH6oxn.js} +2 -2
  30. package/src/assets/web-panel/assets/{Dropdown-CVFldXSL.js → Dropdown-00e2YWRB.js} +1 -1
  31. package/src/assets/web-panel/assets/{EmailListRenderer-Bufv638J.js → EmailListRenderer-By-ugRDL.js} +1 -1
  32. package/src/assets/web-panel/assets/{FamilyGuardDashboard-4ncjoIjL.js → FamilyGuardDashboard-C396yu5m.js} +1 -1
  33. package/src/assets/web-panel/assets/{Federation-DsknEDoX.js → Federation-BME5sbZY.js} +1 -1
  34. package/src/assets/web-panel/assets/{FormItemContext-Cqe5jWXA.js → FormItemContext-B4TEZCr-.js} +1 -1
  35. package/src/assets/web-panel/assets/{GenericCardRenderer-NAJaFKxc.js → GenericCardRenderer-_9CX9ieY.js} +1 -1
  36. package/src/assets/web-panel/assets/{Git-CszKQpnl.js → Git-BrS6WVSr.js} +2 -2
  37. package/src/assets/web-panel/assets/{Governance-BXGodXi6.js → Governance-BMdCWnKF.js} +1 -1
  38. package/src/assets/web-panel/assets/{Inference-CkoYuG2c.js → Inference-Bcp3vzcA.js} +1 -1
  39. package/src/assets/web-panel/assets/{KnowledgeGraph-DFlEr_T0.js → KnowledgeGraph-DlLuqGY5.js} +1 -1
  40. package/src/assets/web-panel/assets/{Logs-CVaENddA.js → Logs-D-W_6x09.js} +2 -2
  41. package/src/assets/web-panel/assets/MarkdownRenderer-DElGPxCZ.js +1 -0
  42. package/src/assets/web-panel/assets/{Marketplace-CDlLT0fw.js → Marketplace-Dzn2guvI.js} +1 -1
  43. package/src/assets/web-panel/assets/{McpTools-DdwOyszN.js → McpTools-uPict-KL.js} +6 -6
  44. package/src/assets/web-panel/assets/{Memory-DKQnkKuG.js → Memory-BCw43kOb.js} +2 -2
  45. package/src/assets/web-panel/assets/{MobileBridge-DGseqlzJ.js → MobileBridge-DmV8Wv7F.js} +1 -1
  46. package/src/assets/web-panel/assets/{MobileProjects-COBbEOlj.js → MobileProjects-C-HaCmSM.js} +1 -1
  47. package/src/assets/web-panel/assets/{Mtc-O61Vwyli.js → Mtc-C6jxJ34Y.js} +5 -5
  48. package/src/assets/web-panel/assets/{MtcAudit-Dw2SyasS.js → MtcAudit-Za8ExwhQ.js} +5 -5
  49. package/src/assets/web-panel/assets/{Multisig-hSu_l8kf.js → Multisig-KKDbuEgb.js} +3 -3
  50. package/src/assets/web-panel/assets/{NLProgramming-CX1Epurr.js → NLProgramming-Dj97zbCk.js} +1 -1
  51. package/src/assets/web-panel/assets/{Notes-R9xX8o8_.js → Notes-DBXvMraU.js} +4 -4
  52. package/src/assets/web-panel/assets/{NotificationSettings-jtSNLCuK.js → NotificationSettings-DOxITLYl.js} +1 -1
  53. package/src/assets/web-panel/assets/OrderTableRenderer-7DVjZwMM.js +1 -0
  54. package/src/assets/web-panel/assets/{Organization-Pu2WO-U3.js → Organization-D1i73mjb.js} +4 -4
  55. package/src/assets/web-panel/assets/{Overflow-BjnqUyFp.js → Overflow-kW6Q3rvg.js} +1 -1
  56. package/src/assets/web-panel/assets/{P2P-jjkvz44c.js → P2P-C-v_8p2v.js} +2 -2
  57. package/src/assets/web-panel/assets/PdhVaultBrowser-tUbbY64W.js +7 -0
  58. package/src/assets/web-panel/assets/{Permissions-D4yDpivd.js → Permissions-DkHxEZ58.js} +4 -4
  59. package/src/assets/web-panel/assets/{PersonalDataHub-0qsL6iH1.js → PersonalDataHub-DWuMPGrK.js} +5 -5
  60. package/src/assets/web-panel/assets/{Pipeline-Cx7Ybrk2.js → Pipeline-30IYXWWm.js} +1 -1
  61. package/src/assets/web-panel/assets/{Privacy-PbfR_M_V.js → Privacy-DZNQ4RrH.js} +1 -1
  62. package/src/assets/web-panel/assets/{ProjectInit-CyV6Gsub.js → ProjectInit-De2MCElf.js} +2 -2
  63. package/src/assets/web-panel/assets/{ProjectSettings-C7KZ2Wdk.js → ProjectSettings-5uHk9wsC.js} +2 -2
  64. package/src/assets/web-panel/assets/{Projects-DQDjO-yK.js → Projects-XjDfrFLb.js} +1 -1
  65. package/src/assets/web-panel/assets/{Providers-DyFVBBMX.js → Providers-Bgwj6gcE.js} +1 -1
  66. package/src/assets/web-panel/assets/{QrScannerModal-CzB1BC9_.js → QrScannerModal-gKql9umv.js} +1 -1
  67. package/src/assets/web-panel/assets/{QuickAsk-Bk636mC1.js → QuickAsk-BWvmwkh7.js} +1 -1
  68. package/src/assets/web-panel/assets/{Recommend-DoWxHIT3.js → Recommend-Uok4hZPd.js} +1 -1
  69. package/src/assets/web-panel/assets/{RemoteSession-oOVIv9wq.js → RemoteSession-DLJzTk9a.js} +3 -3
  70. package/src/assets/web-panel/assets/{Reputation-BucoReGG.js → Reputation-ZVwIPMSO.js} +1 -1
  71. package/src/assets/web-panel/assets/{Row-DzmOdJU7.js → Row-CN04HxWR.js} +1 -1
  72. package/src/assets/web-panel/assets/{RssFeed-C1tK7KGU.js → RssFeed-BdSrEG4g.js} +3 -3
  73. package/src/assets/web-panel/assets/{Search-CSnInOqk.js → Search-5PwVd0IR.js} +1 -1
  74. package/src/assets/web-panel/assets/{Security-dlejr15l.js → Security-DdBo4zjN.js} +3 -3
  75. package/src/assets/web-panel/assets/{Services-BioPZuNh.js → Services-D3letU7M.js} +2 -2
  76. package/src/assets/web-panel/assets/{Skeleton-DWMibwpC.js → Skeleton--Jb83f1v.js} +1 -1
  77. package/src/assets/web-panel/assets/{Skills-BAAnx1B2.js → Skills-Bg-CulHX.js} +1 -1
  78. package/src/assets/web-panel/assets/{Sla-jWNp4hNO.js → Sla-7QOa7S-X.js} +1 -1
  79. package/src/assets/web-panel/assets/{SpeechSettings-y5kqKha-.js → SpeechSettings-DQwppjRw.js} +1 -1
  80. package/src/assets/web-panel/assets/{SyncSettings-B9GNsc3e.js → SyncSettings-dNPQGL-s.js} +2 -2
  81. package/src/assets/web-panel/assets/{Tasks-BDBYKRen.js → Tasks-Ggs-Z48q.js} +1 -1
  82. package/src/assets/web-panel/assets/{Templates-DRiE5eaN.js → Templates-78TYHgRO.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tenant-BGlAvExF.js → Tenant-xHwwv9vO.js} +1 -1
  84. package/src/assets/web-panel/assets/{Terminal-B8uzrbNY.js → Terminal-BJXSJfm4.js} +2 -2
  85. package/src/assets/web-panel/assets/{TimelineRenderer-Df48iveY.js → TimelineRenderer-fLbjRhJw.js} +1 -1
  86. package/src/assets/web-panel/assets/{Tokens-CcmHndN6.js → Tokens-oMSBSBmB.js} +1 -1
  87. package/src/assets/web-panel/assets/{Trigger-DPkWxmQ2.js → Trigger-CfnY_wX_.js} +1 -1
  88. package/src/assets/web-panel/assets/{Trust-DTb5a5AV.js → Trust-AdyTgYKO.js} +1 -1
  89. package/src/assets/web-panel/assets/{UkeySign-CBmg5vch.js → UkeySign-C5K_81dS.js} +1 -1
  90. package/src/assets/web-panel/assets/{VideoEditing-B0mZrz4O.js → VideoEditing-vcGVDqki.js} +1 -1
  91. package/src/assets/web-panel/assets/{Wallet-Bxs7_mpd.js → Wallet-hhOc3hlY.js} +4 -4
  92. package/src/assets/web-panel/assets/{WebAuthn-C8x3cMxU.js → WebAuthn-CVloC11s.js} +3 -3
  93. package/src/assets/web-panel/assets/{WorkflowEditor-DPrNznrP.js → WorkflowEditor-CYeE32R5.js} +1 -1
  94. package/src/assets/web-panel/assets/{chat-D3bYWu7S.js → chat-CNROR5bN.js} +1 -1
  95. package/src/assets/web-panel/assets/{colors-DY-PwMu4.js → colors-Cjx-cnwU.js} +1 -1
  96. package/src/assets/web-panel/assets/{compact-item-LDk10Kw6.js → compact-item-DOIfelvD.js} +1 -1
  97. package/src/assets/web-panel/assets/{createContext-C-2MZnFq.js → createContext-DfA7UZ8u.js} +1 -1
  98. package/src/assets/web-panel/assets/devWarning-ChcCBGs7.js +1 -0
  99. package/src/assets/web-panel/assets/{hasIn-BQIBjcnB.js → hasIn-BMSCzcfM.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CQVb2dWp.js → index-5-HXgOX5.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BdXnYMCZ.js → index-AWg-0M1S.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Cx6D_dx2.js → index-B4iYzpkL.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-_HRO_cIu.js → index-B5Udeb_6.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DlRYqt3S.js → index-B7gf77CJ.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BrnRO9yE.js → index-BEMwBBHk.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-VCh5zNJo.js → index-BM1y_9hM.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BRI3ngNg.js → index-BUonmKSE.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-C3GNvExG.js → index-BbQ2eQ8H.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DSvo_bp0.js → index-BemJ2u_E.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-L6qixyLc.js → index-BolaOQxx.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BI4KgcYC.js → index-BxOk9vkG.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CY4KnaO9.js → index-By61ojUx.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-L3smcoQX.js → index-C2K9SNVX.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BX2b9Orc.js → index-C3L5gdiD.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-Cz4b6Z_7.js → index-C7xn0Nub.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-COG61sRv.js → index-CAnvhwg6.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-C7FC8cP2.js → index-CEKMcOyU.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BN-xdSWZ.js → index-CNC5onm4.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DY2FIrmz.js → index-CVL27kXC.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CiTvBAr-.js → index-CVm1_i3t.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DhRt9cYJ.js → index-CdYBye8B.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-B5pgtZnY.js → index-ClNMrqEY.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-7xKu7Fns.js → index-Cs6l7uRu.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-D4K1weKc.js → index-CshQbilz.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-k7C_oDCO.js → index-Cyweh0Hy.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-D3Oq-DLL.js → index-DBpWXFed.js} +3 -3
  127. package/src/assets/web-panel/assets/{index-DYyLJPlF.js → index-DHtpHZAQ.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Dh-tkpKQ.js → index-DLmn0BoK.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-8JC9BJa1.js → index-DPAWBrMf.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Dd2Km97U.js → index-DjEsxO5h.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-KFZO_lcx.js → index-FBc_CJBd.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DTIZpPtG.js → index-Icdoqmzt.js} +1 -1
  133. package/src/assets/web-panel/assets/index-Q2IajL54.js +1 -0
  134. package/src/assets/web-panel/assets/index-bRkHgOMc.js +1 -0
  135. package/src/assets/web-panel/assets/{index-lmm9p-jm.js → index-dCd8cSUq.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-HasPt4-h.js → index-m2vG9gG_.js} +1 -1
  137. package/src/assets/web-panel/assets/{index-CaslYch6.js → index-mTpHoEzr.js} +1 -1
  138. package/src/assets/web-panel/assets/{index-CbR6ROOa.js → index-ti_lnTWl.js} +1 -1
  139. package/src/assets/web-panel/assets/{initDefaultProps-zQPSHf2C.js → initDefaultProps-Bu8k7H1Y.js} +1 -1
  140. package/src/assets/web-panel/assets/{motion-CKCStGVk.js → motion-s3iVK41k.js} +1 -1
  141. package/src/assets/web-panel/assets/{move-BufVDGYF.js → move-B6B-E5Jz.js} +1 -1
  142. package/src/assets/web-panel/assets/{mtc-parser-DcaFxy5D.js → mtc-parser-BiYgTidA.js} +1 -1
  143. package/src/assets/web-panel/assets/{omit-EScpkGdo.js → omit-pU1RdUDA.js} +1 -1
  144. package/src/assets/web-panel/assets/{pickAttrs-72hG_qfT.js → pickAttrs-Cdoq_SeM.js} +1 -1
  145. package/src/assets/web-panel/assets/{placementArrow-CMFWiH20.js → placementArrow-DIuvAn2K.js} +1 -1
  146. package/src/assets/web-panel/assets/{responsiveObserve-DKQHS41p.js → responsiveObserve-8w16YR2D.js} +1 -1
  147. package/src/assets/web-panel/assets/{slide-QVAFHTIQ.js → slide-VZ01cZe3.js} +1 -1
  148. package/src/assets/web-panel/assets/{statusUtils-DIz38e2G.js → statusUtils-lh8YMN8Z.js} +1 -1
  149. package/src/assets/web-panel/assets/{styleChecker-zK5cyLby.js → styleChecker-CmDyreec.js} +1 -1
  150. package/src/assets/web-panel/assets/{useFlexGapSupport-DhZngk62.js → useFlexGapSupport-hiJWMU5y.js} +1 -1
  151. package/src/assets/web-panel/assets/{useFs-BvV2cvkg.js → useFs-Thnu-Iaj.js} +1 -1
  152. package/src/assets/web-panel/assets/{usePersonalDataHub-CRmxb9l3.js → usePersonalDataHub-LBdOxjwY.js} +1 -1
  153. package/src/assets/web-panel/assets/{vnode-CgQIbobP.js → vnode-Cg6lFY_X.js} +1 -1
  154. package/src/assets/web-panel/assets/{zoom-D4XrrO0R.js → zoom-DVfsR1YO.js} +1 -1
  155. package/src/assets/web-panel/index.html +1 -1
  156. package/src/cli-help.js +181 -0
  157. package/src/command-help-index.json +181 -0
  158. package/src/command-manifest.json +1107 -175
  159. package/src/command-surface-policy.js +197 -0
  160. package/src/commands/agent.js +98 -33
  161. package/src/commands/artifacts.js +400 -2
  162. package/src/commands/background-session.js +41 -3
  163. package/src/commands/checkpoint-managed.js +1059 -0
  164. package/src/commands/checkpoint-restore-recovery.js +1476 -0
  165. package/src/commands/checkpoint.js +950 -22
  166. package/src/commands/compact.js +101 -25
  167. package/src/commands/config.js +506 -20
  168. package/src/commands/doctor.js +4 -1
  169. package/src/commands/hub.js +1 -1
  170. package/src/commands/mcp.js +688 -24
  171. package/src/commands/pack.js +16 -2
  172. package/src/commands/plugin.js +20 -12
  173. package/src/commands/session-mcp-recovery.js +218 -0
  174. package/src/commands/session.js +470 -110
  175. package/src/commands/setup.js +36 -10
  176. package/src/commands/skill.js +181 -110
  177. package/src/commands/status.js +21 -5
  178. package/src/commands/team-distributed.js +3324 -0
  179. package/src/commands/team.js +1130 -74
  180. package/src/commands/update.js +68 -6
  181. package/src/constants.js +11 -0
  182. package/src/data/changelog.json +26 -0
  183. package/src/gateways/ws/action-protocol.js +10 -0
  184. package/src/gateways/ws/session-protocol.js +555 -27
  185. package/src/gateways/ws/ws-agent-handler.js +541 -14
  186. package/src/gateways/ws/ws-session-gateway.js +129 -22
  187. package/src/gateways/ws/ws-session-state.js +431 -0
  188. package/src/harness/background-task-manager.js +233 -36
  189. package/src/harness/jsonl-session-store.js +2551 -167
  190. package/src/harness/mcp-client.js +802 -61
  191. package/src/harness/prompt-compressor.js +227 -27
  192. package/src/harness/session-index.js +89 -38
  193. package/src/harness/session-list-index.js +254 -0
  194. package/src/harness/structured-handoff.js +410 -0
  195. package/src/lazy-dispatch.js +747 -84
  196. package/src/lib/__tests__/logger.test.js +50 -2
  197. package/src/lib/advisor-runtime.js +1047 -0
  198. package/src/lib/agent-core.js +2 -0
  199. package/src/lib/agent-sandbox.js +120 -26
  200. package/src/lib/agent-session-export.js +20 -0
  201. package/src/lib/agent-team/task-lease.js +271 -3
  202. package/src/lib/agent-team/team-adjudication.js +1501 -0
  203. package/src/lib/agent-team/team-budget.js +4 -1
  204. package/src/lib/agent-team/team-control-store.js +582 -0
  205. package/src/lib/agent-team/team-distributed-queue.js +5246 -0
  206. package/src/lib/agent-team/team-process-checkpoint.js +211 -0
  207. package/src/lib/agent-team/team-runner.js +543 -24
  208. package/src/lib/agent-team/team-worktree.js +1403 -95
  209. package/src/lib/artifact-store.js +131 -8
  210. package/src/lib/background-agent-supervisor.js +185 -13
  211. package/src/lib/background-interaction-journal.js +37 -9
  212. package/src/lib/background-launch-profile.js +1058 -0
  213. package/src/lib/checkpoint-restore-already-completed-controller.js +902 -0
  214. package/src/lib/checkpoint-restore-orchestrator.js +987 -0
  215. package/src/lib/checkpoint-restore-partial-rollback-controller.js +1953 -0
  216. package/src/lib/checkpoint-restore-recovery-controller.js +689 -0
  217. package/src/lib/checkpoint-restore-recovery.js +884 -0
  218. package/src/lib/checkpoint-restore-retention.js +126 -0
  219. package/src/lib/checkpoint-restore-saga.js +5079 -0
  220. package/src/lib/checkpoint-restore-session-recovery.js +1178 -0
  221. package/src/lib/checkpoint-restore-workspace-target-verifier.js +270 -0
  222. package/src/lib/checkpoint-store.js +1688 -97
  223. package/src/lib/checkpoint-timeline-authority.js +522 -0
  224. package/src/lib/checkpoint-timeline.js +642 -0
  225. package/src/lib/config-keys.js +18 -119
  226. package/src/lib/config-manager.js +446 -27
  227. package/src/lib/config-redaction.js +57 -0
  228. package/src/lib/config-schema.js +853 -0
  229. package/src/lib/cowork-mcp-tools.js +5 -0
  230. package/src/lib/cowork-task-runner.js +458 -63
  231. package/src/lib/delivery-coordinator.js +1234 -0
  232. package/src/lib/delivery-evidence.js +450 -0
  233. package/src/lib/doctor-checkup.js +199 -14
  234. package/src/lib/executable-path.js +34 -0
  235. package/src/lib/fatal-handler.js +16 -0
  236. package/src/lib/file-checkpoint.js +4909 -186
  237. package/src/lib/file-lines.js +125 -0
  238. package/src/lib/headless-config-command.js +16 -5
  239. package/src/lib/hook-runner.cjs +139 -38
  240. package/src/lib/hooks-v2-workspace-context.js +10 -0
  241. package/src/lib/impacted-gate-selector.js +424 -0
  242. package/src/lib/interaction-adapter.js +62 -0
  243. package/src/lib/jsonl-session-store.js +1 -35
  244. package/src/lib/logger.js +66 -14
  245. package/src/lib/managed-checkpoint-render.js +60 -0
  246. package/src/lib/managed-tool-checkpoint.js +194 -0
  247. package/src/lib/mcp-call-ledger-store.js +1069 -0
  248. package/src/lib/mcp-call-ledger.js +747 -0
  249. package/src/lib/mcp-client.js +5 -0
  250. package/src/lib/mcp-conflict-scheduler.js +468 -0
  251. package/src/lib/mcp-effect-contract.js +102 -0
  252. package/src/lib/mcp-headers-helper-trust.js +145 -0
  253. package/src/lib/mcp-headers-helper.js +616 -0
  254. package/src/lib/mcp-host-recovery-runtime.js +131 -0
  255. package/src/lib/mcp-ledger-recovery-admission.js +1065 -0
  256. package/src/lib/mcp-recovery-adjudication.js +443 -0
  257. package/src/lib/output-context.js +86 -0
  258. package/src/lib/packer/file-identity.js +170 -0
  259. package/src/lib/packer/index.js +3 -0
  260. package/src/lib/packer/native-update-state.js +277 -0
  261. package/src/lib/packer/pack-update-applier.js +1983 -136
  262. package/src/lib/packer/pack-update-checker.js +34 -0
  263. package/src/lib/packer/pack-update-downloader.js +875 -86
  264. package/src/lib/packer/pack-update-signature.js +86 -0
  265. package/src/lib/packer/pkg-config-generator.js +6 -0
  266. package/src/lib/paths.js +65 -10
  267. package/src/lib/plan-mode.js +831 -14
  268. package/src/lib/plan-persistence.js +540 -0
  269. package/src/lib/plugin-runtime/hooks.js +227 -69
  270. package/src/lib/plugin-runtime/plugin-options.js +189 -44
  271. package/src/lib/pr-automation-policy.js +146 -8
  272. package/src/lib/process-execution-broker/credential-agent.js +7 -0
  273. package/src/lib/process-execution-broker/index.js +491 -13
  274. package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +28 -1
  275. package/src/lib/process-execution-broker/linux-generic-bwrap.js +28 -4
  276. package/src/lib/process-execution-broker/platform-sandbox.js +92 -70
  277. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  278. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  279. package/src/lib/process-execution-broker/windows-sandbox.cs +284 -19
  280. package/src/lib/process-execution-broker/workspace-transaction.js +4459 -0
  281. package/src/lib/project-instructions.js +165 -29
  282. package/src/lib/project-mcp-trust.js +67 -0
  283. package/src/lib/public-ide-capability-manifest.js +272 -0
  284. package/src/lib/public-ide-capability-validation.js +351 -0
  285. package/src/lib/secret-store.js +267 -43
  286. package/src/lib/secure-file-identity.js +433 -0
  287. package/src/lib/secure-fs.js +1089 -0
  288. package/src/lib/security-audit.js +58 -0
  289. package/src/lib/service-manager.js +34 -13
  290. package/src/lib/session-budget-runtime.js +1452 -0
  291. package/src/lib/session-host-snapshot.js +388 -0
  292. package/src/lib/session-message-provenance.js +429 -0
  293. package/src/lib/session-projection.js +804 -0
  294. package/src/lib/session-resource-budget.js +1495 -0
  295. package/src/lib/settings-hooks.cjs +138 -22
  296. package/src/lib/settings-loader.cjs +25 -2
  297. package/src/lib/side-effect-ledger-store.js +45 -23
  298. package/src/lib/skill-execution-identity.js +217 -0
  299. package/src/lib/skill-loader.js +299 -18
  300. package/src/lib/sub-agent-context.js +236 -28
  301. package/src/lib/sub-agent-registry.js +5 -0
  302. package/src/lib/subagent-contract.js +94 -0
  303. package/src/lib/todo-manager.js +185 -18
  304. package/src/lib/todo-persistence.js +417 -0
  305. package/src/lib/turn-binding-store.js +41 -23
  306. package/src/lib/turn-binding.js +160 -2
  307. package/src/lib/with-file-lock.js +165 -24
  308. package/src/lib/ws-chat-handler.js +21 -0
  309. package/src/program-base.js +18 -0
  310. package/src/repl/advisor-command.js +103 -0
  311. package/src/repl/agent-repl.js +2175 -146
  312. package/src/repl/btw-command.js +93 -10
  313. package/src/repl/clipboard-image.js +119 -0
  314. package/src/repl/config-summary.js +64 -108
  315. package/src/repl/prompt-editor.js +233 -0
  316. package/src/repl/prompt-interactions.js +344 -0
  317. package/src/repl/prompt-stash.js +354 -0
  318. package/src/repl/prompt-suggestions.js +312 -0
  319. package/src/repl/repl-keybindings.js +227 -0
  320. package/src/repl/session-recap.js +217 -0
  321. package/src/repl/slash-command-registry.js +22 -0
  322. package/src/repl/terminal-layout.js +88 -0
  323. package/src/runtime/agent-core.js +1630 -447
  324. package/src/runtime/coding-agent-contract-shared.cjs +13 -1
  325. package/src/runtime/coding-agent-managed-tool-policy.cjs +7 -2
  326. package/src/runtime/diagnostics.js +32 -13
  327. package/src/runtime/headless-runner.js +310 -118
  328. package/src/runtime/headless-stream.js +356 -95
  329. package/src/runtime/mcp-config.js +148 -14
  330. package/src/runtime/policies/agent-policy.js +14 -0
  331. package/src/runtime/status-diagnostics-lite.js +137 -0
  332. package/src/assets/web-panel/assets/MarkdownRenderer-7iWGwZ-r.js +0 -1
  333. package/src/assets/web-panel/assets/OrderTableRenderer-BU2Yqq5H.js +0 -1
  334. package/src/assets/web-panel/assets/PdhVaultBrowser-69ca_WeR.js +0 -7
  335. package/src/assets/web-panel/assets/devWarning-B4dXIJqD.js +0 -1
  336. package/src/assets/web-panel/assets/index-C-C7DaG6.js +0 -1
  337. package/src/assets/web-panel/assets/index-DkfWzWtd.js +0 -1
@@ -1,57 +1,622 @@
1
1
  /**
2
- * Lazy CLI dispatch - fast path for single commands, full program for help/unknown
2
+ * Two-phase CLI dispatcher.
3
+ *
4
+ * Phase 0 handles version, root help and default-agent routing with built-in
5
+ * Node modules plus the generated manifest only. Command modules, Commander,
6
+ * the process broker, telemetry and the Event Runtime are loaded afterwards.
3
7
  */
4
- import { createProgramAsync } from "./index.js";
5
- import { pathToFileURL } from "node:url";
6
- import { dirname, join } from "node:path";
7
- import { fileURLToPath } from "node:url";
8
8
  import { readFileSync } from "node:fs";
9
+ import { dirname, join } from "node:path";
10
+ import { pathToFileURL, fileURLToPath } from "node:url";
9
11
  import {
10
- startDefaultEventRuntimeHost,
11
- stopDefaultEventRuntimeHost,
12
- } from "./lib/event-runtime-host.js";
12
+ buildHelpDocument,
13
+ buildNamespaceHelpDocument,
14
+ formatNamespaceHelp,
15
+ formatRootHelp,
16
+ } from "./cli-help.js";
13
17
 
14
18
  const __dirname = dirname(fileURLToPath(import.meta.url));
15
19
  const manifest = JSON.parse(
16
20
  readFileSync(join(__dirname, "command-manifest.json"), "utf8"),
17
21
  );
22
+ const packageMetadata = JSON.parse(
23
+ readFileSync(join(__dirname, "..", "package.json"), "utf8"),
24
+ );
25
+
26
+ const ROOT_HELP_FLAGS = new Set(["--help", "-h"]);
27
+ const ROOT_VERSION_FLAGS = new Set(["--version", "-v", "-V"]);
28
+ const HELP_CONTROL_FLAGS = new Set(["--all", "-a", "--json"]);
18
29
 
19
30
  /**
20
- * Run the CLI with lazy dispatch optimization
21
- * @param {string[]} argv - process.argv
22
- * @returns {Promise<void>}
31
+ * Dependency-free mirror of program-base.js' Commander root options. Tests
32
+ * compare names and arity against createBaseProgram(), so phase 0 cannot
33
+ * silently widen this allowlist or drift from phase 1.
23
34
  */
24
- /** Return the first top-level command token in a process argv array. */
25
- export function resolveCommandToken(argv = []) {
26
- const args = Array.isArray(argv) ? argv.slice(2) : [];
27
- for (let index = 0; index < args.length; index++) {
28
- const token = args[index];
29
- if (token === "--") return null;
30
- if (token === "--verbose" || token === "--quiet") continue;
31
- if (token === "--otlp-endpoint" || token === "--jsii-runtime") {
35
+ export const PHASE_ZERO_GLOBAL_OPTION_SCHEMA = Object.freeze([
36
+ Object.freeze({ flag: "--verbose", arity: 0 }),
37
+ Object.freeze({ flag: "--quiet", arity: 0 }),
38
+ Object.freeze({
39
+ flag: "--jsii-runtime",
40
+ arity: 1,
41
+ allowedValues: Object.freeze(["native", "quickjs"]),
42
+ }),
43
+ Object.freeze({
44
+ flag: "--otlp-endpoint",
45
+ arity: 1,
46
+ allowedProtocols: Object.freeze(["http:", "https:"]),
47
+ }),
48
+ ]);
49
+
50
+ const GLOBAL_OPTION_BY_FLAG = new Map(
51
+ PHASE_ZERO_GLOBAL_OPTION_SCHEMA.map((option) => [option.flag, option]),
52
+ );
53
+
54
+ function writeLine(stream, value) {
55
+ stream.write(`${value}\n`);
56
+ }
57
+
58
+ function findManifestEntry(commandName, manifestData = manifest) {
59
+ if (!commandName) return null;
60
+ return (
61
+ manifestData.commands.find(
62
+ (entry) =>
63
+ entry.name === commandName || entry.aliases?.includes(commandName),
64
+ ) || null
65
+ );
66
+ }
67
+
68
+ function validateGlobalOptionValue(option, value) {
69
+ if (typeof value !== "string" || value.length === 0) {
70
+ return `Global option '${option.flag}' requires a value`;
71
+ }
72
+ if (option.allowedValues && !option.allowedValues.includes(value)) {
73
+ return (
74
+ `Global option '${option.flag}' must be one of: ` +
75
+ option.allowedValues.join(", ")
76
+ );
77
+ }
78
+ if (option.allowedProtocols) {
79
+ let parsed;
80
+ try {
81
+ parsed = new URL(value);
82
+ } catch {
83
+ return `Global option '${option.flag}' requires an absolute http(s) URL`;
84
+ }
85
+ if (
86
+ !option.allowedProtocols.includes(parsed.protocol) ||
87
+ !parsed.hostname
88
+ ) {
89
+ return `Global option '${option.flag}' requires an absolute http(s) URL`;
90
+ }
91
+ }
92
+ return null;
93
+ }
94
+
95
+ function consumeGlobalOption(argv, index) {
96
+ const token = argv[index];
97
+ const equalsIndex = token.indexOf("=");
98
+ const flag = equalsIndex < 0 ? token : token.slice(0, equalsIndex);
99
+ const option = GLOBAL_OPTION_BY_FLAG.get(flag);
100
+ if (!option) return null;
101
+
102
+ if (option.arity === 0) {
103
+ return {
104
+ nextIndex: index + 1,
105
+ error:
106
+ equalsIndex < 0
107
+ ? null
108
+ : `Global option '${option.flag}' does not accept a value`,
109
+ };
110
+ }
111
+
112
+ if (equalsIndex >= 0) {
113
+ return {
114
+ nextIndex: index + 1,
115
+ error: validateGlobalOptionValue(option, token.slice(equalsIndex + 1)),
116
+ };
117
+ }
118
+
119
+ const value = argv[index + 1];
120
+ if (typeof value !== "string" || value.startsWith("-")) {
121
+ return {
122
+ nextIndex: index + 1,
123
+ error: `Global option '${option.flag}' requires a value`,
124
+ };
125
+ }
126
+ return {
127
+ nextIndex: index + 2,
128
+ error: validateGlobalOptionValue(option, value),
129
+ };
130
+ }
131
+
132
+ function scanLeadingCommand(argv = []) {
133
+ let firstError = null;
134
+ for (let index = 2; index < argv.length;) {
135
+ const token = argv[index];
136
+ if (token === "--") return { location: null, error: firstError };
137
+ if (ROOT_HELP_FLAGS.has(token) || ROOT_VERSION_FLAGS.has(token)) {
138
+ return { location: null, error: firstError };
139
+ }
140
+ const globalOption = consumeGlobalOption(argv, index);
141
+ if (globalOption) {
142
+ firstError ||= globalOption.error;
143
+ index = globalOption.nextIndex;
144
+ continue;
145
+ }
146
+ if (token.startsWith("-")) {
147
+ firstError ||= `Unknown global option '${token}'`;
32
148
  index++;
33
149
  continue;
34
150
  }
151
+ return { location: { index, token }, error: firstError };
152
+ }
153
+ return { location: null, error: firstError };
154
+ }
155
+
156
+ function findCommandTokenLocation(argv = []) {
157
+ return scanLeadingCommand(argv).location;
158
+ }
159
+
160
+ function commandNamespace(manifestData, name) {
161
+ return (manifestData?.surface?.namespaces || []).find(
162
+ (candidate) => candidate.name === name,
163
+ );
164
+ }
165
+
166
+ function findHelpSubjectLocation(argv, helpIndex) {
167
+ let firstError = null;
168
+ for (let index = helpIndex + 1; index < argv.length;) {
169
+ const token = argv[index];
170
+ if (token === "--") return { location: null, error: firstError };
35
171
  if (
36
- token.startsWith("--otlp-endpoint=") ||
37
- token.startsWith("--jsii-runtime=")
172
+ HELP_CONTROL_FLAGS.has(token) ||
173
+ ROOT_HELP_FLAGS.has(token) ||
174
+ ROOT_VERSION_FLAGS.has(token)
38
175
  ) {
176
+ index++;
177
+ continue;
178
+ }
179
+ const globalOption = consumeGlobalOption(argv, index);
180
+ if (globalOption) {
181
+ firstError ||= globalOption.error;
182
+ index = globalOption.nextIndex;
183
+ continue;
184
+ }
185
+ if (token.startsWith("-")) {
186
+ firstError ||= `Unknown global option '${token}'`;
187
+ index++;
188
+ continue;
189
+ }
190
+ return { location: { index, token }, error: firstError };
191
+ }
192
+ return { location: null, error: firstError };
193
+ }
194
+
195
+ function namespaceEntry(manifestData, namespace, target) {
196
+ if (!namespace?.commands?.includes(target)) return null;
197
+ const entry = findManifestEntry(target, manifestData);
198
+ if (!entry || entry.replacement !== `${namespace.name} ${entry.name}`) {
199
+ return null;
200
+ }
201
+ return entry;
202
+ }
203
+
204
+ function scanNamespaceTarget(
205
+ argv,
206
+ namespaceIndex,
207
+ { helpInvocation = false } = {},
208
+ ) {
209
+ for (let index = namespaceIndex + 1; index < argv.length;) {
210
+ const token = argv[index];
211
+ if (token === "--") {
212
+ return {
213
+ error: "'--' may only appear after a lab command target",
214
+ };
215
+ }
216
+ if (ROOT_HELP_FLAGS.has(token)) return { help: true };
217
+ if (ROOT_VERSION_FLAGS.has(token)) return { version: true };
218
+ if (HELP_CONTROL_FLAGS.has(token)) {
219
+ if (helpInvocation) {
220
+ index++;
221
+ continue;
222
+ }
223
+ return {
224
+ error: `Option '${token}' must follow a lab command target`,
225
+ };
226
+ }
227
+ const globalOption = consumeGlobalOption(argv, index);
228
+ if (globalOption) {
229
+ if (globalOption.error) return { error: globalOption.error };
230
+ index = globalOption.nextIndex;
39
231
  continue;
40
232
  }
41
- if (["--help", "-h", "--version", "-v", "-V"].includes(token)) return null;
42
- if (!token.startsWith("-")) return token;
233
+ if (token.startsWith("-")) {
234
+ return { error: `Unknown option '${token}' before lab command target` };
235
+ }
236
+ return { index, target: token };
237
+ }
238
+ return { help: true };
239
+ }
240
+
241
+ function rewriteNamespaceArgv(argv, namespaceIndex, targetIndex, target) {
242
+ return [
243
+ ...argv.slice(0, namespaceIndex),
244
+ ...argv.slice(namespaceIndex + 1, targetIndex),
245
+ target,
246
+ ...argv.slice(targetIndex + 1),
247
+ ];
248
+ }
249
+
250
+ function namespaceError(message) {
251
+ return {
252
+ kind: "namespace-error",
253
+ message: `${message}. Run 'cc lab --help' for available commands.`,
254
+ };
255
+ }
256
+
257
+ /**
258
+ * Resolve virtual compatibility namespaces before Commander is imported.
259
+ * Rewrites only argv; the selected legacy manifest entry and registrar remain
260
+ * the sole route that can execute the action.
261
+ */
262
+ export function resolveCommandLifecycleInvocation(
263
+ argv,
264
+ manifestData = manifest,
265
+ ) {
266
+ const leading = scanLeadingCommand(argv);
267
+ const location = leading.location;
268
+ const args = argv.slice(2);
269
+ const endOfOptions = args.indexOf("--");
270
+ if (!location) {
271
+ if (endOfOptions >= 0 && args[endOfOptions + 1] === "lab") {
272
+ return namespaceError("The lab namespace must appear before '--'");
273
+ }
274
+ return { kind: "passthrough", argv };
275
+ }
276
+
277
+ if (location.token === "help") {
278
+ const subjectScan = findHelpSubjectLocation(argv, location.index);
279
+ const subject = subjectScan.location;
280
+ if (!subject) return { kind: "passthrough", argv };
281
+ const namespaceIndex = subject.index;
282
+ const namespace = commandNamespace(manifestData, subject.token);
283
+ if (!namespace) return { kind: "passthrough", argv };
284
+ if (leading.error || subjectScan.error) {
285
+ return namespaceError(leading.error || subjectScan.error);
286
+ }
287
+ const target = scanNamespaceTarget(argv, namespaceIndex, {
288
+ helpInvocation: true,
289
+ });
290
+ if (target.error) return namespaceError(target.error);
291
+ if (target.help || target.version) {
292
+ return {
293
+ kind: "namespace-help",
294
+ namespace,
295
+ json: args.includes("--json"),
296
+ };
297
+ }
298
+ const entry = namespaceEntry(manifestData, namespace, target.target);
299
+ if (!entry) {
300
+ return namespaceError(
301
+ `Unknown ${namespace.name} command '${target.target}'`,
302
+ );
303
+ }
304
+ return {
305
+ kind: "namespace-rewrite",
306
+ namespace,
307
+ entry,
308
+ argv: rewriteNamespaceArgv(
309
+ argv,
310
+ namespaceIndex,
311
+ target.index,
312
+ entry.name,
313
+ ),
314
+ };
315
+ }
316
+
317
+ const namespace = commandNamespace(manifestData, location.token);
318
+ if (!namespace) return { kind: "passthrough", argv };
319
+ if (leading.error) return namespaceError(leading.error);
320
+ const target = scanNamespaceTarget(argv, location.index);
321
+ if (target.error) return namespaceError(target.error);
322
+ if (target.version) return { kind: "namespace-version", namespace };
323
+ if (target.help) {
324
+ return { kind: "namespace-help", namespace, json: args.includes("--json") };
325
+ }
326
+ const entry = namespaceEntry(manifestData, namespace, target.target);
327
+ if (!entry) {
328
+ return namespaceError(
329
+ `Unknown ${namespace.name} command '${target.target}'`,
330
+ );
331
+ }
332
+ return {
333
+ kind: "namespace-rewrite",
334
+ namespace,
335
+ entry,
336
+ argv: rewriteNamespaceArgv(argv, location.index, target.index, entry.name),
337
+ };
338
+ }
339
+
340
+ export function formatCommandDeprecationWarning(entry, invokedName) {
341
+ const lifecycle = entry?.lifecycle;
342
+ if (lifecycle?.state !== "deprecated" || !entry.replacement) return null;
343
+ return (
344
+ `Deprecated command 'cc ${invokedName}' (since ${lifecycle.deprecatedSince}); ` +
345
+ `use 'cc ${entry.replacement}'. Removal will not occur before ` +
346
+ `${lifecycle.removalNotBefore} (${lifecycle.minimumReleaseCycles} ` +
347
+ `${lifecycle.releaseCycle} release cycles).`
348
+ );
349
+ }
350
+
351
+ let commandHelpIndex = null;
352
+
353
+ function readCommandHelp(entry) {
354
+ if (!commandHelpIndex) {
355
+ try {
356
+ commandHelpIndex = JSON.parse(
357
+ readFileSync(join(__dirname, "command-help-index.json"), "utf8"),
358
+ );
359
+ } catch {
360
+ commandHelpIndex = { commands: {} };
361
+ }
362
+ }
363
+ return commandHelpIndex.commands?.[entry?.name] || null;
364
+ }
365
+
366
+ /** Return the first top-level command token in a process argv array. */
367
+ export function resolveCommandToken(argv = []) {
368
+ return findCommandTokenLocation(argv)?.token || null;
369
+ }
370
+
371
+ function hasOnlyGlobalOptions(argv = []) {
372
+ for (let index = 2; index < argv.length;) {
373
+ const globalOption = consumeGlobalOption(argv, index);
374
+ if (!globalOption || globalOption.error) return false;
375
+ index = globalOption.nextIndex;
376
+ }
377
+ return true;
378
+ }
379
+
380
+ function helpRequest(argv, manifestData = manifest) {
381
+ const args = argv.slice(2);
382
+ const commandName = resolveCommandToken(argv);
383
+ if (commandName === "help") {
384
+ const helpIndex = args.indexOf("help");
385
+ const rest = args.slice(helpIndex + 1);
386
+ const subjectScan = findHelpSubjectLocation(argv, helpIndex + 2);
387
+ if (subjectScan.error) return null;
388
+ const requestedCommand = subjectScan.location?.token;
389
+ return {
390
+ all: rest.includes("--all") || rest.includes("-a"),
391
+ json: rest.includes("--json"),
392
+ entry: findManifestEntry(requestedCommand, manifestData),
393
+ requestedCommand: requestedCommand || null,
394
+ };
395
+ }
396
+ const entry = findManifestEntry(commandName, manifestData);
397
+ if (entry && args.some((token) => ROOT_HELP_FLAGS.has(token))) {
398
+ const commandIndex = args.indexOf(commandName);
399
+ const hasAdditionalPositional = args
400
+ .slice(commandIndex + 1)
401
+ .some((token) => !token.startsWith("-") && !ROOT_HELP_FLAGS.has(token));
402
+ // The generated index intentionally contains top-level command help only.
403
+ // A positional after the domain may be a nested command (or a command
404
+ // argument), so phase 0 must not replace its help with the parent page.
405
+ // Loading the one manifest registrar remains lazy while allowing Commander
406
+ // to resolve arbitrarily deep `cc <domain> <subcommand> --help` requests.
407
+ if (hasAdditionalPositional) return null;
408
+ return {
409
+ all: false,
410
+ json: args.includes("--json"),
411
+ entry,
412
+ requestedCommand: entry.name,
413
+ direct: true,
414
+ };
415
+ }
416
+ if (
417
+ commandName === null &&
418
+ args.some((token) => ROOT_HELP_FLAGS.has(token))
419
+ ) {
420
+ return {
421
+ all: args.includes("--all") || args.includes("-a"),
422
+ json: args.includes("--json"),
423
+ entry: null,
424
+ requestedCommand: null,
425
+ };
43
426
  }
44
427
  return null;
45
428
  }
46
429
 
430
+ function rewriteHelpCommand(argv, commandName) {
431
+ const args = argv.slice(2);
432
+ const helpIndex = args.indexOf("help");
433
+ const beforeHelp = args.slice(0, helpIndex);
434
+ const afterCommand = args
435
+ .slice(helpIndex + 1)
436
+ .filter((token) => token !== commandName && token !== "--json");
437
+ return [
438
+ argv[0],
439
+ argv[1],
440
+ ...beforeHelp,
441
+ commandName,
442
+ "--help",
443
+ ...afterCommand,
444
+ ];
445
+ }
446
+
447
+ function appendDefaultCommand(argv, manifestData, prompt = null) {
448
+ const defaultCommand = manifestData?.surface?.defaultCommand || "agent";
449
+ const next = [...argv, defaultCommand];
450
+ // Inline form keeps prompts beginning with '-' from being reinterpreted as
451
+ // another option by Commander after stdin has already been consumed.
452
+ if (prompt !== null) next.push(`--print=${prompt}`);
453
+ return next;
454
+ }
455
+
456
+ function readInput(stream) {
457
+ return new Promise((resolve) => {
458
+ let data = "";
459
+ stream.setEncoding?.("utf8");
460
+ stream.on("data", (chunk) => {
461
+ data += chunk;
462
+ });
463
+ stream.on("end", () => resolve(data));
464
+ stream.on("error", () => resolve(data));
465
+ stream.resume?.();
466
+ });
467
+ }
468
+
469
+ /**
470
+ * Resolve phase-0 requests without importing Commander or any command module.
471
+ * Returns either a handled result or the argv that should enter phase 1.
472
+ */
473
+ export async function prepareInvocation(
474
+ argv,
475
+ {
476
+ stdin = process.stdin,
477
+ stdout = process.stdout,
478
+ stderr = process.stderr,
479
+ manifestData = manifest,
480
+ version = packageMetadata.version,
481
+ readStdin = readInput,
482
+ } = {},
483
+ ) {
484
+ const lifecycleInvocation = resolveCommandLifecycleInvocation(
485
+ argv,
486
+ manifestData,
487
+ );
488
+ if (lifecycleInvocation.kind === "namespace-error") {
489
+ writeLine(stderr, lifecycleInvocation.message);
490
+ return { handled: true, kind: "namespace-error", exitCode: 1 };
491
+ }
492
+ if (lifecycleInvocation.kind === "namespace-version") {
493
+ writeLine(stdout, version);
494
+ return { handled: true, kind: "version" };
495
+ }
496
+ if (lifecycleInvocation.kind === "namespace-help") {
497
+ if (lifecycleInvocation.json) {
498
+ writeLine(
499
+ stdout,
500
+ JSON.stringify(
501
+ buildNamespaceHelpDocument(
502
+ manifestData,
503
+ lifecycleInvocation.namespace.name,
504
+ ),
505
+ ),
506
+ );
507
+ } else {
508
+ stdout.write(
509
+ formatNamespaceHelp(manifestData, lifecycleInvocation.namespace.name),
510
+ );
511
+ }
512
+ return { handled: true, kind: "namespace-help" };
513
+ }
514
+
515
+ argv = lifecycleInvocation.argv;
516
+ const args = argv.slice(2);
517
+ const commandName = resolveCommandToken(argv);
518
+
519
+ if (lifecycleInvocation.kind !== "namespace-rewrite") {
520
+ const invokedEntry = findManifestEntry(commandName, manifestData);
521
+ const warning = formatCommandDeprecationWarning(invokedEntry, commandName);
522
+ if (warning) writeLine(stderr, warning);
523
+ }
524
+
525
+ if (
526
+ commandName === null &&
527
+ args.some((token) => ROOT_VERSION_FLAGS.has(token))
528
+ ) {
529
+ writeLine(stdout, version);
530
+ return { handled: true, kind: "version" };
531
+ }
532
+
533
+ const help = helpRequest(argv, manifestData);
534
+ if (help) {
535
+ if (
536
+ lifecycleInvocation.kind !== "namespace-rewrite" &&
537
+ commandName === "help" &&
538
+ help.entry
539
+ ) {
540
+ const warning = formatCommandDeprecationWarning(
541
+ help.entry,
542
+ help.requestedCommand,
543
+ );
544
+ if (warning) writeLine(stderr, warning);
545
+ }
546
+ if (help.requestedCommand) {
547
+ if (!help.entry) return { handled: false, argv, kind: "unknown-help" };
548
+ if (help.json) {
549
+ const command = buildHelpDocument(manifestData, {
550
+ all: true,
551
+ }).commands.find((candidate) => candidate.name === help.entry.name);
552
+ writeLine(
553
+ stdout,
554
+ JSON.stringify({
555
+ schema: "chainlesschain.command-help.v1",
556
+ command,
557
+ }),
558
+ );
559
+ return { handled: true, kind: "command-help-json" };
560
+ }
561
+ const generatedHelp = readCommandHelp(help.entry);
562
+ if (generatedHelp) {
563
+ stdout.write(
564
+ generatedHelp.endsWith("\n") ? generatedHelp : `${generatedHelp}\n`,
565
+ );
566
+ return { handled: true, kind: "command-help" };
567
+ }
568
+ if (help.direct) {
569
+ return { handled: false, argv, kind: "command-help" };
570
+ }
571
+ return {
572
+ handled: false,
573
+ argv: rewriteHelpCommand(argv, help.requestedCommand),
574
+ kind: "command-help",
575
+ };
576
+ }
577
+ if (help.json) {
578
+ writeLine(stdout, JSON.stringify(buildHelpDocument(manifestData, help)));
579
+ } else {
580
+ stdout.write(formatRootHelp(manifestData, help));
581
+ }
582
+ return { handled: true, kind: help.all ? "help-all" : "help" };
583
+ }
584
+
585
+ if (commandName === null && hasOnlyGlobalOptions(argv)) {
586
+ if (stdin.isTTY && stdout.isTTY) {
587
+ return {
588
+ handled: false,
589
+ argv: appendDefaultCommand(argv, manifestData),
590
+ kind: "default-agent",
591
+ };
592
+ }
593
+ if (!stdin.isTTY) {
594
+ const piped = await readStdin(stdin);
595
+ if (piped.trim()) {
596
+ return {
597
+ handled: false,
598
+ argv: appendDefaultCommand(argv, manifestData, piped),
599
+ kind: "default-agent-stdin",
600
+ };
601
+ }
602
+ }
603
+ stdout.write(formatRootHelp(manifestData));
604
+ return { handled: true, kind: "non-interactive-help" };
605
+ }
606
+
607
+ return { handled: false, argv, kind: "command" };
608
+ }
609
+
47
610
  export async function withDefaultEventRuntimeLifecycle(
48
611
  task,
49
- { hostOptions = {} } = {},
612
+ { hostOptions = {}, runtimeModule = null } = {},
50
613
  ) {
51
614
  if (typeof task !== "function") {
52
615
  throw new TypeError("Event Runtime lifecycle task must be a function");
53
616
  }
54
- const host = startDefaultEventRuntimeHost({
617
+ const runtime =
618
+ runtimeModule || (await import("./lib/event-runtime-host.js"));
619
+ const host = runtime.startDefaultEventRuntimeHost({
55
620
  ...hostOptions,
56
621
  // Let the selected command finish registering its handlers before the
57
622
  // first claim. Resident commands then run on the normal interval; short
@@ -61,88 +626,186 @@ export async function withDefaultEventRuntimeLifecycle(
61
626
  try {
62
627
  return await task(host);
63
628
  } finally {
64
- if (host) await stopDefaultEventRuntimeHost({ drain: true });
629
+ if (host) await runtime.stopDefaultEventRuntimeHost({ drain: true });
65
630
  }
66
631
  }
67
632
 
68
- async function dispatchCli(argv) {
69
- const args = argv.slice(2);
70
-
71
- // Resolve the command before deciding whether help/version needs the eager
72
- // program. `cc <command> --help` is command-scoped help and must load only
73
- // that command; treating every `--help` as root help silently discards the
74
- // command token (and broke `cc agent --help` after lazy dispatch landed).
75
- const commandName = resolveCommandToken(argv);
76
- const entry = manifest.commands.find(
77
- (c) =>
78
- c.name === commandName || (c.aliases && c.aliases.includes(commandName)),
79
- );
633
+ async function defaultLoadCommandModule(entry) {
634
+ const modulePath = join(__dirname, entry.module.replace("./", ""));
635
+ return import(pathToFileURL(modulePath).href);
636
+ }
80
637
 
81
- // Fast path: if no args, or --help, or --version, use full program
82
- if (
83
- args.length === 0 ||
84
- (!entry &&
85
- (args.includes("--help") ||
86
- args.includes("-h") ||
87
- args.includes("--version") ||
88
- args.includes("-V")))
89
- ) {
90
- const program = await createProgramAsync();
91
- await program.parseAsync(argv);
92
- return;
93
- }
638
+ async function defaultCreateBaseProgram() {
639
+ const { createBaseProgram } = await import("./program-base.js");
640
+ return createBaseProgram();
641
+ }
94
642
 
95
- // Try to find the command in manifest
96
- // Unknown command, use full program to show error/help
97
- if (!entry) {
98
- const program = await createProgramAsync();
99
- await program.parseAsync(argv);
100
- return;
101
- }
643
+ async function defaultLoadFullProgram() {
644
+ const { createProgramAsync } = await import("./index.js");
645
+ return createProgramAsync();
646
+ }
102
647
 
103
- // Known command: lazy-load just that command, create minimal program
648
+ /**
649
+ * Load/register may fall back to the compatibility program. parseAsync is
650
+ * intentionally outside that catch: once an action begins, any failure must
651
+ * propagate and the command must never be run for a second time.
652
+ */
653
+ export async function dispatchManifestEntry(
654
+ argv,
655
+ entry,
656
+ {
657
+ loadCommandModule = defaultLoadCommandModule,
658
+ createBaseProgram = defaultCreateBaseProgram,
659
+ loadFullProgram = defaultLoadFullProgram,
660
+ stderr = process.stderr,
661
+ env = process.env,
662
+ } = {},
663
+ ) {
664
+ let program;
104
665
  try {
105
- const { createBaseProgram } = await import("./program-base.js");
106
- const program = createBaseProgram();
107
-
108
- const modulePath = join(__dirname, entry.module.replace("./", ""));
109
- const moduleUrl = pathToFileURL(modulePath).href;
110
- const mod = await import(moduleUrl);
666
+ program = await createBaseProgram();
667
+ const mod = await loadCommandModule(entry);
111
668
  const registerFn = mod[entry.register];
112
-
113
669
  if (typeof registerFn !== "function") {
114
670
  throw new Error(
115
671
  `Register function '${entry.register}' not found in ${entry.module}`,
116
672
  );
117
673
  }
118
-
119
674
  registerFn(program);
120
- await program.parseAsync(argv);
121
- } catch (err) {
122
- // Fallback to full program on any error
123
- if (process.env.DEBUG) {
124
- console.warn(
125
- "Lazy dispatch failed, falling back to full program:",
126
- err.message,
675
+ } catch (error) {
676
+ if (env.DEBUG || env.CC_DEBUG) {
677
+ stderr.write(
678
+ `Lazy command registration failed; loading compatibility program: ${error.message}\n`,
127
679
  );
128
680
  }
129
- const program = await createProgramAsync();
681
+ program = await loadFullProgram();
682
+ }
683
+
684
+ // Do not wrap this call in the registration fallback above. An action may
685
+ // have already written files, sent a request, or emitted an event.
686
+ await program.parseAsync(argv);
687
+ }
688
+
689
+ export async function dispatchCli(
690
+ argv,
691
+ { manifestData = manifest, ...dispatchOptions } = {},
692
+ ) {
693
+ const commandName = resolveCommandToken(argv);
694
+ const entry = findManifestEntry(commandName, manifestData);
695
+ if (!entry) {
696
+ const program = await (
697
+ dispatchOptions.loadFullProgram || defaultLoadFullProgram
698
+ )();
130
699
  await program.parseAsync(argv);
700
+ return;
131
701
  }
702
+ await dispatchManifestEntry(argv, entry, dispatchOptions);
132
703
  }
133
704
 
134
- export async function runCli(argv) {
135
- return withDefaultEventRuntimeLifecycle(() => dispatchCli(argv));
705
+ export function isFastReadOnlyInvocation(argv, env = process.env) {
706
+ const args = argv.slice(2);
707
+ return (
708
+ resolveCommandToken(argv) === "status" &&
709
+ !args.includes("--deep") &&
710
+ !args.includes("--otlp-endpoint") &&
711
+ !args.some((token) => token.startsWith("--otlp-endpoint=")) &&
712
+ !env.OTEL_EXPORTER_OTLP_ENDPOINT &&
713
+ !env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT &&
714
+ !env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
715
+ );
136
716
  }
137
717
 
138
- export class LazyDispatch {
139
- constructor(manifest) {
140
- this.manifest = manifest;
718
+ let processHandlersInstalled = false;
719
+
720
+ async function initializeCommandRuntime(argv) {
721
+ // The broker must patch child_process before a command graph can cache a
722
+ // native reference. Phase-0 requests execute before this expensive import.
723
+ await import("./lib/process-execution-broker/patch-child-process.js");
724
+ const [{ ensureUtf8 }, observabilityModule, fatalModule] = await Promise.all([
725
+ import("./lib/ensure-utf8.js"),
726
+ import("./lib/observability/index.js"),
727
+ import("./lib/fatal-handler.js"),
728
+ ]);
729
+ ensureUtf8();
730
+
731
+ for (const stream of [process.stdout, process.stderr]) {
732
+ if (!stream.isTTY && stream._handle?.setBlocking) {
733
+ stream._handle.setBlocking(true);
734
+ }
141
735
  }
142
- matches(argv) {
143
- return false;
736
+
737
+ const observability = observabilityModule.initObservability({
738
+ endpoint: observabilityModule.resolveOtlpEndpointFromArgv(argv),
739
+ });
740
+ if (!processHandlersInstalled) {
741
+ fatalModule.installGlobalErrorHandlers(process, async (error) => {
742
+ await observability.shutdown().catch(() => {});
743
+ fatalModule.reportFatal(error);
744
+ });
745
+ processHandlersInstalled = true;
144
746
  }
145
- async spawn(argv) {
146
- return false;
747
+ return observability;
748
+ }
749
+
750
+ async function withInvocationOutputContext(argv, task) {
751
+ const output = await import("./lib/output-context.js");
752
+ const previous = output.getOutputContext();
753
+ const args = argv.slice(2);
754
+ output.bindOutputContext({
755
+ quiet: args.includes("--quiet"),
756
+ verbose: args.includes("--verbose"),
757
+ machineReadable: output.argvRequestsMachineReadableOutput(argv),
758
+ });
759
+ try {
760
+ return await task();
761
+ } finally {
762
+ // Keep diagnostics emitted while the Event Runtime and observability are
763
+ // shutting down under the same contract as the command itself, then put
764
+ // the process singleton back for programmatic/repeated invocations.
765
+ output.bindOutputContext(previous);
147
766
  }
148
767
  }
768
+
769
+ export async function runCli(argv, options = {}) {
770
+ const prepared = await prepareInvocation(argv, options);
771
+ if (prepared.handled) {
772
+ if (prepared.exitCode) {
773
+ if (typeof options.setExitCode === "function") {
774
+ options.setExitCode(prepared.exitCode);
775
+ } else {
776
+ process.exitCode = prepared.exitCode;
777
+ }
778
+ }
779
+ return;
780
+ }
781
+
782
+ const dispatchArgv = prepared.argv;
783
+ return withInvocationOutputContext(dispatchArgv, async () => {
784
+ const commandHelp =
785
+ prepared.kind === "command-help" ||
786
+ dispatchArgv.slice(2).some((token) => ROOT_HELP_FLAGS.has(token));
787
+ if (commandHelp) {
788
+ await dispatchCli(dispatchArgv, options);
789
+ return;
790
+ }
791
+
792
+ // Quick status performs filesystem/PID/PATH/TCP reads only. Keeping it in
793
+ // phase 1 avoids initializing the process sandbox and telemetry solely to
794
+ // report that those services are absent. --deep and explicit OTLP probes
795
+ // still enter the full managed runtime below.
796
+ if (isFastReadOnlyInvocation(dispatchArgv)) {
797
+ await dispatchCli(dispatchArgv, options);
798
+ return;
799
+ }
800
+
801
+ const observability = await initializeCommandRuntime(dispatchArgv);
802
+ try {
803
+ return await withDefaultEventRuntimeLifecycle(
804
+ () => dispatchCli(dispatchArgv, options),
805
+ options,
806
+ );
807
+ } finally {
808
+ await observability.shutdown().catch(() => {});
809
+ }
810
+ });
811
+ }