chainlesschain 0.166.90 → 0.166.91

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 (172) hide show
  1. package/README.md +9 -7
  2. package/package.json +3 -3
  3. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  4. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  5. package/src/assets/web-panel/assets/{AIOps-CZzXRe1-.js → AIOps-DgV7xb8F.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-_AZfbW1Q.js → ActionButton-CgANpkKu.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-CzaUx_wv.js → Analytics-DnvpX7RB.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-xHEeeD-m.js → AppLayout-C2bHccBM.js} +4 -4
  9. package/src/assets/web-panel/assets/{Artifacts-DmTbtudE.js → Artifacts-BIhijC9g.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-Cn4ng4fo.js → Audit-CKRjWGdp.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-DLUY1VD2.js → BackgroundAgents-CblYtgBE.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-B2v--wB6.js → Backup-Cq35b78a.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-Bgih7yAv.js → BaseInput-DcB7NoRz.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-1MiiA3yA.js → Chat-tc3b-s7i.js} +5 -5
  15. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CPLynmbb.js → ChatBubbleRenderer-fcc_Tvqu.js} +1 -1
  16. package/src/assets/web-panel/assets/{Checkbox-DsyBa_NO.js → Checkbox-BLD5bH5u.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-B7WCFx9H.js → Codegen-BLOsoazN.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-D2x4GBGm.js → Col-Bdr7JwIx.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-Rnwg9nea.js → Community-C84BsWE0.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-BPczlrRh.js → Compact-Dzdwd04z.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-Br1L_wGU.js → Compliance-CCG-R0EV.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-DlsWB_oS.js → Cowork-BYj72SK0.js} +3 -3
  23. package/src/assets/web-panel/assets/{Cron-BWo_KGpG.js → Cron-B6iKAwOf.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-Cug7N8ge.js → Crosschain-BJ-oDC6u.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-CMbyOZJN.js → DID-BnMckGLr.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-C4dl_UaE.js → Dashboard-Cyje-gCO.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-CBrC7M-9.js → Dropdown-BpNlenjK.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-DTq7tU4b.js → EmailListRenderer-BhonO7Nv.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-DWP3csxS.js → EvolutionSettings-DVoNU-Id.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DZl7zuv_.js → FamilyGuardDashboard-tdn-KC67.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-W-GSlVK5.js → Federation--EEVrHhz.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-DMB7xYFV.js → FormItemContext-Cy8zr0-4.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-DNv8GEoq.js → GenericCardRenderer-BuUhpgFi.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-BZ0Bbzw6.js → Git-Ctd3E5Pe.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-BNEdcOM5.js → Governance-Ce7dV6aU.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-C8249gIz.js → Inference-CD1vExIH.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-ngzebU3e.js → KnowledgeGraph-Dn64OdQ7.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-CP15th-f.js → Logs-PmElVRrT.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-CW3B3JDq.js → MarkdownRenderer-BFiVKf5t.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-CaH59OsY.js → Marketplace-OW4jTXwx.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-C07vnJev.js → McpTools-BEq2Ib4x.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-CqAOkVAS.js → Memory-Can_P2oK.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-qp7mZimq.js → MobileBridge-DJ8R-dn3.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-DKhbqvTw.js → MobileProjects-B7kV9GOt.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-CRYCnWXv.js → Mtc-BfxamolS.js} +4 -4
  46. package/src/assets/web-panel/assets/{MtcAudit-Z08IrKws.js → MtcAudit-DHtuv7av.js} +4 -4
  47. package/src/assets/web-panel/assets/{Multisig-BWdatUnH.js → Multisig-DLkLpvxc.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-BKWiCZ_m.js → NLProgramming-u4XtJTIt.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-Bgpzk3sm.js → Notes-BwuuPJLS.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-DvtZEktR.js → NotificationSettings-HEeu-E9v.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-CBcy0szc.js → OrderTableRenderer-BtvN-Qwh.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-DRRL6vW1.js → Organization-Yh-czs3b.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-COmfB8Ns.js → Overflow-DmE8mYVM.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-BqMq_DSa.js → P2P-CWVck8WN.js} +2 -2
  55. package/src/assets/web-panel/assets/PdhVaultBrowser-DgFqekod.js +7 -0
  56. package/src/assets/web-panel/assets/{Permissions-DzYkjmV_.js → Permissions-BtJBVOHV.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-BBTcxBbN.js → PersonalDataHub-6VBObXzd.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-eRkYFSbO.js → Pipeline-D222FmqY.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-Ch7IFKBh.js → Privacy-Bi9FMikp.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-Ci8EcBYg.js → ProjectInit-Bo52H47H.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-B4lYHFbI.js → ProjectSettings-BPkesfOc.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-zkE5cCo_.js → Projects-GynohSFX.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-BKDVD3_e.js → Providers-DVdMg04n.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-BromrHlf.js → QrScannerModal-DqJCb595.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-CCgoY1gR.js → QuickAsk-J7loQbXi.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-DCPZvpq7.js → Recommend-BI5aURVc.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-DPnFP8HU.js → RemoteSession-BN2sqGvz.js} +3 -3
  68. package/src/assets/web-panel/assets/{Reputation-l6r8ytAs.js → Reputation-BGOND-Fi.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-ke9Mk1cx.js → Row-77dfwaUk.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-DQOEzUEn.js → RssFeed-FtBAxS3g.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-BqgA0aUz.js → Search-BaYVLFb7.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-FeGD_jqV.js → Security-LE3Vv6ab.js} +3 -3
  73. package/src/assets/web-panel/assets/{Services-4kiYYAjZ.js → Services-C5pP-Whz.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-BbU8Xegs.js → Skeleton-CLqKUVsF.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-Dl2bUMUL.js → Skills-BPjN0SX5.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-xRGALeaZ.js → Sla-14jD70kg.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-DZfd4RDm.js → SpeechSettings-Dr9ij42W.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-BRtCV9Ga.js → SyncSettings-BzLHP7B8.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-DVRQklfG.js → Tasks-YqV9b0rV.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-BbhE5jt5.js → Templates-CxxAE4PK.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-qXPDNKbK.js → Tenant-CRb3PcKJ.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-CV48Ks7E.js → Terminal-CTzPpBaP.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-BLGfJIDr.js → TimelineRenderer-DjFUj_hy.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-7G9H6Hrt.js → Tokens-Bbb8tPvx.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger--F64N11F.js → Trigger-CSeWGM0W.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-Cq1r-D_y.js → Trust-JgESMBo3.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-Dqyu4RVh.js → UkeySign-CiObLk0T.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-DuFmWH_B.js → VideoEditing-CFEZaQ2x.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-C3mg7EWP.js → Wallet-DR8ZGDNn.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-CDK-Aj_X.js → WebAuthn-DxZukvu7.js} +5 -5
  91. package/src/assets/web-panel/assets/{WorkflowEditor--K7K-T1F.js → WorkflowEditor-CKgSZQwn.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-BQDcS6VP.js → chat-CTxEQE66.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-BKxJL2-T.js → colors-CAjKMUu3.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-CFjQAMbY.js → compact-item-BXuz49at.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-DbgCsdQd.js → createContext-CFN_Hwr9.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-CfB8DxT2.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-BhkaOBNv.js → hasIn-BwoSBSfP.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-D-Yh3-1z.js → index-B0QbLlWn.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BfGGsAU7.js → index-B2o_BBjg.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CoOu7sdP.js → index-B2tEnBPx.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BRqlCTrz.js → index-B7kp-zRE.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CB4oHynY.js → index-B9yR7zqr.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DEwHywz9.js → index-BK4ftQ4d.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Du_SxxBY.js → index-Bj4hIiLW.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DFt48Z-x.js → index-BmQITjMU.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DdcrixaQ.js → index-BmXpdcHI.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BuWPqSGT.js → index-Bqv_Cray.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DmYK9Tqt.js → index-Bu2P6u8m.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-T9ka3Xj3.js → index-Bw9s2d3c.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-COGy6wXn.js → index-C8er4W9u.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-sKfUUldY.js → index-CB3kVd9c.js} +1 -1
  112. package/src/assets/web-panel/assets/index-CCsRfd0k.js +1 -0
  113. package/src/assets/web-panel/assets/{index-Dhfa_BIl.js → index-CF9lWi1o.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CRtUDiXx.js → index-CN53dE_u.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-D2Zb-Kd1.js → index-CSmFby3Q.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DP1NrM9J.js → index-CehdwJ_Q.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-aPdVzagA.js → index-Cgk0YEiq.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-3YutaXnp.js → index-Cp5y7lX_.js} +1 -1
  119. package/src/assets/web-panel/assets/index-CsmiZIQ4.js +1 -0
  120. package/src/assets/web-panel/assets/{index-C0DzhUOX.js → index-DTX9CJPx.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-bMX8BBLE.js → index-DViK2bkv.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Dn2QSsuI.js → index-DY-gBSm8.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BNjYPJNU.js → index-DjF5BOZx.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CE506mgj.js → index-DmkbAADP.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-De7daEnc.js → index-DpdDnZX_.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-3uR0ThJO.js → index-Dv7V2kg6.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CUs7XpUO.js → index-DxunxaTw.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-3djsY75k.js → index-F2E5RCwz.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-D9sVcw6v.js → index-IY9bd5az.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DJ2OiRvh.js → index-IahILygB.js} +3 -3
  131. package/src/assets/web-panel/assets/{index-DjmVlpap.js → index-T3MTE6jB.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-CSUDlsIr.js → index-Tz5dheZa.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-B4LlAJqc.js → index-_ZtCyUdz.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-CJoXgJ2N.js → index-o9DpkZKf.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-7BY44UEv.js → index-t2Ch_JKn.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-DvWWFJHJ.js → index-u9_DM3ZC.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-wrqabmui.js → initDefaultProps-BoiGJDoO.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-BoyB3ilP.js → motion-5eL4E0pA.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-Cq31cSFE.js → move-DjggDi_1.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-BkxNt-8H.js → mtc-parser-Ce8Vo2T3.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-DofGni53.js → omit-D1yOBaO2.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-BnluLL16.js → pickAttrs-8NLceQe8.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-C-yegJSP.js → placementArrow-CsIdBRmQ.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-CD3ziNhu.js → responsiveObserve-GM5NE8En.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-ToZO4gQ1.js → slide-44yj3u49.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-DFVmDmVl.js → statusUtils-B8tqtWcX.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-De0Y8g1O.js → styleChecker-NhDPBbyB.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-wBKIYFKX.js → useFlexGapSupport-C8Qz1GtN.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-CP9nmUMJ.js → useFs-ClUv4kih.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-vFGrVDyp.js → usePersonalDataHub-BwkOVEh6.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-BcBIjvjH.js → vnode--gMF33R0.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-DnXDAQxA.js → zoom-DXg3TqOP.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +1 -1
  155. package/src/commands/agent-process-ownership.js +121 -0
  156. package/src/commands/agent.js +2 -0
  157. package/src/commands/hub.js +86 -9
  158. package/src/data/changelog.json +15 -2
  159. package/src/lib/audit-logger.js +46 -20
  160. package/src/lib/checkpoint-restore-saga.js +11 -1
  161. package/src/lib/eval/verify01-host-evidence.js +36 -3
  162. package/src/lib/process-execution-broker/index.js +91 -1
  163. package/src/lib/process-execution-broker/platform-sandbox.js +42 -0
  164. package/src/lib/process-execution-broker/windows-native-evaluator-capabilities.js +757 -0
  165. package/src/lib/process-execution-broker/windows-native-evaluator.js +316 -0
  166. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  167. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  168. package/src/lib/process-execution-broker/windows-sandbox.cs +383 -11
  169. package/src/assets/web-panel/assets/PdhVaultBrowser-BX7iNvle.js +0 -7
  170. package/src/assets/web-panel/assets/devWarning-DlIv9Mbc.js +0 -1
  171. package/src/assets/web-panel/assets/index-BC972Grv.js +0 -1
  172. package/src/assets/web-panel/assets/index-CVifyQqL.js +0 -1
@@ -6,6 +6,8 @@ using System.IO;
6
6
  using Microsoft.Win32.SafeHandles;
7
7
  using System.Runtime.InteropServices;
8
8
  using System.Security.Cryptography;
9
+ using System.Security.AccessControl;
10
+ using System.Security.Principal;
9
11
  using System.Runtime.Serialization;
10
12
  using System.Runtime.Serialization.Json;
11
13
  using System.Text;
@@ -404,6 +406,45 @@ namespace ChainlessChain.WindowsSandbox
404
406
  private static extern Int32 DeleteAppContainerProfile(
405
407
  string appContainerName);
406
408
 
409
+ [DllImport("FirewallAPI.dll")]
410
+ private static extern UInt32 NetworkIsolationGetAppContainerConfig(out UInt32 count, out IntPtr sids);
411
+
412
+ [DllImport("kernel32.dll")]
413
+ private static extern IntPtr GetProcessHeap();
414
+
415
+ [DllImport("kernel32.dll")]
416
+ [return: MarshalAs(UnmanagedType.Bool)]
417
+ private static extern bool HeapFree(IntPtr heap, UInt32 flags, IntPtr memory);
418
+
419
+ private static void AssertNoLoopbackExemption(IntPtr appSid)
420
+ {
421
+ UInt32 count;
422
+ IntPtr entries;
423
+ UInt32 result = NetworkIsolationGetAppContainerConfig(out count, out entries);
424
+ if (result != 0) throw new Win32Exception(checked((int)result), "Cannot attest AppContainer loopback exclusions");
425
+ // SID_AND_ATTRIBUTES contains a pointer and DWORD; x64 tail padding
426
+ // makes each entry two pointer widths. Free each SID and the array
427
+ // with the process heap, as documented by this API.
428
+ int stride = IntPtr.Size == 8 ? 16 : 8;
429
+ try
430
+ {
431
+ if (count > 65536 || (count > 0 && entries == IntPtr.Zero))
432
+ throw new InvalidDataException("Invalid AppContainer loopback configuration");
433
+ for (UInt32 index = 0; index < count; index++)
434
+ if (EqualSid(Marshal.ReadIntPtr(entries, checked((int)index * stride)), appSid))
435
+ throw new InvalidDataException("Native evaluator SID has a loopback exemption");
436
+ }
437
+ finally
438
+ {
439
+ if (entries != IntPtr.Zero)
440
+ {
441
+ for (UInt32 index = 0; index < Math.Min(count, 65536U); index++)
442
+ HeapFree(GetProcessHeap(), 0, Marshal.ReadIntPtr(entries, checked((int)index * stride)));
443
+ HeapFree(GetProcessHeap(), 0, entries);
444
+ }
445
+ }
446
+ }
447
+
407
448
  [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
408
449
  private static extern IntPtr _get_osfhandle(Int32 fileDescriptor);
409
450
 
@@ -584,6 +625,13 @@ namespace ChainlessChain.WindowsSandbox
584
625
  UInt32 desiredAccess,
585
626
  out IntPtr token);
586
627
 
628
+ [DllImport("advapi32.dll", EntryPoint = "SetFileSecurityW", CharSet = CharSet.Unicode, SetLastError = true)]
629
+ [return: MarshalAs(UnmanagedType.Bool)]
630
+ private static extern bool SetFileSecurity(
631
+ string path,
632
+ UInt32 securityInformation,
633
+ byte[] securityDescriptor);
634
+
587
635
  [DllImport("advapi32.dll", SetLastError = true)]
588
636
  [return: MarshalAs(UnmanagedType.Bool)]
589
637
  private static extern bool CreateRestrictedToken(
@@ -995,7 +1043,7 @@ namespace ChainlessChain.WindowsSandbox
995
1043
  "restriction status");
996
1044
  }
997
1045
 
998
- private static bool TokenHasUnexpectedEnabledPrivileges(IntPtr token)
1046
+ private static bool TokenHasUnexpectedEnabledPrivileges(IntPtr token, bool includeDisabled = false)
999
1047
  {
1000
1048
  IntPtr privilegesBuffer = IntPtr.Zero;
1001
1049
  try
@@ -1049,11 +1097,11 @@ namespace ChainlessChain.WindowsSandbox
1049
1097
  privilegeName.ToString(),
1050
1098
  "SeChangeNotifyPrivilege",
1051
1099
  StringComparison.Ordinal) &&
1052
- (
1100
+ (includeDisabled || (
1053
1101
  privilege.Attributes &
1054
1102
  (
1055
1103
  SE_PRIVILEGE_ENABLED |
1056
- SE_PRIVILEGE_ENABLED_BY_DEFAULT)) != 0)
1104
+ SE_PRIVILEGE_ENABLED_BY_DEFAULT)) != 0))
1057
1105
  {
1058
1106
  return true;
1059
1107
  }
@@ -1244,7 +1292,8 @@ namespace ChainlessChain.WindowsSandbox
1244
1292
  StringComparison.Ordinal))
1245
1293
  {
1246
1294
  throw new InvalidDataException(
1247
- "Target AppContainer token retained an unexpected privilege");
1295
+ "Target AppContainer token retained an unexpected privilege: " + privilegeName +
1296
+ " (attributes=" + privilege.Attributes + ")");
1248
1297
  }
1249
1298
  }
1250
1299
  return SidToString(actualAppContainerSid);
@@ -2102,6 +2151,7 @@ namespace ChainlessChain.WindowsSandbox
2102
2151
  string finalPath,
2103
2152
  FILE_ID_INFO handleIdentity,
2104
2153
  UInt64 handlePathStatFileId,
2154
+ bool allowDirectory,
2105
2155
  out NodeFileIdentityProjection fixedProjection,
2106
2156
  out NodeFileIdentityProjection node22Projection)
2107
2157
  {
@@ -2131,8 +2181,10 @@ namespace ChainlessChain.WindowsSandbox
2131
2181
  }
2132
2182
 
2133
2183
  UInt64 pathStatFileId = unchecked((UInt64)information.FileId);
2184
+ // Evaluator guards also attest directories. Keep the caller's
2185
+ // type restriction consistent across fast and legacy stat paths.
2134
2186
  if (
2135
- (information.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ||
2187
+ (!allowDirectory && (information.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) ||
2136
2188
  (information.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 ||
2137
2189
  information.VolumeSerialNumber !=
2138
2190
  handleIdentity.VolumeSerialNumber ||
@@ -2165,13 +2217,14 @@ namespace ChainlessChain.WindowsSandbox
2165
2217
  }
2166
2218
 
2167
2219
  private static LaunchPathFileIdentity ReadLaunchPathFileIdentity(
2168
- IntPtr handle)
2220
+ IntPtr handle,
2221
+ bool allowDirectory = false)
2169
2222
  {
2170
2223
  BY_HANDLE_FILE_INFORMATION basic;
2171
2224
  if (!GetFileInformationByHandle(handle, out basic))
2172
2225
  ThrowLastError("GetFileInformationByHandle(launch path)");
2173
2226
  if (
2174
- (basic.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ||
2227
+ (!allowDirectory && (basic.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) ||
2175
2228
  (basic.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0)
2176
2229
  {
2177
2230
  throw new InvalidDataException(
@@ -2201,6 +2254,7 @@ namespace ChainlessChain.WindowsSandbox
2201
2254
  finalPath,
2202
2255
  fileId,
2203
2256
  handlePathStatFileId,
2257
+ allowDirectory,
2204
2258
  out fixedFastNodeIdentity,
2205
2259
  out node22FastNodeIdentity);
2206
2260
  }
@@ -3203,6 +3257,248 @@ namespace ChainlessChain.WindowsSandbox
3203
3257
  }
3204
3258
  }
3205
3259
 
3260
+ [DataContract]
3261
+ public sealed class EvaluatorPathSpec
3262
+ {
3263
+ [DataMember] public string path { get; set; }
3264
+ [DataMember] public string dev { get; set; }
3265
+ [DataMember] public string ino { get; set; }
3266
+ [DataMember] public long bytes { get; set; }
3267
+ [DataMember] public string sha256 { get; set; }
3268
+ }
3269
+
3270
+ [DataContract]
3271
+ public sealed class NativeEvaluatorSpec
3272
+ {
3273
+ [DataMember] public int version { get; set; }
3274
+ [DataMember] public string root { get; set; }
3275
+ [DataMember] public string workspace { get; set; }
3276
+ [DataMember] public string control { get; set; }
3277
+ [DataMember] public string scratch { get; set; }
3278
+ [DataMember] public string check { get; set; }
3279
+ [DataMember] public int wallTimeMs { get; set; }
3280
+ [DataMember] public string manifestDigest { get; set; }
3281
+ [DataMember] public EvaluatorPathSpec runtime { get; set; }
3282
+ [DataMember] public EvaluatorPathSpec[] directories { get; set; }
3283
+ [DataMember] public EvaluatorPathSpec[] files { get; set; }
3284
+ }
3285
+
3286
+ private static bool SameEvaluatorPath(string left, string right)
3287
+ {
3288
+ return String.Equals(Path.GetFullPath(left), Path.GetFullPath(right), StringComparison.OrdinalIgnoreCase);
3289
+ }
3290
+
3291
+ private static IntPtr HoldEvaluatorPath(string file, bool directory, List<IntPtr> guards)
3292
+ {
3293
+ ValidateExistingLocalPath(file, "Native evaluator path", false);
3294
+ SECURITY_ATTRIBUTES attributes = new SECURITY_ATTRIBUTES();
3295
+ attributes.nLength = checked((UInt32)Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES)));
3296
+ // Directory handles block rename/deletion; read-only file handles
3297
+ // block writes and deletion for the complete target Job lifetime.
3298
+ IntPtr handle = CreateFile(file, directory ? FILE_READ_ATTRIBUTES : GENERIC_READ,
3299
+ directory ? FILE_SHARE_READ | FILE_SHARE_WRITE : FILE_SHARE_READ,
3300
+ ref attributes, OPEN_EXISTING, directory ? 0x02200000U : 0x00200000U, IntPtr.Zero);
3301
+ if (IsInvalidHandle(handle)) ThrowLastError("CreateFile(native evaluator guard)");
3302
+ guards.Add(handle);
3303
+ return handle;
3304
+ }
3305
+
3306
+ private static void VerifyEvaluatorPath(EvaluatorPathSpec expected, IntPtr handle, bool directory)
3307
+ {
3308
+ LaunchPathFileIdentity actual = ReadLaunchPathFileIdentity(handle, directory);
3309
+ UInt64 device, inode;
3310
+ if (!UInt64.TryParse(expected.dev, out device) || !UInt64.TryParse(expected.ino, out inode) ||
3311
+ !MatchesExpectedNodeFileIdentity(actual, device, inode) ||
3312
+ !SameEvaluatorPath(NormalizeFinalPath(actual.FinalPath), expected.path) ||
3313
+ (((actual.Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) != directory))
3314
+ throw new InvalidDataException("Native evaluator path identity changed");
3315
+ if (directory) return;
3316
+ if (actual.Links != 1 || actual.Bytes != (UInt64)expected.bytes || !IsLowercaseSha256(expected.sha256))
3317
+ throw new InvalidDataException("Native evaluator file identity or link count changed");
3318
+ using (SafeFileHandle safe = new SafeFileHandle(handle, false))
3319
+ using (FileStream stream = new FileStream(safe, FileAccess.Read))
3320
+ using (SHA256 algorithm = SHA256.Create())
3321
+ {
3322
+ string digest = BitConverter.ToString(algorithm.ComputeHash(stream)).Replace("-", "").ToLowerInvariant();
3323
+ if (digest != expected.sha256) throw new InvalidDataException("Native evaluator file digest changed");
3324
+ }
3325
+ }
3326
+
3327
+ private static void PrepareNativeEvaluator(NativeEvaluatorSpec spec, string application,
3328
+ string[] arguments, string workingDirectory, string appSid, int wallTimeMs,
3329
+ List<IntPtr> guards, ref bool rootAttested)
3330
+ {
3331
+ if (spec.version != 1 || !IsLowercaseSha256(spec.manifestDigest) || spec.runtime == null ||
3332
+ spec.directories == null || spec.directories.Length < 4 || spec.directories.Length > 128 ||
3333
+ spec.files == null || spec.files.Length < 2 || spec.files.Length > 65 ||
3334
+ wallTimeMs < 1 || spec.wallTimeMs != wallTimeMs || String.IsNullOrWhiteSpace(appSid))
3335
+ throw new InvalidDataException("Native evaluator manifest is incomplete");
3336
+ string root = NormalizeLocalDosPath(spec.root, null, "Native evaluator stage");
3337
+ string expectedParent = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Temp");
3338
+ if (!SameEvaluatorPath(Path.GetDirectoryName(root), expectedParent) ||
3339
+ !System.Text.RegularExpressions.Regex.IsMatch(Path.GetFileName(root), "^cc-native-evaluator-[A-Za-z0-9_-]{6}$") ||
3340
+ !SameEvaluatorPath(spec.workspace, Path.Combine(root, "workspace")) ||
3341
+ !SameEvaluatorPath(spec.control, Path.Combine(root, "control")) ||
3342
+ !SameEvaluatorPath(spec.scratch, Path.Combine(root, "scratch")) ||
3343
+ !SameEvaluatorPath(spec.check, Path.Combine(spec.control, "check.cjs")) ||
3344
+ !SameEvaluatorPath(spec.runtime.path, Path.Combine(spec.control, "node.exe")) ||
3345
+ !SameEvaluatorPath(application, spec.runtime.path) || arguments.Length != 5 ||
3346
+ arguments[0] != "--preserve-symlinks" || arguments[1] != "--preserve-symlinks-main" ||
3347
+ !SameEvaluatorPath(arguments[2], spec.check) || !SameEvaluatorPath(arguments[3], spec.workspace) ||
3348
+ !SameEvaluatorPath(arguments[4], spec.scratch) || !SameEvaluatorPath(workingDirectory, spec.scratch) ||
3349
+ !SameEvaluatorPath(spec.directories[0].path, root))
3350
+ throw new InvalidDataException("Native evaluator launch or private stage binding changed");
3351
+ string ancestor = Path.GetPathRoot(root);
3352
+ foreach (string part in root.Substring(ancestor.Length).Split(Path.DirectorySeparatorChar))
3353
+ {
3354
+ ancestor = Path.Combine(ancestor, part);
3355
+ if (!SameEvaluatorPath(ancestor, root)) HoldEvaluatorPath(ancestor, true, guards);
3356
+ }
3357
+ HashSet<string> expected = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
3358
+ foreach (EvaluatorPathSpec directory in spec.directories)
3359
+ {
3360
+ string full = Path.GetFullPath(directory.path);
3361
+ if ((!SameEvaluatorPath(full, root) && !full.StartsWith(root + "\\", StringComparison.OrdinalIgnoreCase)) || !expected.Add(full))
3362
+ throw new InvalidDataException("Native evaluator directory is outside the private stage or duplicated");
3363
+ VerifyEvaluatorPath(directory, HoldEvaluatorPath(full, true, guards), true);
3364
+ if (SameEvaluatorPath(full, root)) rootAttested = true;
3365
+ }
3366
+ long total = 0;
3367
+ foreach (EvaluatorPathSpec file in spec.files)
3368
+ {
3369
+ string full = Path.GetFullPath(file.path);
3370
+ if ((!full.StartsWith(spec.workspace + "\\", StringComparison.OrdinalIgnoreCase) && !SameEvaluatorPath(full, spec.check)) ||
3371
+ !expected.Add(full) || file.bytes < 0 || file.bytes > 1024 * 1024)
3372
+ throw new InvalidDataException("Native evaluator file is outside its read-only roots or exceeds bounds");
3373
+ total = checked(total + file.bytes);
3374
+ if (total > 8 * 1024 * 1024) throw new InvalidDataException("Native evaluator tree exceeds byte bound");
3375
+ VerifyEvaluatorPath(file, HoldEvaluatorPath(full, false, guards), false);
3376
+ }
3377
+ if (!expected.Contains(spec.check) || !expected.Contains(spec.workspace) || !expected.Contains(spec.control) || !expected.Contains(spec.scratch))
3378
+ throw new InvalidDataException("Native evaluator manifest omits a required path");
3379
+ if (spec.runtime.bytes < 1 || spec.runtime.bytes > 128 * 1024 * 1024 || !expected.Add(spec.runtime.path))
3380
+ throw new InvalidDataException("Native evaluator runtime exceeds byte bound or duplicates a path");
3381
+ VerifyEvaluatorPath(spec.runtime, HoldEvaluatorPath(application, false, guards), false);
3382
+ foreach (EvaluatorPathSpec directory in spec.directories)
3383
+ foreach (string child in Directory.GetFileSystemEntries(directory.path))
3384
+ if (!expected.Contains(child)) throw new InvalidDataException("Native evaluator tree has an unlisted entry");
3385
+ if (Directory.GetFileSystemEntries(spec.scratch).Length != 0)
3386
+ throw new InvalidDataException("Native evaluator scratch must start empty");
3387
+ SecurityIdentifier sid = new SecurityIdentifier(appSid);
3388
+ SecurityIdentifier owner = WindowsIdentity.GetCurrent().User;
3389
+ SecurityIdentifier system = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
3390
+ foreach (EvaluatorPathSpec directory in spec.directories)
3391
+ {
3392
+ DirectorySecurity security = new DirectorySecurity();
3393
+ security.SetAccessRuleProtection(true, false);
3394
+ security.AddAccessRule(new FileSystemAccessRule(owner, FileSystemRights.FullControl,
3395
+ InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
3396
+ security.AddAccessRule(new FileSystemAccessRule(system, FileSystemRights.FullControl,
3397
+ InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
3398
+ bool scratch = SameEvaluatorPath(directory.path, spec.scratch);
3399
+ security.AddAccessRule(new FileSystemAccessRule(sid,
3400
+ scratch ? FileSystemRights.Modify : FileSystemRights.ReadAndExecute,
3401
+ scratch ? InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit : InheritanceFlags.None,
3402
+ PropagationFlags.None, AccessControlType.Allow));
3403
+ SetEvaluatorAccessControl(directory.path, security);
3404
+ }
3405
+ foreach (EvaluatorPathSpec file in spec.files)
3406
+ {
3407
+ FileSecurity security = new FileSecurity();
3408
+ security.SetAccessRuleProtection(true, false);
3409
+ security.AddAccessRule(new FileSystemAccessRule(owner, FileSystemRights.FullControl, AccessControlType.Allow));
3410
+ security.AddAccessRule(new FileSystemAccessRule(system, FileSystemRights.FullControl, AccessControlType.Allow));
3411
+ security.AddAccessRule(new FileSystemAccessRule(sid, FileSystemRights.ReadAndExecute, AccessControlType.Allow));
3412
+ SetEvaluatorAccessControl(file.path, security);
3413
+ }
3414
+ FileSecurity runtimeSecurity = new FileSecurity();
3415
+ runtimeSecurity.SetAccessRuleProtection(true, false);
3416
+ runtimeSecurity.AddAccessRule(new FileSystemAccessRule(owner, FileSystemRights.FullControl, AccessControlType.Allow));
3417
+ runtimeSecurity.AddAccessRule(new FileSystemAccessRule(system, FileSystemRights.FullControl, AccessControlType.Allow));
3418
+ runtimeSecurity.AddAccessRule(new FileSystemAccessRule(sid, FileSystemRights.ReadAndExecute, AccessControlType.Allow));
3419
+ SetEvaluatorAccessControl(spec.runtime.path, runtimeSecurity);
3420
+ }
3421
+
3422
+ private static void SetEvaluatorAccessControl(string path, FileSystemSecurity security)
3423
+ {
3424
+ // Directory/File.SetAccessControl exist only in .NET Framework.
3425
+ // Persist the same protected DACL through Win32 so the byte-loaded
3426
+ // assembly enforces identical ACLs in Windows PowerShell and pwsh.
3427
+ if (!security.AreAccessRulesProtected)
3428
+ throw new InvalidDataException("Native evaluator DACL must be protected");
3429
+ const UInt32 DACL_SECURITY_INFORMATION = 0x00000004;
3430
+ const UInt32 PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000;
3431
+ if (!SetFileSecurity(path,
3432
+ DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
3433
+ security.GetSecurityDescriptorBinaryForm()))
3434
+ ThrowLastError("SetFileSecurity(native evaluator protected DACL)");
3435
+ }
3436
+
3437
+ // This timer belongs to the native supervisor, not the JavaScript
3438
+ // caller. It also covers a target that stops reading its entry pipe.
3439
+ // The gate prevents a queued callback from touching a closed/reused
3440
+ // Job handle after Dispose. Cleanup still requires an empty-Job fence.
3441
+ private sealed class JobWallTimeWatchdog : IDisposable
3442
+ {
3443
+ private readonly object gate = new object();
3444
+ private readonly IntPtr job;
3445
+ private readonly int milliseconds;
3446
+ private readonly System.Diagnostics.Stopwatch clock;
3447
+ private readonly Timer timer;
3448
+ private bool stopped;
3449
+ private bool expired;
3450
+ private int terminationError;
3451
+
3452
+ public JobWallTimeWatchdog(IntPtr jobHandle, int wallTimeMs)
3453
+ {
3454
+ job = jobHandle;
3455
+ milliseconds = wallTimeMs;
3456
+ clock = System.Diagnostics.Stopwatch.StartNew();
3457
+ timer = new Timer(Expire, null, wallTimeMs, Timeout.Infinite);
3458
+ }
3459
+
3460
+ private void Expire(object state)
3461
+ {
3462
+ lock (gate)
3463
+ {
3464
+ if (stopped) return;
3465
+ expired = true;
3466
+ if (!TerminateJobObject(job, 125))
3467
+ terminationError = Marshal.GetLastWin32Error();
3468
+ }
3469
+ }
3470
+
3471
+ public UInt32 RemainingMilliseconds
3472
+ {
3473
+ get
3474
+ {
3475
+ return checked((UInt32)Math.Max(
3476
+ 0L, milliseconds - clock.ElapsedMilliseconds));
3477
+ }
3478
+ }
3479
+
3480
+ public void ThrowIfExpired()
3481
+ {
3482
+ lock (gate)
3483
+ {
3484
+ if (expired || clock.ElapsedMilliseconds >= milliseconds)
3485
+ throw new TimeoutException(
3486
+ "Windows sandbox wall-time limit exceeded" +
3487
+ (terminationError == 0 ? String.Empty :
3488
+ " (Job termination error " + terminationError + ")"));
3489
+ }
3490
+ }
3491
+
3492
+ public void Dispose()
3493
+ {
3494
+ lock (gate)
3495
+ {
3496
+ stopped = true;
3497
+ timer.Dispose();
3498
+ }
3499
+ }
3500
+ }
3501
+
3206
3502
  public static int Run(
3207
3503
  string application,
3208
3504
  string[] arguments,
@@ -3222,8 +3518,12 @@ namespace ChainlessChain.WindowsSandbox
3222
3518
  LaunchPathLockSpec[] launchPathLockSpecs,
3223
3519
  byte[] entrySnapshotOverride,
3224
3520
  string snapshotTestGateToken,
3225
- string snapshotTestGateReleasePath)
3521
+ string snapshotTestGateReleasePath,
3522
+ int wallTimeMs = 0,
3523
+ NativeEvaluatorSpec nativeEvaluator = null)
3226
3524
  {
3525
+ if (wallTimeMs < 0 || wallTimeMs > 3600000)
3526
+ throw new ArgumentOutOfRangeException("wallTimeMs");
3227
3527
  targetEnvironment =
3228
3528
  targetEnvironment ?? CaptureCurrentEnvironment();
3229
3529
  workingDirectory = NormalizeLocalDosPath(
@@ -3290,6 +3590,9 @@ namespace ChainlessChain.WindowsSandbox
3290
3590
  bool targetExited = false;
3291
3591
  int targetExitCode = 125;
3292
3592
  Exception launchError = null;
3593
+ JobWallTimeWatchdog wallTimeWatchdog = null;
3594
+ List<IntPtr> evaluatorGuards = new List<IntPtr>();
3595
+ bool evaluatorRootAttested = false;
3293
3596
 
3294
3597
  try
3295
3598
  {
@@ -3359,6 +3662,19 @@ namespace ChainlessChain.WindowsSandbox
3359
3662
  }
3360
3663
  ConfigureAppContainerEnvironment(targetEnvironment);
3361
3664
  }
3665
+ if (nativeEvaluator != null)
3666
+ {
3667
+ if (!useAppContainer || nodeIpcFd >= 0 || detached || entrySnapshot != null)
3668
+ throw new InvalidDataException("Native evaluator requires a synchronous AppContainer launch");
3669
+ AssertNoLoopbackExemption(appContainerSid);
3670
+ PrepareNativeEvaluator(nativeEvaluator, application, arguments, workingDirectory,
3671
+ expectedAppContainerSid, wallTimeMs, evaluatorGuards, ref evaluatorRootAttested);
3672
+ targetEnvironment = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
3673
+ targetEnvironment["SystemRoot"] = Path.GetDirectoryName(Environment.SystemDirectory);
3674
+ targetEnvironment["WINDIR"] = Path.GetDirectoryName(Environment.SystemDirectory);
3675
+ targetEnvironment["PATH"] = Path.GetDirectoryName(application);
3676
+ ConfigureAppContainerEnvironment(targetEnvironment);
3677
+ }
3362
3678
  environmentBuffer =
3363
3679
  BuildEnvironmentBlock(targetEnvironment);
3364
3680
 
@@ -3387,8 +3703,12 @@ namespace ChainlessChain.WindowsSandbox
3387
3703
  // an exact primary-token duplicate instead of filtering again.
3388
3704
  bool sourceTokenWasFiltered =
3389
3705
  TokenWasFiltered(sourceToken);
3706
+ // A UAC-filtered token can retain disabled privileges. The
3707
+ // AppContainer attestation requires their removal, not merely
3708
+ // that they are disabled. Compatibility workers retain their
3709
+ // existing enabled-only predicate for nested token support.
3390
3710
  bool sourceTokenHasUnexpectedEnabledPrivileges =
3391
- TokenHasUnexpectedEnabledPrivileges(sourceToken);
3711
+ TokenHasUnexpectedEnabledPrivileges(sourceToken, useAppContainer);
3392
3712
  bool sourceTokenHasEnabledAdministratorSid =
3393
3713
  disableAdministratorSids &&
3394
3714
  TokenHasEnabledAdministratorSid(sourceToken);
@@ -3627,6 +3947,8 @@ namespace ChainlessChain.WindowsSandbox
3627
3947
  // atomic handoff; release the stream guards before resume so
3628
3948
  // target code cannot deadlock on a break owned by the helper.
3629
3949
  ReleaseLaunchPathLocks(launchPathLocks);
3950
+ if (wallTimeMs > 0)
3951
+ wallTimeWatchdog = new JobWallTimeWatchdog(job, wallTimeMs);
3630
3952
  if (ResumeThread(processInfo.hThread) == UInt32.MaxValue)
3631
3953
  {
3632
3954
  TerminateProcess(processInfo.hProcess, 125);
@@ -3668,7 +3990,13 @@ namespace ChainlessChain.WindowsSandbox
3668
3990
 
3669
3991
  UInt32 targetWait = WaitForSingleObject(
3670
3992
  processInfo.hProcess,
3671
- INFINITE);
3993
+ wallTimeWatchdog == null ? INFINITE :
3994
+ wallTimeWatchdog.RemainingMilliseconds);
3995
+ if (targetWait == WAIT_TIMEOUT && wallTimeWatchdog != null)
3996
+ throw new TimeoutException(
3997
+ "Windows sandbox wall-time limit exceeded");
3998
+ if (wallTimeWatchdog != null)
3999
+ wallTimeWatchdog.ThrowIfExpired();
3672
4000
  if (targetWait != WAIT_OBJECT_0)
3673
4001
  ThrowLastError("WaitForSingleObject(target)");
3674
4002
  targetExited = true;
@@ -3684,6 +4012,12 @@ namespace ChainlessChain.WindowsSandbox
3684
4012
  finally
3685
4013
  {
3686
4014
  Exception cleanupError = null;
4015
+ if (wallTimeWatchdog != null)
4016
+ {
4017
+ wallTimeWatchdog.Dispose();
4018
+ try { wallTimeWatchdog.ThrowIfExpired(); }
4019
+ catch (TimeoutException error) { launchError = error; }
4020
+ }
3687
4021
  if (processInfo.hProcess != IntPtr.Zero && !targetExited)
3688
4022
  TerminateProcess(processInfo.hProcess, 125);
3689
4023
  if (job != IntPtr.Zero)
@@ -3742,6 +4076,11 @@ namespace ChainlessChain.WindowsSandbox
3742
4076
  foreach (IntPtr handle in ownedStandardHandles)
3743
4077
  CloseHandle(handle);
3744
4078
  if (limitBuffer != IntPtr.Zero) Marshal.FreeHGlobal(limitBuffer);
4079
+ if (nativeEvaluator != null && !IsInvalidHandle(appContainerSid))
4080
+ {
4081
+ try { AssertNoLoopbackExemption(appContainerSid); }
4082
+ catch (Exception error) { cleanupError = error; }
4083
+ }
3745
4084
  if (!IsInvalidHandle(appContainerSid)) FreeSid(appContainerSid);
3746
4085
  if (restrictedToken != IntPtr.Zero) CloseHandle(restrictedToken);
3747
4086
  if (sourceToken != IntPtr.Zero) CloseHandle(sourceToken);
@@ -3776,11 +4115,38 @@ namespace ChainlessChain.WindowsSandbox
3776
4115
  launchError,
3777
4116
  cleanupError);
3778
4117
  }
4118
+ if (nativeEvaluator != null && evaluatorRootAttested && cleanupError == null)
4119
+ {
4120
+ try
4121
+ {
4122
+ PublishTargetIdentity(Path.Combine(nativeEvaluator.root, "settlement.json"),
4123
+ JsonCodec.SerializeObject("manifestDigest", nativeEvaluator.manifestDigest,
4124
+ "cleanupConfirmed", true, "capabilityCount", 0,
4125
+ "loopbackExemptionAbsent", true,
4126
+ "targetPid", processInfo.dwProcessId,
4127
+ "appContainerSid", expectedAppContainerSid,
4128
+ "wallTimeMs", wallTimeMs,
4129
+ "targetExitCode", targetExitCode,
4130
+ "supervisorUserSidSha256", HashEvaluatorUserSid(),
4131
+ "executionFailed", launchError != null));
4132
+ }
4133
+ catch (Exception error) { launchError = error; }
4134
+ }
4135
+ foreach (IntPtr guard in evaluatorGuards) CloseHandle(guard);
4136
+ evaluatorGuards.Clear();
3779
4137
  }
3780
4138
  if (launchError != null)
3781
4139
  throw launchError;
3782
4140
  return targetExitCode;
3783
4141
  }
4142
+
4143
+ private static string HashEvaluatorUserSid()
4144
+ {
4145
+ using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
4146
+ using (SHA256 algorithm = SHA256.Create())
4147
+ return BitConverter.ToString(algorithm.ComputeHash(Encoding.UTF8.GetBytes(identity.User.Value)))
4148
+ .Replace("-", "").ToLowerInvariant();
4149
+ }
3784
4150
  }
3785
4151
 
3786
4152
  public static class Program
@@ -3791,6 +4157,10 @@ namespace ChainlessChain.WindowsSandbox
3791
4157
  [DataContract]
3792
4158
  public sealed class LaunchSpec
3793
4159
  {
4160
+ [DataMember]
4161
+ public Native.NativeEvaluatorSpec nativeEvaluator { get; set; }
4162
+ [DataMember]
4163
+ public int wallTimeMs { get; set; }
3794
4164
  [DataMember]
3795
4165
  public int cpuSeconds { get; set; }
3796
4166
  [DataMember]
@@ -4159,7 +4529,9 @@ namespace ChainlessChain.WindowsSandbox
4159
4529
  spec.launchPathLocks,
4160
4530
  null,
4161
4531
  spec.snapshotTestGateToken,
4162
- spec.snapshotTestGateReleasePath);
4532
+ spec.snapshotTestGateReleasePath,
4533
+ spec.wallTimeMs,
4534
+ spec.nativeEvaluator);
4163
4535
  }
4164
4536
  catch (Exception error)
4165
4537
  {
@@ -1,7 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./ChatBubbleRenderer-CPLynmbb.js","./vendor-Bn1JzzAn.js","./index-DJ2OiRvh.js","./icons-DG5UD-6K.js","./index-Cq93VfoF.css","./ChatBubbleRenderer-gy5SDGw2.css","./OrderTableRenderer-CBcy0szc.js","./OrderTableRenderer-CfrDjSHT.css","./TimelineRenderer-BLGfJIDr.js","./TimelineRenderer-BlTAtkOc.css","./EmailListRenderer-DTq7tU4b.js","./EmailListRenderer-DTPZPx_S.css","./GenericCardRenderer-DNv8GEoq.js","./GenericCardRenderer-o85VDYQS.css"])))=>i.map(i=>d[i]);
2
- import{E as ue,r as R,b as w,I as g,P as u,J as O,U as v,c,S as C,V as E,_ as M,F as B,Z as se,a0 as le,R as L,K as m,Q as b,W as A,o as J}from"./vendor-Bn1JzzAn.js";import{u as U}from"./usePersonalDataHub-vFGrVDyp.js";import{_ as D,e as F,d as P}from"./index-DJ2OiRvh.js";import{aa as q,ag as Q,M as z,aI as G,v as X,aH as H,aq as K,ac as W,e as de,d as fe,k as pe,ai as me,aA as _e,R as ye}from"./icons-DG5UD-6K.js";import"./useShellMode-CgR0wCYM.js";const I=Object.freeze({q:"",category:null,adapter:null,subtype:null,since:null,until:null}),N=50,Y=300,Z=ue("pdhBrowser",()=>{const r=R({...I}),t=R([]),n=R(null),e=R(!1),o=R(!1),l=R(null),a=R(null),s=R(!1),i=R({byCategory:{},byAdapter:{},bySubtype:{},total:0});let d=0,_=null;const x=w(()=>t.value.length>0),j=w(()=>n.value!=null);function h(S={}){const p={},f=r.value;return f.q&&f.q.trim()&&(p.q=f.q.trim()),f.category&&(p.category=f.category),f.adapter&&(p.adapter=f.adapter),f.subtype&&(p.subtype=f.subtype),Number.isFinite(f.since)&&(p.since=f.since),Number.isFinite(f.until)&&(p.until=f.until),{...p,...S}}async function y(){const S=++d;e.value=!0,l.value=null;const p=U();try{const[f,T]=await Promise.all([p.searchEvents(h({limit:N})),p.facetCounts({...r.value.q&&r.value.q.trim()?{q:r.value.q.trim()}:{},...Number.isFinite(r.value.since)?{since:r.value.since}:{},...Number.isFinite(r.value.until)?{until:r.value.until}:{}})]);if(S!==d)return;t.value=f.rows||[],n.value=f.nextCursor||null,a.value=f.mode||"like",s.value=!!f.shortQuery,i.value={byCategory:T.byCategory||{},byAdapter:T.byAdapter||{},bySubtype:T.bySubtype||{},total:T.total||0}}catch(f){if(S!==d)return;l.value=f&&f.message?f.message:String(f),t.value=[],n.value=null}finally{S===d&&(e.value=!1)}}async function k(){if(!n.value||o.value)return;o.value=!0,l.value=null;const S=U();try{const p=await S.searchEvents(h({cursor:n.value,limit:N}));t.value=t.value.concat(p.rows||[]),n.value=p.nextCursor||null,a.value=p.mode||a.value}catch(p){l.value=p&&p.message?p.message:String(p)}finally{o.value=!1}}function ae(S,p){if(!(S in I))throw new Error(`pdhBrowser.setFilter: unknown key "${S}"`);r.value={...r.value,[S]:p},_&&clearTimeout(_),_=setTimeout(()=>{_=null,y()},Y)}function ie(S){return r.value={...I,...S},_&&(clearTimeout(_),_=null),y()}function ce(){r.value={...I},t.value=[],n.value=null,l.value=null,i.value={byCategory:{},byAdapter:{},bySubtype:{},total:0}}return{filters:r,results:t,cursor:n,isLoading:e,isAppending:o,error:l,mode:a,shortQuery:s,facets:i,hasResults:x,canLoadMore:j,search:y,loadMore:k,setFilter:ae,setFilters:ie,reset:ce,PAGE_SIZE:N,SEARCH_DEBOUNCE_MS:Y}}),ge=Object.freeze(["chat","social","email","shopping","travel","system","ai-chat","other"]),ve=Object.freeze({chat:"社交聊天",social:"内容平台",email:"邮件",shopping:"支付订单",travel:"出行",system:"系统数据","ai-chat":"AI 对话",other:"其他"});function V(r){return ve[r]||r||"未知"}const be=Object.freeze([["wechat","chat"],["messaging-","chat"],["social-","social"],["email-","email"],["shopping-","shopping"],["alipay-","shopping"],["travel-","travel"],["system-data","system"],["browser-","system"],["meeting-","system"],["vscode","system"],["vscodium","system"],["jetbrains-ide","system"],["win-recent","system"],["git-activity","system"],["shell-history","system"],["hbuilderx","system"],["local-files","system"],["cursor","ai-chat"],["claude-code","ai-chat"],["ai-chat-","ai-chat"]]);function $(r){if(typeof r!="string"||r.length===0)return"other";for(const[t,n]of be)if(t.endsWith("-")||t==="system-data"){if(r.startsWith(t))return n}else if(r===t)return n;return"other"}const he={__name:"CategorySidebar",props:{selected:{type:String,default:null},facets:{type:Object,default:()=>({byCategory:{},total:0})}},emits:["select"],setup(r,{expose:t}){t();const n=r,e=w(()=>n.facets.total||0),o={chat:W,social:K,email:H,shopping:X,travel:G,system:z,"ai-chat":Q,other:q};function l(i){return o[i]||q}function a(i){return i?{backgroundColor:"#fff",color:"#1677ff"}:{backgroundColor:"#f0f0f0",color:"#666"}}const s={props:n,total:e,ICONS:o,iconFor:l,badgeStyle:a,computed:w,get AppstoreOutlined(){return q},get MessageOutlined(){return W},get PlayCircleOutlined(){return K},get MailOutlined(){return H},get ShoppingOutlined(){return X},get CarOutlined(){return G},get MobileOutlined(){return z},get RobotOutlined(){return Q},get CATEGORIES(){return ge},get categoryLabel(){return V}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},Se={class:"pdh-sidebar"},Oe=["onClick"],we={class:"label"};function Ce(r,t,n,e,o,l){const a=g("a-badge");return u(),O("div",Se,[t[2]||(t[2]=v("div",{class:"sidebar-title"},"数据类型",-1)),v("div",{class:M(["cat-item",{active:n.selected===null}]),onClick:t[0]||(t[0]=s=>r.$emit("select",null))},[c(e.AppstoreOutlined,{class:"icon"}),t[1]||(t[1]=v("span",{class:"label"},"全部",-1)),e.total>0?(u(),C(a,{key:0,count:e.total,"number-style":e.badgeStyle(n.selected===null),"overflow-count":9999},null,8,["count","number-style"])):E("v-if",!0)],2),(u(!0),O(B,null,se(e.CATEGORIES,s=>(u(),O("div",{key:s,class:M(["cat-item",{active:n.selected===s,dim:!n.facets.byCategory[s]}]),onClick:i=>r.$emit("select",s)},[(u(),C(le(e.iconFor(s)),{class:"icon"})),v("span",we,L(e.categoryLabel(s)),1),n.facets.byCategory[s]?(u(),C(a,{key:0,count:n.facets.byCategory[s],"number-style":e.badgeStyle(n.selected===s),"overflow-count":9999},null,8,["count","number-style"])):E("v-if",!0)],10,Oe))),128))])}const ke=D(he,[["render",Ce],["__scopeId","data-v-6b62a22e"],["__file","/tmp/cc-web-panel-lNX50L/repo/packages/web-panel/src/components/pdh/CategorySidebar.vue"]]),Ee={__name:"SearchFilterBar",props:{filters:{type:Object,required:!0},facets:{type:Object,default:()=>({byAdapter:{}})},isLoading:{type:Boolean,default:!1},mode:{type:String,default:null},shortQuery:{type:Boolean,default:!1}},emits:["set-filter","reset"],setup(r,{expose:t,emit:n}){t();const e=r,o=n,l=w(()=>e.filters.category?`在「${e.filters.category}」类目内搜索…`:"搜索关键词(如:支付宝、罗技、Kotlin)…"),a=w(()=>Object.entries(e.facets.byAdapter||{}).sort((y,k)=>k[1]-y[1]).map(([y,k])=>({value:y,label:`${y} (${k})`}))),s=w(()=>!e.filters.since&&!e.filters.until?null:[e.filters.since?new Date(e.filters.since):null,e.filters.until?new Date(e.filters.until):null]),i=w(()=>!!(e.filters.q||e.filters.adapter||e.filters.subtype||e.filters.since||e.filters.until));function d(h){o("set-filter","q",h||"")}function _(h){o("set-filter","q",h||"")}function x(h){if(!h||h.length===0){o("set-filter","since",null),o("set-filter","until",null);return}const[y,k]=h;o("set-filter","since",y?+y:null),o("set-filter","until",k?+k:null)}const j={props:e,emit:o,placeholderText:l,adapterOptions:a,dateRangeValue:s,hasActiveFilters:i,onQInput:d,onSearch:_,onDateChange:x,computed:w,get SearchOutlined(){return pe},get CloseCircleOutlined(){return fe},get InfoCircleOutlined(){return de}};return Object.defineProperty(j,"__isScriptSetup",{enumerable:!1,value:!0}),j}},Re={class:"pdh-filter-bar"},Le={key:1,class:"hint"},xe={key:2,class:"hint"};function je(r,t,n,e,o,l){const a=g("a-input-search"),s=g("a-select"),i=g("a-range-picker"),d=g("a-button");return u(),O("div",Re,[c(a,{value:n.filters.q,placeholder:e.placeholderText,"enter-button":"搜索","allow-clear":"",loading:n.isLoading,style:{flex:"1","max-width":"480px"},"onUpdate:value":e.onQInput,onSearch:e.onSearch},{prefix:m(()=>[c(e.SearchOutlined)]),_:1},8,["value","placeholder","loading"]),c(s,{value:n.filters.adapter,placeholder:"所有 adapter","allow-clear":"",options:e.adapterOptions,style:{width:"200px"},"onUpdate:value":t[0]||(t[0]=_=>r.$emit("set-filter","adapter",_||null))},null,8,["value","options"]),c(i,{value:e.dateRangeValue,placeholder:["开始日期","结束日期"],style:{width:"280px"},"onUpdate:value":e.onDateChange},null,8,["value"]),e.hasActiveFilters?(u(),C(d,{key:0,type:"link",danger:"",onClick:t[1]||(t[1]=_=>r.$emit("reset"))},{icon:m(()=>[c(e.CloseCircleOutlined)]),default:m(()=>[t[2]||(t[2]=b(" 清空筛选 ",-1))]),_:1})):E("v-if",!0),n.shortQuery?(u(),O("span",Le,[c(e.InfoCircleOutlined),t[3]||(t[3]=b(" 关键词需至少 3 字 (FTS5 trigram 限制) ",-1))])):n.mode==="like"?(u(),O("span",xe,[c(e.InfoCircleOutlined),t[4]||(t[4]=b(" 当前为 LIKE 兜底模式 ",-1))])):E("v-if",!0)])}const Ae=D(Ee,[["render",je],["__scopeId","data-v-d7cce6e9"],["__file","/tmp/cc-web-panel-lNX50L/repo/packages/web-panel/src/components/pdh/SearchFilterBar.vue"]]),Fe={__name:"RendererDispatcher",props:{event:{type:Object,required:!0}},setup(r,{expose:t}){t();const n=A(()=>F(()=>import("./ChatBubbleRenderer-CPLynmbb.js"),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url)),e=A(()=>F(()=>import("./OrderTableRenderer-CBcy0szc.js"),__vite__mapDeps([6,1,2,3,4,7]),import.meta.url)),o=A(()=>F(()=>import("./TimelineRenderer-BLGfJIDr.js"),__vite__mapDeps([8,1,2,3,4,9]),import.meta.url)),l=A(()=>F(()=>import("./EmailListRenderer-DTq7tU4b.js"),__vite__mapDeps([10,1,2,3,4,11]),import.meta.url)),a=A(()=>F(()=>import("./GenericCardRenderer-DNv8GEoq.js"),__vite__mapDeps([12,1,2,3,4,13]),import.meta.url));function s(d){const _=d&&d.source&&d.source.adapter;switch($(_)){case"chat":case"ai-chat":return n;case"shopping":return e;case"travel":return o;case"email":return l;default:return a}}const i={ChatBubbleRenderer:n,OrderTableRenderer:e,TimelineRenderer:o,EmailListRenderer:l,GenericCardRenderer:a,rendererFor:s,defineAsyncComponent:A,get getCategory(){return $}};return Object.defineProperty(i,"__isScriptSetup",{enumerable:!1,value:!0}),i}};function De(r,t,n,e,o,l){return u(),C(le(e.rendererFor(n.event)),{event:n.event},null,8,["event"])}const Te=D(Fe,[["render",De],["__file","/tmp/cc-web-panel-lNX50L/repo/packages/web-panel/src/components/pdh/renderers/RendererDispatcher.vue"]]);function ee(r){return JSON.stringify(r,null,2)}function te(r){return r.map(t=>JSON.stringify(t)).join(`
3
- `)+`
4
- `}function ne(r){const n=["id","subtype","occurredAt","occurredAtIso","actor","place","adapter","summary","contentJson","extraJson"].join(","),e=r.map(o=>{const l=Number.isFinite(o.occurredAt)?o.occurredAt:null,a=l?new Date(l).toISOString():"",s=o.source&&o.source.adapter||"",i=o.content&&(o.content.text||o.content.title||o.content.subject)||"";return[o.id||"",o.subtype||"",l!=null?String(l):"",a,o.actor||"",o.place||"",s,i,o.content?JSON.stringify(o.content):"",o.extra?JSON.stringify(o.extra):""].map(Ie).join(",")});return[n,...e].join(`
5
- `)+`
6
- `}function Ie(r){const t=String(r??"");return t.includes(",")||t.includes('"')||t.includes(`
7
- `)||t.includes("\r")?'"'+t.replace(/"/g,'""')+'"':t}function re(r,t,n="application/octet-stream"){if(typeof window>"u"||typeof document>"u")return t;const e=new Blob([r],{type:n}),o=URL.createObjectURL(e),l=document.createElement("a");return l.href=o,l.download=t,document.body.appendChild(l),l.click(),document.body.removeChild(l),setTimeout(()=>URL.revokeObjectURL(o),1e3),t}function oe(r,t=null){const n=new Date,e=n.getFullYear(),o=String(n.getMonth()+1).padStart(2,"0"),l=String(n.getDate()).padStart(2,"0"),a=r==="ndjson"?"ndjson":r,s=t?`-${t}`:"";return`pdh-events-${e}-${o}-${l}${s}.${a}`}const Pe={__name:"ExportDropdown",props:{events:{type:Array,required:!0},category:{type:String,default:null}},setup(r,{expose:t}){t();const n=r,e=w(()=>n.events.length>0),o={json:"application/json;charset=utf-8",ndjson:"application/x-ndjson;charset=utf-8",csv:"text/csv;charset=utf-8"};function l(i){switch(i){case"json":return ee(n.events);case"ndjson":return te(n.events);case"csv":return ne(n.events);default:throw new Error(`unknown format: ${i}`)}}function a({key:i}){try{const d=l(i),_=oe(i,n.category);re(d,_,o[i]),P.success(`已导出 ${n.events.length} 条到 ${_}`)}catch(d){P.error(`导出失败: ${d.message||d}`)}}const s={props:n,hasResults:e,MIME:o,serialize:l,onClick:a,computed:w,get DownloadOutlined(){return _e},get DownOutlined(){return me},get message(){return P},get eventsToJson(){return ee},get eventsToNdjson(){return te},get eventsToCsv(){return ne},get downloadAs(){return re},get suggestFilename(){return oe}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}};function qe(r,t,n,e,o,l){const a=g("a-button"),s=g("a-menu-item"),i=g("a-menu"),d=g("a-dropdown");return u(),C(d,{disabled:!e.hasResults},{overlay:m(()=>[c(i,{onClick:e.onClick},{default:m(()=>[c(s,{key:"json"},{default:m(()=>[...t[0]||(t[0]=[b("JSON (.json)",-1)])]),_:1}),c(s,{key:"ndjson"},{default:m(()=>[...t[1]||(t[1]=[b("NDJSON (.ndjson)",-1)])]),_:1}),c(s,{key:"csv"},{default:m(()=>[...t[2]||(t[2]=[b("CSV (.csv)",-1)])]),_:1})]),_:1})]),default:m(()=>[c(a,{disabled:!e.hasResults},{icon:m(()=>[c(e.DownloadOutlined)]),default:m(()=>[b(" 导出 ("+L(n.events.length)+") ",1),c(e.DownOutlined)]),_:1},8,["disabled"])]),_:1},8,["disabled"])}const Ne=D(Pe,[["render",qe],["__file","/tmp/cc-web-panel-lNX50L/repo/packages/web-panel/src/components/pdh/ExportDropdown.vue"]]),Be={__name:"PdhVaultBrowser",setup(r,{expose:t}){t();const n=Z(),e=w(()=>n.filters.q?`没有匹配 "${n.filters.q}" 的事件 — 试试更短的关键词或换个类目`:n.filters.category?`「${V(n.filters.category)}」类目下还没有数据 — 去采集页同步对应 adapter`:"Vault 里还没有数据 — 去「个人数据中台」页面同步任意 adapter");function o(s){n.filters.category=s,n.search()}function l(s,i){n.setFilter(s,i)}J(()=>{!n.hasResults&&!n.isLoading&&n.search()});const a={store:n,emptyHint:e,onCategorySelect:o,onSetFilter:l,onMounted:J,computed:w,get ReloadOutlined(){return ye},get usePdhBrowserStore(){return Z},get categoryLabel(){return V},CategorySidebar:ke,SearchFilterBar:Ae,RendererDispatcher:Te,ExportDropdown:Ne};return Object.defineProperty(a,"__isScriptSetup",{enumerable:!1,value:!0}),a}},Ve={class:"pdh-browser-page"},Me={class:"page-header"},Je={class:"main-pane"},Ue={class:"results-summary"},Qe={key:0},ze={key:0},Ge={key:1},Xe={class:"loaded-of"},He={class:"results-list"},Ke={key:2,class:"load-more"};function We(r,t,n,e,o,l){const a=g("a-tag"),s=g("a-button"),i=g("a-space"),d=g("a-col"),_=g("a-spin"),x=g("a-alert"),j=g("a-empty"),h=g("a-row");return u(),O("div",Ve,[v("div",Me,[t[6]||(t[6]=v("div",null,[v("h2",{class:"page-title"},"数据浏览器"),v("p",{class:"page-sub"}," Vault 里所有已采集的数据,按类目浏览 / 全文检索 / 时间窗口筛选。 完全离线,不外传。 ")],-1)),c(i,null,{default:m(()=>[e.store.mode==="fts5"?(u(),C(a,{key:0,color:"green"},{default:m(()=>[...t[3]||(t[3]=[b("FTS5 trigram",-1)])]),_:1})):e.store.mode==="like"?(u(),C(a,{key:1,color:"orange"},{default:m(()=>[...t[4]||(t[4]=[b("LIKE 兜底",-1)])]),_:1})):E("v-if",!0),c(e.ExportDropdown,{events:e.store.results,category:e.store.filters.category},null,8,["events","category"]),c(s,{onClick:t[0]||(t[0]=y=>e.store.search()),loading:e.store.isLoading},{icon:m(()=>[c(e.ReloadOutlined)]),default:m(()=>[t[5]||(t[5]=b(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),c(h,{gutter:16,class:"browser-layout"},{default:m(()=>[c(d,{xs:24,sm:24,md:6,lg:5,xl:4},{default:m(()=>[c(e.CategorySidebar,{selected:e.store.filters.category,facets:e.store.facets,onSelect:e.onCategorySelect},null,8,["selected","facets"])]),_:1}),c(d,{xs:24,sm:24,md:18,lg:19,xl:20},{default:m(()=>[v("div",Je,[c(e.SearchFilterBar,{filters:e.store.filters,facets:e.store.facets,"is-loading":e.store.isLoading,mode:e.store.mode,"short-query":e.store.shortQuery,onSetFilter:e.onSetFilter,onReset:t[1]||(t[1]=y=>{e.store.reset(),e.store.search()})},null,8,["filters","facets","is-loading","mode","short-query"]),v("div",Ue,[e.store.isLoading&&e.store.results.length===0?(u(),O("span",Qe,[c(_,{size:"small"}),t[7]||(t[7]=b(" 载入中… ",-1))])):(u(),O(B,{key:1},[v("strong",null,L(e.store.facets.total),1),t[11]||(t[11]=b(" 条事件 ",-1)),e.store.filters.category?(u(),O("span",ze,[t[8]||(t[8]=b(" / 当前类目 ",-1)),v("strong",null,L(e.categoryLabel(e.store.filters.category)),1),v("strong",null,L(e.store.facets.byCategory[e.store.filters.category]||0),1)])):E("v-if",!0),e.store.filters.q?(u(),O("span",Ge,[t[9]||(t[9]=b(' / 关键词 "',-1)),v("em",null,L(e.store.filters.q),1),t[10]||(t[10]=b('"',-1))])):E("v-if",!0),v("span",Xe," / 已显示 "+L(e.store.results.length),1)],64))]),e.store.error?(u(),C(x,{key:0,type:"error","show-icon":"",message:e.store.error,closable:"",style:{margin:"12px 0"}},null,8,["message"])):E("v-if",!0),!e.store.isLoading&&e.store.results.length===0&&!e.store.error?(u(),C(j,{key:1,description:e.emptyHint,style:{"margin-top":"40px"}},null,8,["description"])):E("v-if",!0),v("div",He,[(u(!0),O(B,null,se(e.store.results,(y,k)=>(u(),C(e.RendererDispatcher,{key:`r-${k}-${y.id}`,event:y},null,8,["event"]))),128))]),e.store.canLoadMore?(u(),O("div",Ke,[c(s,{loading:e.store.isAppending,onClick:t[2]||(t[2]=y=>e.store.loadMore()),block:""},{default:m(()=>[...t[12]||(t[12]=[b(" 加载下一页 (50 条) ",-1)])]),_:1},8,["loading"])])):E("v-if",!0)])]),_:1})]),_:1})])}const nt=D(Be,[["render",We],["__scopeId","data-v-0f7c02cd"],["__file","/tmp/cc-web-panel-lNX50L/repo/packages/web-panel/src/views/PdhVaultBrowser.vue"]]);export{nt as default};
@@ -1 +0,0 @@
1
- import{Q as r}from"./index-DJ2OiRvh.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-D2x4GBGm.js";import{a0 as t}from"./index-DJ2OiRvh.js";import"./vendor-Bn1JzzAn.js";import"./index-D2Zb-Kd1.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};
@@ -1 +0,0 @@
1
- import{A as o}from"./Row-ke9Mk1cx.js";import{a0 as t}from"./index-DJ2OiRvh.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-CD3ziNhu.js";import"./useFlexGapSupport-wBKIYFKX.js";import"./styleChecker-De0Y8g1O.js";import"./index-D2Zb-Kd1.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};