chainlesschain 0.162.183 → 0.162.184

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 (196) 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-BapS7lz4.js → AIOps-DzAl5fGx.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-CXYdXEUI.js → ActionButton-DAHtMGeC.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-CKR5Lexn.js → Analytics-BHQaexv5.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-DATVUOXB.js → AppLayout-Phz_pD0n.js} +4 -4
  7. package/src/assets/web-panel/assets/{Artifacts-vb_0ZlV1.js → Artifacts-DHt47kCA.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-BI1l9GWt.js → Audit--Y_8FULl.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-BFXbaUEf.js → BackgroundAgents-N1zchH7D.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-DEYBJJ6H.js → Backup-B_BoyN30.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-COdzeO0M.js → BaseInput-Gl4uQHcT.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-oSN6sfM5.js → Chat-Cg-eIyAZ.js} +6 -6
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-BzeUi3JH.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-BezEa4tm.js → Checkbox-D0MGR2wA.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-CNEL0Ife.js → Codegen-BdObJEFn.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-Bf2Y2Bn1.js → Col--ghxXT3z.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-BfUlu4Hc.js → Community-BUFeXOqz.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-BN4xWP9e.js → Compact-DhQO2_Mr.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-Bt6BKmEP.js → Compliance-3HoTqKYd.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-DKLp8YxO.js → Cowork-B3zmO4VW.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-o7Hhw6ky.js → Cron-CJDrZOcc.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-DaNXWJIw.js → Crosschain-SMl15obd.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-B-Qa2mha.js → DID-CgTrTWrl.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-CMX0Qnxw.js → Dashboard-dXFKaKol.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-BLuLyRu_.js → Dropdown-qQHEhCvI.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-CFBAeMij.js → EmailListRenderer-C_ej0MWH.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DWzXQ67V.js → FamilyGuardDashboard-D6ajoE7I.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-DB1QSLgr.js → Federation-Cio2y49h.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-C-OKCToP.js → FormItemContext-ClJz1cYp.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-DMJFtFZf.js → GenericCardRenderer-Dr_8Maca.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-DsGSujOV.js → Git-CevLwp5u.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-B0iS9NEW.js → Governance-CW9YyQUY.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-CH004H7c.js → Inference-CQqeAyER.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-Q9MTQ83c.js → KnowledgeGraph-cuGVxHrw.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-B_fyjZK9.js → Logs-DIuHri5d.js} +2 -2
  36. package/src/assets/web-panel/assets/{MarkdownRenderer-C0o4FtpD.js → MarkdownRenderer-R91Qw5JA.js} +1 -1
  37. package/src/assets/web-panel/assets/{Marketplace-BIStF9d1.js → Marketplace-CY1VhFGx.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-pGfal768.js → McpTools-BBAbi1vt.js} +5 -5
  39. package/src/assets/web-panel/assets/{Memory-xbNqpIqB.js → Memory-BWYGHxJA.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-B5EQGrIK.js → MobileBridge-CPIFkW7A.js} +1 -1
  41. package/src/assets/web-panel/assets/MobileProjects-DQyWxCho.js +1 -0
  42. package/src/assets/web-panel/assets/{Mtc-a_rmfxJH.js → Mtc-Bo3GnQbx.js} +4 -4
  43. package/src/assets/web-panel/assets/{MtcAudit-BmKuofUr.js → MtcAudit-C8-c4rSW.js} +4 -4
  44. package/src/assets/web-panel/assets/{Multisig-BQbJ-CAN.js → Multisig-ChqMTtoq.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-JtPJKX25.js → NLProgramming-C48TyhvI.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-ZFKznTSG.js → Notes-zogUFWxp.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-B6aHRBBR.js → NotificationSettings-v-K9XpSB.js} +1 -1
  48. package/src/assets/web-panel/assets/OrderTableRenderer-P94JGGNz.js +1 -0
  49. package/src/assets/web-panel/assets/{Organization-BFDTAUgS.js → Organization-Boi1dQfR.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-0FoTfbWH.js → Overflow-DM5YWwgA.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-CWd90etw.js → P2P-C57LKpKK.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-DtCGC-W-.js → PdhVaultBrowser-BFkPqu6Q.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-CvQ7nr7T.js → Permissions-D6fB9YSp.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-rdNPcR-Z.js → PersonalDataHub-Bp7EefEo.js} +3 -3
  55. package/src/assets/web-panel/assets/{Pipeline-CmrfiNOs.js → Pipeline-BVln3hZf.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-D7ep1h_t.js → Privacy-Bf8P3nF6.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-C0xKINHS.js → ProjectInit-DM6wA2E2.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-AOmZFp-F.js → ProjectSettings-CGbc5Iho.js} +2 -2
  59. package/src/assets/web-panel/assets/{Projects-BWHSkXZP.js → Projects-D0p9EOxm.js} +1 -1
  60. package/src/assets/web-panel/assets/{Providers-Cb7JCTPL.js → Providers-B2kJcxS6.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-BDMehcXC.js → QrScannerModal-Cxu7dXYy.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-BF6_1nvx.js → QuickAsk-DTlrTPms.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-BHfT-A28.js → Recommend-Cm3X-cCj.js} +1 -1
  64. package/src/assets/web-panel/assets/RemoteSession-DNb2kjvt.js +5 -0
  65. package/src/assets/web-panel/assets/{Reputation-CsWHLEcj.js → Reputation-CZUFFjc1.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-D6srnWhm.js → Row-DAPgloxA.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-Xhr-KyVd.js → RssFeed-dsx9S793.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-vIbIJvwL.js → Search-DnnC8kz-.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-Bzi5Aiko.js → Security-VuZknRMK.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-BHtVX52P.js → Services-B3XNX8Vx.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-C0R8B2jf.js → Skeleton-Dl1nVtCj.js} +1 -1
  72. package/src/assets/web-panel/assets/Skills-CY09CZ_W.js +1 -0
  73. package/src/assets/web-panel/assets/{Sla-0B37mxVU.js → Sla-HzU56n1z.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-0V2jE1Bs.js → SpeechSettings-CRle7Jl2.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-CYedRzaj.js → SyncSettings-DWadz7Sl.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-D-R1x8vm.js → Tasks-CNVTDGg8.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-BKoHztGT.js → Templates-BBAgvrlM.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant--17nwVNZ.js → Tenant-BsbbvGN8.js} +1 -1
  79. package/src/assets/web-panel/assets/Terminal-uscpZI4q.js +3 -0
  80. package/src/assets/web-panel/assets/{TimelineRenderer-C5jx4AE3.js → TimelineRenderer-mTyjNE6r.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-DYJKYa9t.js → Tokens-Bz97oBgs.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-DChpWiQ9.js → Trigger-BTRKC140.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-DfWG52EA.js → Trust-B4A_KuyX.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-CMugYcyA.js → UkeySign-DES9TmLU.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-BOSmrHAd.js → VideoEditing-ClXs7Qxp.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-D5g3k3Sa.js → Wallet-IzZqFz-7.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-D-7u4Mkc.js → WebAuthn-BtOP04g_.js} +3 -3
  88. package/src/assets/web-panel/assets/{WorkflowEditor-CFzZMSUJ.js → WorkflowEditor-_0cqnopY.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-VbR6l6mc.js → chat-ax7193uU.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-BSZn8EDS.js → colors-Bu4WGJah.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-y74obMEq.js → compact-item-BX1dlTW0.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-C326bjex.js → createContext-CktA_Dj7.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-x877iKKS.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-D_INJQT_.js → hasIn-D5wd817l.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-CsovTpx9.js → index-5PYYkr8S.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-9PIVuXqo.js → index-A4uBPQCz.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BjcWKg1S.js → index-BAtBNfkr.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CMHqs3Jb.js → index-BLLsUNDc.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-B7SrC-On.js → index-BQtoRyTO.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DUU2606o.js → index-BRfXoRuh.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-Iw0FfqUz.js → index-Bad2CYeH.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Dlxh9D8D.js → index-BcGdL3sG.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DuIkfnTF.js → index-C3HmzCLt.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-E_v1ZCTP.js → index-C8DkWyNr.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-4eyH-eC2.js → index-C8tLR2TG.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BnSfnSMP.js → index-CP8ELJBc.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DwHSZLXg.js → index-CUForzsG.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-C2NyllnW.js → index-CYRE0NJA.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Bnua8IX3.js → index-CeVZaJSC.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-KF9Zmqln.js → index-CfzxR61U.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Cr3uuz0C.js → index-Ci3y1ZAv.js} +3 -3
  112. package/src/assets/web-panel/assets/{index-DBkzrpiL.js → index-CjEJjl5C.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-abmn_8Yz.js → index-Cv7bVWJ5.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-qMA4GYdQ.js → index-D-o4Rwjk.js} +1 -1
  115. package/src/assets/web-panel/assets/index-D7pfPouB.js +1 -0
  116. package/src/assets/web-panel/assets/{index-jYaogFE8.js → index-D9op8poE.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-GA80ir_u.js → index-DF1TysIF.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CzE53HiB.js → index-DYo9S5OT.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-gINyI1rh.js → index-D_cycOET.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-FQBsuExX.js → index-Db3CpWTr.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-IZAWt0H8.js → index-DkD1K-fF.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-C327pLbw.js → index-DmPJ6T6F.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DdyjrCAu.js → index-DmVUeWUk.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CfLJ42kv.js → index-Dzdr0zDf.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DkH1JvEt.js → index-PBLzwYnu.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DNMxIsDg.js → index-bFCaM7Eq.js} +1 -1
  127. package/src/assets/web-panel/assets/index-e4i-VLBd.js +1 -0
  128. package/src/assets/web-panel/assets/{index-C-ZCaUJc.js → index-h3KJZr95.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Bfw2hf2s.js → index-iHcPtQ2e.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BJi3UqBt.js → index-jzlzm4VK.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BY8-nCgs.js → index-o14NNnxw.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-nSn2-C4N.js → index-tYPSfGbd.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-4PIeTM--.js → index-ytp2H5Zx.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-DI0Zaf8-.js → initDefaultProps-D2Iut83B.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-BZDKSy3Z.js → motion-BuaJVdK9.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-DsIW01Vp.js → move-CaEuM92y.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-CohkDhsf.js → mtc-parser-wuKNBwys.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-DpiN5rzg.js → omit-7a3eklaq.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-qbuqni3y.js → pickAttrs-Dn4z7KvJ.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-mBky6714.js → placementArrow-DVn_qT4-.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-Bas3eQ2K.js → responsiveObserve-Dodz1OMQ.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-CBx_SKoK.js → slide-CxoGskbp.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-BlYguJSV.js → statusUtils-DBh_epQH.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-BCYQmRGv.js → styleChecker-RXQ4gG5P.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-Dp5dybLM.js → useFlexGapSupport-1Wxm0HEG.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-DHAMBgA2.js → useFs-CI_ySNxJ.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-W6jsSw76.js → usePersonalDataHub-C6973rZP.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-BkI6aayc.js → vnode-CalynwKr.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-C_IMGueq.js → zoom-CM1cd-Q0.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/commands/agenda.js +74 -1
  152. package/src/commands/background-session.js +11 -1
  153. package/src/commands/batch.js +160 -5
  154. package/src/commands/plugin.js +90 -27
  155. package/src/commands/session.js +31 -1
  156. package/src/commands/team.js +212 -6
  157. package/src/data/changelog.json +13 -0
  158. package/src/harness/jsonl-session-store.js +57 -6
  159. package/src/harness/mcp-client.js +65 -43
  160. package/src/lib/agent-batch.js +4 -1
  161. package/src/lib/agent-team/team-worktree.js +3 -0
  162. package/src/lib/async-hook-supervisor.cjs +82 -10
  163. package/src/lib/async-hook-supervisor.js +50 -4
  164. package/src/lib/collaboration-run-store.js +362 -0
  165. package/src/lib/hook-runner.cjs +98 -17
  166. package/src/lib/hook-runner.js +77 -6
  167. package/src/lib/hook-shell-command.cjs +148 -0
  168. package/src/lib/hooks-v2-runtime.js +188 -77
  169. package/src/lib/jsonl-session-store.js +2 -0
  170. package/src/lib/lsp/__tests__/lsp-client.test.js +18 -0
  171. package/src/lib/lsp/lsp-client.js +12 -1
  172. package/src/lib/plugin-monitor-supervisor.js +53 -16
  173. package/src/lib/plugin-runtime/bin.js +1 -1
  174. package/src/lib/plugin-runtime/install.js +249 -57
  175. package/src/lib/plugin-runtime/mcp.js +21 -2
  176. package/src/lib/plugin-runtime/monitors.js +19 -3
  177. package/src/lib/plugin-runtime/sandbox-policy.js +99 -0
  178. package/src/lib/process-execution-broker/index.js +453 -12
  179. package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +1347 -0
  180. package/src/lib/process-execution-broker/linux-generic-bwrap.js +1260 -0
  181. package/src/lib/process-execution-broker/platform-sandbox.js +580 -56
  182. package/src/lib/session-usage.js +202 -2
  183. package/src/lib/stream-retry.js +29 -0
  184. package/src/repl/agent-repl.js +32 -3
  185. package/src/runtime/agent-core.js +32 -4
  186. package/src/runtime/headless-runner.js +37 -0
  187. package/src/runtime/headless-stream.js +34 -2
  188. package/src/assets/web-panel/assets/ChatBubbleRenderer-CI_jT0ru.js +0 -1
  189. package/src/assets/web-panel/assets/MobileProjects-VTc3gT1y.js +0 -1
  190. package/src/assets/web-panel/assets/OrderTableRenderer-DdcsOqEz.js +0 -1
  191. package/src/assets/web-panel/assets/RemoteSession-B6EEf8hh.js +0 -5
  192. package/src/assets/web-panel/assets/Skills-DtT6rWOX.js +0 -1
  193. package/src/assets/web-panel/assets/Terminal-Dnkos7vW.js +0 -3
  194. package/src/assets/web-panel/assets/devWarning-D3Bho_6u.js +0 -1
  195. package/src/assets/web-panel/assets/index-5iAFwYx1.js +0 -1
  196. package/src/assets/web-panel/assets/index-BfnB7LPx.js +0 -1
@@ -26,35 +26,72 @@ import fs from "node:fs/promises";
26
26
  import path from "node:path";
27
27
  import broker from "./process-execution-broker/index.js";
28
28
  import hookEnvironment from "./hook-environment.cjs";
29
+ import hookShellCommand from "./hook-shell-command.cjs";
29
30
  import permissionRules from "./permission-rules.cjs";
30
31
  import { EventRuntimeStore } from "./event-runtime-store.js";
31
32
  import { getDefaultEventRuntimeHost } from "./event-runtime-host.js";
32
33
 
33
34
  const { globToRegExp } = permissionRules;
34
35
  const { buildManagedHookEnvironment } = hookEnvironment;
36
+ const {
37
+ buildExplicitHookShellInvocation,
38
+ issueTrustedHookSandboxContract,
39
+ isPathInside,
40
+ requireTrustedHookRoot,
41
+ requiresExplicitHookShell,
42
+ sandboxBoundaryError,
43
+ } = hookShellCommand;
35
44
 
36
45
  const VALID_HOOK_EVENTS = new Set([
37
46
  "Setup",
38
47
  // Session
39
- "PreToolUse", "PostToolUse", "Notification", "Stop", "SubagentStart", "SubagentStop",
40
- "SessionResume", "SessionPause", "PostCompact", "StopFailure",
48
+ "PreToolUse",
49
+ "PostToolUse",
50
+ "Notification",
51
+ "Stop",
52
+ "SubagentStart",
53
+ "SubagentStop",
54
+ "SessionResume",
55
+ "SessionPause",
56
+ "PostCompact",
57
+ "StopFailure",
41
58
  // Auth
42
- "PreCommit", "PostCommit",
59
+ "PreCommit",
60
+ "PostCommit",
43
61
  // Skill
44
- "UserPromptSubmit", "UserPromptExpansion", "SessionStart", "SessionEnd",
62
+ "UserPromptSubmit",
63
+ "UserPromptExpansion",
64
+ "SessionStart",
65
+ "SessionEnd",
45
66
  // Model
46
- "PreCompact", "ModelSelection",
67
+ "PreCompact",
68
+ "ModelSelection",
47
69
  // Config
48
- "ConfigChange", "PermissionAllow", "PermissionDeny", "PermissionRequest", "PermissionDenied",
70
+ "ConfigChange",
71
+ "PermissionAllow",
72
+ "PermissionDeny",
73
+ "PermissionRequest",
74
+ "PermissionDenied",
49
75
  // Timeline
50
76
  "TimelineEntry",
51
77
  // MCP
52
- "McpRequest", "McpResponse", "MCPElicitation", "Elicitation", "ElicitationResult",
78
+ "McpRequest",
79
+ "McpResponse",
80
+ "MCPElicitation",
81
+ "Elicitation",
82
+ "ElicitationResult",
53
83
  // Task / workspace lifecycle
54
- "TaskCreated", "TaskCompleted", "InstructionsLoaded", "CwdChanged",
55
- "WorktreeCreate", "WorktreeRemove", "TeammateIdle",
84
+ "TaskCreated",
85
+ "TaskCompleted",
86
+ "InstructionsLoaded",
87
+ "CwdChanged",
88
+ "WorktreeCreate",
89
+ "WorktreeRemove",
90
+ "TeammateIdle",
56
91
  // Tool aggregate / failure / filesystem lifecycle
57
- "PostToolUseFailure", "PostToolBatch", "FileChanged",
92
+ "PostToolUseFailure",
93
+ "PostToolBatch",
94
+ "FileChanged",
58
95
  ]);
59
96
 
60
97
  const VALID_EXECUTOR_TYPES = new Set([
@@ -137,7 +174,9 @@ function strictestDecision(results) {
137
174
 
138
175
  function hostnameMatches(hostname, pattern) {
139
176
  const host = String(hostname || "").toLowerCase();
140
- const rule = String(pattern || "").trim().toLowerCase();
177
+ const rule = String(pattern || "")
178
+ .trim()
179
+ .toLowerCase();
141
180
  if (!host || !rule) return false;
142
181
  if (rule.startsWith("*.")) {
143
182
  const suffix = rule.slice(1);
@@ -259,10 +298,7 @@ export function assertManagedHookPolicy(
259
298
  );
260
299
  }
261
300
  const executable = String(hook.command || "");
262
- const commandCandidates = new Set([
263
- executable,
264
- path.basename(executable),
265
- ]);
301
+ const commandCandidates = new Set([executable, path.basename(executable)]);
266
302
  if (
267
303
  Array.isArray(policy.commandAllowlist) &&
268
304
  ![...commandCandidates].some((value) =>
@@ -315,7 +351,11 @@ export function fileChangedHookMatches(hook, context = {}) {
315
351
  hook?.globs ?? hook?.paths ?? hook?.glob ?? hook?.if ?? null;
316
352
  if (configured == null) return true;
317
353
  const patterns = (Array.isArray(configured) ? configured : [configured])
318
- .map((value) => String(value || "").trim().replace(/\\/g, "/"))
354
+ .map((value) =>
355
+ String(value || "")
356
+ .trim()
357
+ .replace(/\\/g, "/"),
358
+ )
319
359
  .filter(Boolean);
320
360
  if (patterns.length === 0) return true;
321
361
 
@@ -392,6 +432,10 @@ class HooksV2Runtime extends EventEmitter {
392
432
  constructor(configDir, options = {}) {
393
433
  super();
394
434
  this.configDir = configDir;
435
+ // Both values are host constructor inputs. Hook definitions may select a
436
+ // cwd inside this root, but can never replace the writable root used to
437
+ // issue a Linux one-shot execution contract.
438
+ this.workspaceRoot = options.workspaceRoot || configDir || null;
395
439
  this.durableStore = options.durableStore || null;
396
440
  this.durableOwner =
397
441
  options.durableOwner ||
@@ -457,14 +501,18 @@ class HooksV2Runtime extends EventEmitter {
457
501
  const config = JSON.parse(content);
458
502
  this.hooks.clear();
459
503
 
460
- const hookDefs = Array.isArray(config) ? config : (config.hooks || []);
504
+ const hookDefs = Array.isArray(config) ? config : config.hooks || [];
461
505
  for (const def of hookDefs) {
462
506
  if (!VALID_HOOK_EVENTS.has(def.event)) {
463
- process.emitWarning(`[hooks-v2] Unknown event type: ${def.event}, skipping`);
507
+ process.emitWarning(
508
+ `[hooks-v2] Unknown event type: ${def.event}, skipping`,
509
+ );
464
510
  continue;
465
511
  }
466
512
  if (!VALID_EXECUTOR_TYPES.has(def.type)) {
467
- process.emitWarning(`[hooks-v2] Unknown executor type: ${def.type} for ${def.event}, skipping`);
513
+ process.emitWarning(
514
+ `[hooks-v2] Unknown executor type: ${def.type} for ${def.event}, skipping`,
515
+ );
468
516
  continue;
469
517
  }
470
518
  const id = def.id || crypto.randomUUID();
@@ -472,7 +520,10 @@ class HooksV2Runtime extends EventEmitter {
472
520
  this.hooks.get(def.event).push({ id, ...def });
473
521
  }
474
522
  this._loaded = true;
475
- this.emit("loaded", { count: hookDefs.length, events: Array.from(this.hooks.keys()) });
523
+ this.emit("loaded", {
524
+ count: hookDefs.length,
525
+ events: Array.from(this.hooks.keys()),
526
+ });
476
527
  } catch (e) {
477
528
  if (e.code !== "ENOENT") {
478
529
  this.emit("load:error", e);
@@ -484,8 +535,10 @@ class HooksV2Runtime extends EventEmitter {
484
535
  * Register a hook programmatically
485
536
  */
486
537
  registerHook(def) {
487
- if (!VALID_HOOK_EVENTS.has(def.event)) throw new Error(`Invalid event: ${def.event}`);
488
- if (!VALID_EXECUTOR_TYPES.has(def.type)) throw new Error(`Invalid executor type: ${def.type}`);
538
+ if (!VALID_HOOK_EVENTS.has(def.event))
539
+ throw new Error(`Invalid event: ${def.event}`);
540
+ if (!VALID_EXECUTOR_TYPES.has(def.type))
541
+ throw new Error(`Invalid executor type: ${def.type}`);
489
542
  const contract = HOOK_EVENT_CONTRACTS[def.event];
490
543
  if (!contract.allowedExecutors.includes(def.type)) {
491
544
  throw new Error(
@@ -501,7 +554,7 @@ class HooksV2Runtime extends EventEmitter {
501
554
 
502
555
  unregisterHook(id) {
503
556
  for (const [event, hooks] of this.hooks.entries()) {
504
- const idx = hooks.findIndex(h => h.id === id);
557
+ const idx = hooks.findIndex((h) => h.id === id);
505
558
  if (idx >= 0) {
506
559
  hooks.splice(idx, 1);
507
560
  return true;
@@ -536,20 +589,20 @@ class HooksV2Runtime extends EventEmitter {
536
589
  );
537
590
  const durableRecord =
538
591
  this.durableStore && options.skipDurable !== true
539
- ? this.durableStore.enqueueInbox(
540
- {
541
- runtime_type: "hooks.v2",
542
- requiresHandler: true,
543
- event: eventName,
544
- context,
545
- },
546
- {
547
- id: context.event_id || context.eventId || null,
548
- claimOwner: this.durableOwner,
549
- leaseMs: longestHookTimeout + this.durableRecoveryBufferMs,
550
- },
551
- )
552
- : null;
592
+ ? this.durableStore.enqueueInbox(
593
+ {
594
+ runtime_type: "hooks.v2",
595
+ requiresHandler: true,
596
+ event: eventName,
597
+ context,
598
+ },
599
+ {
600
+ id: context.event_id || context.eventId || null,
601
+ claimOwner: this.durableOwner,
602
+ leaseMs: longestHookTimeout + this.durableRecoveryBufferMs,
603
+ },
604
+ )
605
+ : null;
553
606
  if (durableRecord?.duplicate) {
554
607
  if (durableRecord.status === "done" && durableRecord.result) {
555
608
  return { ...durableRecord.result, duplicate: true };
@@ -577,7 +630,13 @@ class HooksV2Runtime extends EventEmitter {
577
630
  const runOne = async (hook) => {
578
631
  const execId = crypto.randomUUID();
579
632
  const start = Date.now();
580
- const record = { execId, hookId: hook.id, event: eventName, type: hook.type, startedAt: new Date() };
633
+ const record = {
634
+ execId,
635
+ hookId: hook.id,
636
+ event: eventName,
637
+ type: hook.type,
638
+ startedAt: new Date(),
639
+ };
581
640
 
582
641
  try {
583
642
  assertManagedHookPolicy(
@@ -629,9 +688,10 @@ class HooksV2Runtime extends EventEmitter {
629
688
  this.executionLog.push(record);
630
689
  return record;
631
690
  };
632
- const results = options.parallel === false
633
- ? []
634
- : await Promise.all(uniqueHooks.map(runOne));
691
+ const results =
692
+ options.parallel === false
693
+ ? []
694
+ : await Promise.all(uniqueHooks.map(runOne));
635
695
  if (options.parallel === false) {
636
696
  for (const hook of uniqueHooks) results.push(await runOne(hook));
637
697
  }
@@ -643,8 +703,7 @@ class HooksV2Runtime extends EventEmitter {
643
703
  const blocked = decision === "block";
644
704
  const blockingResult = blocking[0]?.result || null;
645
705
  const outcome = {
646
- success:
647
- !blocked && results.every((record) => record.status !== "error"),
706
+ success: !blocked && results.every((record) => record.status !== "error"),
648
707
  results,
649
708
  blocked,
650
709
  requiresApproval: decision === "ask",
@@ -689,24 +748,72 @@ class HooksV2Runtime extends EventEmitter {
689
748
  throw new Error("command hook requires a command");
690
749
  }
691
750
  const budget = hookBudget(hook);
692
- const sandboxPolicy = resolveHookSandboxPolicy(
693
- hook,
694
- this.managedPolicy,
695
- );
751
+ const sandboxPolicy = resolveHookSandboxPolicy(hook, this.managedPolicy);
752
+ const requiresContract = requiresExplicitHookShell(sandboxPolicy);
753
+ const trustedRoot = requiresContract
754
+ ? requireTrustedHookRoot(
755
+ this.workspaceRoot,
756
+ "Hooks v2 trusted workspace root",
757
+ )
758
+ : null;
759
+ const commandCwd =
760
+ hook.cwd || this.configDir || trustedRoot || process.cwd();
761
+ if (requiresContract) {
762
+ requireTrustedHookRoot(commandCwd, "Hooks v2 hook working directory");
763
+ if (!isPathInside(trustedRoot, commandCwd)) {
764
+ throw sandboxBoundaryError(
765
+ "Hooks v2 hook working directory escapes the trusted workspace root",
766
+ );
767
+ }
768
+ }
769
+ const invocation =
770
+ requiresContract && hook.shell === true
771
+ ? buildExplicitHookShellInvocation(hook.command, {
772
+ args: hook.args || [],
773
+ })
774
+ : {
775
+ file: hook.command,
776
+ argv: hook.args || [],
777
+ };
778
+ const commandOptions = {
779
+ cwd: commandCwd,
780
+ env: buildHookEnvironment(hook, this.managedPolicy),
781
+ stdio: ["pipe", "pipe", "pipe"],
782
+ timeout: budget.timeoutMs,
783
+ shell: requiresContract ? false : hook.shell === true,
784
+ origin: "hook",
785
+ scope: "hook",
786
+ policy: "allow",
787
+ hookName: hook.id,
788
+ ...(sandboxPolicy ? { sandboxPolicy } : {}),
789
+ };
790
+ const sandboxExecutionContract = requiresContract
791
+ ? issueTrustedHookSandboxContract({
792
+ issuer:
793
+ this.executionBroker.issueLinuxWorkspaceSandboxExecutionContract,
794
+ receiver: this.executionBroker,
795
+ file: invocation.file,
796
+ args: invocation.argv,
797
+ options: commandOptions,
798
+ trustedRoot,
799
+ label: "trusted Hooks v2 sandbox contract issuance failed",
800
+ })
801
+ : null;
802
+ if (
803
+ process.platform === "linux" &&
804
+ requiresContract &&
805
+ !sandboxExecutionContract
806
+ ) {
807
+ throw sandboxBoundaryError(
808
+ "trusted Linux Hooks v2 sandbox contract could not be issued",
809
+ );
810
+ }
696
811
  const child = await this.executionBroker.spawn(
697
- hook.command,
698
- hook.args || [],
812
+ invocation.file,
813
+ invocation.argv,
699
814
  {
700
- cwd: hook.cwd || this.configDir || process.cwd(),
701
- env: buildHookEnvironment(hook, this.managedPolicy),
702
- stdio: ["pipe", "pipe", "pipe"],
703
- timeout: budget.timeoutMs,
704
- shell: hook.shell === true,
705
- origin: "hook",
706
- scope: "hook",
707
- policy: "allow",
708
- hookName: hook.id,
709
- ...(sandboxPolicy ? { sandboxPolicy } : {}),
815
+ ...commandOptions,
816
+ ...(sandboxExecutionContract ? { sandboxExecutionContract } : {}),
710
817
  },
711
818
  );
712
819
  const payload = JSON.stringify({
@@ -716,14 +823,19 @@ class HooksV2Runtime extends EventEmitter {
716
823
  });
717
824
  child.stdin?.end(payload);
718
825
  return new Promise((resolve, reject) => {
719
- let stdout = "", stderr = "";
720
- child.stdout?.on("data", d => stdout += d);
721
- child.stderr?.on("data", d => stderr += d);
826
+ let stdout = "",
827
+ stderr = "";
828
+ child.stdout?.on("data", (d) => (stdout += d));
829
+ child.stderr?.on("data", (d) => (stderr += d));
722
830
  child.on("error", reject);
723
831
  child.on("exit", (code) => {
724
832
  if (code === 0) {
725
833
  let parsed = {};
726
- try { parsed = JSON.parse(stdout); } catch { parsed = { raw: stdout }; }
834
+ try {
835
+ parsed = JSON.parse(stdout);
836
+ } catch {
837
+ parsed = { raw: stdout };
838
+ }
727
839
  resolve({ ...parsed, exitCode: code, stderr });
728
840
  } else {
729
841
  reject(new Error(`Hook command failed with exit ${code}: ${stderr}`));
@@ -763,7 +875,10 @@ class HooksV2Runtime extends EventEmitter {
763
875
  const res = await this.fetchImpl(target, {
764
876
  method,
765
877
  headers,
766
- body: method !== "GET" ? JSON.stringify({ event: hook.event, context }) : undefined,
878
+ body:
879
+ method !== "GET"
880
+ ? JSON.stringify({ event: hook.event, context })
881
+ : undefined,
767
882
  signal: controller.signal,
768
883
  });
769
884
  clearTimeout(timer);
@@ -782,10 +897,7 @@ class HooksV2Runtime extends EventEmitter {
782
897
  throw new Error("prompt hook executor is not configured");
783
898
  }
784
899
  const budget = hookBudget(hook);
785
- const sandboxPolicy = resolveHookSandboxPolicy(
786
- hook,
787
- this.managedPolicy,
788
- );
900
+ const sandboxPolicy = resolveHookSandboxPolicy(hook, this.managedPolicy);
789
901
  return executeWithHookTimeout("prompt", budget, (signal) =>
790
902
  executor({
791
903
  hook,
@@ -805,10 +917,7 @@ class HooksV2Runtime extends EventEmitter {
805
917
  throw new Error("agent hook executor is not configured");
806
918
  }
807
919
  const budget = hookBudget(hook);
808
- const sandboxPolicy = resolveHookSandboxPolicy(
809
- hook,
810
- this.managedPolicy,
811
- );
920
+ const sandboxPolicy = resolveHookSandboxPolicy(hook, this.managedPolicy);
812
921
  return executeWithHookTimeout("agent", budget, (signal) =>
813
922
  executor({
814
923
  hook,
@@ -858,10 +967,7 @@ class HooksV2Runtime extends EventEmitter {
858
967
  }
859
968
  }
860
969
  const budget = hookBudget(hook);
861
- const sandboxPolicy = resolveHookSandboxPolicy(
862
- hook,
863
- this.managedPolicy,
864
- );
970
+ const sandboxPolicy = resolveHookSandboxPolicy(hook, this.managedPolicy);
865
971
  return executeWithHookTimeout("mcp_tool", budget, (signal) =>
866
972
  executor({
867
973
  server: hook.server,
@@ -889,7 +995,12 @@ class HooksV2Runtime extends EventEmitter {
889
995
  getHookRegistry() {
890
996
  const registry = {};
891
997
  for (const [event, hooks] of this.hooks.entries()) {
892
- registry[event] = hooks.map(h => ({ id: h.id, type: h.type, description: h.description, blocking: h.blocking }));
998
+ registry[event] = hooks.map((h) => ({
999
+ id: h.id,
1000
+ type: h.type,
1001
+ description: h.description,
1002
+ blocking: h.blocking,
1003
+ }));
893
1004
  }
894
1005
  return registry;
895
1006
  }
@@ -16,6 +16,8 @@ export {
16
16
  appendAssistantMessage,
17
17
  appendToolCall,
18
18
  appendToolCallCompact,
19
+ appendLlmRetryCompact,
20
+ MAX_COMPACT_DURATION_MS,
19
21
  appendToolResult,
20
22
  appendCompactEvent,
21
23
  readEvents,
@@ -100,6 +100,13 @@ describe("LSPClient handshake", () => {
100
100
 
101
101
  it("passes plugin sandbox requirements to ProcessExecutionBroker", async () => {
102
102
  const child = new FakeChild();
103
+ const contract = Object.freeze({ kind: "test-workspace-contract" });
104
+ const issueAuthority = vi
105
+ .spyOn(
106
+ executionBroker,
107
+ "issueLinuxWorkspaceSandboxExecutionContract",
108
+ )
109
+ .mockReturnValue(contract);
103
110
  const brokerSpawn = vi
104
111
  .spyOn(executionBroker, "spawn")
105
112
  .mockReturnValue(child);
@@ -123,8 +130,19 @@ describe("LSPClient handshake", () => {
123
130
  sandboxPolicy: {
124
131
  requiredBoundaries: ["filesystem", "network"],
125
132
  },
133
+ sandboxExecutionContract: contract,
126
134
  }),
127
135
  );
136
+ expect(issueAuthority).toHaveBeenCalledWith(
137
+ "fake-lsp",
138
+ ["--stdio"],
139
+ expect.objectContaining({
140
+ cwd: "/proj",
141
+ shell: false,
142
+ origin: "plugin:lsp",
143
+ }),
144
+ "/proj",
145
+ );
128
146
  expect(_deps.spawn).not.toHaveBeenCalled();
129
147
  });
130
148
 
@@ -83,7 +83,7 @@ export class LSPClient extends EventEmitter {
83
83
  const spawnFn = String(this.origin || "").startsWith("plugin:")
84
84
  ? executionBroker.spawn.bind(executionBroker)
85
85
  : _deps.spawn;
86
- this._child = spawnFn(spawnSpec.file, spawnSpec.args, {
86
+ const spawnOptions = {
87
87
  cwd: this.rootPath,
88
88
  env: { ...process.env, ...this.env },
89
89
  stdio: ["pipe", "pipe", "pipe"],
@@ -103,6 +103,17 @@ export class LSPClient extends EventEmitter {
103
103
  : {}),
104
104
  }
105
105
  : {}),
106
+ };
107
+ const sandboxExecutionContract =
108
+ executionBroker.issueLinuxWorkspaceSandboxExecutionContract(
109
+ spawnSpec.file,
110
+ spawnSpec.args,
111
+ spawnOptions,
112
+ this.rootPath,
113
+ );
114
+ this._child = spawnFn(spawnSpec.file, spawnSpec.args, {
115
+ ...spawnOptions,
116
+ ...(sandboxExecutionContract ? { sandboxExecutionContract } : {}),
106
117
  });
107
118
 
108
119
  this._child.on("error", (err) => {
@@ -25,6 +25,7 @@ import { executionBroker } from "./process-execution-broker/index.js";
25
25
  import { EventRuntimeProducer } from "./event-runtime-producer.js";
26
26
  import { EventRuntimeStore } from "./event-runtime-store.js";
27
27
  import { monitorEventId } from "./monitor-event.js";
28
+ import { resolvePluginWorkspaceAuthority } from "./plugin-runtime/sandbox-policy.js";
28
29
 
29
30
  export const _deps = {
30
31
  spawn: (...args) => executionBroker.spawn(...args),
@@ -44,7 +45,9 @@ export class PluginMonitorSupervisor {
44
45
  this._pluginSpawn = opts.brokerSpawn || this._spawn;
45
46
  const eventRuntimeStore =
46
47
  opts.eventRuntimeStore ||
47
- (process.env.CC_EVENT_RUNTIME_DURABLE === "1" ? new EventRuntimeStore() : null);
48
+ (process.env.CC_EVENT_RUNTIME_DURABLE === "1"
49
+ ? new EventRuntimeStore()
50
+ : null);
48
51
  this._runtimeProducer = eventRuntimeStore
49
52
  ? new EventRuntimeProducer({ store: eventRuntimeStore, emitter: this })
50
53
  : null;
@@ -118,7 +121,11 @@ export class PluginMonitorSupervisor {
118
121
  { origin: "monitor", id: monitorEventId(desc.id, { stream, line }) },
119
122
  );
120
123
  } catch (error) {
121
- this._outputs.push({ ...output, stream: "error", line: `durable publish failed: ${error.message}` });
124
+ this._outputs.push({
125
+ ...output,
126
+ stream: "error",
127
+ line: `durable publish failed: ${error.message}`,
128
+ });
122
129
  }
123
130
  if (this._outputs.length > OUTPUT_RING) this._outputs.shift();
124
131
  }
@@ -211,24 +218,54 @@ export class PluginMonitorSupervisor {
211
218
 
212
219
  _spawnForDescriptor(desc, options) {
213
220
  const isPlugin = desc?.origin === "plugin:monitor";
221
+ const pluginWorkspaceRoot = isPlugin
222
+ ? resolvePluginWorkspaceAuthority(desc.pluginWorkspaceAuthority, {
223
+ origin: desc.origin,
224
+ pluginId: desc.pluginId,
225
+ pluginVersion: desc.pluginVersion,
226
+ pluginSource: desc.pluginSource,
227
+ })
228
+ : null;
229
+ if (
230
+ isPlugin &&
231
+ desc.sandboxPolicy?.requiredBoundaries?.length > 0 &&
232
+ !pluginWorkspaceRoot
233
+ ) {
234
+ throw new Error(
235
+ `plugin monitor "${desc.id || desc.name || "unknown"}" is missing its trusted workspace authority`,
236
+ );
237
+ }
238
+ const spawnOptions = {
239
+ ...options,
240
+ origin: isPlugin ? desc.origin : "plugin-monitor:process",
241
+ policy: "allow",
242
+ scope: "plugin-monitor",
243
+ ...(isPlugin
244
+ ? {
245
+ pluginId: desc.pluginId,
246
+ pluginVersion: desc.pluginVersion,
247
+ pluginSource: desc.pluginSource,
248
+ ...(desc.sandboxPolicy
249
+ ? { sandboxPolicy: desc.sandboxPolicy }
250
+ : {}),
251
+ }
252
+ : {}),
253
+ };
254
+ const sandboxExecutionContract =
255
+ isPlugin && pluginWorkspaceRoot
256
+ ? executionBroker.issueLinuxWorkspaceSandboxExecutionContract(
257
+ desc.command,
258
+ desc.args,
259
+ spawnOptions,
260
+ pluginWorkspaceRoot,
261
+ )
262
+ : null;
214
263
  return (isPlugin ? this._pluginSpawn : this._spawn)(
215
264
  desc.command,
216
265
  desc.args,
217
266
  {
218
- ...options,
219
- origin: isPlugin ? desc.origin : "plugin-monitor:process",
220
- policy: "allow",
221
- scope: "plugin-monitor",
222
- ...(isPlugin
223
- ? {
224
- pluginId: desc.pluginId,
225
- pluginVersion: desc.pluginVersion,
226
- pluginSource: desc.pluginSource,
227
- ...(desc.sandboxPolicy
228
- ? { sandboxPolicy: desc.sandboxPolicy }
229
- : {}),
230
- }
231
- : {}),
267
+ ...spawnOptions,
268
+ ...(sandboxExecutionContract ? { sandboxExecutionContract } : {}),
232
269
  },
233
270
  );
234
271
  }
@@ -1118,7 +1118,7 @@ export function createPluginSandboxExecutionContract(invocation) {
1118
1118
  contractVersion: 1,
1119
1119
  kind:
1120
1120
  runtime === "native"
1121
- ? "strict-plugin-native-static-elf-bin"
1121
+ ? "strict-plugin-native-elf-bin"
1122
1122
  : "strict-plugin-node-bin",
1123
1123
  pluginRoot,
1124
1124
  workingDirectory: pluginRoot,