chainlesschain 0.166.65 → 0.166.68

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 (198) hide show
  1. package/README.md +20 -12
  2. package/package.json +4 -4
  3. package/src/assets/web-panel/assets/{AIOps-Byz17CTN.js → AIOps-CXkSNOGY.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-C5LiW2-J.js → ActionButton-ysMR6gTs.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-D1INcvZF.js → Analytics-WGZ0sWuw.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-DZzHO1VV.js → AppLayout-Cs2iRlQG.js} +4 -4
  7. package/src/assets/web-panel/assets/{Artifacts-WfYQL6Ia.js → Artifacts-5IdfxWz0.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-DohBoGWO.js → Audit-U9V434QX.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-Chtk-Hde.js → BackgroundAgents-BvFwxPlC.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-B813PuMz.js → Backup-C9yTr9hO.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-DaDdWWgK.js → BaseInput-BdsSwUgE.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-D4pJ6oZ7.js → Chat-BB_2oBgH.js} +5 -5
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-Bpf1hDUl.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-Clo9TvO6.js → Checkbox-v6M5m7dK.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-uejLg8Ih.js → Codegen-CtouWSIz.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-B7nbx-iJ.js → Col-CqQJ4ORW.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-FEyjPK1j.js → Community-BO__QCOy.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-B6Fk0Kn6.js → Compact-D0Kq4xlH.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-BQG8goUl.js → Compliance-BSLKKBjA.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-CbBeEfHp.js → Cowork-VsujXW5o.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-DPzlFcEZ.js → Cron-j8DbLGi5.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-B8pWJrbg.js → Crosschain-DWpYH1yN.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-gGQHUlFN.js → DID-mLaRxLQh.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-C2TMFHrn.js → Dashboard-Cff033Jr.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-BVPxGbll.js → Dropdown-B1Upt6fP.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-CNPxs0hd.js → EmailListRenderer-CPtb8joV.js} +1 -1
  27. package/src/assets/web-panel/assets/{EvolutionSettings-_XTiB7q1.js → EvolutionSettings-CVh4Uv4g.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-UyE3VWtI.js → FamilyGuardDashboard-CrD1PhbF.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-CLt6FHK-.js → Federation-ftxrvqW5.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-CdNQPRPw.js → FormItemContext-9O80slC1.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-BJ0AMhrh.js → GenericCardRenderer-DaYvYIj9.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-CQnvMfOM.js → Git-BKZh0YE5.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-deYsHC-o.js → Governance-vWbN873j.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-qaSck43z.js → Inference-BN6RR-l8.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-De0aJ3Ls.js → KnowledgeGraph-x49x9m7Q.js} +1 -1
  36. package/src/assets/web-panel/assets/Logs-Co2EPLsJ.js +2 -0
  37. package/src/assets/web-panel/assets/MarkdownRenderer-D7wIB-c7.js +1 -0
  38. package/src/assets/web-panel/assets/{Marketplace-Byz3xCBN.js → Marketplace-DpPu6XQp.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-DOZUUW6z.js → McpTools-BR0ksiax.js} +3 -3
  40. package/src/assets/web-panel/assets/{Memory-C33wC2hA.js → Memory-BXznJ5-C.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-zZe-T_6M.js → MobileBridge-BHSOpfv7.js} +1 -1
  42. package/src/assets/web-panel/assets/{MobileProjects-CRnUIume.js → MobileProjects-DdWmgIup.js} +1 -1
  43. package/src/assets/web-panel/assets/{Mtc-C1xlRVAN.js → Mtc-D9Rk_IGT.js} +5 -5
  44. package/src/assets/web-panel/assets/{MtcAudit-D0U07bIi.js → MtcAudit--i8q1lKc.js} +2 -2
  45. package/src/assets/web-panel/assets/{Multisig-DF8uvV3h.js → Multisig-BHnNG7R9.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-bBPGAFlt.js → NLProgramming-Duo1ij2_.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-BHAaOsgg.js → Notes-B44Le73p.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-Cl0fG_rA.js → NotificationSettings-C3oy_7Gf.js} +1 -1
  49. package/src/assets/web-panel/assets/{OrderTableRenderer-BEPAs8Zv.js → OrderTableRenderer-Da_73SI5.js} +1 -1
  50. package/src/assets/web-panel/assets/{Organization-BAxSwgk5.js → Organization-ChsSwKxT.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-D68KubAu.js → Overflow-DR5G_cCn.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-bhdT17zk.js → P2P-yfaobqow.js} +2 -2
  53. package/src/assets/web-panel/assets/PdhVaultBrowser-DgimH6Jp.js +7 -0
  54. package/src/assets/web-panel/assets/{Permissions-Bq8fvkak.js → Permissions-DhinFvtE.js} +4 -4
  55. package/src/assets/web-panel/assets/{PersonalDataHub-BYd2JEic.js → PersonalDataHub-CfeNVic1.js} +5 -5
  56. package/src/assets/web-panel/assets/{Pipeline-Csg_ja69.js → Pipeline-CGKO26Nk.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-lwxwLj4M.js → Privacy-CxxfYEJh.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-BdBZkH8z.js → ProjectInit-CZsaAab9.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-ClWgFy-K.js → ProjectSettings-BUm_6clQ.js} +2 -2
  60. package/src/assets/web-panel/assets/{Projects-Bu-qj8N1.js → Projects-Capr8bVq.js} +1 -1
  61. package/src/assets/web-panel/assets/{Providers-DEjxrxw3.js → Providers-D28VqPja.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-eccy-8Vi.js → QrScannerModal-Cj200vUb.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-Vx3uDvFg.js → QuickAsk-BGpnEiam.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-CfUivNps.js → Recommend-Ix79Tpni.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-BU4gk7GI.js → RemoteSession-BdGAFbIk.js} +3 -3
  66. package/src/assets/web-panel/assets/{Reputation-CbPzdZ0C.js → Reputation-B1Lis0Wk.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-CYLrgfKA.js → Row-Ba_okwOW.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-DbY1oyuv.js → RssFeed-DDbEuI-m.js} +3 -3
  69. package/src/assets/web-panel/assets/{Search-QeW41K5r.js → Search-D89wAkMy.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-CJxf1kLZ.js → Security-CJKCKAU-.js} +3 -3
  71. package/src/assets/web-panel/assets/{Services-CFO9ySZc.js → Services-mitEc1XV.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-CQFjeQN0.js → Skeleton-CnBjLDfX.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-CLLB4INW.js → Skills-DSzDYvH3.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-DxeLIJk0.js → Sla-CglJ_4p3.js} +1 -1
  75. package/src/assets/web-panel/assets/SpeechSettings-BicWJS7f.js +1 -0
  76. package/src/assets/web-panel/assets/{SyncSettings-C6NOkcQK.js → SyncSettings-Cq7o6fmr.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-LmVPWDfQ.js → Tasks-DOxFOBpU.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-BdEfUoVB.js → Templates-bY0wSbQM.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-IUlESacN.js → Tenant-BAyyl0qX.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-B9pDe7sn.js → Terminal-BGBhSpqc.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-ZCwB-Pki.js → TimelineRenderer-BvW5lXYz.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-4qk16LX1.js → Tokens-Ua_LIx8-.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-jXNyargn.js → Trigger-BGwb2KL1.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-D13PydtT.js → Trust-CD2IEHvj.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-yPgws6mS.js → UkeySign-D5LetK6P.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-B329WjpG.js → VideoEditing-oP7ehFgR.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-T8VM-Ttm.js → Wallet-BBtu4-xa.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-XuRibrpP.js → WebAuthn-iSPRU4Ht.js} +5 -5
  89. package/src/assets/web-panel/assets/{WorkflowEditor-D1Gwz3YR.js → WorkflowEditor-DuEDhQmB.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-DjydtnT-.js → chat-DGDgqvvm.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-gFtBvPrr.js → colors-DGQMWa1-.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-CndxhGfx.js → compact-item-COVznBL4.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-DnfGpd0L.js → createContext-DIxVeHXI.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-CjR9h-Z_.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-CmT5hRVW.js → hasIn-DkxZO3E9.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-BGlmPbl_.js → index-0ToBFsvW.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BsRKmb6k.js → index-2JZizEPc.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-C14jryXi.js → index-BAL2p7YC.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-B0WFjxWs.js → index-BAlrovUm.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BlTcxT_L.js → index-BBw2MLIe.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DjcR-CwS.js → index-BHH95jcm.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DreYqebI.js → index-BOTshZNx.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DaEPE2DC.js → index-BQm7ntcn.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BNHdO6Jr.js → index-BUqwlzc8.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-C3HvYeA3.js → index-BY6MSbWT.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DUlubR4l.js → index-BY9Ossof.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Dbpk75MO.js → index-BgM-3a1w.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CqpR0Des.js → index-Bv0_u0ze.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DjY-3sMA.js → index-C3XeNS82.js} +3 -3
  110. package/src/assets/web-panel/assets/{index-DV6NrfJx.js → index-C3bN6751.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DuAvYTmY.js → index-CNRRrP3-.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BW3nWiu0.js → index-CV0KnNqR.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CZLDbPTa.js → index-CcNGQWum.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-D5na0B7G.js → index-Ci34vbh0.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DoBKSzqu.js → index-ClQVcrFt.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CuOx4Pbe.js → index-Cligb-Dl.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CgMKElUh.js → index-CokrhbY2.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BFif4Cev.js → index-CpZxDiVK.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-HHP1zzo7.js → index-CyMHF2Bi.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-_-wGLtAg.js → index-DDwPBGdA.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-ktN-K1Tf.js → index-DU1ArKl5.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-C4Mqhmas.js → index-DV0H83eS.js} +1 -1
  123. package/src/assets/web-panel/assets/index-D_nxBMX5.js +1 -0
  124. package/src/assets/web-panel/assets/{index-BXNUTiW8.js → index-DaWQSp5a.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DKyuE_Y2.js → index-DmduvOYT.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DV2PR3Fa.js → index-ECoDhyH3.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BVM_w30N.js → index-ZcqTvPnt.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CRqz8TtI.js → index-b2_M6o20.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CB27echm.js → index-b_0qTo8O.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-D88-8bsB.js → index-dfYkGovV.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DGbKeg8G.js → index-jo7DbU0w.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-D2d7358Y.js → index-usmG13jq.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-zQf599Uq.js → index-vXrktF3e.js} +1 -1
  134. package/src/assets/web-panel/assets/index-z_cTUMX-.js +1 -0
  135. package/src/assets/web-panel/assets/{initDefaultProps-KV3V-PNH.js → initDefaultProps-CkSeiBwL.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-PFGQg7_X.js → motion-CSzhDP0s.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-Dnl79wq4.js → move-mgCt4iC6.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-Bwl5JH9V.js → mtc-parser-BEZBLcKt.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-DCcTtM1l.js → omit-BsHctMEr.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-Cl6BjjDf.js → pickAttrs-1BHamnGW.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-fdqhyo42.js → placementArrow--Vb4Bd7l.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-DYQpmcDW.js → responsiveObserve-DD33SqCm.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-C4l-VfO4.js → slide-DfrLtxgK.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-DYDw_dyZ.js → statusUtils-D9Pe_gXW.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-BEsubSMu.js → styleChecker-0NY5iMun.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-Cj82ggQ_.js → useFlexGapSupport-DSsZstwg.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-B7L1eJ0V.js → useFs-BU8HyH59.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-DVlJVD4d.js → usePersonalDataHub-D_xttink.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-BBAbRN_Y.js → vnode-39VhX2lM.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-BYn48q-I.js → zoom-D5KQ8Pks.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/data/changelog.json +20 -7
  153. package/src/lib/dependency-install-policy.js +1 -1
  154. package/src/lib/evolution/browser-download-action-authority.js +747 -0
  155. package/src/lib/evolution/browser-download-artifact-disposal-authority.js +436 -0
  156. package/src/lib/evolution/browser-filesystem-quarantine-custody.js +2453 -0
  157. package/src/lib/evolution/browser-filesystem-quarantine-disposal.js +36 -0
  158. package/src/lib/evolution/browser-keyboard-action-authority.js +560 -0
  159. package/src/lib/evolution/browser-navigation-action-authority.js +546 -0
  160. package/src/lib/evolution/browser-quarantine-lock-maintenance-authority.js +573 -0
  161. package/src/lib/evolution/browser-quarantine-operator-revocation-authority.js +442 -0
  162. package/src/lib/evolution/browser-quarantine-retention-authority.js +503 -0
  163. package/src/lib/evolution/browser-quarantine-retention-scheduler.js +207 -0
  164. package/src/lib/evolution/browser-quarantined-download-executor.js +525 -0
  165. package/src/lib/evolution/browser-tab-open-action-authority.js +491 -0
  166. package/src/lib/evolution/browser-vision-action-authority.js +444 -0
  167. package/src/lib/evolution/browser-vision-observation-authority.js +304 -0
  168. package/src/lib/evolution/evolution-deployment-loader.js +202 -1
  169. package/src/lib/evolution/evolution-eval-child-evidence-ledger-adapter.js +5 -0
  170. package/src/lib/evolution/evolution-eval-gate.js +2 -1
  171. package/src/lib/evolution/evolution-eval-process-supervisor-worker.mjs +71 -9
  172. package/src/lib/evolution/evolution-eval-process-supervisor.js +276 -9
  173. package/src/lib/evolution/evolution-workbench-metrics.js +81 -21
  174. package/src/lib/evolution/pm-exploration-benchmark.js +747 -0
  175. package/src/lib/evolution/pm-exploration-budget-executor.js +106 -9
  176. package/src/lib/evolution/pm-exploration-egress-authority.js +382 -0
  177. package/src/lib/evolution/pm-exploration-evidence-bundle.js +149 -44
  178. package/src/lib/evolution/pm-exploration-execution-host.js +1254 -8
  179. package/src/lib/evolution/pm-exploration-process-grader.js +458 -0
  180. package/src/lib/evolution/pm-exploration-process-reviewer.js +456 -0
  181. package/src/lib/evolution/pm-exploration-process-runner.js +500 -0
  182. package/src/lib/evolution/pm-exploration-receipts.js +211 -11
  183. package/src/lib/evolution/pm-exploration-recovery-snapshot-store.js +465 -46
  184. package/src/lib/evolution/pm-exploration-transition-committer.js +185 -34
  185. package/src/lib/evolution/skill-outcome-index-authority.js +7 -3
  186. package/src/lib/governance-coverage.js +1 -1
  187. package/src/lib/headless-manifest.js +1 -1
  188. package/src/lib/protocol-replay.js +1 -1
  189. package/src/lib/skill-outcome-transcript-authority.js +45 -5
  190. package/src/runtime/agent-core.js +17 -0
  191. package/src/assets/web-panel/assets/ChatBubbleRenderer-Cf3LLgDc.js +0 -1
  192. package/src/assets/web-panel/assets/Logs-ZtS98jCm.js +0 -2
  193. package/src/assets/web-panel/assets/MarkdownRenderer-CTsYo9NN.js +0 -1
  194. package/src/assets/web-panel/assets/PdhVaultBrowser-DqaO6wgH.js +0 -7
  195. package/src/assets/web-panel/assets/SpeechSettings-D4FA9KYI.js +0 -1
  196. package/src/assets/web-panel/assets/devWarning-D60SbiD-.js +0 -1
  197. package/src/assets/web-panel/assets/index-C0yR4_7h.js +0 -1
  198. package/src/assets/web-panel/assets/index-D4xuvo03.js +0 -1
@@ -0,0 +1,36 @@
1
+ import { types } from "node:util";
2
+
3
+ import { createBrowserDownloadArtifactDisposalAuthority } from "./browser-download-artifact-disposal-authority.js";
4
+ import { captureBrowserFilesystemQuarantineCustody } from "./browser-filesystem-quarantine-custody.js";
5
+
6
+ function exact(value, keys, label) {
7
+ if (
8
+ !value ||
9
+ typeof value !== "object" ||
10
+ Array.isArray(value) ||
11
+ types.isProxy(value) ||
12
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value)) ||
13
+ Reflect.ownKeys(value).length !== keys.length ||
14
+ keys.some((key) => {
15
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
16
+ return !descriptor?.enumerable || !("value" in descriptor);
17
+ })
18
+ )
19
+ throw new TypeError(`${label} has unexpected or accessor fields`);
20
+ }
21
+
22
+ export function createBrowserFilesystemQuarantineDisposalAuthority(options) {
23
+ exact(
24
+ options,
25
+ ["descriptor", "custody", "authorize", "now"],
26
+ "filesystem quarantine disposal composition",
27
+ );
28
+ const custody = captureBrowserFilesystemQuarantineCustody(options.custody);
29
+ const disposeArtifact = custody.bindDisposalAuthority(options.descriptor);
30
+ return createBrowserDownloadArtifactDisposalAuthority({
31
+ descriptor: options.descriptor,
32
+ authorize: options.authorize,
33
+ disposeArtifact,
34
+ now: options.now,
35
+ });
36
+ }
@@ -0,0 +1,560 @@
1
+ import { createHash } from "node:crypto";
2
+ import { types } from "node:util";
3
+
4
+ export const BROWSER_KEYBOARD_ACTION_AUTHORITY_DESCRIPTOR_SCHEMA =
5
+ "chainlesschain.browser-keyboard-action-authority-descriptor/v1";
6
+ export const BROWSER_KEYBOARD_ACTION_REQUEST_SCHEMA =
7
+ "chainlesschain.browser-keyboard-action-request/v1";
8
+ export const BROWSER_KEYBOARD_ACTION_RECEIPT_SCHEMA =
9
+ "chainlesschain.browser-keyboard-action-receipt/v1";
10
+ export const BROWSER_KEYBOARD_ACTION_OUTCOME_REQUEST_SCHEMA =
11
+ "chainlesschain.browser-keyboard-action-outcome-request/v1";
12
+ export const BROWSER_KEYBOARD_ACTION_OUTCOME_ACK_SCHEMA =
13
+ "chainlesschain.browser-keyboard-action-outcome-ack/v1";
14
+
15
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
16
+ const ID = /^[A-Za-z0-9._:-]{1,128}$/u;
17
+ const NAMED_KEYS = new Set([
18
+ "Backspace",
19
+ "Delete",
20
+ "End",
21
+ "Enter",
22
+ "Escape",
23
+ "Home",
24
+ "Insert",
25
+ "PageDown",
26
+ "PageUp",
27
+ "Space",
28
+ "Tab",
29
+ "ArrowDown",
30
+ "ArrowLeft",
31
+ "ArrowRight",
32
+ "ArrowUp",
33
+ ]);
34
+ const MODIFIER_ORDER = ["Control", "Alt", "Shift", "Meta"];
35
+ const RESERVED_BROWSER_SHORTCUTS = new Set([
36
+ "f5",
37
+ "alt+arrowleft",
38
+ "alt+arrowright",
39
+ "alt+d",
40
+ "alt+e",
41
+ "alt+f",
42
+ "alt+home",
43
+ "alt+f4",
44
+ "shift+escape",
45
+ ...Array.from({ length: 9 }, (_, index) => `control+${index + 1}`),
46
+ ...Array.from({ length: 9 }, (_, index) => `meta+${index + 1}`),
47
+ "control+f5",
48
+ "control+d",
49
+ "control+e",
50
+ "control+f",
51
+ "control+g",
52
+ "control+h",
53
+ "control+j",
54
+ "control+k",
55
+ "control+l",
56
+ "control+n",
57
+ "control+o",
58
+ "control+p",
59
+ "control+r",
60
+ "control+s",
61
+ "control+t",
62
+ "control+u",
63
+ "control+w",
64
+ "control+tab",
65
+ "control+pagedown",
66
+ "control+pageup",
67
+ "control+shift+a",
68
+ "control+shift+b",
69
+ "control+shift+delete",
70
+ "control+shift+escape",
71
+ "control+shift+g",
72
+ "control+shift+i",
73
+ "control+shift+j",
74
+ "control+shift+n",
75
+ "control+shift+o",
76
+ "control+shift+p",
77
+ "control+shift+q",
78
+ "control+shift+r",
79
+ "control+shift+t",
80
+ "control+shift+tab",
81
+ "control+shift+c",
82
+ "control+shift+w",
83
+ "control+shift+pagedown",
84
+ "control+shift+pageup",
85
+ "meta+d",
86
+ "meta+e",
87
+ "meta+f",
88
+ "meta+g",
89
+ "meta+h",
90
+ "meta+l",
91
+ "meta+n",
92
+ "meta+o",
93
+ "meta+p",
94
+ "meta+q",
95
+ "meta+r",
96
+ "meta+s",
97
+ "meta+t",
98
+ "meta+u",
99
+ "meta+w",
100
+ "meta+y",
101
+ "meta+tab",
102
+ "meta+pagedown",
103
+ "meta+pageup",
104
+ "alt+meta+i",
105
+ "alt+shift+meta+i",
106
+ "shift+meta+a",
107
+ "shift+meta+b",
108
+ "shift+meta+g",
109
+ "shift+meta+h",
110
+ "shift+meta+j",
111
+ "shift+meta+t",
112
+ "shift+meta+n",
113
+ "shift+meta+o",
114
+ "shift+meta+p",
115
+ "shift+meta+q",
116
+ "shift+meta+w",
117
+ ]);
118
+ const authorities = new WeakMap();
119
+
120
+ function canonical(value) {
121
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
122
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
123
+ return `{${Object.keys(value)
124
+ .sort()
125
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
126
+ .join(",")}}`;
127
+ }
128
+
129
+ function digest(domain, value) {
130
+ return `sha256:${createHash("sha256")
131
+ .update(`${domain}\0`)
132
+ .update(canonical(value))
133
+ .digest("hex")}`;
134
+ }
135
+
136
+ function exact(value, keys, label) {
137
+ if (
138
+ !value ||
139
+ typeof value !== "object" ||
140
+ Array.isArray(value) ||
141
+ types.isProxy(value) ||
142
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value)) ||
143
+ Reflect.ownKeys(value).length !== keys.length ||
144
+ keys.some((key) => {
145
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
146
+ return !descriptor?.enumerable || !("value" in descriptor);
147
+ })
148
+ ) {
149
+ throw new TypeError(`${label} has an invalid shape`);
150
+ }
151
+ }
152
+
153
+ function snapshotJson(value, label) {
154
+ let nodes = 0;
155
+ const visit = (entry, depth) => {
156
+ if (++nodes > 2048 || depth > 12)
157
+ throw new TypeError(`${label} exceeds its structure budget`);
158
+ if (
159
+ entry === null ||
160
+ typeof entry === "boolean" ||
161
+ (typeof entry === "number" && Number.isFinite(entry)) ||
162
+ typeof entry === "string"
163
+ )
164
+ return entry;
165
+ if (
166
+ !entry ||
167
+ typeof entry !== "object" ||
168
+ types.isProxy(entry) ||
169
+ ![Object.prototype, null, Array.prototype].includes(
170
+ Object.getPrototypeOf(entry),
171
+ )
172
+ )
173
+ throw new TypeError(`${label} must be finite plain JSON data`);
174
+ if (Array.isArray(entry))
175
+ return Object.freeze(entry.map((item) => visit(item, depth + 1)));
176
+ const output = {};
177
+ for (const key of Object.keys(entry)) {
178
+ const descriptor = Object.getOwnPropertyDescriptor(entry, key);
179
+ if (!descriptor?.enumerable || !("value" in descriptor))
180
+ throw new TypeError(`${label} must contain plain data`);
181
+ output[key] = visit(descriptor.value, depth + 1);
182
+ }
183
+ return Object.freeze(output);
184
+ };
185
+ const result = visit(value, 0);
186
+ if (Buffer.byteLength(canonical(result), "utf8") > 16 * 1024)
187
+ throw new TypeError(`${label} exceeds its byte budget`);
188
+ return result;
189
+ }
190
+
191
+ function key(value) {
192
+ if (
193
+ typeof value !== "string" ||
194
+ !(/^[A-Za-z0-9]$/u.test(value) || NAMED_KEYS.has(value))
195
+ )
196
+ throw new TypeError("browser keyboard action key is invalid");
197
+ return value;
198
+ }
199
+
200
+ function modifiers(value) {
201
+ if (!Array.isArray(value) || types.isProxy(value) || value.length > 4)
202
+ throw new TypeError("browser keyboard action modifiers are invalid");
203
+ const unique = new Set(value);
204
+ if (
205
+ unique.size !== value.length ||
206
+ value.some((entry) => !MODIFIER_ORDER.includes(entry))
207
+ )
208
+ throw new TypeError("browser keyboard action modifiers are invalid");
209
+ return Object.freeze(
210
+ MODIFIER_ORDER.filter((modifier) => unique.has(modifier)),
211
+ );
212
+ }
213
+
214
+ function normalizeDescriptor(value) {
215
+ exact(
216
+ value,
217
+ [
218
+ "schema",
219
+ "authorityId",
220
+ "tenantId",
221
+ "handlerArtifactDigest",
222
+ "policyRevision",
223
+ "maxGrantTtlMs",
224
+ "approvalMode",
225
+ "auditMode",
226
+ ],
227
+ "browser keyboard action authority descriptor",
228
+ );
229
+ if (
230
+ value.schema !== BROWSER_KEYBOARD_ACTION_AUTHORITY_DESCRIPTOR_SCHEMA ||
231
+ !ID.test(value.authorityId) ||
232
+ !ID.test(value.tenantId) ||
233
+ !DIGEST.test(value.handlerArtifactDigest) ||
234
+ !ID.test(value.policyRevision) ||
235
+ !Number.isSafeInteger(value.maxGrantTtlMs) ||
236
+ value.maxGrantTtlMs < 1 ||
237
+ value.maxGrantTtlMs > 30_000 ||
238
+ value.approvalMode !== "interactive" ||
239
+ value.auditMode !== "authenticated-durable-readback"
240
+ )
241
+ throw new TypeError("browser keyboard action descriptor is invalid");
242
+ return Object.freeze({ ...value });
243
+ }
244
+
245
+ function normalizeRequest(value) {
246
+ exact(
247
+ value,
248
+ [
249
+ "schema",
250
+ "requestId",
251
+ "targetId",
252
+ "operation",
253
+ "senderId",
254
+ "frameUrlDigest",
255
+ "key",
256
+ "modifiers",
257
+ "delay",
258
+ "inputDigest",
259
+ "authorization",
260
+ "requestedAt",
261
+ ],
262
+ "browser keyboard action request",
263
+ );
264
+ const normalizedKey = key(value.key);
265
+ const normalizedModifiers = modifiers(value.modifiers);
266
+ const shortcut = [...normalizedModifiers, normalizedKey]
267
+ .join("+")
268
+ .toLowerCase();
269
+ if (RESERVED_BROWSER_SHORTCUTS.has(shortcut))
270
+ throw new TypeError(
271
+ "browser keyboard action must not bypass a dedicated browser contract",
272
+ );
273
+ const inputCore = Object.freeze({
274
+ targetId: value.targetId,
275
+ operation: value.operation,
276
+ key: normalizedKey,
277
+ modifiers: normalizedModifiers,
278
+ delay: value.delay,
279
+ });
280
+ if (
281
+ value.schema !== BROWSER_KEYBOARD_ACTION_REQUEST_SCHEMA ||
282
+ !ID.test(value.requestId) ||
283
+ typeof value.targetId !== "string" ||
284
+ value.targetId.length < 1 ||
285
+ value.targetId.length > 512 ||
286
+ value.operation !== "key-press" ||
287
+ !Number.isSafeInteger(value.senderId) ||
288
+ value.senderId < 1 ||
289
+ !DIGEST.test(value.frameUrlDigest) ||
290
+ !Number.isSafeInteger(value.delay) ||
291
+ value.delay < 0 ||
292
+ value.delay > 5000 ||
293
+ value.inputDigest !==
294
+ digest("chainlesschain.browser-keyboard-action-input/v1", inputCore) ||
295
+ !Number.isFinite(Date.parse(value.requestedAt))
296
+ )
297
+ throw new TypeError("browser keyboard action request is invalid");
298
+ return Object.freeze({
299
+ ...value,
300
+ key: normalizedKey,
301
+ modifiers: normalizedModifiers,
302
+ authorization: snapshotJson(
303
+ value.authorization,
304
+ "browser keyboard action authorization",
305
+ ),
306
+ inputCore,
307
+ });
308
+ }
309
+
310
+ function normalizeDecision(value) {
311
+ if (!value || typeof value !== "object" || types.isProxy(value))
312
+ throw new TypeError("browser keyboard action decision is invalid");
313
+ if (value.decision === "deny") {
314
+ exact(
315
+ value,
316
+ Object.hasOwn(value, "reason") ? ["decision", "reason"] : ["decision"],
317
+ "browser keyboard action decision",
318
+ );
319
+ if (
320
+ value.reason !== undefined &&
321
+ (typeof value.reason !== "string" || value.reason.length > 512)
322
+ )
323
+ throw new TypeError("browser keyboard action denial reason is invalid");
324
+ return Object.freeze({ decision: "deny", reason: value.reason ?? null });
325
+ }
326
+ exact(
327
+ value,
328
+ ["decision", "approvalEvidenceRef", "validUntil"],
329
+ "browser keyboard action decision",
330
+ );
331
+ if (value.decision !== "allow")
332
+ throw new TypeError("browser keyboard action decision is invalid");
333
+ return Object.freeze({ ...value });
334
+ }
335
+
336
+ function requestEvidence(request) {
337
+ const core = {
338
+ schema: request.schema,
339
+ requestId: request.requestId,
340
+ targetId: request.targetId,
341
+ operation: request.operation,
342
+ senderId: request.senderId,
343
+ frameUrlDigest: request.frameUrlDigest,
344
+ keyDigest: digest("chainlesschain.browser-keyboard-action-key/v1", {
345
+ key: request.key,
346
+ modifiers: request.modifiers,
347
+ }),
348
+ delay: request.delay,
349
+ inputDigest: request.inputDigest,
350
+ authorizationDigest: digest(
351
+ "chainlesschain.browser-keyboard-action-authorization/v1",
352
+ request.authorization,
353
+ ),
354
+ requestedAt: request.requestedAt,
355
+ };
356
+ return Object.freeze({
357
+ ...core,
358
+ requestDigest: digest(BROWSER_KEYBOARD_ACTION_REQUEST_SCHEMA, core),
359
+ });
360
+ }
361
+
362
+ function normalizeOutcome(value) {
363
+ exact(
364
+ value,
365
+ [
366
+ "schema",
367
+ "actionReceiptDigest",
368
+ "requestDigest",
369
+ "targetId",
370
+ "operation",
371
+ "inputDigest",
372
+ "status",
373
+ "resultDigest",
374
+ "recordedAt",
375
+ ],
376
+ "browser keyboard action outcome request",
377
+ );
378
+ if (
379
+ value.schema !== BROWSER_KEYBOARD_ACTION_OUTCOME_REQUEST_SCHEMA ||
380
+ !DIGEST.test(value.actionReceiptDigest) ||
381
+ !DIGEST.test(value.requestDigest) ||
382
+ typeof value.targetId !== "string" ||
383
+ value.targetId.length < 1 ||
384
+ value.targetId.length > 512 ||
385
+ value.operation !== "key-press" ||
386
+ !DIGEST.test(value.inputDigest) ||
387
+ !["succeeded", "failed"].includes(value.status) ||
388
+ !DIGEST.test(value.resultDigest) ||
389
+ !Number.isFinite(Date.parse(value.recordedAt))
390
+ )
391
+ throw new TypeError("browser keyboard action outcome is invalid");
392
+ const core = Object.freeze({ ...value });
393
+ return Object.freeze({
394
+ ...core,
395
+ outcomeRequestDigest: digest(
396
+ BROWSER_KEYBOARD_ACTION_OUTCOME_REQUEST_SCHEMA,
397
+ core,
398
+ ),
399
+ });
400
+ }
401
+
402
+ function normalizeAck(value, descriptor, request) {
403
+ exact(
404
+ value,
405
+ [
406
+ "schema",
407
+ "authorityId",
408
+ "tenantId",
409
+ "handlerArtifactDigest",
410
+ "actionReceiptDigest",
411
+ "outcomeRequestDigest",
412
+ "auditEventDigest",
413
+ "durabilityReceiptDigest",
414
+ "authenticated",
415
+ "durable",
416
+ "readbackVerified",
417
+ "qualifiesForPromotion",
418
+ ],
419
+ "browser keyboard action outcome acknowledgement",
420
+ );
421
+ if (
422
+ value.schema !== BROWSER_KEYBOARD_ACTION_OUTCOME_ACK_SCHEMA ||
423
+ value.authorityId !== descriptor.authorityId ||
424
+ value.tenantId !== descriptor.tenantId ||
425
+ value.handlerArtifactDigest !== descriptor.handlerArtifactDigest ||
426
+ value.actionReceiptDigest !== request.actionReceiptDigest ||
427
+ value.outcomeRequestDigest !== request.outcomeRequestDigest ||
428
+ !DIGEST.test(value.auditEventDigest) ||
429
+ !DIGEST.test(value.durabilityReceiptDigest) ||
430
+ value.authenticated !== true ||
431
+ value.durable !== true ||
432
+ value.readbackVerified !== true ||
433
+ value.qualifiesForPromotion !== false
434
+ )
435
+ throw new Error("browser keyboard action acknowledgement is invalid");
436
+ return Object.freeze({ ...value });
437
+ }
438
+
439
+ export function createBrowserKeyboardActionAuthority({
440
+ descriptor,
441
+ authorize,
442
+ recordOutcome,
443
+ now = Date.now,
444
+ } = {}) {
445
+ const normalizedDescriptor = normalizeDescriptor(descriptor);
446
+ if (
447
+ typeof authorize !== "function" ||
448
+ types.isProxy(authorize) ||
449
+ typeof recordOutcome !== "function" ||
450
+ types.isProxy(recordOutcome) ||
451
+ typeof now !== "function" ||
452
+ types.isProxy(now)
453
+ )
454
+ throw new TypeError("browser keyboard action authority ports are invalid");
455
+ const authority = Object.freeze({});
456
+ authorities.set(authority, {
457
+ descriptor: normalizedDescriptor,
458
+ authorize,
459
+ recordOutcome,
460
+ now,
461
+ issued: new Map(),
462
+ });
463
+ return authority;
464
+ }
465
+
466
+ export function captureBrowserKeyboardActionAuthority(value) {
467
+ const captured = authorities.get(value);
468
+ if (!captured)
469
+ throw new TypeError(
470
+ "A branded browser keyboard action authority is required",
471
+ );
472
+ return Object.freeze({
473
+ descriptor: captured.descriptor,
474
+ authorizeAction: async (input) => {
475
+ const request = normalizeRequest(input);
476
+ const evidence = requestEvidence(request);
477
+ const decision = normalizeDecision(
478
+ await captured.authorize(
479
+ Object.freeze({ ...request, requestDigest: evidence.requestDigest }),
480
+ ),
481
+ );
482
+ if (decision.decision !== "allow") {
483
+ const error = new Error(
484
+ decision.reason ?? "Browser keyboard action was denied",
485
+ );
486
+ error.code = "BROWSER_KEYBOARD_ACTION_DENIED";
487
+ throw error;
488
+ }
489
+ const nowMs = captured.now();
490
+ const validUntilMs = Date.parse(decision.validUntil);
491
+ if (
492
+ typeof decision.approvalEvidenceRef !== "string" ||
493
+ decision.approvalEvidenceRef.length < 1 ||
494
+ decision.approvalEvidenceRef.length > 512 ||
495
+ !Number.isFinite(nowMs) ||
496
+ !Number.isFinite(validUntilMs) ||
497
+ validUntilMs <= nowMs ||
498
+ validUntilMs > nowMs + captured.descriptor.maxGrantTtlMs
499
+ )
500
+ throw new Error("Browser keyboard action decision is invalid");
501
+ const core = {
502
+ schema: BROWSER_KEYBOARD_ACTION_RECEIPT_SCHEMA,
503
+ authorityId: captured.descriptor.authorityId,
504
+ tenantId: captured.descriptor.tenantId,
505
+ policyRevision: captured.descriptor.policyRevision,
506
+ handlerArtifactDigest: captured.descriptor.handlerArtifactDigest,
507
+ approvalMode: captured.descriptor.approvalMode,
508
+ requestId: request.requestId,
509
+ targetId: request.targetId,
510
+ operation: request.operation,
511
+ senderId: request.senderId,
512
+ frameUrlDigest: request.frameUrlDigest,
513
+ keyDigest: evidence.keyDigest,
514
+ delay: request.delay,
515
+ inputDigest: request.inputDigest,
516
+ authorizationDigest: evidence.authorizationDigest,
517
+ requestDigest: evidence.requestDigest,
518
+ approvalEvidenceRef: decision.approvalEvidenceRef,
519
+ authorizedAt: new Date(nowMs).toISOString(),
520
+ validUntil: new Date(validUntilMs).toISOString(),
521
+ };
522
+ const receipt = Object.freeze({
523
+ ...core,
524
+ receiptDigest: digest(BROWSER_KEYBOARD_ACTION_RECEIPT_SCHEMA, core),
525
+ });
526
+ captured.issued.set(receipt.receiptDigest, {
527
+ requestDigest: receipt.requestDigest,
528
+ targetId: receipt.targetId,
529
+ operation: receipt.operation,
530
+ inputDigest: receipt.inputDigest,
531
+ outcomeRequestDigest: null,
532
+ });
533
+ return receipt;
534
+ },
535
+ recordActionOutcome: async (input) => {
536
+ const request = normalizeOutcome(input);
537
+ const issued = captured.issued.get(request.actionReceiptDigest);
538
+ if (
539
+ !issued ||
540
+ issued.requestDigest !== request.requestDigest ||
541
+ issued.targetId !== request.targetId ||
542
+ issued.operation !== request.operation ||
543
+ issued.inputDigest !== request.inputDigest ||
544
+ (issued.outcomeRequestDigest !== null &&
545
+ issued.outcomeRequestDigest !== request.outcomeRequestDigest)
546
+ )
547
+ throw new Error(
548
+ "browser keyboard action outcome differs from authorization",
549
+ );
550
+ issued.outcomeRequestDigest = request.outcomeRequestDigest;
551
+ const acknowledgement = normalizeAck(
552
+ await captured.recordOutcome(request),
553
+ captured.descriptor,
554
+ request,
555
+ );
556
+ captured.issued.delete(request.actionReceiptDigest);
557
+ return acknowledgement;
558
+ },
559
+ });
560
+ }