@xopcai/xopc 0.0.232 → 0.0.233

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 (183) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-VXCWz43N.js → activity-store-DQ5L3PTi.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BXRaZYW8.js → agent-avatar-dicebear-Bps8fvBp.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-dR7HMaRX.js → agent-defaults-settings-panel-JrK80PvP.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agents-Bileycwe.js → agents-CJYEnz94.js} +1 -1
  7. package/dist/gateway/static/root/assets/{api-wGPgL8xY.js → api-DE6tZKG0.js} +1 -1
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-BJfClfPx.js → app-management-settings-panel-BryzDVod.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-C_R0vUAu.js → appearance-settings-BoweLBDm.js} +1 -1
  10. package/dist/gateway/static/root/assets/apps-page-Bt8_sWtU.js +1 -0
  11. package/dist/gateway/static/root/assets/{archive-plugin-DnFHkSHE.js → archive-plugin-DyujzZNu.js} +1 -1
  12. package/dist/gateway/static/root/assets/{attachment-load-DZrEwytM.js → attachment-load-DmXGUWve.js} +1 -1
  13. package/dist/gateway/static/root/assets/attachment-preview-renderer-BDTD8YUe.js +12 -0
  14. package/dist/gateway/static/root/assets/{automations-page-DpkKajui.js → automations-page-DrTVSK7o.js} +1 -1
  15. package/dist/gateway/static/root/assets/automations-workspace-86UTesz3.js +6 -0
  16. package/dist/gateway/static/root/assets/{binary-plugins-Ckc_Csue.js → binary-plugins-mFyeC74W.js} +2 -2
  17. package/dist/gateway/static/root/assets/{block-editor-DAC6w-iV.js → block-editor-D5yMFrgH.js} +3 -3
  18. package/dist/gateway/static/root/assets/browser-settings-page-DfMU7yXv.js +8 -0
  19. package/dist/gateway/static/root/assets/{browser-workflow-inputs-BGd7R8GO.js → browser-workflow-inputs-B6rLBtua.js} +1 -1
  20. package/dist/gateway/static/root/assets/{browser-workflows-page-DUfj7ntM.js → browser-workflows-page-C74sg50f.js} +2 -2
  21. package/dist/gateway/static/root/assets/capabilities-settings-panel-lsHRuBlX.js +7 -0
  22. package/dist/gateway/static/root/assets/channels-settings-CxR_clkO.js +1 -0
  23. package/dist/gateway/static/root/assets/{channels-status-swr-CfboECLt.js → channels-status-swr-DowVNjNw.js} +1 -1
  24. package/dist/gateway/static/root/assets/{chat-terminal-dock-CA9fndbZ.js → chat-terminal-dock-BO6_BgjE.js} +1 -1
  25. package/dist/gateway/static/root/assets/connectors-page-CpNLyKB4.js +2 -0
  26. package/dist/gateway/static/root/assets/{cron-expression-CqPu7HYJ.js → cron-expression-CYMXfk4M.js} +1 -1
  27. package/dist/gateway/static/root/assets/{date-picker-C8dJsCgk.js → date-picker-DIM_OkQP.js} +1 -1
  28. package/dist/gateway/static/root/assets/{dependency-picker-Iz2wYimy.js → dependency-picker-Cp8I6rsL.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-settings-YfeVVzLe.js → desktop-pet-settings-NjPiz3M_.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-C3h40FmG.js → desktop-pet-wzSzZ6S8.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-debug-page-CChgztz_.js → extension-debug-page-CoMl13ET.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-page-DF6ct6_y.js → extension-page-CXc1Lc8x.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-jgBsjn0F.js → extension-settings-page-CfEWpgjl.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-config-api-CVajuIGL.js → gateway-config-api-yH4KAEkK.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-config-swr-BGQn8duh.js → gateway-config-swr-YyZJKvFf.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-settings-BbssNGid.js → gateway-settings-BmjJIiKh.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-startup-retry-D2Rnh9fX.js → gateway-startup-retry-Dnrl91pU.js} +1 -1
  38. package/dist/gateway/static/root/assets/{heartbeat-settings-CJtXu8iD.js → heartbeat-settings-DGq9q4b6.js} +1 -1
  39. package/dist/gateway/static/root/assets/home-page-Dj4B1wb3.js +1 -0
  40. package/dist/gateway/static/root/assets/{image-generation-api-D7W2p5_8.js → image-generation-api-BNzAAw4Y.js} +1 -1
  41. package/dist/gateway/static/root/assets/index-BGf-TiZj.js +70 -0
  42. package/dist/gateway/static/root/assets/index-BTUuTnc9.css +2 -0
  43. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BvHYyNus.js → keyboard-shortcuts-settings-CfNV1ysF.js} +1 -1
  44. package/dist/gateway/static/root/assets/local-app-workbench-page-IJg75WaN.js +2 -0
  45. package/dist/gateway/static/root/assets/{local-apps-page-Cb8t2wWM.js → local-apps-page-MPd4Fl_l.js} +1 -1
  46. package/dist/gateway/static/root/assets/{locale-store-DLwVxS3V.js → locale-store-D_dq_0LV.js} +1 -1
  47. package/dist/gateway/static/root/assets/logs-page-NsfoazgK.js +2 -0
  48. package/dist/gateway/static/root/assets/{management-settings-B8Jie4-J.js → management-settings-DeIjN4e0.js} +1 -1
  49. package/dist/gateway/static/root/assets/{markdown-split-BD1r4o2i.js → markdown-split-BUAVv6Gu.js} +1 -1
  50. package/dist/gateway/static/root/assets/markdown-view-CPkBOY3h.js +201 -0
  51. package/dist/gateway/static/root/assets/{media-plugins-BCev8fkW.js → media-plugins-DFsVnOY-.js} +1 -1
  52. package/dist/gateway/static/root/assets/messages-D4qOHT4D.js +3 -0
  53. package/dist/gateway/static/root/assets/{mobile-device-api-DACoHhhk.js → mobile-device-api-D9JevyCE.js} +1 -1
  54. package/dist/gateway/static/root/assets/models-hub-cache-C5y2gzMU.js +1 -0
  55. package/dist/gateway/static/root/assets/{notes-api-DEdNKw0I.js → notes-api-BWSfTP1w.js} +1 -1
  56. package/dist/gateway/static/root/assets/{notes-page-BBTLjJwa.js → notes-page-CV8UJj7g.js} +1 -1
  57. package/dist/gateway/static/root/assets/notes-workbench-DrjMVgEI.js +4 -0
  58. package/dist/gateway/static/root/assets/{oauth-api-BNCO2YK5.js → oauth-api-DnanEBsf.js} +1 -1
  59. package/dist/gateway/static/root/assets/{product-open-page-fEBbRekH.js → product-open-page-zNg1KOy2.js} +1 -1
  60. package/dist/gateway/static/root/assets/project-detail-page-tfcGYL-O.js +1 -0
  61. package/dist/gateway/static/root/assets/{projects-page-dHDXpMCg.js → projects-page-BkjnXLdJ.js} +1 -1
  62. package/dist/gateway/static/root/assets/{registry-api-Cvr4Qm7N.js → registry-api-BeVzfRvs.js} +1 -1
  63. package/dist/gateway/static/root/assets/remote-access-hub-BXn-3n2d.js +1 -0
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-BT5B74IH.js → runtime-tools-settings-panel-BxoioSvT.js} +2 -2
  65. package/dist/gateway/static/root/assets/{schema-form-C4tB34S5.js → schema-form-vzbmscrE.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-MLNjrOkw.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-ByNLBY2q.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-D1oXhkgI.js → settings-form-section-x9k7MWD3.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-loading-skeleton-CldfX6FJ.js → settings-loading-skeleton-BLFOD9h9.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-c3LJnbvE.js → settings-page-CwgTooar.js} +1 -1
  71. package/dist/gateway/static/root/assets/setup-status-panel-bnueBZg8.js +1 -0
  72. package/dist/gateway/static/root/assets/{share-preview-page-DptCK_mk.js → share-preview-page-COTrPAd-.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-D-v_psqL.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-DJICr4wh.js +1 -0
  75. package/dist/gateway/static/root/assets/{skills-page-OHBeBtSg.js → skills-page-D9wM6_Jn.js} +1 -1
  76. package/dist/gateway/static/root/assets/{skills-page.utils-B9WZbOLC.js → skills-page.utils-PtlQLM5a.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-Dj_DpOGw.js → system-settings-panel-BR74mNEK.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-B-rmeE8t.js +1 -0
  79. package/dist/gateway/static/root/assets/{theme-store-Cpd3Gd5R.js → theme-store-Bud54q9e.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-autosave-DCl5Yq7N.js → use-autosave-DH47MH7s.js} +1 -1
  81. package/dist/gateway/static/root/assets/user-context-page-B6eyxxOT.js +1 -0
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-BB_ZQV8F.js → voice-api-key-field-B59GaqRa.js} +1 -1
  83. package/dist/gateway/static/root/assets/{voice-config-api-BNiYmpl5.js → voice-config-api-C0ahrZ0e.js} +1 -1
  84. package/dist/gateway/static/root/assets/{work-discovery-overlay-BrIdtdum.js → work-discovery-overlay-DTn4RCcx.js} +1 -1
  85. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-hKh-uCLo.js → workflow-run-setup-panel-yDFoEX06.js} +2 -2
  86. package/dist/gateway/static/root/assets/workflows-page-BOwSbfWm.js +5 -0
  87. package/dist/gateway/static/root/index.html +13 -13
  88. package/dist/package.js +1 -1
  89. package/dist/packages/endpoint-tools-protocol/src/index.js +162 -2
  90. package/dist/packages/gateway-contract/src/product-delivery.js +6 -2
  91. package/dist/packages/gateway-contract/src/turn-outcome.js +77 -1
  92. package/dist/src/agent/capabilities/definitions.d.ts +1 -1
  93. package/dist/src/agent/capabilities/definitions.js +2 -1
  94. package/dist/src/agent/external-tools/endpoint-provider.js +5 -1
  95. package/dist/src/agent/prompt/sections/tooling.js +5 -0
  96. package/dist/src/agent/tools/create-share-tool.js +2 -1
  97. package/dist/src/agent/tools/exec-command.js +2 -1
  98. package/dist/src/agent/tools/factory.js +2 -0
  99. package/dist/src/agent/tools/index.d.ts +1 -0
  100. package/dist/src/agent/tools/index.js +2 -1
  101. package/dist/src/agent/tools/publish-artifacts.d.ts +2 -0
  102. package/dist/src/agent/tools/publish-artifacts.js +82 -0
  103. package/dist/src/agent/tools/send-media.js +2 -1
  104. package/dist/src/cli/command-catalog.js +4 -0
  105. package/dist/src/cli/command-loaders.js +1 -0
  106. package/dist/src/cli/command-manifest.js +4 -0
  107. package/dist/src/cli/commands/auth.js +1 -1
  108. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  109. package/dist/src/cli/commands/onboard/model.js +1 -1
  110. package/dist/src/cli/commands/providers.js +1 -1
  111. package/dist/src/cli/commands/support.d.ts +1 -0
  112. package/dist/src/cli/commands/support.js +51 -0
  113. package/dist/src/endpoint-tools/binding-service.d.ts +22 -0
  114. package/dist/src/endpoint-tools/binding-service.js +45 -0
  115. package/dist/src/endpoint-tools/index.d.ts +1 -0
  116. package/dist/src/endpoint-tools/index.js +2 -1
  117. package/dist/src/endpoint-tools/invocation-service.d.ts +1 -0
  118. package/dist/src/endpoint-tools/invocation-service.js +8 -0
  119. package/dist/src/endpoint-tools/policy.d.ts +4 -1
  120. package/dist/src/endpoint-tools/policy.js +68 -5
  121. package/dist/src/endpoint-tools/registry.js +1 -1
  122. package/dist/src/endpoint-tools/runtime.d.ts +2 -0
  123. package/dist/src/endpoint-tools/runtime.js +8 -0
  124. package/dist/src/files/file-service.js +14 -5
  125. package/dist/src/gateway/chat-stream/turn-outcome-collector.js +41 -6
  126. package/dist/src/gateway/heartbeat/service.js +1 -1
  127. package/dist/src/gateway/hono/middleware/auth.js +3 -2
  128. package/dist/src/gateway/hono/routes/endpoint-tools.js +68 -1
  129. package/dist/src/gateway/hono/routes/files.js +7 -0
  130. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  131. package/dist/src/gateway/hono/routes/media.js +46 -2
  132. package/dist/src/gateway/hono/routes/support.d.ts +3 -0
  133. package/dist/src/gateway/hono/routes/support.js +28 -0
  134. package/dist/src/gateway/hono/routes/you.js +24 -0
  135. package/dist/src/heartbeat/index.js +1 -1
  136. package/dist/src/media/store.js +9 -0
  137. package/dist/src/storage/sqlite/endpoint-session-binding-repository.d.ts +8 -0
  138. package/dist/src/storage/sqlite/endpoint-session-binding-repository.js +32 -0
  139. package/dist/src/storage/sqlite/index.d.ts +1 -0
  140. package/dist/src/storage/sqlite/index.js +2 -1
  141. package/dist/src/storage/sqlite/migrations/139_turn_outcome_artifact_backfill.sql +231 -0
  142. package/dist/src/storage/sqlite/migrations/140_endpoint_session_bindings.sql +8 -0
  143. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  144. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  145. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  146. package/dist/src/storage/sqlite/schema.js +1 -1
  147. package/dist/src/support/build-support-investigation-prompt.d.ts +2 -0
  148. package/dist/src/support/build-support-investigation-prompt.js +29 -0
  149. package/dist/src/support/collect-support-report.d.ts +16 -0
  150. package/dist/src/support/collect-support-report.js +216 -0
  151. package/dist/src/support/redact-support-report.d.ts +16 -0
  152. package/dist/src/support/redact-support-report.js +89 -0
  153. package/dist/src/support/types.d.ts +76 -0
  154. package/dist/src/support/types.js +18 -0
  155. package/dist/src/user-context/user-avatar.d.ts +17 -0
  156. package/dist/src/user-context/user-avatar.js +116 -0
  157. package/package.json +2 -2
  158. package/dist/gateway/static/root/assets/apps-page-CBow8pBI.js +0 -1
  159. package/dist/gateway/static/root/assets/attachment-preview-renderer-Cmo-5BP5.js +0 -11
  160. package/dist/gateway/static/root/assets/automations-workspace-BBntVWgv.js +0 -6
  161. package/dist/gateway/static/root/assets/browser-settings-page-DrsMd-Po.js +0 -8
  162. package/dist/gateway/static/root/assets/capabilities-settings-panel-97gkGeSV.js +0 -7
  163. package/dist/gateway/static/root/assets/channels-settings-CuBsz8UI.js +0 -1
  164. package/dist/gateway/static/root/assets/connectors-page-SuL7td7Z.js +0 -2
  165. package/dist/gateway/static/root/assets/home-page-Be1o1AXQ.js +0 -1
  166. package/dist/gateway/static/root/assets/index-B2OJSXX9.js +0 -70
  167. package/dist/gateway/static/root/assets/index-rHjAElxG.css +0 -2
  168. package/dist/gateway/static/root/assets/local-app-workbench-page-COfelgk7.js +0 -2
  169. package/dist/gateway/static/root/assets/logs-page-DA8oDjeB.js +0 -2
  170. package/dist/gateway/static/root/assets/markdown-view-B-BHEcNd.js +0 -201
  171. package/dist/gateway/static/root/assets/messages-Dp1OxSKt.js +0 -3
  172. package/dist/gateway/static/root/assets/models-hub-cache-C8zjqmIv.js +0 -1
  173. package/dist/gateway/static/root/assets/notes-workbench-DICgUGPv.js +0 -4
  174. package/dist/gateway/static/root/assets/project-detail-page-CqdkznYJ.js +0 -1
  175. package/dist/gateway/static/root/assets/remote-access-hub-2feZudJw.js +0 -1
  176. package/dist/gateway/static/root/assets/sessions-page-CO2JCFdy.js +0 -1
  177. package/dist/gateway/static/root/assets/settings-advanced-gate-DxMVaqdn.js +0 -1
  178. package/dist/gateway/static/root/assets/setup-status-panel-DZNHb6A5.js +0 -1
  179. package/dist/gateway/static/root/assets/shares-settings-DakZ2AGN.js +0 -1
  180. package/dist/gateway/static/root/assets/skill-reload-api-BOiNkWJC.js +0 -1
  181. package/dist/gateway/static/root/assets/task-detail-page-D5Nbe3C8.js +0 -1
  182. package/dist/gateway/static/root/assets/user-context-page-CAPSUK8B.js +0 -1
  183. package/dist/gateway/static/root/assets/workflows-page-ahDvypGO.js +0 -5
@@ -0,0 +1,216 @@
1
+ import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
2
+ import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
3
+ import { init_paths, resolveConfigPath } from "../config/paths.js";
4
+ import { collectDoctorResults } from "../cli/commands/doctor/flow.js";
5
+ import { queryLogs } from "../utils/logger/log-store.js";
6
+ import { SupportRedactor } from "./redact-support-report.js";
7
+ import { homedir } from "node:os";
8
+ //#region src/support/collect-support-report.ts
9
+ init_paths();
10
+ init_paths_state();
11
+ init_package_version();
12
+ const LOG_WINDOW_MS = 300 * 1e3;
13
+ const MAX_OCCURRED_AGE_MS = 10080 * 60 * 1e3;
14
+ const MAX_LOGS = 100;
15
+ function occurredAt(input, now) {
16
+ const parsed = input ? new Date(input) : now;
17
+ if (Number.isNaN(parsed.getTime())) return now;
18
+ const timestamp = Math.min(now.getTime(), Math.max(now.getTime() - MAX_OCCURRED_AGE_MS, parsed.getTime()));
19
+ return new Date(timestamp);
20
+ }
21
+ function asRecord(value) {
22
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
23
+ }
24
+ function sanitizeDoctorCheck(check, redactor) {
25
+ return {
26
+ id: check.id,
27
+ label: redactor.text(check.label, 500) ?? "",
28
+ status: check.status,
29
+ message: redactor.text(check.message, 2e3) ?? "",
30
+ hints: check.hints.slice(0, 10).map((hint) => redactor.text(hint, 2e3) ?? "")
31
+ };
32
+ }
33
+ function sanitizeLogEntry(entry, redactor) {
34
+ redactor.addIdentifier(entry.requestId, "request");
35
+ redactor.addIdentifier(entry.sessionKey, "session");
36
+ redactor.addIdentifier(entry.sessionId, "session");
37
+ const meta = asRecord(entry.meta);
38
+ const error = asRecord(entry.err) ?? asRecord(meta?.err);
39
+ const phase = typeof entry.phase === "string" ? entry.phase : typeof meta?.phase === "string" ? meta.phase : void 0;
40
+ const sanitizedError = error ? {
41
+ name: redactor.text(typeof error.name === "string" ? error.name : void 0, 300),
42
+ message: redactor.text(typeof error.message === "string" ? error.message : void 0, 2e3),
43
+ stack: redactor.text(typeof error.stack === "string" ? error.stack : void 0, 6e3)
44
+ } : void 0;
45
+ return {
46
+ timestamp: entry.timestamp,
47
+ level: entry.level,
48
+ message: redactor.text(entry.message, 4e3) ?? "",
49
+ module: redactor.text(entry.module, 300),
50
+ phase: redactor.text(phase, 300),
51
+ requestId: redactor.identifier(entry.requestId, "request"),
52
+ sessionId: redactor.identifier(entry.sessionId, "session"),
53
+ ...sanitizedError && Object.values(sanitizedError).some(Boolean) ? { error: sanitizedError } : {}
54
+ };
55
+ }
56
+ async function collectRelevantLogs(params) {
57
+ const base = {
58
+ levels: [
59
+ "warn",
60
+ "error",
61
+ "fatal"
62
+ ],
63
+ from: params.from.toISOString(),
64
+ to: params.to.toISOString(),
65
+ limit: MAX_LOGS,
66
+ order: "asc"
67
+ };
68
+ if (params.input.requestId) {
69
+ const logs = await params.query({
70
+ ...base,
71
+ requestId: params.input.requestId
72
+ });
73
+ if (logs.length > 0) return logs;
74
+ }
75
+ if (params.input.sessionKey) {
76
+ const logs = await params.query({
77
+ ...base,
78
+ sessionKey: params.input.sessionKey
79
+ });
80
+ if (logs.length > 0) return logs;
81
+ }
82
+ if (params.input.requestId || params.input.sessionKey) return [];
83
+ return params.query(base);
84
+ }
85
+ function codeBlock(value) {
86
+ return value.replace(/```/g, "``​`");
87
+ }
88
+ function formatMarkdown(report) {
89
+ const relevantChecks = report.doctor.filter((check) => check.status !== "pass");
90
+ const lines = [
91
+ `# ${report.title}`,
92
+ "",
93
+ "## 问题描述",
94
+ "",
95
+ report.problem
96
+ ];
97
+ if (report.reproduction) lines.push("", "## 复现步骤", "", report.reproduction);
98
+ if (report.expected) lines.push("", "## 期望结果", "", report.expected);
99
+ lines.push("", "## 环境信息", "", `- xopc: ${report.environment.xopcVersion}`, `- Node.js: ${report.environment.nodeVersion}`, `- 系统: ${report.environment.platform}-${report.environment.arch}`, `- 问题时间: ${report.occurredAt}`, `- 采集时间: ${report.capturedAt}`);
100
+ if (report.environment.surface) lines.push(`- 入口: ${report.environment.surface}`);
101
+ if (report.environment.currentPage) lines.push(`- 页面: ${report.environment.currentPage}`);
102
+ if (report.runtime?.gatewayStatus) lines.push(`- Gateway: ${report.runtime.gatewayStatus}`);
103
+ lines.push("", "## Doctor 结果", "");
104
+ if (relevantChecks.length === 0) lines.push("- 未发现警告或失败项。");
105
+ else for (const check of relevantChecks) {
106
+ lines.push(`- [${check.status.toUpperCase()}] ${check.label}: ${check.message}`);
107
+ for (const hint of check.hints) lines.push(` - ${hint}`);
108
+ }
109
+ lines.push("", "## 相关日志", "");
110
+ if (report.logs.length === 0) lines.push("指定时间范围内没有匹配的 warn/error/fatal 日志。");
111
+ else {
112
+ lines.push("```text");
113
+ for (const entry of report.logs) {
114
+ const context = [entry.module, entry.phase].filter(Boolean).join("/");
115
+ lines.push(codeBlock(`[${entry.timestamp}] ${entry.level.toUpperCase()}${context ? ` ${context}` : ""} ${entry.message}`));
116
+ if (entry.error?.message && entry.error.message !== entry.message) lines.push(codeBlock(` ${entry.error.name ? `${entry.error.name}: ` : ""}${entry.error.message}`));
117
+ }
118
+ lines.push("```");
119
+ }
120
+ if (report.rendererError) lines.push("", "## 前端错误", "", "```text", codeBlock(report.rendererError), "```");
121
+ lines.push("", "## 隐私说明", "", `报告已执行自动脱敏,共替换 ${report.redaction.replacements} 处敏感标识或路径;未包含配置原文、凭据、数据库或会话正文。`);
122
+ return lines.join("\n");
123
+ }
124
+ function titleFromProblem(problem) {
125
+ return `[Bug] ${(problem.split(/\r?\n/, 1)[0]?.trim() || "xopc 使用问题").slice(0, 80)}`;
126
+ }
127
+ async function collectSupportReport(input, deps = {}) {
128
+ const now = deps.now?.() ?? /* @__PURE__ */ new Date();
129
+ const issueTime = occurredAt(input.occurredAt, now);
130
+ const from = new Date(issueTime.getTime() - LOG_WINDOW_MS);
131
+ const to = new Date(Math.min(now.getTime(), issueTime.getTime() + LOG_WINDOW_MS));
132
+ const stateDir = deps.paths?.stateDir ?? resolveStateDir();
133
+ const redactor = new SupportRedactor({
134
+ homeDir: deps.paths?.homeDir ?? homedir(),
135
+ stateDir,
136
+ workspaceDir: deps.paths?.workspaceDir
137
+ });
138
+ const doctorContext = {
139
+ configPath: deps.paths?.configPath ?? resolveConfigPath(),
140
+ stateDir,
141
+ options: {
142
+ fix: false,
143
+ json: true,
144
+ deep: false,
145
+ security: false
146
+ }
147
+ };
148
+ redactor.addIdentifier(input.requestId, "request");
149
+ redactor.addIdentifier(input.sessionKey, "session");
150
+ let rawLogs = [];
151
+ let logCollectionError;
152
+ try {
153
+ rawLogs = await collectRelevantLogs({
154
+ input,
155
+ from,
156
+ to,
157
+ query: deps.queryLogs ?? queryLogs
158
+ });
159
+ } catch (error) {
160
+ logCollectionError = error instanceof Error ? error.message : String(error);
161
+ }
162
+ let doctorResults;
163
+ try {
164
+ doctorResults = await (deps.collectDoctor ?? collectDoctorResults)(doctorContext);
165
+ } catch (error) {
166
+ doctorResults = [{
167
+ id: "support-doctor-collection",
168
+ label: "Doctor collection",
169
+ status: "warn",
170
+ message: error instanceof Error ? error.message : String(error),
171
+ hints: []
172
+ }];
173
+ }
174
+ if (logCollectionError) doctorResults.push({
175
+ id: "support-log-collection",
176
+ label: "Log collection",
177
+ status: "warn",
178
+ message: logCollectionError,
179
+ hints: []
180
+ });
181
+ const problem = redactor.text(input.problem, 1e4) ?? "";
182
+ const base = {
183
+ schemaVersion: 1,
184
+ title: titleFromProblem(problem),
185
+ capturedAt: now.toISOString(),
186
+ occurredAt: issueTime.toISOString(),
187
+ problem,
188
+ expected: redactor.text(input.expected, 5e3),
189
+ reproduction: redactor.text(input.reproduction, 1e4),
190
+ environment: {
191
+ xopcVersion: PACKAGE_VERSION,
192
+ nodeVersion: process.version,
193
+ platform: process.platform,
194
+ arch: process.arch,
195
+ surface: input.clientContext?.surface,
196
+ currentPage: redactor.text(input.clientContext?.currentPage, 2e3),
197
+ userAgent: redactor.text(input.clientContext?.userAgent, 2e3)
198
+ },
199
+ runtime: deps.runtime,
200
+ rendererError: redactor.text(input.clientContext?.rendererError, 2e4),
201
+ doctor: doctorResults.map((check) => sanitizeDoctorCheck(check, redactor)),
202
+ logs: rawLogs.map((entry) => sanitizeLogEntry(entry, redactor)),
203
+ logWindow: {
204
+ from: from.toISOString(),
205
+ to: to.toISOString()
206
+ },
207
+ redaction: { replacements: 0 }
208
+ };
209
+ base.redaction.replacements = redactor.replacements;
210
+ return {
211
+ ...base,
212
+ markdown: formatMarkdown(base)
213
+ };
214
+ }
215
+ //#endregion
216
+ export { collectSupportReport };
@@ -0,0 +1,16 @@
1
+ export declare class SupportRedactor {
2
+ private replacementCount;
3
+ private readonly pathAliases;
4
+ private readonly identifierAliases;
5
+ constructor(paths?: {
6
+ homeDir?: string;
7
+ stateDir?: string;
8
+ workspaceDir?: string;
9
+ });
10
+ get replacements(): number;
11
+ addIdentifier(raw: string | undefined, namespace: string): void;
12
+ text(raw: string | undefined, maxLength?: number): string | undefined;
13
+ identifier(raw: string | undefined, namespace: string): string | undefined;
14
+ private identifierValue;
15
+ private replace;
16
+ }
@@ -0,0 +1,89 @@
1
+ import { createHash } from "node:crypto";
2
+ //#region src/support/redact-support-report.ts
3
+ const SECRET_PATTERNS = [
4
+ /(\b[A-Z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|AUTHORIZATION)\b["']?\s*[=:]\s*)(["']?)[^\s,"'}]+\2/gi,
5
+ /(Authorization\s*[:=]\s*Bearer\s+)[A-Za-z0-9._\-+=]+/gi,
6
+ /\b(?:sk-[A-Za-z0-9_-]{8,}|ghp_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}|xox[baprs]-[A-Za-z0-9-]+|\d+:[A-Za-z0-9_-]{35,})\b/gi,
7
+ /(-----BEGIN\s+\w+\s+PRIVATE KEY-----)[\s\S]*?(-----END\s+\w+\s+PRIVATE KEY-----)/g
8
+ ];
9
+ function escapeRegExp(value) {
10
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11
+ }
12
+ function normalizedRoots(roots) {
13
+ return [...new Set(roots.map((root) => root.trim()).filter(Boolean))].sort((left, right) => right.length - left.length);
14
+ }
15
+ var SupportRedactor = class {
16
+ replacementCount = 0;
17
+ pathAliases;
18
+ identifierAliases = [];
19
+ constructor(paths = {}) {
20
+ const aliases = [
21
+ {
22
+ value: paths.workspaceDir,
23
+ alias: "<WORKSPACE>"
24
+ },
25
+ {
26
+ value: paths.stateDir,
27
+ alias: "<STATE_DIR>"
28
+ },
29
+ {
30
+ value: paths.homeDir,
31
+ alias: "<HOME>"
32
+ }
33
+ ].filter((item) => Boolean(item.value?.trim()));
34
+ this.pathAliases = normalizedRoots(aliases.map((item) => item.value)).map((root) => ({
35
+ pattern: new RegExp(escapeRegExp(root), "g"),
36
+ alias: aliases.find((item) => item.value === root)?.alias ?? "<PATH>"
37
+ }));
38
+ }
39
+ get replacements() {
40
+ return this.replacementCount;
41
+ }
42
+ addIdentifier(raw, namespace) {
43
+ if (!raw) return;
44
+ const source = escapeRegExp(raw);
45
+ if (this.identifierAliases.some((item) => item.pattern.source === source)) return;
46
+ this.identifierAliases.push({
47
+ pattern: new RegExp(source, "g"),
48
+ alias: this.identifierValue(raw, namespace)
49
+ });
50
+ }
51
+ text(raw, maxLength = 8e3) {
52
+ if (!raw) return void 0;
53
+ let value = raw.slice(0, maxLength);
54
+ for (const { pattern, alias } of this.pathAliases) value = this.replace(value, pattern, alias);
55
+ for (const { pattern, alias } of this.identifierAliases) value = this.replace(value, pattern, alias);
56
+ value = this.replace(value, /\/(?:Users|home)\/[^/\s]+/g, "<HOME>");
57
+ value = this.replace(value, /[A-Za-z]:\\Users\\[^\\\s]+/g, "<HOME>");
58
+ value = this.replace(value, /https?:\/\/[^\s<>{}"']+/g, (match) => {
59
+ const rawUrl = String(match);
60
+ try {
61
+ const url = new URL(rawUrl);
62
+ return `${url.origin}${url.pathname}`;
63
+ } catch {
64
+ return rawUrl;
65
+ }
66
+ });
67
+ for (const pattern of SECRET_PATTERNS) value = this.replace(value, pattern, (...args) => {
68
+ if (String(args[0]).includes("PRIVATE KEY-----")) return `${typeof args[1] === "string" ? args[1] : "-----BEGIN PRIVATE KEY-----"}\n[REDACTED]\n${typeof args[2] === "string" ? args[2] : "-----END PRIVATE KEY-----"}`;
69
+ return `${typeof args[1] === "string" && args[1] ? args[1] : ""}[REDACTED]`;
70
+ });
71
+ return value;
72
+ }
73
+ identifier(raw, namespace) {
74
+ if (!raw) return void 0;
75
+ this.replacementCount += 1;
76
+ return this.identifierValue(raw, namespace);
77
+ }
78
+ identifierValue(raw, namespace) {
79
+ return `${namespace}_${createHash("sha256").update(`${namespace}:${raw}`).digest("hex").slice(0, 12)}`;
80
+ }
81
+ replace(value, pattern, replacement) {
82
+ return value.replace(pattern, (...args) => {
83
+ this.replacementCount += 1;
84
+ return typeof replacement === "string" ? replacement : replacement(...args);
85
+ });
86
+ }
87
+ };
88
+ //#endregion
89
+ export { SupportRedactor };
@@ -0,0 +1,76 @@
1
+ import { z } from 'zod';
2
+ export declare const SupportReportInputSchema: z.ZodObject<{
3
+ problem: z.ZodString;
4
+ expected: z.ZodOptional<z.ZodString>;
5
+ reproduction: z.ZodOptional<z.ZodString>;
6
+ occurredAt: z.ZodOptional<z.ZodString>;
7
+ sessionKey: z.ZodOptional<z.ZodString>;
8
+ requestId: z.ZodOptional<z.ZodString>;
9
+ clientContext: z.ZodOptional<z.ZodObject<{
10
+ currentPage: z.ZodOptional<z.ZodString>;
11
+ rendererError: z.ZodOptional<z.ZodString>;
12
+ surface: z.ZodOptional<z.ZodEnum<{
13
+ electron: "electron";
14
+ web: "web";
15
+ }>>;
16
+ userAgent: z.ZodOptional<z.ZodString>;
17
+ }, z.core.$strict>>;
18
+ }, z.core.$strict>;
19
+ export type SupportReportInput = z.infer<typeof SupportReportInputSchema>;
20
+ export type SupportDoctorCheck = {
21
+ id: string;
22
+ label: string;
23
+ status: 'pass' | 'warn' | 'fail' | 'skip';
24
+ message: string;
25
+ hints: string[];
26
+ };
27
+ export type SupportLogEntry = {
28
+ timestamp: string;
29
+ level: string;
30
+ message: string;
31
+ module?: string;
32
+ phase?: string;
33
+ requestId?: string;
34
+ sessionId?: string;
35
+ error?: {
36
+ name?: string;
37
+ message?: string;
38
+ stack?: string;
39
+ };
40
+ };
41
+ export type SupportRuntimeSnapshot = {
42
+ gatewayStatus?: string;
43
+ gatewayVersion?: string;
44
+ gatewayUptimeMs?: number;
45
+ channels?: Record<string, string>;
46
+ };
47
+ export type SupportReport = {
48
+ schemaVersion: 1;
49
+ title: string;
50
+ capturedAt: string;
51
+ occurredAt: string;
52
+ problem: string;
53
+ expected?: string;
54
+ reproduction?: string;
55
+ environment: {
56
+ xopcVersion: string;
57
+ nodeVersion: string;
58
+ platform: NodeJS.Platform;
59
+ arch: string;
60
+ surface?: 'web' | 'electron';
61
+ currentPage?: string;
62
+ userAgent?: string;
63
+ };
64
+ runtime?: SupportRuntimeSnapshot;
65
+ rendererError?: string;
66
+ doctor: SupportDoctorCheck[];
67
+ logs: SupportLogEntry[];
68
+ logWindow: {
69
+ from: string;
70
+ to: string;
71
+ };
72
+ redaction: {
73
+ replacements: number;
74
+ };
75
+ markdown: string;
76
+ };
@@ -0,0 +1,18 @@
1
+ import { z } from "zod";
2
+ //#region src/support/types.ts
3
+ const SupportReportInputSchema = z.object({
4
+ problem: z.string().trim().min(1).max(1e4),
5
+ expected: z.string().trim().max(5e3).optional(),
6
+ reproduction: z.string().trim().max(1e4).optional(),
7
+ occurredAt: z.string().datetime().optional(),
8
+ sessionKey: z.string().trim().max(1e3).optional(),
9
+ requestId: z.string().trim().max(1e3).optional(),
10
+ clientContext: z.object({
11
+ currentPage: z.string().trim().max(2e3).optional(),
12
+ rendererError: z.string().trim().max(2e4).optional(),
13
+ surface: z.enum(["web", "electron"]).optional(),
14
+ userAgent: z.string().trim().max(2e3).optional()
15
+ }).strict().optional()
16
+ }).strict();
17
+ //#endregion
18
+ export { SupportReportInputSchema };
@@ -0,0 +1,17 @@
1
+ export declare const USER_AVATAR_MAX_BYTES: number;
2
+ type UserAvatarMime = 'image/png' | 'image/jpeg' | 'image/webp';
3
+ export type UserAvatarResult<T> = {
4
+ ok: true;
5
+ data: T;
6
+ } | {
7
+ ok: false;
8
+ error: string;
9
+ status: 400 | 404;
10
+ };
11
+ export declare function readUserAvatar(): Promise<UserAvatarResult<{
12
+ buffer: Buffer;
13
+ contentType: UserAvatarMime;
14
+ }>>;
15
+ export declare function writeUserAvatar(base64: string, mimeType: string): Promise<UserAvatarResult<{}>>;
16
+ export declare function deleteUserAvatar(): Promise<UserAvatarResult<{}>>;
17
+ export {};
@@ -0,0 +1,116 @@
1
+ import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
2
+ import { join } from "node:path";
3
+ import { mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
4
+ //#region src/user-context/user-avatar.ts
5
+ init_paths_state();
6
+ const USER_AVATAR_MAX_BYTES = 2 * 1024 * 1024;
7
+ const USER_AVATAR_DIR = "profile";
8
+ const USER_AVATAR_BASENAME = "user-avatar";
9
+ const USER_AVATAR_EXTENSIONS = [
10
+ ".png",
11
+ ".jpg",
12
+ ".webp"
13
+ ];
14
+ function avatarRoot() {
15
+ return join(resolveStateDir(), USER_AVATAR_DIR);
16
+ }
17
+ function avatarFilenames() {
18
+ return USER_AVATAR_EXTENSIONS.map((extension) => `${USER_AVATAR_BASENAME}${extension}`);
19
+ }
20
+ function mimeToExtension(mimeType) {
21
+ const normalized = mimeType.toLowerCase().trim();
22
+ if (normalized === "image/png") return ".png";
23
+ if (normalized === "image/jpeg" || normalized === "image/jpg") return ".jpg";
24
+ if (normalized === "image/webp") return ".webp";
25
+ return null;
26
+ }
27
+ function extensionToMime(extension) {
28
+ if (extension === ".png") return "image/png";
29
+ if (extension === ".webp") return "image/webp";
30
+ return "image/jpeg";
31
+ }
32
+ function detectImageMime(buffer) {
33
+ if (buffer.length >= 8 && buffer[0] === 137 && buffer[1] === 80 && buffer[2] === 78 && buffer[3] === 71) return "image/png";
34
+ if (buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255) return "image/jpeg";
35
+ if (buffer.length >= 12 && buffer[0] === 82 && buffer[1] === 73 && buffer[2] === 70 && buffer[3] === 70 && buffer[8] === 87 && buffer[9] === 69 && buffer[10] === 66 && buffer[11] === 80) return "image/webp";
36
+ return null;
37
+ }
38
+ async function readUserAvatar() {
39
+ const root = avatarRoot();
40
+ for (const filename of avatarFilenames()) {
41
+ const path = join(root, filename);
42
+ try {
43
+ const metadata = await stat(path);
44
+ if (!metadata.isFile() || metadata.size <= 0 || metadata.size > 2097152) continue;
45
+ const buffer = await readFile(path);
46
+ const contentType = detectImageMime(buffer);
47
+ if (!contentType) continue;
48
+ return {
49
+ ok: true,
50
+ data: {
51
+ buffer,
52
+ contentType
53
+ }
54
+ };
55
+ } catch {}
56
+ }
57
+ return {
58
+ ok: false,
59
+ error: "avatar not found",
60
+ status: 404
61
+ };
62
+ }
63
+ async function writeUserAvatar(base64, mimeType) {
64
+ const extension = mimeToExtension(mimeType);
65
+ if (!extension) return {
66
+ ok: false,
67
+ error: "unsupported mimeType (use image/png, image/jpeg, or image/webp)",
68
+ status: 400
69
+ };
70
+ if (!base64 || !/^[A-Za-z0-9+/]*={0,2}$/.test(base64)) return {
71
+ ok: false,
72
+ error: "invalid base64",
73
+ status: 400
74
+ };
75
+ const buffer = Buffer.from(base64, "base64");
76
+ if (buffer.length === 0 || buffer.length > 2097152) return {
77
+ ok: false,
78
+ error: `avatar must be non-empty and at most ${USER_AVATAR_MAX_BYTES} bytes`,
79
+ status: 400
80
+ };
81
+ const detectedMime = detectImageMime(buffer);
82
+ if (!detectedMime || detectedMime !== extensionToMime(extension)) return {
83
+ ok: false,
84
+ error: "file content does not match declared image type",
85
+ status: 400
86
+ };
87
+ const root = avatarRoot();
88
+ await mkdir(root, {
89
+ recursive: true,
90
+ mode: 448
91
+ });
92
+ const targetFilename = `${USER_AVATAR_BASENAME}${extension}`;
93
+ for (const filename of avatarFilenames()) {
94
+ if (filename === targetFilename) continue;
95
+ try {
96
+ await unlink(join(root, filename));
97
+ } catch {}
98
+ }
99
+ await writeFile(join(root, targetFilename), buffer, { mode: 384 });
100
+ return {
101
+ ok: true,
102
+ data: {}
103
+ };
104
+ }
105
+ async function deleteUserAvatar() {
106
+ const root = avatarRoot();
107
+ for (const filename of avatarFilenames()) try {
108
+ await unlink(join(root, filename));
109
+ } catch {}
110
+ return {
111
+ ok: true,
112
+ data: {}
113
+ };
114
+ }
115
+ //#endregion
116
+ export { USER_AVATAR_MAX_BYTES, deleteUserAvatar, readUserAvatar, writeUserAvatar };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xopcai/xopc",
3
- "version": "0.0.232",
3
+ "version": "0.0.233",
4
4
  "description": "Local-first personal AI assistant with reviewable user understanding, durable tasks, workflows, automations, and local or cloud models.",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -163,9 +163,9 @@
163
163
  "vitepress": "^1.6.4",
164
164
  "vitest": "4.1.5",
165
165
  "vue": "^3.5.35",
166
- "@xopcai/endpoint-tools-protocol": "0.0.0",
167
166
  "@xopcai/gateway-contract": "0.0.0",
168
167
  "@xopcai/realtime-protocol": "0.0.0",
168
+ "@xopcai/endpoint-tools-protocol": "0.0.0",
169
169
  "@xopcai/realtime-client": "0.0.0"
170
170
  },
171
171
  "scripts": {
@@ -1 +0,0 @@
1
- import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{a as t,n,t as r}from"./vendor-react-BOUWij0V.js";import{p as i,t as a}from"./chunk-KS7C4IRE-BaASWQor.js";import{t as o}from"./check-DUBLcKHA.js";import{t as s}from"./external-link-DjqjBmc3.js";import{t as c}from"./markdown-view-B-BHEcNd.js";import{t as l}from"./loader-circle-CifKLtgG.js";import{t as u}from"./plus-Q2yW6OE7.js";import{t as d}from"./search-DA7gz22f.js";import{t as f}from"./x-B_N4OPjy.js";import{t as p}from"./cn-JdwAhgNB.js";import{t as m}from"./button-CSEbl4zT.js";import{t as h}from"./messages-Dp1OxSKt.js";import{a as g,i as _,n as v,r as y,s as b}from"./locale-store-DLwVxS3V.js";import{a as x,i as S,o as C,r as w,s as T,t as E}from"./dist-BPoKqzeH.js";import{a as D,i as O}from"./vendor-swr-BIWyz7Rc.js";import{Ds as k,Fo as A,Io as j,Oa as M,Ta as N,_a as P,ba as F,ha as I,il as L,is as R,ml as ee,oa as z,pa as B,qc as V,ts as te,va as H,ya as U}from"./index-B2OJSXX9.js";import{t as W}from"./page-tabs-BaEQMYm_.js";var G=e(t(),1),ne=n();function K(e){return e===`builtin`||e===`user`?e:`marketplace`}async function q(e){try{let t=await e.json();if(typeof t.error==`string`)return t.error;if(t.error&&typeof t.error==`object`&&typeof t.error.message==`string`)return t.error.message;if(typeof t.message==`string`)return t.message}catch{}return e.statusText||`HTTP ${e.status}`}async function re(e){let t=await _(y(`/api/marketplace/packages/${encodeURIComponent(e.trim())}`),{cache:`no-store`});if(!t.ok)throw Error(await q(t));let n=await t.json();if(!n.ok||!n.payload?.id)throw Error(n.error??`Invalid response`);return n.payload}async function J(e){let t=await _(y(`/api/marketplace/install`),{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});if(!t.ok)throw Error(await q(t));let n=await t.json();if(!n.ok||!n.payload?.extensionId)throw Error(n.error??`Invalid response`);return n.payload}async function Y(e){let t=await _(y(`/api/extensions/bundled/activation`),{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({extensionId:e.extensionId.trim(),enabled:e.enabled})});if(!t.ok)throw Error(await q(t));let n=await t.json();if(!n.ok||!n.payload)throw Error(n.error?.message??`Invalid response`);return n.payload}async function X(e){let t=await _(y(`/api/marketplace/uninstall`),{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({extensionId:e})});if(!t.ok)throw Error(await q(t));let n=await t.json();if(!n.ok||!n.payload)throw Error(n.error??`Invalid response`);return n.payload}var Z=r();function ie(e,t){let n=e.find(e=>e.id===t);return n?n.source===`bundled`?`bundled`:`user`:`absent`}var Q={q:``,debounced:``,detailPkg:null,rowBusy:null,actionError:null,restartHint:null};function $({className:e}){let t=h(v(e=>e.language)).extensionsPage,n=b(e=>!!e.token),r=P(),{mutate:i}=D(),[a,o]=(0,G.useReducer)(z,Q),{q:s,debounced:c,detailPkg:u,rowBusy:f,actionError:m,restartHint:_}=a,x=n?`marketplace-${c}`:null;(0,G.useEffect)(()=>{let e=window.setTimeout(()=>o({type:`patch`,patch:{debounced:s.trim()}}),300);return()=>window.clearTimeout(e)},[s]);let{data:S,isLoading:C,error:w}=O(x,async()=>g(c.length>0?y(`/api/marketplace?q=${encodeURIComponent(c)}`):y(`/api/marketplace`)),{revalidateOnFocus:!1}),T=(0,G.useCallback)(()=>{i(`gateway-extensions-list`),N()},[i]),E=(0,G.useCallback)(async(e,n)=>{o({type:`patch`,patch:{actionError:null,restartHint:null,rowBusy:e}});try{let r=await J({name:e,overwrite:n});T(),r.requiresGatewayRestart&&o({type:`patch`,patch:{restartHint:t.marketplaceRestartHint}})}catch(e){throw o({type:`patch`,patch:{actionError:e instanceof Error?e.message:t.marketplaceInstallFailed}}),e}finally{o({type:`patch`,patch:{rowBusy:null}})}},[t.marketplaceInstallFailed,t.marketplaceRestartHint,T]),A=(0,G.useCallback)(async e=>{o({type:`patch`,patch:{actionError:null,restartHint:null,rowBusy:e}});try{let n=await X(e);T(),n.requiresGatewayRestart&&o({type:`patch`,patch:{restartHint:t.marketplaceRestartHint}})}catch(e){throw o({type:`patch`,patch:{actionError:e instanceof Error?e.message:t.marketplaceUninstallFailed}}),e}finally{o({type:`patch`,patch:{rowBusy:null}})}},[t.marketplaceRestartHint,t.marketplaceUninstallFailed,T]),M=S?.extensions??[];return(0,Z.jsxs)(`div`,{className:p(`flex flex-col gap-4`,e),children:[(0,Z.jsxs)(`div`,{className:`relative`,children:[(0,Z.jsx)(d,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-fg-muted`,strokeWidth:1.75,"aria-hidden":!0}),(0,Z.jsx)(`input`,{type:`search`,value:s,onChange:e=>o({type:`patch`,patch:{q:e.target.value}}),placeholder:t.marketplaceSearchPlaceholder,className:`ui-input h-10 w-full rounded-lg border border-edge bg-surface-base pl-9 pr-3 text-sm text-fg placeholder:text-fg-muted`})]}),w?(0,Z.jsx)(`p`,{className:`text-sm text-fg-muted`,children:w instanceof Error?w.message:t.marketplaceLoadFailed}):null,m?(0,Z.jsx)(`p`,{className:`text-sm text-red-600 dark:text-red-400`,children:m}):null,_?(0,Z.jsx)(`p`,{className:`text-sm text-fg-muted`,children:_}):null,C&&!S?(0,Z.jsx)(`ul`,{className:`flex flex-col gap-3`,"aria-label":t.marketplaceLoading,children:[0,1,2].map(e=>(0,Z.jsx)(`li`,{className:`rounded-xl bg-surface-panel p-4 shadow-surface`,children:(0,Z.jsxs)(`div`,{className:`flex items-start justify-between gap-4`,children:[(0,Z.jsxs)(`div`,{className:`min-w-0 flex-1 space-y-2.5`,children:[(0,Z.jsx)(B,{className:`h-5 w-40`}),(0,Z.jsx)(B,{className:`h-4 w-full max-w-xl`}),(0,Z.jsx)(B,{className:`h-4 w-2/3 max-w-md`})]}),(0,Z.jsx)(B,{className:`h-8 w-20`})]})},e))}):(0,Z.jsx)(`ul`,{className:`flex flex-col gap-3`,children:M.length===0?(0,Z.jsx)(`li`,{className:`text-sm text-fg-muted`,children:t.marketplaceEmpty}):M.map(e=>{let n=ie(r,e.id),i=f===e.id;return(0,Z.jsx)(`li`,{className:`list-none`,children:(0,Z.jsxs)(`div`,{role:`button`,tabIndex:0,"aria-label":`${e.name}, ${t.marketplaceDetailTitle}`,onClick:()=>o({type:`patch`,patch:{detailPkg:e.id}}),onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),o({type:`patch`,patch:{detailPkg:e.id}}))},className:p(`flex w-full cursor-pointer flex-wrap items-start gap-3 rounded-xl bg-surface-panel p-4 text-left shadow-surface`,`transition-[transform,background-color,box-shadow] duration-150 ease-out`,`hover:bg-surface-hover/40`,`active:scale-[0.992] active:bg-surface-hover/55`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel`,`dark:hover:bg-surface-hover/25 dark:active:bg-surface-hover/35`),children:[(0,Z.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Z.jsx)(`h3`,{className:`font-semibold text-fg`,children:e.name}),e.verified?(0,Z.jsx)(V,{className:`size-4 shrink-0 text-emerald-600 dark:text-emerald-400`,strokeWidth:1.75,"aria-label":`Verified`}):null,e.version?(0,Z.jsx)(`span`,{className:`text-xs text-fg-muted`,children:e.version}):null]}),e.description?(0,Z.jsx)(`p`,{className:`mt-1 line-clamp-2 text-sm text-fg-muted`,children:e.description}):null,(0,Z.jsx)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:(e.categories??[]).map(e=>(0,Z.jsx)(`span`,{className:`rounded-md border border-edge bg-surface-panel px-2 py-0.5 text-[11px] text-fg-muted`,children:e},e))}),(0,Z.jsxs)(`p`,{className:`mt-2 flex items-center gap-1.5 text-xs text-fg-muted`,children:[(0,Z.jsx)(k,{className:`size-3.5 shrink-0`,strokeWidth:1.75,"aria-hidden":!0}),(0,Z.jsx)(`code`,{className:`rounded bg-surface-panel px-1 py-0.5`,children:e.npmPackage})]})]}),(0,Z.jsx)(`div`,{role:`group`,className:`flex shrink-0 flex-col items-end gap-2 sm:min-w-[9rem]`,onClick:e=>e.stopPropagation(),onKeyDown:e=>e.stopPropagation(),children:n===`bundled`?(0,Z.jsx)(`span`,{className:`rounded-md bg-surface-hover px-2 py-1 text-[11px] font-medium text-fg-muted`,children:t.marketplaceBuiltin}):n===`user`?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`span`,{className:`text-[11px] font-medium text-fg-muted`,children:t.marketplaceInstalled}),(0,Z.jsxs)(`button`,{type:`button`,disabled:i,onClick:()=>{window.confirm(t.marketplaceUninstallConfirm)&&A(e.id).catch(()=>{})},className:p(`inline-flex items-center justify-center gap-1.5 rounded-lg border border-edge px-3 py-2 text-xs font-medium text-fg`,`transition-colors active:scale-[0.98] active:bg-surface-hover/80`,`hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,`disabled:pointer-events-none disabled:opacity-50`),children:[i?(0,Z.jsx)(l,{className:`size-3.5 animate-spin`,"aria-hidden":!0}):(0,Z.jsx)(j,{className:`size-3.5`,strokeWidth:2,"aria-hidden":!0}),t.marketplaceUninstall]})]}):(0,Z.jsx)(`button`,{type:`button`,onClick:()=>o({type:`patch`,patch:{detailPkg:e.id}}),className:p(`inline-flex w-full items-center justify-center rounded-lg border border-edge px-3 py-2 text-xs font-medium text-fg`,`transition-[transform,background-color] active:scale-[0.98]`,`hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`),children:t.marketplaceReview})})]})},e.id)})}),u?(0,Z.jsx)(ae,{packageName:u,copy:t,extensions:r,onClose:()=>o({type:`patch`,patch:{detailPkg:null}}),onInstall:E,onUninstall:A}):null]})}function ae(e){let t=(0,ne.c)(102),{packageName:n,copy:r,extensions:i,onClose:o,onInstall:s,onUninstall:u}=e,[d,m]=(0,G.useState)(!1),[h,g]=(0,G.useState)(!1),_=b(ue)?`ext-mp-detail-${n}`:null,v;t[0]===n?v=t[1]:(v=async()=>re(n),t[0]=n,t[1]=v);let y;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(y={revalidateOnFocus:!1},t[2]=y):y=t[2];let{data:S,error:D,isLoading:k}=O(_,v,y),M;t[3]!==i||t[4]!==n?(M=ie(i,n),t[3]=i,t[4]=n,t[5]=M):M=t[5];let N=M,P=N===`user`,F=S?.manifest?.permissions,I,L,R,z,V,H,U,W,K,q,J;if(t[6]!==r.detailBack||t[7]!==r.detailClose||t[8]!==r.marketplaceAuthor||t[9]!==r.marketplaceCodeRisk||t[10]!==r.marketplaceDependencies||t[11]!==r.marketplaceDetailLoadFailed||t[12]!==r.marketplaceDetailReadmeHeading||t[13]!==r.marketplaceDetailTitle||t[14]!==r.marketplaceDownloads||t[15]!==r.marketplaceIntegrity||t[16]!==r.marketplaceIntegrityVerified||t[17]!==r.marketplaceLifecycleScripts||t[18]!==r.marketplaceLoadFailed||t[19]!==r.marketplaceLoading||t[20]!==r.marketplaceNoReadme||t[21]!==r.marketplacePermissions||t[22]!==r.marketplacePermissionsNone||t[23]!==r.marketplaceRiskConfirm||t[24]!==r.marketplaceRiskTitle||t[25]!==r.marketplaceUnavailableBody||t[26]!==r.marketplaceUnavailableTitle||t[27]!==r.marketplaceVersion||t[28]!==S||t[29]!==D||t[30]!==N||t[31]!==k||t[32]!==o||t[33]!==F||t[34]!==h){let e=F&&typeof F==`object`&&!Array.isArray(F)?Object.entries(F):[],n;t[46]!==r.marketplaceNoReadme||t[47]!==S?(n=S?.readme?.trim()||(S?.description?.trim()?`### ${S.name}\n\n${S.description}`:`*${r.marketplaceNoReadme}*`),t[46]=r.marketplaceNoReadme,t[47]=S,t[48]=n):n=t[48];let i=n;R=E,z=!0,t[49]===o?V=t[50]:(V=e=>!e&&o(),t[49]=o,t[50]=V),L=C,t[51]===Symbol.for(`react.memo_cache_sentinel`)?(J=(0,Z.jsx)(x,{className:`xopc-dialog-overlay fixed inset-0 z-[130] bg-scrim`}),t[51]=J):J=t[51],I=w,W=`fixed left-1/2 top-1/2 z-[131] flex h-[min(44rem,calc(100vh-1.5rem))] w-[min(42rem,calc(100vw-1.5rem))] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-xl border border-edge bg-surface-panel shadow-elevated`,K=le;let a;t[52]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,Z.jsx)(ee,{className:`size-5`}),t[52]=a):a=t[52];let s;t[53]!==r.detailBack||t[54]!==o?(s=(0,Z.jsx)(`button`,{type:`button`,onClick:o,className:`inline-flex size-9 items-center justify-center rounded-lg text-fg-muted hover:bg-surface-hover hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,"aria-label":r.detailBack,children:a}),t[53]=r.detailBack,t[54]=o,t[55]=s):s=t[55];let l;t[56]===r.marketplaceDetailTitle?l=t[57]:(l=(0,Z.jsx)(T,{className:`min-w-0 flex-1 truncate text-center text-sm font-semibold text-fg`,children:r.marketplaceDetailTitle}),t[56]=r.marketplaceDetailTitle,t[57]=l);let u;t[58]===Symbol.for(`react.memo_cache_sentinel`)?(u=(0,Z.jsx)(f,{className:`size-5`}),t[58]=u):u=t[58];let d;t[59]!==r.detailClose||t[60]!==o?(d=(0,Z.jsx)(`button`,{type:`button`,onClick:o,className:`inline-flex size-9 items-center justify-center rounded-lg text-fg-muted hover:bg-surface-hover hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,"aria-label":r.detailClose,children:u}),t[59]=r.detailClose,t[60]=o,t[61]=d):d=t[61],t[62]!==s||t[63]!==l||t[64]!==d?(q=(0,Z.jsxs)(`div`,{className:`flex shrink-0 items-center justify-between gap-2 border-b border-edge px-4 py-3`,children:[s,l,d]}),t[62]=s,t[63]=l,t[64]=d,t[65]=q):q=t[65],H=`min-h-0 flex-1 overflow-y-auto p-5`,U=k&&!S?(0,Z.jsxs)(`div`,{className:`space-y-4`,"aria-label":r.marketplaceLoading,children:[(0,Z.jsx)(B,{className:`h-6 w-48`}),(0,Z.jsx)(B,{className:`h-4 w-28`}),(0,Z.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Z.jsx)(B,{className:`h-12`}),(0,Z.jsx)(B,{className:`h-12`})]}),(0,Z.jsx)(B,{className:`h-28 w-full`}),(0,Z.jsx)(B,{className:`h-36 w-full`})]}):D?(0,Z.jsxs)(`div`,{className:`rounded-lg border border-red-300/70 bg-red-50 p-4 text-sm dark:border-red-900 dark:bg-red-950/30`,children:[(0,Z.jsx)(`p`,{className:`font-medium text-red-700 dark:text-red-300`,children:r.marketplaceDetailLoadFailed}),(0,Z.jsx)(`p`,{className:`mt-1 break-words text-red-600 dark:text-red-400`,children:D instanceof Error?D.message:r.marketplaceLoadFailed})]}):S?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`h3`,{className:`text-lg font-semibold text-fg`,children:S.name}),(0,Z.jsx)(`p`,{className:`mt-1 text-xs text-fg-muted`,children:(0,Z.jsx)(`code`,{className:`rounded bg-surface-panel px-1 py-0.5`,children:S.id})}),(0,Z.jsxs)(`dl`,{className:`mt-3 grid gap-2 text-xs text-fg-muted sm:grid-cols-2`,children:[(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`dt`,{className:`font-medium text-fg`,children:r.marketplaceAuthor}),(0,Z.jsx)(`dd`,{children:S.author.username})]}),(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`dt`,{className:`font-medium text-fg`,children:r.marketplaceVersion}),(0,Z.jsx)(`dd`,{children:S.latestVersion.version})]}),(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`dt`,{className:`font-medium text-fg`,children:r.marketplaceDownloads}),(0,Z.jsx)(`dd`,{children:S.downloads})]})]}),N===`bundled`?null:(0,Z.jsxs)(`section`,{className:`mt-5 space-y-3 rounded-lg border border-edge bg-surface-base p-4`,children:[(0,Z.jsxs)(`div`,{className:`flex items-start gap-2.5`,children:[S.installability.available?(0,Z.jsx)(te,{className:`mt-0.5 size-5 shrink-0 text-emerald-600 dark:text-emerald-400`,"aria-hidden":!0}):(0,Z.jsx)(A,{className:`mt-0.5 size-5 shrink-0 text-amber-600 dark:text-amber-400`,"aria-hidden":!0}),(0,Z.jsxs)(`div`,{className:`min-w-0`,children:[(0,Z.jsx)(`h4`,{className:`text-sm font-semibold text-fg`,children:S.installability.available?r.marketplaceRiskTitle:r.marketplaceUnavailableTitle}),(0,Z.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-fg-muted`,children:S.installability.available?r.marketplaceCodeRisk:S.installability.reason??r.marketplaceUnavailableBody})]})]}),S.installability.available?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`dl`,{className:`grid gap-2 text-xs text-fg-muted sm:grid-cols-2`,children:[(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`dt`,{className:`font-medium text-fg`,children:r.marketplaceIntegrity}),(0,Z.jsx)(`dd`,{children:r.marketplaceIntegrityVerified})]}),(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`dt`,{className:`font-medium text-fg`,children:r.marketplaceDependencies}),(0,Z.jsx)(`dd`,{children:S.packageSummary?.dependencyCount??0})]})]}),(0,Z.jsxs)(`div`,{className:`text-xs text-fg-muted`,children:[(0,Z.jsx)(`p`,{className:`font-medium text-fg`,children:r.marketplacePermissions}),e.length>0?(0,Z.jsx)(`ul`,{className:`mt-1 space-y-1`,children:e.map(ce)}):(0,Z.jsx)(`p`,{className:`mt-1`,children:r.marketplacePermissionsNone})]}),(S.packageSummary?.lifecycleScripts.length??0)>0?(0,Z.jsxs)(`p`,{className:`text-xs leading-relaxed text-amber-700 dark:text-amber-300`,children:[r.marketplaceLifecycleScripts,`: `,S.packageSummary?.lifecycleScripts.join(`, `)]}):null,(0,Z.jsxs)(`label`,{className:`flex cursor-pointer items-start gap-2 text-sm text-fg`,children:[(0,Z.jsx)(`input`,{type:`checkbox`,checked:h,onChange:e=>g(e.target.checked),className:`mt-0.5 size-4 rounded border-edge accent-[var(--color-accent)]`}),(0,Z.jsx)(`span`,{children:r.marketplaceRiskConfirm})]})]}):null]}),S.readme?.trim()?(0,Z.jsx)(`h4`,{className:`mb-2 mt-6 text-sm font-semibold text-fg`,children:r.marketplaceDetailReadmeHeading}):null,(0,Z.jsx)(`div`,{className:`markdown-content min-w-0 break-words text-sm`,children:(0,Z.jsx)(c,{content:i})})]}):null,t[6]=r.detailBack,t[7]=r.detailClose,t[8]=r.marketplaceAuthor,t[9]=r.marketplaceCodeRisk,t[10]=r.marketplaceDependencies,t[11]=r.marketplaceDetailLoadFailed,t[12]=r.marketplaceDetailReadmeHeading,t[13]=r.marketplaceDetailTitle,t[14]=r.marketplaceDownloads,t[15]=r.marketplaceIntegrity,t[16]=r.marketplaceIntegrityVerified,t[17]=r.marketplaceLifecycleScripts,t[18]=r.marketplaceLoadFailed,t[19]=r.marketplaceLoading,t[20]=r.marketplaceNoReadme,t[21]=r.marketplacePermissions,t[22]=r.marketplacePermissionsNone,t[23]=r.marketplaceRiskConfirm,t[24]=r.marketplaceRiskTitle,t[25]=r.marketplaceUnavailableBody,t[26]=r.marketplaceUnavailableTitle,t[27]=r.marketplaceVersion,t[28]=S,t[29]=D,t[30]=N,t[31]=k,t[32]=o,t[33]=F,t[34]=h,t[35]=I,t[36]=L,t[37]=R,t[38]=z,t[39]=V,t[40]=H,t[41]=U,t[42]=W,t[43]=K,t[44]=q,t[45]=J}else I=t[35],L=t[36],R=t[37],z=t[38],V=t[39],H=t[40],U=t[41],W=t[42],K=t[43],q=t[44],J=t[45];let Y;t[66]!==H||t[67]!==U?(Y=(0,Z.jsx)(`div`,{className:H,children:U}),t[66]=H,t[67]=U,t[68]=Y):Y=t[68];let X;t[69]!==d||t[70]!==r.marketplaceBuiltinGoBuiltin||t[71]!==r.marketplaceBuiltinManageHint||t[72]!==r.marketplaceInstall||t[73]!==r.marketplaceReinstall||t[74]!==r.marketplaceReinstallConfirm||t[75]!==r.marketplaceUninstall||t[76]!==r.marketplaceUninstallConfirm||t[77]!==S||t[78]!==N||t[79]!==o||t[80]!==s||t[81]!==u||t[82]!==n||t[83]!==h||t[84]!==P?(X=S?(0,Z.jsx)(`div`,{className:`flex shrink-0 flex-wrap items-center justify-end gap-2 border-t border-edge-subtle px-5 py-4`,children:N===`bundled`?(0,Z.jsxs)(`div`,{className:`flex w-full flex-col items-stretch gap-2`,children:[(0,Z.jsx)(`p`,{className:`text-sm leading-relaxed text-fg-muted`,children:r.marketplaceBuiltinManageHint}),(0,Z.jsx)(a,{to:`/extensions?tab=builtin`,onClick:o,className:`inline-flex w-fit items-center justify-center rounded-lg border border-edge px-3 py-2 text-sm font-medium text-fg hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,children:r.marketplaceBuiltinGoBuiltin})]}):(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`button`,{type:`button`,disabled:d||!S.installability.available||!h,onClick:()=>{P&&!window.confirm(r.marketplaceReinstallConfirm)||(m(!0),s(n,P).catch(se).finally(()=>m(!1)))},className:p(`inline-flex items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-sm font-medium`,`bg-accent text-white shadow-surface hover:bg-accent-hover`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel`,`disabled:pointer-events-none disabled:opacity-50`),children:[d?(0,Z.jsx)(l,{className:`size-4 animate-spin`,"aria-hidden":!0}):null,P?r.marketplaceReinstall:r.marketplaceInstall]}),P?(0,Z.jsxs)(`button`,{type:`button`,disabled:d,onClick:()=>{window.confirm(r.marketplaceUninstallConfirm)&&(m(!0),u(n).then(()=>o()).catch(oe).finally(()=>m(!1)))},className:p(`inline-flex items-center justify-center gap-1.5 rounded-lg border border-edge px-3 py-2 text-sm font-medium text-fg`,`hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,`disabled:pointer-events-none disabled:opacity-50`),children:[(0,Z.jsx)(j,{className:`size-4 shrink-0`,"aria-hidden":!0}),r.marketplaceUninstall]}):null]})}):null,t[69]=d,t[70]=r.marketplaceBuiltinGoBuiltin,t[71]=r.marketplaceBuiltinManageHint,t[72]=r.marketplaceInstall,t[73]=r.marketplaceReinstall,t[74]=r.marketplaceReinstallConfirm,t[75]=r.marketplaceUninstall,t[76]=r.marketplaceUninstallConfirm,t[77]=S,t[78]=N,t[79]=o,t[80]=s,t[81]=u,t[82]=n,t[83]=h,t[84]=P,t[85]=X):X=t[85];let Q;t[86]!==I||t[87]!==Y||t[88]!==X||t[89]!==W||t[90]!==K||t[91]!==q?(Q=(0,Z.jsxs)(I,{className:W,onOpenAutoFocus:K,children:[q,Y,X]}),t[86]=I,t[87]=Y,t[88]=X,t[89]=W,t[90]=K,t[91]=q,t[92]=Q):Q=t[92];let $;t[93]!==L||t[94]!==Q||t[95]!==J?($=(0,Z.jsxs)(L,{children:[J,Q]}),t[93]=L,t[94]=Q,t[95]=J,t[96]=$):$=t[96];let ae;return t[97]!==R||t[98]!==z||t[99]!==V||t[100]!==$?(ae=(0,Z.jsx)(R,{defaultOpen:z,onOpenChange:V,children:$}),t[97]=R,t[98]=z,t[99]=V,t[100]=$,t[101]=ae):ae=t[101],ae}function oe(){}function se(){}function ce(e){let[t,n]=e;return(0,Z.jsxs)(`li`,{className:`break-words`,children:[(0,Z.jsx)(`code`,{children:t}),`: `,Array.isArray(n)?n.join(`, `):String(n)]},t)}function le(e){return e.preventDefault()}function ue(e){return!!e.token}function de(){let e=v(e=>e.language),t=h(e),n=M(e=>e.setPageHeader),r=M(e=>e.clearPageHeader),o=P(),s=H(),[c,l]=i(),f=K(c.get(`tab`)),p=c.get(`q`)??``,[g,_]=(0,G.useState)(f),[y,b]=(0,G.useState)(p),[x,S]=(0,G.useState)(null),C=c.toString(),w=(0,G.useRef)(C);if(w.current!==C){w.current=C;let e=K(c.get(`tab`)),t=c.get(`q`)??``;_(t=>t===e?t:e),b(e=>e===t?e:t)}(0,G.useEffect)(()=>{l(e=>{let t=new URLSearchParams(e),n=y.trim();return n?t.set(`q`,n):t.delete(`q`),g===`marketplace`?t.delete(`tab`):t.set(`tab`,g),t.toString()===e.toString()?e:t},{replace:!0})},[g,y,l]);let T=(0,G.useMemo)(()=>o.filter(e=>e.source===`bundled`),[o]),E=(0,G.useMemo)(()=>o.filter(e=>e.source!==`bundled`),[o]),D=g===`builtin`?T:E,O=(0,G.useMemo)(()=>{let t=y.trim().toLowerCase(),n=D;return t&&(n=n.filter(e=>(e.name??``).toLowerCase().includes(t)||e.id.toLowerCase().includes(t)||(e.description??``).toLowerCase().includes(t))),n.toSorted((t,n)=>t.hasUi===n.hasUi?(t.name||t.id).localeCompare(n.name||n.id,e):t.hasUi?-1:1)},[D,y,e]);if((0,G.useEffect)(()=>{S(e=>{if(!e)return e;let t=o.find(t=>t.id===e.id);return t?fe(e)===fe(t)&&e.active===t.active?e:t:null})},[o]),(0,G.useLayoutEffect)(()=>(n({startExtra:null,main:(0,Z.jsx)(`div`,{className:`min-w-0`,children:(0,Z.jsx)(`h1`,{className:`truncate text-base font-semibold tracking-tight text-fg`,children:t.extensionsPage.title})}),end:(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(m,{asChild:!0,variant:`secondary`,className:`h-9`,children:(0,Z.jsxs)(a,{to:`/local-apps`,"aria-label":t.extensionsPage.openLocalApps,title:t.extensionsPage.openLocalApps,children:[(0,Z.jsx)(L,{className:`size-4`}),(0,Z.jsx)(`span`,{className:`hidden sm:inline`,children:t.extensionsPage.openLocalApps})]})}),(0,Z.jsx)(m,{asChild:!0,variant:`primary`,className:`h-9`,children:(0,Z.jsxs)(a,{to:`/local-apps/new`,children:[(0,Z.jsx)(u,{className:`size-4`}),t.extensionsPage.createLocalApp]})})]})}),()=>r()),[r,t.extensionsPage.createLocalApp,t.extensionsPage.openLocalApps,t.extensionsPage.title,n]),s&&g!==`marketplace`)return(0,Z.jsx)(ye,{});let k=g!==`marketplace`&&D.length>0;return(0,Z.jsxs)(`div`,{className:`flex min-h-0 min-w-0 flex-1 flex-col bg-surface-panel`,children:[(0,Z.jsxs)(`div`,{className:`w-full px-3 py-8 sm:px-5 xl:px-6`,children:[(0,Z.jsxs)(`div`,{className:`mb-5 flex flex-col gap-3 rounded-xl border border-edge-subtle bg-surface-base p-3 shadow-surface sm:flex-row sm:items-center sm:justify-between`,children:[(0,Z.jsx)(W,{items:[{id:`marketplace`,label:t.extensionsPage.tabMarketplace},{id:`builtin`,label:t.extensionsPage.tabBuiltin,count:T.length},{id:`user`,label:t.extensionsPage.tabUser,count:E.length}],activeTab:g,onChange:_,ariaLabel:t.extensionsPage.extensionsNavAria,tabIdPrefix:`extensions-tab`,panelIdPrefix:`extensions-panel`,className:`flex-wrap`}),k?(0,Z.jsxs)(`div`,{className:`relative w-full min-w-0 sm:max-w-xs`,children:[(0,Z.jsx)(d,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-fg-muted`,"aria-hidden":!0}),(0,Z.jsx)(`input`,{type:`search`,value:y,onChange:e=>b(e.target.value),placeholder:t.extensionsPage.searchPlaceholder,className:`w-full rounded-lg border border-edge bg-surface-base py-2 pl-9 pr-3 text-sm text-fg placeholder:text-fg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,autoComplete:`off`})]}):null]}),g===`marketplace`?(0,Z.jsx)($,{}):g===`builtin`&&T.length===0?(0,Z.jsx)(xe,{message:t.extensionsPage.emptyBuiltin}):g===`user`&&E.length===0?(0,Z.jsx)(xe,{message:t.extensionsPage.emptyUser}):O.length===0?(0,Z.jsx)(`p`,{className:`rounded-xl border border-edge-subtle bg-surface-base px-3 py-8 text-center text-sm text-fg-muted shadow-surface sm:px-5 xl:px-6`,children:t.extensionsPage.noSearchResults}):(0,Z.jsx)(`div`,{className:`grid gap-4 sm:grid-cols-2 lg:grid-cols-3`,children:O.map(e=>(0,Z.jsx)(ge,{extension:e,copy:t.extensionsPage,showSourceBadge:g===`user`,onOpen:()=>S(e)},e.id))})]}),x?(0,Z.jsx)(_e,{extension:x,copy:t.extensionsPage,onClose:()=>S(null)},x.id):null]})}function fe(e){return e.activationEligible??e.active}function pe(e,t){return e.source===`bundled`?t.providerBundled:e.source===`global`?t.providerGlobal:e.source===`workspace`?t.providerWorkspace:t.providerOther}function me(e,t){return e.source===`global`?t.badgeSourceGlobal:e.source===`workspace`?t.badgeSourceWorkspace:t.badgeSourceOther}function he(e,t){let n=fe(e);return n&&e.active?t.runStateLive:n&&!e.active?t.runStatePendingOn:!n&&e.active?t.runStatePendingOff:t.runStateOff}function ge(e){let t=(0,ne.c)(45),{extension:n,copy:r,showSourceBadge:i,onOpen:a}=e,s;t[0]===n?s=t[1]:(s=fe(n),t[0]=n,t[1]=s);let c=s,l=n.hasUi?r.cardTooltipHasUi:r.cardTooltipNoUi,d;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(d=p(`group flex w-full flex-col rounded-xl border border-edge-subtle bg-surface-base p-4 text-left shadow-surface transition-colors`,`hover:bg-surface-hover/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,`dark:hover:bg-surface-hover/25`),t[2]=d):d=t[2];let f=n.name||n.id,m;t[3]===f?m=t[4]:(m=f.charAt(0).toUpperCase(),t[3]=f,t[4]=m);let h;t[5]===m?h=t[6]:(h=(0,Z.jsx)(`div`,{className:`flex size-12 shrink-0 items-center justify-center rounded-xl bg-accent-soft text-base font-semibold text-accent-fg`,"aria-hidden":!0,children:m}),t[5]=m,t[6]=h);let g;t[7]===n.name?g=t[8]:(g=(0,Z.jsx)(`h2`,{className:`truncate text-sm font-semibold text-fg`,children:n.name}),t[7]=n.name,t[8]=g);let _;t[9]===n.version?_=t[10]:(_=n.version?(0,Z.jsxs)(`span`,{className:`text-[11px] text-fg-muted`,children:[`v`,n.version]}):null,t[9]=n.version,t[10]=_);let v;t[11]!==g||t[12]!==_?(v=(0,Z.jsxs)(`div`,{className:`min-w-0`,children:[g,_]}),t[11]=g,t[12]=_,t[13]=v):v=t[13];let y;t[14]!==r.statusEnabled||t[15]!==c?(y=c?(0,Z.jsxs)(`span`,{className:`inline-flex shrink-0 items-center gap-1 rounded-full bg-surface-hover px-2 py-0.5 text-[11px] font-medium text-fg-muted`,children:[(0,Z.jsx)(o,{className:`size-3`,strokeWidth:2.5,"aria-hidden":!0}),r.statusEnabled]}):(0,Z.jsx)(`span`,{className:`flex size-8 shrink-0 items-center justify-center rounded-full border-2 border-accent text-accent`,"aria-hidden":!0,children:(0,Z.jsx)(u,{className:`size-4`,strokeWidth:2.5})}),t[14]=r.statusEnabled,t[15]=c,t[16]=y):y=t[16];let b;t[17]!==v||t[18]!==y?(b=(0,Z.jsxs)(`div`,{className:`flex items-start justify-between gap-2`,children:[v,y]}),t[17]=v,t[18]=y,t[19]=b):b=t[19];let x;t[20]!==r.cardNoDescription||t[21]!==n.description?(x=n.description?.trim()||r.cardNoDescription,t[20]=r.cardNoDescription,t[21]=n.description,t[22]=x):x=t[22];let S;t[23]===x?S=t[24]:(S=(0,Z.jsx)(`p`,{className:`mt-2 line-clamp-2 text-xs leading-relaxed text-fg-muted`,children:x}),t[23]=x,t[24]=S);let C=n.hasUi?r.badgeKindUi:r.badgeKindBackend,w;t[25]!==C||t[26]!==l?(w=(0,Z.jsx)(`span`,{title:l,className:`rounded-md bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-muted`,children:C}),t[25]=C,t[26]=l,t[27]=w):w=t[27];let T;t[28]!==r||t[29]!==n||t[30]!==i?(T=n.source===`bundled`?(0,Z.jsx)(`span`,{className:`rounded-md bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-muted`,children:r.badgeBundled}):i?(0,Z.jsx)(`span`,{title:pe(n,r),className:`rounded-md bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-muted`,children:me(n,r)}):null,t[28]=r,t[29]=n,t[30]=i,t[31]=T):T=t[31];let E;t[32]!==w||t[33]!==T?(E=(0,Z.jsxs)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:[w,T]}),t[32]=w,t[33]=T,t[34]=E):E=t[34];let D;t[35]!==b||t[36]!==S||t[37]!==E?(D=(0,Z.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[b,S,E]}),t[35]=b,t[36]=S,t[37]=E,t[38]=D):D=t[38];let O;t[39]!==D||t[40]!==h?(O=(0,Z.jsxs)(`div`,{className:`flex gap-3`,children:[h,D]}),t[39]=D,t[40]=h,t[41]=O):O=t[41];let k;return t[42]!==a||t[43]!==O?(k=(0,Z.jsx)(`button`,{type:`button`,onClick:a,className:d,children:O}),t[42]=a,t[43]=O,t[44]=k):k=t[44],k}function _e({extension:e,copy:t,onClose:n}){let{mutate:r}=D(),[i,o]=(0,G.useState)(!1),[c,u]=(0,G.useState)(null),[d,h]=(0,G.useState)(!1),g=e.activationEligible===!0,_=(0,G.useCallback)(async()=>{if(e.source===`bundled`){u(null),h(!1),o(!0);try{let{requiresGatewayRestart:t}=await Y({extensionId:e.id,enabled:!g});await r(`gateway-extensions-list`),N(),h(t)}catch(e){u(e instanceof Error?e.message:t.builtinToggleFailed)}finally{o(!1)}}},[g,t.builtinToggleFailed,e.id,e.source,r]),v=e.ui?.contributions?.pages??[],y=e.ui?.contributions?.settingsPanels??[],b=e.ui?.contributions?.chatWidgets??[],O=e.ui?.contributions?.sidebarPanels??[],k=v.find(e=>e.showInNav)??v[0],A=y[0],j=k?I(e.id,k):null,M=A?`/settings/ext/${e.id}/${A.id}`:e.hasConfigSchema||U(e)?`/settings/ext/${e.id}`:null;return(0,Z.jsx)(E,{defaultOpen:!0,onOpenChange:e=>!e&&n(),children:(0,Z.jsxs)(C,{children:[(0,Z.jsx)(x,{className:`xopc-dialog-overlay fixed inset-0 z-[130] bg-scrim`}),(0,Z.jsxs)(w,{className:`fixed left-1/2 top-1/2 z-[131] flex max-h-[min(90vh,44rem)] w-[min(42rem,calc(100vw-1.5rem))] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-xl border border-edge bg-surface-panel shadow-elevated`,onOpenAutoFocus:e=>e.preventDefault(),children:[(0,Z.jsxs)(`div`,{className:`flex shrink-0 items-center justify-between gap-2 border-b border-edge px-4 py-3`,children:[(0,Z.jsx)(`button`,{type:`button`,onClick:n,className:`inline-flex size-9 items-center justify-center rounded-lg text-fg-muted hover:bg-surface-hover hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,"aria-label":t.detailBack,children:(0,Z.jsx)(ee,{className:`size-5`})}),(0,Z.jsx)(T,{className:`min-w-0 flex-1 truncate text-center text-sm font-semibold text-fg`,children:t.detailTitle}),(0,Z.jsxs)(S,{className:`sr-only`,children:[e.name,` (`,e.id,`)`]}),(0,Z.jsx)(`button`,{type:`button`,onClick:n,className:`inline-flex size-9 items-center justify-center rounded-lg text-fg-muted hover:bg-surface-hover hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,"aria-label":t.detailClose,children:(0,Z.jsx)(f,{className:`size-5`})})]}),(0,Z.jsxs)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-5`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-start gap-4`,children:[(0,Z.jsx)(`div`,{className:`flex size-16 shrink-0 items-center justify-center rounded-2xl bg-accent-soft text-xl font-semibold text-accent-fg`,"aria-hidden":!0,children:(e.name||e.id).charAt(0).toUpperCase()}),(0,Z.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Z.jsx)(`h3`,{className:`text-lg font-semibold text-fg`,children:e.name}),(0,Z.jsxs)(`p`,{className:`mt-0.5 text-sm text-fg-muted`,children:[t.detailProviderPrefix,` `,pe(e,t)]}),e.version?(0,Z.jsxs)(`p`,{className:`mt-1 text-xs text-fg-muted`,children:[`v`,e.version]}):null]})]}),(0,Z.jsx)(`p`,{className:`mt-5 text-sm leading-relaxed text-fg`,children:e.description?.trim()||t.detailNoDescription}),e.hasUi?null:(0,Z.jsx)(`p`,{className:`mt-3 text-xs text-fg-muted`,children:t.backendOnlyHint}),(0,Z.jsx)(`p`,{className:`mt-2 text-xs text-fg-muted`,children:he(e,t)}),e.source===`bundled`?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`p`,{className:`mt-4 rounded-lg bg-surface-hover/40 px-3 py-2 text-xs text-fg-muted shadow-surface dark:bg-surface-hover/20`,children:t.builtinConfigHint}),(0,Z.jsxs)(`div`,{className:`mt-3 rounded-lg bg-surface-hover/40 p-3 shadow-surface dark:bg-surface-hover/20`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Z.jsx)(`span`,{className:`text-xs font-medium text-fg`,children:t.builtinRuntimeToggle}),(0,Z.jsx)(m,{type:`button`,variant:`secondary`,disabled:i,onClick:()=>void _(),className:`shrink-0 py-1.5 text-xs`,children:i?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(l,{className:`mr-1.5 size-3.5 shrink-0 animate-spin`,"aria-hidden":!0}),t.builtinToggleBusy]}):g?t.builtinToggleDisable:t.builtinToggleEnable})]}),c?(0,Z.jsx)(`p`,{className:`mt-2 text-xs text-rose-600 dark:text-rose-400`,children:c}):null,d?(0,Z.jsx)(`p`,{className:`mt-2 text-xs text-fg-muted`,children:t.builtinToggleRestartHint}):null]})]}):(0,Z.jsx)(`p`,{className:`mt-4 rounded-lg bg-surface-hover/40 px-3 py-2 text-xs text-fg-muted shadow-surface dark:bg-surface-hover/20`,children:t.cliManageHint}),e.hasUi&&(v.length>0||y.length>0||b.length>0)?(0,Z.jsxs)(`section`,{className:`mt-8`,children:[(0,Z.jsx)(`h4`,{className:`mb-3 text-sm font-semibold text-fg`,children:t.detailSectionFeatures}),(0,Z.jsxs)(`div`,{className:`flex flex-wrap gap-1.5`,children:[(0,Z.jsx)(ve,{template:t.badgePages,count:v.length,hidden:v.length===0}),(0,Z.jsx)(ve,{template:t.badgeSettings,count:y.length,hidden:y.length===0}),(0,Z.jsx)(ve,{template:t.badgeWidgets,count:b.length,hidden:b.length===0}),(0,Z.jsx)(ve,{template:t.badgeSidebar,count:O.length,hidden:O.length===0})]})]}):null,F(e)&&(j||M)?(0,Z.jsxs)(`div`,{className:`mt-6 flex flex-wrap gap-2 border-t border-edge-subtle pt-4`,children:[j?(0,Z.jsxs)(a,{to:j,onClick:n,className:p(`inline-flex items-center gap-1.5 rounded-lg border border-edge px-3 py-2 text-sm font-medium text-fg`,`hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`),children:[(0,Z.jsx)(s,{className:`size-4 shrink-0 opacity-80`,"aria-hidden":!0}),t.open]}):null,M?(0,Z.jsxs)(a,{to:M,onClick:n,className:p(`inline-flex items-center gap-1.5 rounded-lg border border-edge px-3 py-2 text-sm font-medium text-fg`,`hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`),children:[(0,Z.jsx)(R,{className:`size-4 shrink-0 opacity-80`,"aria-hidden":!0}),t.openSettings]}):null]}):null,(0,Z.jsx)(`p`,{className:`mt-6 text-[11px] leading-relaxed text-fg-muted`,children:t.restartNote})]})]})]})})}function ve(e){let t=(0,ne.c)(6),{template:n,count:r,hidden:i}=e;if(i||r===0)return null;let a;if(t[0]!==r||t[1]!==n){let e;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(e=/\{\{count\}\}/g,t[3]=e):e=t[3],a=n.replace(e,String(r)),t[0]=r,t[1]=n,t[2]=a}else a=t[2];let o;return t[4]===a?o=t[5]:(o=(0,Z.jsx)(`span`,{className:`inline-flex items-center rounded-md bg-surface-hover px-2 py-0.5 text-[11px] font-medium text-fg-muted`,children:a}),t[4]=a,t[5]=o),o}function ye(){let e=(0,ne.c)(5),t,n,r;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,Z.jsx)(`div`,{className:`mb-6 h-8 w-40 max-w-full animate-pulse rounded-md bg-surface-hover`}),n=(0,Z.jsx)(`div`,{className:`mb-2 h-4 w-full max-w-md animate-pulse rounded bg-surface-hover`}),r=(0,Z.jsx)(`div`,{className:`mb-5 h-9 w-full max-w-lg animate-pulse rounded-full bg-surface-hover`}),e[0]=t,e[1]=n,e[2]=r):(t=e[0],n=e[1],r=e[2]);let i;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(i=[`ap0`,`ap1`,`ap2`,`ap3`,`ap4`,`ap5`],e[3]=i):i=e[3];let a;return e[4]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,Z.jsx)(`div`,{className:`flex min-h-0 min-w-0 flex-1 flex-col bg-surface-panel`,children:(0,Z.jsxs)(`div`,{className:`w-full px-3 py-8 sm:px-5 xl:px-6`,children:[t,n,r,(0,Z.jsx)(`div`,{className:`mt-6 grid gap-4 sm:grid-cols-2 lg:grid-cols-3`,children:i.map(be)})]})}),e[4]=a):a=e[4],a}function be(e){return(0,Z.jsx)(`div`,{className:`h-36 animate-pulse rounded-xl border border-edge-subtle bg-surface-base shadow-surface`},e)}function xe(e){let t=(0,ne.c)(2),{message:n}=e,r;return t[0]===n?r=t[1]:(r=(0,Z.jsx)(`div`,{className:`flex min-h-[min(40vh,16rem)] flex-col items-center justify-center rounded-xl border border-edge-subtle bg-surface-base px-4 py-12 text-center shadow-surface`,children:(0,Z.jsx)(`p`,{className:`text-sm text-fg-muted`,children:n})}),t[0]=n,t[1]=r),r}export{de as ExtensionsPage};