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
@@ -12,7 +12,28 @@
12
12
  */
13
13
 
14
14
  import chalk from "chalk";
15
- import { ArtifactStore } from "../lib/artifact-store.js";
15
+ import fs from "node:fs";
16
+ import { randomUUID } from "node:crypto";
17
+ import {
18
+ ArtifactStore,
19
+ publicArtifactMetadata,
20
+ } from "../lib/artifact-store.js";
21
+ import {
22
+ assessDeliveryEvidence,
23
+ createDeliveryEvidenceRecord,
24
+ DELIVERY_EVIDENCE_SCHEMA,
25
+ verifyDeliveryEvidenceRecord,
26
+ } from "../lib/delivery-evidence.js";
27
+ import { selectImpactedGates } from "../lib/impacted-gate-selector.js";
28
+ import {
29
+ createDeliveryFlow,
30
+ projectDeliveryFlow,
31
+ requestDeliveryAction,
32
+ restoreDeliveryFlow,
33
+ settleDeliveryAction,
34
+ validateDeliveryActionResult,
35
+ } from "../lib/delivery-coordinator.js";
36
+ import { withFileLock } from "../lib/with-file-lock.js";
16
37
 
17
38
  export function registerArtifactsCommand(program) {
18
39
  const cmd = program
@@ -66,6 +87,78 @@ export function registerArtifactsCommand(program) {
66
87
  .action((options) => {
67
88
  process.exitCode = runArtifactsClean(options);
68
89
  });
90
+
91
+ cmd
92
+ .command("select-gates <input>")
93
+ .description(
94
+ "Select impacted required gates from an analyzer JSON file (unknowns fall back to the full suite)",
95
+ )
96
+ .option("--json", "Machine-readable JSON output")
97
+ .action((input, options) => {
98
+ process.exitCode = runArtifactsSelectGates(input, options);
99
+ });
100
+
101
+ cmd
102
+ .command("delivery-evidence <input>")
103
+ .description(
104
+ "Validate and archive a versioned delivery-evidence JSON record (does not create or merge a PR)",
105
+ )
106
+ .option("--session <id>", "Bind the artifact to an agent session")
107
+ .option("--ttl-days <days>", "Artifact retention in days")
108
+ .option("--json", "Machine-readable JSON output")
109
+ .action((input, options) => {
110
+ process.exitCode = runArtifactsDeliveryEvidence(input, options);
111
+ });
112
+
113
+ cmd
114
+ .command("delivery-init <input>")
115
+ .description(
116
+ "Create a resumable delivery-flow snapshot from JSON (no external actions)",
117
+ )
118
+ .option("--json", "Machine-readable JSON output")
119
+ .action((input, options) => {
120
+ process.exitCode = runArtifactsDeliveryInit(input, options);
121
+ });
122
+
123
+ cmd
124
+ .command("delivery-step <state>")
125
+ .description(
126
+ "Request or settle one explicit delivery action without invoking an external adapter",
127
+ )
128
+ .option("--action <action>", "Action to request when no effect is pending")
129
+ .option("--payload-file <path>", "Optional action payload JSON")
130
+ .option(
131
+ "--result-file <path>",
132
+ "Versioned effect-bound external/fake result envelope to settle",
133
+ )
134
+ .option(
135
+ "--expected-revision <revision>",
136
+ "Fail closed unless the snapshot still has this revision",
137
+ )
138
+ .option(
139
+ "--expected-state-digest <digest>",
140
+ "Fail closed unless the snapshot still has this sha256 digest",
141
+ )
142
+ .option(
143
+ "--expected-effect-id <effectId>",
144
+ "Fail closed unless this exact effect is still pending",
145
+ )
146
+ .option(
147
+ "--write-state",
148
+ "Atomically persist the CLI-produced next snapshot under a strict lock",
149
+ )
150
+ .option("--json", "Machine-readable JSON output")
151
+ .action((state, options) => {
152
+ process.exitCode = runArtifactsDeliveryStep(state, options);
153
+ });
154
+
155
+ cmd
156
+ .command("delivery-project <state>")
157
+ .description("Validate and project a delivery snapshot for IDE consumption")
158
+ .option("--json", "Machine-readable JSON output")
159
+ .action((state, options) => {
160
+ process.exitCode = runArtifactsDeliveryProject(state, options);
161
+ });
69
162
  }
70
163
 
71
164
  export function runArtifactsList(options = {}, deps = {}) {
@@ -108,7 +201,11 @@ export function runArtifactsShow(id, options = {}, deps = {}) {
108
201
  console.error(chalk.red(`No artifact with id "${id}".`));
109
202
  return 1;
110
203
  }
111
- const payload = { ...entry, storedPath: store.storedPath(entry) };
204
+ const payload = {
205
+ ...entry,
206
+ storedPath: store.storedPath(entry),
207
+ integrity: store.verifyIntegrity(entry),
208
+ };
112
209
  if (options.json) {
113
210
  console.log(JSON.stringify(payload, null, 2));
114
211
  return 0;
@@ -159,3 +256,304 @@ export function runArtifactsClean(options = {}, deps = {}) {
159
256
  );
160
257
  return 0;
161
258
  }
259
+
260
+ function readJsonFile(inputPath, deps = {}) {
261
+ const readFileSync = deps.readFileSync || fs.readFileSync;
262
+ return JSON.parse(readFileSync(inputPath, "utf-8"));
263
+ }
264
+
265
+ export function runArtifactsSelectGates(inputPath, options = {}, deps = {}) {
266
+ try {
267
+ const selection = selectImpactedGates(readJsonFile(inputPath, deps));
268
+ if (options.json) {
269
+ console.log(JSON.stringify(selection, null, 2));
270
+ } else {
271
+ console.log(
272
+ selection.mode === "blocked"
273
+ ? chalk.red(`Gate selection blocked: ${selection.reason}`)
274
+ : chalk.green(
275
+ `Gate selection: ${selection.mode} (${selection.selectedGateIds.join(", ")})`,
276
+ ),
277
+ );
278
+ if (selection.fallback) {
279
+ console.log(
280
+ chalk.yellow(`Full required-suite fallback: ${selection.reason}`),
281
+ );
282
+ }
283
+ }
284
+ return selection.decision === "blocked" ? 1 : 0;
285
+ } catch (error) {
286
+ const payload = {
287
+ schema: "chainlesschain.impacted-gate-selection-error",
288
+ version: 1,
289
+ error: error.message,
290
+ };
291
+ if (options.json) console.error(JSON.stringify(payload));
292
+ else console.error(chalk.red(`Gate selection failed: ${error.message}`));
293
+ return 1;
294
+ }
295
+ }
296
+
297
+ export function runArtifactsDeliveryEvidence(
298
+ inputPath,
299
+ options = {},
300
+ deps = {},
301
+ ) {
302
+ const store = deps.store || new ArtifactStore();
303
+ try {
304
+ const input = readJsonFile(inputPath, deps);
305
+ const record =
306
+ input?.schema === DELIVERY_EVIDENCE_SCHEMA
307
+ ? input
308
+ : createDeliveryEvidenceRecord(input, { now: deps.now });
309
+ const verification = verifyDeliveryEvidenceRecord(record);
310
+ const readiness = assessDeliveryEvidence(record);
311
+ const recordJson = `${JSON.stringify(record, null, 2)}\n`;
312
+ const digestSuffix = String(record.recordDigest || "unverified")
313
+ .replace(/^sha256:/, "")
314
+ .slice(0, 16);
315
+ const entry = store.publishData({
316
+ data: recordJson,
317
+ fileName: `delivery-evidence-v1-${digestSuffix}.json`,
318
+ title: `Delivery evidence ${digestSuffix}`,
319
+ kind: "data",
320
+ mime: "application/json",
321
+ sessionId: options.session || null,
322
+ ttlDays: options.ttlDays,
323
+ immutable: true,
324
+ recordDigest: record.recordDigest || null,
325
+ });
326
+ const payload = {
327
+ schema: "chainlesschain.delivery-evidence-command-result",
328
+ version: 1,
329
+ archived: true,
330
+ artifact: publicArtifactMetadata(entry),
331
+ artifactIntegrity: store.verifyIntegrity(entry),
332
+ verification,
333
+ readiness,
334
+ record,
335
+ };
336
+ if (options.json) {
337
+ console.log(JSON.stringify(payload, null, 2));
338
+ } else {
339
+ console.log(
340
+ readiness.ready
341
+ ? chalk.green(`Delivery evidence ready: ${entry.id}`)
342
+ : chalk.yellow(
343
+ `Delivery evidence archived but blocked: ${readiness.reason}`,
344
+ ),
345
+ );
346
+ console.log(chalk.dim(store.storedPath(entry)));
347
+ }
348
+ return readiness.ready ? 0 : 1;
349
+ } catch (error) {
350
+ const payload = {
351
+ schema: "chainlesschain.delivery-evidence-command-error",
352
+ version: 1,
353
+ archived: false,
354
+ error: error.message,
355
+ };
356
+ if (options.json) console.error(JSON.stringify(payload));
357
+ else console.error(chalk.red(`Delivery evidence failed: ${error.message}`));
358
+ return 1;
359
+ }
360
+ }
361
+
362
+ function deliveryCommandPayload(state) {
363
+ return {
364
+ schema: "chainlesschain.delivery-flow-command-result",
365
+ version: 1,
366
+ state,
367
+ projection: projectDeliveryFlow(state),
368
+ };
369
+ }
370
+
371
+ function printDeliveryCommandPayload(payload, options) {
372
+ if (options.json) {
373
+ console.log(JSON.stringify(payload, null, 2));
374
+ return;
375
+ }
376
+ const projection = payload.projection;
377
+ console.log(
378
+ `${chalk.cyan(projection.flowId || "invalid")} ${projection.status || "invalid"}/${projection.phase || "unknown"} revision=${projection.revision ?? "?"}`,
379
+ );
380
+ if (projection.pendingEffect) {
381
+ console.log(
382
+ chalk.yellow(
383
+ `Pending explicit effect: ${projection.pendingEffect.action} (${projection.pendingEffect.id})`,
384
+ ),
385
+ );
386
+ }
387
+ if (projection.stopReason) {
388
+ console.log(chalk.yellow(`Stop reason: ${projection.stopReason}`));
389
+ }
390
+ }
391
+
392
+ export function runArtifactsDeliveryInit(inputPath, options = {}, deps = {}) {
393
+ try {
394
+ const config = readJsonFile(inputPath, deps);
395
+ const state = createDeliveryFlow(config, { now: deps.now });
396
+ const payload = deliveryCommandPayload(state);
397
+ printDeliveryCommandPayload(payload, options);
398
+ return state.status === "blocked" ? 1 : 0;
399
+ } catch (error) {
400
+ const payload = {
401
+ schema: "chainlesschain.delivery-flow-command-error",
402
+ version: 1,
403
+ error: error.message,
404
+ };
405
+ if (options.json) console.error(JSON.stringify(payload));
406
+ else
407
+ console.error(chalk.red(`Delivery flow init failed: ${error.message}`));
408
+ return 1;
409
+ }
410
+ }
411
+
412
+ export function runArtifactsDeliveryStep(statePath, options = {}, deps = {}) {
413
+ try {
414
+ const step = () => {
415
+ let state = restoreDeliveryFlow(readJsonFile(statePath, deps));
416
+ assertDeliveryStepExpectation(state, options);
417
+ if (state.pendingEffect) {
418
+ if (options.action && options.action !== state.pendingEffect.action) {
419
+ throw new Error(
420
+ `snapshot already has pending ${state.pendingEffect.action}; it cannot request ${options.action}`,
421
+ );
422
+ }
423
+ if (!options.resultFile) {
424
+ throw new Error(
425
+ "snapshot has a pending effect; provide --result-file to settle it explicitly",
426
+ );
427
+ }
428
+ } else {
429
+ if (!options.action) {
430
+ throw new Error("--action is required when no effect is pending");
431
+ }
432
+ if (options.expectedEffectId) {
433
+ throw new Error(
434
+ "expected effectId but snapshot has no pending effect",
435
+ );
436
+ }
437
+ const actionPayload = options.payloadFile
438
+ ? readJsonFile(options.payloadFile, deps)
439
+ : {};
440
+ state = requestDeliveryAction(state, options.action, actionPayload, {
441
+ now: deps.now,
442
+ });
443
+ }
444
+ if (options.resultFile) {
445
+ const envelope = readJsonFile(options.resultFile, deps);
446
+ const validation = validateDeliveryActionResult(envelope);
447
+ if (!validation.valid) {
448
+ throw new Error(`invalid action result: ${validation.reason}`);
449
+ }
450
+ if (envelope.effectId !== state.pendingEffect.id) {
451
+ throw new Error(
452
+ "action result effectId does not match pending effect",
453
+ );
454
+ }
455
+ state = settleDeliveryAction(
456
+ state,
457
+ state.pendingEffect.id,
458
+ envelope.result,
459
+ { now: deps.now },
460
+ );
461
+ }
462
+ if (options.writeState) writeDeliveryState(statePath, state, deps);
463
+ return state;
464
+ };
465
+ const state = options.writeState
466
+ ? (deps.withFileLock || withFileLock)(statePath, step, {
467
+ failIfUnavailable: true,
468
+ })
469
+ : step();
470
+ const payload = deliveryCommandPayload(state);
471
+ printDeliveryCommandPayload(payload, options);
472
+ return 0;
473
+ } catch (error) {
474
+ const payload = {
475
+ schema: "chainlesschain.delivery-flow-command-error",
476
+ version: 1,
477
+ error: error.message,
478
+ };
479
+ if (options.json) console.error(JSON.stringify(payload));
480
+ else
481
+ console.error(chalk.red(`Delivery flow step failed: ${error.message}`));
482
+ return 1;
483
+ }
484
+ }
485
+
486
+ function assertDeliveryStepExpectation(state, options) {
487
+ if (options.expectedRevision != null) {
488
+ const expected = Number(options.expectedRevision);
489
+ if (!Number.isInteger(expected) || expected < 0) {
490
+ throw new Error("expected revision must be a non-negative integer");
491
+ }
492
+ if (state.revision !== expected) {
493
+ throw new Error(
494
+ `stale delivery revision: expected ${expected}, found ${state.revision}`,
495
+ );
496
+ }
497
+ }
498
+ if (
499
+ options.expectedStateDigest &&
500
+ state.stateDigest !== String(options.expectedStateDigest)
501
+ ) {
502
+ throw new Error("stale delivery state digest");
503
+ }
504
+ if (options.expectedEffectId) {
505
+ if (!state.pendingEffect) {
506
+ throw new Error("expected effectId but snapshot has no pending effect");
507
+ }
508
+ if (state.pendingEffect.id !== String(options.expectedEffectId)) {
509
+ throw new Error("stale delivery effectId");
510
+ }
511
+ }
512
+ }
513
+
514
+ function writeDeliveryState(statePath, state, deps = {}) {
515
+ const writeFileSync = deps.writeFileSync || fs.writeFileSync;
516
+ const renameSync = deps.renameSync || fs.renameSync;
517
+ const rmSync = deps.rmSync || fs.rmSync;
518
+ const temporary = `${statePath}.${process.pid}.${randomUUID()}.tmp`;
519
+ try {
520
+ writeFileSync(temporary, `${JSON.stringify(state, null, 2)}\n`, {
521
+ encoding: "utf8",
522
+ mode: 0o600,
523
+ flag: "wx",
524
+ });
525
+ renameSync(temporary, statePath);
526
+ } catch (error) {
527
+ try {
528
+ rmSync(temporary, { force: true });
529
+ } catch {
530
+ // Preserve the authoritative write error.
531
+ }
532
+ throw error;
533
+ }
534
+ }
535
+
536
+ export function runArtifactsDeliveryProject(
537
+ statePath,
538
+ options = {},
539
+ deps = {},
540
+ ) {
541
+ try {
542
+ const state = restoreDeliveryFlow(readJsonFile(statePath, deps));
543
+ const payload = deliveryCommandPayload(state);
544
+ printDeliveryCommandPayload(payload, options);
545
+ return 0;
546
+ } catch (error) {
547
+ const payload = {
548
+ schema: "chainlesschain.delivery-flow-command-error",
549
+ version: 1,
550
+ error: error.message,
551
+ };
552
+ if (options.json) console.error(JSON.stringify(payload));
553
+ else
554
+ console.error(
555
+ chalk.red(`Delivery flow projection failed: ${error.message}`),
556
+ );
557
+ return 1;
558
+ }
559
+ }
@@ -7,6 +7,7 @@ import {
7
7
  listCollaborationRuns,
8
8
  projectCollaborationTasks,
9
9
  } from "../lib/collaboration-run-store.js";
10
+ import { readSessionHostResumeState } from "../lib/session-host-snapshot.js";
10
11
  import executionBroker from "../lib/process-execution-broker/index.js";
11
12
 
12
13
  function formatAge(ms) {
@@ -172,6 +173,14 @@ export function readLogFromOffset(file, offset) {
172
173
  return { text: text.slice(offset), offset: text.length };
173
174
  }
174
175
 
176
+ /** Content-free JSONL authority exposed at the real background attach seam. */
177
+ export function readBackgroundAttachSessionSnapshot(state, dependencies = {}) {
178
+ if (!state?.sessionId) return null;
179
+ return (
180
+ readSessionHostResumeState(state.sessionId, dependencies)?.snapshot || null
181
+ );
182
+ }
183
+
175
184
  async function followBackgroundAgent(id, options = {}) {
176
185
  const {
177
186
  readBackgroundAgentState,
@@ -355,7 +364,36 @@ export async function interactiveAttach(id, state, options = {}) {
355
364
  closed = true;
356
365
  },
357
366
  });
358
- } catch {
367
+ // Read authority only after the authenticated transport handshake. This
368
+ // binds attach to both the live worker and its canonical JSONL transcript.
369
+ const sessionSnapshot = readBackgroundAttachSessionSnapshot(state);
370
+ if (sessionSnapshot) {
371
+ if (typeof options.onSessionSnapshot === "function") {
372
+ await options.onSessionSnapshot(sessionSnapshot);
373
+ }
374
+ logger.log(
375
+ chalk.gray(
376
+ `Session ${sessionSnapshot.sessionId} revision=${sessionSnapshot.revision} ` +
377
+ `head=${sessionSnapshot.head.hash || "unverified"} ` +
378
+ `messages=${sessionSnapshot.messages.length}`,
379
+ ),
380
+ );
381
+ if (!sessionSnapshot.verified) {
382
+ try {
383
+ conn.close();
384
+ } catch {
385
+ /* peer already closed */
386
+ }
387
+ const error = new Error(
388
+ "Background attach refused an unverified canonical JSONL session",
389
+ );
390
+ error.code = "CC_SESSION_HOST_SNAPSHOT_UNVERIFIED";
391
+ error.sessionSnapshot = sessionSnapshot;
392
+ throw error;
393
+ }
394
+ }
395
+ } catch (error) {
396
+ if (error?.code === "CC_SESSION_HOST_SNAPSHOT_UNVERIFIED") throw error;
359
397
  return false; // transport gone (worker finalizing/finalized) — fall back
360
398
  }
361
399
 
@@ -382,8 +420,8 @@ export async function interactiveAttach(id, state, options = {}) {
382
420
 
383
421
  const readline = await import("node:readline");
384
422
  const rl = readline.createInterface({
385
- input: process.stdin,
386
- output: process.stdout,
423
+ input: options.input || process.stdin,
424
+ output: options.output || process.stdout,
387
425
  });
388
426
  rl.on("line", (line) => {
389
427
  const text = line.trim();