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,642 @@
1
+ /**
2
+ * Host-independent checkpoint / rewind timeline projection.
3
+ *
4
+ * The CLI owns the canonical turn bindings and every state-changing restore.
5
+ * IDEs consume this bounded, versioned projection and submit the embedded
6
+ * action envelope back to the CLI; they never infer coverage or synthesize a
7
+ * broader restore locally.
8
+ */
9
+
10
+ import { createHash } from "node:crypto";
11
+
12
+ export const CHECKPOINT_TIMELINE_SCHEMA = "cc-checkpoint-timeline/v1";
13
+ export const CHECKPOINT_TIMELINE_VERSION = 1;
14
+ export const CHECKPOINT_TIMELINE_ACTION_SCHEMA =
15
+ "cc-checkpoint-timeline-action/v1";
16
+ export const CHECKPOINT_TIMELINE_ACTION_VERSION = 1;
17
+
18
+ export const CHECKPOINT_TIMELINE_COVERAGE = Object.freeze({
19
+ FULL: "full",
20
+ PARTIAL: "partial",
21
+ NONE: "none",
22
+ });
23
+
24
+ export const CHECKPOINT_TIMELINE_MARKERS = Object.freeze({
25
+ CHECKPOINT: "checkpoint",
26
+ COMMIT: "commit",
27
+ TOOL_SIDE_EFFECT: "tool-side-effect",
28
+ ARTIFACT: "artifact",
29
+ VERIFICATION: "verification",
30
+ });
31
+
32
+ export const CHECKPOINT_TIMELINE_ACTIONS = Object.freeze({
33
+ RESTORE_CODE: "restore-code",
34
+ RESTORE_CONVERSATION: "restore-conversation",
35
+ RESTORE_BOTH: "restore-both",
36
+ SUMMARY_FROM: "summary-from",
37
+ SUMMARY_TO: "summary-to",
38
+ BRANCH: "branch",
39
+ });
40
+
41
+ const MARKER_ORDER = Object.freeze(Object.values(CHECKPOINT_TIMELINE_MARKERS));
42
+ const ACTION_ORDER = Object.freeze(Object.values(CHECKPOINT_TIMELINE_ACTIONS));
43
+ const COVERAGES = new Set(Object.values(CHECKPOINT_TIMELINE_COVERAGE));
44
+ const MARKERS = new Set(MARKER_ORDER);
45
+ const MAX_TURNS = 1_000;
46
+ const MAX_MARKERS = 4_096;
47
+ const MAX_LIST_ITEMS = 256;
48
+
49
+ function boundedString(value, max = 512) {
50
+ if (value == null) return null;
51
+ const text = Array.from(String(value), (character) => {
52
+ const code = character.charCodeAt(0);
53
+ return code <= 0x1f || code === 0x7f ? "" : character;
54
+ })
55
+ .join("")
56
+ .trim();
57
+ return text ? text.slice(0, max) : null;
58
+ }
59
+
60
+ function uniqueStrings(values, max = MAX_LIST_ITEMS) {
61
+ const out = [];
62
+ const seen = new Set();
63
+ const source = Array.isArray(values) ? values.slice(0, max) : [];
64
+ for (const value of source) {
65
+ const text = boundedString(value, 1_024);
66
+ if (!text || seen.has(text)) continue;
67
+ seen.add(text);
68
+ out.push(text);
69
+ if (out.length >= max) break;
70
+ }
71
+ return out;
72
+ }
73
+
74
+ function jsonObject(value) {
75
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
76
+ try {
77
+ const cloned = JSON.parse(JSON.stringify(value));
78
+ return cloned && typeof cloned === "object" && !Array.isArray(cloned)
79
+ ? cloned
80
+ : {};
81
+ } catch {
82
+ return {};
83
+ }
84
+ }
85
+
86
+ function canonicalValue(value, depth = 0) {
87
+ if (depth > 32 || value == null) return value == null ? null : null;
88
+ if (typeof value === "string" || typeof value === "boolean") return value;
89
+ if (typeof value === "number") return Number.isFinite(value) ? value : null;
90
+ if (Array.isArray(value)) {
91
+ return value
92
+ .slice(0, MAX_MARKERS)
93
+ .map((item) => canonicalValue(item, depth + 1));
94
+ }
95
+ if (typeof value !== "object") return String(value);
96
+ const out = {};
97
+ for (const key of Object.keys(value).sort().slice(0, MAX_LIST_ITEMS)) {
98
+ out[key] = canonicalValue(value[key], depth + 1);
99
+ }
100
+ return out;
101
+ }
102
+
103
+ /** Deterministic authority revision over the persisted session/checkpoint view. */
104
+ export function deriveCheckpointTimelineRevision({
105
+ sessionId,
106
+ turns = [],
107
+ checkpoints = [],
108
+ markers = [],
109
+ headHash = null,
110
+ } = {}) {
111
+ const sourceTurns =
112
+ turns && typeof turns.list === "function" ? turns.list() : turns;
113
+ const material = canonicalValue({
114
+ sessionId: boundedString(sessionId, 256) || "default",
115
+ headHash: boundedString(headHash, 256),
116
+ turns: Array.isArray(sourceTurns) ? sourceTurns.slice(0, MAX_TURNS) : [],
117
+ checkpoints: Array.isArray(checkpoints)
118
+ ? checkpoints.slice(0, MAX_MARKERS)
119
+ : [],
120
+ markers: Array.isArray(markers) ? markers.slice(0, MAX_MARKERS) : [],
121
+ });
122
+ return `sha256:${createHash("sha256")
123
+ .update(JSON.stringify(material))
124
+ .digest("hex")}`;
125
+ }
126
+
127
+ function timestampString(value) {
128
+ if (typeof value === "string" && value.trim()) {
129
+ return value.trim().slice(0, 128);
130
+ }
131
+ if (Number.isFinite(Number(value)) && value != null) {
132
+ try {
133
+ return new Date(Number(value)).toISOString();
134
+ } catch {
135
+ return null;
136
+ }
137
+ }
138
+ return null;
139
+ }
140
+
141
+ function normalizeCoverage(value) {
142
+ return COVERAGES.has(value) ? value : CHECKPOINT_TIMELINE_COVERAGE.NONE;
143
+ }
144
+
145
+ function normalizeConversationOffset(value) {
146
+ if (value == null) return null;
147
+ const number = Number(value);
148
+ return Number.isSafeInteger(number) && number >= 0 ? number : null;
149
+ }
150
+
151
+ function normalizeCheckpointIdentity(value) {
152
+ const identity = boundedString(value, 256);
153
+ return /^(?:git:(?:[a-f0-9]{40}|[a-f0-9]{64})|sha256:[a-f0-9]{64})$/.test(
154
+ identity || "",
155
+ )
156
+ ? identity
157
+ : null;
158
+ }
159
+
160
+ function normalizeMarker(marker, index) {
161
+ if (!marker || typeof marker !== "object" || !MARKERS.has(marker.kind)) {
162
+ return null;
163
+ }
164
+ const turnId = boundedString(marker.turnId, 256);
165
+ const referenceId = boundedString(
166
+ marker.referenceId ?? marker.checkpointId ?? marker.commitId ?? marker.id,
167
+ 512,
168
+ );
169
+ const id =
170
+ boundedString(marker.id, 512) ||
171
+ `${marker.kind}:${turnId || "unbound"}:${referenceId || index}`;
172
+ return {
173
+ kind: marker.kind,
174
+ id,
175
+ turnId,
176
+ referenceId,
177
+ label: boundedString(marker.label, 512),
178
+ status: boundedString(marker.status, 128) || "recorded",
179
+ reversible:
180
+ typeof marker.reversible === "boolean"
181
+ ? marker.reversible
182
+ : marker.kind === CHECKPOINT_TIMELINE_MARKERS.CHECKPOINT ||
183
+ marker.kind === CHECKPOINT_TIMELINE_MARKERS.COMMIT ||
184
+ marker.kind === CHECKPOINT_TIMELINE_MARKERS.VERIFICATION,
185
+ timestamp: timestampString(marker.timestamp ?? marker.createdAt),
186
+ metadata: jsonObject(marker.metadata),
187
+ };
188
+ }
189
+
190
+ function checkpointMarker(checkpoint, turnId = null) {
191
+ const id = boundedString(checkpoint?.id, 512);
192
+ if (!id) return null;
193
+ const metadata = {};
194
+ if (Number.isFinite(Number(checkpoint.fileCount))) {
195
+ metadata.fileCount = Number(checkpoint.fileCount);
196
+ }
197
+ const commit = boundedString(checkpoint.commit, 128);
198
+ if (commit) metadata.commit = commit;
199
+ const identity = normalizeCheckpointIdentity(checkpoint.identity);
200
+ if (identity) metadata.identity = identity;
201
+ return normalizeMarker(
202
+ {
203
+ kind: CHECKPOINT_TIMELINE_MARKERS.CHECKPOINT,
204
+ id: `checkpoint:${id}`,
205
+ turnId,
206
+ referenceId: id,
207
+ label: checkpoint.label || id,
208
+ status: "available",
209
+ reversible: true,
210
+ timestamp: checkpoint.createdAt,
211
+ metadata,
212
+ },
213
+ 0,
214
+ );
215
+ }
216
+
217
+ function markerSort(left, right) {
218
+ const kind =
219
+ MARKER_ORDER.indexOf(left.kind) - MARKER_ORDER.indexOf(right.kind);
220
+ if (kind !== 0) return kind;
221
+ const timestamp = String(left.timestamp || "").localeCompare(
222
+ String(right.timestamp || ""),
223
+ );
224
+ if (timestamp !== 0) return timestamp;
225
+ return left.id.localeCompare(right.id);
226
+ }
227
+
228
+ function dedupeMarkers(markers) {
229
+ const out = [];
230
+ const seen = new Set();
231
+ for (const marker of markers.sort(markerSort)) {
232
+ const key = `${marker.kind}\u0000${marker.id}`;
233
+ if (seen.has(key)) continue;
234
+ seen.add(key);
235
+ out.push(marker);
236
+ }
237
+ return out;
238
+ }
239
+
240
+ function actionAvailability(
241
+ action,
242
+ hasCheckpoint,
243
+ hasCheckpointIdentity,
244
+ hasConversation,
245
+ ) {
246
+ if (action === CHECKPOINT_TIMELINE_ACTIONS.RESTORE_CODE) {
247
+ if (!hasCheckpoint) {
248
+ return { enabled: false, reason: "checkpoint-unavailable" };
249
+ }
250
+ return hasCheckpointIdentity
251
+ ? { enabled: true, reason: null }
252
+ : { enabled: false, reason: "checkpoint-identity-unavailable" };
253
+ }
254
+ if (action === CHECKPOINT_TIMELINE_ACTIONS.RESTORE_BOTH) {
255
+ if (!hasCheckpoint || !hasConversation) {
256
+ return {
257
+ enabled: false,
258
+ reason: "checkpoint-and-conversation-required",
259
+ };
260
+ }
261
+ return hasCheckpointIdentity
262
+ ? { enabled: true, reason: null }
263
+ : { enabled: false, reason: "checkpoint-identity-unavailable" };
264
+ }
265
+ return hasConversation
266
+ ? { enabled: true, reason: null }
267
+ : { enabled: false, reason: "conversation-offset-unavailable" };
268
+ }
269
+
270
+ function buildActions({
271
+ sessionId,
272
+ revision,
273
+ turnId,
274
+ checkpointId,
275
+ checkpointIdentity,
276
+ conversationOffset,
277
+ }) {
278
+ const hasCheckpoint = Boolean(checkpointId);
279
+ const hasCheckpointIdentity = Boolean(checkpointIdentity);
280
+ const hasConversation = conversationOffset != null;
281
+ return ACTION_ORDER.map((action) => {
282
+ const availability = actionAvailability(
283
+ action,
284
+ hasCheckpoint,
285
+ hasCheckpointIdentity,
286
+ hasConversation,
287
+ );
288
+ return {
289
+ action,
290
+ enabled: availability.enabled,
291
+ reason: availability.reason,
292
+ submission: availability.enabled
293
+ ? {
294
+ schema: CHECKPOINT_TIMELINE_ACTION_SCHEMA,
295
+ version: CHECKPOINT_TIMELINE_ACTION_VERSION,
296
+ authority: "cli",
297
+ revision,
298
+ action,
299
+ sessionId,
300
+ turnId,
301
+ checkpointId: checkpointId || null,
302
+ ...((action === CHECKPOINT_TIMELINE_ACTIONS.RESTORE_CODE ||
303
+ action === CHECKPOINT_TIMELINE_ACTIONS.RESTORE_BOTH) &&
304
+ checkpointIdentity
305
+ ? { checkpointIdentity }
306
+ : {}),
307
+ conversationOffset,
308
+ }
309
+ : null,
310
+ };
311
+ });
312
+ }
313
+
314
+ function managedCheckpointMarkers(turn, turnId) {
315
+ const markers = [];
316
+ const checkpoints = Array.isArray(turn?.managedCheckpoints)
317
+ ? turn.managedCheckpoints.slice(0, MAX_LIST_ITEMS)
318
+ : [];
319
+ for (const checkpoint of checkpoints) {
320
+ const checkpointId = boundedString(checkpoint?.checkpointId, 512);
321
+ if (checkpointId) {
322
+ const marker = normalizeMarker(
323
+ {
324
+ kind: CHECKPOINT_TIMELINE_MARKERS.CHECKPOINT,
325
+ id: `managed-checkpoint:${checkpointId}`,
326
+ turnId,
327
+ referenceId: checkpointId,
328
+ label: checkpoint.tool || checkpointId,
329
+ status: checkpoint.phase || "recorded",
330
+ reversible: checkpoint.fileCoverage !== "none",
331
+ metadata: {
332
+ managed: true,
333
+ transactionId: checkpoint.transactionId || null,
334
+ evidenceDigest: checkpoint.evidenceDigest || null,
335
+ coverage: normalizeCoverage(checkpoint.coverage),
336
+ fileCoverage: normalizeCoverage(checkpoint.fileCoverage),
337
+ },
338
+ },
339
+ markers.length,
340
+ );
341
+ if (marker) markers.push(marker);
342
+ }
343
+ if (normalizeCoverage(checkpoint?.coverage) !== "full") {
344
+ const marker = normalizeMarker(
345
+ {
346
+ kind: CHECKPOINT_TIMELINE_MARKERS.TOOL_SIDE_EFFECT,
347
+ id: `managed-side-effect:${checkpoint?.transactionId || checkpoint?.toolUseId || markers.length}`,
348
+ turnId,
349
+ referenceId: checkpoint?.toolUseId || checkpoint?.transactionId,
350
+ label: checkpoint?.tool || "managed tool side effect",
351
+ status: checkpoint?.phase || "recorded",
352
+ reversible: false,
353
+ metadata: {
354
+ transactionId: checkpoint?.transactionId || null,
355
+ coverage: normalizeCoverage(checkpoint?.coverage),
356
+ },
357
+ },
358
+ markers.length,
359
+ );
360
+ if (marker) markers.push(marker);
361
+ }
362
+ }
363
+ return markers;
364
+ }
365
+
366
+ function turnPaths(turn) {
367
+ const values = [];
368
+ const append = (source) => {
369
+ for (const value of Array.isArray(source) ? source : []) {
370
+ if (values.length >= MAX_LIST_ITEMS) return;
371
+ values.push(value);
372
+ }
373
+ };
374
+ append(turn?.excludedPaths);
375
+ append(turn?.uncoveredPaths);
376
+ const checkpoints = Array.isArray(turn?.managedCheckpoints)
377
+ ? turn.managedCheckpoints.slice(0, MAX_LIST_ITEMS)
378
+ : [];
379
+ for (const checkpoint of checkpoints) {
380
+ append(checkpoint?.excludedPaths);
381
+ append(checkpoint?.exclusions);
382
+ append(checkpoint?.uncoveredPaths);
383
+ if (values.length >= MAX_LIST_ITEMS) break;
384
+ }
385
+ return uniqueStrings(values);
386
+ }
387
+
388
+ function turnIrreversibleEffects(turn, coverage, markers) {
389
+ const values = Array.isArray(turn?.irreversibleSideEffects)
390
+ ? turn.irreversibleSideEffects.slice(0, MAX_LIST_ITEMS)
391
+ : [];
392
+ for (const marker of markers) {
393
+ if (
394
+ (marker.kind === CHECKPOINT_TIMELINE_MARKERS.TOOL_SIDE_EFFECT ||
395
+ marker.kind === CHECKPOINT_TIMELINE_MARKERS.ARTIFACT) &&
396
+ marker.reversible === false
397
+ ) {
398
+ values.push(marker.label || marker.referenceId || marker.id);
399
+ }
400
+ }
401
+ if (
402
+ coverage === CHECKPOINT_TIMELINE_COVERAGE.PARTIAL &&
403
+ values.length === 0
404
+ ) {
405
+ values.push("untracked-external-side-effect");
406
+ }
407
+ if (coverage === CHECKPOINT_TIMELINE_COVERAGE.NONE && values.length === 0) {
408
+ values.push("unrestorable-workspace-side-effect");
409
+ }
410
+ return uniqueStrings(values);
411
+ }
412
+
413
+ function warningCodes(coverage, excludedPaths, irreversibleSideEffects) {
414
+ const warnings = [];
415
+ if (coverage === CHECKPOINT_TIMELINE_COVERAGE.PARTIAL) {
416
+ warnings.push("partial-coverage");
417
+ } else if (coverage === CHECKPOINT_TIMELINE_COVERAGE.NONE) {
418
+ warnings.push("no-restore-coverage");
419
+ }
420
+ if (excludedPaths.length > 0) warnings.push("excluded-paths");
421
+ if (irreversibleSideEffects.length > 0) {
422
+ warnings.push("irreversible-side-effects");
423
+ }
424
+ return warnings;
425
+ }
426
+
427
+ /**
428
+ * Build the canonical projection from a turn-binding log (or turn array), file
429
+ * checkpoint rows, and optional marker records produced by other CLI systems.
430
+ */
431
+ export function buildCheckpointTimeline({
432
+ sessionId,
433
+ turns = [],
434
+ checkpoints = [],
435
+ markers = [],
436
+ revision = null,
437
+ headHash = null,
438
+ } = {}) {
439
+ const normalizedSessionId = boundedString(sessionId, 256) || "default";
440
+ const sourceTurns =
441
+ turns && typeof turns.list === "function" ? turns.list() : turns;
442
+ const turnList = (Array.isArray(sourceTurns) ? sourceTurns : [])
443
+ .filter((turn) => turn && turn.turnId != null)
444
+ .slice(0, MAX_TURNS);
445
+ const checkpointSource = (
446
+ Array.isArray(checkpoints) ? checkpoints : []
447
+ ).filter((checkpoint) => boundedString(checkpoint?.id, 512));
448
+ const checkpointList = checkpointSource.slice(0, MAX_MARKERS);
449
+ const referencedCheckpointIds = new Set(
450
+ turnList
451
+ .map((turn) => boundedString(turn?.fileCheckpointId, 512))
452
+ .filter(Boolean),
453
+ );
454
+ const checkpointById = new Map();
455
+ // Keep the bounded projection, but also retain the exact rows referenced by
456
+ // the bounded turn list. Manual checkpoint history is intentionally
457
+ // unbounded, so a referenced target can sit beyond MAX_MARKERS and still
458
+ // needs its immutable identity embedded in the action envelope.
459
+ for (let index = 0; index < checkpointSource.length; index += 1) {
460
+ const checkpoint = checkpointSource[index];
461
+ const checkpointId = String(checkpoint.id);
462
+ if (
463
+ !checkpointById.has(checkpointId) &&
464
+ (index < MAX_MARKERS || referencedCheckpointIds.has(checkpointId))
465
+ ) {
466
+ checkpointById.set(checkpointId, checkpoint);
467
+ }
468
+ }
469
+ const usedCheckpointIds = new Set();
470
+
471
+ const normalizedMarkers = (Array.isArray(markers) ? markers : [])
472
+ .slice(0, MAX_MARKERS)
473
+ .map((marker, index) => normalizeMarker(marker, index))
474
+ .filter(Boolean);
475
+ const timelineRevision =
476
+ boundedString(revision, 256) ||
477
+ deriveCheckpointTimelineRevision({
478
+ sessionId: normalizedSessionId,
479
+ turns: turnList,
480
+ checkpoints: checkpointList,
481
+ markers: normalizedMarkers,
482
+ headHash,
483
+ });
484
+ const markerByTurn = new Map();
485
+ const unboundMarkers = [];
486
+ for (const marker of normalizedMarkers) {
487
+ if (!marker.turnId) {
488
+ unboundMarkers.push(marker);
489
+ continue;
490
+ }
491
+ if (!markerByTurn.has(marker.turnId)) markerByTurn.set(marker.turnId, []);
492
+ markerByTurn.get(marker.turnId).push(marker);
493
+ }
494
+
495
+ const entries = turnList.map((turn, ordinal) => {
496
+ const turnId = boundedString(turn.turnId, 256);
497
+ const conversationOffset = normalizeConversationOffset(
498
+ turn.conversationOffset,
499
+ );
500
+ const checkpointId = boundedString(turn.fileCheckpointId, 512);
501
+ const checkpointIdentity = normalizeCheckpointIdentity(
502
+ checkpointById.get(checkpointId)?.identity,
503
+ );
504
+ const coverage = normalizeCoverage(turn.coverage);
505
+ const turnMarkers = [...(markerByTurn.get(turnId) || [])];
506
+ if (checkpointId) {
507
+ usedCheckpointIds.add(checkpointId);
508
+ const marker = checkpointMarker(
509
+ checkpointById.get(checkpointId) || { id: checkpointId },
510
+ turnId,
511
+ );
512
+ if (marker) turnMarkers.push(marker);
513
+ }
514
+ turnMarkers.push(...managedCheckpointMarkers(turn, turnId));
515
+ if (
516
+ coverage !== CHECKPOINT_TIMELINE_COVERAGE.FULL &&
517
+ !turnMarkers.some(
518
+ (marker) =>
519
+ marker.kind === CHECKPOINT_TIMELINE_MARKERS.TOOL_SIDE_EFFECT,
520
+ )
521
+ ) {
522
+ const marker = normalizeMarker(
523
+ {
524
+ kind: CHECKPOINT_TIMELINE_MARKERS.TOOL_SIDE_EFFECT,
525
+ id: `coverage-side-effect:${turnId}`,
526
+ turnId,
527
+ label:
528
+ coverage === CHECKPOINT_TIMELINE_COVERAGE.NONE
529
+ ? "workspace mutation without a restorable checkpoint"
530
+ : "irreversible or excluded side effect",
531
+ status: "unverified",
532
+ reversible: false,
533
+ metadata: { synthesizedFromCoverage: true },
534
+ },
535
+ turnMarkers.length,
536
+ );
537
+ if (marker) turnMarkers.push(marker);
538
+ }
539
+ const orderedMarkers = dedupeMarkers(turnMarkers);
540
+ const excludedPaths = turnPaths(turn);
541
+ const irreversibleSideEffects = turnIrreversibleEffects(
542
+ turn,
543
+ coverage,
544
+ orderedMarkers,
545
+ );
546
+ return {
547
+ turnId,
548
+ ordinal,
549
+ conversationOffset,
550
+ coverage,
551
+ excludedPaths,
552
+ irreversibleSideEffects,
553
+ warnings: warningCodes(coverage, excludedPaths, irreversibleSideEffects),
554
+ markers: orderedMarkers,
555
+ actions: buildActions({
556
+ sessionId: normalizedSessionId,
557
+ revision: timelineRevision,
558
+ turnId,
559
+ checkpointId,
560
+ checkpointIdentity,
561
+ conversationOffset,
562
+ }),
563
+ };
564
+ });
565
+
566
+ const knownTurnIds = new Set(entries.map((entry) => entry.turnId));
567
+ for (const [turnId, turnMarkers] of markerByTurn) {
568
+ if (!knownTurnIds.has(turnId)) unboundMarkers.push(...turnMarkers);
569
+ }
570
+ for (const checkpoint of checkpointList) {
571
+ const checkpointId = String(checkpoint.id);
572
+ if (usedCheckpointIds.has(checkpointId)) continue;
573
+ const marker = checkpointMarker(checkpoint);
574
+ if (marker) unboundMarkers.push(marker);
575
+ }
576
+
577
+ return {
578
+ schema: CHECKPOINT_TIMELINE_SCHEMA,
579
+ version: CHECKPOINT_TIMELINE_VERSION,
580
+ authority: "cli",
581
+ actionSchema: CHECKPOINT_TIMELINE_ACTION_SCHEMA,
582
+ sessionId: normalizedSessionId,
583
+ revision: timelineRevision,
584
+ entries,
585
+ unboundMarkers: dedupeMarkers(unboundMarkers).slice(0, MAX_MARKERS),
586
+ };
587
+ }
588
+
589
+ /** Fail-closed lookup used by hosts before they submit an embedded action. */
590
+ export function resolveCheckpointTimelineAction(timeline, turnId, action) {
591
+ if (
592
+ !timeline ||
593
+ timeline.schema !== CHECKPOINT_TIMELINE_SCHEMA ||
594
+ timeline.version !== CHECKPOINT_TIMELINE_VERSION ||
595
+ timeline.authority !== "cli" ||
596
+ timeline.actionSchema !== CHECKPOINT_TIMELINE_ACTION_SCHEMA ||
597
+ typeof timeline.revision !== "string" ||
598
+ !timeline.revision
599
+ ) {
600
+ return { ok: false, code: "TIMELINE_SCHEMA_UNSUPPORTED" };
601
+ }
602
+ const entry = (timeline.entries || []).find(
603
+ (candidate) => candidate?.turnId === String(turnId),
604
+ );
605
+ if (!entry) return { ok: false, code: "TIMELINE_TURN_NOT_FOUND" };
606
+ const projected = (entry.actions || []).find(
607
+ (candidate) => candidate?.action === action,
608
+ );
609
+ if (!projected) return { ok: false, code: "TIMELINE_ACTION_UNKNOWN" };
610
+ if (projected.enabled !== true || !projected.submission) {
611
+ return {
612
+ ok: false,
613
+ code: "TIMELINE_ACTION_UNAVAILABLE",
614
+ reason: projected.reason || null,
615
+ };
616
+ }
617
+ if (projected.submission.revision !== timeline.revision) {
618
+ return { ok: false, code: "TIMELINE_SUBMISSION_REVISION_INVALID" };
619
+ }
620
+ return {
621
+ ok: true,
622
+ submission: JSON.parse(JSON.stringify(projected.submission)),
623
+ };
624
+ }
625
+
626
+ /** Small cross-host comparison projection used by shared conformance fixtures. */
627
+ export function projectCheckpointTimeline(timeline) {
628
+ return {
629
+ sessionId: timeline?.sessionId || null,
630
+ revision: timeline?.revision || null,
631
+ entries: (timeline?.entries || []).map((entry) => ({
632
+ turnId: entry.turnId,
633
+ coverage: entry.coverage,
634
+ markerKinds: (entry.markers || []).map((marker) => marker.kind),
635
+ enabledActions: (entry.actions || [])
636
+ .filter((action) => action.enabled === true)
637
+ .map((action) => action.action),
638
+ excludedPaths: [...(entry.excludedPaths || [])],
639
+ irreversibleSideEffects: [...(entry.irreversibleSideEffects || [])],
640
+ })),
641
+ };
642
+ }