chainlesschain 0.162.182 → 0.162.183

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 (176) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-DzZ5_xoj.js → AIOps-BapS7lz4.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-DeLXddIg.js → ActionButton-CXYdXEUI.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-rvDCmet1.js → Analytics-CKR5Lexn.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-Yt6QVDnp.js → AppLayout-DATVUOXB.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-BS112K5L.js → Artifacts-vb_0ZlV1.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-0wJuQrNu.js → Audit-BI1l9GWt.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-B90PMgbn.js → BackgroundAgents-BFXbaUEf.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-TkgMglQQ.js → Backup-DEYBJJ6H.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-CQVS9p1l.js → BaseInput-COdzeO0M.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-YTjQHoC7.js → Chat-oSN6sfM5.js} +6 -6
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-CI_jT0ru.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-5bwaOabq.js → Checkbox-BezEa4tm.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-BFmNQ_Xe.js → Codegen-CNEL0Ife.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-BT_u4Dzp.js → Col-Bf2Y2Bn1.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-CJP52u5b.js → Community-BfUlu4Hc.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-BpzhJE9i.js → Compact-BN4xWP9e.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-Cg7rfslp.js → Compliance-Bt6BKmEP.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-JisxL6Yy.js → Cowork-DKLp8YxO.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-Bu7Ug_MC.js → Cron-o7Hhw6ky.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-CvuqoLdj.js → Crosschain-DaNXWJIw.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-C2u9G8Pu.js → DID-B-Qa2mha.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-BFt5Yv3d.js → Dashboard-CMX0Qnxw.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-DIaT9Wxq.js → Dropdown-BLuLyRu_.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-D_A601Y4.js → EmailListRenderer-CFBAeMij.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard--IyQ8I8w.js → FamilyGuardDashboard-DWzXQ67V.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-BihWHxuY.js → Federation-DB1QSLgr.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-BB8dOXc_.js → FormItemContext-C-OKCToP.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-DQYhj1HH.js → GenericCardRenderer-DMJFtFZf.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-B-2QZxGf.js → Git-DsGSujOV.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-CusSb-nG.js → Governance-B0iS9NEW.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-BAjmvPPL.js → Inference-CH004H7c.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DoNYWKYq.js → KnowledgeGraph-Q9MTQ83c.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-B8fKWD-n.js → Logs-B_fyjZK9.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-BlJm1J7E.js → MarkdownRenderer-C0o4FtpD.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-CyOscbSL.js → Marketplace-BIStF9d1.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-Ex6Om5da.js → McpTools-pGfal768.js} +5 -5
  38. package/src/assets/web-panel/assets/{Memory-CDcD8l8r.js → Memory-xbNqpIqB.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-xfBqoFDg.js → MobileBridge-B5EQGrIK.js} +1 -1
  40. package/src/assets/web-panel/assets/MobileProjects-VTc3gT1y.js +1 -0
  41. package/src/assets/web-panel/assets/{Mtc-CIWd36OV.js → Mtc-a_rmfxJH.js} +5 -5
  42. package/src/assets/web-panel/assets/{MtcAudit-CPX0ouuA.js → MtcAudit-BmKuofUr.js} +4 -4
  43. package/src/assets/web-panel/assets/{Multisig-BDJsIUuW.js → Multisig-BQbJ-CAN.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-DEkbuD3N.js → NLProgramming-JtPJKX25.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-DJpHRhH1.js → Notes-ZFKznTSG.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-C1UZ-Qd5.js → NotificationSettings-B6aHRBBR.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-GlJtqLjT.js → OrderTableRenderer-DdcsOqEz.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-Bbhj0fac.js → Organization-BFDTAUgS.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-1H04x3kx.js → Overflow-0FoTfbWH.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-CDpPe3et.js → P2P-CWd90etw.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-MUX0Bpvw.js → PdhVaultBrowser-DtCGC-W-.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-A07-0Ci1.js → Permissions-CvQ7nr7T.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-DhhDWxAZ.js → PersonalDataHub-rdNPcR-Z.js} +5 -5
  54. package/src/assets/web-panel/assets/{Pipeline-CyfbJfe-.js → Pipeline-CmrfiNOs.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-CNFps3ED.js → Privacy-D7ep1h_t.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit--T-u3Dr5.js → ProjectInit-C0xKINHS.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-DJmrK2fC.js → ProjectSettings-AOmZFp-F.js} +2 -2
  58. package/src/assets/web-panel/assets/Projects-BWHSkXZP.js +1 -0
  59. package/src/assets/web-panel/assets/{Providers-DLzzbOZd.js → Providers-Cb7JCTPL.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-CexOomKS.js → QrScannerModal-BDMehcXC.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-QklGi19_.js → QuickAsk-BF6_1nvx.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-Bb9kwSw8.js → Recommend-BHfT-A28.js} +1 -1
  63. package/src/assets/web-panel/assets/RemoteSession-B6EEf8hh.js +5 -0
  64. package/src/assets/web-panel/assets/{Reputation-Dr5cLP0N.js → Reputation-CsWHLEcj.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-oCQHYv5t.js → Row-D6srnWhm.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-IFDEykIR.js → RssFeed-Xhr-KyVd.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-CspVIxDc.js → Search-vIbIJvwL.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-Bm66o_DH.js → Security-Bzi5Aiko.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-DvanNqXl.js → Services-BHtVX52P.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-CHjEe9_O.js → Skeleton-C0R8B2jf.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-Cb8jWjMX.js → Skills-DtT6rWOX.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-DxZm1491.js → Sla-0B37mxVU.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-DWxEEclC.js → SpeechSettings-0V2jE1Bs.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-FIvOFw5p.js → SyncSettings-CYedRzaj.js} +2 -2
  75. package/src/assets/web-panel/assets/Tasks-D-R1x8vm.js +1 -0
  76. package/src/assets/web-panel/assets/{Templates-CaNjzV_t.js → Templates-BKoHztGT.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-DjlP6TmH.js → Tenant--17nwVNZ.js} +1 -1
  78. package/src/assets/web-panel/assets/Terminal-Dnkos7vW.js +3 -0
  79. package/src/assets/web-panel/assets/{TimelineRenderer-DoZ8y7y8.js → TimelineRenderer-C5jx4AE3.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-390cg2TC.js → Tokens-DYJKYa9t.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-CLrtCj5_.js → Trigger-DChpWiQ9.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-DpESfSPn.js → Trust-DfWG52EA.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-CN6279O0.js → UkeySign-CMugYcyA.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-DPtAUlSe.js → VideoEditing-BOSmrHAd.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-nKOMV_1n.js → Wallet-D5g3k3Sa.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-HuXlSOc4.js → WebAuthn-D-7u4Mkc.js} +5 -5
  87. package/src/assets/web-panel/assets/{WorkflowEditor-CUfFjARi.js → WorkflowEditor-CFzZMSUJ.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-6Eq0PcZJ.js → chat-VbR6l6mc.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-BP_Sf6Iy.js → colors-BSZn8EDS.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-BufMKIh5.js → compact-item-y74obMEq.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-BBMXxWSW.js → createContext-C326bjex.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-D3Bho_6u.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-fUK_tRO2.js → hasIn-D_INJQT_.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-LvCBfTLo.js → index-4PIeTM--.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-CgiECHu2.js → index-4eyH-eC2.js} +1 -1
  96. package/src/assets/web-panel/assets/index-5iAFwYx1.js +1 -0
  97. package/src/assets/web-panel/assets/{index-DLpIs_P_.js → index-9PIVuXqo.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-cpEli44X.js → index-B7SrC-On.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-6GmBa4Kg.js → index-BJi3UqBt.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-D9vU25ij.js → index-BY8-nCgs.js} +1 -1
  101. package/src/assets/web-panel/assets/index-BfnB7LPx.js +1 -0
  102. package/src/assets/web-panel/assets/{index-B2vS66eI.js → index-Bfw2hf2s.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DVsqvI4M.js → index-BjcWKg1S.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-C44atv4k.js → index-BnSfnSMP.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BWKoBU8R.js → index-Bnua8IX3.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-GwdRUZ-x.js → index-C-ZCaUJc.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-pum7HYBA.js → index-C2NyllnW.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-B9WYSn4m.js → index-C327pLbw.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Bkg4ZePE.js → index-CMHqs3Jb.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DmkMXwnR.js → index-CfLJ42kv.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Dyngbd29.js → index-Cr3uuz0C.js} +19 -19
  112. package/src/assets/web-panel/assets/{index-t8N1tSeX.js → index-CsovTpx9.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DocdRcbd.js → index-CzE53HiB.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-fzaMtSJ8.js → index-DBkzrpiL.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CE2DdTP2.js → index-DNMxIsDg.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-wKTLbKyc.js → index-DUU2606o.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-uCbEN7cY.js → index-DdyjrCAu.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CZ6Yt17L.js → index-DkH1JvEt.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CwSf5pnf.js → index-Dlxh9D8D.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-3FuwBewR.js → index-DuIkfnTF.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CW_G-MXw.js → index-DwHSZLXg.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BHy6yNiF.js → index-E_v1ZCTP.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-wV6iGdpY.js → index-FQBsuExX.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DASluSqY.js → index-GA80ir_u.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BMLHv389.js → index-IZAWt0H8.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-B7Etk0Te.js → index-Iw0FfqUz.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-D4_MuGkd.js → index-KF9Zmqln.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Cp8vhyZy.js → index-abmn_8Yz.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-2A5ph8b2.js → index-gINyI1rh.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CeASi4fr.js → index-jYaogFE8.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CGjmILDm.js → index-nSn2-C4N.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DPdUNk1i.js → index-qMA4GYdQ.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-V5Fo95FM.js → initDefaultProps-DI0Zaf8-.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BYWU0hUT.js → motion-BZDKSy3Z.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-Cr1M-J2h.js → move-DsIW01Vp.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-BysQKi2N.js → mtc-parser-CohkDhsf.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-D1zHU8GC.js → omit-DpiN5rzg.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-CUArxtfi.js → pickAttrs-qbuqni3y.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-ChoYEys0.js → placementArrow-mBky6714.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-BQRs3Mo7.js → responsiveObserve-Bas3eQ2K.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-B8zbsCkg.js → slide-CBx_SKoK.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-C2U8Gs6h.js → statusUtils-BlYguJSV.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-Dd8MgL_V.js → styleChecker-BCYQmRGv.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-hknqY5NH.js → useFlexGapSupport-Dp5dybLM.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-CLTAmcfw.js → useFs-DHAMBgA2.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-ByegHbiB.js → usePersonalDataHub-W6jsSw76.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-DqlAy5DP.js → vnode-BkI6aayc.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-DiXiztQn.js → zoom-C_IMGueq.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/commands/agent.js +9 -0
  151. package/src/commands/background-session.js +49 -0
  152. package/src/commands/plugin.js +235 -23
  153. package/src/commands/session.js +13 -0
  154. package/src/data/changelog.json +13 -0
  155. package/src/harness/jsonl-session-store.js +6 -4
  156. package/src/lib/agent-team/team-runner.js +19 -1
  157. package/src/lib/background-agent-supervisor.js +49 -0
  158. package/src/lib/plugin-runtime/install.js +226 -7
  159. package/src/lib/plugin-runtime/scopes.js +13 -2
  160. package/src/lib/plugin-usage-attribution.js +44 -0
  161. package/src/lib/process-execution-broker/index.js +252 -1
  162. package/src/lib/process-execution-broker/platform-sandbox.js +1251 -101
  163. package/src/lib/session-usage.js +77 -0
  164. package/src/repl/agent-repl.js +6 -6
  165. package/src/runtime/headless-runner.js +9 -1
  166. package/src/runtime/headless-stream.js +20 -1
  167. package/src/runtime/mcp-config.js +15 -5
  168. package/src/assets/web-panel/assets/ChatBubbleRenderer-PR074hUN.js +0 -1
  169. package/src/assets/web-panel/assets/MobileProjects-BwObMMA2.js +0 -1
  170. package/src/assets/web-panel/assets/Projects-Qx_MdX9k.js +0 -1
  171. package/src/assets/web-panel/assets/RemoteSession-DZuVNNN5.js +0 -5
  172. package/src/assets/web-panel/assets/Tasks-CyuLnDFR.js +0 -1
  173. package/src/assets/web-panel/assets/Terminal-DwzGMniO.js +0 -3
  174. package/src/assets/web-panel/assets/devWarning-DgVKduH2.js +0 -1
  175. package/src/assets/web-panel/assets/index-DOZTSoS7.js +0 -1
  176. package/src/assets/web-panel/assets/index-DhpvjpqI.js +0 -1
@@ -12,6 +12,7 @@ import {
12
12
  readEvents,
13
13
  listJsonlSessions,
14
14
  } from "../harness/jsonl-session-store.js";
15
+ import { extractPluginUsageAttribution } from "./plugin-usage-attribution.js";
15
16
 
16
17
  // Injectable disk seams (tests override). readEvents skips malformed JSON lines
17
18
  // but does NOT guard readFileSync, so an unreadable session file (EACCES /
@@ -228,6 +229,7 @@ function _isToolResultError(event) {
228
229
  export function aggregateToolCalls(events) {
229
230
  const byTool = new Map();
230
231
  const byServer = new Map();
232
+ const byPlugin = new Map();
231
233
  let totalCalls = 0;
232
234
  let totalErrors = 0;
233
235
 
@@ -253,19 +255,42 @@ export function aggregateToolCalls(events) {
253
255
  }
254
256
  return s;
255
257
  };
258
+ const bumpPlugin = (plugin, version = null) => {
259
+ const key = `${plugin}@${version || "?"}`;
260
+ let row = byPlugin.get(key);
261
+ if (!row) {
262
+ row = {
263
+ plugin,
264
+ version: version || null,
265
+ calls: 0,
266
+ errors: 0,
267
+ turnTokens: 0,
268
+ };
269
+ byPlugin.set(key, row);
270
+ }
271
+ return row;
272
+ };
256
273
 
257
274
  let turnTools = new Set();
258
275
  let turnServers = new Set();
276
+ let turnPlugins = new Set();
259
277
  let turnTokens = 0;
278
+ let pendingPlugin = null;
260
279
  const flushTurn = () => {
261
280
  if (turnTokens > 0) {
262
281
  for (const name of turnTools) bumpTool(name).turnTokens += turnTokens;
263
282
  for (const server of turnServers)
264
283
  bumpServer(server).turnTokens += turnTokens;
284
+ for (const key of turnPlugins) {
285
+ const row = byPlugin.get(key);
286
+ if (row) row.turnTokens += turnTokens;
287
+ }
265
288
  }
266
289
  turnTools = new Set();
267
290
  turnServers = new Set();
291
+ turnPlugins = new Set();
268
292
  turnTokens = 0;
293
+ pendingPlugin = null;
269
294
  };
270
295
 
271
296
  for (const evt of events || []) {
@@ -292,6 +317,21 @@ export function aggregateToolCalls(events) {
292
317
  if (isErr) s.errors++;
293
318
  turnServers.add(server);
294
319
  }
320
+ const plugin =
321
+ typeof evt.data?.plugin === "string" && evt.data.plugin
322
+ ? evt.data.plugin
323
+ : null;
324
+ const pluginVersion =
325
+ typeof evt.data?.plugin_version === "string"
326
+ ? evt.data.plugin_version
327
+ : null;
328
+ pendingPlugin = { tool: name, plugin, version: pluginVersion };
329
+ if (plugin) {
330
+ const p = bumpPlugin(plugin, pluginVersion);
331
+ p.calls++;
332
+ if (isErr) p.errors++;
333
+ turnPlugins.add(`${plugin}@${pluginVersion || "?"}`);
334
+ }
295
335
  continue;
296
336
  }
297
337
  if (evt.type === "tool_result") {
@@ -304,6 +344,26 @@ export function aggregateToolCalls(events) {
304
344
  bumpTool(name).errors++;
305
345
  if (server) bumpServer(server).errors++;
306
346
  }
347
+ const extracted = extractPluginUsageAttribution(evt.data?.result);
348
+ const plugin =
349
+ typeof evt.data?.plugin === "string" && evt.data.plugin
350
+ ? evt.data.plugin
351
+ : extracted.plugin || null;
352
+ const pluginVersion =
353
+ typeof evt.data?.plugin_version === "string"
354
+ ? evt.data.plugin_version
355
+ : extracted.pluginVersion || null;
356
+ if (plugin) {
357
+ const p = bumpPlugin(plugin, pluginVersion);
358
+ const countedByCall =
359
+ pendingPlugin?.tool === name &&
360
+ pendingPlugin?.plugin === plugin &&
361
+ (pendingPlugin?.version || null) === (pluginVersion || null);
362
+ if (!countedByCall) p.calls++;
363
+ if (_isToolResultError(evt) && !countedByCall) p.errors++;
364
+ turnPlugins.add(`${plugin}@${pluginVersion || "?"}`);
365
+ }
366
+ pendingPlugin = null;
307
367
  continue;
308
368
  }
309
369
  const u = extractUsage(evt);
@@ -317,6 +377,7 @@ export function aggregateToolCalls(events) {
317
377
  totalErrors,
318
378
  byTool: Array.from(byTool.values()).sort(byCallsDesc),
319
379
  byMcpServer: Array.from(byServer.values()).sort(byCallsDesc),
380
+ byPlugin: Array.from(byPlugin.values()).sort(byCallsDesc),
320
381
  };
321
382
  }
322
383
 
@@ -457,6 +518,7 @@ export function allSessionsUsage({ limit = 1000 } = {}) {
457
518
  const gSubagent = new Map();
458
519
  const gTool = new Map();
459
520
  const gServer = new Map();
521
+ const gPlugin = new Map();
460
522
  let gToolCalls = 0;
461
523
  let gToolErrors = 0;
462
524
  const mergeRow = (map, key, row, seed) => {
@@ -508,6 +570,20 @@ export function allSessionsUsage({ limit = 1000 } = {}) {
508
570
  entry.turnTokens += row.turnTokens || 0;
509
571
  gServer.set(row.server, entry);
510
572
  }
573
+ for (const row of tools.byPlugin || []) {
574
+ const key = `${row.plugin}@${row.version || "?"}`;
575
+ const entry = gPlugin.get(key) || {
576
+ plugin: row.plugin,
577
+ version: row.version || null,
578
+ calls: 0,
579
+ errors: 0,
580
+ turnTokens: 0,
581
+ };
582
+ entry.calls += row.calls || 0;
583
+ entry.errors += row.errors || 0;
584
+ entry.turnTokens += row.turnTokens || 0;
585
+ gPlugin.set(key, entry);
586
+ }
511
587
  }
512
588
  const byCallsDesc = (a, b) => b.calls - a.calls;
513
589
 
@@ -527,6 +603,7 @@ export function allSessionsUsage({ limit = 1000 } = {}) {
527
603
  totalErrors: gToolErrors,
528
604
  byTool: Array.from(gTool.values()).sort(byCallsDesc),
529
605
  byMcpServer: Array.from(gServer.values()).sort(byCallsDesc),
606
+ byPlugin: Array.from(gPlugin.values()).sort(byCallsDesc),
530
607
  },
531
608
  },
532
609
  };
@@ -108,6 +108,7 @@ import {
108
108
  import { resolveSlashMacro } from "./slash-macro.js";
109
109
  import { expandMcpPrompt, renderMcpSurface } from "./mcp-prompt.js";
110
110
  import { newCostStore, addUsage } from "./session-cost.js";
111
+ import { extractPluginUsageAttribution } from "../lib/plugin-usage-attribution.js";
111
112
  import { parseThinkCommand, parseEffortCommand } from "./think-command.js";
112
113
  import { parseBtwCommand, buildAsideBlock, applyAside } from "./btw-command.js";
113
114
  import { shouldStreamLive } from "./stream-decision.js";
@@ -360,9 +361,9 @@ export async function agentLoop(messages, options) {
360
361
  );
361
362
  } else if (event.type === "tool-result") {
362
363
  // 用量归因: persist a compact tool_call record (name + error flag +
363
- // skill hint — never args, which can carry whole file bodies) so
364
- // `cc session usage --by tool|mcp` and `cc insights` can aggregate
365
- // tool use for REPL sessions. Best-effort; opt out with
364
+ // skill/plugin hints — never args, which can carry whole file bodies)
365
+ // so `cc session usage --by tool|mcp|plugin` and `cc insights` can
366
+ // aggregate tool use for REPL sessions. Best-effort; opt out with
366
367
  // options.persistToolCalls === false.
367
368
  if (options.sessionId && options.persistToolCalls !== false) {
368
369
  try {
@@ -373,6 +374,7 @@ export async function agentLoop(messages, options) {
373
374
  event.tool === "run_skill" && _lastExec?.tool === "run_skill"
374
375
  ? _lastExec.args?.skill_name
375
376
  : undefined,
377
+ ...extractPluginUsageAttribution(event.result),
376
378
  });
377
379
  } catch (_e) {
378
380
  // persistence is best-effort — never break the turn
@@ -1844,9 +1846,7 @@ export async function startAgentRepl(options = {}) {
1844
1846
  " Open this secure page? [y/N] ",
1845
1847
  ),
1846
1848
  async (answer) => {
1847
- const approved = /^(y|yes)$/i.test(
1848
- String(answer || "").trim(),
1849
- );
1849
+ const approved = /^(y|yes)$/i.test(String(answer || "").trim());
1850
1850
  if (!approved) {
1851
1851
  resolve({ action: "decline" });
1852
1852
  rl.prompt();
@@ -95,6 +95,7 @@ import {
95
95
  formatDenials,
96
96
  } from "../lib/repl-denials.js";
97
97
  import executionBroker from "../lib/process-execution-broker/index.js";
98
+ import { extractPluginUsageAttribution } from "../lib/plugin-usage-attribution.js";
98
99
 
99
100
  const goalBrokerRunner = executionBroker.spawnSync.bind(executionBroker);
100
101
 
@@ -2054,7 +2055,12 @@ export async function runAgentHeadless(options = {}, deps = {}) {
2054
2055
  : {}),
2055
2056
  });
2056
2057
  if (toolCalls.length > 0) {
2057
- toolCalls[toolCalls.length - 1].is_error = Boolean(err);
2058
+ const settledCall = toolCalls[toolCalls.length - 1];
2059
+ settledCall.is_error = Boolean(err);
2060
+ Object.assign(
2061
+ settledCall,
2062
+ extractPluginUsageAttribution(event.result),
2063
+ );
2058
2064
  }
2059
2065
  // Track policy denials (not plain tool failures) for the end-of-run
2060
2066
  // summary. The preceding tool-executing pushed the args.
@@ -2532,6 +2538,8 @@ export async function runAgentHeadless(options = {}, deps = {}) {
2532
2538
  isError: Boolean(tc.is_error),
2533
2539
  skill:
2534
2540
  tc.tool === "run_skill" ? tc.args?.skill_name || null : undefined,
2541
+ plugin: tc.plugin || undefined,
2542
+ pluginVersion: tc.pluginVersion || undefined,
2535
2543
  });
2536
2544
  }
2537
2545
  // Attributed child-loop usage first (chronology: it happened during
@@ -81,6 +81,7 @@ import {
81
81
  startSession as jsonlStartSession,
82
82
  appendUserMessage as jsonlAppendUserMessage,
83
83
  appendAssistantMessage as jsonlAppendAssistantMessage,
84
+ appendToolCallCompact as jsonlAppendToolCallCompact,
84
85
  appendEvent as jsonlAppendEvent,
85
86
  readEvents as jsonlReadEvents,
86
87
  rebuildMessages as jsonlRebuildMessages,
@@ -105,6 +106,7 @@ import {
105
106
  executeSessionSlashCommand,
106
107
  parseSessionSlashCommandEvent,
107
108
  } from "./session-slash-commands.js";
109
+ import { extractPluginUsageAttribution } from "../lib/plugin-usage-attribution.js";
108
110
 
109
111
  /**
110
112
  * Resolve the streaming-delta coalesce window (ms). Adjacent partial-message
@@ -871,7 +873,10 @@ async function runTurn(
871
873
  ? toolCalls.find((call) => call.id === event.tool_use_id)
872
874
  : null) ||
873
875
  (toolCalls.length > 0 ? toolCalls[toolCalls.length - 1] : null);
874
- if (lastCall) lastCall.is_error = Boolean(err);
876
+ if (lastCall) {
877
+ lastCall.is_error = Boolean(err);
878
+ Object.assign(lastCall, extractPluginUsageAttribution(event.result));
879
+ }
875
880
  const pm = getPlanModeManager();
876
881
  const settledItem = lastCall?.planItemId
877
882
  ? pm.settlePlanItem(lastCall.planItemId, {
@@ -1190,6 +1195,8 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1190
1195
  appendUserMessage: deps.appendUserMessage || jsonlAppendUserMessage,
1191
1196
  appendAssistantMessage:
1192
1197
  deps.appendAssistantMessage || jsonlAppendAssistantMessage,
1198
+ appendToolCallCompact:
1199
+ deps.appendToolCallCompact || jsonlAppendToolCallCompact,
1193
1200
  appendEvent: deps.appendEvent || jsonlAppendEvent,
1194
1201
  readEvents: deps.readEvents || jsonlReadEvents,
1195
1202
  rebuildMessages: deps.rebuildMessages || jsonlRebuildMessages,
@@ -2897,6 +2904,18 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
2897
2904
  if (persist) {
2898
2905
  try {
2899
2906
  store.appendAssistantMessage(sessionId, outcome.finalText);
2907
+ for (const call of outcome.toolCalls || []) {
2908
+ store.appendToolCallCompact(sessionId, {
2909
+ tool: call.tool,
2910
+ isError: Boolean(call.is_error),
2911
+ skill:
2912
+ call.tool === "run_skill"
2913
+ ? call.args?.skill_name || null
2914
+ : undefined,
2915
+ plugin: call.plugin || undefined,
2916
+ pluginVersion: call.pluginVersion || undefined,
2917
+ });
2918
+ }
2900
2919
  } catch {
2901
2920
  /* best-effort */
2902
2921
  }
@@ -153,7 +153,8 @@ export async function setupMcpFromConfig(servers, deps = {}) {
153
153
  const writeErr = deps.writeErr || (() => {});
154
154
  const createClient =
155
155
  deps.createClient ||
156
- (() => new MCPClient({ eventRuntimeStore: deps.eventRuntimeStore || null }));
156
+ (() =>
157
+ new MCPClient({ eventRuntimeStore: deps.eventRuntimeStore || null }));
157
158
  servers = filterMcpServersByPolicy(servers, deps.mcpPolicy, writeErr);
158
159
 
159
160
  // `deps.into` lets a second batch (e.g. registered servers) accumulate into
@@ -194,8 +195,10 @@ export async function setupMcpFromConfig(servers, deps = {}) {
194
195
  if (deps.sessionId != null && typeof mcpClient.setSessionId === "function") {
195
196
  mcpClient.setSessionId(deps.sessionId);
196
197
  }
197
- if (typeof mcpClient.setElicitationHandler === "function" &&
198
- typeof deps.elicitationHandler === "function") {
198
+ if (
199
+ typeof mcpClient.setElicitationHandler === "function" &&
200
+ typeof deps.elicitationHandler === "function"
201
+ ) {
199
202
  mcpClient.setElicitationHandler(deps.elicitationHandler, {
200
203
  timeoutMs: deps.elicitationTimeoutMs,
201
204
  });
@@ -310,7 +313,12 @@ export async function setupMcpFromConfig(servers, deps = {}) {
310
313
  name: full,
311
314
  kind: "mcp",
312
315
  category: "mcp",
313
- source: name,
316
+ // A trusted plugin MCP server carries immutable plugin provenance in
317
+ // its collected server config. Preserve it at the tool descriptor
318
+ // boundary so toolAttribution and persisted usage can distinguish a
319
+ // plugin-provided MCP tool from a user/project MCP server.
320
+ source: cfg.pluginId ? `plugin:${cfg.pluginId}` : name,
321
+ ...(cfg.pluginVersion ? { version: cfg.pluginVersion } : {}),
314
322
  };
315
323
  }
316
324
  }
@@ -770,7 +778,9 @@ export async function resolveAgentMcp(args = {}, deps = {}) {
770
778
  const eventRuntimeStore =
771
779
  deps.eventRuntimeStore ||
772
780
  args.eventRuntimeStore ||
773
- (runtimeEnv.CC_EVENT_RUNTIME_DURABLE === "1" ? new EventRuntimeStore() : null);
781
+ (runtimeEnv.CC_EVENT_RUNTIME_DURABLE === "1"
782
+ ? new EventRuntimeStore()
783
+ : null);
774
784
  // Thread the agent session id down to setupMcpFromConfig so spawned stdio MCP
775
785
  // servers get CC_SESSION_ID / CLAUDE_CODE_SESSION_ID (Claude-Code parity).
776
786
  let mcpPolicy = deps.mcpPolicy || null;
@@ -1 +0,0 @@
1
- import{I as v,P as u,J as S,U as n,R as a,S as y,K as C,Q as x,V as w,_ as B,b as s}from"./vendor-Bn1JzzAn.js";import{_ as k}from"./index-Dyngbd29.js";import"./icons-DG5UD-6K.js";const N={__name:"ChatBubbleRenderer",props:{event:{type:Object,required:!0}},setup(c,{expose:i}){i();const t=c,r=s(()=>{const e=t.event.content||{};return e.text||e.body||e.message||e.title||JSON.stringify(e).slice(0,200)}),d=s(()=>{const e=t.event.content||{};return e.from||e.sender||e.senderName||t.event.actor||"(unknown)"}),l=s(()=>{const e=(t.event.actor||"").toLowerCase();return e.includes("self")||e==="me"||e.endsWith("_self")}),o=s(()=>{const e=t.event.source.adapter||"";return e.startsWith("messaging-qq")?"magenta":e==="wechat"?"green":"blue"}),m=s(()=>{if(!t.event.occurredAt)return"";try{const e=new Date(t.event.occurredAt),p=e.getFullYear(),f=String(e.getMonth()+1).padStart(2,"0"),g=String(e.getDate()).padStart(2,"0"),b=String(e.getHours()).padStart(2,"0"),h=String(e.getMinutes()).padStart(2,"0");return`${p}-${f}-${g} ${b}:${h}`}catch{return""}}),_={props:t,messageText:r,actorLabel:d,isMine:l,adapterColor:o,formattedTime:m,computed:s};return Object.defineProperty(_,"__isScriptSetup",{enumerable:!1,value:!0}),_}},T={class:"bubble"},M={class:"meta"},R={class:"actor"},V={class:"time"},q={class:"body"};function A(c,i,t,r,d,l){const o=v("a-tag");return u(),S("div",{class:B(["chat-row",{mine:r.isMine}])},[n("div",T,[n("div",M,[n("span",R,a(r.actorLabel),1),n("span",V,a(r.formattedTime),1)]),n("div",q,a(r.messageText),1),t.event.source.adapter?(u(),y(o,{key:0,class:"src",color:r.adapterColor},{default:C(()=>[x(a(t.event.source.adapter),1)]),_:1},8,["color"])):w("v-if",!0)])],2)}const j=k(N,[["render",A],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-UAH1Xi/repo/packages/web-panel/src/components/pdh/renderers/ChatBubbleRenderer.vue"]]);export{j as default};
@@ -1 +0,0 @@
1
- import{I as n,J as g,c as l,K as r,N as u,P as h,U as o,R as t,Q as b}from"./vendor-Bn1JzzAn.js";import{_ as v,b as m}from"./index-Dyngbd29.js";import{a8 as y,M}from"./icons-DG5UD-6K.js";const B={__name:"MobileProjects",setup(p,{expose:i}){i();const c=u(),{t:e}=m();function a(){c.push("/projects")}function _(){c.push("/mobile-bridge")}const s={router:c,t:e,goToProjects:a,goToMobileBridge:_,get useRouter(){return u},get useI18n(){return m},get MobileOutlined(){return M},get FolderOutlined(){return y}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},x={class:"mobile-projects-placeholder"},O={class:"title"},k={class:"subtitle"},w={class:"explainer"};function T(p,i,c,e,a,_){const s=n("a-alert"),d=n("a-button"),f=n("a-space"),P=n("a-empty"),j=n("a-card");return h(),g("div",x,[l(j,null,{default:r(()=>[l(P,{description:!1},{image:r(()=>[l(e.MobileOutlined,{style:{fontSize:"64px",color:"#bfbfbf"}})]),default:r(()=>[o("h2",O,t(e.t("mobileProjects.title")),1),o("p",k,t(e.t("mobileProjects.subtitle")),1),l(s,{message:e.t("mobileProjects.v02Banner"),type:"info","show-icon":"",class:"banner"},null,8,["message"]),o("div",w,[o("h3",null,t(e.t("mobileProjects.currentDirection")),1),o("p",null,t(e.t("mobileProjects.currentDirectionBody")),1),o("ul",null,[o("li",null,t(e.t("mobileProjects.stepPhone")),1),o("li",null,t(e.t("mobileProjects.stepTap")),1),o("li",null,t(e.t("mobileProjects.stepPull")),1)]),o("h3",null,t(e.t("mobileProjects.reverseDirection")),1),o("p",null,t(e.t("mobileProjects.reverseDirectionBody")),1)]),l(f,{class:"actions"},{default:r(()=>[l(d,{type:"primary",onClick:e.goToProjects},{default:r(()=>[l(e.FolderOutlined),b(" "+t(e.t("mobileProjects.viewLocalProjects")),1)]),_:1}),l(d,{onClick:e.goToMobileBridge},{default:r(()=>[l(e.MobileOutlined),b(" "+t(e.t("mobileProjects.checkBridge")),1)]),_:1})]),_:1})]),_:1})]),_:1})])}const N=v(B,[["render",T],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-UAH1Xi/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{N as default};
@@ -1 +0,0 @@
1
- import{I as i,J as U,U as I,R as s,Q as r,c as t,K as a,V as _,S as x,o as oe,b as ee,r as u,P as p,F as ne,a2 as ge}from"./vendor-Bn1JzzAn.js";import{_ as we,b as re,u as ie,d}from"./index-Dyngbd29.js";import{u as de}from"./useShellMode-CgR0wCYM.js";import{aN as ke,aO as Fe,aP as be,f as je,a5 as Ce,a8 as xe,at as Oe,R as Se}from"./icons-DG5UD-6K.js";const Pe={__name:"Projects",setup(se,{expose:l}){l();const{t:te}=re(),e=ie(),{isEmbedded:W}=de();async function w(o,f,ye,ae=8e3){if(W){const Z=await e.sendRaw({...f,type:o},ae);if(!Z?.ok){const $=Z?.error;throw new Error(typeof $=="string"?$:$?.message||`${o} failed`)}return Z.result}return e.executeJson(ye,ae)}const B=u(!1),y=u([]),O=u(""),S=u(""),P=u(!1),v=u(null),h=u([]),k=u(!1),E=u(!1),L=u(!1),F=u({name:"",description:"",type:"document",rootPath:""}),z=[{title:"ID",key:"id",width:110},{title:"名称",key:"name"},{title:"类型",key:"project_type",width:120},{title:"状态",key:"status",width:100},{title:"同步",key:"sync_status",width:100},{title:"更新",key:"updated_at",width:160},{title:"操作",key:"actions",width:180,fixed:"right"}],V=ee(()=>{const o={active:0,draft:0,completed:0,archived:0};for(const f of y.value)o[f.status]!==void 0&&(o[f.status]+=1);return o}),J=ee(()=>y.value.filter(o=>!(O.value&&o.status!==O.value||S.value&&!o.name.toLowerCase().includes(S.value.toLowerCase()))));function g(o){switch(o){case"active":return"green";case"draft":return"default";case"completed":return"cyan";case"archived":return"gold";default:return"default"}}function H(o){switch(o){case"synced":return"green";case"pending":return"orange";case"conflict":return"red";case"error":return"red";default:return"default"}}function K(o){return!o&&o!==0?"-":new Date(typeof o=="number"?o:parseInt(o,10)).toLocaleString("zh-CN",{hour12:!1})}async function C(){B.value=!0;try{const o=await w("project.list",{limit:500},"project list --limit 500 --json",1e4);y.value=Array.isArray(o?.projects)?o.projects:Array.isArray(o)?o:[]}catch(o){d.error("加载失败: "+(o.message||o)),y.value=[]}finally{B.value=!1}}function Q(o){return{onClick:()=>M(o)}}async function M(o){v.value=o,P.value=!0,k.value=!0,h.value=[];try{const f=await w("project.listFiles",{projectId:o.id,limit:200},`project list-files ${o.id} --json`,8e3);h.value=Array.isArray(f?.files)?f.files:[]}catch{h.value=[]}finally{k.value=!1}}async function X(o){try{(await w("project.delete",{id:o.id},`project delete ${o.id} --json`,8e3))?.ok?(d.success(`已删除项目 '${o.name}'`),P.value=!1,await C()):d.error("删除失败")}catch(f){d.error(f.message||String(f))}}function G(){F.value={name:"",description:"",type:"document",rootPath:""},E.value=!0}async function T(){if(!F.value.name.trim()){d.warning("请输入项目名称");return}L.value=!0;try{const o=await w("project.init",{name:F.value.name.trim(),description:F.value.description||null,projectType:F.value.type,rootPath:F.value.rootPath||null},`project init "${F.value.name.trim()}" --type ${F.value.type} --json`,8e3);o?.id?(d.success(`已创建项目 '${o.name}'`),E.value=!1,await C()):d.error("创建失败")}catch(o){d.error(o.message||String(o))}finally{L.value=!1}}const b=u(!1),D=u(!1),j=u({path:"",content:""}),A=u(!1),m=u(!1),R=u({path:""}),n=u(!1),c=u(null),q=u(""),Y=u(!1);function ue(){j.value={path:"",content:""},b.value=!0}function ce(){R.value={path:""},A.value=!0}async function N(){if(v.value){k.value=!0;try{const o=await w("project.listFiles",{projectId:v.value.id,limit:200},`project list-files ${v.value.id} --json`,8e3);h.value=Array.isArray(o?.files)?o.files:[]}catch(o){d.error("刷新文件失败: "+(o.message||o))}finally{k.value=!1}}}async function fe(){if(!j.value.path.trim()){d.warning("请输入文件路径");return}if(v.value){D.value=!0;try{const o=await w("project.createFile",{projectId:v.value.id,filePath:j.value.path.trim(),content:j.value.content||""},`project create-file ${v.value.id} "${j.value.path.trim()}" --json`,8e3);o?.id?(d.success(`已创建文件 '${o.file_name}'`),b.value=!1,await N(),await C()):d.error("创建文件失败")}catch(o){d.error(o.message||String(o))}finally{D.value=!1}}}async function pe(){if(!R.value.path.trim()){d.warning("请输入文件夹路径");return}if(v.value){m.value=!0;try{const o=await w("project.createFolder",{projectId:v.value.id,folderPath:R.value.path.trim()},`project create-folder ${v.value.id} "${R.value.path.trim()}" --json`,8e3);o?.id?(d.success(`已创建文件夹 '${o.file_name}'`),A.value=!1,await N(),await C()):d.error("创建文件夹失败")}catch(o){d.error(o.message||String(o))}finally{m.value=!1}}}async function ve(o){try{(await w("project.deleteFile",{fileId:o.id},`project delete-file ${o.id} --json`,8e3))?.deleted?(d.success(`已删除 '${o.file_name}'`),await N(),await C()):d.error("删除失败")}catch(f){d.error(f.message||String(f))}}async function me(o){if(o.is_folder){d.info("文件夹无内容可编辑");return}try{const f=await w("project.getFile",{fileId:o.id},`project get-file ${o.id} --json`,8e3);c.value=o,q.value=f?.content||"",n.value=!0}catch(f){d.error("读取文件失败: "+(f.message||f))}}async function _e(){if(c.value){Y.value=!0;try{(await w("project.writeFile",{fileId:c.value.id,content:q.value},`project write-file ${c.value.id} --json`,8e3))?.id?(d.success("已保存"),n.value=!1,await N()):d.error("保存失败")}catch(o){d.error(o.message||String(o))}finally{Y.value=!1}}}oe(()=>{C()});const le={t:te,ws:e,isEmbedded:W,callProjectTopic:w,loading:B,projects:y,statusFilter:O,nameFilter:S,detailOpen:P,detail:v,files:h,filesLoading:k,createOpen:E,creating:L,newProject:F,columns:z,countByStatus:V,filteredProjects:J,statusColor:g,syncColor:H,formatTime:K,loadAll:C,onRowClick:Q,openDetail:M,onDelete:X,onShowCreate:G,onCreate:T,createFileOpen:b,creatingFile:D,newFile:j,createFolderOpen:A,creatingFolder:m,newFolder:R,editFileOpen:n,editingFile:c,editFileContent:q,savingFile:Y,openCreateFile:ue,openCreateFolder:ce,refreshFiles:N,onCreateFile:fe,onCreateFolder:pe,onDeleteFile:ve,openEditFile:me,onSaveFile:_e,ref:u,computed:ee,onMounted:oe,get ReloadOutlined(){return Se},get PlusOutlined(){return Oe},get FolderOutlined(){return xe},get FileTextOutlined(){return Ce},get CheckCircleOutlined(){return je},get CheckSquareOutlined(){return be},get FileAddOutlined(){return Fe},get FolderAddOutlined(){return ke},get message(){return d},get useI18n(){return re},get useWsStore(){return ie},get useShellMode(){return de}};return Object.defineProperty(le,"__isScriptSetup",{enumerable:!1,value:!0}),le}},ze={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},Ae={class:"page-title"},Ue={class:"page-sub"},Ie={class:"filter-bar",style:{"margin-bottom":"12px",display:"flex",gap:"12px","align-items":"center"}},he={key:0,style:{"font-size":"12px",color:"#888"}},De={key:0,style:{color:"#888","font-size":"12px"}},Re={key:0},Te={key:1,style:{color:"#888"}},Be=["onClick"],Ee={key:0,style:{color:"#888","font-size":"12px"}};function Le(se,l,te,e,W,w){const B=i("router-link"),y=i("a-button"),O=i("a-space"),S=i("a-statistic"),P=i("a-card"),v=i("a-col"),h=i("a-row"),k=i("a-radio-button"),E=i("a-radio-group"),L=i("a-input-search"),F=i("a-alert"),z=i("a-tag"),V=i("a-popconfirm"),J=i("a-table"),g=i("a-descriptions-item"),H=i("a-descriptions"),K=i("a-divider"),C=i("a-empty"),Q=i("a-list-item"),M=i("a-list"),X=i("a-spin"),G=i("a-drawer"),T=i("a-input"),b=i("a-form-item"),D=i("a-textarea"),j=i("a-form"),A=i("a-modal"),m=i("a-select-option"),R=i("a-select");return p(),U("div",null,[I("div",ze,[I("div",null,[I("h2",Ae,s(e.t("projects.title")),1),I("p",Ue,[l[17]||(l[17]=r("桌面 / CLI / 手机 三端共享同一份项目数据,Phase 3d sync 自动同步 (",-1)),t(B,{to:"/project-init"},{default:a(()=>[...l[16]||(l[16]=[r("项目初始化 / 环境设置",-1)])]),_:1}),l[18]||(l[18]=r(")",-1))])]),t(O,null,{default:a(()=>[t(y,{loading:e.loading,onClick:e.loadAll},{icon:a(()=>[t(e.ReloadOutlined)]),default:a(()=>[l[19]||(l[19]=r(" 刷新 ",-1))]),_:1},8,["loading"]),t(y,{type:"primary",onClick:e.onShowCreate},{icon:a(()=>[t(e.PlusOutlined)]),default:a(()=>[l[20]||(l[20]=r(" 新建项目 ",-1))]),_:1})]),_:1})]),_(" Stats "),t(h,{gutter:[16,16],style:{"margin-bottom":"20px"}},{default:a(()=>[t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"总项目",value:e.projects.length,"value-style":{color:"#1677ff",fontSize:"20px"}},{prefix:a(()=>[t(e.FolderOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"活跃",value:e.countByStatus.active,"value-style":{color:"#52c41a",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckCircleOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"草稿",value:e.countByStatus.draft,"value-style":{color:"#8c8c8c",fontSize:"20px"}},{prefix:a(()=>[t(e.FileTextOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"已完成",value:e.countByStatus.completed,"value-style":{color:"#13c2c2",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckSquareOutlined)]),_:1},8,["value"])]),_:1})]),_:1})]),_:1}),_(" Filter "),I("div",Ie,[t(E,{value:e.statusFilter,"onUpdate:value":l[0]||(l[0]=n=>e.statusFilter=n),size:"small","button-style":"solid"},{default:a(()=>[t(k,{value:""},{default:a(()=>[...l[21]||(l[21]=[r("全部",-1)])]),_:1}),t(k,{value:"active"},{default:a(()=>[...l[22]||(l[22]=[r("活跃",-1)])]),_:1}),t(k,{value:"draft"},{default:a(()=>[...l[23]||(l[23]=[r("草稿",-1)])]),_:1}),t(k,{value:"completed"},{default:a(()=>[...l[24]||(l[24]=[r("已完成",-1)])]),_:1}),t(k,{value:"archived"},{default:a(()=>[...l[25]||(l[25]=[r("已归档",-1)])]),_:1})]),_:1},8,["value"]),t(L,{value:e.nameFilter,"onUpdate:value":l[1]||(l[1]=n=>e.nameFilter=n),placeholder:"按名称过滤",style:{"max-width":"260px"},"allow-clear":""},null,8,["value"])]),!e.projects.length&&!e.loading?(p(),x(F,{key:0,type:"info",message:"还没有项目",description:'运行 `cc project init <name>` 或点击右上角"新建项目"按钮创建。桌面 / CLI / 手机三端共享同一份数据。',"show-icon":"",style:{"margin-bottom":"16px"}})):_("v-if",!0),e.projects.length||e.loading?(p(),x(J,{key:1,columns:e.columns,"data-source":e.filteredProjects,loading:e.loading,pagination:{pageSize:20,showSizeChanger:!0},"row-key":"id","custom-row":e.onRowClick},{bodyCell:a(({column:n,record:c})=>[n.key==="id"?(p(),U("code",he,s(c.id.slice(0,8))+"…",1)):n.key==="name"?(p(),U(ne,{key:1},[I("strong",null,s(c.name),1),c.description?(p(),U("div",De,s(c.description),1)):_("v-if",!0)],64)):n.key==="project_type"?(p(),x(z,{key:2},{default:a(()=>[r(s(c.project_type),1)]),_:2},1024)):n.key==="status"?(p(),x(z,{key:3,color:e.statusColor(c.status)},{default:a(()=>[r(s(c.status),1)]),_:2},1032,["color"])):n.key==="sync_status"?(p(),x(z,{key:4,color:e.syncColor(c.sync_status)},{default:a(()=>[r(s(c.sync_status||"unknown"),1)]),_:2},1032,["color"])):n.key==="updated_at"?(p(),U(ne,{key:5},[r(s(e.formatTime(c.updated_at)),1)],64)):n.key==="actions"?(p(),x(O,{key:6,onClick:l[2]||(l[2]=ge(()=>{},["stop"]))},{default:a(()=>[t(y,{size:"small",onClick:q=>e.openDetail(c)},{default:a(()=>[...l[26]||(l[26]=[r("详情",-1)])]),_:1},8,["onClick"]),t(V,{title:`删除项目 '${c.name}' ?`,"ok-text":"删除","ok-type":"danger","cancel-text":"取消",onConfirm:q=>e.onDelete(c)},{default:a(()=>[t(y,{size:"small",danger:""},{default:a(()=>[...l[27]||(l[27]=[r("删除",-1)])]),_:1})]),_:1},8,["title","onConfirm"])]),_:2},1024)):_("v-if",!0)]),_:1},8,["data-source","loading"])):_("v-if",!0),_(" Detail drawer "),t(G,{open:e.detailOpen,"onUpdate:open":l[3]||(l[3]=n=>e.detailOpen=n),title:e.detail?.name||"项目详情",width:"640",placement:"right"},{default:a(()=>[e.detail?(p(),x(H,{key:0,column:1,bordered:"",size:"small"},{default:a(()=>[t(g,{label:"ID"},{default:a(()=>[I("code",null,s(e.detail.id),1)]),_:1}),t(g,{label:"名称"},{default:a(()=>[r(s(e.detail.name),1)]),_:1}),t(g,{label:"描述"},{default:a(()=>[r(s(e.detail.description||"-"),1)]),_:1}),t(g,{label:"类型"},{default:a(()=>[t(z,null,{default:a(()=>[r(s(e.detail.project_type),1)]),_:1})]),_:1}),t(g,{label:"状态"},{default:a(()=>[t(z,{color:e.statusColor(e.detail.status)},{default:a(()=>[r(s(e.detail.status),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"同步状态"},{default:a(()=>[t(z,{color:e.syncColor(e.detail.sync_status)},{default:a(()=>[r(s(e.detail.sync_status||"unknown"),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"用户"},{default:a(()=>[r(s(e.detail.user_id),1)]),_:1}),t(g,{label:"根路径"},{default:a(()=>[e.detail.root_path?(p(),U("code",Re,s(e.detail.root_path),1)):(p(),U("span",Te,"(无)"))]),_:1}),t(g,{label:"文件数"},{default:a(()=>[r(s(e.detail.file_count||0),1)]),_:1}),t(g,{label:"创建"},{default:a(()=>[r(s(e.formatTime(e.detail.created_at)),1)]),_:1}),t(g,{label:"更新"},{default:a(()=>[r(s(e.formatTime(e.detail.updated_at)),1)]),_:1})]),_:1})):_("v-if",!0),t(K,null,{default:a(()=>[...l[28]||(l[28]=[r("文件",-1)])]),_:1}),_(" Sub-phase 7.3 (2026-05-17): 文件 CRUD toolbar "),t(O,{style:{"margin-bottom":"12px"}},{default:a(()=>[t(y,{size:"small",type:"primary",disabled:!e.detail,onClick:e.openCreateFile},{default:a(()=>[t(e.FileAddOutlined),l[29]||(l[29]=r(" 新建文件 ",-1))]),_:1},8,["disabled"]),t(y,{size:"small",disabled:!e.detail,onClick:e.openCreateFolder},{default:a(()=>[t(e.FolderAddOutlined),l[30]||(l[30]=r(" 新建文件夹 ",-1))]),_:1},8,["disabled"])]),_:1}),t(X,{spinning:e.filesLoading},{default:a(()=>[!e.files.length&&!e.filesLoading?(p(),x(C,{key:0,description:"无文件 (点上方按钮新建)"})):(p(),x(M,{key:1,size:"small","data-source":e.files},{renderItem:a(({item:n})=>[t(Q,null,{extra:a(()=>[t(O,null,{default:a(()=>[n.file_size?(p(),U("span",Ee,s(n.file_size)+" B",1)):_("v-if",!0),t(V,{title:`删除 ${n.is_folder?"文件夹":"文件"} '${n.file_name}' ?`,"ok-text":"删除","ok-type":"danger","cancel-text":"取消",onConfirm:c=>e.onDeleteFile(n)},{default:a(()=>[t(y,{size:"small",danger:""},{default:a(()=>[...l[31]||(l[31]=[r("×",-1)])]),_:1})]),_:1},8,["title","onConfirm"])]),_:2},1024)]),default:a(()=>[I("span",{style:{cursor:"pointer"},onClick:c=>e.openEditFile(n)},s(n.is_folder?"📁":"📄")+" "+s(n.file_path),9,Be)]),_:2},1024)]),_:1},8,["data-source"]))]),_:1},8,["spinning"])]),_:1},8,["open","title"]),_(" Sub-phase 7.3: Create file modal "),t(A,{open:e.createFileOpen,"onUpdate:open":l[6]||(l[6]=n=>e.createFileOpen=n),title:"新建文件","confirm-loading":e.creatingFile,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreateFile},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"文件路径(项目内)",required:""},{default:a(()=>[t(T,{value:e.newFile.path,"onUpdate:value":l[4]||(l[4]=n=>e.newFile.path=n),placeholder:"例如 README.md 或 src/main.kt"},null,8,["value"])]),_:1}),t(b,{label:"初始内容(可选)"},{default:a(()=>[t(D,{value:e.newFile.content,"onUpdate:value":l[5]||(l[5]=n=>e.newFile.content=n),rows:6,placeholder:"留空创建空文件"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"]),_(" Sub-phase 7.3: Create folder modal "),t(A,{open:e.createFolderOpen,"onUpdate:open":l[8]||(l[8]=n=>e.createFolderOpen=n),title:"新建文件夹","confirm-loading":e.creatingFolder,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreateFolder},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"文件夹路径(项目内)",required:""},{default:a(()=>[t(T,{value:e.newFolder.path,"onUpdate:value":l[7]||(l[7]=n=>e.newFolder.path=n),placeholder:"例如 src/utils"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"]),_(" Sub-phase 7.3: Edit file content modal "),t(A,{open:e.editFileOpen,"onUpdate:open":l[10]||(l[10]=n=>e.editFileOpen=n),title:`编辑 ${e.editingFile?.file_name||""}`,"confirm-loading":e.savingFile,"ok-text":"保存","cancel-text":"取消",onOk:e.onSaveFile,width:"720"},{default:a(()=>[t(D,{value:e.editFileContent,"onUpdate:value":l[9]||(l[9]=n=>e.editFileContent=n),rows:18,"auto-size":{minRows:12,maxRows:24},style:{"font-family":"monospace"}},null,8,["value"])]),_:1},8,["open","title","confirm-loading"]),_(" Create modal "),t(A,{open:e.createOpen,"onUpdate:open":l[15]||(l[15]=n=>e.createOpen=n),title:"新建项目","confirm-loading":e.creating,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreate},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"项目名称",required:""},{default:a(()=>[t(T,{value:e.newProject.name,"onUpdate:value":l[11]||(l[11]=n=>e.newProject.name=n),placeholder:"例如:旅行计划-上海"},null,8,["value"])]),_:1}),t(b,{label:"描述"},{default:a(()=>[t(D,{value:e.newProject.description,"onUpdate:value":l[12]||(l[12]=n=>e.newProject.description=n),rows:2},null,8,["value"])]),_:1}),t(b,{label:"类型"},{default:a(()=>[t(R,{value:e.newProject.type,"onUpdate:value":l[13]||(l[13]=n=>e.newProject.type=n)},{default:a(()=>[t(m,{value:"document"},{default:a(()=>[...l[32]||(l[32]=[r("文档 (document)",-1)])]),_:1}),t(m,{value:"data"},{default:a(()=>[...l[33]||(l[33]=[r("数据 (data)",-1)])]),_:1}),t(m,{value:"web"},{default:a(()=>[...l[34]||(l[34]=[r("Web",-1)])]),_:1}),t(m,{value:"app"},{default:a(()=>[...l[35]||(l[35]=[r("应用 (app)",-1)])]),_:1}),t(m,{value:"presentation"},{default:a(()=>[...l[36]||(l[36]=[r("演示文稿",-1)])]),_:1}),t(m,{value:"spreadsheet"},{default:a(()=>[...l[37]||(l[37]=[r("表格",-1)])]),_:1}),t(m,{value:"design"},{default:a(()=>[...l[38]||(l[38]=[r("设计",-1)])]),_:1}),t(m,{value:"code"},{default:a(()=>[...l[39]||(l[39]=[r("代码",-1)])]),_:1}),t(m,{value:"workflow"},{default:a(()=>[...l[40]||(l[40]=[r("工作流",-1)])]),_:1}),t(m,{value:"knowledge"},{default:a(()=>[...l[41]||(l[41]=[r("知识库",-1)])]),_:1})]),_:1},8,["value"])]),_:1}),t(b,{label:"根路径 (可选)"},{default:a(()=>[t(T,{value:e.newProject.rootPath,"onUpdate:value":l[14]||(l[14]=n=>e.newProject.rootPath=n),placeholder:"留空则仅元数据"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"])])}const We=we(Pe,[["render",Le],["__scopeId","data-v-019ac5aa"],["__file","/tmp/cc-web-panel-UAH1Xi/repo/packages/web-panel/src/views/Projects.vue"]]);export{We as default};
@@ -1,5 +0,0 @@
1
- import{E as Cn,r as ee,I as W,J as ke,U as Te,c as A,K as _,S as ne,V as he,o as kt,a8 as Tt,b as Le,P,Q as Y,R as ge,F as Nn,Z as Fn,a5 as Hn}from"./vendor-Bn1JzzAn.js";import{Q as Dn}from"./QrScannerModal-CexOomKS.js";import{_ as Zn}from"./index-Dyngbd29.js";import{ax as $n,aC as Mn}from"./icons-DG5UD-6K.js";import"./markdown-CsiA8-E5.js";function zn(t){return t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"&&"BYTES_PER_ELEMENT"in t&&t.BYTES_PER_ELEMENT===1}function Se(t,e=""){if(typeof t!="number"){const n=e&&`"${e}" `;throw new TypeError(`${n}expected number, got ${typeof t}`)}if(!Number.isSafeInteger(t)||t<0){const n=e&&`"${e}" `;throw new RangeError(`${n}expected integer >= 0, got ${t}`)}}function ce(t,e,n=""){const r=zn(t),o=t?.length,s=e!==void 0;if(!r||s&&o!==e){const i=n&&`"${n}" `,a=s?` of length ${e}`:"",f=r?`length=${o}`:`type=${typeof t}`,c=i+"expected Uint8Array"+a+", got "+f;throw r?new RangeError(c):new TypeError(c)}return t}function vt(t){if(typeof t!="function"||typeof t.create!="function")throw new TypeError("Hash must wrapped by utils.createHasher");if(Se(t.outputLen),Se(t.blockLen),t.outputLen<1)throw new Error('"outputLen" must be >= 1');if(t.blockLen<1)throw new Error('"blockLen" must be >= 1')}function et(t,e=!0){if(t.destroyed)throw new Error("Hash instance has been destroyed");if(e&&t.finished)throw new Error("Hash#digest() has already been called")}function on(t,e){ce(t,void 0,"digestInto() output");const n=e.outputLen;if(t.length<n)throw new RangeError('"digestInto() output" expected to be of length >='+n)}function He(...t){for(let e=0;e<t.length;e++)t[e].fill(0)}function it(t){return new DataView(t.buffer,t.byteOffset,t.byteLength)}function se(t,e){return t<<32-e|t>>>e}const sn=typeof Uint8Array.from([]).toHex=="function"&&typeof Uint8Array.fromHex=="function",jn=Array.from({length:256},(t,e)=>e.toString(16).padStart(2,"0"));function xt(t){if(ce(t),sn)return t.toHex();let e="";for(let n=0;n<t.length;n++)e+=jn[t[n]];return e}const ie={_0:48,_9:57,A:65,F:70,a:97,f:102};function Lt(t){if(t>=ie._0&&t<=ie._9)return t-ie._0;if(t>=ie.A&&t<=ie.F)return t-(ie.A-10);if(t>=ie.a&&t<=ie.f)return t-(ie.a-10)}function St(t){if(typeof t!="string")throw new TypeError("hex string expected, got "+typeof t);if(sn)try{return Uint8Array.fromHex(t)}catch(o){throw o instanceof SyntaxError?new RangeError(o.message):o}const e=t.length,n=e/2;if(e%2)throw new RangeError("hex string expected, got unpadded hex of length "+e);const r=new Uint8Array(n);for(let o=0,s=0;o<n;o++,s+=2){const i=Lt(t.charCodeAt(s)),a=Lt(t.charCodeAt(s+1));if(i===void 0||a===void 0){const f=t[s]+t[s+1];throw new RangeError('hex string expected, got non-hex character "'+f+'" at index '+s)}r[o]=i*16+a}return r}function Pn(t,e={}){const n=(o,s)=>t(s).update(o).digest(),r=t(void 0);return n.outputLen=r.outputLen,n.blockLen=r.blockLen,n.canXOF=r.canXOF,n.create=o=>t(o),Object.assign(n,e),Object.freeze(n)}function Yn(t=32){Se(t,"bytesLength");const e=typeof globalThis=="object"?globalThis.crypto:null;if(typeof e?.getRandomValues!="function")throw new Error("crypto.getRandomValues must be defined");if(t>65536)throw new RangeError(`"bytesLength" expected <= 65536, got ${t}`);return e.getRandomValues(new Uint8Array(t))}const Vn=t=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,t])});function Xn(t,e,n){return t&e^~t&n}function Kn(t,e,n){return t&e^t&n^e&n}class Gn{blockLen;outputLen;canXOF=!1;padOffset;isLE;buffer;view;finished=!1;length=0;pos=0;destroyed=!1;constructor(e,n,r,o){this.blockLen=e,this.outputLen=n,this.padOffset=r,this.isLE=o,this.buffer=new Uint8Array(e),this.view=it(this.buffer)}update(e){et(this),ce(e);const{view:n,buffer:r,blockLen:o}=this,s=e.length;for(let i=0;i<s;){const a=Math.min(o-this.pos,s-i);if(a===o){const f=it(e);for(;o<=s-i;i+=o)this.process(f,i);continue}r.set(e.subarray(i,i+a),this.pos),this.pos+=a,i+=a,this.pos===o&&(this.process(n,0),this.pos=0)}return this.length+=e.length,this.roundClean(),this}digestInto(e){et(this),on(e,this),this.finished=!0;const{buffer:n,view:r,blockLen:o,isLE:s}=this;let{pos:i}=this;n[i++]=128,He(this.buffer.subarray(i)),this.padOffset>o-i&&(this.process(r,0),i=0);for(let u=i;u<o;u++)n[u]=0;r.setBigUint64(o-8,BigInt(this.length*8),s),this.process(r,0);const a=it(e),f=this.outputLen;if(f%4)throw new Error("_sha2: outputLen must be aligned to 32bit");const c=f/4,l=this.get();if(c>l.length)throw new Error("_sha2: outputLen bigger than state");for(let u=0;u<c;u++)a.setUint32(4*u,l[u],s)}digest(){const{buffer:e,outputLen:n}=this;this.digestInto(e);const r=e.slice(0,n);return this.destroy(),r}_cloneInto(e){e||=new this.constructor,e.set(...this.get());const{blockLen:n,buffer:r,length:o,finished:s,destroyed:i,pos:a}=this;return e.destroyed=i,e.finished=s,e.length=o,e.pos=a,o%n&&e.buffer.set(r),e}clone(){return this._cloneInto()}}const ae=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),Qn=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),fe=new Uint32Array(64);class Wn extends Gn{constructor(e){super(64,e,8,!1)}get(){const{A:e,B:n,C:r,D:o,E:s,F:i,G:a,H:f}=this;return[e,n,r,o,s,i,a,f]}set(e,n,r,o,s,i,a,f){this.A=e|0,this.B=n|0,this.C=r|0,this.D=o|0,this.E=s|0,this.F=i|0,this.G=a|0,this.H=f|0}process(e,n){for(let u=0;u<16;u++,n+=4)fe[u]=e.getUint32(n,!1);for(let u=16;u<64;u++){const b=fe[u-15],g=fe[u-2],S=se(b,7)^se(b,18)^b>>>3,v=se(g,17)^se(g,19)^g>>>10;fe[u]=v+fe[u-7]+S+fe[u-16]|0}let{A:r,B:o,C:s,D:i,E:a,F:f,G:c,H:l}=this;for(let u=0;u<64;u++){const b=se(a,6)^se(a,11)^se(a,25),g=l+b+Xn(a,f,c)+Qn[u]+fe[u]|0,v=(se(r,2)^se(r,13)^se(r,22))+Kn(r,o,s)|0;l=c,c=f,f=a,a=i+g|0,i=s,s=o,o=r,r=g+v|0}r=r+this.A|0,o=o+this.B|0,s=s+this.C|0,i=i+this.D|0,a=a+this.E|0,f=f+this.F|0,c=c+this.G|0,l=l+this.H|0,this.set(r,o,s,i,a,f,c,l)}roundClean(){He(fe)}destroy(){this.destroyed=!0,this.set(0,0,0,0,0,0,0,0),He(this.buffer)}}class Jn extends Wn{A=ae[0]|0;B=ae[1]|0;C=ae[2]|0;D=ae[3]|0;E=ae[4]|0;F=ae[5]|0;G=ae[6]|0;H=ae[7]|0;constructor(){super(32)}}const qt=Pn(()=>new Jn,Vn(1));const ue=(t,e,n)=>ce(t,e,n),cn=Se,an=xt,er=t=>St(t),tr=t=>Yn(t),tt=BigInt(0),wt=BigInt(1);function fn(t,e=""){if(typeof t!="boolean"){const n=e&&`"${e}" `;throw new TypeError(n+"expected boolean, got type="+typeof t)}return t}function nr(t){if(typeof t=="bigint"){if(!Qe(t))throw new RangeError("positive bigint expected, got "+t)}else cn(t);return t}function Ut(t,e=""){if(typeof t!="number"){const n=e&&`"${e}" `;throw new TypeError(n+"expected number, got type="+typeof t)}if(!Number.isSafeInteger(t)){const n=e&&`"${e}" `;throw new RangeError(n+"expected safe integer, got "+t)}}function ln(t){if(typeof t!="string")throw new TypeError("hex string expected, got "+typeof t);return t===""?tt:BigInt("0x"+t)}function rr(t){return ln(xt(t))}function De(t){return ln(xt(Ze(ce(t)).reverse()))}function un(t,e){if(Se(e),e===0)throw new RangeError("zero length");t=nr(t);const n=t.toString(16);if(n.length>e*2)throw new RangeError("number too large");return St(n.padStart(e*2,"0"))}function dn(t,e){return un(t,e).reverse()}function or(t,e){if(t=ue(t),e=ue(e),t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t[r]^e[r];return n===0}function Ze(t){return Uint8Array.from(ue(t))}const Qe=t=>typeof t=="bigint"&&tt<=t;function sr(t,e,n){return Qe(t)&&Qe(e)&&Qe(n)&&e<=t&&t<n}function nt(t,e,n,r){if(!sr(e,n,r))throw new RangeError("expected valid "+t+": "+n+" <= n < "+r+", got "+e)}function ir(t){if(t<tt)throw new Error("expected non-negative bigint, got "+t);let e;for(e=0;t>tt;t>>=wt,e+=1);return e}const cr=t=>(wt<<BigInt(t))-wt;function It(t,e={},n={}){if(Object.prototype.toString.call(t)!=="[object Object]")throw new TypeError("expected valid options object");function r(s,i,a){if(!a&&i!=="function"&&!Object.hasOwn(t,s))throw new TypeError(`param "${s}" is invalid: expected own property`);const f=t[s];if(a&&f===void 0)return;const c=typeof f;if(c!==i||f===null)throw new TypeError(`param "${s}" is invalid: expected ${i}, got ${c}`)}const o=(s,i)=>Object.entries(s).forEach(([a,f])=>r(a,f,i));o(e,!1),o(n,!0)}const Ct=()=>{throw new Error("not implemented")};const V=BigInt(0),z=BigInt(1),me=BigInt(2),pn=BigInt(3),hn=BigInt(4),gn=BigInt(5),ar=BigInt(7),wn=BigInt(8),fr=BigInt(9),yn=BigInt(16);function C(t,e){if(e<=V)throw new Error("mod: expected positive modulus, got "+e);const n=t%e;return n>=V?n:e+n}function re(t,e,n){if(e<V)throw new Error("pow2: expected non-negative exponent, got "+e);let r=t;for(;e-- >V;)r*=r,r%=n;return r}function Nt(t,e){if(t===V)throw new Error("invert: expected non-zero number");if(e<=V)throw new Error("invert: expected positive modulus, got "+e);let n=C(t,e),r=e,o=V,s=z;for(;n!==V;){const a=r/n,f=r-n*a,c=o-s*a;r=n,n=f,o=s,s=c}if(r!==z)throw new Error("invert: does not exist");return C(o,e)}function _t(t,e,n){const r=t;if(!r.eql(r.sqr(e),n))throw new Error("Cannot find square root")}function mn(t,e){const n=t,r=(n.ORDER+z)/hn,o=n.pow(e,r);return _t(n,o,e),o}function lr(t,e){const n=t,r=(n.ORDER-gn)/wn,o=n.mul(e,me),s=n.pow(o,r),i=n.mul(e,s),a=n.mul(n.mul(i,me),s),f=n.mul(i,n.sub(a,n.ONE));return _t(n,f,e),f}function ur(t){const e=Bt(t),n=bn(t),r=n(e,e.neg(e.ONE)),o=n(e,r),s=n(e,e.neg(r)),i=(t+ar)/yn;return((a,f)=>{const c=a;let l=c.pow(f,i),u=c.mul(l,r);const b=c.mul(l,o),g=c.mul(l,s),S=c.eql(c.sqr(u),f),v=c.eql(c.sqr(b),f);l=c.cmov(l,u,S),u=c.cmov(g,b,v);const d=c.eql(c.sqr(u),f),y=c.cmov(l,u,d);return _t(c,y,f),y})}function bn(t){if(t<pn)throw new Error("sqrt is not defined for small field");let e=t-z,n=0;for(;e%me===V;)e/=me,n++;let r=me;const o=Bt(t);for(;Ft(o,r)===1;)if(r++>1e3)throw new Error("Cannot find square root: probably non-prime P");if(n===1)return mn;let s=o.pow(r,e);const i=(e+z)/me;return function(f,c){const l=f;if(l.is0(c))return c;if(Ft(l,c)!==1)throw new Error("Cannot find square root");let u=n,b=l.mul(l.ONE,s),g=l.pow(c,e),S=l.pow(c,i);for(;!l.eql(g,l.ONE);){if(l.is0(g))return l.ZERO;let v=1,d=l.sqr(g);for(;!l.eql(d,l.ONE);)if(v++,d=l.sqr(d),v===u)throw new Error("Cannot find square root");const y=z<<BigInt(u-v-1),h=l.pow(b,y);u=v,b=l.sqr(h),g=l.mul(g,b),S=l.mul(S,h)}return S}}function dr(t){return t%hn===pn?mn:t%wn===gn?lr:t%yn===fr?ur(t):bn(t)}const we=(t,e)=>(C(t,e)&z)===z,pr=["create","isValid","is0","neg","inv","sqrt","sqr","eql","add","sub","mul","pow","div","addN","subN","mulN","sqrN"];function hr(t){const e={ORDER:"bigint",BYTES:"number",BITS:"number"},n=pr.reduce((r,o)=>(r[o]="function",r),e);if(It(t,n),Ut(t.BYTES,"BYTES"),Ut(t.BITS,"BITS"),t.BYTES<1||t.BITS<1)throw new Error("invalid field: expected BYTES/BITS > 0");if(t.ORDER<=z)throw new Error("invalid field: expected ORDER > 1, got "+t.ORDER);return t}function gr(t,e,n){const r=t;if(n<V)throw new Error("invalid exponent, negatives unsupported");if(n===V)return r.ONE;if(n===z)return e;let o=r.ONE,s=e;for(;n>V;)n&z&&(o=r.mul(o,s)),s=r.sqr(s),n>>=z;return o}function En(t,e,n=!1){const r=t,o=new Array(e.length).fill(n?r.ZERO:void 0),s=e.reduce((a,f,c)=>r.is0(f)?a:(o[c]=a,r.mul(a,f)),r.ONE),i=r.inv(s);return e.reduceRight((a,f,c)=>r.is0(f)?a:(o[c]=r.mul(a,o[c]),r.mul(a,f)),i),o}function Ft(t,e){const n=t,r=(n.ORDER-z)/me,o=n.pow(e,r),s=n.eql(o,n.ONE),i=n.eql(o,n.ZERO),a=n.eql(o,n.neg(n.ONE));if(!s&&!i&&!a)throw new Error("invalid Legendre symbol result");return s?1:i?0:-1}function wr(t,e){if(e!==void 0&&cn(e),t<=V)throw new Error("invalid n length: expected positive n, got "+t);if(e!==void 0&&e<1)throw new Error("invalid n length: expected positive bit length, got "+e);const n=ir(t);if(e!==void 0&&e<n)throw new Error(`invalid n length: expected bit length (${n}) >= n.length (${e})`);const r=e!==void 0?e:n,o=Math.ceil(r/8);return{nBitLength:r,nByteLength:o}}const Ht=new WeakMap;class vn{ORDER;BITS;BYTES;isLE;ZERO=V;ONE=z;_lengths;_mod;constructor(e,n={}){if(e<=z)throw new Error("invalid field: expected ORDER > 1, got "+e);let r;this.isLE=!1,n!=null&&typeof n=="object"&&(typeof n.BITS=="number"&&(r=n.BITS),typeof n.sqrt=="function"&&Object.defineProperty(this,"sqrt",{value:n.sqrt,enumerable:!0}),typeof n.isLE=="boolean"&&(this.isLE=n.isLE),n.allowedLengths&&(this._lengths=Object.freeze(n.allowedLengths.slice())),typeof n.modFromBytes=="boolean"&&(this._mod=n.modFromBytes));const{nBitLength:o,nByteLength:s}=wr(e,r);if(s>2048)throw new Error("invalid field: expected ORDER of <= 2048 bytes");this.ORDER=e,this.BITS=o,this.BYTES=s,Object.freeze(this)}create(e){return C(e,this.ORDER)}isValid(e){if(typeof e!="bigint")throw new TypeError("invalid field element: expected bigint, got "+typeof e);return V<=e&&e<this.ORDER}is0(e){return e===V}isValidNot0(e){return!this.is0(e)&&this.isValid(e)}isOdd(e){return(e&z)===z}neg(e){return C(-e,this.ORDER)}eql(e,n){return e===n}sqr(e){return C(e*e,this.ORDER)}add(e,n){return C(e+n,this.ORDER)}sub(e,n){return C(e-n,this.ORDER)}mul(e,n){return C(e*n,this.ORDER)}pow(e,n){return gr(this,e,n)}div(e,n){return C(e*Nt(n,this.ORDER),this.ORDER)}sqrN(e){return e*e}addN(e,n){return e+n}subN(e,n){return e-n}mulN(e,n){return e*n}inv(e){return Nt(e,this.ORDER)}sqrt(e){let n=Ht.get(this);return n||Ht.set(this,n=dr(this.ORDER)),n(this,e)}toBytes(e){return this.isLE?dn(e,this.BYTES):un(e,this.BYTES)}fromBytes(e,n=!1){ue(e);const{_lengths:r,BYTES:o,isLE:s,ORDER:i,_mod:a}=this;if(r){if(e.length<1||!r.includes(e.length)||e.length>o)throw new Error("Field.fromBytes: expected "+r+" bytes, got "+e.length);const c=new Uint8Array(o);c.set(e,s?0:c.length-e.length),e=c}if(e.length!==o)throw new Error("Field.fromBytes: expected "+o+" bytes, got "+e.length);let f=s?De(e):rr(e);if(a&&(f=C(f,i)),!n&&!this.isValid(f))throw new Error("invalid field element: outside of range 0..ORDER");return f}invertBatch(e){return En(this,e)}cmov(e,n,r){return fn(r,"condition"),r?n:e}}Object.freeze(vn.prototype);function Bt(t,e={}){return new vn(t,e)}const rt=BigInt(0),yt=BigInt(1);function Dt(t,e){const n=e.negate();return t?n:e}function ct(t,e){const n=En(t.Fp,e.map(r=>r.Z));return e.map((r,o)=>t.fromAffine(r.toAffine(n[o])))}function xn(t,e){if(!Number.isSafeInteger(t)||t<=0||t>e)throw new Error("invalid window size, expected [1.."+e+"], got W="+t)}function at(t,e){xn(t,e);const n=Math.ceil(e/t)+1,r=2**(t-1),o=2**t,s=cr(t),i=BigInt(t);return{windows:n,windowSize:r,mask:s,maxNumber:o,shiftBy:i}}function Zt(t,e,n){const{windowSize:r,mask:o,maxNumber:s,shiftBy:i}=n;let a=Number(t&o),f=t>>i;a>r&&(a-=s,f+=yt);const c=e*r,l=c+Math.abs(a)-1,u=a===0,b=a<0,g=e%2!==0;return{nextN:f,offset:l,isZero:u,isNeg:b,isNegF:g,offsetF:c}}const ft=new WeakMap,Sn=new WeakMap;function lt(t){return Sn.get(t)||1}function $t(t){if(t!==rt)throw new Error("invalid wNAF")}class yr{BASE;ZERO;Fn;bits;constructor(e,n){this.BASE=e.BASE,this.ZERO=e.ZERO,this.Fn=e.Fn,this.bits=n}_unsafeLadder(e,n,r=this.ZERO){let o=e;for(;n>rt;)n&yt&&(r=r.add(o)),o=o.double(),n>>=yt;return r}precomputeWindow(e,n){const{windows:r,windowSize:o}=at(n,this.bits),s=[];let i=e,a=i;for(let f=0;f<r;f++){a=i,s.push(a);for(let c=1;c<o;c++)a=a.add(i),s.push(a);i=a.double()}return s}wNAF(e,n,r){if(!this.Fn.isValid(r))throw new Error("invalid scalar");let o=this.ZERO,s=this.BASE;const i=at(e,this.bits);for(let a=0;a<i.windows;a++){const{nextN:f,offset:c,isZero:l,isNeg:u,isNegF:b,offsetF:g}=Zt(r,a,i);r=f,l?s=s.add(Dt(b,n[g])):o=o.add(Dt(u,n[c]))}return $t(r),{p:o,f:s}}wNAFUnsafe(e,n,r,o=this.ZERO){const s=at(e,this.bits);for(let i=0;i<s.windows&&r!==rt;i++){const{nextN:a,offset:f,isZero:c,isNeg:l}=Zt(r,i,s);if(r=a,!c){const u=n[f];o=o.add(l?u.negate():u)}}return $t(r),o}getPrecomputes(e,n,r){let o=ft.get(n);return o||(o=this.precomputeWindow(n,e),e!==1&&(typeof r=="function"&&(o=r(o)),ft.set(n,o))),o}cached(e,n,r){const o=lt(e);return this.wNAF(o,this.getPrecomputes(o,e,r),n)}unsafe(e,n,r,o){const s=lt(e);return s===1?this._unsafeLadder(e,n,o):this.wNAFUnsafe(s,this.getPrecomputes(s,e,r),n,o)}createCache(e,n){xn(n,this.bits),Sn.set(e,n),ft.delete(e)}hasCache(e){return lt(e)!==1}}function Mt(t,e,n){if(e){if(e.ORDER!==t)throw new Error("Field.ORDER must match order: Fp == p, Fn == n");return hr(e),e}else return Bt(t,{isLE:n})}function mr(t,e,n={},r){if(r===void 0&&(r=t==="edwards"),!e||typeof e!="object")throw new Error(`expected valid ${t} CURVE object`);for(const f of["p","n","h"]){const c=e[f];if(!(typeof c=="bigint"&&c>rt))throw new Error(`CURVE.${f} must be positive bigint`)}const o=Mt(e.p,n.Fp,r),s=Mt(e.n,n.Fn,r),a=["Gx","Gy","a","d"];for(const f of a)if(!o.isValid(e[f]))throw new Error(`CURVE.${f} must be valid field element of CURVE.Fp`);return e=Object.freeze(Object.assign({},e)),{CURVE:e,Fp:o,Fn:s}}function br(t,e){return function(r){const o=t(r);return{secretKey:o,publicKey:e(o)}}}const le=BigInt(0),X=BigInt(1),ut=BigInt(2),Er=BigInt(8);function vr(t,e,n,r){const o=t.sqr(n),s=t.sqr(r),i=t.add(t.mul(e.a,o),s),a=t.add(t.ONE,t.mul(e.d,t.mul(o,s)));return t.eql(i,a)}function xr(t,e={}){const n=e,r=mr("edwards",t,n,n.FpFnLE),{Fp:o,Fn:s}=r;let i=r.CURVE;const{h:a}=i;It(n,{},{uvRatio:"function"});const f=ut<<BigInt(s.BYTES*8)-X,c=v=>o.create(v),l=n.uvRatio===void 0?(v,d)=>{try{return{isValid:!0,value:o.sqrt(o.div(v,d))}}catch{return{isValid:!1,value:le}}}:n.uvRatio;if(!vr(o,i,i.Gx,i.Gy))throw new Error("bad curve params: generator point");function u(v,d,y=!1){const h=y?X:le;return nt("coordinate "+v,d,h,f),d}function b(v){if(!(v instanceof g))throw new Error("EdwardsPoint expected")}class g{static BASE=new g(i.Gx,i.Gy,X,c(i.Gx*i.Gy));static ZERO=new g(le,X,X,le);static Fp=o;static Fn=s;X;Y;Z;T;constructor(d,y,h,m){this.X=u("x",d),this.Y=u("y",y),this.Z=u("z",h,!0),this.T=u("t",m),Object.freeze(this)}static CURVE(){return i}static fromAffine(d){if(d instanceof g)throw new Error("extended point not allowed");const{x:y,y:h}=d||{};return u("x",y),u("y",h),new g(y,h,X,c(y*h))}static fromBytes(d,y=!1){const h=o.BYTES,{a:m,d:I}=i;d=Ze(ue(d,h,"point")),fn(y,"zip215");const R=Ze(d),L=d[h-1];R[h-1]=L&-129;const k=De(R),q=y?f:o.ORDER;nt("point.y",k,le,q);const T=c(k*k),F=c(T-X),H=c(I*T-m);let{isValid:j,value:D}=l(F,H);if(!j)throw new Error("bad point: invalid y coordinate");const B=(D&X)===X,E=(L&128)!==0;if(!y&&D===le&&E)throw new Error("bad point: x=0 and x_0=1");return E!==B&&(D=c(-D)),g.fromAffine({x:D,y:k})}static fromHex(d,y=!1){return g.fromBytes(er(d),y)}get x(){return this.toAffine().x}get y(){return this.toAffine().y}precompute(d=8,y=!0){return S.createCache(this,d),y||this.multiply(ut),this}assertValidity(){const d=this,{a:y,d:h}=i;if(d.is0())throw new Error("bad point: ZERO");const{X:m,Y:I,Z:R,T:L}=d,k=c(m*m),q=c(I*I),T=c(R*R),F=c(T*T),H=c(k*y),j=c(T*c(H+q)),D=c(F+c(h*c(k*q)));if(j!==D)throw new Error("bad point: equation left != right (1)");const B=c(m*I),E=c(R*L);if(B!==E)throw new Error("bad point: equation left != right (2)")}equals(d){b(d);const{X:y,Y:h,Z:m}=this,{X:I,Y:R,Z:L}=d,k=c(y*L),q=c(I*m),T=c(h*L),F=c(R*m);return k===q&&T===F}is0(){return this.equals(g.ZERO)}negate(){return new g(c(-this.X),this.Y,this.Z,c(-this.T))}double(){const{a:d}=i,{X:y,Y:h,Z:m}=this,I=c(y*y),R=c(h*h),L=c(ut*c(m*m)),k=c(d*I),q=y+h,T=c(c(q*q)-I-R),F=k+R,H=F-L,j=k-R,D=c(T*H),B=c(F*j),E=c(T*j),U=c(H*F);return new g(D,B,U,E)}add(d){b(d);const{a:y,d:h}=i,{X:m,Y:I,Z:R,T:L}=this,{X:k,Y:q,Z:T,T:F}=d,H=c(m*k),j=c(I*q),D=c(L*h*F),B=c(R*T),E=c((m+I)*(k+q)-H-j),U=B-D,$=B+D,M=c(j-y*H),Z=c(E*U),G=c($*M),te=c(E*M),Q=c(U*$);return new g(Z,G,Q,te)}subtract(d){return b(d),this.add(d.negate())}multiply(d){if(!s.isValidNot0(d))throw new RangeError("invalid scalar: expected 1 <= sc < curve.n");const{p:y,f:h}=S.cached(this,d,m=>ct(g,m));return ct(g,[y,h])[0]}multiplyUnsafe(d){if(!s.isValid(d))throw new RangeError("invalid scalar: expected 0 <= sc < curve.n");return d===le?g.ZERO:this.is0()||d===X?this:S.unsafe(this,d,y=>ct(g,y))}isSmallOrder(){return this.clearCofactor().is0()}isTorsionFree(){return S.unsafe(this,i.n).is0()}toAffine(d){const y=this;let h=d;const{X:m,Y:I,Z:R}=y,L=y.is0();h==null&&(h=L?Er:o.inv(R));const k=c(m*h),q=c(I*h),T=o.mul(R,h);if(L)return{x:le,y:X};if(T!==X)throw new Error("invZ was invalid");return{x:k,y:q}}clearCofactor(){return a===X?this:this.multiplyUnsafe(a)}toBytes(){const{x:d,y}=this.toAffine(),h=o.toBytes(y);return h[h.length-1]|=d&X?128:0,h}toHex(){return an(this.toBytes())}toString(){return`<Point ${this.is0()?"ZERO":this.toHex()}>`}}const S=new yr(g,s.BITS);return s.BITS>=8&&g.BASE.precompute(8),Object.freeze(g.prototype),Object.freeze(g),g}class Sr{static BASE;static ZERO;static Fp;static Fn;ep;constructor(e){this.ep=e}static fromBytes(e){Ct()}static fromHex(e){Ct()}get x(){return this.toAffine().x}get y(){return this.toAffine().y}clearCofactor(){return this}assertValidity(){this.ep.assertValidity()}toAffine(e){return this.ep.toAffine(e)}toHex(){return an(this.toBytes())}toString(){return this.toHex()}isTorsionFree(){return!0}isSmallOrder(){return!1}add(e){return this.assertSame(e),this.init(this.ep.add(e.ep))}subtract(e){return this.assertSame(e),this.init(this.ep.subtract(e.ep))}multiply(e){return this.init(this.ep.multiply(e))}multiplyUnsafe(e){return this.init(this.ep.multiplyUnsafe(e))}double(){return this.init(this.ep.double())}negate(){return this.init(this.ep.negate())}precompute(e,n){return this.ep.precompute(e,n),this}}const qe=BigInt(0),Ee=BigInt(1),Pe=BigInt(2);function Ir(t){return It(t,{P:"bigint",type:"string",adjustScalarBytes:"function",powPminus2:"function"},{randomBytes:"function"}),Object.freeze({...t})}function _r(t){const e=Ir(t),{P:n,type:r,adjustScalarBytes:o,powPminus2:s,randomBytes:i}=e,a=r==="x25519";if(!a&&r!=="x448")throw new Error("invalid type");const f=i===void 0?tr:i,c=a?255:448,l=a?32:56,u=BigInt(a?9:5),b=BigInt(a?121665:39081),g=a?Pe**BigInt(254):Pe**BigInt(447),S=a?BigInt(8)*Pe**BigInt(251)-Ee:BigInt(4)*Pe**BigInt(445)-Ee,v=g+S+Ee,d=B=>C(B,n),y=h(u);function h(B){return dn(d(B),l)}function m(B){const E=Ze(ue(B,l,"uCoordinate"));return a&&(E[31]&=127),d(De(E))}function I(B){return De(o(Ze(ue(B,l,"scalar"))))}function R(B,E){const U=F(m(E),I(B));if(U===qe)throw new Error("invalid private or public key received");return h(U)}function L(B){return R(B,y)}const k=L,q=R;function T(B,E,U){const $=d(B*(E-U));return E=d(E-$),U=d(U+$),{x_2:E,x_3:U}}function F(B,E){nt("u",B,qe,n),nt("scalar",E,g,v);const U=E,$=B;let M=Ee,Z=qe,G=B,te=Ee,Q=qe;for(let _e=BigInt(c-1);_e>=qe;_e--){const ze=U>>_e&Ee;Q^=ze,{x_2:M,x_3:G}=T(Q,M,G),{x_2:Z,x_3:te}=T(Q,Z,te),Q=ze;const Be=M+Z,Re=d(Be*Be),Ae=M-Z,Oe=d(Ae*Ae),p=Re-Oe,w=G+te,x=G-te,O=d(x*Be),oe=d(w*Ae),pe=O+oe,je=O-oe;G=d(pe*pe),te=d($*d(je*je)),M=d(Re*Oe),Z=d(p*(Re+d(b*p)))}({x_2:M,x_3:G}=T(Q,M,G)),{x_2:Z,x_3:te}=T(Q,Z,te);const st=s(Z);return d(M*st)}const H={secretKey:l,publicKey:l,seed:l},j=B=>(B=B===void 0?f(l):B,ue(B,H.seed,"seed"),B),D={randomSecretKey:j};return Object.freeze(H),Object.freeze(D),Object.freeze({keygen:br(j,k),getSharedSecret:q,getPublicKey:k,scalarMult:R,scalarMultBase:L,utils:D,GuBytes:y.slice(),lengths:H})}const Br=BigInt(0),Fe=BigInt(1),zt=BigInt(2),Rr=BigInt(3),Ar=BigInt(5),Or=BigInt(8),Ie=BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"),In={p:Ie,n:BigInt("0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed"),h:Or,a:BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"),d:BigInt("0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3"),Gx:BigInt("0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a"),Gy:BigInt("0x6666666666666666666666666666666666666666666666666666666666666658")};function _n(t){const e=BigInt(10),n=BigInt(20),r=BigInt(40),o=BigInt(80),s=Ie,a=t*t%s*t%s,f=re(a,zt,s)*a%s,c=re(f,Fe,s)*t%s,l=re(c,Ar,s)*c%s,u=re(l,e,s)*l%s,b=re(u,n,s)*u%s,g=re(b,r,s)*b%s,S=re(g,o,s)*g%s,v=re(S,o,s)*g%s,d=re(v,e,s)*l%s;return{pow_p_5_8:re(d,zt,s)*t%s,b2:a}}function kr(t){return t[0]&=248,t[31]&=127,t[31]|=64,t}const mt=BigInt("19681161376707505956807079304988542015446066515923890162744021073123829784752");function Bn(t,e){const n=Ie,r=C(e*e*e,n),o=C(r*r*e,n),s=_n(t*o).pow_p_5_8;let i=C(t*r*s,n);const a=C(e*i*i,n),f=i,c=C(i*mt,n),l=a===t,u=a===C(-t,n),b=a===C(-t*mt,n);return l&&(i=f),(u||b)&&(i=c),we(i,n)&&(i=C(-i,n)),{isValid:l||u,value:i}}const xe=xr(In,{uvRatio:Bn}),ye=xe.Fp,Tr=xe.Fn,bt=(()=>{const t=Ie;return _r({P:t,type:"x25519",powPminus2:e=>{const{pow_p_5_8:n,b2:r}=_n(e);return C(re(n,Rr,t)*r,t)},adjustScalarBytes:kr})})(),jt=mt,Lr=BigInt("54469307008909316920995813868745141605393597292927456921205312896311721017578"),Pt=t=>Bn(Fe,t),qr=BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),Ur=t=>ye.create(De(t)&qr);class J extends Sr{static BASE=new J(xe.BASE);static ZERO=new J(xe.ZERO);static Fp=ye;static Fn=Tr;constructor(e){super(e)}static fromAffine(e){return new J(xe.fromAffine(e))}assertSame(e){if(!(e instanceof J))throw new Error("RistrettoPoint expected")}init(e){return new J(e)}static fromBytes(e){ce(e,32);const{a:n,d:r}=In,o=Ie,s=I=>ye.create(I),i=Ur(e);if(!or(ye.toBytes(i),e)||we(i,o))throw new Error("invalid ristretto255 encoding 1");const a=s(i*i),f=s(Fe+n*a),c=s(Fe-n*a),l=s(f*f),u=s(c*c),b=s(n*r*l-u),{isValid:g,value:S}=Pt(s(b*u)),v=s(S*c),d=s(S*v*b);let y=s((i+i)*v);we(y,o)&&(y=s(-y));const h=s(f*d),m=s(y*h);if(!g||we(m,o)||h===Br)throw new Error("invalid ristretto255 encoding 2");return new J(new xe(y,h,Fe,m))}static fromHex(e){return J.fromBytes(St(e))}toBytes(){let{X:e,Y:n,Z:r,T:o}=this.ep;const s=Ie,i=d=>ye.create(d),a=i(i(r+n)*i(r-n)),f=i(e*n),c=i(f*f),{value:l}=Pt(i(a*c)),u=i(l*a),b=i(l*f),g=i(u*b*o);let S;if(we(o*g,s)){let d=i(n*jt),y=i(e*jt);e=d,n=y,S=i(u*Lr)}else S=b;we(e*g,s)&&(n=i(-n));let v=i((r-n)*S);return we(v,s)&&(v=i(-v)),ye.toBytes(v)}equals(e){this.assertSame(e);const{X:n,Y:r}=this.ep,{X:o,Y:s}=e.ep,i=c=>ye.create(c),a=i(n*s)===i(r*o),f=i(r*s)===i(n*o);return a||f}is0(){return this.equals(J.ZERO)}}Object.freeze(J.BASE);Object.freeze(J.ZERO);Object.freeze(J.prototype);Object.freeze(J);class Yt{oHash;iHash;blockLen;outputLen;canXOF=!1;finished=!1;destroyed=!1;constructor(e,n){if(vt(e),ce(n,void 0,"key"),this.iHash=e.create(),typeof this.iHash.update!="function")throw new Error("Expected instance of class which extends utils.Hash");this.blockLen=this.iHash.blockLen,this.outputLen=this.iHash.outputLen;const r=this.blockLen,o=new Uint8Array(r);o.set(n.length>r?e.create().update(n).digest():n);for(let s=0;s<o.length;s++)o[s]^=54;this.iHash.update(o),this.oHash=e.create();for(let s=0;s<o.length;s++)o[s]^=106;this.oHash.update(o),He(o)}update(e){return et(this),this.iHash.update(e),this}digestInto(e){et(this),on(e,this),this.finished=!0;const n=e.subarray(0,this.outputLen);this.iHash.digestInto(n),this.oHash.update(n),this.oHash.digestInto(n),this.destroy()}digest(){const e=new Uint8Array(this.oHash.outputLen);return this.digestInto(e),e}_cloneInto(e){e||=Object.create(Object.getPrototypeOf(this),{});const{oHash:n,iHash:r,finished:o,destroyed:s,blockLen:i,outputLen:a}=this;return e=e,e.finished=o,e.destroyed=s,e.blockLen=i,e.outputLen=a,e.oHash=n._cloneInto(e.oHash),e.iHash=r._cloneInto(e.iHash),e}clone(){return this._cloneInto()}destroy(){this.destroyed=!0,this.oHash.destroy(),this.iHash.destroy()}}const Rn=(()=>{const t=((e,n,r)=>new Yt(e,n).update(r).digest());return t.create=(e,n)=>new Yt(e,n),t})();function Cr(t,e,n){return vt(t),n===void 0&&(n=new Uint8Array(t.outputLen)),Rn(t,n,e)}const dt=Uint8Array.of(0),Vt=Uint8Array.of();function Nr(t,e,n,r=32){vt(t),Se(r,"length"),ce(e,void 0,"prk");const o=t.outputLen;if(e.length<o)throw new Error('"prk" must be at least HashLen octets');if(r>255*o)throw new Error("Length must be <= 255*HashLen");const s=Math.ceil(r/o);n===void 0?n=Vt:ce(n,void 0,"info");const i=new Uint8Array(s*o),a=Rn.create(t,e),f=a._cloneInto(),c=new Uint8Array(a.outputLen);for(let l=0;l<s;l++)dt[0]=l+1,f.update(l===0?Vt:c).update(n).update(dt).digestInto(c),i.set(c,o*l),a._cloneInto(f);return a.destroy(),f.destroy(),He(c,dt),i.slice(0,r)}const Fr=(t,e,n,r,o)=>Nr(t,Cr(t,e,n),r,o);function Hr(t){return t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"&&"BYTES_PER_ELEMENT"in t&&t.BYTES_PER_ELEMENT===1}function Xt(t){if(typeof t!="number")throw new TypeError("number expected, got "+typeof t);if(!Number.isSafeInteger(t)||t<0)throw new RangeError("positive integer expected, got "+t)}function K(t,e,n=""){const r=Hr(t),o=t?.length,s=e!==void 0;if(!r||s&&o!==e){const i=n&&`"${n}" `,a=s?` of length ${e}`:"",f=r?`length=${o}`:`type=${typeof t}`,c=i+"expected Uint8Array"+a+", got "+f;throw r?new RangeError(c):new TypeError(c)}return t}function Kt(t,e=!0){if(t.destroyed)throw new Error("Hash instance has been destroyed");if(e&&t.finished)throw new Error("Hash#digest() has already been called")}function Dr(t,e,n=!1){K(t,void 0,"output");const r=e.outputLen;if(t.length<r)throw new RangeError("digestInto() expects output buffer of length at least "+r);if(n&&!$e(t))throw new Error("invalid output, must be aligned")}function Zr(t){return new Uint8Array(t.buffer,t.byteOffset,t.byteLength)}function be(t){return new Uint32Array(t.buffer,t.byteOffset,Math.floor(t.byteLength/4))}function de(...t){for(let e=0;e<t.length;e++)t[e].fill(0)}function ot(t){return new DataView(t.buffer,t.byteOffset,t.byteLength)}const Rt=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68,An=t=>t<<24&4278190080|t<<8&16711680|t>>>8&65280|t>>>24&255,N=Rt?t=>t:t=>An(t)>>>0,$r=t=>{for(let e=0;e<t.length;e++)t[e]=An(t[e]);return t},At=Rt?t=>t:$r;function Mr(t,e){if(t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t[r]^e[r];return n===0}function zr(t,e,n){const r=e,o=n||(()=>[]),s=(a,f)=>r(f,...o(a)).update(a).digest(),i=r(new Uint8Array(t),...o(new Uint8Array(0)));return s.outputLen=i.outputLen,s.blockLen=i.blockLen,s.create=(a,...f)=>r(a,...f),s}const jr=(t,e)=>{function n(r,...o){if(K(r,void 0,"key"),t.nonceLength!==void 0){const l=o[0];K(l,t.varSizeNonce?void 0:t.nonceLength,"nonce")}const s=t.tagLength;s&&o[1]!==void 0&&K(o[1],void 0,"AAD");const i=e(r,...o),a=(l,u)=>{if(u!==void 0){if(l!==2)throw new Error("cipher output not supported");K(u,void 0,"output")}};let f=!1;return{encrypt(l,u){if(f)throw new Error("cannot encrypt() twice with same key + nonce");return f=!0,K(l),a(i.encrypt.length,u),i.encrypt(l,u)},decrypt(l,u){if(K(l),s&&l.length<s)throw new Error('"ciphertext" expected length bigger than tagLength='+s);return a(i.decrypt.length,u),i.decrypt(l,u)}}}return Object.assign(n,t),n};function Pr(t,e,n=!0){if(e===void 0)return new Uint8Array(t);if(K(e,void 0,"output"),e.length!==t)throw new Error('"output" expected Uint8Array of length '+t+", got: "+e.length);if(n&&!$e(e))throw new Error("invalid output, must be aligned");return e}function Yr(t,e,n){Xt(t),Xt(e);const r=new Uint8Array(16),o=ot(r);return o.setBigUint64(0,BigInt(e),n),o.setBigUint64(8,BigInt(t),n),r}function $e(t){return t.byteOffset%4===0}function Me(t){return Uint8Array.from(K(t))}const ve=16,On=new Uint8Array(16),Ue=be(On),Vr=225,Xr=(t,e,n,r)=>{const o=r&1;return{s3:n<<31|r>>>1,s2:e<<31|n>>>1,s1:t<<31|e>>>1,s0:t>>>1^Vr<<24&-(o&1)}},Ye=t=>(t>>>0&255)<<24|(t>>>8&255)<<16|(t>>>16&255)<<8|t>>>24&255|0,Kr=t=>t>64*1024?8:t>1024?4:2;class Gr{blockLen=ve;outputLen=ve;s0=0;s1=0;s2=0;s3=0;finished=!1;destroyed=!1;t;W;windowSize;constructor(e,n){K(e,16,"key"),e=Me(e);const r=ot(e);let o=r.getUint32(0,!1),s=r.getUint32(4,!1),i=r.getUint32(8,!1),a=r.getUint32(12,!1);const f=[];for(let S=0;S<128;S++)f.push({s0:Ye(o),s1:Ye(s),s2:Ye(i),s3:Ye(a)}),{s0:o,s1:s,s2:i,s3:a}=Xr(o,s,i,a);const c=Kr(n||1024);if(![1,2,4,8].includes(c))throw new Error("ghash: invalid window size, expected 2, 4 or 8");this.W=c;const u=128/c,b=this.windowSize=2**c,g=[];for(let S=0;S<u;S++)for(let v=0;v<b;v++){let d=0,y=0,h=0,m=0;for(let I=0;I<c;I++){if(!(v>>>c-I-1&1))continue;const{s0:L,s1:k,s2:q,s3:T}=f[c*S+I];d^=L,y^=k,h^=q,m^=T}g.push({s0:d,s1:y,s2:h,s3:m})}this.t=g}_updateBlock(e,n,r,o){e^=this.s0,n^=this.s1,r^=this.s2,o^=this.s3;const{W:s,t:i,windowSize:a}=this;let f=0,c=0,l=0,u=0;const b=(1<<s)-1;let g=0;for(const S of[e,n,r,o])for(let v=0;v<4;v++){const d=S>>>8*v&255;for(let y=8/s-1;y>=0;y--){const h=d>>>s*y&b,{s0:m,s1:I,s2:R,s3:L}=i[g*a+h];f^=m,c^=I,l^=R,u^=L,g+=1}}this.s0=f,this.s1=c,this.s2=l,this.s3=u}update(e){Kt(this),K(e),e=Me(e);const n=be(e),r=Math.floor(e.length/ve),o=e.length%ve;for(let s=0;s<r;s++)this._updateBlock(N(n[s*4+0]),N(n[s*4+1]),N(n[s*4+2]),N(n[s*4+3]));return o&&(On.set(e.subarray(r*ve)),this._updateBlock(N(Ue[0]),N(Ue[1]),N(Ue[2]),N(Ue[3])),de(Ue)),this}destroy(){this.destroyed=!0;const{t:e}=this;for(const n of e)n.s0=0,n.s1=0,n.s2=0,n.s3=0}digestInto(e){Kt(this),Dr(e,this,!0),this.finished=!0;const{s0:n,s1:r,s2:o,s3:s}=this,i=be(e);i[0]=n,i[1]=r,i[2]=o,i[3]=s,At(i)}digest(){const e=new Uint8Array(ve);return this.digestInto(e),this.destroy(),e}}const Gt=zr(16,(t,e)=>new Gr(t,e),t=>[t.length]),Et=16,Qr=4,Ve=new Uint8Array(Et),Wr=283;function Jr(t){if(![16,24,32].includes(t.length))throw new Error('"aes key" expected Uint8Array of length 16/24/32, got length='+t.length)}function Ot(t){return t<<1^Wr&-(t>>7)}function Qt(t,e){let n=0;for(;e>0;e>>=1)n^=t&-(e&1),t=Ot(t);return n}const eo=(()=>{const t=new Uint8Array(256);for(let n=0,r=1;n<256;n++,r^=Ot(r))t[n]=r;const e=new Uint8Array(256);e[0]=99;for(let n=0;n<255;n++){let r=t[255-n];r|=r<<8,e[t[n]]=(r^r>>4^r>>5^r>>6^r>>7^99)&255}return de(t),e})(),to=t=>t<<24|t>>>8,pt=t=>t<<8|t>>>24;function no(t,e){if(t.length!==256)throw new Error("Wrong sbox length");const n=new Uint32Array(256).map((c,l)=>e(t[l])),r=n.map(pt),o=r.map(pt),s=o.map(pt),i=new Uint32Array(256*256),a=new Uint32Array(256*256),f=new Uint16Array(256*256);for(let c=0;c<256;c++)for(let l=0;l<256;l++){const u=c*256+l;i[u]=n[c]^r[l],a[u]=o[c]^s[l],f[u]=t[c]<<8|t[l]}return{sbox:t,sbox2:f,T0:n,T1:r,T2:o,T3:s,T01:i,T23:a}}const kn=no(eo,t=>Qt(t,3)<<24|t<<16|t<<8|Qt(t,2)),ro=(()=>{const t=new Uint8Array(16);for(let e=0,n=1;e<16;e++,n=Ot(n))t[e]=n;return t})();function oo(t){K(t);const e=t.length;Jr(t);const{sbox2:n}=kn,r=[];(!Rt||!$e(t))&&r.push(t=Me(t));const o=At(be(t)),s=o.length,i=f=>Ce(n,f,f,f,f),a=new Uint32Array(e+28);a.set(o);for(let f=s;f<a.length;f++){let c=a[f-1];f%s===0?c=i(to(c))^ro[f/s-1]:s>6&&f%s===4&&(c=i(c)),a[f]=a[f-s]^c}return de(...r),a}function Xe(t,e,n,r,o,s){return t[n<<8&65280|r>>>8&255]^e[o>>>8&65280|s>>>24&255]}function Ce(t,e,n,r,o){return t[e&255|n&65280]|t[r>>>16&255|o>>>16&65280]<<16}function Wt(t,e,n,r,o){const{sbox2:s,T01:i,T23:a}=kn;let f=0;e^=t[f++],n^=t[f++],r^=t[f++],o^=t[f++];const c=t.length/4-2;for(let S=0;S<c;S++){const v=t[f++]^Xe(i,a,e,n,r,o),d=t[f++]^Xe(i,a,n,r,o,e),y=t[f++]^Xe(i,a,r,o,e,n),h=t[f++]^Xe(i,a,o,e,n,r);e=v,n=d,r=y,o=h}const l=t[f++]^Ce(s,e,n,r,o),u=t[f++]^Ce(s,n,r,o,e),b=t[f++]^Ce(s,r,o,e,n),g=t[f++]^Ce(s,o,e,n,r);return{s0:l,s1:u,s2:b,s3:g}}function Ke(t,e,n,r,o){K(n,Et,"nonce"),K(r),o=Pr(r.length,o);const s=n,i=be(s),a=ot(s),f=be(r),c=be(o),l=e?0:12,u=r.length;let b=a.getUint32(l,e),{s0:g,s1:S,s2:v,s3:d}=Wt(t,N(i[0]),N(i[1]),N(i[2]),N(i[3]));for(let h=0;h+4<=f.length;h+=4)c[h+0]=f[h+0]^N(g),c[h+1]=f[h+1]^N(S),c[h+2]=f[h+2]^N(v),c[h+3]=f[h+3]^N(d),b=b+1>>>0,a.setUint32(l,b,e),{s0:g,s1:S,s2:v,s3:d}=Wt(t,N(i[0]),N(i[1]),N(i[2]),N(i[3]));const y=Et*Math.floor(f.length/Qr);if(y<u){const h=new Uint32Array([g,S,v,d]);At(h);const m=Zr(h);for(let I=y,R=0;I<u;I++,R++)o[I]=r[I]^m[R];de(h)}return o}function so(t,e,n,r,o){const s=o?o.length:0,i=t.create(n,r.length+s);o&&i.update(o);const a=Yr(8*r.length,8*s,e);i.update(r),i.update(a);const f=i.digest();return de(a),f}const Jt=jr({blockSize:16,nonceLength:12,tagLength:16,varSizeNonce:!0},function(e,n,r){if(n.length<8)throw new Error("aes/gcm: invalid nonce length");const o=16;function s(a,f,c){const l=so(Gt,!1,a,c,r);for(let u=0;u<f.length;u++)l[u]^=f[u];return l}function i(){const a=oo(e),f=Ve.slice(),c=Ve.slice();if(Ke(a,!1,c,c,f),n.length===12)c.set(n);else{const u=Ve.slice();ot(u).setBigUint64(8,BigInt(n.length*8),!1);const g=Gt.create(f).update(n).update(u);g.digestInto(c),g.destroy()}const l=Ke(a,!1,c,Ve);return{xk:a,authKey:f,counter:c,tagMask:l}}return{encrypt(a){const{xk:f,authKey:c,counter:l,tagMask:u}=i(),b=new Uint8Array(a.length+o),g=[f,c,l,u];$e(a)||g.push(a=Me(a)),Ke(f,!1,l,a,b.subarray(0,a.length));const S=s(c,u,b.subarray(0,b.length-o));return g.push(S),b.set(S,a.length),de(...g),b},decrypt(a){const{xk:f,authKey:c,counter:l,tagMask:u}=i(),b=[f,c,u,l];$e(a)||b.push(a=Me(a));const g=a.subarray(0,-o),S=a.subarray(-o),v=s(c,u,g);if(b.push(v),!Mr(v,S))throw de(...b),new Error("aes/gcm: invalid ghash tag");const d=Ke(f,!1,l,g);return de(...b),d}}}),Tn="chainlesschain.remote-session.e2ee.v1",en="chainlesschain://remote-session/pair#",ht=32,io=new TextEncoder,Ln=new TextDecoder;function We(t){return io.encode(t)}function Ge(t){let e="";for(const n of t)e+=String.fromCharCode(n);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Ne(t){const e=String(t).replace(/-/g,"+").replace(/_/g,"/"),n=atob(e),r=new Uint8Array(n.length);for(let o=0;o<n.length;o+=1)r[o]=n.charCodeAt(o);return r}function co(t){const e=new Uint8Array(t);return globalThis.crypto.getRandomValues(e),e}function ao(){const t=bt.utils;return t.randomSecretKey?t.randomSecretKey():t.randomPrivateKey()}function tn(t,e,n){return We(`${Tn}
2
- ${t}
3
- ${e}
4
- ${n}`)}function fo(t,e=Date.now()){if(typeof t!="string"||!t.startsWith(en))throw new Error("Invalid Remote Session pairing URI");let n;try{n=JSON.parse(Ln.decode(Ne(t.slice(en.length))))}catch{throw new Error("Malformed Remote Session pairing payload")}if(n.v!==1||!n.relayUrl||!n.remoteSessionId||!n.hostPeerId||!n.hostPublicKey||!n.pairingToken)throw new Error("Incomplete Remote Session pairing payload");if(n.expiresAt&&n.expiresAt<=e)throw new Error("Remote Session pairing payload expired");let r;try{r=new URL(n.relayUrl).protocol}catch{r=null}if(r!=="ws:"&&r!=="wss:")throw new Error("Remote Session relay must use ws or wss");return n}class lo{constructor(e,n){if(!e||!n)throw new Error("sessionId and localPeerId are required");this.sessionId=e,this.localPeerId=n,this.secretKey=ao(),this.publicKey=bt.getPublicKey(this.secretKey),this.key=null,this.sendSequence=0,this.receivedSequences=new Map}publicKeyBase64(){return Ge(this.publicKey)}pair(e,n){if(!e||!n)throw new Error("Incomplete peer key material");const r=Ne(e),o=r.length===ht?r:r.slice(-ht);if(o.length!==ht)throw new Error("Invalid X25519 host public key");const s=bt.getSharedSecret(this.secretKey,o),i=qt(We(n));this.key=Fr(qt,s,i,We(`${Tn}:${this.sessionId}`),32)}encrypt(e){if(!this.key)throw new Error("Remote Session is not paired");const n=this.sendSequence+=1,r=co(12),o=Jt(this.key,r,tn(this.sessionId,this.localPeerId,n)).encrypt(We(JSON.stringify(e)));return{v:1,sessionId:this.sessionId,senderId:this.localPeerId,sequence:n,nonce:Ge(r),ciphertext:Ge(o.slice(0,o.length-16)),tag:Ge(o.slice(o.length-16))}}decrypt(e){if(e?.v!==1||e.sessionId!==this.sessionId)throw new Error("Invalid encrypted Remote Session envelope");if(!this.key)throw new Error("Remote Session is not paired");const n=this.receivedSequences.get(e.senderId)||0;if(!Number.isSafeInteger(e.sequence)||e.sequence<=n)throw new Error("Remote Session replay or out-of-order envelope rejected");const r=new Uint8Array([...Ne(e.ciphertext),...Ne(e.tag)]),o=Jt(this.key,Ne(e.nonce),tn(this.sessionId,e.senderId,e.sequence)).decrypt(r);return this.receivedSequences.set(e.senderId,e.sequence),JSON.parse(Ln.decode(o))}}const qn="chainlesschain://remote-control/pair#";function uo(t){const e=String(t).replace(/-/g,"+").replace(/_/g,"/"),n=e.padEnd(e.length+(4-e.length%4)%4,"="),r=atob(n),o=new Uint8Array(r.length);for(let s=0;s<r.length;s+=1)o[s]=r.charCodeAt(s);return new TextDecoder().decode(o)}function Un(t){return typeof t=="string"&&t.startsWith(qn)}function gt(t){const e=/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(t);if(!e)return!1;const[n,r]=[Number(e[1]),Number(e[2])];return[e[1],e[2],e[3],e[4]].some(o=>Number(o)>255)?!1:n===127||n===10||n===172&&r>=16&&r<=31||n===192&&r===168||n===169&&r===254}function po(t){const e=String(t||"").toLowerCase().replace(/^\[|\]$/g,"");if(!e)return!1;if(e==="localhost"||gt(e)||e==="::1")return!0;const n=/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/.exec(e);if(n)return gt(n[1]);const r=/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(e);if(r){const o=parseInt(r[1],16),s=parseInt(r[2],16);return gt(`${o>>8&255}.${o&255}.${s>>8&255}.${s&255}`)}return!!(/^fe[89ab]/.test(e)||/^f[cd]/.test(e))}function ho(t){let e;try{e=new URL(String(t))}catch{throw new Error(`Invalid direct pairing endpoint: ${t}`)}if(e.protocol!=="ws:"&&e.protocol!=="wss:")throw new Error(`Direct pairing endpoint must be ws:// or wss:// (got ${e.protocol})`);if(e.protocol==="ws:"&&!po(e.hostname))throw new Error(`Refusing plaintext ws:// to non-private host "${e.hostname}" — direct pairing is LAN/loopback only; use wss:// for anything else`);return e}function go(t,e=Date.now()){if(!Un(t))throw new Error("Not a remote-control pairing URI");let n;try{n=JSON.parse(uo(t.slice(qn.length)))}catch{throw new Error("Malformed remote-control pairing payload")}if(n.v!==1||n.transport!=="direct")throw new Error(`Unsupported remote-control pairing payload (v=${n.v}, transport=${n.transport})`);if(!n.wsUrl||!n.remoteSessionId||!n.pairingToken)throw new Error("Pairing payload is missing wsUrl/session/token");if(n.expiresAt!=null&&n.expiresAt<=e)throw new Error("Pairing link has expired — generate a new one");return ho(n.wsUrl),{wsUrl:n.wsUrl,serverToken:n.serverToken||null,remoteSessionId:n.remoteSessionId,agentSessionId:n.agentSessionId||null,pairingToken:n.pairingToken,scopes:Array.isArray(n.scopes)?n.scopes:null,expiresAt:n.expiresAt??null}}const wo=1e3,yo=3e4,mo=20,bo=15e3;let nn=0;function Je(){return globalThis.crypto?.randomUUID?globalThis.crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`}function Eo(){return`web-${Je()}`}const rn=Cn("remoteSession",()=>{const t=ee("idle"),e=ee([]),n=ee(""),r=ee(null),o=ee(null),s=ee(null),i=ee([]),a=ee([]);let f=null,c=null,l=null,u=null,b=!1,g=!1,S=0,v=null,d=null,y=0,h=null,m=null,I=new Map,R=0;function L(){v&&(clearTimeout(v),v=null)}function k(p){const w=p?.payload&&typeof p.payload=="object"?p.payload:p;if(p?.type==="permission.request"){const x=p.requestId||p.approvalId||null;x&&!i.value.some(O=>O.requestId===x)&&(i.value=[...i.value,{requestId:x,tool:p.tool||null,action:p.action||null,detail:p.detail||null,askedAt:p.askedAt||Date.now()}])}else if(p?.type==="permission.resolved"){const x=p.requestId||p.approvalId||null;x&&q(x)}else if(["question_request","question.requested","question"].includes(p?.type)){const x=w?.requestId||w?.id||p?.id||null,O=w?.binding&&typeof w.binding=="object"&&!Array.isArray(w.binding)?w.binding:null;x&&O&&!a.value.some(oe=>oe.requestId===x)&&(a.value=[...a.value,{requestId:x,question:w.question||w.prompt||"",options:Array.isArray(w.options)?w.options:[],multiSelect:w.multiSelect===!0,binding:O}])}else if(["question_resolved","question.resolved"].includes(p?.type)){const x=w?.requestId||w?.id||p?.id||null;x&&T(x)}nn+=1,e.value=[...e.value,{...p,_id:nn,_rxAt:Date.now()}].slice(-200)}function q(p){i.value=i.value.filter(w=>w.requestId!==p)}function T(p){a.value=a.value.filter(w=>w.requestId!==p)}function F(p){!p||!p.requestId||e.value.some(x=>x.type==="permission.resolved"&&x.requestId===p.requestId)||i.value.some(x=>x.requestId===p.requestId)||(i.value=[...i.value,p])}function H(){if(!l)return;const p=new WebSocket(l.relayUrl);f=p,p.addEventListener("open",()=>{p===f&&p.send(JSON.stringify({type:"register",peerId:u,deviceType:"web",deviceInfo:{protocol:"remote-session.e2ee.v1"}}))}),p.addEventListener("message",w=>{p===f&&B(w.data)}),p.addEventListener("close",()=>{p===f&&(f=null,g?t.value="disconnected":j())}),p.addEventListener("error",()=>{p===f&&(n.value="Remote Session relay connection error")})}function j(){if(g||v)return;if(S>=mo){t.value="disconnected",n.value="Remote Session 重连已放弃(中继长时间不可达)— 回到本页可自动重试";return}const p=Math.min(wo*2**S,yo);S+=1,t.value="reconnecting",v=setTimeout(()=>{v=null,g||H()},p)}function D(){o.value!=="relay"||!l||g||f||v||(S=0,n.value="",t.value="connecting",H())}function B(p){try{let w=JSON.parse(typeof p=="string"?p:String(p));if(w.type==="offline-message"&&(w=w.originalMessage||{}),w.type==="registered"){b?t.value="connected":(t.value="pairing",U());return}if(w.type!=="message")return;const x=w.payload;if(!x||x.type!=="remote-session.encrypted")return;const O=c.decrypt(x.envelope);O.type==="pair.accepted"?(b=!0,S=0,t.value="connected"):O.type==="session.revoked"?(g=!0,b=!1,L(),f&&f.close(),f=null,t.value="revoked"):k(O)}catch(w){t.value="error",n.value=w?.message||"Remote Session protocol error"}}function E(p,w){return!f||f.readyState!==WebSocket.OPEN||!l?!1:(f.send(JSON.stringify({type:"message",to:l.hostPeerId,payload:{type:p,...w}})),!0)}function U(){const p={type:"pair.join",remoteSessionId:l.remoteSessionId,token:l.pairingToken};d?.token&&(p.pushToken=d.token,p.pushProvider=d.provider||"web"),E("remote-session.pair",{mobilePeerId:u,mobilePublicKey:c.publicKeyBase64(),envelope:c.encrypt(p)})}function $(p){if(!f||f.readyState!==WebSocket.OPEN||!b)return!1;const w={...p,commandId:p.commandId||Je(),seq:p.seq??++y};return E("remote-session.encrypted",{envelope:c.encrypt(w)})}function M(p){for(const[,w]of I)clearTimeout(w.timer),w.reject(new Error(p));I=new Map}function Z(p,w={}){const x=h;if(!x||x.readyState!==WebSocket.OPEN)return Promise.reject(new Error("not connected"));const O=`web-rc-${++R}-${Je()}`;return new Promise((oe,pe)=>{const je=setTimeout(()=>{I.delete(O),pe(new Error(`request "${p}" timed out`))},bo);I.set(O,{resolve:oe,reject:pe,timer:je}),x.send(JSON.stringify({id:O,type:p,...w}))})}function G(p){let w;try{w=JSON.parse(typeof p=="string"?p:String(p))}catch{return}const x=w.requestId&&I.has(w.requestId)?w.requestId:w.id&&I.has(w.id)?w.id:null;if(x){const O=I.get(x);I.delete(x),clearTimeout(O.timer),w.type==="error"?O.reject(new Error(w.message||w.payload?.message||"server error")):O.resolve(w);return}if(w.type==="remote-session-event"&&w.remoteSessionId===m?.remoteSessionId){k(w.event||{});return}w.type==="remote-session-revoked"&&w.remoteSessionId===m?.remoteSessionId&&(g=!0,h&&h.close(),h=null,t.value="revoked")}function te(p){m=p,r.value=p.remoteSessionId,o.value="direct",s.value=p.scopes,t.value="connecting";const w=new WebSocket(p.wsUrl);h=w,w.addEventListener("open",async()=>{if(w===h)try{if(t.value="pairing",p.serverToken){const O=await Z("auth",{token:p.serverToken});if(!O.success)throw new Error(O.message||"authentication failed")}const x=await Z("remote-session-join",{remoteSessionId:p.remoteSessionId,token:p.pairingToken});if(w!==h)return;s.value=x.member?.scopes||p.scopes,t.value="connected"}catch(x){if(w!==h)return;t.value="error",n.value=x?.message||"Direct pairing failed";try{w.close()}catch{}h=null}}),w.addEventListener("message",x=>{w===h&&G(x.data)}),w.addEventListener("close",()=>{if(w===h){if(h=null,M("connection closed"),g){t.value!=="revoked"&&(t.value="disconnected");return}(t.value==="connected"||t.value==="pairing")&&(t.value="disconnected",n.value="直连会话已断开 — 配对码为一次性,请在主机端重新生成配对链接")}}),w.addEventListener("error",()=>{w===h&&(n.value="Remote control host connection error")})}function Q(p){return Z("remote-session-publish",{remoteSessionId:m.remoteSessionId,commandId:Je(),seq:++y,event:p}).catch(w=>(n.value=w?.message||"Remote control send failed",null))}function st(p,w={}){Oe();try{if(n.value="",e.value=[],i.value=[],g=!1,y=0,Un(p))return te(go(p)),!0;const x=fo(p);return d=w.pushCredentials||null,u=Eo(),c=new lo(x.remoteSessionId,u),c.pair(x.hostPublicKey,x.pairingToken),l=x,r.value=x.remoteSessionId,o.value="relay",s.value=null,b=!1,S=0,t.value="connecting",H(),!0}catch(x){return t.value="error",n.value=x?.message||"Invalid pairing link",!1}}function _e(p){const w=(p||"").trim();if(w){if(o.value==="direct"){h?Q({type:"prompt",content:w}):n.value="Remote Session is not connected";return}$({type:"prompt",content:w})||(n.value="Remote Session is not connected")}}function ze(p,w){if(!p)return;const x=i.value.find(O=>O.requestId===p)||null;if(q(p),o.value==="direct"){if(!h){n.value="Remote Session is not connected",F(x);return}Q({type:"approval.resolve",requestId:p,answer:w,approved:w}).then(O=>{O===null&&F(x)});return}$({type:"approval.resolve",requestId:p,approved:w})||(n.value="Remote Session is not connected",F(x))}function Be(p,w){if(!p)return;const x=a.value.find(oe=>oe.requestId===p)||null;if(!x?.binding)return;T(p);const O={type:"question.answer",requestId:p,answer:w,binding:x.binding};if(o.value==="direct"){if(!h){n.value="Remote Session is not connected",a.value=[...a.value,x];return}Q(O).then(oe=>{oe===null&&!a.value.some(pe=>pe.requestId===p)&&(a.value=[...a.value,x])});return}$(O)||(n.value="Remote Session is not connected",a.value=[...a.value,x])}function Re(){if(o.value==="direct"){h&&Q({type:"interrupt"});return}$({type:"interrupt"})}function Ae(p,w="web"){if(d=p?{token:p,provider:w}:null,!b)return;const x={type:"push.register"};d?.token&&(x.pushToken=d.token,x.pushProvider=d.provider),$(x)}function Oe(){if(g=!0,b=!1,L(),f)try{f.close()}catch{}if(f=null,h)try{h.close()}catch{}h=null,m=null,M("disconnected"),t.value!=="revoked"&&(t.value="disconnected")}return{status:t,events:e,error:n,remoteSessionId:r,transport:o,scopes:s,pendingApprovals:i,pendingQuestions:a,connect:st,sendPrompt:_e,approve:ze,answerQuestion:Be,interrupt:Re,updatePushCredentials:Ae,resumeReconnect:D,disconnect:Oe}}),vo={__name:"RemoteSession",setup(t,{expose:e}){e();const n=rn();kt(()=>n.resumeReconnect());const{status:r,events:o,error:s,transport:i,pendingApprovals:a,pendingQuestions:f}=Tt(n),c=ee(""),l=ee(""),u=ee(!1),b=Le(()=>["connecting","pairing","connected","reconnecting"].includes(r.value)),g=Le(()=>({idle:"未连接",connecting:"连接中",pairing:"配对中",connected:"已连接",reconnecting:"重连中",disconnected:"已断开",revoked:"已被撤销",error:"错误"})[r.value]||r.value),S=Le(()=>r.value==="connected"?"green":["connecting","pairing","reconnecting"].includes(r.value)?"blue":["revoked","error"].includes(r.value)?"red":"default"),v=Le(()=>[...o.value].reverse());function d(E){return String(E?.type||"").includes("approval")}function y(E){return E?.content||E?.payload?.content||E?.message||""}function h(E){return E?.requestId||E?.approvalId||""}function m(){n.connect(c.value.trim())}function I(E){u.value=!1,E&&(c.value=E,n.connect(E))}function R(E){const U=typeof E=="string"?E:l.value;n.sendPrompt(U),l.value=""}function L(E,U){n.approve(h(E),U)}function k(E,U){n.approve(E.requestId,U)}function q(E){return String(E&&typeof E=="object"?E.label??E.value??"":E??"")}function T(E){return E&&typeof E=="object"&&"value"in E?E.value:q(E)}function F(E,U){let $=U;if($===void 0){const M=E.options.map(q).filter(Boolean),Z=window.prompt(`${E.question||"Input required"}${M.length?`
5
- Options: ${M.join(", ")}`:""}`);if(Z===null)return;$=E.multiSelect?Z.split(",").map(G=>G.trim()).filter(Boolean):Z}n.answerQuestion(E.requestId,$)}function H(){n.interrupt()}function j(){n.disconnect()}function D(){s.value=""}const B={store:n,status:r,events:o,error:s,transport:i,pendingApprovals:a,pendingQuestions:f,pairingLink:c,promptText:l,scannerOpen:u,isActive:b,statusLabel:g,statusColor:S,orderedEvents:v,isApproval:d,eventBody:y,requestIdOf:h,connect:m,onScanned:I,send:R,respond:L,respondPermission:k,optionLabel:q,optionValue:T,answerQuestion:F,interrupt:H,disconnect:j,clearError:D,computed:Le,onMounted:kt,ref:ee,get storeToRefs(){return Tt},get LinkOutlined(){return Mn},get ScanOutlined(){return $n},QrScannerModal:Dn,get useRemoteSessionStore(){return rn}};return Object.defineProperty(B,"__isScriptSetup",{enumerable:!1,value:!0}),B}},xo={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},So={key:0,class:"page-sub"},Io={key:0,style:{"word-break":"break-all"}},_o={key:1,class:"page-sub"};function Bo(t,e,n,r,o,s){const i=W("a-tag"),a=W("a-space"),f=W("a-alert"),c=W("a-textarea"),l=W("a-button"),u=W("a-card"),b=W("a-input-search"),g=W("a-spin"),S=W("a-list-item-meta"),v=W("a-list-item"),d=W("a-list"),y=W("a-badge"),h=W("a-empty");return P(),ke("div",null,[Te("div",xo,[e[4]||(e[4]=Te("div",null,[Te("h2",{class:"page-title"},"远程会话"),Te("p",{class:"page-sub"}," 扫码或粘贴桌面端的配对链接,接管一个编码会话(观察 / 提示 / 审批 / 中断)——支持中继 E2EE 链接与局域网直连链接 ")],-1)),A(a,null,{default:_(()=>[r.transport?(P(),ne(i,{key:0,color:"purple"},{default:_(()=>[Y(ge(r.transport==="direct"?"直连":"中继"),1)]),_:1})):he("v-if",!0),A(i,{color:r.statusColor},{default:_(()=>[Y(ge(r.statusLabel),1)]),_:1},8,["color"])]),_:1})]),r.error?(P(),ne(f,{key:0,type:"error","show-icon":"",style:{"margin-bottom":"16px"},message:r.error,closable:"",onClose:r.clearError},null,8,["message"])):he("v-if",!0),r.isActive?(P(),ne(u,{key:2,title:"会话控制",style:{background:"var(--bg-card)","border-color":"var(--border-color)","margin-bottom":"16px"}},{extra:_(()=>[A(a,null,{default:_(()=>[A(l,{size:"small",onClick:r.interrupt},{default:_(()=>[...e[8]||(e[8]=[Y("中断",-1)])]),_:1}),A(l,{size:"small",danger:"",onClick:r.disconnect},{default:_(()=>[...e[9]||(e[9]=[Y("断开",-1)])]),_:1})]),_:1})]),default:_(()=>[A(a,{direction:"vertical",style:{width:"100%"},size:8},{default:_(()=>[A(b,{value:r.promptText,"onUpdate:value":e[2]||(e[2]=m=>r.promptText=m),placeholder:"发送提示到远程会话…","enter-button":"发送",disabled:r.status!=="connected",onSearch:r.send},null,8,["value","disabled"]),r.status==="reconnecting"?(P(),ne(g,{key:0,size:"small"},{tip:_(()=>[...e[10]||(e[10]=[Y("正在重连…",-1)])]),_:1})):he("v-if",!0)]),_:1})]),_:1})):(P(),ne(u,{key:1,title:"连接远程会话",style:{background:"var(--bg-card)","border-color":"var(--border-color)","margin-bottom":"16px"}},{default:_(()=>[A(a,{direction:"vertical",style:{width:"100%"},size:12},{default:_(()=>[A(c,{value:r.pairingLink,"onUpdate:value":e[0]||(e[0]=m=>r.pairingLink=m),rows:3,placeholder:"chainlesschain://remote-session/pair#…(中继)或 chainlesschain://remote-control/pair#…(局域网直连)","allow-clear":""},null,8,["value"]),A(a,null,{default:_(()=>[A(l,{type:"primary",disabled:!r.pairingLink.trim(),onClick:r.connect},{icon:_(()=>[A(r.LinkOutlined)]),default:_(()=>[e[5]||(e[5]=Y(" 连接 ",-1))]),_:1},8,["disabled"]),A(l,{onClick:e[1]||(e[1]=m=>r.scannerOpen=!0)},{icon:_(()=>[A(r.ScanOutlined)]),default:_(()=>[e[6]||(e[6]=Y(" 扫码 ",-1))]),_:1})]),_:1}),e[7]||(e[7]=Te("p",{class:"page-sub",style:{margin:"0"}}," 链接为一次性配对码,敏感载荷仅在片段(#)中,不会发往服务器。 ",-1))]),_:1})]),_:1})),r.pendingQuestions.length?(P(),ne(u,{key:3,title:"Agent questions",style:{background:"var(--bg-card)","border-color":"var(--warning-color, #faad14)","margin-bottom":"16px"}},{default:_(()=>[A(d,{size:"small","data-source":r.pendingQuestions,"data-testid":"question-cards"},{renderItem:_(({item:m})=>[A(v,null,{actions:_(()=>[(P(!0),ke(Nn,null,Fn(m.multiSelect?[]:m.options,I=>(P(),ne(l,{key:r.optionLabel(I),size:"small",onClick:R=>r.answerQuestion(m,r.optionValue(I))},{default:_(()=>[Y(ge(r.optionLabel(I)),1)]),_:2},1032,["onClick"]))),128)),m.multiSelect||!m.options.length?(P(),ne(l,{key:0,type:"primary",size:"small",onClick:I=>r.answerQuestion(m)},{default:_(()=>[...e[11]||(e[11]=[Y(" Answer ",-1)])]),_:1},8,["onClick"])):he("v-if",!0)]),default:_(()=>[A(S,{description:m.question||"Input required"},null,8,["description"])]),_:2},1024)]),_:1},8,["data-source"])]),_:1})):he("v-if",!0),r.pendingApprovals.length?(P(),ne(u,{key:4,style:{background:"var(--bg-card)","border-color":"var(--warning-color, #faad14)","margin-bottom":"16px"}},{title:_(()=>[e[12]||(e[12]=Y(" 待审批权限请求 ",-1)),A(y,{count:r.pendingApprovals.length,style:{"margin-left":"8px"}},null,8,["count"])]),default:_(()=>[A(d,{size:"small","data-source":r.pendingApprovals,"data-testid":"approval-cards"},{renderItem:_(({item:m})=>[A(v,null,{actions:_(()=>[A(l,{type:"primary",size:"small",onClick:I=>r.respondPermission(m,!0)},{default:_(()=>[...e[13]||(e[13]=[Y("批准",-1)])]),_:1},8,["onClick"]),A(l,{size:"small",danger:"",onClick:I=>r.respondPermission(m,!1)},{default:_(()=>[...e[14]||(e[14]=[Y("拒绝",-1)])]),_:1},8,["onClick"])]),default:_(()=>[A(S,null,{title:_(()=>[A(a,null,{default:_(()=>[A(i,{color:"orange"},{default:_(()=>[Y(ge(m.tool||"tool"),1)]),_:2},1024),m.action?(P(),ke("span",So,ge(m.action),1)):he("v-if",!0)]),_:2},1024)]),description:_(()=>[m.detail?(P(),ke("code",Io,ge(m.detail),1)):(P(),ke("span",_o,"(无详情)"))]),_:2},1024)]),_:2},1024)]),_:1},8,["data-source"])]),_:1})):he("v-if",!0),A(u,{title:"会话事件",style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:_(()=>[r.events.length?(P(),ne(d,{key:1,size:"small","data-source":r.orderedEvents},{renderItem:_(({item:m})=>[A(v,null,Hn({default:_(()=>[A(S,{description:r.eventBody(m)},{title:_(()=>[A(i,{color:r.isApproval(m)?"orange":"blue"},{default:_(()=>[Y(ge(m.type||"event"),1)]),_:2},1032,["color"])]),_:2},1032,["description"])]),_:2},[r.isApproval(m)?{name:"actions",fn:_(()=>[A(l,{type:"link",size:"small",onClick:I=>r.respond(m,!0)},{default:_(()=>[...e[15]||(e[15]=[Y("批准",-1)])]),_:1},8,["onClick"]),A(l,{type:"link",size:"small",danger:"",onClick:I=>r.respond(m,!1)},{default:_(()=>[...e[16]||(e[16]=[Y("拒绝",-1)])]),_:1},8,["onClick"])]),key:"0"}:void 0]),1024)]),_:1},8,["data-source"])):(P(),ne(h,{key:0,description:"尚无事件"}))]),_:1}),A(r.QrScannerModal,{open:r.scannerOpen,onScanned:r.onScanned,onCancel:e[3]||(e[3]=m=>r.scannerOpen=!1)},null,8,["open"])])}const Lo=Zn(vo,[["render",Bo],["__file","/tmp/cc-web-panel-UAH1Xi/repo/packages/web-panel/src/views/RemoteSession.vue"]]);export{Lo as default};
@@ -1 +0,0 @@
1
- import{E as F,b as D,r as R,I as p,J as c,U as _,c as n,K as a,S as C,V as x,o as I,x as V,P as i,Q as k,R as r,F as T,Z as O}from"./vendor-Bn1JzzAn.js";import{u as P,_ as U}from"./index-Dyngbd29.js";import{R as E}from"./icons-DG5UD-6K.js";const B=F("tasks",()=>{const y=R([]),l=R(!1);let u=null,t=null,d=null;const b=D(()=>y.value.filter(e=>e.status==="running")),v=D(()=>y.value.filter(e=>e.status==="pending")),w=D(()=>y.value.filter(e=>e.status==="completed"||e.status==="failed"||e.status==="timeout"));async function s(){const e=P();l.value=!0;try{const g=await e.sendRaw({type:"tasks-list"});g&&Array.isArray(g.tasks)&&(y.value=g.tasks)}catch{}finally{l.value=!1}}async function m(e){const g=P();try{await g.sendRaw({type:"tasks-stop",taskId:e})}catch{}finally{await s()}}const f=R(null);function h(e=5e3){N(),s(),u=setInterval(s,e),S()}function N(){u&&(clearInterval(u),u=null),t&&(t(),t=null),d&&(clearTimeout(d),d=null)}function S(){const e=P();if(t)return;const g=z=>{z.type==="task:notification"&&z.payload?.task&&(f.value=z.payload.task,s(),d&&clearTimeout(d),d=setTimeout(()=>{f.value=null,d=null},8e3))};t=e.onRuntimeEvent(g)}function A(e){return!e||e<0?"-":e<1e3?`${e}ms`:e<6e4?`${(e/1e3).toFixed(1)}s`:`${(e/6e4).toFixed(1)}m`}function o(e){switch(e){case"running":return"processing";case"pending":return"default";case"completed":return"success";case"failed":return"error";case"timeout":return"warning";default:return"default"}}return{tasks:y,loading:l,running:b,pending:v,completed:w,lastNotification:f,fetchTasks:s,stopTask:m,startPolling:h,stopPolling:N,formatDuration:A,getStatusColor:o}}),L={__name:"Tasks",setup(y,{expose:l}){l();const u=B(),t=[{title:"状态",key:"status",width:90},{title:"描述",key:"description",ellipsis:!0},{title:"类型",dataIndex:"type",width:100},{title:"耗时",key:"duration",width:90},{title:"创建时间",key:"createdAt",width:180},{title:"结果",key:"result",ellipsis:!0},{title:"操作",key:"action",width:80}];function d(s){return s.status==="running"&&s.startedAt?u.formatDuration(Date.now()-s.startedAt):s.completedAt&&s.startedAt?u.formatDuration(s.completedAt-s.startedAt):"-"}function b(s){return s?new Date(s).toLocaleString():"-"}function v(s,m){return s?s.length>m?`${s.slice(0,m)}...`:s:""}I(()=>u.startPolling(5e3)),V(()=>u.stopPolling());const w={store:u,columns:t,getDuration:d,formatTime:b,truncate:v,onMounted:I,onUnmounted:V,get ReloadOutlined(){return E},get useTasksStore(){return B}};return Object.defineProperty(w,"__isScriptSetup",{enumerable:!1,value:!0}),w}},j={class:"page-header"},H={key:0,class:"error-text"},J={key:1},K={class:"task-header"},M={class:"task-desc"},Q={class:"task-id"},W={class:"task-meta"},X=["title"],Z={key:0,class:"error-text"},q={key:1,class:"success-text"},G={key:2,class:"muted-text"};function Y(y,l,u,t,d,b){const v=p("a-button"),w=p("a-space"),s=p("a-alert"),m=p("a-statistic"),f=p("a-card"),h=p("a-col"),N=p("a-row"),S=p("a-tag"),A=p("a-table");return i(),c("div",null,[_("div",j,[l[3]||(l[3]=_("div",null,[_("h2",{class:"page-title"},"后台任务"),_("p",{class:"page-sub"},"查看后台任务队列、实时通知和任务执行结果。")],-1)),n(w,null,{default:a(()=>[n(v,{ghost:"",loading:t.store.loading,onClick:l[0]||(l[0]=o=>t.store.fetchTasks())},{icon:a(()=>[n(t.ReloadOutlined)]),default:a(()=>[l[2]||(l[2]=k(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),t.store.lastNotification?(i(),C(s,{key:0,type:t.store.lastNotification.status==="completed"?"success":"error","show-icon":"",closable:"",class:"banner",onClose:l[1]||(l[1]=o=>t.store.lastNotification=null)},{message:a(()=>[k(" 任务"+r(t.store.lastNotification.status==="completed"?"完成":"结束")+": "+r(t.store.lastNotification.description||t.store.lastNotification.id.slice(0,16)),1)]),description:a(()=>[t.store.lastNotification.error?(i(),c("span",H,r(t.store.lastNotification.error),1)):t.store.lastNotification.result?(i(),c("span",J,r(t.truncate(String(t.store.lastNotification.result),120)),1)):x("v-if",!0)]),_:1},8,["type"])):x("v-if",!0),n(N,{gutter:[16,16],class:"stats-row"},{default:a(()=>[n(h,{xs:12,sm:6},{default:a(()=>[n(f,{class:"stat-card",size:"small"},{default:a(()=>[n(m,{title:"全部任务",value:t.store.tasks.length},null,8,["value"])]),_:1})]),_:1}),n(h,{xs:12,sm:6},{default:a(()=>[n(f,{class:"stat-card",size:"small"},{default:a(()=>[n(m,{title:"运行中",value:t.store.running.length},null,8,["value"])]),_:1})]),_:1}),n(h,{xs:12,sm:6},{default:a(()=>[n(f,{class:"stat-card",size:"small"},{default:a(()=>[n(m,{title:"等待中",value:t.store.pending.length},null,8,["value"])]),_:1})]),_:1}),n(h,{xs:12,sm:6},{default:a(()=>[n(f,{class:"stat-card",size:"small"},{default:a(()=>[n(m,{title:"已完成",value:t.store.completed.length},null,8,["value"])]),_:1})]),_:1})]),_:1}),t.store.running.length>0?(i(),C(f,{key:1,title:"运行中的任务",class:"panel-card",size:"small"},{default:a(()=>[(i(!0),c(T,null,O(t.store.running,o=>(i(),c("div",{key:o.id,class:"task-item running"},[_("div",K,[n(S,{color:t.store.getStatusColor(o.status)},{default:a(()=>[k(r(o.status.toUpperCase()),1)]),_:2},1032,["color"]),_("span",M,r(o.description),1),_("span",Q,r(o.id.slice(0,16)),1)]),_("div",W,[_("span",null,"类型: "+r(o.type||"-"),1),_("span",null,"已运行: "+r(t.store.formatDuration(Date.now()-o.startedAt)),1),n(v,{size:"small",danger:"",onClick:e=>t.store.stopTask(o.id)},{default:a(()=>[...l[4]||(l[4]=[k("停止",-1)])]),_:1},8,["onClick"])])]))),128))]),_:1})):x("v-if",!0),n(f,{class:"panel-card"},{default:a(()=>[n(A,{columns:t.columns,"data-source":t.store.tasks,pagination:{pageSize:15,size:"small"},loading:t.store.loading,"row-key":"id",size:"small"},{bodyCell:a(({column:o,record:e})=>[o.key==="status"?(i(),C(S,{key:0,color:t.store.getStatusColor(e.status)},{default:a(()=>[k(r(e.status),1)]),_:2},1032,["color"])):o.key==="description"?(i(),c("span",{key:1,title:e.command},r(e.description),9,X)):o.key==="duration"?(i(),c(T,{key:2},[k(r(t.getDuration(e)),1)],64)):o.key==="createdAt"?(i(),c(T,{key:3},[k(r(t.formatTime(e.createdAt)),1)],64)):o.key==="result"?(i(),c(T,{key:4},[e.error?(i(),c("span",Z,r(t.truncate(e.error,60)),1)):e.result?(i(),c("span",q,r(t.truncate(String(e.result),60)),1)):(i(),c("span",G,"-"))],64)):o.key==="action"?(i(),c(T,{key:5},[e.status==="running"?(i(),C(v,{key:0,size:"small",danger:"",onClick:g=>t.store.stopTask(e.id)},{default:a(()=>[...l[5]||(l[5]=[k(" 停止 ",-1)])]),_:1},8,["onClick"])):x("v-if",!0)],64)):x("v-if",!0)]),_:1},8,["data-source","loading"])]),_:1})])}const st=U(L,[["render",Y],["__scopeId","data-v-da5ff6a2"],["__file","/tmp/cc-web-panel-UAH1Xi/repo/packages/web-panel/src/views/Tasks.vue"]]);export{st as default};
@@ -1,3 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./xterm-BZcWGsqw.js","./markdown-CsiA8-E5.js","./markdown-Dfs9RUU9.css","./addon-fit-CK6X9sAG.js","./xterm-DFuMZ0ql.css"])))=>i.map(i=>d[i]);
2
- import{u as fe,_ as me,d as U,e as V}from"./index-Dyngbd29.js";import{I as z,J as x,U as _,Q as D,S as K,K as T,V as R,c as A,F as Q,Z as Y,R as E,o as Z,f as G,w as $,n as q,b as ee,r as S,P as y,_ as ve,a2 as we,a3 as he,a4 as _e}from"./vendor-Bn1JzzAn.js";import{R as ye,b as pe,at as ge}from"./icons-DG5UD-6K.js";const k=new Map,C=new Map,N=new Set,F=new Set;let te=!1;function xe(c){te||(te=!0,c.onMessage(o=>{if(!(!o||typeof o.type!="string")){if(o.type==="terminal.stdout"){const{sessionId:s,data:e,seq:i}=o.payload||{};if(!s)return;let w;try{const d=atob(e||""),f=new Uint8Array(d.length);for(let n=0;n<d.length;n++)f[n]=d.charCodeAt(n);w=new TextDecoder("utf-8").decode(f)}catch{w=""}const u={sessionId:s,data:w,seq:i};k.get(s)?.forEach(d=>d(u)),N.forEach(d=>d(u))}else if(o.type==="terminal.exit"){const{sessionId:s,exitCode:e,signal:i}=o.payload||{};if(!s)return;const w={sessionId:s,exitCode:e,signal:i};C.get(s)?.forEach(u=>u(w)),F.forEach(u=>u(w))}}}))}function ne(c){const o=new TextEncoder().encode(c);let s="";for(let e=0;e<o.length;e++)s+=String.fromCharCode(o[e]);return btoa(s)}function ae(c){const o=atob(c||""),s=new Uint8Array(o.length);for(let e=0;e<o.length;e++)s[e]=o.charCodeAt(e);return new TextDecoder("utf-8").decode(s)}function oe(){const c=fe();xe(c);async function o(n={}){const a=await c.sendRaw({type:"terminal.create",payload:{shell:n.shell,cwd:n.cwd,env:n.env,cols:n.cols,rows:n.rows}});if(a.ok===!1)throw new Error(a.error||"terminal_create_failed");return a.result??a}async function s(){const n=await c.sendRaw({type:"terminal.list",payload:{}});if(n.ok===!1)throw new Error(n.error||"terminal_list_failed");const a=n.result??n;return Array.isArray(a.sessions)?a.sessions:[]}async function e(n,a){const r=await c.sendRaw({type:"terminal.stdin",payload:{sessionId:n,data:ne(String(a))}});if(r.ok===!1)throw new Error(r.error||"terminal_stdin_failed");return r.result??r}async function i(n,a,r){const h=await c.sendRaw({type:"terminal.resize",payload:{sessionId:n,cols:a,rows:r}});if(h.ok===!1)throw new Error(h.error||"terminal_resize_failed");return h.result??h}async function w(n){const a=await c.sendRaw({type:"terminal.close",payload:{sessionId:n}});if(a.ok===!1)throw new Error(a.error||"terminal_close_failed");return a.result??a}async function u(n,a=0){const r=await c.sendRaw({type:"terminal.history",payload:{sessionId:n,fromSeq:a}});if(r.ok===!1)throw new Error(r.error||"terminal_history_failed");const h=r.result??r;return{truncated:!!h.truncated,chunks:(h.chunks||[]).map(L=>({seq:L.seq,data:ae(L.data)}))}}function d(n,a){return n?(k.has(n)||k.set(n,new Set),k.get(n).add(a),()=>{k.get(n)?.delete(a),k.get(n)?.size===0&&k.delete(n)}):(N.add(a),()=>N.delete(a))}function f(n,a){return n?(C.has(n)||C.set(n,new Set),C.get(n).add(a),()=>{C.get(n)?.delete(a),C.get(n)?.size===0&&C.delete(n)}):(F.add(a),()=>F.delete(a))}return{create:o,list:s,stdin:e,resize:i,close:w,history:u,onStdout:d,onExit:f,_internal:{stdoutSubs:k,exitSubs:C,toBase64Utf8:ne,fromBase64Utf8:ae}}}const Se={__name:"Terminal",setup(c,{expose:o}){o();const s=oe(),e=S([]),i=S(null),w=S("pwsh"),u=S(!1),d=S(!1),f=S(""),n=S(""),a=S([]),r=[{value:"pwsh",label:"PowerShell"},{value:"cmd",label:"CMD"},{value:"bash",label:"Bash"},{value:"wsl",label:"WSL"}],h=ee(()=>e.value.find(t=>t.id===i.value));function L(t){return t?t.slice(0,8):""}let O=null,M=null;async function I(){if(O)return{xtermMod:O,fitAddonMod:M};try{O=await V(()=>import("./xterm-BZcWGsqw.js").then(t=>t.x),__vite__mapDeps([0,1,2]),import.meta.url),M=await V(()=>import("./addon-fit-CK6X9sAG.js").then(t=>t.a),__vite__mapDeps([3,1,2]),import.meta.url),await V(()=>Promise.resolve({}),__vite__mapDeps([4]),import.meta.url)}catch(t){throw n.value="xterm 资源加载失败:"+(t?.message||"未知错误"),t}return{xtermMod:O,fitAddonMod:M}}async function B(t){await q();const{xtermMod:l,fitAddonMod:p}=await I(),b=a.value.find(v=>v?.dataset?.sessionId===t.id);if(!b)return;const m=new l.Terminal({cursorBlink:!0,fontFamily:'Consolas, "Courier New", monospace',fontSize:13,theme:{background:"#1e1e1e",foreground:"#d4d4d4"},convertEol:!1}),P=new p.FitAddon;m.loadAddon(P),m.open(b);try{P.fit()}catch{}t.xterm=m,t.fitAddon=P;const ie=m.onData(v=>{s.stdin(t.id,v).catch(g=>{String(g?.message||"").includes("dangerous_keyword_blocked")?U.warning("该命令被桌面端拦截(高危关键字)"):U.error("stdin 失败: "+(g?.message||g))})}),ce=s.onStdout(t.id,({data:v,seq:g})=>{t.lastSeq=g,m.write(v)}),de=s.onExit(t.id,({exitCode:v,signal:g})=>{t.alive=!1,t.exitCode=v,t.signal=g,m.writeln(`\r
3
- \x1B[33m[session exited, code=${v}, signal=${g??"-"}]\x1B[0m`)});t.offs=()=>{try{ie.dispose?.()}catch{}ce(),de()};try{const{chunks:v,truncated:g}=await s.history(t.id,0);g&&m.writeln("\x1B[2m[history truncated — earlier output was evicted]\x1B[0m");for(const J of v)m.write(J.data),t.lastSeq=J.seq}catch(v){m.writeln(`\x1B[31m[history fetch failed: ${v?.message||v}]\x1B[0m`)}const H=new ResizeObserver(()=>{try{P.fit(),s.resize(t.id,m.cols,m.rows).catch(()=>{})}catch{}});H.observe(b);const ue=t.offs;t.offs=()=>{try{H.disconnect()}catch{}ue()}}async function re(){u.value=!0,f.value="";try{const t=await s.create({shell:w.value,cols:80,rows:24}),l={id:t.sessionId,shell:t.shell,cwd:"",alive:!0,lastSeq:0,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(l),i.value=l.id,await B(l)}catch(t){f.value=t?.message||String(t)}finally{u.value=!1}}async function se(t){try{await s.close(t)}catch(l){f.value=l?.message||String(l)}setTimeout(()=>W(t),500)}function W(t){const l=e.value.findIndex(b=>b.id===t);if(l===-1)return;const p=e.value[l];try{p.offs?.()}catch{}try{p.xterm?.dispose?.()}catch{}e.value.splice(l,1),i.value===t&&(i.value=e.value[0]?.id||null)}function le(t){i.value=t,q(()=>{const l=e.value.find(p=>p.id===t);try{l?.fitAddon?.fit()}catch{}})}async function X(){d.value=!0,f.value="";try{const t=await s.list();for(const l of t){const p=e.value.find(m=>m.id===l.id);if(p){p.alive=l.alive,p.lastSeq=l.lastSeq;continue}const b={id:l.id,shell:l.shell,cwd:l.cwd,alive:l.alive,lastSeq:l.lastSeq,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(b),await B(b)}!i.value&&e.value.length>0&&(i.value=e.value[0].id)}catch(t){f.value=t?.message||String(t)}finally{d.value=!1}}Z(async()=>{await X()}),G(()=>{for(const t of e.value){try{t.offs?.()}catch{}try{t.xterm?.dispose?.()}catch{}}}),$(i,()=>{q(()=>{const t=h.value;try{t?.fitAddon?.fit()}catch{}})});const j={term:s,sessions:e,activeId:i,newShell:w,creating:u,loadingList:d,error:f,warning:n,xtermContainers:a,shellOptions:r,active:h,shortId:L,get xtermMod(){return O},set xtermMod(t){O=t},get fitAddonMod(){return M},set fitAddonMod(t){M=t},loadXterm:I,mountXterm:B,onCreate:re,onClose:se,removeSession:W,activate:le,refreshList:X,ref:S,computed:ee,onMounted:Z,onBeforeUnmount:G,nextTick:q,watch:$,get message(){return U},get PlusOutlined(){return ge},get CloseOutlined(){return pe},get ReloadOutlined(){return ye},get useTerminal(){return oe}};return Object.defineProperty(j,"__isScriptSetup",{enumerable:!1,value:!0}),j}},be={class:"terminal-page"},ke={class:"terminal-header"},Ce={class:"page-sub"},Ae={class:"terminal-body"},Ee={class:"session-tabs"},Oe=["onClick"],Te={class:"session-shell"},Re={class:"session-id"},Me={key:0,class:"session-empty"},ze={class:"xterm-host"},Le=["data-session-id"],Pe={key:0,class:"xterm-placeholder"},De={key:1,class:"terminal-footer"},qe={key:0,class:"footer-exit"};function Be(c,o,s,e,i,w){const u=z("a-tag"),d=z("a-select"),f=z("a-button"),n=z("a-space"),a=z("a-alert");return y(),x("div",be,[_("div",ke,[_("div",null,[o[3]||(o[3]=_("h2",{class:"page-title"},"远程终端",-1)),_("p",Ce,[o[2]||(o[2]=D(" 桌面端托管的 PTY 会话;Android 端可远程操控同一通道 ",-1)),e.warning?(y(),K(u,{key:0,color:"orange",style:{"margin-left":"8px"}},{default:T(()=>[D(E(e.warning),1)]),_:1})):R("v-if",!0)])]),A(n,null,{default:T(()=>[A(d,{value:e.newShell,"onUpdate:value":o[0]||(o[0]=r=>e.newShell=r),style:{width:"130px"},size:"small",options:e.shellOptions},null,8,["value"]),A(f,{type:"primary",size:"small",loading:e.creating,onClick:e.onCreate},{icon:T(()=>[A(e.PlusOutlined)]),default:T(()=>[o[4]||(o[4]=D(" 新会话 ",-1))]),_:1},8,["loading"]),A(f,{size:"small",loading:e.loadingList,onClick:e.refreshList},{icon:T(()=>[A(e.ReloadOutlined)]),default:T(()=>[o[5]||(o[5]=D(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.error?(y(),K(a,{key:0,message:e.error,type:"error","show-icon":"",closable:"",style:{"margin-bottom":"12px"},onClose:o[1]||(o[1]=r=>e.error="")},null,8,["message"])):R("v-if",!0),_("div",Ae,[_("div",Ee,[(y(!0),x(Q,null,Y(e.sessions,r=>(y(),x("div",{key:r.id,class:ve(["session-tab",{active:r.id===e.activeId,dead:!r.alive}]),onClick:h=>e.activate(r.id)},[_("span",Te,E(r.shell),1),_("span",Re,E(e.shortId(r.id)),1),A(e.CloseOutlined,{class:"session-close",onClick:we(h=>e.onClose(r.id),["stop"])},null,8,["onClick"])],10,Oe))),128)),e.sessions.length===0?(y(),x("div",Me,' 点击 "新会话" 创建第一个终端 ')):R("v-if",!0)]),_("div",ze,[(y(!0),x(Q,null,Y(e.sessions,r=>he((y(),x("div",{key:r.id,ref_for:!0,ref:"xtermContainers","data-session-id":r.id,class:"xterm-container"},null,8,Le)),[[_e,r.id===e.activeId]])),128)),e.sessions.length===0?(y(),x("div",Pe,[...o[6]||(o[6]=[_("span",null,"无活跃会话",-1)])])):R("v-if",!0)])]),e.active?(y(),x("div",De,[_("span",null,E(e.active.shell)+" · "+E(e.active.cwd||"(默认 cwd)")+" · seq "+E(e.active.lastSeq),1),e.active.alive?R("v-if",!0):(y(),x("span",qe,"已退出 (code="+E(e.active.exitCode??"-")+")",1))])):R("v-if",!0)])}const Fe=me(Se,[["render",Be],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-UAH1Xi/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
@@ -1 +0,0 @@
1
- import{Q as r}from"./index-Dyngbd29.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-BT_u4Dzp.js";import{a0 as t}from"./index-Dyngbd29.js";import"./vendor-Bn1JzzAn.js";import"./index-D9vU25ij.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};
@@ -1 +0,0 @@
1
- import{A as o}from"./Row-oCQHYv5t.js";import{a0 as t}from"./index-Dyngbd29.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-BQRs3Mo7.js";import"./useFlexGapSupport-hknqY5NH.js";import"./styleChecker-Dd8MgL_V.js";import"./index-D9vU25ij.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};