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
@@ -26,6 +26,7 @@ import {
26
26
  rmSync,
27
27
  } from "node:fs";
28
28
  import { join, basename } from "node:path";
29
+ import { release as kernelRelease } from "node:os";
29
30
  import { getHomeDir, getConfigPath } from "./paths.js";
30
31
  import { inspectPrivatePaths, repairPrivatePaths } from "./secure-fs.js";
31
32
  import executionBroker from "./process-execution-broker/index.js";
@@ -68,6 +69,7 @@ export const _deps = {
68
69
  spawnSync: (...args) => executionBroker.spawnSync(...args),
69
70
  now: () => Date.now(),
70
71
  platform: () => process.platform,
72
+ kernelRelease,
71
73
  };
72
74
 
73
75
  function check(id, name, level, detail = "", fix = null) {
@@ -1242,12 +1244,39 @@ async function runtimeSection(opts, deps) {
1242
1244
 
1243
1245
  // ── execution context (P1-7) ───────────────────────────────────────────────
1244
1246
  // "任务在哪执行是 Session 一等属性": surface the DETECTED execution location and
1245
- // the fail-closed permission posture it implies. Read-only advisory — it never
1246
- // blocks. A local trusted machine is OK; a remote/unknown environment is a WARN
1247
+ // the fail-closed permission posture it implies. Read-only diagnosis; this does
1248
+ // not change execution authority. A remote/unknown environment is a WARN
1247
1249
  // because a session there fails closed to read-only unless powers are granted
1248
1250
  // explicitly (and any policy violation from the pure model is listed).
1249
1251
  async function executionSection(opts, deps) {
1250
1252
  const checks = [];
1253
+ try {
1254
+ // WSL1 lacks STATX_BTIME: Node substitutes mutable ctime for birthtime.
1255
+ // Do not silently drop generation from workspace identity, reset consent,
1256
+ // or claim that a different kernel establishes filesystem trust support.
1257
+ if (
1258
+ deps.platform() === "linux" &&
1259
+ /^4\.4\..*-Microsoft$/iu.test(deps.kernelRelease())
1260
+ ) {
1261
+ checks.push(
1262
+ check(
1263
+ "workspace-trust-identity",
1264
+ "Workspace trust filesystem identity",
1265
+ CHECK_LEVELS.ERR,
1266
+ "WSL1 reports mutable change time as creation time; workspace consent can be lost after directory edits or moves. Use the native Windows CLI for workspace trust operations. There is no safe automatic repair.",
1267
+ ),
1268
+ );
1269
+ }
1270
+ } catch {
1271
+ checks.push(
1272
+ check(
1273
+ "workspace-trust-identity",
1274
+ "Workspace trust filesystem identity",
1275
+ CHECK_LEVELS.ERR,
1276
+ "Kernel information is unavailable; the WSL1 workspace trust limitation could not be checked.",
1277
+ ),
1278
+ );
1279
+ }
1251
1280
  try {
1252
1281
  const {
1253
1282
  detectAmbientLocation,
@@ -48,7 +48,12 @@ export function readSecurityStore(filePath, label) {
48
48
 
49
49
  export function writeSecurityStore(filePath, label, store) {
50
50
  const directory = path.dirname(filePath);
51
- fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
51
+ // A caller may already hold a Linux directory through /proc/self/fd/N.
52
+ // WSL1 refuses mkdir on that existing descriptor alias; keep all later
53
+ // writes and fsync bound to the held directory without reopening its path.
54
+ if (!fs.statSync(directory, { throwIfNoEntry: false })?.isDirectory()) {
55
+ fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
56
+ }
52
57
  const temporaryPath = path.join(
53
58
  directory,
54
59
  `.${path.basename(filePath)}.${process.pid}.${crypto.randomUUID()}.tmp`,
@@ -0,0 +1,21 @@
1
+ import os from "node:os";
2
+
3
+ // WSL1's stat fallback reports ctime as birthtime. Creating an index or child
4
+ // directory changes that value without replacing the object. It supplies no
5
+ // creation-time identity; keep device/inode and the caller's no-link, physical
6
+ // containment and descriptor checks. WSL2 and other platforms retain birthtime.
7
+ export function artifactPhysicalIdentity(
8
+ stat,
9
+ { platform = process.platform, kernelRelease = os.release() } = {},
10
+ ) {
11
+ const birthtimeMs = Number(stat.birthtimeMs);
12
+ const wsl1CtimeFallback =
13
+ platform === "linux" &&
14
+ /^4\.4\..*-Microsoft$/iu.test(kernelRelease) &&
15
+ birthtimeMs === Number(stat.ctimeMs);
16
+ return Object.freeze({
17
+ birthtimeMs: wsl1CtimeFallback ? null : birthtimeMs,
18
+ dev: String(stat.dev),
19
+ ino: String(stat.ino),
20
+ });
21
+ }
@@ -13,6 +13,7 @@ import fs from "node:fs";
13
13
  import path from "node:path";
14
14
  import { types as utilTypes } from "node:util";
15
15
  import { ArtifactStore } from "../artifact-store.js";
16
+ import { artifactPhysicalIdentity as physicalIdentity } from "./evolution-artifact-identity.js";
16
17
  import { withEvolutionFileIdentity } from "./evolution-file-identity.js";
17
18
  import {
18
19
  EVOLUTION_ARTIFACT_REF_SCHEMA,
@@ -1060,19 +1061,12 @@ function isContained(root, candidate) {
1060
1061
  );
1061
1062
  }
1062
1063
 
1063
- function physicalIdentity(stat) {
1064
- return Object.freeze({
1065
- birthtimeMs: Number(stat.birthtimeMs),
1066
- dev: String(stat.dev),
1067
- ino: String(stat.ino),
1068
- });
1069
- }
1070
-
1071
1064
  function samePhysicalIdentity(stat, expected) {
1065
+ const actual = physicalIdentity(stat);
1072
1066
  return (
1073
- String(stat.dev) === expected.dev &&
1074
- String(stat.ino) === expected.ino &&
1075
- Number(stat.birthtimeMs) === expected.birthtimeMs
1067
+ actual.dev === expected.dev &&
1068
+ actual.ino === expected.ino &&
1069
+ actual.birthtimeMs === expected.birthtimeMs
1076
1070
  );
1077
1071
  }
1078
1072
 
@@ -0,0 +1,389 @@
1
+ /** Join a sealed admission inventory to presented final Eval receipts.
2
+ * Missing receipts stay unresolved; a caller-supplied set cannot prove global coverage.
3
+ */
4
+ import { createHash } from "node:crypto";
5
+ import { isProxy } from "node:util/types";
6
+ import {
7
+ resolveEvolutionEvalCohortEnrollment,
8
+ resolveEvolutionEvalCohortReconciliation,
9
+ } from "./evolution-eval-cohort-enrollment.js";
10
+ import {
11
+ computeEvolutionEvalContextDigest,
12
+ computeEvolutionEvalLaunchRequestDigest,
13
+ isEvolutionEvalReceiptVerifier,
14
+ verifyEvolutionEvalReceipt,
15
+ } from "./evolution-eval-gate.js";
16
+ import { verifyPmExplorationEffectAttemptCohort } from "./pm-exploration-benchmark.js";
17
+
18
+ export const EVOLUTION_EVAL_COHORT_RECEIPT_RECONCILIATION_SCHEMA =
19
+ "chainlesschain.evolution-eval-cohort-receipt-reconciliation/v1";
20
+ export const EVOLUTION_EVAL_COHORT_RECEIPT_RECONCILIATION_FAILED_CODE =
21
+ "CC_EVOLUTION_EVAL_COHORT_RECEIPT_RECONCILIATION_FAILED";
22
+ export const PM_EXPLORATION_ADMISSION_BOUND_COHORT_SCHEMA =
23
+ "chainlesschain.pm-exploration-admission-bound-cohort/v1";
24
+
25
+ function fail(message) {
26
+ const error = new Error(message);
27
+ error.code = EVOLUTION_EVAL_COHORT_RECEIPT_RECONCILIATION_FAILED_CODE;
28
+ throw error;
29
+ }
30
+
31
+ function snapshot(value, budget = { nodes: 0, chars: 0 }, depth = 0) {
32
+ if (++budget.nodes > 50_000 || depth > 50)
33
+ fail("cohort receipt evidence exceeds structural limits");
34
+ if (value === null || typeof value === "boolean") return value;
35
+ if (typeof value === "number" && Number.isFinite(value)) return value;
36
+ if (typeof value === "string") {
37
+ budget.chars += value.length;
38
+ if (budget.chars > 4_000_000)
39
+ fail("cohort receipt evidence exceeds size limit");
40
+ return value;
41
+ }
42
+ if (!value || typeof value !== "object" || isProxy(value))
43
+ fail("cohort receipt evidence must contain plain JSON data");
44
+ if (Array.isArray(value)) {
45
+ if (
46
+ Object.getPrototypeOf(value) !== Array.prototype ||
47
+ Reflect.ownKeys(value).length !== value.length + 1
48
+ )
49
+ fail("cohort receipt array must be dense own data");
50
+ return Array.from({ length: value.length }, (_, index) => {
51
+ const property = Object.getOwnPropertyDescriptor(value, String(index));
52
+ if (!property || !("value" in property))
53
+ fail("cohort receipt array must be own data");
54
+ return snapshot(property.value, budget, depth + 1);
55
+ });
56
+ }
57
+ if (![Object.prototype, null].includes(Object.getPrototypeOf(value)))
58
+ fail("cohort receipt evidence must be plain data");
59
+ return Object.fromEntries(
60
+ Reflect.ownKeys(value).map((key) => {
61
+ const property = Object.getOwnPropertyDescriptor(value, key);
62
+ if (
63
+ typeof key !== "string" ||
64
+ !property?.enumerable ||
65
+ !("value" in property)
66
+ )
67
+ fail("cohort receipt fields must be own data");
68
+ budget.chars += key.length;
69
+ if (budget.chars > 4_000_000)
70
+ fail("cohort receipt evidence exceeds size limit");
71
+ return [key, snapshot(property.value, budget, depth + 1)];
72
+ }),
73
+ );
74
+ }
75
+
76
+ function exact(value, keys, label) {
77
+ if (
78
+ !value ||
79
+ Array.isArray(value) ||
80
+ typeof value !== "object" ||
81
+ Reflect.ownKeys(value).length !== keys.length ||
82
+ keys.some((key) => !Object.hasOwn(value, key))
83
+ )
84
+ fail(`${label} must contain exactly its registered fields`);
85
+ return value;
86
+ }
87
+
88
+ function captureRecord(value, keys, label) {
89
+ if (
90
+ !value ||
91
+ Array.isArray(value) ||
92
+ typeof value !== "object" ||
93
+ isProxy(value) ||
94
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value)) ||
95
+ Reflect.ownKeys(value).length !== keys.length
96
+ )
97
+ fail(`${label} must contain exactly its own data fields`);
98
+ return Object.fromEntries(
99
+ keys.map((key) => {
100
+ const property = Object.getOwnPropertyDescriptor(value, key);
101
+ if (!property?.enumerable || !("value" in property))
102
+ fail(`${label} must contain exactly its own data fields`);
103
+ return [key, property.value];
104
+ }),
105
+ );
106
+ }
107
+
108
+ function canonical(value) {
109
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
110
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
111
+ return `{${Object.keys(value)
112
+ .sort()
113
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
114
+ .join(",")}}`;
115
+ }
116
+
117
+ function hash(
118
+ value,
119
+ schema = EVOLUTION_EVAL_COHORT_RECEIPT_RECONCILIATION_SCHEMA,
120
+ ) {
121
+ return `sha256:${createHash("sha256")
122
+ .update(`${schema}\0${canonical(value)}`)
123
+ .digest("hex")}`;
124
+ }
125
+
126
+ function frozen(value) {
127
+ if (value && typeof value === "object") {
128
+ for (const child of Object.values(value)) frozen(child);
129
+ Object.freeze(value);
130
+ }
131
+ return value;
132
+ }
133
+
134
+ /** Re-audit the sealed admission set after signature checks. */
135
+ export async function reconcileEvolutionEvalCohortReceipts(
136
+ authority,
137
+ verifier,
138
+ input,
139
+ ) {
140
+ if (!isEvolutionEvalReceiptVerifier(verifier))
141
+ fail("a branded final Eval receipt verifier is required");
142
+ const source = exact(
143
+ snapshot(input),
144
+ ["cohortId", "slots"],
145
+ "cohort receipt source",
146
+ );
147
+ if (
148
+ typeof source.cohortId !== "string" ||
149
+ !Array.isArray(source.slots) ||
150
+ source.slots.length > 32
151
+ )
152
+ fail("cohort receipt slots are invalid");
153
+ const lookup = { cohortId: source.cohortId };
154
+ const enrollment = resolveEvolutionEvalCohortEnrollment(authority, lookup);
155
+ const sealed = await resolveEvolutionEvalCohortReconciliation(
156
+ authority,
157
+ lookup,
158
+ );
159
+ if (source.slots.length !== enrollment.evidence.slots.length)
160
+ fail("cohort receipt source must cover every enrolled slot");
161
+ const admitted = new Map(
162
+ sealed.inventory.admissions.map((entry) => [entry.slotId, entry]),
163
+ );
164
+ const slots = [];
165
+ let signedReceiptCount = 0;
166
+ let receiptUnavailableCount = 0;
167
+ for (const [index, item] of source.slots.entries()) {
168
+ const entry = exact(
169
+ item,
170
+ ["slotId", "launchRequest", "receipt", "receiptContext"],
171
+ "cohort receipt slot",
172
+ );
173
+ const registered = enrollment.evidence.slots[index];
174
+ if (entry.slotId !== registered.slotId)
175
+ fail("cohort receipt slots differ from enrolled order");
176
+ const admission = admitted.get(entry.slotId);
177
+ if (entry.receipt === null) {
178
+ if (entry.launchRequest !== null || entry.receiptContext !== null)
179
+ fail("missing receipt cannot carry a substituted source");
180
+ if (admission) receiptUnavailableCount += 1;
181
+ slots.push({
182
+ slotId: entry.slotId,
183
+ status: admission ? "receipt-unavailable" : "unadmitted",
184
+ admissionDigest: admission?.admissionDigest ?? null,
185
+ runId: admission?.runId ?? null,
186
+ receiptDigest: null,
187
+ decision: null,
188
+ });
189
+ continue;
190
+ }
191
+ if (!admission || !entry.launchRequest || !entry.receiptContext)
192
+ fail("signed receipt has no matching admitted slot or context");
193
+ const request = exact(
194
+ entry.launchRequest,
195
+ [
196
+ "suiteRef",
197
+ "candidateId",
198
+ "baselineId",
199
+ "targetEnvironmentRef",
200
+ "evaluationContext",
201
+ ],
202
+ "cohort launch request",
203
+ );
204
+ const context = exact(
205
+ entry.receiptContext,
206
+ [
207
+ "runId",
208
+ "runNonce",
209
+ "suiteDigest",
210
+ "policyDigest",
211
+ "evaluationAuthorityRoot",
212
+ "targetEnvironmentRef",
213
+ "evaluationContextDigest",
214
+ "candidateId",
215
+ "baselineId",
216
+ "environmentDigest",
217
+ "tenantId",
218
+ "provenanceAudience",
219
+ "trainerAuthority",
220
+ "trainerRevision",
221
+ ],
222
+ "cohort receipt context",
223
+ );
224
+ const run = exact(
225
+ request.evaluationContext,
226
+ ["planDigest", "targetMatrixRoot", "cellId", "runtimeId"],
227
+ "cohort evaluation context",
228
+ );
229
+ if (
230
+ computeEvolutionEvalLaunchRequestDigest(request) !==
231
+ admission.requestDigest ||
232
+ run.planDigest !== registered.evaluationPlanDigest ||
233
+ run.cellId !== entry.slotId ||
234
+ request.candidateId !== context.candidateId ||
235
+ request.baselineId !== context.baselineId ||
236
+ request.targetEnvironmentRef !== context.targetEnvironmentRef ||
237
+ context.runId !== admission.runId ||
238
+ context.runNonce !== admission.runNonce ||
239
+ context.tenantId !== enrollment.evidence.descriptor.tenantId ||
240
+ context.policyDigest !== registered.policyDigest ||
241
+ context.evaluationAuthorityRoot !== registered.evaluationAuthorityRoot ||
242
+ context.evaluationContextDigest !==
243
+ computeEvolutionEvalContextDigest({
244
+ ...run,
245
+ tenantId: context.tenantId,
246
+ targetEnvironmentRef: context.targetEnvironmentRef,
247
+ environmentDigest: context.environmentDigest,
248
+ candidateId: context.candidateId,
249
+ baselineId: context.baselineId,
250
+ suiteDigest: context.suiteDigest,
251
+ policyDigest: context.policyDigest,
252
+ evaluationAuthorityRoot: context.evaluationAuthorityRoot,
253
+ })
254
+ )
255
+ fail("signed receipt differs from admitted request or enrolled cell");
256
+ const verified = await verifyEvolutionEvalReceipt(
257
+ verifier,
258
+ entry.receipt,
259
+ context,
260
+ );
261
+ signedReceiptCount += 1;
262
+ slots.push({
263
+ slotId: entry.slotId,
264
+ status: "signed-receipt",
265
+ admissionDigest: admission.admissionDigest,
266
+ runId: admission.runId,
267
+ receiptDigest: verified.receiptDigest,
268
+ decision: verified.decision,
269
+ });
270
+ }
271
+ const finalSeal = await resolveEvolutionEvalCohortReconciliation(
272
+ authority,
273
+ lookup,
274
+ );
275
+ if (canonical(finalSeal) !== canonical(sealed))
276
+ fail("sealed Ledger inventory changed during receipt verification");
277
+ const core = {
278
+ schema: EVOLUTION_EVAL_COHORT_RECEIPT_RECONCILIATION_SCHEMA,
279
+ cohortId: source.cohortId,
280
+ enrollmentDigest: sealed.enrollmentDigest,
281
+ sealDigest: sealed.sealDigest,
282
+ admissionInventoryAuthenticated: true,
283
+ signedReceiptCount,
284
+ receiptUnavailableCount,
285
+ unadmittedSlotCount: sealed.inventory.unadmittedSlotIds.length,
286
+ slots,
287
+ presentedReceiptsAuthenticated: true,
288
+ receiptSetCompletenessAuthenticated: false,
289
+ executionCoverageAuthenticated: false,
290
+ cohortCompletenessAuthenticated: false,
291
+ promotionAuthority: false,
292
+ };
293
+ return frozen({ ...core, reconciliationDigest: hash(core) });
294
+ }
295
+
296
+ /** Bind the independently verified PM denominator to the signed admission/receipt census. */
297
+ export async function reconcilePmExplorationAdmissionBoundCohort(
298
+ authority,
299
+ verifier,
300
+ input,
301
+ ) {
302
+ if (!isEvolutionEvalReceiptVerifier(verifier))
303
+ fail("a branded final Eval receipt verifier is required");
304
+ const source = captureRecord(
305
+ input,
306
+ ["cohortId", "receiptSlots", "cohortSource", "cohort", "registration"],
307
+ "PM admission-bound cohort source",
308
+ );
309
+ const receiptSlots = snapshot(source.receiptSlots);
310
+ const registration = exact(
311
+ snapshot(source.registration),
312
+ ["cohortId", "planDigest", "slots"],
313
+ "PM cohort registration",
314
+ );
315
+ // This verifier snapshots its source and expected context before its first await.
316
+ const pm = await verifyPmExplorationEffectAttemptCohort(
317
+ verifier,
318
+ { source: source.cohortSource, cohort: source.cohort },
319
+ registration,
320
+ );
321
+ const joined = await reconcileEvolutionEvalCohortReceipts(
322
+ authority,
323
+ verifier,
324
+ { cohortId: source.cohortId, slots: receiptSlots },
325
+ );
326
+ const enrollment = resolveEvolutionEvalCohortEnrollment(authority, {
327
+ cohortId: source.cohortId,
328
+ });
329
+ if (
330
+ pm.cohortId !== source.cohortId ||
331
+ registration.cohortId !== source.cohortId ||
332
+ pm.planDigest !== enrollment.evidence.plan.planDigest ||
333
+ registration.planDigest !== pm.planDigest ||
334
+ pm.registeredSlotCount !== enrollment.evidence.manifest.slotIds.length ||
335
+ pm.perArmDenominator !==
336
+ enrollment.evidence.manifest.plannedTestObservationsPerArm ||
337
+ canonical(registration.slots.map((slot) => slot.slotId)) !==
338
+ canonical(enrollment.evidence.manifest.slotIds)
339
+ )
340
+ fail("PM denominator differs from signed cohort enrollment");
341
+ for (const [index, attempt] of pm.attempts.entries()) {
342
+ const admitted = joined.slots[index];
343
+ if (
344
+ attempt.slotId !== admitted.slotId ||
345
+ (admitted.status === "signed-receipt" &&
346
+ (attempt.kind === "receipt-unavailable" ||
347
+ attempt.runId !== admitted.runId ||
348
+ attempt.receiptDigest !== admitted.receiptDigest)) ||
349
+ (admitted.status !== "signed-receipt" &&
350
+ (attempt.kind !== "receipt-unavailable" ||
351
+ attempt.runId !== null ||
352
+ attempt.receiptDigest !== null))
353
+ )
354
+ fail("PM attempt differs from its sealed admission and final receipt");
355
+ }
356
+ if (
357
+ pm.authenticatedAttemptCount !== joined.signedReceiptCount ||
358
+ (pm.missingReceiptCount ?? 0) !==
359
+ joined.receiptUnavailableCount + joined.unadmittedSlotCount
360
+ )
361
+ fail("PM attempt counts differ from sealed admission inventory");
362
+ const core = {
363
+ schema: PM_EXPLORATION_ADMISSION_BOUND_COHORT_SCHEMA,
364
+ cohortId: source.cohortId,
365
+ planDigest: pm.planDigest,
366
+ enrollmentDigest: joined.enrollmentDigest,
367
+ sealDigest: joined.sealDigest,
368
+ receiptReconciliationDigest: joined.reconciliationDigest,
369
+ attemptCohortDigest: pm.cohortDigest,
370
+ registeredSlotCount: pm.registeredSlotCount,
371
+ signedReceiptCount: joined.signedReceiptCount,
372
+ admittedMissingReceiptCount: joined.receiptUnavailableCount,
373
+ unadmittedSlotCount: joined.unadmittedSlotCount,
374
+ perArmDenominator: pm.perArmDenominator,
375
+ baseline: pm.baseline,
376
+ candidate: pm.candidate,
377
+ admissionAndAttemptBindingAuthenticated: true,
378
+ receiptSetCompletenessAuthenticated: false,
379
+ executionCoverageAuthenticated: false,
380
+ cohortCompletenessAuthenticated: false,
381
+ reportAuthenticated: false,
382
+ requiresIndependentPilotApproval: true,
383
+ qualifiesForPromotion: false,
384
+ };
385
+ return frozen({
386
+ ...core,
387
+ bindingDigest: hash(core, PM_EXPLORATION_ADMISSION_BOUND_COHORT_SCHEMA),
388
+ });
389
+ }
@@ -0,0 +1,63 @@
1
+ // Diagnostic locations are public source labels, never target paths, stack
2
+ // text or error messages. They do not grant authority or trigger a retry.
3
+ const SOURCES = Object.freeze({
4
+ "commands/session-location.js": "session-location",
5
+ "harness/jsonl-session-store.js": "session-store",
6
+ "harness/session-index.js": "session-index",
7
+ "harness/transcript-integrity.js": "transcript-integrity",
8
+ "lib/secure-fs.js": "private-storage",
9
+ "lib/secure-file-identity.js": "file-identity",
10
+ "lib/session-anti-rollback-anchor.js": "session-anchor",
11
+ "lib/with-file-lock.js": "file-lock",
12
+ "lib/execution-location-local-supervisor.mjs": "local-supervisor",
13
+ "lib/execution-location-contract.js": "location-contract",
14
+ });
15
+ const LABELS = new Set(Object.values(SOURCES));
16
+ const PREFIX = "CC_EXECUTION_LOCATION_FAILURE_SITE=";
17
+ const MAX_DIAGNOSTIC_CHARS = 8192;
18
+
19
+ // PowerShell diagnostics are deliberately bounded to fixed native operation
20
+ // labels and HRESULTs; neither paths nor exception text cross the boundary.
21
+ export function readExecutionLocationStorageFailure(stderr) {
22
+ const match = String(stderr || "")
23
+ .slice(0, MAX_DIAGNOSTIC_CHARS)
24
+ .match(
25
+ /\[windows-acl:(initialize|traversal|lookup|repair-lock|repair-inspect|repair-write|verify|timeout(?:-(?:startup|initialize|traversal|lookup|repair-lock|repair-inspect|repair-write|verify))?|spawn|output)(:0x[0-9a-f]{8})?\]/u,
26
+ );
27
+ return match ? `${match[1]}${match[2] || ""}` : null;
28
+ }
29
+
30
+ export function executionLocationFailureSite(error) {
31
+ const stack = String(error?.stack || "").slice(0, MAX_DIAGNOSTIC_CHARS);
32
+ for (const frame of stack.split(/\r?\n/u).slice(1)) {
33
+ if (!/^\s+at /u.test(frame)) continue;
34
+ const normalized = frame.replaceAll("\\", "/");
35
+ for (const [source, label] of Object.entries(SOURCES)) {
36
+ const suffix = `/packages/cli/src/${source}:`;
37
+ const index = normalized.lastIndexOf(suffix);
38
+ if (index < 0) continue;
39
+ const position = normalized.slice(index + suffix.length);
40
+ const line = position.match(/^([1-9][0-9]{0,5}):[0-9]+\)?$/u)?.[1];
41
+ if (line) return `${label}:${line}`;
42
+ }
43
+ }
44
+ return null;
45
+ }
46
+
47
+ export function formatExecutionLocationFailureSite(error) {
48
+ const site = executionLocationFailureSite(error);
49
+ return site === null ? "" : `${PREFIX}${site}\n`;
50
+ }
51
+
52
+ export function readExecutionLocationFailureSite(stderr) {
53
+ const text = String(stderr || "").slice(0, MAX_DIAGNOSTIC_CHARS);
54
+ for (const line of text.split(/\r?\n/u)) {
55
+ if (!line.startsWith(PREFIX)) continue;
56
+ const match = line
57
+ .slice(PREFIX.length)
58
+ .match(/^([a-z-]+):([1-9][0-9]{0,5})$/u);
59
+ if (match && LABELS.has(match[1])) return `${match[1]}:${match[2]}`;
60
+ }
61
+ // An uncaught supervisor exception already has a stack on stderr.
62
+ return executionLocationFailureSite({ stack: text });
63
+ }