chainlesschain 0.165.4 → 0.165.6

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 (214) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/.build-hash +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-C__nnraW.js → AIOps-vfoDb6HZ.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-CsKWHEZ-.js → ActionButton-Cm5f7p93.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-BhIjfjWO.js → Analytics-yRuvgWxa.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-BjuXFzWZ.js → AppLayout-BROsC4h1.js} +4 -4
  7. package/src/assets/web-panel/assets/{Artifacts-k6whDkZJ.js → Artifacts-CimHApb1.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-C4FBMYRh.js → Audit-DI8kr8zI.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-C_vRrSXk.js → BackgroundAgents-DSLzKy-n.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-CngFZeVp.js → Backup-DkH_n2r1.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-B_H9EBRm.js → BaseInput-CKSrUoRA.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-DLEC5kt7.js → Chat-ClwfMXUS.js} +3 -3
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-CjMaqfL7.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-m3ClR4xh.js → Checkbox-BYTehcQG.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-CmLSFrgp.js → Codegen-B8AMcp6J.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-DFGQteHN.js → Col-BNSogPo3.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-EUUVORHE.js → Community-JxPvGb8O.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-2PSg0Yr7.js → Compact-DF7bFAgE.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-CcKur7gB.js → Compliance-Bvhqnwrq.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-DK_Fezfa.js → Cowork-BDS0CJvM.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-Dbw89xl7.js → Cron-DqvRfxoQ.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-CH66h_Ec.js → Crosschain-CDcIvnqS.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-D1igRb17.js → DID-D7jaUxU3.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-DVAsrobk.js → Dashboard-B5A18wEV.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-Dl7W8AQs.js → Dropdown-_6IVkGag.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-D5tpaEQC.js → EmailListRenderer-C9PeiKCG.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-O_VQf8gq.js → FamilyGuardDashboard-DXjuEHrX.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-BTVcgS9n.js → Federation-B4IAR9zv.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-BRnkJAIz.js → FormItemContext-CxQeSNx1.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-8OWSCkDj.js → GenericCardRenderer-B8GS-Y3N.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-WXLYTQj2.js → Git-BS8SouUX.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-BezaUhtc.js → Governance-Dq9aYb5Q.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-CuRay3Gu.js → Inference-BrCEe9AJ.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-DfWLDW1m.js → KnowledgeGraph-DybOpiY2.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-C55y2pPY.js → Logs-DBpzbRfx.js} +2 -2
  36. package/src/assets/web-panel/assets/MarkdownRenderer-CFyt8iUd.js +1 -0
  37. package/src/assets/web-panel/assets/{Marketplace-Dk08Uycg.js → Marketplace-Cc7CCSCu.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-C11fSB5V.js → McpTools-DFaIhOfu.js} +3 -3
  39. package/src/assets/web-panel/assets/{Memory-mr0eZc97.js → Memory-KCqlp9ol.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-C0iCSRbb.js → MobileBridge-Bys84ySN.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-CY-xMG8Z.js → MobileProjects-B-6qU-je.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-Bplqc_Wc.js → Mtc-BgY-fvCq.js} +4 -4
  43. package/src/assets/web-panel/assets/{MtcAudit-BlzwsoSM.js → MtcAudit-B8pCmqQJ.js} +4 -4
  44. package/src/assets/web-panel/assets/{Multisig-BBLmTty6.js → Multisig-BbOmYutA.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-DtT1uf1W.js → NLProgramming-BocLQz_M.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-DcqQAxTK.js → Notes-CSwbxEop.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-cb0kWoZe.js → NotificationSettings-CqFNSYG3.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-kw9HZQNN.js → OrderTableRenderer-C6gMfAk7.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-DlTlbkUN.js → Organization-QrDXVdMJ.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-pp1qs-oY.js → Overflow-Cxntotjt.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-BESLnyYz.js → P2P-CIdBOwNq.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-B-J1mGuf.js → PdhVaultBrowser-CT5aP8rD.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-B36PeT1_.js → Permissions-DH7OM8XU.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-CTK2ad-3.js → PersonalDataHub-CnJqbWce.js} +3 -3
  55. package/src/assets/web-panel/assets/{Pipeline-zJNGXsac.js → Pipeline-5C3HG1kH.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-b9fz0Qf0.js → Privacy-B4yIp7xK.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-DjZbZgiB.js → ProjectInit-BMvt-2M0.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-C-hHJXlD.js → ProjectSettings-CvSTEMRG.js} +2 -2
  59. package/src/assets/web-panel/assets/Projects-BKBJxEek.js +1 -0
  60. package/src/assets/web-panel/assets/Providers-BdwUqFWN.js +1 -0
  61. package/src/assets/web-panel/assets/{QrScannerModal-A0yoQ3-3.js → QrScannerModal-DtnCKlTm.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-DrFgFJNC.js → QuickAsk-sTbgwyNr.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-KC8hF1g4.js → Recommend-Bzr14gSb.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-DGTPIk6u.js → RemoteSession-C_TF5IaJ.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-QmbwM7Yk.js → Reputation-GCAM4H2K.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-BxjJylia.js → Row-Dir0r6OQ.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-B7Wda1J6.js → RssFeed-CpGnlecX.js} +2 -2
  68. package/src/assets/web-panel/assets/{Search-_plQ_YSA.js → Search-DMMamC6u.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-CD2YJZfx.js → Security-yqay5yG-.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-qQE7NmwE.js → Services-C5i2wh9G.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-DgQqkFf7.js → Skeleton-vUqk35yj.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-C4C0oFFt.js → Skills-DzcSkhot.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-Px2N2B5c.js → Sla-CB6qbYNr.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-DN6C3lQd.js → SpeechSettings-BHUI7cox.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-jm5aH_m7.js → SyncSettings-D-RrsxTJ.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-DlkJcv67.js → Tasks-DFxdOJiq.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-DyrTHUBs.js → Templates-SKAob_Aq.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-mC434PtL.js → Tenant-BPfsfHQ-.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-o0_s3NgK.js → Terminal-8iw7FpUf.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-DAGlAXOw.js → TimelineRenderer-C4Gjj5Su.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-BnulS_bs.js → Tokens-COYhN18e.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-suQbVXYM.js → Trigger-B-JzXcf6.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-DbIJAPo5.js → Trust-BJ5bg0nI.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-CQNpbIHi.js → UkeySign-BG_ByRMf.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-D8aWCERk.js → VideoEditing-B3kOnSiU.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-CuLpYfZc.js → Wallet-CcoGFnK7.js} +2 -2
  87. package/src/assets/web-panel/assets/{WebAuthn-CsfG8ZMc.js → WebAuthn-DdT8vRC_.js} +4 -4
  88. package/src/assets/web-panel/assets/{WorkflowEditor-BYsEAZbd.js → WorkflowEditor-CZu3M9N8.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-FT4Um3-I.js → chat-DxJt3Qba.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-CKbS_Wlt.js → colors-DdYfwJaB.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-CFJtzuJM.js → compact-item-BG3SUzwj.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-B9kSRW6K.js → createContext-By51z2-1.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-DorRZcI9.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-DR-x0Xpi.js → hasIn-B0apZ3KJ.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-DjEP7WkH.js → index-3jWkIu5j.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-7jHr_A_k.js → index-B3rWuPMW.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DcfxhKXR.js → index-B5rLiEo0.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-tqSEHPRT.js → index-BBPf3TpM.js} +1 -1
  99. package/src/assets/web-panel/assets/index-BETiL0a3.js +1 -0
  100. package/src/assets/web-panel/assets/{index-Cr2FLUsD.js → index-BIrJfqO4.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-Bt4fS2eL.js → index-BLIbGOLX.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BwR7yc2h.js → index-BP94CrBV.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BVPU43b1.js → index-BWF8_mkx.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DShSkww-.js → index-BYINoRLK.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Bzz0C1BZ.js → index-BZ_0qm4g.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-KqDaCApw.js → index-BewKYrX9.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BW-t9n-q.js → index-BfWYsB9t.js} +1 -1
  108. package/src/assets/web-panel/assets/index-BhAVHuW8.js +1 -0
  109. package/src/assets/web-panel/assets/{index-B7osrXqy.js → index-Bissefox.js} +3 -3
  110. package/src/assets/web-panel/assets/{index-DW4BWjTk.js → index-BkvcEo4p.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DdkIhfi-.js → index-Bos5_aMV.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DTxNy0ZU.js → index-C1C9i79A.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-QBSeNVO3.js → index-CAhHirVH.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-D4LfPvWA.js → index-CNIxXMmN.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-C_enk9I_.js → index-CW93tZDv.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-WE08gMJP.js → index-CWEuZWCK.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-r2VI1Ikk.js → index-Cp6e-hGw.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Dap9c3eD.js → index-CpjZhgNd.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DWdqx7zI.js → index-CzmQElZy.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BGbPnC5x.js → index-DCn8IcxV.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DiNUEpSQ.js → index-DE76D-kA.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DtkFqPVA.js → index-DaIz0NAW.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CGaXUsIs.js → index-Da_WBdLX.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-B3ZX81mK.js → index-Dz49VOyQ.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BK3TiKVq.js → index-Q2SCX-MI.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CJmIQ9XR.js → index-RD6O-0C6.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CvrCCqJt.js → index-SQqOlR3d.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BI5hP_qy.js → index-ZFbps9po.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DeSgw-WV.js → index-ZxtP8jG7.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DMGmg497.js → index-bP_VlDb4.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BfFCQHL3.js → index-kf57LJ93.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-OSzjTzGM.js → index-oxRrmFO9.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-C2JvmYRc.js → index-p1_8SbI1.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-Dd7n7VgI.js → initDefaultProps-BWJktcg8.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-BwxouRw1.js → motion-BEXBzUFV.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-DObN0PG9.js → move-BUKwn2sx.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-B3nOUQc7.js → mtc-parser-FTI7btqQ.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-o9WU2Nbl.js → omit-CsLtSPH3.js} +1 -1
  139. package/src/assets/web-panel/assets/parsers-YNLm7sQ0.js +4 -0
  140. package/src/assets/web-panel/assets/{pickAttrs-CL_vvfQ_.js → pickAttrs-DWZxsT_S.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-CYrM2tyK.js → placementArrow-Bcfs43CX.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-k_06cQ96.js → responsiveObserve-a9bcC1p-.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-CPKG0pxS.js → slide-BDTzgOXN.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-BDDEeLTw.js → statusUtils-Iq1j_HUg.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-Cmb7RTh7.js → styleChecker-DAZEYxeh.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-e2IedC4N.js → useFlexGapSupport-DVkjyDrh.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-CE_gxVnm.js → useFs-wXTpNTHt.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-BkMIIKMz.js → usePersonalDataHub-CtQM_aZr.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-DW886XV1.js → vnode-hjEoG85v.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-Dwo_adaf.js → zoom-BHVpyKg_.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/command-help-index.json +3 -3
  153. package/src/commands/agent.js +14 -2
  154. package/src/commands/artifacts.js +235 -0
  155. package/src/commands/background-session.js +100 -10
  156. package/src/commands/cowork.js +86 -57
  157. package/src/commands/mcp.js +5 -0
  158. package/src/commands/plugin.js +145 -29
  159. package/src/commands/remote-control.js +295 -110
  160. package/src/commands/session-location.js +20 -1
  161. package/src/commands/session-message.js +171 -0
  162. package/src/commands/session.js +75 -69
  163. package/src/data/changelog.json +29 -3
  164. package/src/gateways/ws/message-dispatcher.js +57 -0
  165. package/src/harness/mcp-client.js +141 -10
  166. package/src/lib/artifact-access-ledger.js +1 -0
  167. package/src/lib/artifact-deletion-ledger.js +1 -0
  168. package/src/lib/artifact-recovery.js +970 -0
  169. package/src/lib/artifact-workbench-projection.js +171 -0
  170. package/src/lib/background-session-transport.js +153 -27
  171. package/src/lib/dynamic-workflow-runtime.js +408 -1
  172. package/src/lib/execution-location-target.js +4 -2
  173. package/src/lib/mcp-client.js +2 -0
  174. package/src/lib/mcp-headers-helper.js +47 -5
  175. package/src/lib/mcp-oauth.js +55 -6
  176. package/src/lib/mcp-stdio-executable-identity.js +16 -0
  177. package/src/lib/mcp-stdio-native-code-policy.js +74 -0
  178. package/src/lib/mcp-stdio-package-materialization.js +12 -3
  179. package/src/lib/mcp-tls.js +230 -0
  180. package/src/lib/output-styles.js +12 -0
  181. package/src/lib/plugin-runtime/install.js +614 -71
  182. package/src/lib/plugin-runtime/marketplace-archive-source.js +331 -0
  183. package/src/lib/plugin-runtime/marketplace-catalog.js +52 -6
  184. package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +1 -0
  185. package/src/lib/plugin-runtime/marketplace-source-adapter.js +163 -0
  186. package/src/lib/plugin-runtime/marketplace-source-cache.js +11 -1
  187. package/src/lib/plugin-runtime/remote-source.js +435 -55
  188. package/src/lib/plugin-security.js +393 -41
  189. package/src/lib/plugin-source-identity.js +850 -0
  190. package/src/lib/process-execution-broker/index.js +112 -0
  191. package/src/lib/process-execution-broker/platform-sandbox.js +57 -3
  192. package/src/lib/process-execution-broker/workspace-transaction.js +26 -0
  193. package/src/lib/remote-approval-bridge.js +136 -46
  194. package/src/lib/remote-control.js +217 -31
  195. package/src/lib/session-message-fabric.js +1105 -0
  196. package/src/lib/session-projection.js +171 -12
  197. package/src/lib/session-runtime-retention.js +155 -0
  198. package/src/lib/settings-loader.cjs +29 -0
  199. package/src/repl/agent-repl.js +51 -14
  200. package/src/repl/permission-prompt.js +31 -8
  201. package/src/repl/repl-keybindings.js +55 -0
  202. package/src/runtime/agent-core.js +63 -2
  203. package/src/runtime/headless-runner.js +47 -66
  204. package/src/runtime/headless-stream.js +18 -24
  205. package/src/runtime/mcp-config.js +2 -0
  206. package/src/runtime/policies/agent-policy.js +2 -0
  207. package/src/assets/web-panel/assets/ChatBubbleRenderer-xijcWkJe.js +0 -1
  208. package/src/assets/web-panel/assets/MarkdownRenderer-hDpWdiBc.js +0 -1
  209. package/src/assets/web-panel/assets/Projects-BC9KSDM6.js +0 -1
  210. package/src/assets/web-panel/assets/Providers-Dz-CAYYU.js +0 -1
  211. package/src/assets/web-panel/assets/devWarning-DJZ0gAMu.js +0 -1
  212. package/src/assets/web-panel/assets/index-Bizb4hkw.js +0 -1
  213. package/src/assets/web-panel/assets/index-OHSl-xCh.js +0 -1
  214. package/src/assets/web-panel/assets/parsers-UEvh_ShA.js +0 -4
@@ -0,0 +1,171 @@
1
+ import { publicArtifactMetadata } from "./artifact-store.js";
2
+ import { readArtifactAccessLedger } from "./artifact-access-ledger.js";
3
+ import { readArtifactCleanupLedger } from "./artifact-cleanup-ledger.js";
4
+ import { readArtifactDeletionLedger } from "./artifact-deletion-ledger.js";
5
+ import {
6
+ buildArtifactRecoveryPlan,
7
+ readArtifactOrphanGcLedger,
8
+ } from "./artifact-recovery.js";
9
+
10
+ export const ARTIFACT_WORKBENCH_PROJECTION_SCHEMA = "cc-artifact-workbench/v1";
11
+ export const MAX_ARTIFACT_WORKBENCH_ACTIVITY = 200;
12
+
13
+ function returnedResultLineage(lineage) {
14
+ if (lineage?.schema !== "cc-execution-location-result-artifact-lineage/v1") {
15
+ return null;
16
+ }
17
+ const fields = [
18
+ "sessionId",
19
+ "requestId",
20
+ "reviewDigest",
21
+ "item",
22
+ "kind",
23
+ "mediaType",
24
+ "byteLength",
25
+ "sourceDigest",
26
+ ];
27
+ if (fields.some((field) => lineage[field] == null)) return null;
28
+ return Object.freeze(
29
+ Object.fromEntries(fields.map((field) => [field, lineage[field]])),
30
+ );
31
+ }
32
+
33
+ function accessActivity(event) {
34
+ return Object.freeze({
35
+ type: "access",
36
+ occurredAt: event.authorizedAt,
37
+ artifactId: event.artifactId,
38
+ artifactSessionId: event.artifactSessionId,
39
+ recordDigest: event.recordDigest,
40
+ action: event.action,
41
+ client: event.client,
42
+ settlementId: event.accessId,
43
+ eventDigest: event.eventDigest,
44
+ });
45
+ }
46
+
47
+ function deletionActivity(event) {
48
+ return Object.freeze({
49
+ type: "deletion",
50
+ phase: event.phase,
51
+ occurredAt: event.occurredAt,
52
+ artifactId: event.artifactId,
53
+ artifactSessionId: event.artifactSessionId,
54
+ recordDigest: event.recordDigest,
55
+ action: event.reason,
56
+ client: event.client,
57
+ settlementId: event.deletionId,
58
+ eventDigest: event.eventDigest,
59
+ });
60
+ }
61
+
62
+ function cleanupActivity(event) {
63
+ return Object.freeze({
64
+ type: "cleanup",
65
+ phase: event.phase,
66
+ occurredAt: event.occurredAt,
67
+ artifactId: null,
68
+ artifactSessionId: null,
69
+ recordDigest: null,
70
+ action: "expired",
71
+ client: event.client,
72
+ settlementId: event.cleanupId,
73
+ itemCount: event.itemCount,
74
+ eventDigest: event.eventDigest,
75
+ });
76
+ }
77
+
78
+ function orphanGcActivity(event) {
79
+ return Object.freeze({
80
+ type: "orphan-gc",
81
+ phase: event.phase,
82
+ occurredAt: event.occurredAt,
83
+ artifactId: null,
84
+ artifactSessionId: null,
85
+ recordDigest: null,
86
+ action: event.decision,
87
+ client: "administrator",
88
+ settlementId: event.adjudicationId,
89
+ outcome: event.outcome,
90
+ eventDigest: event.eventDigest,
91
+ });
92
+ }
93
+
94
+ function occurredAtMs(event) {
95
+ const parsed = Date.parse(event.occurredAt || "");
96
+ return Number.isFinite(parsed) ? parsed : 0;
97
+ }
98
+
99
+ export function buildArtifactWorkbenchProjection(store, options = {}) {
100
+ if (!store?.dir) {
101
+ throw new TypeError("artifact workbench requires an ArtifactStore");
102
+ }
103
+ const recovery = (
104
+ options.buildArtifactRecoveryPlan || buildArtifactRecoveryPlan
105
+ )(store, options.recoveryOptions || {});
106
+ const access = (options.readArtifactAccessLedger || readArtifactAccessLedger)(
107
+ store,
108
+ options.accessOptions || {},
109
+ );
110
+ const deletion = (
111
+ options.readArtifactDeletionLedger || readArtifactDeletionLedger
112
+ )(store, options.deletionOptions || {});
113
+ const cleanup = (
114
+ options.readArtifactCleanupLedger || readArtifactCleanupLedger
115
+ )(store, options.cleanupOptions || {});
116
+ const orphanGc = (
117
+ options.readArtifactOrphanGcLedger || readArtifactOrphanGcLedger
118
+ )(store, options.orphanGcOptions || {});
119
+ const accessByArtifact = new Map();
120
+ for (const event of access.events) {
121
+ const events = accessByArtifact.get(event.artifactId) || [];
122
+ events.push(event);
123
+ accessByArtifact.set(event.artifactId, events);
124
+ }
125
+ const artifacts = store.list().map((entry) => {
126
+ const metadata = publicArtifactMetadata(entry);
127
+ const accesses = accessByArtifact.get(entry.id) || [];
128
+ const latestAccess = accesses.at(-1) || null;
129
+ return Object.freeze({
130
+ ...metadata,
131
+ returnedResult: returnedResultLineage(metadata.lineage),
132
+ history: Object.freeze({
133
+ accessCount: accesses.length,
134
+ latestAccess: latestAccess
135
+ ? Object.freeze({
136
+ action: latestAccess.action,
137
+ client: latestAccess.client,
138
+ authorizedAt: latestAccess.authorizedAt,
139
+ eventDigest: latestAccess.eventDigest,
140
+ })
141
+ : null,
142
+ }),
143
+ });
144
+ });
145
+ const allActivity = [
146
+ ...access.events.map(accessActivity),
147
+ ...deletion.events.map(deletionActivity),
148
+ ...cleanup.events.map(cleanupActivity),
149
+ ...orphanGc.events.map(orphanGcActivity),
150
+ ].sort((left, right) => {
151
+ const time = occurredAtMs(right) - occurredAtMs(left);
152
+ return time || right.eventDigest.localeCompare(left.eventDigest);
153
+ });
154
+ const activity = allActivity.slice(0, MAX_ARTIFACT_WORKBENCH_ACTIVITY);
155
+ return Object.freeze({
156
+ schema: ARTIFACT_WORKBENCH_PROJECTION_SCHEMA,
157
+ observedAt: recovery.observedAt,
158
+ artifacts: Object.freeze(artifacts),
159
+ recovery,
160
+ history: Object.freeze({
161
+ accessHeadDigest: access.headDigest,
162
+ deletionHeadDigest: deletion.headDigest,
163
+ cleanupHeadDigest: cleanup.headDigest,
164
+ orphanGcHeadDigest: orphanGc.headDigest,
165
+ totalEventCount: allActivity.length,
166
+ returnedEventCount: activity.length,
167
+ truncated: allActivity.length > activity.length,
168
+ activity: Object.freeze(activity),
169
+ }),
170
+ });
171
+ }
@@ -33,6 +33,10 @@ import {
33
33
 
34
34
  const HELLO_TIMEOUT_MS = 5000;
35
35
  const MAX_LINE_BYTES = 1024 * 1024;
36
+ export const BACKGROUND_SESSION_BACKLOG_LIMITS = Object.freeze({
37
+ messages: 256,
38
+ bytes: 1024 * 1024,
39
+ });
36
40
 
37
41
  /** Pipe endpoint for a session id (Windows named pipe / POSIX socket file). */
38
42
  export function transportPipePath(id, dir, options = {}) {
@@ -70,14 +74,128 @@ export function createNdjsonReader(onMessage, onError = () => {}) {
70
74
  };
71
75
  }
72
76
 
73
- function writeMessage(socket, message) {
74
- if (!socket || socket.destroyed) return false;
75
- try {
76
- socket.write(`${JSON.stringify(message)}\n`);
77
- return true;
78
- } catch {
77
+ /**
78
+ * A socket writer with an application-level queue above Node's native write
79
+ * buffer. Once `socket.write()` reports backpressure, later messages wait for
80
+ * `drain`; a consumer that exceeds either cap is disconnected instead of
81
+ * retaining an unbounded event history in the worker.
82
+ */
83
+ export function createBoundedSocketWriter(socket, configured = {}) {
84
+ const maxMessages = Math.max(
85
+ 1,
86
+ Number.isFinite(configured.messages)
87
+ ? Math.floor(configured.messages)
88
+ : BACKGROUND_SESSION_BACKLOG_LIMITS.messages,
89
+ );
90
+ const maxBytes = Math.max(
91
+ 1024,
92
+ Number.isFinite(configured.bytes)
93
+ ? Math.floor(configured.bytes)
94
+ : BACKGROUND_SESSION_BACKLOG_LIMITS.bytes,
95
+ );
96
+ const queue = [];
97
+ let queuedBytes = 0;
98
+ let waitingForDrain = false;
99
+ let closed = false;
100
+ let overflowed = false;
101
+
102
+ const nativeBufferedBytes = () =>
103
+ Number.isFinite(socket?.writableLength)
104
+ ? Math.max(0, socket.writableLength)
105
+ : 0;
106
+ const clear = () => {
107
+ queue.length = 0;
108
+ queuedBytes = 0;
109
+ waitingForDrain = false;
110
+ };
111
+ const overflow = () => {
112
+ if (overflowed) return false;
113
+ overflowed = true;
114
+ closed = true;
115
+ clear();
116
+ try {
117
+ configured.onOverflow?.({ maxMessages, maxBytes });
118
+ } catch {
119
+ /* observer errors do not change the fail-closed outcome */
120
+ }
121
+ try {
122
+ socket?.destroy();
123
+ } catch {
124
+ /* already closed */
125
+ }
79
126
  return false;
80
- }
127
+ };
128
+ const writePayload = (payload) => {
129
+ try {
130
+ if (socket.write(payload) === false) waitingForDrain = true;
131
+ return true;
132
+ } catch {
133
+ closed = true;
134
+ clear();
135
+ return false;
136
+ }
137
+ };
138
+ const flush = () => {
139
+ if (closed || socket?.destroyed) {
140
+ closed = true;
141
+ clear();
142
+ return;
143
+ }
144
+ waitingForDrain = false;
145
+ while (queue.length > 0 && !waitingForDrain) {
146
+ const next = queue.shift();
147
+ queuedBytes -= next.bytes;
148
+ if (!writePayload(next.payload)) break;
149
+ }
150
+ };
151
+ const close = () => {
152
+ if (closed) return;
153
+ closed = true;
154
+ clear();
155
+ socket?.removeListener?.("drain", flush);
156
+ };
157
+
158
+ socket?.on?.("drain", flush);
159
+ socket?.once?.("close", close);
160
+ socket?.once?.("error", close);
161
+
162
+ return Object.freeze({
163
+ write(message) {
164
+ if (closed || !socket || socket.destroyed) return false;
165
+ let payload;
166
+ try {
167
+ payload = `${JSON.stringify(message)}\n`;
168
+ } catch {
169
+ return false;
170
+ }
171
+ const bytes = Buffer.byteLength(payload, "utf8");
172
+ if (bytes > maxBytes) return overflow();
173
+ if (waitingForDrain || queue.length > 0) {
174
+ if (
175
+ queue.length + 1 > maxMessages ||
176
+ nativeBufferedBytes() + queuedBytes + bytes > maxBytes
177
+ ) {
178
+ return overflow();
179
+ }
180
+ queue.push({ payload, bytes });
181
+ queuedBytes += bytes;
182
+ return true;
183
+ }
184
+ if (nativeBufferedBytes() + bytes > maxBytes) return overflow();
185
+ return writePayload(payload);
186
+ },
187
+ close,
188
+ state: () => ({
189
+ queuedMessages: queue.length,
190
+ queuedBytes,
191
+ nativeBufferedBytes: nativeBufferedBytes(),
192
+ waitingForDrain,
193
+ overflowed,
194
+ closed,
195
+ maxMessages,
196
+ maxBytes,
197
+ }),
198
+ });
81
199
  }
82
200
 
83
201
  /**
@@ -117,7 +235,7 @@ export function startBackgroundSessionServer(opts) {
117
235
  /* fine — usually ENOENT */
118
236
  }
119
237
  }
120
- const clients = new Set();
238
+ const clients = new Map();
121
239
  const notifyClients = () => {
122
240
  try {
123
241
  onClientChange?.(clients.size);
@@ -128,6 +246,8 @@ export function startBackgroundSessionServer(opts) {
128
246
 
129
247
  const server = net.createServer((socket) => {
130
248
  let authed = false;
249
+ const writer = createBoundedSocketWriter(socket);
250
+ const send = (message) => writer.write(message);
131
251
  const helloTimer = setTimeout(() => {
132
252
  if (!authed) socket.destroy();
133
253
  }, HELLO_TIMEOUT_MS);
@@ -141,8 +261,8 @@ export function startBackgroundSessionServer(opts) {
141
261
  if (message.type === "hello" && message.token === token) {
142
262
  authed = true;
143
263
  clearTimeout(helloTimer);
144
- clients.add(socket);
145
- writeMessage(socket, {
264
+ clients.set(socket, writer);
265
+ send({
146
266
  type: "hello",
147
267
  ...(getStatus ? getStatus() : { id }),
148
268
  });
@@ -156,7 +276,7 @@ export function startBackgroundSessionServer(opts) {
156
276
  case "prompt": {
157
277
  const text = String(message.text || "").trim();
158
278
  if (!text) {
159
- writeMessage(socket, {
279
+ send({
160
280
  type: "error",
161
281
  message: "prompt text is empty",
162
282
  });
@@ -164,12 +284,12 @@ export function startBackgroundSessionServer(opts) {
164
284
  }
165
285
  try {
166
286
  const result = onPrompt(text);
167
- writeMessage(socket, {
287
+ send({
168
288
  type: "accepted",
169
289
  queued: result?.queued ?? 1,
170
290
  });
171
291
  } catch (error) {
172
- writeMessage(socket, {
292
+ send({
173
293
  type: "error",
174
294
  message: error?.message || String(error),
175
295
  });
@@ -177,7 +297,7 @@ export function startBackgroundSessionServer(opts) {
177
297
  return;
178
298
  }
179
299
  case "status": {
180
- writeMessage(socket, {
300
+ send({
181
301
  type: "status",
182
302
  ...(getStatus ? getStatus() : { id }),
183
303
  });
@@ -186,9 +306,9 @@ export function startBackgroundSessionServer(opts) {
186
306
  case "stop": {
187
307
  try {
188
308
  onStop?.();
189
- writeMessage(socket, { type: "stopping" });
309
+ send({ type: "stopping" });
190
310
  } catch (error) {
191
- writeMessage(socket, {
311
+ send({
192
312
  type: "error",
193
313
  message: error?.message || String(error),
194
314
  });
@@ -206,7 +326,7 @@ export function startBackgroundSessionServer(opts) {
206
326
  message;
207
327
  const resolvedId = requestId || intId;
208
328
  if (!resolvedId) {
209
- writeMessage(socket, {
329
+ send({
210
330
  type: "error",
211
331
  message: "interaction_response requires requestId or intId",
212
332
  });
@@ -219,7 +339,7 @@ export function startBackgroundSessionServer(opts) {
219
339
  answer: answer ?? result,
220
340
  error,
221
341
  });
222
- writeMessage(socket, {
342
+ send({
223
343
  type: "received",
224
344
  requestId: resolvedId,
225
345
  accepted:
@@ -232,7 +352,7 @@ export function startBackgroundSessionServer(opts) {
232
352
  : false,
233
353
  });
234
354
  } catch (err) {
235
- writeMessage(socket, {
355
+ send({
236
356
  type: "error",
237
357
  message: err?.message || String(err),
238
358
  });
@@ -240,7 +360,7 @@ export function startBackgroundSessionServer(opts) {
240
360
  return;
241
361
  }
242
362
  default:
243
- writeMessage(socket, {
363
+ send({
244
364
  type: "error",
245
365
  message: `unknown message type: ${message.type}`,
246
366
  });
@@ -256,6 +376,7 @@ export function startBackgroundSessionServer(opts) {
256
376
 
257
377
  const drop = () => {
258
378
  clearTimeout(helloTimer);
379
+ writer.close();
259
380
  if (clients.delete(socket)) notifyClients();
260
381
  };
261
382
  socket.on("close", drop);
@@ -281,11 +402,11 @@ export function startBackgroundSessionServer(opts) {
281
402
  pipePath,
282
403
  clientCount: () => clients.size,
283
404
  broadcast: (message) => {
284
- for (const socket of clients) writeMessage(socket, message);
405
+ for (const writer of clients.values()) writer.write(message);
285
406
  },
286
407
  broadcastInteractionRequest: (intId, payload, binding = null) => {
287
- for (const socket of clients)
288
- writeMessage(socket, {
408
+ for (const writer of clients.values())
409
+ writer.write({
289
410
  type: "interaction_request",
290
411
  intId,
291
412
  requestId: intId,
@@ -302,7 +423,10 @@ export function startBackgroundSessionServer(opts) {
302
423
  },
303
424
  close: () =>
304
425
  new Promise((done) => {
305
- for (const socket of clients) socket.destroy();
426
+ for (const [socket, writer] of clients) {
427
+ writer.close();
428
+ socket.destroy();
429
+ }
306
430
  clients.clear();
307
431
  server.close(() => {
308
432
  if (process.platform !== "win32") {
@@ -341,6 +465,7 @@ export function connectBackgroundSession(opts) {
341
465
  return new Promise((resolve, reject) => {
342
466
  let settled = false;
343
467
  const socket = net.connect(pipePath);
468
+ const writer = createBoundedSocketWriter(socket);
344
469
  const timer = setTimeout(() => {
345
470
  if (!settled) {
346
471
  settled = true;
@@ -367,7 +492,7 @@ export function connectBackgroundSession(opts) {
367
492
  socket.unref?.();
368
493
  resolve({
369
494
  hello: message,
370
- send: (msg) => writeMessage(socket, msg),
495
+ send: (msg) => writer.write(msg),
371
496
  close: () => {
372
497
  // Best-effort graceful detach, then HARD destroy so the client
373
498
  // handle is released synchronously. `socket.end()` alone leaves
@@ -380,10 +505,11 @@ export function connectBackgroundSession(opts) {
380
505
  // the worker sees the socket close and finalizes the same as it
381
506
  // would on an explicit detach.
382
507
  try {
383
- writeMessage(socket, { type: "detach" });
508
+ writer.write({ type: "detach" });
384
509
  } catch {
385
510
  /* peer already gone */
386
511
  }
512
+ writer.close();
387
513
  socket.destroy();
388
514
  },
389
515
  });
@@ -398,7 +524,7 @@ export function connectBackgroundSession(opts) {
398
524
  }),
399
525
  );
400
526
  socket.on("connect", () => {
401
- writeMessage(socket, { type: "hello", token });
527
+ writer.write({ type: "hello", token });
402
528
  });
403
529
  socket.on("error", (error) => {
404
530
  if (!settled) {