chainlesschain 0.166.77 → 0.166.79

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 (230) hide show
  1. package/README.md +9 -8
  2. package/completions/_cc +1 -1
  3. package/completions/cc.bash +1 -1
  4. package/completions/cc.fish +1 -1
  5. package/completions/cc.ps1 +1 -1
  6. package/package.json +1 -1
  7. package/src/assets/linux-subreaper/linux-arm64/manifest.json +10 -0
  8. package/src/assets/linux-subreaper/linux-arm64/supervisor +0 -0
  9. package/src/assets/linux-subreaper/linux-x64/manifest.json +10 -0
  10. package/src/assets/linux-subreaper/linux-x64/supervisor +0 -0
  11. package/src/assets/web-panel/assets/{AIOps-CpiCBhRh.js → AIOps-CwD6Pm_Y.js} +1 -1
  12. package/src/assets/web-panel/assets/{ActionButton-CnU-Xvx-.js → ActionButton-Du5Rp-O6.js} +1 -1
  13. package/src/assets/web-panel/assets/{Analytics-BJW-CNtf.js → Analytics-DY9l72ma.js} +3 -3
  14. package/src/assets/web-panel/assets/{AppLayout-UFQJL3G9.js → AppLayout-7t1WIaCJ.js} +5 -5
  15. package/src/assets/web-panel/assets/{Artifacts-Dr_IUDoY.js → Artifacts-BLIA5yny.js} +1 -1
  16. package/src/assets/web-panel/assets/{Audit-aglWo6rr.js → Audit-BC_N0QTg.js} +1 -1
  17. package/src/assets/web-panel/assets/{BackgroundAgents-Dm_TCiXC.js → BackgroundAgents-CA7SxDtg.js} +1 -1
  18. package/src/assets/web-panel/assets/{Backup-DUdX4-gA.js → Backup-BZ4AzS1_.js} +1 -1
  19. package/src/assets/web-panel/assets/{BaseInput-BTcLjy1o.js → BaseInput-BhiggGaH.js} +1 -1
  20. package/src/assets/web-panel/assets/{Chat-Bhy9qZrl.js → Chat-CDdBoIBI.js} +5 -5
  21. package/src/assets/web-panel/assets/ChatBubbleRenderer-hsBsrl31.js +1 -0
  22. package/src/assets/web-panel/assets/{Checkbox-CblrPa21.js → Checkbox-asoMKSEK.js} +1 -1
  23. package/src/assets/web-panel/assets/{Codegen-SEAHzOlr.js → Codegen-B0gElLdm.js} +1 -1
  24. package/src/assets/web-panel/assets/{Col-DJz8iFOR.js → Col-DrNzLpF6.js} +1 -1
  25. package/src/assets/web-panel/assets/{Community-RufKhcQt.js → Community-DCzB5qkI.js} +1 -1
  26. package/src/assets/web-panel/assets/{Compact-Dlifx08U.js → Compact-Db-Eua_j.js} +1 -1
  27. package/src/assets/web-panel/assets/{Compliance-DdhQWcHh.js → Compliance-B76NByjl.js} +1 -1
  28. package/src/assets/web-panel/assets/{Cowork-BLNn6oOm.js → Cowork-C-nK6Qpk.js} +3 -3
  29. package/src/assets/web-panel/assets/{Cron-Dv-JWY2d.js → Cron-C-GlQO19.js} +2 -2
  30. package/src/assets/web-panel/assets/{Crosschain-k7Pz7O-b.js → Crosschain-Cuuz9IIh.js} +1 -1
  31. package/src/assets/web-panel/assets/{DID-C_10syUW.js → DID-gwFaT973.js} +2 -2
  32. package/src/assets/web-panel/assets/{Dashboard-CMyH6Szx.js → Dashboard-DHDt5jEf.js} +2 -2
  33. package/src/assets/web-panel/assets/{Dropdown-DjmD2Saa.js → Dropdown-CJ9kog-Y.js} +1 -1
  34. package/src/assets/web-panel/assets/{EmailListRenderer-36_IRUSo.js → EmailListRenderer-DOSXFRiQ.js} +1 -1
  35. package/src/assets/web-panel/assets/{EvolutionSettings-CmtU0XmM.js → EvolutionSettings-CHYMP7rR.js} +1 -1
  36. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DEgf9kyP.js → FamilyGuardDashboard-C1gzG5EK.js} +1 -1
  37. package/src/assets/web-panel/assets/{Federation-DGO1wQls.js → Federation-CEdNVWUw.js} +1 -1
  38. package/src/assets/web-panel/assets/{FormItemContext-Doj1FmKW.js → FormItemContext-CwVOWPX8.js} +1 -1
  39. package/src/assets/web-panel/assets/{GenericCardRenderer-GzOU27iT.js → GenericCardRenderer-CgNUs3kT.js} +1 -1
  40. package/src/assets/web-panel/assets/{Git-Dd7D1EDK.js → Git-DM4MNnQo.js} +2 -2
  41. package/src/assets/web-panel/assets/{Governance-6IY8LcjI.js → Governance-DdOtjkvd.js} +1 -1
  42. package/src/assets/web-panel/assets/{Inference-BB9gl8q1.js → Inference-28PidFfr.js} +1 -1
  43. package/src/assets/web-panel/assets/{KnowledgeGraph-CeCed5wd.js → KnowledgeGraph-Bpj_qNUK.js} +1 -1
  44. package/src/assets/web-panel/assets/{Logs-CYOeHuaI.js → Logs-C6Ix19Ay.js} +2 -2
  45. package/src/assets/web-panel/assets/{MarkdownRenderer-Bk8Zqc2R.js → MarkdownRenderer-Bj6mtPbf.js} +1 -1
  46. package/src/assets/web-panel/assets/{Marketplace-D-_xgHgM.js → Marketplace-DqkhRSMP.js} +1 -1
  47. package/src/assets/web-panel/assets/{McpTools-NnaUTF5t.js → McpTools-1WQ2SjaE.js} +3 -3
  48. package/src/assets/web-panel/assets/{Memory-CndN9pMt.js → Memory-BWTi7v6R.js} +2 -2
  49. package/src/assets/web-panel/assets/{MobileBridge-BXblFmhY.js → MobileBridge-DB4wu3UE.js} +1 -1
  50. package/src/assets/web-panel/assets/{MobileProjects-CC26Dm2k.js → MobileProjects-Bh9pWx2f.js} +1 -1
  51. package/src/assets/web-panel/assets/{Mtc-BhaqWCiW.js → Mtc-BVF1Wrno.js} +4 -4
  52. package/src/assets/web-panel/assets/{MtcAudit-D6fktM2w.js → MtcAudit-DtNfslPf.js} +5 -5
  53. package/src/assets/web-panel/assets/{Multisig-CFvahz7s.js → Multisig-4qcXP0bf.js} +3 -3
  54. package/src/assets/web-panel/assets/{NLProgramming-Co73Ivya.js → NLProgramming-BRJl5Ehw.js} +1 -1
  55. package/src/assets/web-panel/assets/{Notes-B4g33L1o.js → Notes-BRY_bgMk.js} +3 -3
  56. package/src/assets/web-panel/assets/{NotificationSettings-lXd17EbN.js → NotificationSettings-DirXMFz4.js} +1 -1
  57. package/src/assets/web-panel/assets/{OrderTableRenderer-BiOB0GIi.js → OrderTableRenderer-BlrY8lwu.js} +1 -1
  58. package/src/assets/web-panel/assets/{Organization-JQ7_wQIA.js → Organization-CVzQ1vO-.js} +4 -4
  59. package/src/assets/web-panel/assets/{Overflow-gwgJgozQ.js → Overflow-A3rXTPG4.js} +1 -1
  60. package/src/assets/web-panel/assets/{P2P-D9L_0gie.js → P2P-Db9ABWz0.js} +2 -2
  61. package/src/assets/web-panel/assets/{PdhVaultBrowser-CbOPsFE9.js → PdhVaultBrowser-CPv0H2OZ.js} +3 -3
  62. package/src/assets/web-panel/assets/{Permissions-Cz42HNQf.js → Permissions-COnW4sIR.js} +4 -4
  63. package/src/assets/web-panel/assets/{PersonalDataHub-DjorYtrF.js → PersonalDataHub-C1hG7rp7.js} +5 -5
  64. package/src/assets/web-panel/assets/{Pipeline-DyWPhmm5.js → Pipeline---GLRDEe.js} +1 -1
  65. package/src/assets/web-panel/assets/{Privacy-DyfLMl2j.js → Privacy-aaN9R3Lu.js} +1 -1
  66. package/src/assets/web-panel/assets/{ProjectInit-CyqDx1OE.js → ProjectInit-C-kw49hE.js} +2 -2
  67. package/src/assets/web-panel/assets/{ProjectSettings-DsBw0Csy.js → ProjectSettings-y5tTkBTC.js} +2 -2
  68. package/src/assets/web-panel/assets/Projects-DZHlhyPB.js +1 -0
  69. package/src/assets/web-panel/assets/{Providers-CCI_klN-.js → Providers-LqxnV72o.js} +1 -1
  70. package/src/assets/web-panel/assets/{QrScannerModal-DNsnlDdS.js → QrScannerModal-D_q-Y5F0.js} +1 -1
  71. package/src/assets/web-panel/assets/{QuickAsk-B9r2iaee.js → QuickAsk-_E_KB5o8.js} +1 -1
  72. package/src/assets/web-panel/assets/{Recommend-BJDe03GR.js → Recommend-BN8S5WJA.js} +1 -1
  73. package/src/assets/web-panel/assets/{RemoteSession-J7JR3rRo.js → RemoteSession-BFzrY_aW.js} +3 -3
  74. package/src/assets/web-panel/assets/{Reputation-DR39AJeV.js → Reputation-C1HCLaTV.js} +1 -1
  75. package/src/assets/web-panel/assets/{Row-Dh77m3NZ.js → Row-B8T2-Qv7.js} +1 -1
  76. package/src/assets/web-panel/assets/{RssFeed-BUdg28nJ.js → RssFeed-CNQLk8v1.js} +3 -3
  77. package/src/assets/web-panel/assets/{Search-BNC7sGhj.js → Search-BOx720Kc.js} +1 -1
  78. package/src/assets/web-panel/assets/{Security-DISENGI7.js → Security-Ds8z6PF6.js} +4 -4
  79. package/src/assets/web-panel/assets/{Services-BBBGpJ1-.js → Services-C0-YkRSF.js} +2 -2
  80. package/src/assets/web-panel/assets/{Skeleton-DMcIoIv2.js → Skeleton-DUHlSySD.js} +1 -1
  81. package/src/assets/web-panel/assets/{Skills-QAyFbI3r.js → Skills-C8CBbbh0.js} +1 -1
  82. package/src/assets/web-panel/assets/{Sla-CSg5wLH7.js → Sla-lQltyYfB.js} +1 -1
  83. package/src/assets/web-panel/assets/{SpeechSettings-DMPxTc5x.js → SpeechSettings-B5vyOma-.js} +1 -1
  84. package/src/assets/web-panel/assets/{SyncSettings-CPG7l30y.js → SyncSettings-BKDPu_y-.js} +2 -2
  85. package/src/assets/web-panel/assets/{Tasks-Y1kOVvVL.js → Tasks-Bgvf7LTx.js} +1 -1
  86. package/src/assets/web-panel/assets/{Templates-jt9NagL0.js → Templates-BMZyYYS7.js} +1 -1
  87. package/src/assets/web-panel/assets/{Tenant-DauuJICx.js → Tenant-7PYTig8f.js} +1 -1
  88. package/src/assets/web-panel/assets/{Terminal-E9rnKeGq.js → Terminal-C2W0LMdR.js} +2 -2
  89. package/src/assets/web-panel/assets/{TimelineRenderer-Cc7z2APG.js → TimelineRenderer-CqREew_l.js} +1 -1
  90. package/src/assets/web-panel/assets/{Tokens-CV0UthRA.js → Tokens-BhTyxTuD.js} +1 -1
  91. package/src/assets/web-panel/assets/{Trigger-BFcJJGfu.js → Trigger-DxNSSZy_.js} +1 -1
  92. package/src/assets/web-panel/assets/{Trust-BAydbNJA.js → Trust-Dy_wfbIh.js} +1 -1
  93. package/src/assets/web-panel/assets/{UkeySign-DcOS6sqL.js → UkeySign-DJC5ANqx.js} +1 -1
  94. package/src/assets/web-panel/assets/{VideoEditing-BLHJZvif.js → VideoEditing-CNFevrO4.js} +1 -1
  95. package/src/assets/web-panel/assets/{Wallet-4QFLKHwW.js → Wallet-CXzuS1YK.js} +4 -4
  96. package/src/assets/web-panel/assets/{WebAuthn-BocEOOSj.js → WebAuthn-BWS6HP8c.js} +5 -5
  97. package/src/assets/web-panel/assets/{WorkflowEditor-DCfF7D0B.js → WorkflowEditor-swiN_7Vj.js} +1 -1
  98. package/src/assets/web-panel/assets/{chat-CxvfsYGr.js → chat-NwH7qlBs.js} +1 -1
  99. package/src/assets/web-panel/assets/{colors-KtQB9DmQ.js → colors-h6nRhBTw.js} +1 -1
  100. package/src/assets/web-panel/assets/{compact-item-Dx4J6arN.js → compact-item-BQ6B6rP2.js} +1 -1
  101. package/src/assets/web-panel/assets/{createContext-Cq0olgzo.js → createContext-CQkJuRcG.js} +1 -1
  102. package/src/assets/web-panel/assets/devWarning-Bz6vqBGV.js +1 -0
  103. package/src/assets/web-panel/assets/{hasIn-Bf9-h3D-.js → hasIn-Diwl1WyI.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CpO6DKuu.js → index-0ZztPzIm.js} +1 -1
  105. package/src/assets/web-panel/assets/index-1b7DEw-w.js +1 -0
  106. package/src/assets/web-panel/assets/{index-DQDR-_ai.js → index-AzeSQJDK.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BMcC4cbj.js → index-B3QgcUBV.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BO6XvO-C.js → index-B5gj_uCC.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-ClUfSChI.js → index-BI3ALCgN.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-B3xfiItB.js → index-BRl3KUj0.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DFdEDvFn.js → index-BYYb8oeV.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CqnggDos.js → index-BcKDUGYf.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-B_8UcDan.js → index-BcjlIMP9.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CmQuG0fr.js → index-BheCvudN.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-iE9tqEN5.js → index-BjcARUtr.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-nmyDOh_b.js → index-BnQUin2K.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Br1mDMfO.js → index-Bs6HyCfP.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DZWjYfWt.js → index-BvPz6vZ8.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-0fi8DIVQ.js → index-C3Ye1ISy.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-hSzyoXri.js → index-C7-T-u0L.js} +3 -3
  121. package/src/assets/web-panel/assets/{index-DfrFNMvz.js → index-CRWpixu2.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-C9yaUHm9.js → index-CatBQDSQ.js} +1 -1
  123. package/src/assets/web-panel/assets/index-CfD4tMuW.js +1 -0
  124. package/src/assets/web-panel/assets/{index-DMR-keCL.js → index-CqH-oOR3.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-Cy865Hhq.js → index-CwsoVDi-.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DI5bRqNG.js → index-CyBtEVLM.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-gt5N6VM_.js → index-D5P498Rk.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-6dDDSCHD.js → index-DKaB4xTf.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BKtQyb2o.js → index-DQYZa1Ci.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CaIclw-E.js → index-DZ9CNcbJ.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-_FIz-0tp.js → index-DZAsByy4.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DBRlZdZj.js → index-D_HY0nyN.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DsCdl2Od.js → index-Da8frO_A.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-Cfsn7N18.js → index-DjB8IC9D.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-CeYP_kT9.js → index-Dwpthe2b.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-B8WuPI-h.js → index-Fm95dO4u.js} +1 -1
  137. package/src/assets/web-panel/assets/{index-CK2U_AHi.js → index-GTefQSbY.js} +1 -1
  138. package/src/assets/web-panel/assets/{index-DnU-dUWd.js → index-OEWSrqit.js} +1 -1
  139. package/src/assets/web-panel/assets/{index-DDAe1UmZ.js → index-TYMmUsxZ.js} +1 -1
  140. package/src/assets/web-panel/assets/{index-D2BfSIrn.js → index-iHNOr_wL.js} +1 -1
  141. package/src/assets/web-panel/assets/{index-Cz7f4Jaq.js → index-mxxZtsHp.js} +1 -1
  142. package/src/assets/web-panel/assets/{index-BHmdMKYl.js → index-pYwYBVeQ.js} +1 -1
  143. package/src/assets/web-panel/assets/{initDefaultProps-DvzKJ6o5.js → initDefaultProps-BeUrpC_H.js} +1 -1
  144. package/src/assets/web-panel/assets/{motion-D1yTvmxW.js → motion-CHW5EXt1.js} +1 -1
  145. package/src/assets/web-panel/assets/{move-DxtSIF8K.js → move-CWaoWJvF.js} +1 -1
  146. package/src/assets/web-panel/assets/{mtc-parser-BDsQgIHY.js → mtc-parser-CEC6Us1u.js} +1 -1
  147. package/src/assets/web-panel/assets/{omit-UVBJW8kh.js → omit-1D-kP_Qj.js} +1 -1
  148. package/src/assets/web-panel/assets/{pickAttrs-D4QqtTyX.js → pickAttrs-CsS0myLl.js} +1 -1
  149. package/src/assets/web-panel/assets/{placementArrow-QXmu6vBf.js → placementArrow-bMThOvkI.js} +1 -1
  150. package/src/assets/web-panel/assets/{responsiveObserve-D-PmXO9M.js → responsiveObserve-B72knbW8.js} +1 -1
  151. package/src/assets/web-panel/assets/{slide-CKbGxEZJ.js → slide-C3bI_2yy.js} +1 -1
  152. package/src/assets/web-panel/assets/{statusUtils-BbgXPkXm.js → statusUtils-0-FmcCAS.js} +1 -1
  153. package/src/assets/web-panel/assets/{styleChecker-DOr9rk68.js → styleChecker-DXUyqoWY.js} +1 -1
  154. package/src/assets/web-panel/assets/{useFlexGapSupport-B2wO2r36.js → useFlexGapSupport-BSSnL3f1.js} +1 -1
  155. package/src/assets/web-panel/assets/{useFs-SeVGBK34.js → useFs-B0Cvvl0S.js} +1 -1
  156. package/src/assets/web-panel/assets/{usePersonalDataHub-DUJBCxjD.js → usePersonalDataHub-6D-d4WU5.js} +1 -1
  157. package/src/assets/web-panel/assets/{vnode-CF4EYsig.js → vnode-zjIrlxT_.js} +1 -1
  158. package/src/assets/web-panel/assets/{zoom-pRUs5pqI.js → zoom-Hw7NEisu.js} +1 -1
  159. package/src/assets/web-panel/index.html +1 -1
  160. package/src/command-help-index.json +1 -1
  161. package/src/command-manifest.json +1 -1
  162. package/src/commands/checkpoint.js +42 -7
  163. package/src/commands/orchestrate.js +85 -25
  164. package/src/commands/session-location.js +5 -0
  165. package/src/commands/session-show.js +109 -1
  166. package/src/commands/session.js +26 -2
  167. package/src/commands/tokens.js +9 -4
  168. package/src/data/changelog.json +26 -0
  169. package/src/generated/cc-agent-protocol.schema.json +71 -0
  170. package/src/harness/jsonl-session-store.js +357 -114
  171. package/src/harness/mcp-client.js +44 -1
  172. package/src/lib/agent-router.js +35 -7
  173. package/src/lib/agent-sandbox.js +302 -2
  174. package/src/lib/app-server/server.js +14 -0
  175. package/src/lib/background-agent-supervisor.js +14 -4
  176. package/src/lib/causal-observability.js +64 -1
  177. package/src/lib/checkpoint-summary-projection.js +98 -0
  178. package/src/lib/checkpoint-timeline-authority.js +15 -51
  179. package/src/lib/claude-code-bridge.js +302 -60
  180. package/src/lib/codex-app-server-adapter.js +161 -35
  181. package/src/lib/cost-budget.js +4 -0
  182. package/src/lib/doctor-checkup.js +31 -2
  183. package/src/lib/durable-security-store.js +6 -1
  184. package/src/lib/evolution/evolution-artifact-identity.js +21 -0
  185. package/src/lib/evolution/evolution-artifact-ports.js +5 -11
  186. package/src/lib/evolution/evolution-eval-cohort-receipt-reconciliation.js +389 -0
  187. package/src/lib/execution-location-failure-site.js +63 -0
  188. package/src/lib/execution-location-target.js +102 -8
  189. package/src/lib/external-agent-adapters.js +2 -0
  190. package/src/lib/image-file-boundary.js +154 -0
  191. package/src/lib/image-input.js +16 -3
  192. package/src/lib/llm-pricing.js +114 -8
  193. package/src/lib/lsp/code-intelligence.js +7 -1
  194. package/src/lib/mcp-call-ledger-store.js +7 -2
  195. package/src/lib/model-capabilities.js +21 -10
  196. package/src/lib/model-context-catalog.js +60 -1
  197. package/src/lib/openai-responses.js +7 -1
  198. package/src/lib/orchestrator.js +8 -2
  199. package/src/lib/process-execution-broker/index.js +93 -1
  200. package/src/lib/process-execution-broker/linux-subreaper-artifact.js +120 -0
  201. package/src/lib/process-execution-broker/linux-subreaper-helper.js +344 -0
  202. package/src/lib/process-execution-broker/linux-subreaper-process.js +326 -0
  203. package/src/lib/process-execution-broker/linux-subreaper-supervisor.c +360 -0
  204. package/src/lib/process-execution-broker/owned-posix-process-group-worker.mjs +131 -0
  205. package/src/lib/process-execution-broker/owned-posix-process-group.js +267 -0
  206. package/src/lib/process-execution-broker/process-ownership-journal.js +297 -0
  207. package/src/lib/process-execution-broker/process-ownership-quarantine.js +91 -0
  208. package/src/lib/runtime-usage-ledger.js +3 -0
  209. package/src/lib/sandbox-docker-egress.js +507 -0
  210. package/src/lib/sandbox-egress-proxy.js +167 -10
  211. package/src/lib/sandbox-egress-worker-thread.js +38 -0
  212. package/src/lib/sandbox-egress-worker.js +196 -0
  213. package/src/lib/secure-fs.js +158 -42
  214. package/src/lib/session-branch-history.js +240 -0
  215. package/src/lib/session-history-origins.js +285 -0
  216. package/src/lib/session-input-receipt.js +110 -0
  217. package/src/lib/session-resource-budget.js +8 -8
  218. package/src/lib/session-transcript-history.js +456 -0
  219. package/src/lib/session-transcript-page.js +164 -0
  220. package/src/lib/session-transcript-reference.js +38 -0
  221. package/src/lib/session-usage.js +8 -0
  222. package/src/lib/token-tracker.js +32 -54
  223. package/src/lib/usage-pricing-context.js +93 -0
  224. package/src/runtime/agent-core.js +141 -21
  225. package/src/runtime/headless-stream.js +202 -4
  226. package/src/assets/web-panel/assets/ChatBubbleRenderer-D0WrJQaQ.js +0 -1
  227. package/src/assets/web-panel/assets/Projects-CRaSI25Z.js +0 -1
  228. package/src/assets/web-panel/assets/devWarning-CmgDNkoO.js +0 -1
  229. package/src/assets/web-panel/assets/index-BpIZ2S01.js +0 -1
  230. package/src/assets/web-panel/assets/index-C-VmKuyv.js +0 -1
@@ -235,9 +235,62 @@ function assertNoLinkTraversal(
235
235
  return target;
236
236
  }
237
237
 
238
+ // Reapplying an unchanged directory DACL propagates to existing children on
239
+ // Windows and changes their ctime, invalidating otherwise intact session
240
+ // witnesses. Serialize check-and-repair across processes and skip a verified
241
+ // owner-only ACL. Keep the post-repair inspection and all traversal guards.
242
+ const WINDOWS_ACL_IDEMPOTENT_REPAIR = String.raw`
243
+ function Test-CcOwnerOnlySecurity($item, $security) {
244
+ $owner = $security.GetOwner([System.Security.Principal.SecurityIdentifier]).Value
245
+ $rules = @($security.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier]))
246
+ if ($owner -ne $sid.Value -or $rules.Count -ne 1 -or ($item.PSIsContainer -and -not $security.AreAccessRulesProtected)) { return $false }
247
+ $rule = $rules[0]
248
+ $inheritance = [System.Security.AccessControl.InheritanceFlags]::None
249
+ if ($item.PSIsContainer) {
250
+ $inheritance = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
251
+ }
252
+ return ($rule.IdentityReference.Value -eq $sid.Value -and
253
+ $rule.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow -and
254
+ (-not $item.PSIsContainer -or -not $rule.IsInherited) -and
255
+ $rule.InheritanceFlags -eq $inheritance -and
256
+ $rule.PropagationFlags -eq [System.Security.AccessControl.PropagationFlags]::None -and
257
+ ($rule.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::FullControl) -eq [System.Security.AccessControl.FileSystemRights]::FullControl)
258
+ }
259
+ function Write-CcOwnerOnlyAcl($item, [string]$path) {
260
+ $script:ccAclStage = 'repair-lock'
261
+ [Console]::Error.WriteLine('CC_WINDOWS_ACL_STAGE=repair-lock')
262
+ $digest = [System.Security.Cryptography.SHA256]::Create()
263
+ try {
264
+ $key = [System.BitConverter]::ToString($digest.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($sid.Value + ':' + [System.IO.Path]::GetFullPath($path).ToUpperInvariant()))).Replace('-', '')
265
+ } finally { $digest.Dispose() }
266
+ $mutex = [System.Threading.Mutex]::new($false, ('Global\ChainlessChain.PrivateAcl.' + $key))
267
+ $held = $false
268
+ try {
269
+ try { $held = $mutex.WaitOne(10000) }
270
+ catch [System.Threading.AbandonedMutexException] { $held = $true }
271
+ if (-not $held) { throw 'Timed out waiting for owner-only ACL repair' }
272
+ Assert-CcNoReparseTraversal $path
273
+ $script:ccAclStage = 'repair-inspect'
274
+ [Console]::Error.WriteLine('CC_WINDOWS_ACL_STAGE=repair-inspect')
275
+ $current = Get-Item -LiteralPath $path -Force
276
+ $security = Read-CcAcl $path
277
+ if (Test-CcOwnerOnlySecurity $current $security) { return }
278
+ $script:ccAclStage = 'repair-write'
279
+ [Console]::Error.WriteLine('CC_WINDOWS_ACL_STAGE=repair-write')
280
+ Write-CcOwnerOnlyAclImpl $current $path
281
+ } finally {
282
+ if ($held) { $mutex.ReleaseMutex() }
283
+ $mutex.Dispose()
284
+ }
285
+ }
286
+ `;
287
+
238
288
  const WINDOWS_ACL_SCRIPT = String.raw`
239
289
  param([string]$target, [string]$operation)
240
290
  $ErrorActionPreference = 'Stop'
291
+ $script:ccAclStage = 'initialize'
292
+ try {
293
+ [Console]::Error.WriteLine('CC_WINDOWS_ACL_STAGE=initialize')
241
294
  $utf8 = [System.Text.UTF8Encoding]::new($false)
242
295
  [Console]::OutputEncoding = $utf8
243
296
  $sections =
@@ -263,7 +316,11 @@ function Assert-CcNoReparseTraversal([string]$path) {
263
316
  }
264
317
  }
265
318
 
319
+ $script:ccAclStage = 'traversal'
320
+ [Console]::Error.WriteLine('CC_WINDOWS_ACL_STAGE=traversal')
266
321
  Assert-CcNoReparseTraversal $target
322
+ $script:ccAclStage = 'lookup'
323
+ [Console]::Error.WriteLine('CC_WINDOWS_ACL_STAGE=lookup')
267
324
  $item = Get-Item -LiteralPath $target -Force
268
325
 
269
326
  function Read-CcAcl([string]$path) {
@@ -273,7 +330,8 @@ function Read-CcAcl([string]$path) {
273
330
  return [System.Security.AccessControl.FileSecurity]::new($path, $sections)
274
331
  }
275
332
 
276
- function Write-CcOwnerOnlyAcl($item, [string]$path) {
333
+ ${WINDOWS_ACL_IDEMPOTENT_REPAIR}
334
+ function Write-CcOwnerOnlyAclImpl($item, [string]$path) {
277
335
  $security = Read-CcAcl $path
278
336
  $owner = $security.GetOwner([System.Security.Principal.SecurityIdentifier])
279
337
  if ($owner.Value -ne $sid.Value) {
@@ -322,6 +380,8 @@ if ($operation -eq 'repair') {
322
380
  Write-CcOwnerOnlyAcl $item $target
323
381
  }
324
382
 
383
+ $script:ccAclStage = 'verify'
384
+ [Console]::Error.WriteLine('CC_WINDOWS_ACL_STAGE=verify')
325
385
  $acl = Read-CcAcl $target
326
386
  $owner = $acl.GetOwner([System.Security.Principal.SecurityIdentifier]).Value
327
387
  $rules = @($acl.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier]))
@@ -366,6 +426,18 @@ if ($ownerOnly) {
366
426
  aceCount = $rules.Count
367
427
  } | ConvertTo-Json -Compress
368
428
  if (-not $ownerOnly) { exit 4 }
429
+ } catch {
430
+ # Emit only a fixed stage and the deepest native HRESULT. Never emit the
431
+ # exception message, target path or arbitrary PowerShell error record.
432
+ $failure = $_.Exception
433
+ while ($null -ne $failure.InnerException) { $failure = $failure.InnerException }
434
+ [pscustomobject]@{
435
+ ownerOnly = $false
436
+ failureStage = $script:ccAclStage
437
+ hresult = ('0x{0:X8}' -f $failure.HResult)
438
+ } | ConvertTo-Json -Compress
439
+ exit 5
440
+ }
369
441
  `;
370
442
 
371
443
  const WINDOWS_ACL_BATCH_SCRIPT = String.raw`
@@ -481,7 +553,8 @@ function Read-CcAcl([string]$path) {
481
553
  return [System.Security.AccessControl.FileSecurity]::new($path, $sections)
482
554
  }
483
555
 
484
- function Write-CcOwnerOnlyAcl($item, [string]$path) {
556
+ ${WINDOWS_ACL_IDEMPOTENT_REPAIR}
557
+ function Write-CcOwnerOnlyAclImpl($item, [string]$path) {
485
558
  $security = Read-CcAcl $path
486
559
  $owner = $security.GetOwner([System.Security.Principal.SecurityIdentifier])
487
560
  if ($owner.Value -ne $sid.Value) {
@@ -614,19 +687,48 @@ export const _deps = {
614
687
  };
615
688
 
616
689
  // ACL repair starts a short PowerShell process on Windows. Cache successful
617
- // production repairs by path for this process; explicit injected-dependency
690
+ // production repairs by path and filesystem identity for this process; injected-dependency
618
691
  // tests and repairPrivatePath() always execute and verify the operation.
619
- const securedWindowsPaths = new Set();
692
+ const securedWindowsPaths = new Map();
693
+
694
+ function windowsPathIdentity(target, deps) {
695
+ try {
696
+ const entry = deps.fs.lstatSync(target, { bigint: true });
697
+ if (entry.isSymbolicLink() || !entry.ino) return null;
698
+ return `${entry.dev}:${entry.ino}:${entry.birthtimeNs}`;
699
+ } catch {
700
+ // An unreliable Node stat must take the native verification path again.
701
+ return null;
702
+ }
703
+ }
704
+
705
+ function rememberSecuredWindowsPath(target, deps) {
706
+ const identity = windowsPathIdentity(target, deps);
707
+ if (identity) securedWindowsPaths.set(target, identity);
708
+ else securedWindowsPaths.delete(target);
709
+ }
710
+
711
+ function isSecuredWindowsPath(target, deps) {
712
+ const cached = securedWindowsPaths.get(target);
713
+ return Boolean(cached && cached === windowsPathIdentity(target, deps));
714
+ }
620
715
  const WINDOWS_ACL_BATCH_SIZE = 500;
621
716
  const WINDOWS_ACL_TIMEOUT_ENV = "CC_SECURE_FS_WINDOWS_ACL_TIMEOUT_MS";
622
717
  const MAX_WINDOWS_ACL_TIMEOUT_MS = 5 * 60_000;
623
- const WINDOWS_ACL_TIMEOUT_RETRY_LIMIT = 1;
624
718
 
625
719
  export function _windowsAclWorkingDirectory(
626
720
  environment = process.env,
627
721
  filesystem = fs,
628
722
  ) {
629
- if (!isFormalQualityHermeticRuntime(environment)) return null;
723
+ // Isolated profiles can make Windows PowerShell first-use caches relative
724
+ // to cwd. Contain those writes in application state, never the source tree.
725
+ const isolatedLocalTarget =
726
+ typeof environment.CC_EXECUTION_LOCATION_RUNNER_ID === "string" &&
727
+ environment.CC_EXECUTION_LOCATION_RUNNER_ID.length > 0 &&
728
+ typeof environment.CHAINLESSCHAIN_HOME === "string" &&
729
+ isNativeAbsolute(environment.CHAINLESSCHAIN_HOME);
730
+ if (!isFormalQualityHermeticRuntime(environment) && !isolatedLocalTarget)
731
+ return null;
630
732
  const configuredHome = resolve(String(environment.CHAINLESSCHAIN_HOME));
631
733
  try {
632
734
  const entry = filesystem.lstatSync(configuredHome);
@@ -654,44 +756,25 @@ export function _resolveWindowsAclTimeout(
654
756
  );
655
757
  }
656
758
 
657
- // A timed-out spawn has already been terminated by Node. Retrying that one
658
- // transient runner-startup failure is safe: preflight is read-only and ACL
659
- // repair is idempotent. Both attempts share the caller's original timeout
660
- // budget so a busy Windows runner cannot multiply synchronous blocking time.
661
- // Every other failure remains fail-closed so this never treats a script, parse,
662
- // or permission failure as a transient condition.
759
+ // Give one cold PowerShell process the full bounded operation budget. Splitting
760
+ // it into two shorter spawns repeatedly kills a slow startup before it can
761
+ // finish (and can leave less time than the native mutex's 10-second wait).
762
+ // A process that exhausts the budget remains a failure; never start another
763
+ // process with a fresh budget or accept an unverified ACL after a timeout.
663
764
  function runWindowsAclCommand(deps, args, options) {
664
- const totalTimeoutMs = Math.max(1, Math.floor(Number(options?.timeout) || 1));
665
- const retryTimeoutMs = Math.max(
666
- 1,
667
- Math.floor(totalTimeoutMs / (WINDOWS_ACL_TIMEOUT_RETRY_LIMIT + 1)),
668
- );
669
- const firstTimeoutMs = Math.max(1, totalTimeoutMs - retryTimeoutMs);
670
- let result = deps.spawnSync("powershell.exe", args, {
765
+ return deps.spawnSync("powershell.exe", args, {
671
766
  ...options,
672
- timeout: firstTimeoutMs,
767
+ timeout: Math.max(1, Math.floor(Number(options?.timeout) || 1)),
673
768
  });
674
- for (
675
- let attempt = 0;
676
- result?.error?.code === "ETIMEDOUT" &&
677
- attempt < WINDOWS_ACL_TIMEOUT_RETRY_LIMIT;
678
- attempt += 1
679
- ) {
680
- result = deps.spawnSync("powershell.exe", args, {
681
- ...options,
682
- timeout: retryTimeoutMs,
683
- });
684
- }
685
- return result;
686
769
  }
687
770
 
688
771
  function repairWindowsAclOnce(target, deps, options) {
689
772
  const cacheable = !options.deps;
690
- if (cacheable && securedWindowsPaths.has(target)) {
773
+ if (cacheable && isSecuredWindowsPath(target, deps)) {
691
774
  return { ok: true, platform: "win32", cached: true };
692
775
  }
693
776
  const result = windowsAcl(target, "repair", deps);
694
- if (result.ok && cacheable) securedWindowsPaths.add(target);
777
+ if (result.ok && cacheable) rememberSecuredWindowsPath(target, deps);
695
778
  return result;
696
779
  }
697
780
 
@@ -724,21 +807,54 @@ function windowsAcl(target, operation, deps) {
724
807
  details = null;
725
808
  }
726
809
  if (result?.error) {
727
- return { ok: false, platform: "win32", error: result.error.message };
810
+ const progress =
811
+ [
812
+ ...String(result.stderr || "")
813
+ .slice(0, 8192)
814
+ .matchAll(
815
+ /^CC_WINDOWS_ACL_STAGE=(initialize|traversal|lookup|repair-lock|repair-inspect|repair-write|verify)\r?$/gmu,
816
+ ),
817
+ ].at(-1)?.[1] || "startup";
818
+ const stage =
819
+ result.error.code === "ETIMEDOUT" ? `timeout-${progress}` : "spawn";
820
+ return {
821
+ ok: false,
822
+ platform: "win32",
823
+ error: `owner-only ACL process failed [windows-acl:${stage}]`,
824
+ };
728
825
  }
729
826
  if (result?.status !== 0 || details?.ownerOnly !== true) {
730
827
  return {
731
828
  ok: false,
732
829
  platform: "win32",
733
- error:
734
- String(result?.stderr || "").trim() ||
735
- `owner-only ACL verification exited ${result?.status}`,
830
+ error: `owner-only ACL verification failed ${windowsAclFailureMarker(details)}`,
736
831
  details,
737
832
  };
738
833
  }
739
834
  return { ok: true, platform: "win32", details };
740
835
  }
741
836
 
837
+ function windowsAclFailureMarker(details) {
838
+ const allowedStages = new Set([
839
+ "initialize",
840
+ "traversal",
841
+ "lookup",
842
+ "repair-lock",
843
+ "repair-inspect",
844
+ "repair-write",
845
+ "verify",
846
+ ]);
847
+ if (
848
+ allowedStages.has(details?.failureStage) &&
849
+ /^0x[0-9a-f]{8}$/iu.test(details?.hresult || "")
850
+ ) {
851
+ return `[windows-acl:${details.failureStage}:${details.hresult.toLowerCase()}]`;
852
+ }
853
+ return details?.ownerOnly === false
854
+ ? "[windows-acl:verify]"
855
+ : "[windows-acl:output]";
856
+ }
857
+
742
858
  function windowsAclBatch(targets, operation, deps, expectedKind = null) {
743
859
  if (targets.length === 0) return [];
744
860
  const workingDirectory = _windowsAclWorkingDirectory(process.env, deps.fs);
@@ -999,7 +1115,7 @@ export function repairPrivatePaths(targets, options = {}) {
999
1115
  if (!options.deps) {
1000
1116
  for (const result of results) {
1001
1117
  if (result.ok && result.exists !== false) {
1002
- securedWindowsPaths.add(result.target);
1118
+ rememberSecuredWindowsPath(result.target, deps);
1003
1119
  }
1004
1120
  }
1005
1121
  }
@@ -1064,7 +1180,7 @@ function repairPrivatePathAfterPreflight(target, options, deps) {
1064
1180
  const result = windowsAcl(target, "repair", deps);
1065
1181
  if (!result.ok)
1066
1182
  throw new Error(result.error || "owner-only ACL repair failed");
1067
- if (!options.deps) securedWindowsPaths.add(target);
1183
+ if (!options.deps) rememberSecuredWindowsPath(target, deps);
1068
1184
  return result;
1069
1185
  }
1070
1186
  const stat = deps.fs.lstatSync(target);
@@ -1183,7 +1299,7 @@ export function ensurePrivateFile(target, options = {}) {
1183
1299
  }
1184
1300
  } else if (
1185
1301
  options.applyWindowsAcl === true &&
1186
- (options.deps || !securedWindowsPaths.has(target))
1302
+ (options.deps || !isSecuredWindowsPath(target, deps))
1187
1303
  ) {
1188
1304
  const [result] = windowsAclBatch([String(target)], "repair", deps, "file");
1189
1305
  if (result.errorCode === "EXPECTED_KIND_MISMATCH") {
@@ -1192,7 +1308,7 @@ export function ensurePrivateFile(target, options = {}) {
1192
1308
  if (!result.ok && result.exists !== false && options.failIfUnavailable) {
1193
1309
  throw new Error(result.error || `Could not secure ${target}`);
1194
1310
  }
1195
- if (result.ok && !options.deps) securedWindowsPaths.add(target);
1311
+ if (result.ok && !options.deps) rememberSecuredWindowsPath(target, deps);
1196
1312
  }
1197
1313
  return target;
1198
1314
  }
@@ -0,0 +1,240 @@
1
+ import { canonicalDigest } from "@chainlesschain/context-memory-kernel";
2
+ import { createHash } from "node:crypto";
3
+ import { SESSION_GENERATION_AUTHORITY_FIELD } from "../harness/session-list-index.js";
4
+ import {
5
+ encodePersistedMessage,
6
+ decodeVerifiedPersistedMessage,
7
+ getDurableSystemMessageProvenance,
8
+ projectCanonicalResumeMessages,
9
+ } from "./session-message-provenance.js";
10
+
11
+ export const BRANCH_HISTORY_SCHEMA = "chainlesschain.session-branch-history/v1";
12
+ export const BRANCH_HISTORY_SYSTEM_ORIGINS_SCHEMA =
13
+ "chainlesschain.session-branch-history/v2";
14
+ export const BRANCH_HISTORY_MESSAGE = "session_history_message";
15
+ export const BRANCH_HISTORY_ORIGIN = "session_history_origin";
16
+ const capabilities = new WeakMap();
17
+
18
+ export const branchContextDigest = (messages) =>
19
+ canonicalDigest(
20
+ projectCanonicalResumeMessages(messages, { strict: true }).map(
21
+ encodePersistedMessage,
22
+ ),
23
+ "chainlesschain.branch-history-context/v1",
24
+ );
25
+ export const branchMessageDigest = (message) =>
26
+ canonicalDigest(message, "chainlesschain.branch-history-message/v1");
27
+
28
+ // A caller cannot smuggle JSON-shaped history into a new authority chain. The
29
+ // capability exists only inside a verified source projection's synchronous lock.
30
+ export function withSessionBranchHistory(plan, task) {
31
+ if (typeof task !== "function" || task.constructor?.name === "AsyncFunction")
32
+ throw new TypeError("Branch history consumer must be synchronous");
33
+ const capability = Object.freeze({});
34
+ capabilities.set(capability, plan);
35
+ try {
36
+ const result = task(capability);
37
+ if (result && typeof result.then === "function")
38
+ throw new TypeError("Branch history consumer must be synchronous");
39
+ return result;
40
+ } finally {
41
+ capabilities.delete(capability);
42
+ }
43
+ }
44
+
45
+ export function resolveSessionBranchHistory(
46
+ capability,
47
+ parentSessionId,
48
+ messages,
49
+ ) {
50
+ if (capability == null) return null;
51
+ const plan = capabilities.get(capability);
52
+ if (
53
+ !plan ||
54
+ plan.parentSessionId !== parentSessionId ||
55
+ plan.contextDigest !== branchContextDigest(messages)
56
+ ) {
57
+ throw new Error(
58
+ "Branch history capability is expired or does not match the branch",
59
+ );
60
+ }
61
+ return plan;
62
+ }
63
+
64
+ export function createBranchHistoryImport() {
65
+ let start = null;
66
+ let index = 0;
67
+ let active = null;
68
+ const hash = (value) =>
69
+ typeof value === "string" && /^[a-f0-9]{64}$/u.test(value);
70
+ const integer = (value) => Number.isSafeInteger(value) && value >= 0;
71
+ const invalid = () => {
72
+ const error = new Error(
73
+ "Branch display history is incomplete or inconsistent",
74
+ );
75
+ error.code = "SESSION_BRANCH_HISTORY_INVALID";
76
+ throw error;
77
+ };
78
+ const require = (condition) => {
79
+ if (!condition) invalid();
80
+ };
81
+ return {
82
+ accept(event) {
83
+ index += 1;
84
+ if (index === 1 && event.type === "session_start") {
85
+ const data = { ...event.data };
86
+ delete data[SESSION_GENERATION_AUTHORITY_FIELD];
87
+ start = { type: event.type, data };
88
+ }
89
+ if (event.type === "session_branch" && event.data?.history != null) {
90
+ const descriptor = event.data.history;
91
+ require(
92
+ index === 2 &&
93
+ start &&
94
+ !active &&
95
+ [
96
+ BRANCH_HISTORY_SCHEMA,
97
+ BRANCH_HISTORY_SYSTEM_ORIGINS_SCHEMA,
98
+ ].includes(descriptor.schema) &&
99
+ hash(descriptor.sourceGeneration) &&
100
+ integer(descriptor.totalMessages) &&
101
+ integer(descriptor.contextMessageCount) &&
102
+ descriptor.contextMessageCount <= 32768,
103
+ );
104
+ const coverage = descriptor.coverage;
105
+ require(
106
+ coverage?.kind === "from-origin"
107
+ ? coverage.boundaryEvent === null && coverage.reason === null
108
+ : coverage?.kind === "snapshot-boundary" &&
109
+ hash(coverage.boundaryEvent) &&
110
+ [
111
+ "timeline-replacement",
112
+ "context-snapshot",
113
+ "branch-snapshot",
114
+ ].includes(coverage.reason),
115
+ );
116
+ const digest = createHash("sha256").update(
117
+ `[${JSON.stringify(start)},${JSON.stringify({ type: event.type, data: event.data })}`,
118
+ );
119
+ active = {
120
+ descriptor,
121
+ digest,
122
+ rows: 0,
123
+ contexts: 0,
124
+ pending: null,
125
+ textParts: [],
126
+ textBytes: 0,
127
+ textIdentity: null,
128
+ contextStarted: false,
129
+ };
130
+ return { kind: "start", coverage };
131
+ }
132
+ if (!active) {
133
+ if (
134
+ [BRANCH_HISTORY_MESSAGE, BRANCH_HISTORY_ORIGIN].includes(
135
+ event.type,
136
+ ) ||
137
+ (event.type === "session_branch_complete" &&
138
+ event.data?.schemaVersion === 2)
139
+ )
140
+ invalid();
141
+ return null;
142
+ }
143
+ const state = active;
144
+ if (event.type === "session_branch_complete") {
145
+ require(
146
+ !state.pending &&
147
+ state.textParts.length === 0 &&
148
+ state.rows === state.descriptor.totalMessages &&
149
+ state.contexts === state.descriptor.contextMessageCount &&
150
+ event.data?.schemaVersion === 2 &&
151
+ event.data.messageCount === state.contexts &&
152
+ event.data.inputDigest ===
153
+ `sha256:${state.digest.update("]").digest("hex")}`,
154
+ );
155
+ active = null;
156
+ return { kind: "complete" };
157
+ }
158
+ state.digest.update(
159
+ `,${JSON.stringify({ type: event.type, data: event.data })}`,
160
+ );
161
+ if (event.type === BRANCH_HISTORY_MESSAGE) {
162
+ const row = event.data;
163
+ require(
164
+ !state.contextStarted &&
165
+ state.rows < state.descriptor.totalMessages &&
166
+ ["user", "assistant", "tool"].includes(row?.role) &&
167
+ typeof row.text === "string" &&
168
+ row.text.length <= 128 * 1024 &&
169
+ row.part === state.textParts.length &&
170
+ typeof row.last === "boolean" &&
171
+ hash(row.sourceEventId) &&
172
+ integer(row.sourceItemIndex),
173
+ );
174
+ const identity = `${row.role}:${row.sourceEventId}:${row.sourceItemIndex}`;
175
+ require(state.textIdentity === null || state.textIdentity === identity);
176
+ state.textIdentity = identity;
177
+ state.textBytes += Buffer.byteLength(row.text);
178
+ require(
179
+ state.textBytes <= 16 * 1024 * 1024 && state.textParts.length < 256,
180
+ );
181
+ state.textParts.push(row.text);
182
+ if (!row.last) return { kind: "archive-part" };
183
+ const message = { role: row.role, content: state.textParts.join("") };
184
+ state.textParts = [];
185
+ state.textBytes = 0;
186
+ state.textIdentity = null;
187
+ state.rows += 1;
188
+ return { kind: "archive", message };
189
+ }
190
+ if (
191
+ ["user_message", "assistant_message", "system"].includes(event.type)
192
+ ) {
193
+ require(
194
+ !state.pending &&
195
+ state.textParts.length === 0 &&
196
+ state.rows === state.descriptor.totalMessages &&
197
+ state.contexts < state.descriptor.contextMessageCount &&
198
+ event.data?.role ===
199
+ {
200
+ user_message: "user",
201
+ assistant_message: "assistant",
202
+ system: "system",
203
+ }[event.type],
204
+ );
205
+ state.contextStarted = true;
206
+ state.pending = event.data;
207
+ return { kind: "context" };
208
+ }
209
+ if (event.type === BRANCH_HISTORY_ORIGIN) {
210
+ const message = state.pending;
211
+ const origin = event.data?.origin;
212
+ require(
213
+ message && event.data.messageDigest === branchMessageDigest(message),
214
+ );
215
+ require(
216
+ origin === null
217
+ ? message.role === "system"
218
+ : origin &&
219
+ integer(origin.first) &&
220
+ integer(origin.last) &&
221
+ origin.first <= origin.last &&
222
+ origin.last < state.rows &&
223
+ (message.role !== "system" ||
224
+ (state.descriptor.schema ===
225
+ BRANCH_HISTORY_SYSTEM_ORIGINS_SCHEMA &&
226
+ getDurableSystemMessageProvenance(
227
+ decodeVerifiedPersistedMessage(message),
228
+ ))),
229
+ );
230
+ state.contexts += 1;
231
+ state.pending = null;
232
+ return { kind: "origin", message, origin };
233
+ }
234
+ invalid();
235
+ },
236
+ finish() {
237
+ if (active) invalid();
238
+ },
239
+ };
240
+ }