chainlesschain 0.166.10 → 0.166.14

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 (244) hide show
  1. package/README.md +33 -0
  2. package/bin/chainlesschain.js +5 -0
  3. package/package.json +4 -2
  4. package/src/assets/web-panel/assets/{AIOps-CLYBDAGv.js → AIOps-C8SyFhOo.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-CpeSttcu.js → ActionButton-Dup5gFK0.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-Ba1TNLG0.js → Analytics-8FyOWA7V.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-xBy8EOeg.js → AppLayout-DBzdU9dg.js} +3 -3
  8. package/src/assets/web-panel/assets/{Artifacts-CJ_3TFb8.js → Artifacts-C_0Z8gNy.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-DUATFCG3.js → Audit-Cf2a-58m.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-BRXYPIGp.js → BackgroundAgents-M7w-2zgB.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-D8auLx7y.js → Backup-CCTHQXoL.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-CBgdslQ3.js → BaseInput-DjXpeFwJ.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-B32LvAiE.js → Chat-cAvchsJU.js} +5 -5
  14. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CVfvAy-n.js → ChatBubbleRenderer-DvEvxlZv.js} +1 -1
  15. package/src/assets/web-panel/assets/{Checkbox-BwzBxOpC.js → Checkbox-DKs6qvOn.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-0U5vrg1H.js → Codegen-DlkA7b9X.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-dZ2i4aAj.js → Col-CkfdKhyJ.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-UVvpLr8c.js → Community-iNXMHzj6.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-BDNEb1Bd.js → Compact-DQxPEd09.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-BrzQPxyS.js → Compliance-CSKvMCjs.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-BbgGsu-9.js → Cowork-CkWqazpD.js} +2 -2
  22. package/src/assets/web-panel/assets/{Cron-G321XPhp.js → Cron-k6W8IzhB.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-CgLNUyMn.js → Crosschain-C8MS1OuY.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-BAfRj18q.js → DID-DJuCcgiQ.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-BNIxA4TK.js → Dashboard-LeThKzp3.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-BLAUmCAN.js → Dropdown-BvxwgpE4.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-CsnhTW22.js → EmailListRenderer-n3e_a1M3.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-zcQ7Ip1n.js → FamilyGuardDashboard-509W6W6v.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-KFwxodNU.js → Federation-xgZReQm0.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-3CYRLEHG.js → FormItemContext-jZOhKcQx.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-D3d9D8L9.js → GenericCardRenderer-Jo0ULzHv.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-BJ202nJY.js → Git-BsRcyWQP.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-ClnnXVQ-.js → Governance-JlpMYTAk.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-DNU-PTkc.js → Inference-CUEz872-.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-DJuinbuY.js → KnowledgeGraph-DgrvvEDU.js} +1 -1
  36. package/src/assets/web-panel/assets/{Logs-D4No-46s.js → Logs-Df-KY4U3.js} +2 -2
  37. package/src/assets/web-panel/assets/MarkdownRenderer-BEPDcSwz.js +1 -0
  38. package/src/assets/web-panel/assets/{Marketplace-Ba-KqRN3.js → Marketplace-kPZDTOeI.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-DVoxnPgE.js → McpTools-CRRzPqNX.js} +2 -2
  40. package/src/assets/web-panel/assets/{Memory-D_C8gzAZ.js → Memory-D6pNSkg9.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-DnzTPcDH.js → MobileBridge-g-pvtwRC.js} +1 -1
  42. package/src/assets/web-panel/assets/MobileProjects-Bzayfrfe.js +1 -0
  43. package/src/assets/web-panel/assets/{Mtc-CvEHmHId.js → Mtc-B7S3W-XL.js} +2 -2
  44. package/src/assets/web-panel/assets/{MtcAudit-VNJmWqmv.js → MtcAudit-B8OMEWVb.js} +2 -2
  45. package/src/assets/web-panel/assets/{Multisig-BO0x_Vsa.js → Multisig-CowRp7GH.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-CM2gI1UY.js → NLProgramming-BkQNyi4c.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-CMc1HsML.js → Notes-Cm7gtkKz.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-DGNmSKGM.js → NotificationSettings-CbPTVh9m.js} +1 -1
  49. package/src/assets/web-panel/assets/{OrderTableRenderer-Du-Kct3p.js → OrderTableRenderer-Dswi26mJ.js} +1 -1
  50. package/src/assets/web-panel/assets/{Organization-DRtRZjas.js → Organization-BkjQ9yy7.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-Dp4OeWsn.js → Overflow-DmRFXP7Y.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-DXMJVls8.js → P2P-DQE1toAu.js} +2 -2
  53. package/src/assets/web-panel/assets/PdhVaultBrowser-BujyoDRG.js +7 -0
  54. package/src/assets/web-panel/assets/{Permissions-D1Hbb51o.js → Permissions-xSjfOaiU.js} +4 -4
  55. package/src/assets/web-panel/assets/{PersonalDataHub-BridiDhr.js → PersonalDataHub-B9ICLqVP.js} +3 -3
  56. package/src/assets/web-panel/assets/{Pipeline-B4bUNCm1.js → Pipeline-CUNwyN9E.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-BTu_HEqK.js → Privacy-SOoCricX.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-SVtL2hnt.js → ProjectInit-CSaFul0F.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-B2Sh7JZ2.js → ProjectSettings-CueiB_oe.js} +2 -2
  60. package/src/assets/web-panel/assets/{Projects-BwU1xalW.js → Projects-BOeXvU7y.js} +1 -1
  61. package/src/assets/web-panel/assets/{Providers-BWdWQSDw.js → Providers-CTqf_31h.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-Brzc-Sxb.js → QrScannerModal-C8ZP31E9.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-DIBz7FCe.js → QuickAsk-CPgn4713.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-CZ8RriIJ.js → Recommend-8_e0zw0i.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-CM0KJQ3t.js → RemoteSession-iT7lbGqw.js} +3 -3
  66. package/src/assets/web-panel/assets/{Reputation-D_wo8H0O.js → Reputation-B4q9SUOz.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-D1G1fD7N.js → Row-CA_nASyL.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-dKCVtA0K.js → RssFeed-Cwb0E3yv.js} +2 -2
  69. package/src/assets/web-panel/assets/{Search-Be1D61xo.js → Search-D9iVsOxJ.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-IbNiR6OC.js → Security-DPLbYchG.js} +3 -3
  71. package/src/assets/web-panel/assets/{Services-nuHK8y8p.js → Services-DGMVL_LF.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-DnM5jdnC.js → Skeleton-B_6kym0D.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-DCTdoq_q.js → Skills-Ds6r0dXB.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-DlWun-Ui.js → Sla-BLHAbBhb.js} +1 -1
  75. package/src/assets/web-panel/assets/{SpeechSettings-C19kv2sd.js → SpeechSettings-CZuddd14.js} +1 -1
  76. package/src/assets/web-panel/assets/{SyncSettings-CkQIR_Hu.js → SyncSettings-CdBq7oSl.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-DdbqOEbs.js → Tasks-DfT60Nyl.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-B7GpIXeo.js → Templates-RLfsKy2V.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-ByEstFhY.js → Tenant-Cw8xCNLE.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-BKRVID1a.js → Terminal-BOUkNu4f.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-CNS3dHNv.js → TimelineRenderer-CgGZWaRm.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-BykqylCL.js → Tokens-CpwjVyir.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-ByNxq51W.js → Trigger-DL21H-eb.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-BlrFsdaS.js → Trust-B3ffFclW.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-Dg26A-sd.js → UkeySign-CkBeb5aI.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-C1wUxNn0.js → VideoEditing-U2iVaE3r.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-OphEUzI4.js → Wallet-CQk2wzYd.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-_8lL08hF.js → WebAuthn-DYIuIYzT.js} +5 -5
  89. package/src/assets/web-panel/assets/{WorkflowEditor-BnTuIvnP.js → WorkflowEditor-tg1c2mZQ.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-3N3VLQYr.js → chat-CtL61spq.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-Bo_G96gg.js → colors-DKpbeo8s.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-DjubfjI_.js → compact-item-gPZsrswt.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-Cx_HSLCk.js → createContext-CfHlwzVr.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-DdqnMhzi.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-D5OjAOlA.js → hasIn-MV47g_6X.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-x7o-2T3S.js → index-6G0ETFTW.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CqZq3zWr.js → index-BBw52sEl.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-C-4sfa0l.js → index-BN-wxSQ8.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-uAcJUJkx.js → index-BOyGUuBE.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CC7RnaPP.js → index-BQp5M0s1.js} +1 -1
  101. package/src/assets/web-panel/assets/index-BcK8o4ke.js +1 -0
  102. package/src/assets/web-panel/assets/{index-CNmsP0Xf.js → index-BjlPD7GO.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CVPDhmVH.js → index-C4lF-f_z.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CRKk1JPX.js → index-C6nC_DyY.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-B905-Mcs.js → index-C9RF4ieu.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-3_CEBEEf.js → index-C9gtY4nG.js} +3 -3
  107. package/src/assets/web-panel/assets/{index-Y-H7j25u.js → index-CB1HnbNK.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-C5IwN9q3.js → index-CRv_uMLV.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Q_vn0t8d.js → index-C_B9LiKs.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Cz5tQ5PY.js → index-Cjv0kKCU.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BgPb37tI.js → index-CmM9jqwe.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-Dbdr8tVi.js → index-CmPJpLoD.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DrVjatPe.js → index-CzfxTSPW.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-C-_Cy0k_.js → index-D1XB5-t5.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-C8dPFFhy.js → index-DGtEBodr.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-UnpsQ6A0.js → index-DIeJmlAA.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BxgIE4PD.js → index-DMMvlLp9.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DlcbE0sX.js → index-DU4rZpiK.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-EZr3bvz2.js → index-D_Pl1GnW.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BScGr1BY.js → index-Dd19vRwy.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-Ce8EWU6r.js → index-Ddcpj1El.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CCjq3g32.js → index-Df9sWKpl.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-ydnEPOzZ.js → index-DfLyHCWi.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-C4MAnkl5.js → index-DnZ_zS1M.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DXJqa1-I.js → index-DsH-i_3d.js} +1 -1
  126. package/src/assets/web-panel/assets/index-DvbAjyYI.js +1 -0
  127. package/src/assets/web-panel/assets/{index-DBvZhdCb.js → index-ExAGPAnX.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DD1zSPZH.js → index-Rb7CRMw9.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DE4XtzMl.js → index-Zvkt9xqi.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CmLwI-Y8.js → index-bSFrAszw.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-HioDjvUF.js → index-fYcS7NS0.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BvYo09C0.js → index-srBc9U_s.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-Bj7S5IJw.js → index-xUlgG0Xe.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-DaU60K3A.js → index-yxxXlqBA.js} +1 -1
  135. package/src/assets/web-panel/assets/{initDefaultProps-DurpENJY.js → initDefaultProps-BeOZoSZ4.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-CIh-z-gR.js → motion-BXE8VMKx.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-Uc_yI2NA.js → move-I9sdvPGX.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-DUevj5wz.js → mtc-parser-d25zrJd0.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-85eMYyur.js → omit-D71V_T4e.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-AuxDD20F.js → pickAttrs-BNZKpIAR.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-DOWn8dd1.js → placementArrow-jOcgxTTz.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-CPxTWodH.js → responsiveObserve-pta_O8AU.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-BqvbGPjx.js → slide-Dlq6om7z.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-BzXKkV8d.js → statusUtils-BnkO_yRv.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-B2O7yRk3.js → styleChecker-p8NfWmcG.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-DRWp7px1.js → useFlexGapSupport-KcjZZ5U7.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-Dp0V7sjM.js → useFs-gqonDMWB.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-CyCrG3ql.js → usePersonalDataHub-jIIfE4go.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-CXhoFpFo.js → vnode-Dyo7fBrM.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-0z3mtwEg.js → zoom-6l8BMg9W.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/command-help-index.json +5 -5
  153. package/src/commands/agent.js +76 -23
  154. package/src/commands/compact.js +349 -3
  155. package/src/commands/context.js +72 -1
  156. package/src/commands/graph.js +26 -15
  157. package/src/commands/hmemory.js +21 -0
  158. package/src/commands/hook.js +256 -28
  159. package/src/commands/memory.js +209 -42
  160. package/src/commands/promcomp.js +17 -0
  161. package/src/commands/record-replay.js +772 -0
  162. package/src/commands/serve.js +94 -10
  163. package/src/commands/session.js +2 -3
  164. package/src/commands/skill.js +3 -0
  165. package/src/commands/team.js +7 -1
  166. package/src/data/changelog.json +41 -2
  167. package/src/gateways/ws/session-core-protocol.js +62 -3
  168. package/src/gateways/ws/session-protocol.js +123 -15
  169. package/src/gateways/ws/ws-agent-handler.js +157 -9
  170. package/src/gateways/ws/ws-session-gateway.js +204 -30
  171. package/src/generated/cc-agent-protocol.schema.json +2094 -4
  172. package/src/harness/prompt-compressor.js +5 -55
  173. package/src/lib/agent-sandbox.js +8 -2
  174. package/src/lib/agent-team/team-distributed-graph-bridge.js +3 -3
  175. package/src/lib/agent-team/team-message-tools.js +23 -5
  176. package/src/lib/app-server/context-memory-notifications.js +54 -0
  177. package/src/lib/app-server/rollout-store-factory.js +115 -0
  178. package/src/lib/app-server/rollout-store.js +310 -23
  179. package/src/lib/app-server/server.js +184 -7
  180. package/src/lib/app-server/sqlite-rollout-store.js +59 -16
  181. package/src/lib/auto-mode-config.js +26 -0
  182. package/src/lib/causal-observability.js +13 -1
  183. package/src/lib/context-memory-kernel/authority.js +95 -0
  184. package/src/lib/context-memory-kernel/durable-memory-port.js +296 -0
  185. package/src/lib/context-memory-kernel/index.js +8 -0
  186. package/src/lib/context-memory-kernel/jsonl-session-context-port.js +232 -0
  187. package/src/lib/context-memory-kernel/live-compaction.js +375 -0
  188. package/src/lib/context-memory-kernel/memory-service.js +667 -0
  189. package/src/lib/context-memory-kernel/message-adapter.js +451 -0
  190. package/src/lib/context-memory-kernel/privacy-purge-port.js +244 -0
  191. package/src/lib/context-memory-kernel/provider-context.js +192 -0
  192. package/src/lib/context-memory-kernel/runtime.js +61 -0
  193. package/src/lib/direct-model-usage.js +22 -18
  194. package/src/lib/graph-kernel/cutover-authority-resolver.js +4 -5
  195. package/src/lib/graph-kernel/cutover-ledger.js +2 -2
  196. package/src/lib/graph-kernel/event-store.js +3 -5
  197. package/src/lib/graph-kernel/migration-saga.js +2 -2
  198. package/src/lib/graph-kernel/production-cutover-evidence.js +8 -1
  199. package/src/lib/hierarchical-memory.js +22 -0
  200. package/src/lib/hook-audit-store.js +170 -0
  201. package/src/lib/hook-event-bus.cjs +0 -0
  202. package/src/lib/hook-manager.js +25 -83
  203. package/src/lib/hook-runtime-adapters.js +233 -0
  204. package/src/lib/hook-runtime-contract.cjs +291 -0
  205. package/src/lib/hook-runtime-contract.js +21 -0
  206. package/src/lib/hook-trust.js +210 -0
  207. package/src/lib/hooks-v2-producers.js +52 -6
  208. package/src/lib/hooks-v2-runtime.js +443 -178
  209. package/src/lib/llm-pricing.js +10 -0
  210. package/src/lib/memory-manager.js +29 -4
  211. package/src/lib/model-context-window.js +52 -0
  212. package/src/lib/permanent-memory.js +17 -0
  213. package/src/lib/plan-mode.js +8 -4
  214. package/src/lib/process-execution-broker/credential-transport.js +31 -0
  215. package/src/lib/process-execution-broker/index.js +282 -16
  216. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  217. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  218. package/src/lib/process-execution-broker/windows-sandbox.cs +7 -3
  219. package/src/lib/record-replay/browser-target-policy.js +406 -0
  220. package/src/lib/record-replay/index.js +4 -0
  221. package/src/lib/record-replay/playwright-ui-driver.js +83 -20
  222. package/src/lib/record-replay/playwright-ui-recorder.js +611 -0
  223. package/src/lib/record-replay/recorded-skill-package.js +486 -0
  224. package/src/lib/record-replay/recorded-skill-store.js +1166 -0
  225. package/src/lib/record-replay/skill-recorder.js +634 -64
  226. package/src/lib/runtime-usage-ledger.js +20 -0
  227. package/src/lib/session-consolidator.js +59 -0
  228. package/src/lib/session-core-singletons.js +17 -4
  229. package/src/lib/session-hooks.js +29 -2
  230. package/src/lib/session-transcript-migration.js +188 -0
  231. package/src/lib/settings-hook-events.cjs +37 -401
  232. package/src/lib/settings-hook-events.js +210 -8
  233. package/src/lib/settings-hooks.cjs +42 -83
  234. package/src/lib/ws-session-manager.js +4 -1
  235. package/src/repl/agent-repl.js +186 -53
  236. package/src/runtime/agent-core.js +376 -350
  237. package/src/runtime/headless-runner.js +112 -84
  238. package/src/runtime/headless-stream.js +131 -30
  239. package/src/assets/web-panel/assets/MarkdownRenderer-Dt8hH_qA.js +0 -1
  240. package/src/assets/web-panel/assets/MobileProjects-Jg2dVUc-.js +0 -1
  241. package/src/assets/web-panel/assets/PdhVaultBrowser-0jYeVmyY.js +0 -7
  242. package/src/assets/web-panel/assets/devWarning-BX944k9E.js +0 -1
  243. package/src/assets/web-panel/assets/index-C_9Jt_SR.js +0 -1
  244. package/src/assets/web-panel/assets/index-DL2EFx7m.js +0 -1
@@ -0,0 +1,406 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ const MAX_HTML_CHARS = 1_000_000;
4
+ const MAX_ALLOWED_ORIGINS = 8;
5
+ const MAX_URL_CHARS = 4_096;
6
+ const MAX_STORAGE_STATE_BYTES = 2 * 1024 * 1024;
7
+ const MAX_STORAGE_STATE_DEPTH = 16;
8
+ const MAX_STORAGE_STATE_NODES = 10_000;
9
+ const SHA256_PATTERN = /^sha256:[a-f0-9]{64}$/u;
10
+
11
+ function targetError(code, message) {
12
+ const error = new Error(message);
13
+ error.name = "RecordedSkillBrowserTargetError";
14
+ error.code = code;
15
+ return error;
16
+ }
17
+
18
+ function canonicalValue(value) {
19
+ if (Array.isArray(value)) return value.map(canonicalValue);
20
+ if (!value || typeof value !== "object") return value;
21
+ return Object.fromEntries(
22
+ Object.keys(value)
23
+ .sort()
24
+ .map((key) => [key, canonicalValue(value[key])]),
25
+ );
26
+ }
27
+
28
+ function deepFreeze(value) {
29
+ if (!value || typeof value !== "object" || Object.isFrozen(value))
30
+ return value;
31
+ for (const child of Object.values(value)) deepFreeze(child);
32
+ return Object.freeze(value);
33
+ }
34
+
35
+ function boundedCanonicalStorageState(value) {
36
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
37
+ throw targetError(
38
+ "CC_RECORD_TARGET_INVALID",
39
+ "browser storage state must be a JSON object",
40
+ );
41
+ }
42
+ const seen = new WeakSet();
43
+ const pending = [{ value, depth: 0 }];
44
+ let nodes = 0;
45
+ while (pending.length > 0) {
46
+ const current = pending.pop();
47
+ const item = current.value;
48
+ nodes += 1;
49
+ if (
50
+ nodes > MAX_STORAGE_STATE_NODES ||
51
+ current.depth > MAX_STORAGE_STATE_DEPTH
52
+ ) {
53
+ throw targetError(
54
+ "CC_RECORD_TARGET_INVALID",
55
+ "browser storage state exceeds its structural limits",
56
+ );
57
+ }
58
+ if (!item || typeof item !== "object") {
59
+ if (
60
+ typeof item === "undefined" ||
61
+ typeof item === "bigint" ||
62
+ typeof item === "function" ||
63
+ typeof item === "symbol" ||
64
+ (typeof item === "number" && !Number.isFinite(item))
65
+ ) {
66
+ throw targetError(
67
+ "CC_RECORD_TARGET_INVALID",
68
+ "browser storage state must contain only JSON values",
69
+ );
70
+ }
71
+ continue;
72
+ }
73
+ if (seen.has(item)) {
74
+ throw targetError(
75
+ "CC_RECORD_TARGET_INVALID",
76
+ "browser storage state must not contain cycles or shared objects",
77
+ );
78
+ }
79
+ seen.add(item);
80
+ if (
81
+ !Array.isArray(item) &&
82
+ Object.getPrototypeOf(item) !== Object.prototype
83
+ ) {
84
+ throw targetError(
85
+ "CC_RECORD_TARGET_INVALID",
86
+ "browser storage state must contain plain JSON objects",
87
+ );
88
+ }
89
+ const children = Array.isArray(item) ? item : Object.values(item);
90
+ if (children.length > MAX_STORAGE_STATE_NODES) {
91
+ throw targetError(
92
+ "CC_RECORD_TARGET_INVALID",
93
+ "browser storage state exceeds its structural limits",
94
+ );
95
+ }
96
+ for (const child of children) {
97
+ pending.push({ value: child, depth: current.depth + 1 });
98
+ }
99
+ }
100
+ const canonical = canonicalValue(value);
101
+ if (
102
+ Buffer.byteLength(JSON.stringify(canonical), "utf8") >
103
+ MAX_STORAGE_STATE_BYTES
104
+ ) {
105
+ throw targetError(
106
+ "CC_RECORD_TARGET_INVALID",
107
+ "browser storage state exceeds the 2 MiB limit",
108
+ );
109
+ }
110
+ return deepFreeze(canonical);
111
+ }
112
+
113
+ function digest(value, domain) {
114
+ const bytes = Buffer.isBuffer(value)
115
+ ? value
116
+ : Buffer.from(
117
+ typeof value === "string"
118
+ ? value
119
+ : JSON.stringify(canonicalValue(value)),
120
+ );
121
+ return `sha256:${createHash("sha256")
122
+ .update(domain)
123
+ .update("\0")
124
+ .update(bytes)
125
+ .digest("hex")}`;
126
+ }
127
+
128
+ function isLoopback(hostname) {
129
+ const normalized = String(hostname || "").toLowerCase();
130
+ return (
131
+ normalized === "localhost" ||
132
+ normalized === "127.0.0.1" ||
133
+ normalized === "[::1]" ||
134
+ normalized === "::1"
135
+ );
136
+ }
137
+
138
+ function safeUrl(value, { originOnly = false } = {}) {
139
+ if (
140
+ typeof value !== "string" ||
141
+ value.length < 1 ||
142
+ value.length > MAX_URL_CHARS
143
+ ) {
144
+ throw targetError(
145
+ "CC_RECORD_TARGET_INVALID",
146
+ `browser target URL must be no longer than ${MAX_URL_CHARS} characters`,
147
+ );
148
+ }
149
+ let parsed;
150
+ try {
151
+ parsed = new URL(String(value));
152
+ } catch {
153
+ throw targetError(
154
+ "CC_RECORD_TARGET_INVALID",
155
+ "browser target must be an absolute URL",
156
+ );
157
+ }
158
+ if (
159
+ parsed.username ||
160
+ parsed.password ||
161
+ (parsed.protocol !== "https:" &&
162
+ !(parsed.protocol === "http:" && isLoopback(parsed.hostname)))
163
+ ) {
164
+ throw targetError(
165
+ "CC_RECORD_TARGET_INVALID",
166
+ "browser targets require HTTPS; HTTP is allowed only for loopback testing and URL credentials are forbidden",
167
+ );
168
+ }
169
+ if (originOnly && parsed.href !== `${parsed.origin}/`) {
170
+ throw targetError(
171
+ "CC_RECORD_TARGET_INVALID",
172
+ "allowed origins must not contain a path, query, or fragment",
173
+ );
174
+ }
175
+ return parsed;
176
+ }
177
+
178
+ export function createRecordedSkillNetworkPolicy({
179
+ mode = "deny",
180
+ allowedOrigins = [],
181
+ } = {}) {
182
+ if (mode === "deny") {
183
+ if (!Array.isArray(allowedOrigins) || allowedOrigins.length > 0) {
184
+ throw targetError(
185
+ "CC_RECORD_TARGET_INVALID",
186
+ "deny network policy cannot retain allowed origins",
187
+ );
188
+ }
189
+ const body = { mode: "deny", allowedOrigins: [] };
190
+ return deepFreeze({
191
+ ...body,
192
+ digest: digest(body, "cc.record-replay.network-policy/v1"),
193
+ });
194
+ }
195
+ if (mode !== "allowlist" || !Array.isArray(allowedOrigins)) {
196
+ throw targetError(
197
+ "CC_RECORD_TARGET_INVALID",
198
+ "browser network policy is invalid",
199
+ );
200
+ }
201
+ const origins = [
202
+ ...new Set(
203
+ allowedOrigins.map(
204
+ (value) => safeUrl(value, { originOnly: true }).origin,
205
+ ),
206
+ ),
207
+ ].sort();
208
+ if (origins.length < 1 || origins.length > MAX_ALLOWED_ORIGINS) {
209
+ throw targetError(
210
+ "CC_RECORD_TARGET_INVALID",
211
+ `browser target requires between 1 and ${MAX_ALLOWED_ORIGINS} allowed origins`,
212
+ );
213
+ }
214
+ const body = { mode: "allowlist", allowedOrigins: origins };
215
+ return deepFreeze({
216
+ ...body,
217
+ digest: digest(body, "cc.record-replay.network-policy/v1"),
218
+ });
219
+ }
220
+
221
+ export function digestRecordedSkillStorageState(storageState) {
222
+ if (storageState == null) return null;
223
+ return digest(
224
+ boundedCanonicalStorageState(storageState),
225
+ "cc.record-replay.browser-storage-state/v1",
226
+ );
227
+ }
228
+
229
+ export function prepareRecordedSkillBrowserTarget({
230
+ html,
231
+ url,
232
+ allowedOrigins = [],
233
+ storageState,
234
+ identity = "anonymous",
235
+ } = {}) {
236
+ const hasHtml = typeof html === "string" && html.length > 0;
237
+ const hasUrl = typeof url === "string" && url.length > 0;
238
+ if (hasHtml === hasUrl) {
239
+ throw targetError(
240
+ "CC_RECORD_TARGET_INVALID",
241
+ "provide exactly one self-contained HTML fixture or URL target",
242
+ );
243
+ }
244
+ const safeIdentity = String(identity || "anonymous").trim();
245
+ if (!/^[A-Za-z][A-Za-z0-9._-]{0,127}$/u.test(safeIdentity)) {
246
+ throw targetError(
247
+ "CC_RECORD_TARGET_INVALID",
248
+ "browser identity label is invalid",
249
+ );
250
+ }
251
+ if (hasHtml) {
252
+ if (
253
+ html.length > MAX_HTML_CHARS ||
254
+ allowedOrigins.length > 0 ||
255
+ storageState != null
256
+ ) {
257
+ throw targetError(
258
+ "CC_RECORD_TARGET_INVALID",
259
+ "self-contained HTML recording cannot use network origins or browser credentials",
260
+ );
261
+ }
262
+ const networkPolicy = createRecordedSkillNetworkPolicy({ mode: "deny" });
263
+ return deepFreeze({
264
+ adapter: "self-contained-html",
265
+ html,
266
+ url: null,
267
+ targetDigest: digest(html, "cc.record-replay.ui-fixture/v1"),
268
+ networkPolicy,
269
+ storageState: null,
270
+ storageStateDigest: null,
271
+ identity: safeIdentity,
272
+ });
273
+ }
274
+ const target = safeUrl(url);
275
+ const networkPolicy = createRecordedSkillNetworkPolicy({
276
+ mode: "allowlist",
277
+ allowedOrigins:
278
+ allowedOrigins.length > 0 ? allowedOrigins : [target.origin],
279
+ });
280
+ if (!networkPolicy.allowedOrigins.includes(target.origin)) {
281
+ throw targetError(
282
+ "CC_RECORD_TARGET_INVALID",
283
+ "target origin must be present in the network allowlist",
284
+ );
285
+ }
286
+ const normalizedStorageState =
287
+ storageState == null ? null : boundedCanonicalStorageState(storageState);
288
+ return deepFreeze({
289
+ adapter: "url-origin",
290
+ html: null,
291
+ url: target.href,
292
+ targetDigest: digest(target.href, "cc.record-replay.ui-url/v1"),
293
+ networkPolicy,
294
+ storageState: normalizedStorageState,
295
+ storageStateDigest: digestRecordedSkillStorageState(normalizedStorageState),
296
+ identity: safeIdentity,
297
+ });
298
+ }
299
+
300
+ export function recordedSkillBrowserEnvironment(target) {
301
+ if (
302
+ !target ||
303
+ !["self-contained-html", "url-origin"].includes(target.adapter) ||
304
+ !SHA256_PATTERN.test(String(target.targetDigest || ""))
305
+ ) {
306
+ throw targetError(
307
+ "CC_RECORD_TARGET_INVALID",
308
+ "prepared browser target is invalid",
309
+ );
310
+ }
311
+ return deepFreeze({
312
+ adapter: target.adapter,
313
+ browser: "chromium",
314
+ targetDigest: target.targetDigest,
315
+ selectorContract: "record-replay-dom-v1",
316
+ networkPolicy: Object.freeze({
317
+ mode: target.networkPolicy.mode,
318
+ allowedOrigins: Object.freeze([...target.networkPolicy.allowedOrigins]),
319
+ digest: target.networkPolicy.digest,
320
+ }),
321
+ identity: target.identity,
322
+ storageStateDigest: target.storageStateDigest,
323
+ });
324
+ }
325
+
326
+ export function assertRecordedSkillBrowserBinding(
327
+ target,
328
+ { source, environment } = {},
329
+ ) {
330
+ let reviewedPolicy;
331
+ try {
332
+ reviewedPolicy = createRecordedSkillNetworkPolicy({
333
+ mode: environment?.networkPolicy?.mode,
334
+ allowedOrigins: environment?.networkPolicy?.allowedOrigins || [],
335
+ });
336
+ } catch {
337
+ reviewedPolicy = null;
338
+ }
339
+ if (
340
+ !source ||
341
+ target?.adapter !== source.adapter ||
342
+ target?.targetDigest !== source.targetDigest ||
343
+ environment?.adapter !== source.adapter ||
344
+ environment?.targetDigest !== source.targetDigest
345
+ ) {
346
+ throw targetError(
347
+ "CC_RECORD_TARGET_DRIFT",
348
+ "browser target no longer matches the reviewed recording",
349
+ );
350
+ }
351
+ if (
352
+ (environment.storageStateDigest || null) !==
353
+ (target.storageStateDigest || null)
354
+ ) {
355
+ throw targetError(
356
+ "CC_RECORD_CREDENTIAL_DRIFT",
357
+ "browser storage state no longer matches the reviewed credential binding",
358
+ );
359
+ }
360
+ if (
361
+ environment.identity !== target.identity ||
362
+ reviewedPolicy?.digest !== environment.networkPolicy?.digest ||
363
+ reviewedPolicy?.digest !== target.networkPolicy?.digest
364
+ ) {
365
+ throw targetError(
366
+ "CC_RECORD_ENVIRONMENT_DRIFT",
367
+ "browser identity or network policy no longer matches the reviewed recording",
368
+ );
369
+ }
370
+ return true;
371
+ }
372
+
373
+ export function requestAllowedByRecordedSkillPolicy(rawUrl, target) {
374
+ let parsed;
375
+ try {
376
+ parsed = new URL(String(rawUrl));
377
+ } catch {
378
+ return false;
379
+ }
380
+ if (["about:", "data:"].includes(parsed.protocol)) return true;
381
+ if (parsed.protocol === "blob:") {
382
+ return (
383
+ target.networkPolicy.mode === "allowlist" &&
384
+ target.networkPolicy.allowedOrigins.includes(parsed.origin)
385
+ );
386
+ }
387
+ if (!["http:", "https:"].includes(parsed.protocol)) return false;
388
+ return (
389
+ target.networkPolicy.mode === "allowlist" &&
390
+ target.networkPolicy.allowedOrigins.includes(parsed.origin)
391
+ );
392
+ }
393
+
394
+ export function navigationAllowedByRecordedSkillPolicy(rawUrl, target) {
395
+ let parsed;
396
+ try {
397
+ parsed = new URL(String(rawUrl));
398
+ } catch {
399
+ return false;
400
+ }
401
+ return (
402
+ ["http:", "https:"].includes(parsed.protocol) &&
403
+ target.networkPolicy.mode === "allowlist" &&
404
+ target.networkPolicy.allowedOrigins.includes(parsed.origin)
405
+ );
406
+ }
@@ -1,2 +1,6 @@
1
1
  export * from "./skill-recorder.js";
2
2
  export * from "./playwright-ui-driver.js";
3
+ export * from "./playwright-ui-recorder.js";
4
+ export * from "./recorded-skill-store.js";
5
+ export * from "./recorded-skill-package.js";
6
+ export * from "./browser-target-policy.js";
@@ -1,4 +1,11 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { executionBroker } from "../process-execution-broker/index.js";
3
+ import {
4
+ createRecordedSkillNetworkPolicy,
5
+ navigationAllowedByRecordedSkillPolicy,
6
+ prepareRecordedSkillBrowserTarget,
7
+ requestAllowedByRecordedSkillPolicy,
8
+ } from "./browser-target-policy.js";
2
9
 
3
10
  const ACTION_CAPABILITIES = Object.freeze({
4
11
  observe: "ui.observe",
@@ -7,11 +14,7 @@ const ACTION_CAPABILITIES = Object.freeze({
7
14
  type: "ui.interact",
8
15
  select: "ui.interact",
9
16
  });
10
- const DRIVER_CAPABILITIES = Object.freeze([
11
- "ui.interact",
12
- "ui.observe",
13
- ]);
14
- const DENIED_SCHEMES = new Set(["file:", "http:", "https:", "ws:", "wss:"]);
17
+ const DRIVER_CAPABILITIES = Object.freeze(["ui.interact", "ui.observe"]);
15
18
 
16
19
  function driverError(code, message, details = {}) {
17
20
  const error = new Error(message);
@@ -68,11 +71,17 @@ function requestMetadata(request) {
68
71
  }
69
72
  return Object.freeze({
70
73
  scheme,
71
- method: String(request.method?.() || "GET").toUpperCase().slice(0, 16),
74
+ method: String(request.method?.() || "GET")
75
+ .toUpperCase()
76
+ .slice(0, 16),
72
77
  });
73
78
  }
74
79
 
75
- async function locatorState(locator, timeoutMs, { allowDetached = false } = {}) {
80
+ async function locatorState(
81
+ locator,
82
+ timeoutMs,
83
+ { allowDetached = false } = {},
84
+ ) {
76
85
  const count = await locator.count();
77
86
  if (count !== 1) {
78
87
  if (allowDetached && count === 0) {
@@ -136,12 +145,22 @@ async function assertAction(locator, action, timeoutMs) {
136
145
  */
137
146
  export async function launchPlaywrightRecordedSkillDriver({
138
147
  html,
148
+ url,
149
+ allowedOrigins = [],
150
+ storageState,
151
+ identity = "anonymous",
139
152
  playwright,
140
153
  timeoutMs = 5_000,
141
154
  settleMs = 25,
142
155
  viewport = { width: 960, height: 640 },
143
156
  } = {}) {
144
- const fixtureHtml = boundedString(html, "fixture html", 1_000_000);
157
+ const target = prepareRecordedSkillBrowserTarget({
158
+ html,
159
+ url,
160
+ allowedOrigins,
161
+ storageState,
162
+ identity,
163
+ });
145
164
  if (!Number.isInteger(timeoutMs) || timeoutMs < 100 || timeoutMs > 30_000) {
146
165
  throw driverError(
147
166
  "CC_REPLAY_UI_ARGUMENT_INVALID",
@@ -163,11 +182,23 @@ export async function launchPlaywrightRecordedSkillDriver({
163
182
  );
164
183
  }
165
184
 
166
- const browser = await runtime.chromium.launch({ headless: true });
185
+ const executablePath = runtime.chromium.executablePath?.();
186
+ const browser = executablePath
187
+ ? await executionBroker.runWithProcessContext(
188
+ {
189
+ origin: "record-replay:chromium-driver",
190
+ policy: "allow",
191
+ allowedCommands: [executablePath],
192
+ auditContext: { actor: "record-replay-driver" },
193
+ },
194
+ () => runtime.chromium.launch({ headless: true, executablePath }),
195
+ )
196
+ : await runtime.chromium.launch({ headless: true });
167
197
  const context = await browser.newContext({
168
198
  viewport: safeViewport,
169
199
  acceptDownloads: false,
170
200
  serviceWorkers: "block",
201
+ storageState: target.storageState || undefined,
171
202
  });
172
203
  const deniedRequests = [];
173
204
  const receipts = [];
@@ -175,19 +206,32 @@ export async function launchPlaywrightRecordedSkillDriver({
175
206
  try {
176
207
  await context.route("**/*", async (route) => {
177
208
  const metadata = requestMetadata(route.request());
178
- if (DENIED_SCHEMES.has(metadata.scheme)) {
209
+ if (!requestAllowedByRecordedSkillPolicy(route.request().url(), target)) {
179
210
  deniedRequests.push(metadata);
180
211
  await route.abort("blockedbyclient");
181
212
  return;
182
213
  }
183
214
  await route.continue();
184
215
  });
185
- await context.setOffline(true);
216
+ if (target.networkPolicy.mode === "deny") await context.setOffline(true);
186
217
  page = await context.newPage();
187
- await page.setContent(fixtureHtml, {
188
- waitUntil: "domcontentloaded",
189
- timeout: timeoutMs,
190
- });
218
+ if (target.adapter === "self-contained-html") {
219
+ await page.setContent(target.html, {
220
+ waitUntil: "domcontentloaded",
221
+ timeout: timeoutMs,
222
+ });
223
+ } else {
224
+ await page.goto(target.url, {
225
+ waitUntil: "domcontentloaded",
226
+ timeout: timeoutMs,
227
+ });
228
+ if (!navigationAllowedByRecordedSkillPolicy(page.url(), target)) {
229
+ throw driverError(
230
+ "CC_REPLAY_UI_NETWORK_ATTEMPT",
231
+ "recorded UI target redirected outside its reviewed origin policy",
232
+ );
233
+ }
234
+ }
191
235
  } catch {
192
236
  await browser.close();
193
237
  throw driverError(
@@ -199,18 +243,31 @@ export async function launchPlaywrightRecordedSkillDriver({
199
243
  await browser.close();
200
244
  throw driverError(
201
245
  "CC_REPLAY_UI_FIXTURE_NETWORKED",
202
- "recorded UI fixture attempted filesystem or network access while loading",
246
+ "recorded UI target attempted access outside its reviewed network policy while loading",
203
247
  { deniedRequestCount: deniedRequests.length },
204
248
  );
205
249
  }
206
250
 
207
251
  const executor = Object.freeze({
208
252
  capabilities: DRIVER_CAPABILITIES,
253
+ networkPolicyDigest: target.networkPolicy.digest,
209
254
  async execute(action, { isolation, capability } = {}) {
210
- if (isolation?.sandboxed !== true || isolation?.network !== "deny") {
255
+ let replayNetworkPolicy;
256
+ try {
257
+ replayNetworkPolicy = createRecordedSkillNetworkPolicy({
258
+ mode: isolation?.network,
259
+ allowedOrigins: isolation?.allowedOrigins || [],
260
+ });
261
+ } catch {
262
+ replayNetworkPolicy = null;
263
+ }
264
+ if (
265
+ isolation?.sandboxed !== true ||
266
+ replayNetworkPolicy?.digest !== target.networkPolicy.digest
267
+ ) {
211
268
  throw driverError(
212
269
  "CC_REPLAY_UI_ISOLATION_REQUIRED",
213
- "UI replay driver requires an ephemeral network-denied isolation",
270
+ "UI replay driver requires the exact reviewed browser network policy",
214
271
  );
215
272
  }
216
273
  const kind = String(action?.kind || "");
@@ -278,7 +335,7 @@ export async function launchPlaywrightRecordedSkillDriver({
278
335
  screenshot,
279
336
  "cc.record-replay.ui-screenshot/v1",
280
337
  ),
281
- networkPolicy: "deny",
338
+ networkPolicy: target.networkPolicy.mode,
282
339
  deniedRequestCount: 0,
283
340
  });
284
341
  receipts.push(evidence);
@@ -297,7 +354,13 @@ export async function launchPlaywrightRecordedSkillDriver({
297
354
  return Object.freeze({
298
355
  executor,
299
356
  browserVersion: String(browser.version?.() || "unknown").slice(0, 128),
300
- fixtureDigest: digest(fixtureHtml, "cc.record-replay.ui-fixture/v1"),
357
+ adapter: target.adapter,
358
+ targetDigest: target.targetDigest,
359
+ fixtureDigest:
360
+ target.adapter === "self-contained-html" ? target.targetDigest : null,
361
+ storageStateDigest: target.storageStateDigest,
362
+ identity: target.identity,
363
+ networkPolicy: target.networkPolicy,
301
364
  summary() {
302
365
  return Object.freeze({
303
366
  schema: "chainlesschain.recorded-skill-ui-driver-summary/v1",