chainlesschain 0.166.76 → 0.166.78

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 +19 -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-CNaejClV.js → AIOps-DSyZEY2G.js} +1 -1
  12. package/src/assets/web-panel/assets/{ActionButton-CF_CVKT_.js → ActionButton-DhNyZ577.js} +1 -1
  13. package/src/assets/web-panel/assets/{Analytics-a3Z6J7gv.js → Analytics-HMMpxmyi.js} +3 -3
  14. package/src/assets/web-panel/assets/{AppLayout-BFtWEnct.js → AppLayout-CwKMM5Ie.js} +5 -5
  15. package/src/assets/web-panel/assets/{Artifacts-BQ8oeMvX.js → Artifacts-CNzDmph7.js} +1 -1
  16. package/src/assets/web-panel/assets/{Audit-NOo9bmgk.js → Audit-DxWpUW3V.js} +1 -1
  17. package/src/assets/web-panel/assets/{BackgroundAgents-QRc7F3Tp.js → BackgroundAgents-C1R2ST-P.js} +1 -1
  18. package/src/assets/web-panel/assets/{Backup-UlVgLn2P.js → Backup-B6biTaEV.js} +1 -1
  19. package/src/assets/web-panel/assets/{BaseInput-BER9LJAr.js → BaseInput-CVnkD2Z5.js} +1 -1
  20. package/src/assets/web-panel/assets/{Chat-Z8z2Fdfz.js → Chat-Dbewl4Je.js} +6 -6
  21. package/src/assets/web-panel/assets/{ChatBubbleRenderer-DdmuBrdQ.js → ChatBubbleRenderer-DVZ6SwC5.js} +1 -1
  22. package/src/assets/web-panel/assets/{Checkbox-CXPgyB8L.js → Checkbox-BqqiF1JE.js} +1 -1
  23. package/src/assets/web-panel/assets/{Codegen-D1vOsLJ7.js → Codegen-BVMkGumc.js} +1 -1
  24. package/src/assets/web-panel/assets/{Col-ucLnUJC7.js → Col-DmiRHy96.js} +1 -1
  25. package/src/assets/web-panel/assets/{Community-COsV9n9t.js → Community-BDlpygqA.js} +1 -1
  26. package/src/assets/web-panel/assets/{Compact-D0EkBEYh.js → Compact-B2NME_m-.js} +1 -1
  27. package/src/assets/web-panel/assets/{Compliance-C8w9SUjt.js → Compliance-BlzDLE-R.js} +1 -1
  28. package/src/assets/web-panel/assets/{Cowork-CmVaKEJS.js → Cowork-C8raPybB.js} +3 -3
  29. package/src/assets/web-panel/assets/{Cron-B_FiMMV2.js → Cron-DA8Py0zP.js} +2 -2
  30. package/src/assets/web-panel/assets/{Crosschain-ByO3YL8N.js → Crosschain-DU2XyHqB.js} +1 -1
  31. package/src/assets/web-panel/assets/{DID-DwpsLM9r.js → DID-Df098fT_.js} +2 -2
  32. package/src/assets/web-panel/assets/{Dashboard-B_8IUvM_.js → Dashboard-D1rT702x.js} +2 -2
  33. package/src/assets/web-panel/assets/{Dropdown-Bo6WQkuX.js → Dropdown-BweXGo1O.js} +1 -1
  34. package/src/assets/web-panel/assets/{EmailListRenderer-C9LiQesx.js → EmailListRenderer-B9ShbgJH.js} +1 -1
  35. package/src/assets/web-panel/assets/EvolutionSettings-D75_iBoc.js +1 -0
  36. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Dst6VUnO.js → FamilyGuardDashboard-DrznZFVs.js} +1 -1
  37. package/src/assets/web-panel/assets/{Federation-Ci7CoLkJ.js → Federation-DQZ2adIA.js} +1 -1
  38. package/src/assets/web-panel/assets/{FormItemContext-bdDyUhUM.js → FormItemContext-DN30Dowh.js} +1 -1
  39. package/src/assets/web-panel/assets/{GenericCardRenderer-CrRwOUVi.js → GenericCardRenderer-DRdt0j1e.js} +1 -1
  40. package/src/assets/web-panel/assets/{Git-Dis8h-Z-.js → Git-wwRgStzk.js} +2 -2
  41. package/src/assets/web-panel/assets/{Governance-DX7OH5w2.js → Governance-CI4Uw0Nh.js} +1 -1
  42. package/src/assets/web-panel/assets/{Inference-Cavv_Q_Z.js → Inference-5TuE2AJI.js} +1 -1
  43. package/src/assets/web-panel/assets/{KnowledgeGraph-Cck8tnZn.js → KnowledgeGraph-oXyvmFSR.js} +1 -1
  44. package/src/assets/web-panel/assets/{Logs-BQt3aGMu.js → Logs-ewudSWuv.js} +2 -2
  45. package/src/assets/web-panel/assets/MarkdownRenderer-Cz5nyufm.js +1 -0
  46. package/src/assets/web-panel/assets/{Marketplace-CdmAKNSN.js → Marketplace-DcZeWFrs.js} +1 -1
  47. package/src/assets/web-panel/assets/{McpTools-BUlJdyPY.js → McpTools-BcV9p1RS.js} +3 -3
  48. package/src/assets/web-panel/assets/{Memory-DQRTQDr-.js → Memory-CMhYvugt.js} +2 -2
  49. package/src/assets/web-panel/assets/{MobileBridge-C0dnxgsl.js → MobileBridge-5RP2uwvT.js} +1 -1
  50. package/src/assets/web-panel/assets/{MobileProjects-DQ5Gy7fa.js → MobileProjects-BIuM9Ze4.js} +1 -1
  51. package/src/assets/web-panel/assets/{Mtc-Xl7u2isS.js → Mtc-DmBszTDe.js} +5 -5
  52. package/src/assets/web-panel/assets/{MtcAudit-C3KX0574.js → MtcAudit-Czdp5ZGt.js} +2 -2
  53. package/src/assets/web-panel/assets/{Multisig-CHEhfkn8.js → Multisig-DRWUuNr-.js} +3 -3
  54. package/src/assets/web-panel/assets/{NLProgramming-Ce38mH-8.js → NLProgramming-IRQQN0-c.js} +1 -1
  55. package/src/assets/web-panel/assets/{Notes-C7nuTd7c.js → Notes-CGhD1lW9.js} +4 -4
  56. package/src/assets/web-panel/assets/{NotificationSettings-BcoEcyq8.js → NotificationSettings-BtyPgQAh.js} +1 -1
  57. package/src/assets/web-panel/assets/{OrderTableRenderer-D-t5hKkx.js → OrderTableRenderer-yUaqwCty.js} +1 -1
  58. package/src/assets/web-panel/assets/{Organization-C_BGi4xi.js → Organization-C3kTVn5i.js} +4 -4
  59. package/src/assets/web-panel/assets/{Overflow-BodhraDq.js → Overflow-C2-0iZhq.js} +1 -1
  60. package/src/assets/web-panel/assets/{P2P-BTa3sAIy.js → P2P-CISoEUxA.js} +2 -2
  61. package/src/assets/web-panel/assets/{PdhVaultBrowser-BjZslP9T.js → PdhVaultBrowser-NfTVtvKQ.js} +5 -5
  62. package/src/assets/web-panel/assets/{Permissions-u3UDzGef.js → Permissions-CfK0jJhm.js} +3 -3
  63. package/src/assets/web-panel/assets/{PersonalDataHub-Cb7ybv65.js → PersonalDataHub-OsVxxh_j.js} +4 -4
  64. package/src/assets/web-panel/assets/{Pipeline-CS24k-P7.js → Pipeline-DEmK_Ch2.js} +1 -1
  65. package/src/assets/web-panel/assets/{Privacy-Ddj6Kqs7.js → Privacy-D61s73b0.js} +1 -1
  66. package/src/assets/web-panel/assets/{ProjectInit-Bg5uQIgg.js → ProjectInit-DkLF5gHb.js} +2 -2
  67. package/src/assets/web-panel/assets/{ProjectSettings-AmPR8T12.js → ProjectSettings-BA7odTrI.js} +2 -2
  68. package/src/assets/web-panel/assets/{Projects-DGSbAyTK.js → Projects-CdI1GcAG.js} +1 -1
  69. package/src/assets/web-panel/assets/{Providers-Dc1C3lbB.js → Providers-D9BYyP1r.js} +1 -1
  70. package/src/assets/web-panel/assets/{QrScannerModal-Cv3HXpce.js → QrScannerModal-CXMItUDD.js} +1 -1
  71. package/src/assets/web-panel/assets/{QuickAsk-3dpbXARb.js → QuickAsk-8-tF9ffZ.js} +1 -1
  72. package/src/assets/web-panel/assets/{Recommend-5aGRVnJK.js → Recommend-C2QGWOSi.js} +1 -1
  73. package/src/assets/web-panel/assets/{RemoteSession-CTS2jx0p.js → RemoteSession-B1M_v1lx.js} +2 -2
  74. package/src/assets/web-panel/assets/{Reputation-BxaKI0hY.js → Reputation-D0WZHgv1.js} +1 -1
  75. package/src/assets/web-panel/assets/{Row-C23uQdwd.js → Row-D6nf9-c-.js} +1 -1
  76. package/src/assets/web-panel/assets/{RssFeed-ssX9YOhm.js → RssFeed-ClZ6M-mN.js} +3 -3
  77. package/src/assets/web-panel/assets/{Search-C24GogII.js → Search-ZWkt8vuO.js} +1 -1
  78. package/src/assets/web-panel/assets/{Security-DdAcGKkk.js → Security-BUlQut2m.js} +3 -3
  79. package/src/assets/web-panel/assets/{Services-D0dCiEuq.js → Services-Cd_3xJOc.js} +2 -2
  80. package/src/assets/web-panel/assets/{Skeleton-DEY44o0v.js → Skeleton-C8e2-cHW.js} +1 -1
  81. package/src/assets/web-panel/assets/Skills-DucVRJp1.js +1 -0
  82. package/src/assets/web-panel/assets/{Sla-B_bbo2vB.js → Sla-Csr5pUwI.js} +1 -1
  83. package/src/assets/web-panel/assets/SpeechSettings-CXvyaRAT.js +1 -0
  84. package/src/assets/web-panel/assets/{SyncSettings-CpIXql0Z.js → SyncSettings-KdsIcV5h.js} +2 -2
  85. package/src/assets/web-panel/assets/Tasks-B-eHmJm9.js +1 -0
  86. package/src/assets/web-panel/assets/{Templates-C_44nVPq.js → Templates-BglVeaLK.js} +1 -1
  87. package/src/assets/web-panel/assets/{Tenant-CyZ2ey2P.js → Tenant-BBbQ8qan.js} +1 -1
  88. package/src/assets/web-panel/assets/{Terminal-DwGNHWnp.js → Terminal-Ca_pCVBi.js} +2 -2
  89. package/src/assets/web-panel/assets/{TimelineRenderer-BTAHNkqU.js → TimelineRenderer-YD6XG_vZ.js} +1 -1
  90. package/src/assets/web-panel/assets/{Tokens-DCJWkUwc.js → Tokens-2lRoeVli.js} +1 -1
  91. package/src/assets/web-panel/assets/{Trigger-BCjDO9-E.js → Trigger-C-3XNAU9.js} +1 -1
  92. package/src/assets/web-panel/assets/{Trust-_YS8WbRb.js → Trust-k-1PxdLG.js} +1 -1
  93. package/src/assets/web-panel/assets/{UkeySign-m6R8xGq7.js → UkeySign-FG-qW646.js} +1 -1
  94. package/src/assets/web-panel/assets/{VideoEditing-xOfk29c4.js → VideoEditing-BNOe1cmd.js} +1 -1
  95. package/src/assets/web-panel/assets/{Wallet-B1Gw0awc.js → Wallet-D5C3i2Kw.js} +4 -4
  96. package/src/assets/web-panel/assets/{WebAuthn-CHK5ft18.js → WebAuthn-BOpztqd3.js} +4 -4
  97. package/src/assets/web-panel/assets/{WorkflowEditor-DEp1ukQQ.js → WorkflowEditor-BpVrpUEv.js} +1 -1
  98. package/src/assets/web-panel/assets/{chat-B2sFizun.js → chat-DIuMHb38.js} +1 -1
  99. package/src/assets/web-panel/assets/{colors-DJ17YV1E.js → colors-CTFJPyzQ.js} +1 -1
  100. package/src/assets/web-panel/assets/{compact-item-CBhJJgEC.js → compact-item-CONfmJcW.js} +1 -1
  101. package/src/assets/web-panel/assets/{createContext-BZkpvNJy.js → createContext-RkW5CRrz.js} +1 -1
  102. package/src/assets/web-panel/assets/devWarning-DaEBln_q.js +1 -0
  103. package/src/assets/web-panel/assets/{hasIn-C0ZKo6Ei.js → hasIn-CW4XOjDC.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Bc3vVG2X.js → index-7wMSBCU7.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-vFMwiAN4.js → index-Akmg1WdH.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DOBXNMdh.js → index-B54qoVff.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DLo8Ls9u.js → index-B8r2t0Ch.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-C7gv9dvb.js → index-B9XoBoty.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DHtpMr1G.js → index-B9aS2VLu.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Dxe0YlZe.js → index-BFs1Tznc.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DumLgj1t.js → index-BKgaRT0b.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BNp6HKFh.js → index-BM7bOUvu.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DM0rWF6z.js → index-BMg2JFmW.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-4oULtRqE.js → index-BRZsPxNn.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-LPPe0val.js → index-Bf19fKef.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Ctguam0K.js → index-BkAbfBF-.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DrU5xVpF.js → index-CBjb2A5R.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CCOr6Q27.js → index-CEZWQthY.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-C9gYiACH.js → index-CFGLf88d.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CZW84cEf.js → index-CLUa68JH.js} +3 -3
  121. package/src/assets/web-panel/assets/{index-BoDUYyuo.js → index-CM2X25Er.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DyiCbHeL.js → index-CX4T2uKN.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CW5o1Gar.js → index-CixqfdRk.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-5K2z_tgO.js → index-CkRojEip.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BOfPp5OV.js → index-Cvmc3f25.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CdxJm-HB.js → index-D-lpTPS8.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-8ueG48gl.js → index-D59GbWCN.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BMxOoITz.js → index-DAESljiJ.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DLMr5KMd.js → index-DDHUx4Yz.js} +1 -1
  130. package/src/assets/web-panel/assets/index-DG1mcYTa.js +1 -0
  131. package/src/assets/web-panel/assets/{index-BGIvhCPl.js → index-DP5pPedy.js} +1 -1
  132. package/src/assets/web-panel/assets/index-DRs5Pe8u.js +1 -0
  133. package/src/assets/web-panel/assets/{index-DjdSFO0d.js → index-DSlXL6Ju.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-Cn5UzvgR.js → index-DWCJnn2O.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-Chct9tL8.js → index-DWY7YwDu.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-BEnd5fiz.js → index-DZTwP364.js} +1 -1
  137. package/src/assets/web-panel/assets/{index-KzNhWykP.js → index-DidrMvOx.js} +1 -1
  138. package/src/assets/web-panel/assets/{index-BpyrhOeh.js → index-Dj3K5kHs.js} +1 -1
  139. package/src/assets/web-panel/assets/{index-CZlkPrxb.js → index-YaeGscSw.js} +1 -1
  140. package/src/assets/web-panel/assets/{index-Dfgxe-fw.js → index-YlMnFNOi.js} +1 -1
  141. package/src/assets/web-panel/assets/{index-IHgzfc1u.js → index-asWsB34i.js} +1 -1
  142. package/src/assets/web-panel/assets/{index-DJkoJzTU.js → index-gkjiFjQd.js} +1 -1
  143. package/src/assets/web-panel/assets/{initDefaultProps-Cqfoq0TJ.js → initDefaultProps-BOr4igh3.js} +1 -1
  144. package/src/assets/web-panel/assets/{motion-CIiVJHNu.js → motion-CK469n2j.js} +1 -1
  145. package/src/assets/web-panel/assets/{move-CFl1o_A8.js → move-DzjudlYQ.js} +1 -1
  146. package/src/assets/web-panel/assets/{mtc-parser-DYoCxcZ1.js → mtc-parser-BQaKUxC6.js} +1 -1
  147. package/src/assets/web-panel/assets/{omit-C1P2q5TY.js → omit-MciovCFD.js} +1 -1
  148. package/src/assets/web-panel/assets/{pickAttrs-BtTRpJtC.js → pickAttrs-DDPJ4zAz.js} +1 -1
  149. package/src/assets/web-panel/assets/{placementArrow-Cst2PcNM.js → placementArrow-Cznyb-jI.js} +1 -1
  150. package/src/assets/web-panel/assets/{responsiveObserve-CF5kalV2.js → responsiveObserve-AJK3SLzJ.js} +1 -1
  151. package/src/assets/web-panel/assets/{slide-CtHGqpXN.js → slide-CPQ28wu7.js} +1 -1
  152. package/src/assets/web-panel/assets/{statusUtils-N__biHXf.js → statusUtils-CFjzvqf_.js} +1 -1
  153. package/src/assets/web-panel/assets/{styleChecker-DR8V_H-i.js → styleChecker-BPyFfTuR.js} +1 -1
  154. package/src/assets/web-panel/assets/{useFlexGapSupport-D274dqun.js → useFlexGapSupport-Dq7N6R05.js} +1 -1
  155. package/src/assets/web-panel/assets/{useFs-BwHLYU5b.js → useFs-C3GS0uTc.js} +1 -1
  156. package/src/assets/web-panel/assets/{usePersonalDataHub-BiA-hVqt.js → usePersonalDataHub-BhgIVzP_.js} +1 -1
  157. package/src/assets/web-panel/assets/{vnode-Bugl94dy.js → vnode-4ZD9-MDr.js} +1 -1
  158. package/src/assets/web-panel/assets/{zoom-DEFl8GCu.js → zoom-Bx4MRVNW.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/app-server/server.js +14 -0
  174. package/src/lib/background-agent-supervisor.js +14 -4
  175. package/src/lib/causal-observability.js +64 -1
  176. package/src/lib/checkpoint-summary-projection.js +98 -0
  177. package/src/lib/checkpoint-timeline-authority.js +15 -51
  178. package/src/lib/claude-code-bridge.js +302 -60
  179. package/src/lib/codex-app-server-adapter.js +161 -35
  180. package/src/lib/cost-budget.js +4 -0
  181. package/src/lib/decision-layer/providers.js +84 -9
  182. package/src/lib/decision-layer/runtime.js +86 -49
  183. package/src/lib/direct-model-usage.js +14 -3
  184. package/src/lib/doctor-checkup.js +31 -2
  185. package/src/lib/durable-security-store.js +6 -1
  186. package/src/lib/evolution/evolution-artifact-identity.js +21 -0
  187. package/src/lib/evolution/evolution-artifact-ports.js +5 -11
  188. package/src/lib/evolution/evolution-eval-cohort-receipt-reconciliation.js +389 -0
  189. package/src/lib/execution-location-failure-site.js +63 -0
  190. package/src/lib/execution-location-target.js +102 -8
  191. package/src/lib/external-agent-adapters.js +2 -0
  192. package/src/lib/image-file-boundary.js +154 -0
  193. package/src/lib/image-input.js +16 -3
  194. package/src/lib/llm-pricing.js +114 -8
  195. package/src/lib/mcp-call-ledger-store.js +7 -2
  196. package/src/lib/model-capabilities.js +21 -10
  197. package/src/lib/model-context-catalog.js +60 -1
  198. package/src/lib/openai-responses.js +7 -1
  199. package/src/lib/orchestrator.js +8 -2
  200. package/src/lib/process-execution-broker/index.js +93 -1
  201. package/src/lib/process-execution-broker/linux-subreaper-artifact.js +120 -0
  202. package/src/lib/process-execution-broker/linux-subreaper-helper.js +344 -0
  203. package/src/lib/process-execution-broker/linux-subreaper-process.js +326 -0
  204. package/src/lib/process-execution-broker/linux-subreaper-supervisor.c +360 -0
  205. package/src/lib/process-execution-broker/owned-posix-process-group-worker.mjs +131 -0
  206. package/src/lib/process-execution-broker/owned-posix-process-group.js +267 -0
  207. package/src/lib/process-execution-broker/process-ownership-journal.js +297 -0
  208. package/src/lib/process-execution-broker/process-ownership-quarantine.js +91 -0
  209. package/src/lib/runtime-usage-ledger.js +3 -0
  210. package/src/lib/secure-fs.js +158 -42
  211. package/src/lib/session-branch-history.js +240 -0
  212. package/src/lib/session-history-origins.js +285 -0
  213. package/src/lib/session-input-receipt.js +110 -0
  214. package/src/lib/session-resource-budget.js +8 -8
  215. package/src/lib/session-transcript-history.js +456 -0
  216. package/src/lib/session-transcript-page.js +164 -0
  217. package/src/lib/session-transcript-reference.js +38 -0
  218. package/src/lib/session-usage.js +8 -0
  219. package/src/lib/token-tracker.js +32 -54
  220. package/src/lib/usage-pricing-context.js +93 -0
  221. package/src/runtime/headless-runner.js +8 -0
  222. package/src/runtime/headless-stream.js +202 -4
  223. package/src/assets/web-panel/assets/EvolutionSettings-Pc1IpRfk.js +0 -1
  224. package/src/assets/web-panel/assets/MarkdownRenderer-BIUeeiVA.js +0 -1
  225. package/src/assets/web-panel/assets/Skills-CYt0Mu2W.js +0 -1
  226. package/src/assets/web-panel/assets/SpeechSettings-a2BBjtTL.js +0 -1
  227. package/src/assets/web-panel/assets/Tasks-BYQKU-GL.js +0 -1
  228. package/src/assets/web-panel/assets/devWarning-DZhu13vj.js +0 -1
  229. package/src/assets/web-panel/assets/index-C6iFyQYz.js +0 -1
  230. package/src/assets/web-panel/assets/index-CztThH9f.js +0 -1
@@ -17,6 +17,11 @@ import { EventEmitter } from "events";
17
17
  import crypto from "crypto";
18
18
  import runtimeClaimsContract from "@chainlesschain/session-core/runtime-claims";
19
19
  import executionBroker from "./process-execution-broker/index.js";
20
+ import { PROCESS_OWNERSHIP_UNCONFIRMED } from "./process-execution-broker/process-ownership-quarantine.js";
21
+ import {
22
+ PROCESS_OWNERSHIP_PENDING,
23
+ PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE,
24
+ } from "./process-execution-broker/process-ownership-journal.js";
20
25
  import {
21
26
  createExternalAgentAdapter,
22
27
  EXTERNAL_AGENT_ERROR,
@@ -68,6 +73,7 @@ export const AGENT_STATUS = {
68
73
  FAILED: "failed",
69
74
  TIMEOUT: "timeout",
70
75
  CANCELLED: "cancelled",
76
+ QUARANTINED: "quarantined",
71
77
  };
72
78
 
73
79
  // Bound how much of a child's stdout/stderr we retain in memory. A verbose or
@@ -157,8 +163,20 @@ export class ClaudeCodeAgent extends EventEmitter {
157
163
  * @param {string} options.context - Extra context prepended to task
158
164
  * @param {string} options.allowedTools - Comma-separated tool allow-list
159
165
  * @returns {Promise<{success, output, exitCode, duration, taskId}>}
166
+ * A quarantined failure report does not release process ownership. It emits
167
+ * task:quarantined instead of task:complete and the agent cannot be reused.
160
168
  */
161
169
  async executeTask(taskDescription, options = {}) {
170
+ if (this.status === AGENT_STATUS.QUARANTINED) {
171
+ const error = new Error(
172
+ "External agent still owns an unconfirmed process tree",
173
+ );
174
+ error.code = EXTERNAL_AGENT_ERROR.CLEANUP_UNCONFIRMED;
175
+ throw error;
176
+ }
177
+ if (this.status === AGENT_STATUS.RUNNING) {
178
+ throw new Error("External agent already has a running task");
179
+ }
162
180
  const {
163
181
  cwd = process.cwd(),
164
182
  timeout = 300_000,
@@ -174,7 +192,29 @@ export class ClaudeCodeAgent extends EventEmitter {
174
192
 
175
193
  this.status = AGENT_STATUS.RUNNING;
176
194
  this.currentTask = taskDescription;
195
+ this._cancelRequested = false;
177
196
  this.emit("task:start", { agentId: this.id, task: taskDescription });
197
+ if (this._cancelRequested) {
198
+ this.status = AGENT_STATUS.CANCELLED;
199
+ this.currentTask = null;
200
+ const result = {
201
+ success: false,
202
+ status: AGENT_STATUS.CANCELLED,
203
+ output: "",
204
+ exitCode: -1,
205
+ duration: 0,
206
+ timedOut: false,
207
+ cancelled: true,
208
+ agentId: this.id,
209
+ error: "External agent was cancelled before spawn",
210
+ errorCode: EXTERNAL_AGENT_ERROR.CANCELLED,
211
+ protocol: this.adapter.capabilities().protocol,
212
+ runtimeClaims: VALIDATION_ONLY_CLAIMS,
213
+ terminalEvidence: [],
214
+ };
215
+ this.emit("task:complete", result);
216
+ return result;
217
+ }
178
218
 
179
219
  let args;
180
220
  try {
@@ -201,8 +241,6 @@ export class ClaudeCodeAgent extends EventEmitter {
201
241
  return result;
202
242
  }
203
243
 
204
- this._cancelRequested = false;
205
-
206
244
  return new Promise((resolve) => {
207
245
  const startTime = Date.now();
208
246
  const outputChunks = [];
@@ -213,6 +251,114 @@ export class ClaudeCodeAgent extends EventEmitter {
213
251
  const outDecoder = new TextDecoder("utf-8");
214
252
  const errDecoder = new TextDecoder("utf-8");
215
253
  let timedOut = false;
254
+ let finalized = false;
255
+ let stopping = false;
256
+ let proc = null;
257
+ let timer = null;
258
+ let killTimer = null;
259
+ let processError = null;
260
+ let spawnFailure = null;
261
+ let brokerCloseFence = null;
262
+ const finalize = (result) => {
263
+ if (finalized) return;
264
+ finalized = true;
265
+ clearTimeout(timer);
266
+ clearTimeout(killTimer);
267
+ this._proc = null;
268
+ this._stop = null;
269
+ this.currentTask = null;
270
+ this.emit("task:complete", result);
271
+ resolve(result);
272
+ };
273
+ const failSpawn = (err) => {
274
+ if (finalized) return;
275
+ const admissionBlocked = [
276
+ PROCESS_OWNERSHIP_UNCONFIRMED,
277
+ PROCESS_OWNERSHIP_PENDING,
278
+ PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE,
279
+ ].includes(err.code);
280
+ this.status = AGENT_STATUS.FAILED;
281
+ finalize({
282
+ success: false,
283
+ status: admissionBlocked ? "not-started" : "failed",
284
+ output: "",
285
+ exitCode: -1,
286
+ duration: Date.now() - startTime,
287
+ timedOut,
288
+ cancelled: this._cancelRequested && !timedOut,
289
+ agentId: this.id,
290
+ error: err.message,
291
+ errorCode: admissionBlocked
292
+ ? err.code
293
+ : EXTERNAL_AGENT_ERROR.SPAWN_FAILED,
294
+ protocol: this.adapter.capabilities().protocol,
295
+ runtimeClaims: admissionBlocked
296
+ ? VALIDATION_ONLY_CLAIMS
297
+ : REAL_EXECUTION_CLAIMS,
298
+ terminalEvidence: [],
299
+ ...(admissionBlocked
300
+ ? { executionStarted: false, recoveryRequired: true }
301
+ : {}),
302
+ });
303
+ };
304
+ const quarantine = (receipt) => {
305
+ if (finalized || receipt?.cleanup?.confirmed !== false) return;
306
+ // Return a failure report without declaring task completion or releasing
307
+ // the process handle, task identity or pool slot. No synthetic close.
308
+ finalized = true;
309
+ clearTimeout(timer);
310
+ clearTimeout(killTimer);
311
+ this._stop = null;
312
+ this.status = AGENT_STATUS.QUARANTINED;
313
+ const rawOutput = outputChunks.join("");
314
+ const result = {
315
+ success: false,
316
+ status: AGENT_STATUS.QUARANTINED,
317
+ output: rawOutput.slice(-4000),
318
+ rawOutput,
319
+ outputTruncated,
320
+ stderr: errorChunks.join("").slice(-2000),
321
+ exitCode: null,
322
+ duration: Date.now() - startTime,
323
+ timedOut,
324
+ cancelled: this._cancelRequested && !timedOut,
325
+ agentId: this.id,
326
+ error:
327
+ "External agent process-tree cleanup is unconfirmed; recovery is required",
328
+ errorCode: EXTERNAL_AGENT_ERROR.CLEANUP_UNCONFIRMED,
329
+ protocol: this.adapter.capabilities().protocol,
330
+ runtimeClaims: REAL_EXECUTION_CLAIMS,
331
+ terminalEvidence: [],
332
+ processOwnershipReleased: false,
333
+ recoveryRequired: true,
334
+ cleanup: { ...receipt.cleanup },
335
+ };
336
+ resolve(result);
337
+ this.emit("task:quarantined", result);
338
+ };
339
+ const stop = () => {
340
+ if (finalized || stopping) return;
341
+ stopping = true;
342
+ clearTimeout(timer);
343
+ // Schedule before TERM: a child can close synchronously in adapters.
344
+ // Use the broker's child handle (including its sandbox supervisor),
345
+ // never a delayed numeric PID which may have been reused.
346
+ killTimer = setTimeout(() => {
347
+ if (!finalized) {
348
+ try {
349
+ proc.kill("SIGKILL");
350
+ } catch (err) {
351
+ processError = err;
352
+ }
353
+ }
354
+ }, killGraceMs);
355
+ killTimer.unref?.();
356
+ try {
357
+ proc.kill("SIGTERM");
358
+ } catch (err) {
359
+ processError = err;
360
+ }
361
+ };
216
362
  // Tail-bounded byte counters for the two buffers (see MAX_AGENT_OUTPUT_BYTES).
217
363
  let outBytes = 0;
218
364
  let errBytes = 0;
@@ -227,33 +373,49 @@ export class ClaudeCodeAgent extends EventEmitter {
227
373
  return bytes;
228
374
  };
229
375
 
230
- const proc = _deps.spawn(this.adapter.command, args, {
231
- cwd,
232
- env: { ...process.env },
233
- windowsHide: true,
234
- origin: "claude-code-bridge:agent",
235
- policy: "allow",
236
- scope: "orchestrator",
237
- shell: false,
238
- });
376
+ try {
377
+ proc = _deps.spawn(this.adapter.command, args, {
378
+ cwd,
379
+ env: { ...process.env },
380
+ windowsHide: true,
381
+ origin: "claude-code-bridge:agent",
382
+ policy: "allow",
383
+ scope: "orchestrator",
384
+ shell: false,
385
+ ...(process.platform === "linux"
386
+ ? { linuxSubreaper: { graceMs: killGraceMs } }
387
+ : {}),
388
+ });
389
+ } catch (err) {
390
+ // Broker admission/bookkeeping can fail after native spawn. Its
391
+ // attached child remains ours until close; a kill request is not exit
392
+ // evidence and must not release this agent for another task.
393
+ if (!err?.spawnedProcess) {
394
+ failSpawn(err);
395
+ return;
396
+ }
397
+ proc = err.spawnedProcess;
398
+ processError = err;
399
+ spawnFailure = err;
400
+ brokerCloseFence = err.workspaceProcessClosed;
401
+ }
239
402
  this._proc = proc;
403
+ this._stop = stop;
240
404
 
241
405
  // SIGKILL-escalation timer is hoisted so the close/error handlers can
242
406
  // clear it — otherwise, when the process dies promptly from SIGTERM, this
243
407
  // inner timer still fires a redundant SIGKILL on a dead pid AND holds the
244
408
  // event loop open for the full grace period. unref() is a second guard so
245
409
  // it never keeps the process alive on its own.
246
- let killTimer = null;
247
- const timer = setTimeout(() => {
248
- timedOut = true;
249
- proc.kill("SIGTERM");
250
- killTimer = setTimeout(() => proc.kill("SIGKILL"), killGraceMs);
251
- if (killTimer && typeof killTimer.unref === "function") {
252
- killTimer.unref();
253
- }
254
- }, timeout);
410
+ if (!spawnFailure) {
411
+ timer = setTimeout(() => {
412
+ timedOut = true;
413
+ stop();
414
+ }, timeout);
415
+ }
255
416
 
256
417
  proc.stdout.on("data", (data) => {
418
+ if (finalized) return;
257
419
  const chunk =
258
420
  typeof data === "string"
259
421
  ? data
@@ -270,6 +432,7 @@ export class ClaudeCodeAgent extends EventEmitter {
270
432
  });
271
433
 
272
434
  proc.stderr.on("data", (data) => {
435
+ if (finalized) return;
273
436
  const chunk =
274
437
  typeof data === "string"
275
438
  ? data
@@ -281,19 +444,24 @@ export class ClaudeCodeAgent extends EventEmitter {
281
444
  }
282
445
  });
283
446
 
284
- proc.on("close", (code) => {
285
- clearTimeout(timer);
286
- if (killTimer) clearTimeout(killTimer);
287
- this._proc = null;
447
+ const completeClosed = (code) => {
448
+ if (finalized) return;
288
449
  const duration = Date.now() - startTime;
289
450
  const rawOutput = outputChunks.join("");
290
451
  const cancelled = this._cancelRequested && !timedOut;
291
- const projection = this.adapter.parseTranscript(rawOutput);
452
+ let projection;
453
+ try {
454
+ projection = this.adapter.parseTranscript(rawOutput);
455
+ } catch (err) {
456
+ projection = { terminal: "failed", error: err.message };
457
+ }
292
458
  const missingTerminal =
293
459
  this.adapter.capabilities().requiresTerminalEvent &&
294
460
  projection.terminal === null;
295
461
  const protocolFailed =
296
- projection.terminal === "failed" || missingTerminal;
462
+ projection.terminal === "failed" ||
463
+ missingTerminal ||
464
+ Boolean(processError);
297
465
  const status = timedOut
298
466
  ? AGENT_STATUS.TIMEOUT
299
467
  : cancelled
@@ -336,11 +504,15 @@ export class ClaudeCodeAgent extends EventEmitter {
336
504
  ? EXTERNAL_AGENT_ERROR.TIMEOUT
337
505
  : cancelled
338
506
  ? EXTERNAL_AGENT_ERROR.CANCELLED
339
- : code !== 0
340
- ? EXTERNAL_AGENT_ERROR.EXIT_NONZERO
341
- : protocolFailed
342
- ? EXTERNAL_AGENT_ERROR.PROTOCOL_FAILED
343
- : null;
507
+ : spawnFailure
508
+ ? EXTERNAL_AGENT_ERROR.SPAWN_FAILED
509
+ : processError?.code === PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE
510
+ ? PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE
511
+ : code !== 0
512
+ ? EXTERNAL_AGENT_ERROR.EXIT_NONZERO
513
+ : protocolFailed
514
+ ? EXTERNAL_AGENT_ERROR.PROTOCOL_FAILED
515
+ : null;
344
516
 
345
517
  const result = {
346
518
  success,
@@ -356,7 +528,8 @@ export class ClaudeCodeAgent extends EventEmitter {
356
528
  stderr: errorChunks.join("").slice(-2000),
357
529
  error: success
358
530
  ? undefined
359
- : projection.error ||
531
+ : processError?.message ||
532
+ projection.error ||
360
533
  (missingTerminal
361
534
  ? "External agent JSONL stream ended without a terminal event"
362
535
  : null) ||
@@ -374,44 +547,72 @@ export class ClaudeCodeAgent extends EventEmitter {
374
547
  malformedLineCount: projection.malformedLineCount,
375
548
  runtimeClaims: REAL_EXECUTION_CLAIMS,
376
549
  terminalEvidence,
550
+ ...(processError?.code === PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE
551
+ ? { recoveryRequired: true }
552
+ : {}),
377
553
  };
378
554
 
379
- this.emit("task:complete", result);
380
- resolve(result);
381
- });
555
+ finalize(result);
556
+ };
557
+ proc.on("close", completeClosed);
382
558
 
383
559
  proc.on("error", (err) => {
384
- clearTimeout(timer);
385
- if (killTimer) clearTimeout(killTimer);
386
- this._proc = null;
387
- this.status = AGENT_STATUS.FAILED;
388
- this.currentTask = null;
389
- const result = {
390
- success: false,
391
- status: "failed",
392
- output: "",
393
- exitCode: -1,
394
- duration: Date.now() - startTime,
395
- timedOut: false,
396
- cancelled: false,
397
- agentId: this.id,
398
- error: err.message,
399
- errorCode: EXTERNAL_AGENT_ERROR.SPAWN_FAILED,
400
- protocol: this.adapter.capabilities().protocol,
401
- runtimeClaims: REAL_EXECUTION_CLAIMS,
402
- terminalEvidence: [],
403
- };
404
- this.emit("task:complete", result);
405
- resolve(result);
560
+ if (finalized) return;
561
+ if (err.code === PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE) {
562
+ // The actual child has run. A failed durable settlement must not be
563
+ // mislabeled as an admission denial or evidence that nothing started.
564
+ processError = err;
565
+ return;
566
+ }
567
+ if (err.code === EXTERNAL_AGENT_ERROR.CLEANUP_UNCONFIRMED) {
568
+ quarantine(proc.ownedProcessTreeEvidence);
569
+ if (finalized) return;
570
+ }
571
+ if (
572
+ err.code === EXTERNAL_AGENT_ERROR.SPAWN_FAILED &&
573
+ proc.ownedProcessTreeClosed
574
+ ) {
575
+ processError = err;
576
+ spawnFailure = err;
577
+ }
578
+ if (spawnFailure) {
579
+ // Keep the original admission failure and wait for the owned child;
580
+ // another signal/transport error is still not proof of its exit.
581
+ stop();
582
+ return;
583
+ }
584
+ // A post-spawn error (e.g. signal failure) is not proof of exit.
585
+ // Retain ownership and wait for close, escalating cancellation.
586
+ if (proc.pid && proc.exitCode == null && proc.signalCode == null) {
587
+ processError = err;
588
+ stop();
589
+ } else {
590
+ failSpawn(err);
591
+ }
406
592
  });
593
+ proc.on("cleanup:unconfirmed", quarantine);
594
+ if (spawnFailure) {
595
+ if (brokerCloseFence?.then) {
596
+ Promise.resolve(brokerCloseFence).then(
597
+ (receipt) => {
598
+ if (receipt?.observed === true) completeClosed(receipt.exitCode);
599
+ },
600
+ () => {
601
+ // A failed close observer proves nothing. Keep the actual
602
+ // ChildProcess close listener and termination deadline active.
603
+ },
604
+ );
605
+ }
606
+ stop();
607
+ }
407
608
  });
408
609
  }
409
610
 
410
611
  /** Abort the currently running task. */
411
612
  abort() {
412
- if (this._proc) {
613
+ if (this.status === AGENT_STATUS.RUNNING) {
413
614
  this._cancelRequested = true;
414
- this._proc.kill("SIGTERM");
615
+ this._stop?.();
415
616
  }
416
617
  }
417
618
 
@@ -422,6 +623,9 @@ export class ClaudeCodeAgent extends EventEmitter {
422
623
  cliCommand: this.cliCommand,
423
624
  protocol: this.adapter.capabilities().protocol,
424
625
  currentTask: this.currentTask,
626
+ ...(this.status === AGENT_STATUS.QUARANTINED
627
+ ? { processOwnershipReleased: false, recoveryRequired: true }
628
+ : {}),
425
629
  };
426
630
  }
427
631
  }
@@ -475,6 +679,10 @@ export class ClaudeCodePool extends EventEmitter {
475
679
 
476
680
  // Process in batches of maxParallel
477
681
  for (let i = 0; i < tasks.length; i += this.maxParallel) {
682
+ if (this._hasQuarantinedAgent()) {
683
+ results.push(...tasks.slice(i).map((task) => this._blockedTask(task)));
684
+ break;
685
+ }
478
686
  const batch = tasks.slice(i, i + this.maxParallel);
479
687
  this.emit("batch:start", {
480
688
  batchIndex: i / this.maxParallel,
@@ -496,8 +704,9 @@ export class ClaudeCodePool extends EventEmitter {
496
704
  }
497
705
 
498
706
  async _runTask(task, { cwd }) {
707
+ if (this._hasQuarantinedAgent()) return this._blockedTask(task);
499
708
  const agent = new ClaudeCodeAgent({
500
- id: `agent-${task.id}`,
709
+ id: `agent-${task.id}-${crypto.randomUUID()}`,
501
710
  cliCommand: this.cliCommand,
502
711
  model: this.model,
503
712
  sandbox: this.sandbox,
@@ -505,6 +714,12 @@ export class ClaudeCodePool extends EventEmitter {
505
714
 
506
715
  this._agents.set(agent.id, agent);
507
716
  agent.on("output", (ev) => this.emit("agent:output", ev));
717
+ agent.on("task:quarantined", (result) => {
718
+ // Stop already admitted siblings through their retained handles. Their
719
+ // own close fences still decide release; no new batch may start.
720
+ this.abortAll();
721
+ this.emit("agent:quarantined", { taskId: task.id, ...result });
722
+ });
508
723
 
509
724
  const result = await agent.executeTask(task.description, {
510
725
  cwd,
@@ -513,6 +728,9 @@ export class ClaudeCodePool extends EventEmitter {
513
728
  allowedTools: task.allowedTools || null,
514
729
  });
515
730
 
731
+ if (agent.status === AGENT_STATUS.QUARANTINED) {
732
+ return { taskId: task.id, ...result };
733
+ }
516
734
  this._agents.delete(agent.id);
517
735
  this._completed.push({ ...result, taskId: task.id });
518
736
  if (this._completed.length > this.maxCompleted) {
@@ -523,6 +741,30 @@ export class ClaudeCodePool extends EventEmitter {
523
741
  return { taskId: task.id, ...result };
524
742
  }
525
743
 
744
+ _hasQuarantinedAgent() {
745
+ return [...this._agents.values()].some(
746
+ (agent) => agent.status === AGENT_STATUS.QUARANTINED,
747
+ );
748
+ }
749
+
750
+ _blockedTask(task) {
751
+ return {
752
+ taskId: task.id,
753
+ agentId: null,
754
+ success: false,
755
+ status: "not-started",
756
+ output: "",
757
+ exitCode: null,
758
+ duration: 0,
759
+ executionStarted: false,
760
+ recoveryRequired: true,
761
+ error: "External agent pool retains an unconfirmed process tree",
762
+ errorCode: EXTERNAL_AGENT_ERROR.EXECUTION_BLOCKED,
763
+ runtimeClaims: VALIDATION_ONLY_CLAIMS,
764
+ terminalEvidence: [],
765
+ };
766
+ }
767
+
526
768
  /** Current pool status snapshot. */
527
769
  status() {
528
770
  const active = [...this._agents.values()].map((a) => a.toJSON());