chainlesschain 0.162.184 → 0.162.186

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 (192) hide show
  1. package/bin/chainlesschain.js +21 -5
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-DzAl5fGx.js → AIOps-DTXiO-TB.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-DAHtMGeC.js → ActionButton-BbmDW-Pz.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-BHQaexv5.js → Analytics-CSfgXJuD.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-Phz_pD0n.js → AppLayout-BS0FFLb7.js} +4 -4
  8. package/src/assets/web-panel/assets/{Artifacts-DHt47kCA.js → Artifacts-B19WFPK2.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit--Y_8FULl.js → Audit-CQhZBi7n.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-N1zchH7D.js → BackgroundAgents-BOLZCpGH.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-B_BoyN30.js → Backup-Dz3R_ePD.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-Gl4uQHcT.js → BaseInput-CYfgMpax.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-Cg-eIyAZ.js → Chat-5CymMr1j.js} +5 -5
  14. package/src/assets/web-panel/assets/{ChatBubbleRenderer-BzeUi3JH.js → ChatBubbleRenderer-B2A_TJtl.js} +1 -1
  15. package/src/assets/web-panel/assets/{Checkbox-D0MGR2wA.js → Checkbox-CDXHVYcu.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-BdObJEFn.js → Codegen-uq9Z9oiS.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col--ghxXT3z.js → Col-BuW1K_65.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-BUFeXOqz.js → Community-Bbg-PvRY.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-DhQO2_Mr.js → Compact-co0pPPTw.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-3HoTqKYd.js → Compliance-B-pFAv7z.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-B3zmO4VW.js → Cowork-54ZQS4gC.js} +3 -3
  22. package/src/assets/web-panel/assets/{Cron-CJDrZOcc.js → Cron-B1BF2Seq.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-SMl15obd.js → Crosschain-Dey6qQTj.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-CgTrTWrl.js → DID-ltERvfAj.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-dXFKaKol.js → Dashboard-DuWxOcqN.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-qQHEhCvI.js → Dropdown-CrZ8ekTo.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-C_ej0MWH.js → EmailListRenderer-fIyHXhUS.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-D6ajoE7I.js → FamilyGuardDashboard-BtRyrRPm.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-Cio2y49h.js → Federation-EUC6Wydj.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-ClJz1cYp.js → FormItemContext-BOpka2G-.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-Dr_8Maca.js → GenericCardRenderer-BXtrrYHn.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-CevLwp5u.js → Git-8WMb7PiR.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-CW9YyQUY.js → Governance-DNWOeDTV.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-CQqeAyER.js → Inference-Bne9b_Lb.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-cuGVxHrw.js → KnowledgeGraph-Cp-6Us9b.js} +1 -1
  36. package/src/assets/web-panel/assets/{Logs-DIuHri5d.js → Logs-Ck-uSPAx.js} +2 -2
  37. package/src/assets/web-panel/assets/{MarkdownRenderer-R91Qw5JA.js → MarkdownRenderer-DxjsdAXw.js} +1 -1
  38. package/src/assets/web-panel/assets/{Marketplace-CY1VhFGx.js → Marketplace-Vdq7brrJ.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-BBAbi1vt.js → McpTools-ggLnw4hY.js} +5 -5
  40. package/src/assets/web-panel/assets/{Memory-BWYGHxJA.js → Memory-BKIjNVCU.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-CPIFkW7A.js → MobileBridge-BElCY25a.js} +1 -1
  42. package/src/assets/web-panel/assets/{MobileProjects-DQyWxCho.js → MobileProjects-DpLgovdH.js} +1 -1
  43. package/src/assets/web-panel/assets/{Mtc-Bo3GnQbx.js → Mtc-bNdrF_Zh.js} +4 -4
  44. package/src/assets/web-panel/assets/{MtcAudit-C8-c4rSW.js → MtcAudit-Dw8w1Cqk.js} +2 -2
  45. package/src/assets/web-panel/assets/{Multisig-ChqMTtoq.js → Multisig-CfGKvlqc.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-C48TyhvI.js → NLProgramming-D6OJf7YN.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-zogUFWxp.js → Notes-B3n_LzIS.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-v-K9XpSB.js → NotificationSettings-Uu1V_ICM.js} +1 -1
  49. package/src/assets/web-panel/assets/OrderTableRenderer-aGyWwWcp.js +1 -0
  50. package/src/assets/web-panel/assets/{Organization-Boi1dQfR.js → Organization-qjFFmuwK.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-DM5YWwgA.js → Overflow-J4ZgnwZz.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-C57LKpKK.js → P2P-YEZF-uVH.js} +2 -2
  53. package/src/assets/web-panel/assets/{PdhVaultBrowser-BFkPqu6Q.js → PdhVaultBrowser-yqx7fwqk.js} +3 -3
  54. package/src/assets/web-panel/assets/{Permissions-D6fB9YSp.js → Permissions-DdEjlZ02.js} +4 -4
  55. package/src/assets/web-panel/assets/{PersonalDataHub-Bp7EefEo.js → PersonalDataHub-DbAPYvns.js} +3 -3
  56. package/src/assets/web-panel/assets/{Pipeline-BVln3hZf.js → Pipeline-Bxlk_ZJU.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-Bf8P3nF6.js → Privacy-CpE-05tz.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-DM6wA2E2.js → ProjectInit-DWlhcGHT.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-CGbc5Iho.js → ProjectSettings-BnH6BiTQ.js} +2 -2
  60. package/src/assets/web-panel/assets/Projects-CHw2fXDB.js +1 -0
  61. package/src/assets/web-panel/assets/{Providers-B2kJcxS6.js → Providers-Bdz_sTyb.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-Cxu7dXYy.js → QrScannerModal-BHh2b3pH.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-DTlrTPms.js → QuickAsk-D84M09pe.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-Cm3X-cCj.js → Recommend-Czc30K6M.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-DNb2kjvt.js → RemoteSession-q_TU5qxt.js} +2 -2
  66. package/src/assets/web-panel/assets/{Reputation-CZUFFjc1.js → Reputation-CnTce4WM.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-DAPgloxA.js → Row-C60UFLay.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-dsx9S793.js → RssFeed-BOUFEu9_.js} +3 -3
  69. package/src/assets/web-panel/assets/{Search-DnnC8kz-.js → Search-D4__blE-.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-VuZknRMK.js → Security-BoOm7_JK.js} +4 -4
  71. package/src/assets/web-panel/assets/{Services-B3XNX8Vx.js → Services-AvzrW6HA.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-Dl1nVtCj.js → Skeleton-BZlrHozi.js} +1 -1
  73. package/src/assets/web-panel/assets/Skills-CKaMLuk0.js +1 -0
  74. package/src/assets/web-panel/assets/{Sla-HzU56n1z.js → Sla-DYCNJF8h.js} +1 -1
  75. package/src/assets/web-panel/assets/SpeechSettings-BvCSU6d2.js +1 -0
  76. package/src/assets/web-panel/assets/{SyncSettings-DWadz7Sl.js → SyncSettings-B6tW8dVO.js} +2 -2
  77. package/src/assets/web-panel/assets/Tasks-oNC_2NVz.js +1 -0
  78. package/src/assets/web-panel/assets/{Templates-BBAgvrlM.js → Templates-DvLPvvjL.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-BsbbvGN8.js → Tenant-BDt9UBn_.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-uscpZI4q.js → Terminal-ddCUnH-X.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-mTyjNE6r.js → TimelineRenderer-CA4sDL47.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-Bz97oBgs.js → Tokens-By03hnVs.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-BTRKC140.js → Trigger-Dz2mH-ZU.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-B4A_KuyX.js → Trust-DShSWHeJ.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-DES9TmLU.js → UkeySign-JN8lP3gt.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-ClXs7Qxp.js → VideoEditing-BgPy4gV3.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-IzZqFz-7.js → Wallet-CQGEsXw_.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-BtOP04g_.js → WebAuthn-D8xR-ds_.js} +3 -3
  89. package/src/assets/web-panel/assets/{WorkflowEditor-_0cqnopY.js → WorkflowEditor-Df61_p1p.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-ax7193uU.js → chat-fdPby427.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-Bu4WGJah.js → colors-Dimqhufo.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-BX1dlTW0.js → compact-item-DHayKcqZ.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-CktA_Dj7.js → createContext-hZUhypRH.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-ePxoBp92.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-D5wd817l.js → hasIn-Dw7zC_dV.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-ytp2H5Zx.js → index--DVpUpz3.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-tYPSfGbd.js → index-BHJUptSx.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-A4uBPQCz.js → index-BIxxvaGN.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DmVUeWUk.js → index-BM5BNqp9.js} +1 -1
  100. package/src/assets/web-panel/assets/index-BTBDdCoo.js +1 -0
  101. package/src/assets/web-panel/assets/{index-Ci3y1ZAv.js → index-BVHdkz8F.js} +17 -17
  102. package/src/assets/web-panel/assets/{index-Cv7bVWJ5.js → index-BYdNwhkv.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CUForzsG.js → index-Bhmpp3cm.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-C8DkWyNr.js → index-BuMSdwno.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BRfXoRuh.js → index-BwnUluxu.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-o14NNnxw.js → index-C1yMYKi-.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-C8tLR2TG.js → index-C8XXPz2n.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-5PYYkr8S.js → index-CBQK-LEF.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DkD1K-fF.js → index-CIOE8tt6.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CjEJjl5C.js → index-CPZ3U5iH.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-D9op8poE.js → index-CTiVrnpR.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DYo9S5OT.js → index-CcpDboUd.js} +1 -1
  113. package/src/assets/web-panel/assets/index-CfOGx8Ns.js +1 -0
  114. package/src/assets/web-panel/assets/{index-D-o4Rwjk.js → index-CsCo_A0I.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-h3KJZr95.js → index-CuaVa8tX.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DF1TysIF.js → index-CvKHpaao.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CfzxR61U.js → index-D7jQEwB6.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Db3CpWTr.js → index-DAjvkQ4K.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DmPJ6T6F.js → index-DC2R4zvM.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-C3HmzCLt.js → index-DJP7TjWm.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BAtBNfkr.js → index-DSlda4-6.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-D_cycOET.js → index-DVM_KgzF.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-Dzdr0zDf.js → index-DX1DwDFI.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-bFCaM7Eq.js → index-DnwDYBnG.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-Bad2CYeH.js → index-DxoPzPHy.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-iHcPtQ2e.js → index-DyEhrvpm.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-jzlzm4VK.js → index-DzJXkoZs.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CP8ELJBc.js → index-JE6Udz2r.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CeVZaJSC.js → index-Urt2R5aE.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BLLsUNDc.js → index-cEnkyHtX.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BcGdL3sG.js → index-j0pxzOu7.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-PBLzwYnu.js → index-lPjBQJCy.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-CYRE0NJA.js → index-ulvBurtw.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BQtoRyTO.js → index-y5LHQ5Ck.js} +1 -1
  135. package/src/assets/web-panel/assets/{initDefaultProps-D2Iut83B.js → initDefaultProps-B4pR3px5.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-BuaJVdK9.js → motion-CE7dWPPs.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-CaEuM92y.js → move-Hw8cUObc.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-wuKNBwys.js → mtc-parser-CvRjE4Fa.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-7a3eklaq.js → omit-CkFeLVre.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-Dn4z7KvJ.js → pickAttrs-5ZMqmbbb.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-DVn_qT4-.js → placementArrow-BZ4oeZ0q.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-Dodz1OMQ.js → responsiveObserve-lwoiX_Us.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-CxoGskbp.js → slide-D_as37l8.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-DBh_epQH.js → statusUtils-BsA-4Bs7.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-RXQ4gG5P.js → styleChecker-BVar4sLQ.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-1Wxm0HEG.js → useFlexGapSupport-j1IwVpGd.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-CI_ySNxJ.js → useFs-7Q9bEnUp.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-C6973rZP.js → usePersonalDataHub-BBwTIRMd.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-CalynwKr.js → vnode-C7Dk-M8w.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-CM1cd-Q0.js → zoom-D3UHaTFB.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/commands/eval.js +7 -0
  153. package/src/commands/status.js +55 -0
  154. package/src/commands/team.js +31 -6
  155. package/src/data/changelog.json +26 -0
  156. package/src/gateways/terminal/PtyManager.js +45 -15
  157. package/src/gateways/ws/ws-agent-handler.js +15 -1
  158. package/src/gateways/ws/ws-session-gateway.js +88 -0
  159. package/src/harness/background-task-command-runner.js +234 -0
  160. package/src/harness/background-task-manager.js +150 -20
  161. package/src/harness/background-task-worker.js +17 -11
  162. package/src/lazy-dispatch.js +12 -1
  163. package/src/lib/background-agent-supervisor.js +46 -0
  164. package/src/lib/event-runtime-host.js +12 -10
  165. package/src/lib/hook-runner.cjs +7 -1
  166. package/src/lib/hook-runner.js +2 -0
  167. package/src/lib/hooks-v2-runtime.js +94 -6
  168. package/src/lib/hooks-v2-workspace-context.js +258 -0
  169. package/src/lib/lsp/__tests__/lsp-client.test.js +1 -4
  170. package/src/lib/observability/index.js +191 -19
  171. package/src/lib/observability/otlp-exporter.js +1209 -207
  172. package/src/lib/otlp-exporter.js +8 -36
  173. package/src/lib/plugin-runtime/bin.js +20 -4
  174. package/src/lib/plugin-runtime/sandbox-policy.js +1 -4
  175. package/src/lib/process-execution-broker/index.js +706 -40
  176. package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +212 -2
  177. package/src/lib/process-execution-broker/linux-generic-bwrap.js +124 -6
  178. package/src/lib/process-execution-broker/platform-sandbox.js +6 -2
  179. package/src/program-base.js +9 -2
  180. package/src/repl/agent-repl.js +8 -0
  181. package/src/runtime/agent-core.js +272 -38
  182. package/src/runtime/headless-runner.js +56 -22
  183. package/src/runtime/headless-stream.js +8 -0
  184. package/src/workers/background-agent-worker.js +5 -11
  185. package/src/assets/web-panel/assets/OrderTableRenderer-P94JGGNz.js +0 -1
  186. package/src/assets/web-panel/assets/Projects-D0p9EOxm.js +0 -1
  187. package/src/assets/web-panel/assets/Skills-CY09CZ_W.js +0 -1
  188. package/src/assets/web-panel/assets/SpeechSettings-CRle7Jl2.js +0 -1
  189. package/src/assets/web-panel/assets/Tasks-CNVTDGg8.js +0 -1
  190. package/src/assets/web-panel/assets/devWarning-x877iKKS.js +0 -1
  191. package/src/assets/web-panel/assets/index-D7pfPouB.js +0 -1
  192. package/src/assets/web-panel/assets/index-e4i-VLBd.js +0 -1
@@ -1 +1 @@
1
- import{u as d}from"./index-Ci3y1ZAv.js";import{u as c}from"./useShellMode-CgR0wCYM.js";function u({accept:l=""}={}){return new Promise(a=>{if(typeof document>"u"){a({canceled:!0,path:null,content:null});return}const n=document.createElement("input");n.type="file",l&&(n.accept=l),n.style.display="none",document.body.appendChild(n);let o=!1;const i=()=>{n.parentNode&&n.parentNode.removeChild(n)},r=()=>{if(o)return;o=!0;const e=n.files&&n.files[0];if(!e){i(),a({canceled:!0,path:null,content:null});return}const t=new FileReader;t.onload=()=>{i(),a({canceled:!1,path:e.name,size:e.size,content:typeof t.result=="string"?t.result:""})},t.onerror=()=>{i(),a({canceled:!1,path:e.name,size:e.size,content:null,reason:"read_failed"})},t.readAsText(e)};n.addEventListener("change",r),n.click()})}function f(l,{defaultPath:a="download.txt"}={}){if(typeof document>"u")return{canceled:!0,path:null};const n=new Blob([l],{type:"text/plain"}),o=URL.createObjectURL(n),i=document.createElement("a");return i.href=o,i.download=a,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(o),{canceled:!1,path:a}}function p(l){if(!Array.isArray(l))return"";const a=[];for(const n of l)if(Array.isArray(n.extensions))for(const o of n.extensions)a.push(`.${o.replace(/^\./,"")}`);return a.join(",")}function m(){const l=d();async function a(r={}){if(c().isEmbedded){const e=await l.sendRaw({type:"fs.openDialog",title:r.title,filters:r.filters},6e4);if(e&&e.ok===!1)throw new Error(e.error||"fs.openDialog failed");const t=e?.result??e;return{canceled:!!t.canceled,path:t.path??null,content:t.content??null,size:t.size,reason:t.reason}}return u({accept:p(r.filters)})}async function n(r,e={}){if(typeof r!="string")throw new Error("content must be a string");if(c().isEmbedded){const t=await l.sendRaw({type:"fs.saveDialog",title:e.title,defaultPath:e.defaultPath,filters:e.filters,content:r},6e4);if(t&&t.ok===!1)throw new Error(t.error||"fs.saveDialog failed");const s=t?.result??t;return{canceled:!!s.canceled,path:s.path??null}}return f(r,{defaultPath:e.defaultPath})}async function o(r,e={}){const t=JSON.stringify(r,null,2),s={...e,defaultPath:e.defaultPath||"data.json",filters:e.filters||[{name:"JSON",extensions:["json"]}]};return n(t,s)}async function i(r={}){if(!c().isEmbedded)return{canceled:!0,path:null,initialized:!1,unsupported:!0};const e=await l.sendRaw({type:"fs.openDirectory",title:r.title},6e4);if(e&&e.ok===!1)throw new Error(e.error||"fs.openDirectory failed");const t=e?.result??e;return{canceled:!!t.canceled,path:t.path??null,initialized:!!t.initialized}}return{pickFileText:a,saveText:n,saveJson:o,pickDirectory:i}}export{m as u};
1
+ import{u as d}from"./index-BVHdkz8F.js";import{u as c}from"./useShellMode-CgR0wCYM.js";function u({accept:l=""}={}){return new Promise(a=>{if(typeof document>"u"){a({canceled:!0,path:null,content:null});return}const n=document.createElement("input");n.type="file",l&&(n.accept=l),n.style.display="none",document.body.appendChild(n);let o=!1;const i=()=>{n.parentNode&&n.parentNode.removeChild(n)},r=()=>{if(o)return;o=!0;const e=n.files&&n.files[0];if(!e){i(),a({canceled:!0,path:null,content:null});return}const t=new FileReader;t.onload=()=>{i(),a({canceled:!1,path:e.name,size:e.size,content:typeof t.result=="string"?t.result:""})},t.onerror=()=>{i(),a({canceled:!1,path:e.name,size:e.size,content:null,reason:"read_failed"})},t.readAsText(e)};n.addEventListener("change",r),n.click()})}function f(l,{defaultPath:a="download.txt"}={}){if(typeof document>"u")return{canceled:!0,path:null};const n=new Blob([l],{type:"text/plain"}),o=URL.createObjectURL(n),i=document.createElement("a");return i.href=o,i.download=a,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(o),{canceled:!1,path:a}}function p(l){if(!Array.isArray(l))return"";const a=[];for(const n of l)if(Array.isArray(n.extensions))for(const o of n.extensions)a.push(`.${o.replace(/^\./,"")}`);return a.join(",")}function m(){const l=d();async function a(r={}){if(c().isEmbedded){const e=await l.sendRaw({type:"fs.openDialog",title:r.title,filters:r.filters},6e4);if(e&&e.ok===!1)throw new Error(e.error||"fs.openDialog failed");const t=e?.result??e;return{canceled:!!t.canceled,path:t.path??null,content:t.content??null,size:t.size,reason:t.reason}}return u({accept:p(r.filters)})}async function n(r,e={}){if(typeof r!="string")throw new Error("content must be a string");if(c().isEmbedded){const t=await l.sendRaw({type:"fs.saveDialog",title:e.title,defaultPath:e.defaultPath,filters:e.filters,content:r},6e4);if(t&&t.ok===!1)throw new Error(t.error||"fs.saveDialog failed");const s=t?.result??t;return{canceled:!!s.canceled,path:s.path??null}}return f(r,{defaultPath:e.defaultPath})}async function o(r,e={}){const t=JSON.stringify(r,null,2),s={...e,defaultPath:e.defaultPath||"data.json",filters:e.filters||[{name:"JSON",extensions:["json"]}]};return n(t,s)}async function i(r={}){if(!c().isEmbedded)return{canceled:!0,path:null,initialized:!1,unsupported:!0};const e=await l.sendRaw({type:"fs.openDirectory",title:r.title},6e4);if(e&&e.ok===!1)throw new Error(e.error||"fs.openDirectory failed");const t=e?.result??e;return{canceled:!!t.canceled,path:t.path??null,initialized:!!t.initialized}}return{pickFileText:a,saveText:n,saveJson:o,pickDirectory:i}}export{m as u};
@@ -1 +1 @@
1
- import{u as v}from"./index-Ci3y1ZAv.js";import{u as _}from"./useShellMode-CgR0wCYM.js";function d(r){if(!r)return r;if(r.error)throw new Error(r.error);return r.result!==void 0?r.result:r}async function p(r,s={},e=!0){try{if(e!==!0||!r||typeof r.sendRaw!="function")return{status:"unavailable",path:null};const a=await r.sendRaw({type:"fs.openDirectory",title:s.title},6e4);if(a&&(a.ok===!1||a.error))return{status:"unavailable",path:null};const t=a&&a.result!==void 0?a.result:a;return t&&(t.ok===!1||t.error||t.unsupported===!0)?{status:"unavailable",path:null}:t&&t.canceled===!0?{status:"cancelled",path:null}:t&&typeof t.path=="string"&&t.path.length>0?{status:"selected",path:t.path}:{status:"unavailable",path:null}}catch{return{status:"unavailable",path:null}}}function b(r,s,e,a,t){return typeof r.onMessage!="function"||typeof r.sendRaw!="function"?r.sendRaw({type:s,...e},t).then(d):new Promise((n,u)=>{const l=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`,w=`${s}.event`,m=`${s}.end`;let c=!1,h=()=>{};const o=(i,f)=>{if(!c){c=!0,clearTimeout(g);try{h()}catch{}i(f)}},g=setTimeout(()=>{o(u,new Error(`stream timeout (${t}ms): ${s}`))},t),y=r.onMessage(i=>{if(!(c||!i)&&!(i.id!==l&&i.requestId!==l)){if(i.type===w){if(typeof a=="function")try{a(i.event||i)}catch{}return}if(i.type===m){o(n,d(i));return}i.type==="error"&&o(u,new Error(i.message||"stream error"))}});h=typeof y=="function"?y:()=>{},Promise.resolve(r.sendRaw({id:l,type:s,...e},t)).catch(()=>{})})}function k(){const r=v(),s=_(),e=(a,t={},n=3e4)=>r.sendRaw({type:a,...t},n).then(d);return{async health(){return await e("personal-data-hub.health",{},8e3)},async stats(){return await e("personal-data-hub.stats",{},8e3)},async listAdapters(){return await e("personal-data-hub.list-adapters",{},5e3)},async pickFile(a={}){try{const t=await r.sendRaw({type:"fs.openDialog",title:a.title,filters:a.filters},6e4),n=t&&t.result!==void 0?t.result:t,u=n&&typeof n.path=="string"?n.path:n&&typeof n.filePath=="string"?n.filePath:null;return n&&n.canceled!==!0&&u?u:null}catch{return null}},async pickDirectoryResult(a={}){return await p(r,a,s.isEmbedded)},async pickDirectory(a={}){const t=await p(r,a,s.isEmbedded);return t.status==="selected"?t.path:null},async adapterReadiness(a){return await e("personal-data-hub.adapter-readiness",Number.isInteger(a)?{timeoutMs:a}:{},15e3)},async syncAdapter(a,t={}){return await e("personal-data-hub.sync-adapter",{name:a,options:t},6e5)},async syncAll(a={}){return await e("personal-data-hub.sync-all",{options:a},6e5)},async registerMock({name:a="mock",count:t=20,seed:n=1}={}){return await e("personal-data-hub.register-mock",{name:a,count:t,seed:n})},async unregister(a){return await e("personal-data-hub.unregister",{name:a})},async ask(a,t={}){return await e("personal-data-hub.ask",{question:a,options:t},18e4)},async queryEvents(a={}){return await e("personal-data-hub.query-events",a,1e4)},async recentAudit(a={}){return await e("personal-data-hub.recent-audit",a,1e4)},async searchEvents(a={}){return await e("personal-data-hub.search-events",a,15e3)},async facetCounts(a={}){return await e("personal-data-hub.facet-counts",a,1e4)},async testEmailAuth(a){return await e("personal-data-hub.test-email-auth",{account:a},3e4)},async registerEmail(a,t={}){return await e("personal-data-hub.register-email",{account:a,opts:t},15e3)},async unregisterEmail(a){return await e("personal-data-hub.unregister-email",{email:a},5e3)},async listEmailAccounts(){return await e("personal-data-hub.list-email-accounts",{},5e3)},async activateEmail(a){return await e("personal-data-hub.activate-email",{email:a},5e3)},async eventDetail(a){return await e("personal-data-hub.event-detail",{eventId:a},5e3)},async syncAdapterStream(a,t={},n){return await b(r,"personal-data-hub.sync-adapter-stream",{name:a,options:t},n,6e5)},async syncAllStream(a={},t){return await b(r,"personal-data-hub.sync-all-stream",{options:a},t,9e5)},async registerAlipay(a,t={}){return await e("personal-data-hub.register-alipay",{account:a,opts:t},15e3)},async unregisterAlipay(a){return await e("personal-data-hub.unregister-alipay",{email:a},5e3)},async listAlipayAccounts(){return await e("personal-data-hub.list-alipay-accounts",{},5e3)},async activateAlipay(a){return await e("personal-data-hub.activate-alipay",{email:a},5e3)},async importAlipayBill({zipPath:a,csvPath:t,zipPassword:n}={}){return await e("personal-data-hub.import-alipay-bill",{zipPath:a,csvPath:t,zipPassword:n},3e5)},async reviewQueueList(a=50){return await e("personal-data-hub.review-queue-list",{limit:a},5e3)},async reviewDecision(a,t){return await e("personal-data-hub.review-decision",{reviewId:a,decision:t},5e3)},async manualMerge(a,t){return await e("personal-data-hub.manual-merge",{aId:a,bId:t},5e3)},async manualUnmerge(a){return await e("personal-data-hub.manual-unmerge",{personId:a},5e3)},async resolverDrain(a=50){return await e("personal-data-hub.resolver-drain",{limit:a},18e4)},async resolverStats(){return await e("personal-data-hub.resolver-stats",{},5e3)},async skillsList(){return await e("personal-data-hub.skills-list",{},5e3)},async runSkill(a,t={}){return await e("personal-data-hub.run-skill",{name:a,options:t},12e4)},async openAichatLogin(a,t={}){return await e("personal-data-hub.aichat-open-login",{vendor:a,opts:t},1e4)},async probeAichatCookies(a,t){return await e("personal-data-hub.aichat-probe-cookies",{vendor:a,cookieHeader:t},1e4)},async registerAichatVendor(a,t,n={}){return await e("personal-data-hub.aichat-register-vendor",{vendor:a,cookies:t,opts:n},3e4)},async rotateAichatLogin(a){return await e("personal-data-hub.aichat-rotate-login",{vendor:a},1e4)},async listAichatAccounts(){return await e("personal-data-hub.list-aichat-accounts",{},5e3)},async unregisterAichat(a){return await e("personal-data-hub.unregister-aichat",{vendor:a},5e3)},async aichatHealthCheckOnce(){return await e("personal-data-hub.aichat-health-check-once",{},3e4)},async probeWechatEnv(){return await e("personal-data-hub.wechat-env-probe",{},15e3)},async registerWechat({account:a,dbPath:t,wechatDataPath:n,fridaOpts:u,keyProviderOverride:l}={}){return await e("personal-data-hub.register-wechat",{account:a,dbPath:t,wechatDataPath:n,fridaOpts:u,keyProviderOverride:l},45e3)},async listWechatAccounts(){return await e("personal-data-hub.list-wechat-accounts",{},5e3)},async activateWechat(a,t={}){return await e("personal-data-hub.activate-wechat",{uin:a,fridaOpts:t.fridaOpts,keyProviderOverride:t.keyProviderOverride},45e3)},async unregisterWechat(a){return await e("personal-data-hub.unregister-wechat",{uin:a},5e3)},async bilibiliAdbSync(a={}){return await e("personal-data-hub.bilibili-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},12e4)},async bilibiliAdbDoctor(){return await e("personal-data-hub.bilibili-adb-doctor",{},15e3)},async weiboAdbSync(a={}){return await e("personal-data-hub.weibo-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)},async xhsAdbSync(a={}){return await e("personal-data-hub.xhs-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)},async toutiaoAdbSync(a={}){return await e("personal-data-hub.toutiao-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},9e4)},async kuaishouAdbSync(a={}){return await e("personal-data-hub.kuaishou-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},12e4)},async bridgeDoctor(){return await e("personal-data-hub.bridge-doctor",{},6e4)},async douyinAdbSync(a={}){return await e("personal-data-hub.douyin-adb-sync",{uid:a.uid,limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)}}}export{k as u};
1
+ import{u as v}from"./index-BVHdkz8F.js";import{u as _}from"./useShellMode-CgR0wCYM.js";function d(r){if(!r)return r;if(r.error)throw new Error(r.error);return r.result!==void 0?r.result:r}async function p(r,s={},e=!0){try{if(e!==!0||!r||typeof r.sendRaw!="function")return{status:"unavailable",path:null};const a=await r.sendRaw({type:"fs.openDirectory",title:s.title},6e4);if(a&&(a.ok===!1||a.error))return{status:"unavailable",path:null};const t=a&&a.result!==void 0?a.result:a;return t&&(t.ok===!1||t.error||t.unsupported===!0)?{status:"unavailable",path:null}:t&&t.canceled===!0?{status:"cancelled",path:null}:t&&typeof t.path=="string"&&t.path.length>0?{status:"selected",path:t.path}:{status:"unavailable",path:null}}catch{return{status:"unavailable",path:null}}}function b(r,s,e,a,t){return typeof r.onMessage!="function"||typeof r.sendRaw!="function"?r.sendRaw({type:s,...e},t).then(d):new Promise((n,u)=>{const l=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`,w=`${s}.event`,m=`${s}.end`;let c=!1,h=()=>{};const o=(i,f)=>{if(!c){c=!0,clearTimeout(g);try{h()}catch{}i(f)}},g=setTimeout(()=>{o(u,new Error(`stream timeout (${t}ms): ${s}`))},t),y=r.onMessage(i=>{if(!(c||!i)&&!(i.id!==l&&i.requestId!==l)){if(i.type===w){if(typeof a=="function")try{a(i.event||i)}catch{}return}if(i.type===m){o(n,d(i));return}i.type==="error"&&o(u,new Error(i.message||"stream error"))}});h=typeof y=="function"?y:()=>{},Promise.resolve(r.sendRaw({id:l,type:s,...e},t)).catch(()=>{})})}function k(){const r=v(),s=_(),e=(a,t={},n=3e4)=>r.sendRaw({type:a,...t},n).then(d);return{async health(){return await e("personal-data-hub.health",{},8e3)},async stats(){return await e("personal-data-hub.stats",{},8e3)},async listAdapters(){return await e("personal-data-hub.list-adapters",{},5e3)},async pickFile(a={}){try{const t=await r.sendRaw({type:"fs.openDialog",title:a.title,filters:a.filters},6e4),n=t&&t.result!==void 0?t.result:t,u=n&&typeof n.path=="string"?n.path:n&&typeof n.filePath=="string"?n.filePath:null;return n&&n.canceled!==!0&&u?u:null}catch{return null}},async pickDirectoryResult(a={}){return await p(r,a,s.isEmbedded)},async pickDirectory(a={}){const t=await p(r,a,s.isEmbedded);return t.status==="selected"?t.path:null},async adapterReadiness(a){return await e("personal-data-hub.adapter-readiness",Number.isInteger(a)?{timeoutMs:a}:{},15e3)},async syncAdapter(a,t={}){return await e("personal-data-hub.sync-adapter",{name:a,options:t},6e5)},async syncAll(a={}){return await e("personal-data-hub.sync-all",{options:a},6e5)},async registerMock({name:a="mock",count:t=20,seed:n=1}={}){return await e("personal-data-hub.register-mock",{name:a,count:t,seed:n})},async unregister(a){return await e("personal-data-hub.unregister",{name:a})},async ask(a,t={}){return await e("personal-data-hub.ask",{question:a,options:t},18e4)},async queryEvents(a={}){return await e("personal-data-hub.query-events",a,1e4)},async recentAudit(a={}){return await e("personal-data-hub.recent-audit",a,1e4)},async searchEvents(a={}){return await e("personal-data-hub.search-events",a,15e3)},async facetCounts(a={}){return await e("personal-data-hub.facet-counts",a,1e4)},async testEmailAuth(a){return await e("personal-data-hub.test-email-auth",{account:a},3e4)},async registerEmail(a,t={}){return await e("personal-data-hub.register-email",{account:a,opts:t},15e3)},async unregisterEmail(a){return await e("personal-data-hub.unregister-email",{email:a},5e3)},async listEmailAccounts(){return await e("personal-data-hub.list-email-accounts",{},5e3)},async activateEmail(a){return await e("personal-data-hub.activate-email",{email:a},5e3)},async eventDetail(a){return await e("personal-data-hub.event-detail",{eventId:a},5e3)},async syncAdapterStream(a,t={},n){return await b(r,"personal-data-hub.sync-adapter-stream",{name:a,options:t},n,6e5)},async syncAllStream(a={},t){return await b(r,"personal-data-hub.sync-all-stream",{options:a},t,9e5)},async registerAlipay(a,t={}){return await e("personal-data-hub.register-alipay",{account:a,opts:t},15e3)},async unregisterAlipay(a){return await e("personal-data-hub.unregister-alipay",{email:a},5e3)},async listAlipayAccounts(){return await e("personal-data-hub.list-alipay-accounts",{},5e3)},async activateAlipay(a){return await e("personal-data-hub.activate-alipay",{email:a},5e3)},async importAlipayBill({zipPath:a,csvPath:t,zipPassword:n}={}){return await e("personal-data-hub.import-alipay-bill",{zipPath:a,csvPath:t,zipPassword:n},3e5)},async reviewQueueList(a=50){return await e("personal-data-hub.review-queue-list",{limit:a},5e3)},async reviewDecision(a,t){return await e("personal-data-hub.review-decision",{reviewId:a,decision:t},5e3)},async manualMerge(a,t){return await e("personal-data-hub.manual-merge",{aId:a,bId:t},5e3)},async manualUnmerge(a){return await e("personal-data-hub.manual-unmerge",{personId:a},5e3)},async resolverDrain(a=50){return await e("personal-data-hub.resolver-drain",{limit:a},18e4)},async resolverStats(){return await e("personal-data-hub.resolver-stats",{},5e3)},async skillsList(){return await e("personal-data-hub.skills-list",{},5e3)},async runSkill(a,t={}){return await e("personal-data-hub.run-skill",{name:a,options:t},12e4)},async openAichatLogin(a,t={}){return await e("personal-data-hub.aichat-open-login",{vendor:a,opts:t},1e4)},async probeAichatCookies(a,t){return await e("personal-data-hub.aichat-probe-cookies",{vendor:a,cookieHeader:t},1e4)},async registerAichatVendor(a,t,n={}){return await e("personal-data-hub.aichat-register-vendor",{vendor:a,cookies:t,opts:n},3e4)},async rotateAichatLogin(a){return await e("personal-data-hub.aichat-rotate-login",{vendor:a},1e4)},async listAichatAccounts(){return await e("personal-data-hub.list-aichat-accounts",{},5e3)},async unregisterAichat(a){return await e("personal-data-hub.unregister-aichat",{vendor:a},5e3)},async aichatHealthCheckOnce(){return await e("personal-data-hub.aichat-health-check-once",{},3e4)},async probeWechatEnv(){return await e("personal-data-hub.wechat-env-probe",{},15e3)},async registerWechat({account:a,dbPath:t,wechatDataPath:n,fridaOpts:u,keyProviderOverride:l}={}){return await e("personal-data-hub.register-wechat",{account:a,dbPath:t,wechatDataPath:n,fridaOpts:u,keyProviderOverride:l},45e3)},async listWechatAccounts(){return await e("personal-data-hub.list-wechat-accounts",{},5e3)},async activateWechat(a,t={}){return await e("personal-data-hub.activate-wechat",{uin:a,fridaOpts:t.fridaOpts,keyProviderOverride:t.keyProviderOverride},45e3)},async unregisterWechat(a){return await e("personal-data-hub.unregister-wechat",{uin:a},5e3)},async bilibiliAdbSync(a={}){return await e("personal-data-hub.bilibili-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},12e4)},async bilibiliAdbDoctor(){return await e("personal-data-hub.bilibili-adb-doctor",{},15e3)},async weiboAdbSync(a={}){return await e("personal-data-hub.weibo-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)},async xhsAdbSync(a={}){return await e("personal-data-hub.xhs-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)},async toutiaoAdbSync(a={}){return await e("personal-data-hub.toutiao-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},9e4)},async kuaishouAdbSync(a={}){return await e("personal-data-hub.kuaishou-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},12e4)},async bridgeDoctor(){return await e("personal-data-hub.bridge-doctor",{},6e4)},async douyinAdbSync(a={}){return await e("personal-data-hub.douyin-adb-sync",{uid:a.uid,limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)}}}export{k as u};
@@ -1 +1 @@
1
- import{N as i,h as a,w as l}from"./index-Ci3y1ZAv.js";import{a7 as o,k as g,C as d,F as f,A as p}from"./vendor-Bn1JzzAn.js";function c(e){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,s=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1,u=e;if(Array.isArray(e)&&(u=i(e)[0]),!u)return null;const n=o(u,r,s);return n.props=t?a(a({},n.props),r):n.props,l(typeof n.props.class!="object","class must be string"),n}function V(e){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;return e.map(s=>c(s,r,t))}function v(e,r,t){p(o(e,a({},r)),t)}const m=e=>(e||[]).some(r=>g(r)?!(r.type===d||r.type===f&&!m(r.children)):!0)?e:null;function h(e,r,t,s){var u;const n=(u=e[r])===null||u===void 0?void 0:u.call(e,t);return m(n)?n:s?.()}export{h as a,V as b,c,v as t};
1
+ import{N as i,h as a,w as l}from"./index-BVHdkz8F.js";import{a7 as o,k as g,C as d,F as f,A as p}from"./vendor-Bn1JzzAn.js";function c(e){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,s=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1,u=e;if(Array.isArray(e)&&(u=i(e)[0]),!u)return null;const n=o(u,r,s);return n.props=t?a(a({},n.props),r):n.props,l(typeof n.props.class!="object","class must be string"),n}function V(e){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;return e.map(s=>c(s,r,t))}function v(e,r,t){p(o(e,a({},r)),t)}const m=e=>(e||[]).some(r=>g(r)?!(r.type===d||r.type===f&&!m(r.children)):!0)?e:null;function h(e,r,t,s){var u;const n=(u=e[r])===null||u===void 0?void 0:u.call(e,t);return m(n)?n:s?.()}export{h as a,V as b,c,v as t};
@@ -1,4 +1,4 @@
1
- import{K as o}from"./index-Ci3y1ZAv.js";import{i as f}from"./motion-BuaJVdK9.js";const c=new o("antZoomIn",{"0%":{transform:"scale(0.2)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),y=new o("antZoomOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.2)",opacity:0}}),a=new o("antZoomBigIn",{"0%":{transform:"scale(0.8)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),s=new o("antZoomBigOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.8)",opacity:0}}),g=new o("antZoomUpIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 0%"}}),O=new o("antZoomUpOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 0%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0}}),l=new o("antZoomLeftIn",{"0%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"0% 50%"}}),u=new o("antZoomLeftOut",{"0%":{transform:"scale(1)",transformOrigin:"0% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0}}),p=new o("antZoomRightIn",{"0%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"100% 50%"}}),z=new o("antZoomRightOut",{"0%":{transform:"scale(1)",transformOrigin:"100% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0}}),K=new o("antZoomDownIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 100%"}}),w=new o("antZoomDownOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 100%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0}}),I={zoom:{inKeyframes:c,outKeyframes:y},"zoom-big":{inKeyframes:a,outKeyframes:s},"zoom-big-fast":{inKeyframes:a,outKeyframes:s},"zoom-left":{inKeyframes:l,outKeyframes:u},"zoom-right":{inKeyframes:p,outKeyframes:z},"zoom-up":{inKeyframes:g,outKeyframes:O},"zoom-down":{inKeyframes:K,outKeyframes:w}},h=(n,r)=>{const{antCls:m}=n,t=`${m}-${r}`,{inKeyframes:i,outKeyframes:e}=I[r];return[f(t,i,e,r==="zoom-big-fast"?n.motionDurationFast:n.motionDurationMid),{[`
1
+ import{K as o}from"./index-BVHdkz8F.js";import{i as f}from"./motion-CE7dWPPs.js";const c=new o("antZoomIn",{"0%":{transform:"scale(0.2)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),y=new o("antZoomOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.2)",opacity:0}}),a=new o("antZoomBigIn",{"0%":{transform:"scale(0.8)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),s=new o("antZoomBigOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.8)",opacity:0}}),g=new o("antZoomUpIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 0%"}}),O=new o("antZoomUpOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 0%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0}}),l=new o("antZoomLeftIn",{"0%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"0% 50%"}}),u=new o("antZoomLeftOut",{"0%":{transform:"scale(1)",transformOrigin:"0% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0}}),p=new o("antZoomRightIn",{"0%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"100% 50%"}}),z=new o("antZoomRightOut",{"0%":{transform:"scale(1)",transformOrigin:"100% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0}}),K=new o("antZoomDownIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 100%"}}),w=new o("antZoomDownOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 100%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0}}),I={zoom:{inKeyframes:c,outKeyframes:y},"zoom-big":{inKeyframes:a,outKeyframes:s},"zoom-big-fast":{inKeyframes:a,outKeyframes:s},"zoom-left":{inKeyframes:l,outKeyframes:u},"zoom-right":{inKeyframes:p,outKeyframes:z},"zoom-up":{inKeyframes:g,outKeyframes:O},"zoom-down":{inKeyframes:K,outKeyframes:w}},h=(n,r)=>{const{antCls:m}=n,t=`${m}-${r}`,{inKeyframes:i,outKeyframes:e}=I[r];return[f(t,i,e,r==="zoom-big-fast"?n.motionDurationFast:n.motionDurationMid),{[`
2
2
  ${t}-enter,
3
3
  ${t}-appear
4
4
  `]:{transform:"scale(0)",opacity:0,animationTimingFunction:n.motionEaseOutCirc,"&-prepare":{transform:"none"}},[`${t}-leave`]:{animationTimingFunction:n.motionEaseInOutCirc}}]};export{h as i,c as z};
@@ -8,7 +8,7 @@
8
8
  // Injected by web-ui-server.js at serve time
9
9
  window.__CC_CONFIG__ = __CC_CONFIG_PLACEHOLDER__;
10
10
  </script>
11
- <script type="module" crossorigin src="./assets/index-Ci3y1ZAv.js"></script>
11
+ <script type="module" crossorigin src="./assets/index-BVHdkz8F.js"></script>
12
12
  <link rel="modulepreload" crossorigin href="./assets/vendor-Bn1JzzAn.js">
13
13
  <link rel="modulepreload" crossorigin href="./assets/icons-DG5UD-6K.js">
14
14
  <link rel="stylesheet" crossorigin href="./assets/index-Cq93VfoF.css">
@@ -284,6 +284,13 @@ export function registerEvalCommand(program, { logger } = {}) {
284
284
  (log.error || console.error)(` otlp write failed: ${e.message}`);
285
285
  }
286
286
  }
287
+ try {
288
+ const { exportTelemetryRecorder } =
289
+ await import("../lib/observability/index.js");
290
+ exportTelemetryRecorder(recorder);
291
+ } catch {
292
+ // Collector export is best-effort and never changes evaluation gates.
293
+ }
287
294
 
288
295
  // Append to the trend history (a compact record — pass counts + per-task
289
296
  // pass/fail + a timestamp/label — so `cc eval --trend` can chart it).
@@ -1,6 +1,30 @@
1
1
  import chalk from "chalk";
2
2
  import logger from "../lib/logger.js";
3
3
  import { collectStatusReport } from "../runtime/diagnostics.js";
4
+ import { getObservabilityRuntime } from "../lib/observability/index.js";
5
+
6
+ export function collectOtlpStatus(runtime = getObservabilityRuntime()) {
7
+ return (
8
+ runtime?.getStats?.() || {
9
+ enabled: false,
10
+ protocol: "http/json",
11
+ tracesEndpoint: null,
12
+ metricsEndpoint: null,
13
+ queued: 0,
14
+ queueCapacity: 0,
15
+ queuePressure: "normal",
16
+ enqueued: 0,
17
+ exported: 0,
18
+ retried: 0,
19
+ dropped: 0,
20
+ permanentFailures: 0,
21
+ recovered: 0,
22
+ spoolErrors: 0,
23
+ configurationErrors: [],
24
+ lastError: null,
25
+ }
26
+ );
27
+ }
4
28
 
5
29
  export function registerStatusCommand(program) {
6
30
  program
@@ -10,6 +34,9 @@ export function registerStatusCommand(program) {
10
34
  .action(async (options) => {
11
35
  try {
12
36
  const report = await collectStatusReport();
37
+ report.observability = {
38
+ otlp: collectOtlpStatus(),
39
+ };
13
40
 
14
41
  if (options.json) {
15
42
  console.log(JSON.stringify(report, null, 2));
@@ -66,6 +93,34 @@ export function registerStatusCommand(program) {
66
93
  logger.log(` ${icon} ${p.name}: ${p.port}`);
67
94
  }
68
95
 
96
+ const otlp = report.observability.otlp;
97
+ logger.log(chalk.bold("\n OpenTelemetry Collector\n"));
98
+ if (!otlp.enabled) {
99
+ logger.log(` ${chalk.gray("○")} OTLP export disabled`);
100
+ if (otlp.configurationErrors?.length) {
101
+ logger.log(
102
+ ` configuration: ${otlp.configurationErrors.join("; ")}`,
103
+ );
104
+ }
105
+ } else {
106
+ logger.log(
107
+ ` ${chalk.green("●")} ${otlp.protocol} · queue ${otlp.queued}/${otlp.queueCapacity} (${otlp.queuePressure})`,
108
+ );
109
+ logger.log(` traces: ${otlp.tracesEndpoint || "disabled"}`);
110
+ logger.log(` metrics: ${otlp.metricsEndpoint || "disabled"}`);
111
+ if (otlp.retried || otlp.dropped || otlp.permanentFailures) {
112
+ logger.log(
113
+ ` retries ${otlp.retried}, dropped ${otlp.dropped}, permanent failures ${otlp.permanentFailures}`,
114
+ );
115
+ }
116
+ if (otlp.configurationErrors?.length) {
117
+ logger.log(
118
+ ` configuration: ${otlp.configurationErrors.join("; ")}`,
119
+ );
120
+ }
121
+ if (otlp.lastError) logger.log(` last error: ${otlp.lastError}`);
122
+ }
123
+
69
124
  logger.newline();
70
125
  } catch (err) {
71
126
  logger.error(`Status check failed: ${err.message}`);
@@ -573,17 +573,26 @@ export function registerTeamCommand(program, { logger } = {}) {
573
573
  });
574
574
  else runTask = async () => ({ dryRun: true });
575
575
 
576
- // Optional workflow tracing (Claude-Code 2.1.202 parity): every task
577
- // execution becomes a `team.task` span tagged with workflow.run_id +
578
- // workflow.name so a collector can reassemble the run as one workflow.
576
+ // Workflow tracing (Claude-Code 2.1.202 parity): every task execution can
577
+ // be written to a local OTLP file, exported to a Collector, or both.
579
578
  let recorder = null;
580
- if (options.otlp) {
579
+ let collectorEnabled = false;
580
+ try {
581
+ const { isOtlpCollectorEnabled } =
582
+ await import("../lib/observability/index.js");
583
+ collectorEnabled = isOtlpCollectorEnabled();
584
+ } catch {
585
+ collectorEnabled = false;
586
+ }
587
+ const workflowRunId = `team-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
588
+ const workflowName = path.basename(options.tasks);
589
+ if (options.otlp || collectorEnabled) {
581
590
  const { TelemetryRecorder } =
582
591
  await import("../lib/telemetry/span-recorder.js");
583
592
  recorder = new TelemetryRecorder({
584
593
  defaultAttributes: {
585
- "workflow.run_id": `team-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
586
- "workflow.name": path.basename(options.tasks),
594
+ "workflow.run_id": workflowRunId,
595
+ "workflow.name": workflowName,
587
596
  },
588
597
  });
589
598
  }
@@ -682,6 +691,22 @@ export function registerTeamCommand(program, { logger } = {}) {
682
691
  }
683
692
  }
684
693
 
694
+ if (collectorEnabled) {
695
+ try {
696
+ const { exportTelemetryRecorder, exportTeamTelemetry } =
697
+ await import("../lib/observability/index.js");
698
+ if (recorder) exportTelemetryRecorder(recorder);
699
+ exportTeamTelemetry({
700
+ workflowRunId,
701
+ workflowName,
702
+ summary,
703
+ budget,
704
+ });
705
+ } catch {
706
+ // Collector export is best-effort and never changes team settlement.
707
+ }
708
+ }
709
+
685
710
  // Worktree integration: sequentially preview (and optionally merge) each
686
711
  // committed branch back to base, then remove the worktrees. Conflicts are
687
712
  // reported, never force-merged.
@@ -1,6 +1,32 @@
1
1
  {
2
2
  "source": "CHANGELOG.md",
3
3
  "releases": [
4
+ {
5
+ "productVersion": null,
6
+ "cliVersion": "0.162.186",
7
+ "cliVersions": ["0.162.185", "0.162.186"],
8
+ "date": "2026-07-29",
9
+ "title": "",
10
+ "sections": [
11
+ {
12
+ "heading": "Added — cc CLI 0.162.186: standard OpenTelemetry Collector export",
13
+ "body": "> `chainlesschain` **0.162.185 → 0.162.186** (2026-07-29).\n> CLI-only release; `@chainlesschain/personal-data-hub` remains **0.4.57**\n> and `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Standard Collector protocols**: traces and metrics export over OTLP/HTTP\n JSON, OTLP/HTTP protobuf, or OTLP/gRPC, with standard global and per-signal\n endpoint, protocol, header, timeout, compression, service, and resource\n environment variables.\n- **Enterprise transport**: HTTPS and HTTP/2 gRPC support custom CA trust plus\n client certificate/key mTLS without allowing custom headers to override\n protocol framing.\n- **Bounded delivery**: batching, queue-pressure reporting, `Retry-After` and\n exponential retries, permanent-failure/drop counters, and atomic per-process\n crash spools provide bounded recovery without stealing a live process queue.\n- **Real runtime wiring**: agent, eval, and team recorders feed the Collector;\n team runs add task, token, USD cost, failure, and completion aggregates with\n workflow dimensions. Normal and gated exits perform a final flush.\n- **Private by default**: prompt, response, and tool-argument content stays\n local unless explicitly enabled; all exported string attributes and events\n continue through secret redaction.\n- **Release validation gate**: publication requires this exact release commit\n to pass `CLI CI` and `CLI Strict Sandbox` on their configured Ubuntu,\n Windows, and macOS runners; local tests remain supplementary."
14
+ }
15
+ ]
16
+ },
17
+ {
18
+ "productVersion": null,
19
+ "cliVersion": "0.162.185",
20
+ "cliVersions": ["0.162.184", "0.162.185"],
21
+ "date": "2026-07-29",
22
+ "title": "",
23
+ "sections": [
24
+ {
25
+ "heading": "Fixed — cc CLI 0.162.185: sandbox authority and Hook runtime hardening",
26
+ "body": "> `chainlesschain` **0.162.184 → 0.162.185** (2026-07-29).\n> CLI-only release; `@chainlesschain/personal-data-hub` remains **0.4.57**\n> and `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Complete strong execution routes**: policy-bearing Plugin bins now retain\n pinned identity through async/background launches, while generic background,\n CLI PTY, and Desktop project PTY enter the same fail-closed Linux\n filesystem/network boundary.\n- **Authority and teardown integrity**: every actual bind source requires\n private mount propagation, parent-side pinned descriptors close after spawn,\n raw PTY masters invalidate on close/error, and attached sessions terminate\n their POSIX process group or Windows process tree.\n- **Trusted project and Hook roots**: Desktop V8 migrations quarantine\n unattested project roots and prevent remote metadata from acquiring local PTY\n authority. Hooks v2 binds canonical host roots to generation-aware opaque\n durable identities across headless, stream, REPL, and WebSocket turns.\n- **Hook process reliability**: completed Hook subprocesses preserve their\n status-0 output and status-2 block protocol when Node reports a late stdin\n `EPIPE`; missing exit status and unrelated spawn errors still fail closed.\n- **Single Broker runtime graph**: Hooks v2 now registers its default runtime\n as the Broker event sink without a reverse ESM load, preventing a duplicate\n CredentialTransport Worker, Unix listener, and steady-state file descriptors.\n- **Release validation gate**: publication requires this exact release commit\n to pass `CLI CI` and `CLI Strict Sandbox` on their configured Ubuntu,\n Windows, and macOS runners; local tests remain supplementary."
27
+ }
28
+ ]
29
+ },
4
30
  {
5
31
  "productVersion": null,
6
32
  "cliVersion": "0.162.184",
@@ -20,6 +20,7 @@
20
20
  import EventEmitter from "events";
21
21
  import { randomUUID } from "crypto";
22
22
  import { createRequire } from "module";
23
+ import path from "node:path";
23
24
  import { RingBuffer } from "./RingBuffer.js";
24
25
  import { executionBroker } from "../../lib/process-execution-broker/index.js";
25
26
 
@@ -91,11 +92,17 @@ export class PtyManager extends EventEmitter {
91
92
  ) {
92
93
  throw new TypeError("resolveSandboxPolicy must be a function or null");
93
94
  }
94
- this._policyCwd = opts.policyCwd || process.cwd();
95
+ this._policyCwd = path.resolve(opts.policyCwd || process.cwd());
95
96
  this._resolveSandboxPolicy = resolveSandboxPolicy;
96
97
  this._deps = {
97
98
  loadNodePty: opts._deps?.loadNodePty || (() => require("node-pty")),
98
99
  spawnPty: opts._deps?.spawnPty || null,
100
+ issueLinuxWorkspaceSandboxExecutionContract:
101
+ opts._deps?.issueLinuxWorkspaceSandboxExecutionContract ||
102
+ executionBroker.issueLinuxWorkspaceSandboxExecutionContract.bind(
103
+ executionBroker,
104
+ ),
105
+ platform: opts._deps?.platform || (() => process.platform),
99
106
  now: opts._deps?.now || (() => Date.now()),
100
107
  };
101
108
  this._sessions = new Map();
@@ -120,7 +127,10 @@ export class PtyManager extends EventEmitter {
120
127
  throw new Error("shell_not_allowed");
121
128
  }
122
129
 
123
- const cwd = req.cwd || this.config.defaultCwd || process.cwd();
130
+ const cwd = path.resolve(
131
+ this._policyCwd,
132
+ req.cwd || this.config.defaultCwd || this._policyCwd,
133
+ );
124
134
  // A remote cwd may discover a stricter policy, but it must never replace
125
135
  // the fixed workspace root supplied by the host. Resolve and validate the
126
136
  // pinned policy before loading node-pty or allocating a native terminal.
@@ -133,15 +143,6 @@ export class PtyManager extends EventEmitter {
133
143
  )
134
144
  : null;
135
145
 
136
- let pty;
137
- try {
138
- pty = this._deps.loadNodePty();
139
- } catch {
140
- const err = new Error("pty_native_unavailable");
141
- err.cause = "node-pty failed to load (native binding missing)";
142
- throw err;
143
- }
144
-
145
146
  const cols = Number.isFinite(req.cols) ? req.cols : 80;
146
147
  const rows = Number.isFinite(req.rows) ? req.rows : 24;
147
148
  const cmd = resolveShellCmd(shell);
@@ -152,9 +153,7 @@ export class PtyManager extends EventEmitter {
152
153
  req.env && typeof req.env === "object" && !Array.isArray(req.env)
153
154
  ? req.env
154
155
  : {};
155
- const spawnPty =
156
- this._deps.spawnPty || executionBroker.spawnPty.bind(executionBroker);
157
- const proc = spawnPty(pty, cmd, [], {
156
+ const brokerSpawnOptions = {
158
157
  name: "xterm-256color",
159
158
  cols,
160
159
  rows,
@@ -163,8 +162,39 @@ export class PtyManager extends EventEmitter {
163
162
  origin: "terminal:pty",
164
163
  policy: "allow",
165
164
  scope: "terminal",
165
+ shell: false,
166
166
  ...(sandboxPolicy ? { sandboxPolicy } : {}),
167
- });
167
+ };
168
+ if (sandboxPolicy && this._deps.platform() === "linux") {
169
+ const contract = this._deps.issueLinuxWorkspaceSandboxExecutionContract(
170
+ cmd,
171
+ [],
172
+ brokerSpawnOptions,
173
+ this._policyCwd,
174
+ { pty: true },
175
+ );
176
+ if (!contract) {
177
+ const error = new Error("pty_sandbox_contract_unavailable");
178
+ error.code = "ERR_PTY_SANDBOX_CONTRACT_UNAVAILABLE";
179
+ error.sandboxFailClosed = true;
180
+ error.requiredBoundaries = [...sandboxPolicy.requiredBoundaries];
181
+ throw error;
182
+ }
183
+ brokerSpawnOptions.sandboxExecutionContract = contract;
184
+ }
185
+
186
+ let pty;
187
+ try {
188
+ pty = this._deps.loadNodePty();
189
+ } catch {
190
+ const err = new Error("pty_native_unavailable");
191
+ err.cause = "node-pty failed to load (native binding missing)";
192
+ throw err;
193
+ }
194
+
195
+ const spawnPty =
196
+ this._deps.spawnPty || executionBroker.spawnPty.bind(executionBroker);
197
+ const proc = spawnPty(pty, cmd, [], brokerSpawnOptions);
168
198
 
169
199
  const sessionId = randomUUID();
170
200
  const session = new PtySession({
@@ -27,6 +27,10 @@ import { runnableTaskModel } from "../../lib/runnable-provider.js";
27
27
  import { PlanState } from "../../lib/plan-mode.js";
28
28
  import { CLISlotFiller } from "../../lib/slot-filler.js";
29
29
  import { createAbortError, isAbortError } from "../../lib/abort-utils.js";
30
+ import {
31
+ resolveRegisteredHostHooksV2Workspace,
32
+ runWithHostHooksV2Workspace,
33
+ } from "../../lib/hooks-v2-workspace-context.js";
30
34
  import { createWsApprovalGate } from "./ws-approval-gate.js";
31
35
 
32
36
  export class WSAgentHandler {
@@ -166,7 +170,7 @@ export class WSAgentHandler {
166
170
  diffReviewFollowUps = new DiffReviewFollowUpTracker(sideEffectLedger);
167
171
  let currentSideEffectOpId = null;
168
172
 
169
- const runAgentTurn = async () => {
173
+ const executeAgentTurn = async () => {
170
174
  for await (const event of agentLoop(session.messages, loopOptions)) {
171
175
  switch (event.type) {
172
176
  case "slot-filling":
@@ -250,6 +254,16 @@ export class WSAgentHandler {
250
254
  }
251
255
  }
252
256
  };
257
+ const hooksWorkspaceBinding = resolveRegisteredHostHooksV2Workspace(
258
+ session.hooksV2WorkspaceBindingId,
259
+ );
260
+ const runAgentTurn = () =>
261
+ hooksWorkspaceBinding
262
+ ? runWithHostHooksV2Workspace(
263
+ hooksWorkspaceBinding.workspaceRoot,
264
+ executeAgentTurn,
265
+ )
266
+ : executeAgentTurn();
253
267
 
254
268
  if (session.mcpClient?.withElicitationContext) {
255
269
  await session.mcpClient.withElicitationContext(
@@ -45,6 +45,52 @@ import {
45
45
  CODING_AGENT_MVP_TOOL_NAMES,
46
46
  listCodingAgentToolNames,
47
47
  } from "../../runtime/coding-agent-contract.js";
48
+ import {
49
+ registerHostHooksV2Workspace,
50
+ releaseRegisteredHostHooksV2Workspace,
51
+ } from "../../lib/hooks-v2-workspace-context.js";
52
+
53
+ function normalizeHostWorkspaceRoot(workspaceRoot) {
54
+ if (
55
+ typeof workspaceRoot !== "string" ||
56
+ workspaceRoot.length === 0 ||
57
+ workspaceRoot.includes("\0")
58
+ ) {
59
+ return null;
60
+ }
61
+ try {
62
+ return path.resolve(workspaceRoot);
63
+ } catch {
64
+ return null;
65
+ }
66
+ }
67
+
68
+ function bindSessionHooksV2Workspace(
69
+ session,
70
+ workspaceRoot,
71
+ { releaseOnClose = false, protectedBindingId = null } = {},
72
+ ) {
73
+ const binding = workspaceRoot
74
+ ? registerHostHooksV2Workspace(workspaceRoot)
75
+ : null;
76
+ Object.defineProperty(session, "hooksV2WorkspaceBindingId", {
77
+ value: binding?.bindingId || null,
78
+ enumerable: false,
79
+ writable: false,
80
+ configurable: false,
81
+ });
82
+ Object.defineProperty(session, "_releaseHooksV2WorkspaceBindingOnClose", {
83
+ value: Boolean(
84
+ binding &&
85
+ releaseOnClose === true &&
86
+ binding.bindingId !== protectedBindingId,
87
+ ),
88
+ enumerable: false,
89
+ writable: false,
90
+ configurable: false,
91
+ });
92
+ return session.hooksV2WorkspaceBindingId;
93
+ }
48
94
 
49
95
  /**
50
96
  * @typedef {object} Session
@@ -85,6 +131,15 @@ export class WSSessionManager {
85
131
  this.db = options.db || null;
86
132
  this.config = options.config || {};
87
133
  this.defaultProjectRoot = options.defaultProjectRoot || process.cwd();
134
+ // Snapshot constructor authority once. Later request fields (and even a
135
+ // mutable compatibility assignment to defaultProjectRoot) cannot replace
136
+ // the root used for strong Hooks v2 execution.
137
+ this._hooksV2HostWorkspaceRoot = normalizeHostWorkspaceRoot(
138
+ this.defaultProjectRoot,
139
+ );
140
+ this._hooksV2HostWorkspaceBindingId = this._hooksV2HostWorkspaceRoot
141
+ ? registerHostHooksV2Workspace(this._hooksV2HostWorkspaceRoot).bindingId
142
+ : null;
88
143
  this.mcpClient = options.mcpClient || null;
89
144
  this.allowedMcpServerNames = Array.isArray(options.allowedMcpServerNames)
90
145
  ? options.allowedMcpServerNames
@@ -324,6 +379,11 @@ export class WSSessionManager {
324
379
  const sessionId = this._generateId();
325
380
  const type = options.type || "agent";
326
381
  const baseProjectRoot = options.projectRoot || this.defaultProjectRoot;
382
+ const hostAuthorizedBaseRoot =
383
+ normalizeHostWorkspaceRoot(baseProjectRoot) ===
384
+ this._hooksV2HostWorkspaceRoot
385
+ ? this._hooksV2HostWorkspaceRoot
386
+ : null;
327
387
  const cfgLlm = this.config?.llm || {};
328
388
  const provider = options.provider || cfgLlm.provider || "ollama";
329
389
  const model =
@@ -435,6 +495,18 @@ export class WSSessionManager {
435
495
  createdAt: new Date().toISOString(),
436
496
  lastActivity: new Date().toISOString(),
437
497
  };
498
+ bindSessionHooksV2Workspace(
499
+ session,
500
+ hostAuthorizedBaseRoot
501
+ ? worktree
502
+ ? normalizeHostWorkspaceRoot(projectRoot)
503
+ : hostAuthorizedBaseRoot
504
+ : null,
505
+ {
506
+ releaseOnClose: Boolean(hostAuthorizedBaseRoot && worktree),
507
+ protectedBindingId: this._hooksV2HostWorkspaceBindingId,
508
+ },
509
+ );
438
510
 
439
511
  if (this.db) {
440
512
  try {
@@ -546,6 +618,15 @@ export class WSSessionManager {
546
618
  createdAt: dbSession.created_at,
547
619
  lastActivity: new Date().toISOString(),
548
620
  };
621
+ const recoveredHooksWorkspaceRoot =
622
+ metadata.worktreeIsolation !== true &&
623
+ normalizeHostWorkspaceRoot(baseProjectRoot) ===
624
+ this._hooksV2HostWorkspaceRoot &&
625
+ normalizeHostWorkspaceRoot(workspace.projectRoot) ===
626
+ this._hooksV2HostWorkspaceRoot
627
+ ? this._hooksV2HostWorkspaceRoot
628
+ : null;
629
+ bindSessionHooksV2Workspace(session, recoveredHooksWorkspaceRoot);
549
630
 
550
631
  this._bindPlanManagerPersistence(session);
551
632
  this.sessions.set(session.id, session);
@@ -564,6 +645,13 @@ export class WSSessionManager {
564
645
  const session = this.sessions.get(sessionId);
565
646
  if (!session) return;
566
647
 
648
+ if (
649
+ session._releaseHooksV2WorkspaceBindingOnClose === true &&
650
+ session.hooksV2WorkspaceBindingId
651
+ ) {
652
+ releaseRegisteredHostHooksV2Workspace(session.hooksV2WorkspaceBindingId);
653
+ }
654
+
567
655
  session.status = "closed";
568
656
 
569
657
  // Persist messages to DB