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
@@ -0,0 +1,424 @@
1
+ /**
2
+ * Conservative impacted-gate selection.
3
+ *
4
+ * This module never executes a gate. It turns an analyzer's evidence into a
5
+ * versioned, machine-readable selection. The optimization is intentionally
6
+ * one-way: only a complete/high-confidence analysis may reduce the project
7
+ * required gate set. Every unknown signal falls back to every required gate.
8
+ */
9
+
10
+ import crypto from "node:crypto";
11
+
12
+ export const IMPACTED_GATE_SELECTION_SCHEMA =
13
+ "chainlesschain.impacted-gate-selection";
14
+ export const IMPACTED_GATE_SELECTION_VERSION = 1;
15
+ export const DEFAULT_IMPACT_CONFIDENCE_THRESHOLD = 0.8;
16
+
17
+ export const DEFAULT_SUPPORTED_LANGUAGES = Object.freeze([
18
+ "c",
19
+ "cpp",
20
+ "csharp",
21
+ "css",
22
+ "dart",
23
+ "documentation",
24
+ "go",
25
+ "html",
26
+ "java",
27
+ "javascript",
28
+ "json",
29
+ "kotlin",
30
+ "objective-c",
31
+ "php",
32
+ "python",
33
+ "ruby",
34
+ "rust",
35
+ "shell",
36
+ "swift",
37
+ "typescript",
38
+ "vue",
39
+ "xml",
40
+ "yaml",
41
+ ]);
42
+
43
+ export const DEFAULT_SUPPORTED_ECOSYSTEMS = Object.freeze([
44
+ "android-gradle",
45
+ "cargo",
46
+ "dotnet",
47
+ "flutter",
48
+ "generic",
49
+ "go-modules",
50
+ "gradle",
51
+ "maven",
52
+ "npm",
53
+ "pip",
54
+ "ruby-bundler",
55
+ "swift-package-manager",
56
+ ]);
57
+
58
+ const BUILD_BOUNDARY_RE =
59
+ /(^|\/)(?:package(?:-lock)?\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?|pom\.xml|settings\.gradle(?:\.kts)?|build\.gradle(?:\.kts)?|gradle\.properties|gradle-wrapper\.properties|Cargo\.(?:toml|lock)|go\.(?:mod|sum|work)|pyproject\.toml|poetry\.lock|requirements[^/]*\.txt|Pipfile(?:\.lock)?|Gemfile(?:\.lock)?|Package\.swift|Podfile(?:\.lock)?|[^/]+\.(?:csproj|fsproj|vbproj|sln)|Dockerfile|Makefile)$/i;
60
+
61
+ const WORKFLOW_BOUNDARY_RE = /(^|\/)\.github\/workflows\/[^/]+\.ya?ml$/i;
62
+
63
+ function deepFreeze(value, seen = new WeakSet()) {
64
+ if (!value || typeof value !== "object" || seen.has(value)) return value;
65
+ seen.add(value);
66
+ for (const child of Object.values(value)) deepFreeze(child, seen);
67
+ return Object.freeze(value);
68
+ }
69
+
70
+ function canonicalJson(value) {
71
+ if (value === null || typeof value !== "object") {
72
+ return JSON.stringify(value);
73
+ }
74
+ if (Array.isArray(value)) {
75
+ return `[${value.map((item) => canonicalJson(item)).join(",")}]`;
76
+ }
77
+ return `{${Object.keys(value)
78
+ .sort()
79
+ .map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`)
80
+ .join(",")}}`;
81
+ }
82
+
83
+ function digest(value) {
84
+ return `sha256:${crypto
85
+ .createHash("sha256")
86
+ .update(canonicalJson(value))
87
+ .digest("hex")}`;
88
+ }
89
+
90
+ function normalizePath(value) {
91
+ return String(value || "")
92
+ .replaceAll("\\", "/")
93
+ .replace(/^\.\//, "")
94
+ .replace(/\/{2,}/g, "/")
95
+ .trim();
96
+ }
97
+
98
+ function uniqueStrings(values, normalizer = (value) => String(value).trim()) {
99
+ if (!Array.isArray(values)) return [];
100
+ return [
101
+ ...new Set(values.map(normalizer).filter((value) => value.length > 0)),
102
+ ].sort();
103
+ }
104
+
105
+ function normalizeGate(gate) {
106
+ if (typeof gate === "string") {
107
+ return {
108
+ id: gate.trim(),
109
+ always: true,
110
+ selectors: { paths: [], languages: [], ecosystems: [] },
111
+ };
112
+ }
113
+ const selectors = gate?.selectors || {};
114
+ return {
115
+ id: String(gate?.id || "").trim(),
116
+ always: gate?.always === true,
117
+ selectors: {
118
+ paths: uniqueStrings(selectors.paths, normalizePath),
119
+ languages: uniqueStrings(selectors.languages, (value) =>
120
+ String(value).trim().toLowerCase(),
121
+ ),
122
+ ecosystems: uniqueStrings(selectors.ecosystems, (value) =>
123
+ String(value).trim().toLowerCase(),
124
+ ),
125
+ },
126
+ };
127
+ }
128
+
129
+ function globToRegExp(pattern) {
130
+ let source = "^";
131
+ for (let index = 0; index < pattern.length; index += 1) {
132
+ const char = pattern[index];
133
+ if (char === "*") {
134
+ if (pattern[index + 1] === "*") {
135
+ index += 1;
136
+ if (pattern[index + 1] === "/") {
137
+ index += 1;
138
+ source += "(?:.*/)?";
139
+ } else {
140
+ source += ".*";
141
+ }
142
+ } else {
143
+ source += "[^/]*";
144
+ }
145
+ } else if (char === "?") {
146
+ source += "[^/]";
147
+ } else {
148
+ source += char.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
149
+ }
150
+ }
151
+ return new RegExp(`${source}$`);
152
+ }
153
+
154
+ function gateMatches(gate, context) {
155
+ const { paths, languages, ecosystems } = gate.selectors;
156
+ const hasSelectors =
157
+ paths.length > 0 || languages.length > 0 || ecosystems.length > 0;
158
+ // A required gate without a proven impact selector cannot safely be skipped.
159
+ if (gate.always || !hasSelectors) return true;
160
+ if (
161
+ paths.some((pattern) => {
162
+ try {
163
+ const matcher = globToRegExp(pattern);
164
+ return context.changedFiles.some((file) => matcher.test(file));
165
+ } catch {
166
+ return true;
167
+ }
168
+ })
169
+ ) {
170
+ return true;
171
+ }
172
+ if (languages.some((language) => context.languages.has(language))) {
173
+ return true;
174
+ }
175
+ return ecosystems.some((ecosystem) => context.ecosystems.has(ecosystem));
176
+ }
177
+
178
+ function selectionResult({
179
+ mode,
180
+ reason,
181
+ reasons,
182
+ confidence,
183
+ changedFiles,
184
+ requiredGateIds,
185
+ selectedGateIds,
186
+ analysisMaterial,
187
+ }) {
188
+ return deepFreeze({
189
+ schema: IMPACTED_GATE_SELECTION_SCHEMA,
190
+ version: IMPACTED_GATE_SELECTION_VERSION,
191
+ decision: mode === "blocked" ? "blocked" : "selected",
192
+ mode,
193
+ fallback: mode === "full",
194
+ reason,
195
+ reasons,
196
+ confidence,
197
+ changedFiles,
198
+ requiredGateIds,
199
+ selectedGateIds,
200
+ unverified: reasons,
201
+ analysisDigest: digest(analysisMaterial),
202
+ });
203
+ }
204
+
205
+ /**
206
+ * Select the smallest *proven safe* subset of project-required gates.
207
+ *
208
+ * Expected analyzer evidence:
209
+ * analysis: {
210
+ * confidence,
211
+ * dependencyGraphComplete,
212
+ * languageServicesComplete,
213
+ * testHistoryComplete,
214
+ * classifications: [{path, language, ecosystem, confidence}],
215
+ * impactedGateIds?: []
216
+ * }
217
+ *
218
+ * Any omitted/unknown field causes a full fallback. An empty/invalid project
219
+ * required-gate definition is blocked because there is no safe suite to run.
220
+ */
221
+ export function selectImpactedGates(input = {}) {
222
+ const changedFiles = uniqueStrings(input.changedFiles, normalizePath);
223
+ const requiredGates = Array.isArray(input.requiredGates)
224
+ ? input.requiredGates.map(normalizeGate)
225
+ : [];
226
+ const requiredGateIds = requiredGates.map((gate) => gate.id);
227
+ const analysis =
228
+ input.analysis && typeof input.analysis === "object" ? input.analysis : {};
229
+ const threshold = Number.isFinite(Number(input.confidenceThreshold))
230
+ ? Math.min(1, Math.max(0, Number(input.confidenceThreshold)))
231
+ : DEFAULT_IMPACT_CONFIDENCE_THRESHOLD;
232
+ const confidence = Number.isFinite(Number(analysis.confidence))
233
+ ? Number(analysis.confidence)
234
+ : null;
235
+ const analysisMaterial = {
236
+ changedFiles,
237
+ requiredGates,
238
+ threshold,
239
+ analysis,
240
+ };
241
+
242
+ const invalidGateIds = requiredGateIds.filter((id) => !id);
243
+ const duplicateGateIds = requiredGateIds.filter(
244
+ (id, index) => requiredGateIds.indexOf(id) !== index,
245
+ );
246
+ if (
247
+ requiredGateIds.length === 0 ||
248
+ invalidGateIds.length > 0 ||
249
+ duplicateGateIds.length > 0
250
+ ) {
251
+ const reason =
252
+ requiredGateIds.length === 0
253
+ ? "required-gates-undefined"
254
+ : invalidGateIds.length > 0
255
+ ? "required-gate-id-invalid"
256
+ : "required-gate-id-duplicate";
257
+ return selectionResult({
258
+ mode: "blocked",
259
+ reason,
260
+ reasons: [reason],
261
+ confidence,
262
+ changedFiles,
263
+ requiredGateIds,
264
+ selectedGateIds: [],
265
+ analysisMaterial,
266
+ });
267
+ }
268
+
269
+ const reasons = [];
270
+ if (changedFiles.length === 0) reasons.push("changed-files-unverified");
271
+ if (confidence === null || confidence < threshold) {
272
+ reasons.push("confidence-insufficient");
273
+ }
274
+ if (analysis.dependencyGraphComplete !== true) {
275
+ reasons.push("dependency-graph-incomplete");
276
+ }
277
+ if (analysis.languageServicesComplete !== true) {
278
+ reasons.push("language-services-incomplete");
279
+ }
280
+ if (analysis.testHistoryComplete !== true) {
281
+ reasons.push("test-history-incomplete");
282
+ }
283
+ if (
284
+ changedFiles.some(
285
+ (file) => BUILD_BOUNDARY_RE.test(file) || WORKFLOW_BOUNDARY_RE.test(file),
286
+ )
287
+ ) {
288
+ reasons.push("build-or-workflow-boundary-changed");
289
+ }
290
+
291
+ const classifications = Array.isArray(analysis.classifications)
292
+ ? analysis.classifications.map((item) => ({
293
+ path: normalizePath(item?.path),
294
+ language: String(item?.language || "")
295
+ .trim()
296
+ .toLowerCase(),
297
+ ecosystem: String(item?.ecosystem || "")
298
+ .trim()
299
+ .toLowerCase(),
300
+ confidence: Number.isFinite(Number(item?.confidence))
301
+ ? Number(item.confidence)
302
+ : null,
303
+ }))
304
+ : [];
305
+ const byPath = new Map(classifications.map((item) => [item.path, item]));
306
+ const supportedLanguages = new Set([
307
+ ...DEFAULT_SUPPORTED_LANGUAGES,
308
+ ...uniqueStrings(input.supportedLanguages, (value) =>
309
+ String(value).trim().toLowerCase(),
310
+ ),
311
+ ]);
312
+ const supportedEcosystems = new Set([
313
+ ...DEFAULT_SUPPORTED_ECOSYSTEMS,
314
+ ...uniqueStrings(input.supportedEcosystems, (value) =>
315
+ String(value).trim().toLowerCase(),
316
+ ),
317
+ ]);
318
+ for (const gate of requiredGates) {
319
+ for (const language of gate.selectors.languages) {
320
+ if (!supportedLanguages.has(language)) {
321
+ reasons.push(`gate-selector-language-unknown:${gate.id}:${language}`);
322
+ }
323
+ }
324
+ for (const ecosystem of gate.selectors.ecosystems) {
325
+ if (!supportedEcosystems.has(ecosystem)) {
326
+ reasons.push(`gate-selector-ecosystem-unknown:${gate.id}:${ecosystem}`);
327
+ }
328
+ }
329
+ }
330
+ const classificationPathCounts = new Map();
331
+ for (const classification of classifications) {
332
+ classificationPathCounts.set(
333
+ classification.path,
334
+ (classificationPathCounts.get(classification.path) || 0) + 1,
335
+ );
336
+ }
337
+ for (const [classificationPath, count] of classificationPathCounts) {
338
+ if (count > 1) {
339
+ reasons.push(`classification-ambiguous:${classificationPath || "empty"}`);
340
+ }
341
+ }
342
+ const languages = new Set();
343
+ const ecosystems = new Set();
344
+ for (const file of changedFiles) {
345
+ const classification = byPath.get(file);
346
+ if (!classification) {
347
+ reasons.push(`classification-missing:${file}`);
348
+ continue;
349
+ }
350
+ if (
351
+ classification.confidence === null ||
352
+ classification.confidence < threshold
353
+ ) {
354
+ reasons.push(`classification-confidence-insufficient:${file}`);
355
+ }
356
+ if (!supportedLanguages.has(classification.language)) {
357
+ reasons.push(`language-unknown:${classification.language || file}`);
358
+ } else {
359
+ languages.add(classification.language);
360
+ }
361
+ if (!supportedEcosystems.has(classification.ecosystem)) {
362
+ reasons.push(`ecosystem-unknown:${classification.ecosystem || file}`);
363
+ } else {
364
+ ecosystems.add(classification.ecosystem);
365
+ }
366
+ }
367
+
368
+ const explicitImpacted = analysis.impactedGateIds;
369
+ if (explicitImpacted != null && !Array.isArray(explicitImpacted)) {
370
+ reasons.push("impacted-gate-ids-invalid");
371
+ }
372
+ const explicitIds = uniqueStrings(explicitImpacted);
373
+ for (const id of explicitIds) {
374
+ if (!requiredGateIds.includes(id)) {
375
+ reasons.push(`impacted-gate-unknown:${id}`);
376
+ }
377
+ }
378
+
379
+ const uniqueReasons = [...new Set(reasons)];
380
+ if (uniqueReasons.length > 0) {
381
+ return selectionResult({
382
+ mode: "full",
383
+ reason: uniqueReasons[0],
384
+ reasons: uniqueReasons,
385
+ confidence,
386
+ changedFiles,
387
+ requiredGateIds,
388
+ selectedGateIds: [...requiredGateIds],
389
+ analysisMaterial,
390
+ });
391
+ }
392
+
393
+ const selected = new Set(
394
+ requiredGates
395
+ .filter((gate) =>
396
+ gateMatches(gate, { changedFiles, languages, ecosystems }),
397
+ )
398
+ .map((gate) => gate.id),
399
+ );
400
+ for (const id of explicitIds) selected.add(id);
401
+ if (selected.size === 0) {
402
+ return selectionResult({
403
+ mode: "full",
404
+ reason: "no-gate-impact-proven",
405
+ reasons: ["no-gate-impact-proven"],
406
+ confidence,
407
+ changedFiles,
408
+ requiredGateIds,
409
+ selectedGateIds: [...requiredGateIds],
410
+ analysisMaterial,
411
+ });
412
+ }
413
+
414
+ return selectionResult({
415
+ mode: "impacted",
416
+ reason: "impact-analysis-complete",
417
+ reasons: [],
418
+ confidence,
419
+ changedFiles,
420
+ requiredGateIds,
421
+ selectedGateIds: requiredGateIds.filter((id) => selected.has(id)),
422
+ analysisMaterial,
423
+ });
424
+ }
@@ -138,6 +138,21 @@ export class WebSocketInteractionAdapter extends InteractionAdapter {
138
138
  this.enablePhase5Envelopes = options.enablePhase5Envelopes === true;
139
139
  // Optional fan-out bus for hosted HTTP SSE subscribers.
140
140
  this.envelopeBus = options.envelopeBus || null;
141
+ // Optional persistence hook for approval lifecycle state. It is entirely
142
+ // internal and does not alter the question/session-answer wire protocol.
143
+ this.onPendingApprovalChange =
144
+ typeof options.onPendingApprovalChange === "function"
145
+ ? options.onPendingApprovalChange
146
+ : null;
147
+ }
148
+
149
+ _notifyPendingApproval(type, payload) {
150
+ if (!this.onPendingApprovalChange) return;
151
+ try {
152
+ this.onPendingApprovalChange({ type, payload });
153
+ } catch (_err) {
154
+ // Interaction transport remains usable if optional persistence fails.
155
+ }
141
156
  }
142
157
 
143
158
  /** Generate a unique request id */
@@ -162,6 +177,12 @@ export class WebSocketInteractionAdapter extends InteractionAdapter {
162
177
  return;
163
178
  }
164
179
  this._pending.delete(requestId);
180
+ if (pending.approvalRequest) {
181
+ this._notifyPendingApproval("approval.settled", {
182
+ requestId,
183
+ reason: "timeout",
184
+ });
185
+ }
165
186
  reject(new Error("Question timed out"));
166
187
  },
167
188
  options.timeoutMs || 5 * 60 * 1000,
@@ -169,11 +190,14 @@ export class WebSocketInteractionAdapter extends InteractionAdapter {
169
190
  // `kind` tags what KIND of response settles this request ("question" vs
170
191
  // "host-tool"). Checked in _resolvePending so a peer's session-answer can
171
192
  // never resolve a host-tool call with a plain string (or vice versa).
193
+ const approvalRequest =
194
+ message.approval && typeof message.approval === "object";
172
195
  this._pending.set(requestId, {
173
196
  resolve,
174
197
  reject,
175
198
  timeoutId,
176
199
  kind: options.kind || null,
200
+ approvalRequest,
177
201
  // Approval binding (authority §"权限来源"): when a permission gate raises
178
202
  // this request WITH a binding (tool_call_id + args + policy digest), an
179
203
  // *approve* answer must echo the SAME binding or it is a stale / mis-
@@ -183,6 +207,27 @@ export class WebSocketInteractionAdapter extends InteractionAdapter {
183
207
  bindingType: options.bindingType || null,
184
208
  });
185
209
 
210
+ if (approvalRequest) {
211
+ this._notifyPendingApproval("approval.requested", {
212
+ requestId,
213
+ status: "pending",
214
+ binding: typeof options.binding === "string" ? options.binding : null,
215
+ tool:
216
+ typeof message.approval.tool === "string"
217
+ ? message.approval.tool
218
+ : null,
219
+ risk:
220
+ typeof message.approval.risk === "string"
221
+ ? message.approval.risk
222
+ : null,
223
+ rule:
224
+ typeof message.approval.rule === "string"
225
+ ? message.approval.rule
226
+ : null,
227
+ requestedAt: new Date().toISOString(),
228
+ });
229
+ }
230
+
186
231
  this._sendWs({
187
232
  ...message,
188
233
  ...(message.type === "question_request" ? { id: requestId } : {}),
@@ -408,6 +453,12 @@ export class WebSocketInteractionAdapter extends InteractionAdapter {
408
453
  if (pending.timeoutId) {
409
454
  clearTimeout(pending.timeoutId);
410
455
  }
456
+ if (pending.approvalRequest) {
457
+ this._notifyPendingApproval("approval.settled", {
458
+ requestId,
459
+ reason: error.code || "interrupted",
460
+ });
461
+ }
411
462
  pending.reject(error);
412
463
  }
413
464
  }
@@ -538,6 +589,17 @@ export class WebSocketInteractionAdapter extends InteractionAdapter {
538
589
  if (pending.timeoutId) {
539
590
  clearTimeout(pending.timeoutId);
540
591
  }
592
+ if (pending.approvalRequest) {
593
+ const normalizedApproval =
594
+ effective === true ||
595
+ effective === "true" ||
596
+ effective === "yes" ||
597
+ effective === "y";
598
+ this._notifyPendingApproval("approval.settled", {
599
+ requestId,
600
+ reason: normalizedApproval ? "approved" : "denied",
601
+ });
602
+ }
541
603
  pending.resolve(effective);
542
604
  }
543
605
  }
@@ -9,38 +9,4 @@
9
9
  * in new code.
10
10
  */
11
11
 
12
- export {
13
- appendEvent,
14
- startSession,
15
- appendUserMessage,
16
- appendAssistantMessage,
17
- appendToolCall,
18
- appendToolCallCompact,
19
- appendLlmRetryCompact,
20
- MAX_COMPACT_DURATION_MS,
21
- appendToolResult,
22
- appendCompactEvent,
23
- readEvents,
24
- rebuildMessages,
25
- listJsonlSessions,
26
- listSessionIds,
27
- renameSession,
28
- pruneJsonlSessions,
29
- forkSession,
30
- createBranchSession,
31
- sessionExists,
32
- getLastSessionId,
33
- migrateLegacySessions,
34
- migrateLegacySessionsBatch,
35
- migrateLegacySessionFile,
36
- validateJsonlSession,
37
- validateAllJsonlSessions,
38
- sampleMigratedSessionsValidation,
39
- sessionPath,
40
- isUnsafeSessionId,
41
- appendTokenUsage,
42
- toIsoSafe,
43
- verifySession,
44
- verifyAllSessions,
45
- TRANSCRIPT_CHAIN_STATUS,
46
- } from "../harness/jsonl-session-store.js";
12
+ export * from "../harness/jsonl-session-store.js";
package/src/lib/logger.js CHANGED
@@ -1,25 +1,62 @@
1
1
  import chalk from "chalk";
2
+ import { bindOutputContext, getOutputContext } from "./output-context.js";
2
3
 
3
- let verboseEnabled = false;
4
- let quietEnabled = false;
4
+ const ANSI_ESCAPE_PATTERN = new RegExp(
5
+ String.raw`\u001B\[[0-?]*[ -/]*[@-~]`,
6
+ "g",
7
+ );
8
+
9
+ function diagnosticMessage(message, args) {
10
+ return [message, ...args]
11
+ .map((value) => {
12
+ if (value instanceof Error) return value.message;
13
+ if (typeof value === "string") return value;
14
+ try {
15
+ return JSON.stringify(value);
16
+ } catch {
17
+ return String(value);
18
+ }
19
+ })
20
+ .join(" ")
21
+ .replace(ANSI_ESCAPE_PATTERN, "");
22
+ }
23
+
24
+ function machineDiagnostic(kind, message, args) {
25
+ console.error(
26
+ JSON.stringify({
27
+ [kind]: { message: diagnosticMessage(message, args) },
28
+ }),
29
+ );
30
+ }
5
31
 
6
32
  export function setVerbose(enabled) {
7
- verboseEnabled = enabled;
33
+ const current = getOutputContext();
34
+ bindOutputContext({ ...current, verbose: enabled === true });
8
35
  }
9
36
 
10
37
  export function setQuiet(enabled) {
11
- quietEnabled = enabled;
38
+ const current = getOutputContext();
39
+ bindOutputContext({ ...current, quiet: enabled === true });
40
+ }
41
+
42
+ export function setMachineReadable(enabled) {
43
+ const current = getOutputContext();
44
+ bindOutputContext({ ...current, machineReadable: enabled === true });
12
45
  }
13
46
 
14
47
  export function info(message, ...args) {
15
- if (!quietEnabled) {
16
- console.log(chalk.blue("ℹ"), message, ...args);
48
+ const context = getOutputContext();
49
+ if (!context.quiet) {
50
+ const sink = context.machineReadable ? console.error : console.log;
51
+ sink(chalk.blue("ℹ"), message, ...args);
17
52
  }
18
53
  }
19
54
 
20
55
  export function success(message, ...args) {
21
- if (!quietEnabled) {
22
- console.log(chalk.green("✔"), message, ...args);
56
+ const context = getOutputContext();
57
+ if (!context.quiet) {
58
+ const sink = context.machineReadable ? console.error : console.log;
59
+ sink(chalk.green("✔"), message, ...args);
23
60
  }
24
61
  }
25
62
 
@@ -27,27 +64,41 @@ export function warn(message, ...args) {
27
64
  // stderr, not stdout: a warning must never interleave with a command's
28
65
  // machine-readable stdout (e.g. `--json` payloads), which `| jq` and other
29
66
  // consumers parse. Like error(), warn is never gated by quiet mode.
30
- console.error(chalk.yellow("⚠"), message, ...args);
67
+ if (getOutputContext().machineReadable) {
68
+ machineDiagnostic("warning", message, args);
69
+ } else {
70
+ console.error(chalk.yellow("⚠"), message, ...args);
71
+ }
31
72
  }
32
73
 
33
74
  export function error(message, ...args) {
34
- console.error(chalk.red("✖"), message, ...args);
75
+ if (getOutputContext().machineReadable) {
76
+ machineDiagnostic("error", message, args);
77
+ } else {
78
+ console.error(chalk.red("✖"), message, ...args);
79
+ }
35
80
  }
36
81
 
37
82
  export function verbose(message, ...args) {
38
- if (verboseEnabled) {
39
- console.log(chalk.gray("⋯"), message, ...args);
83
+ const context = getOutputContext();
84
+ if (context.verbose && !context.quiet) {
85
+ // Verbose output is diagnostic by definition. Keeping it on stderr makes
86
+ // `--json`/`--output-format stream-json` stdout safe to parse.
87
+ console.error(chalk.gray("⋯"), message, ...args);
40
88
  }
41
89
  }
42
90
 
43
91
  export function log(message, ...args) {
44
- if (!quietEnabled) {
92
+ const context = getOutputContext();
93
+ // Machine-readable payloads are explicit results and must survive --quiet.
94
+ if (!context.quiet || context.machineReadable) {
45
95
  console.log(message, ...args);
46
96
  }
47
97
  }
48
98
 
49
99
  export function newline() {
50
- if (!quietEnabled) {
100
+ const context = getOutputContext();
101
+ if (!context.quiet && !context.machineReadable) {
51
102
  console.log();
52
103
  }
53
104
  }
@@ -62,5 +113,6 @@ export const logger = {
62
113
  newline,
63
114
  setVerbose,
64
115
  setQuiet,
116
+ setMachineReadable,
65
117
  };
66
118
  export default logger;