@openhands/agent-canvas 1.0.0-rc.3 → 1.0.0-rc.5

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 (34) hide show
  1. package/README.md +2 -2
  2. package/README.windows.md +2 -2
  3. package/build/assets/{analytics-consent-form-modal-Ce-_Skcd.js → analytics-consent-form-modal-D4ndXdkQ.js} +1 -1
  4. package/build/assets/{automations-list-Ces5shz5.js → automations-list-CoYj4o97.js} +1 -1
  5. package/build/assets/{home-sJAFzI6v.js → home-D77Xasws.js} +1 -1
  6. package/build/assets/install-server-modal-BjmEphcZ.js +1 -0
  7. package/build/assets/{manifest-d3e8504d.js → manifest-08c25e0c.js} +1 -1
  8. package/build/assets/{mcp-kJYdM8aJ.js → mcp-CiokQDek.js} +2 -2
  9. package/build/assets/{onboarding-CZ_7nd-M.js → onboarding-CGUaLHfQ.js} +1 -1
  10. package/build/assets/{recommended-automations-launcher-B1kfmFTQ.js → recommended-automations-launcher-C1_CKGHa.js} +1 -1
  11. package/build/assets/{root-CIZ7Rv1X.js → root-DVv3y8Fb.js} +1 -1
  12. package/build/assets/{root-layout-B5ijp9At.js → root-layout-lUjioorg.js} +2 -2
  13. package/build/assets/telemetry--BA6QguL.js +2 -0
  14. package/build/index.html +3 -3
  15. package/config/defaults.json +2 -6
  16. package/dist/api/mcp-service/mcp-service.api.cjs +1 -1
  17. package/dist/api/mcp-service/mcp-service.api.cjs.map +1 -1
  18. package/dist/api/mcp-service/mcp-service.api.js +19 -14
  19. package/dist/api/mcp-service/mcp-service.api.js.map +1 -1
  20. package/dist/components/features/mcp-page/custom-server-editor.cjs +1 -1
  21. package/dist/components/features/mcp-page/custom-server-editor.cjs.map +1 -1
  22. package/dist/components/features/mcp-page/custom-server-editor.js +63 -62
  23. package/dist/components/features/mcp-page/custom-server-editor.js.map +1 -1
  24. package/dist/package.cjs +1 -1
  25. package/dist/package.cjs.map +1 -1
  26. package/dist/package.js +3 -1
  27. package/dist/package.js.map +1 -1
  28. package/package.json +3 -1
  29. package/scripts/check-sdk-version-sync.mjs +6 -6
  30. package/scripts/dev-safe.mjs +32 -8
  31. package/scripts/dev-with-automation.mjs +25 -1
  32. package/scripts/logger.mjs +77 -0
  33. package/build/assets/install-server-modal-BjEzlLF5.js +0 -1
  34. package/build/assets/telemetry-j9SLrtY7.js +0 -2
@@ -19,7 +19,7 @@
19
19
  *
20
20
  * Usage:
21
21
  * node scripts/check-sdk-version-sync.mjs
22
- * EXPECTED_SDK_VERSION=1.25.0 node scripts/check-sdk-version-sync.mjs
22
+ * EXPECTED_SDK_VERSION=1.26.0 node scripts/check-sdk-version-sync.mjs
23
23
  * node scripts/check-sdk-version-sync.mjs --check-pypi
24
24
  *
25
25
  * Environment variables:
@@ -79,7 +79,7 @@ Triggering from other repos:
79
79
  -H "Authorization: token \$GITHUB_TOKEN" \\
80
80
  -H "Accept: application/vnd.github.v3+json" \\
81
81
  https://api.github.com/repos/OpenHands/agent-canvas/dispatches \\
82
- -d '{"event_type": "sdk-version-check", "client_payload": {"version": "1.25.0"}}'
82
+ -d '{"event_type": "sdk-version-check", "client_payload": {"version": "1.26.0"}}'
83
83
  `);
84
84
  process.exit(0);
85
85
  }
@@ -268,9 +268,9 @@ async function fetchPyPIDependencies(packageName, version) {
268
268
  * Parse PyPI requires_dist array and extract SDK package versions
269
269
  *
270
270
  * PyPI returns dependencies in PEP 508 format like:
271
- * "openhands-sdk>=1.25.0,<2.0.0"
272
- * "openhands-tools==1.25.0"
273
- * "openhands-workspace (>=1.25.0)"
271
+ * "openhands-sdk>=1.26.0,<2.0.0"
272
+ * "openhands-tools==1.26.0"
273
+ * "openhands-workspace (>=1.26.0)"
274
274
  */
275
275
  function parseSdkVersionsFromRequiresDist(requiresDist) {
276
276
  const versions = {};
@@ -284,7 +284,7 @@ function parseSdkVersionsFromRequiresDist(requiresDist) {
284
284
  }
285
285
 
286
286
  // Extract the version number - look for patterns like:
287
- // ">=1.25.0", "==1.25.0", "(>=1.25.0)", "~=1.25.0"
287
+ // ">=1.26.0", "==1.26.0", "(>=1.26.0)", "~=1.26.0"
288
288
  // After the package name and before any comma or closing paren
289
289
  const versionPattern = /[><=~!]+\s*([0-9]+(?:\.[0-9]+)*)/;
290
290
  const match = dep.match(versionPattern);
@@ -25,6 +25,7 @@ import {
25
25
  // Docker entrypoint can run it as a CLI. Re-exported below for back-compat
26
26
  // (dev-with-automation.mjs and tests still import it from here).
27
27
  import { buildRuntimeServicesInfo } from "./runtime-services-info.mjs";
28
+ import { fileLog, stripAnsi } from "./logger.mjs";
28
29
 
29
30
  // ── Centralized config (single source of truth for versions, ports, etc.) ───
30
31
  const __dev_safe_dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -419,7 +420,7 @@ export function validateFrontendDependencies(
419
420
  * edits are picked up without a manual reinstall. The agent-server itself
420
421
  * is rebuilt from local source on each invocation (--reinstall).
421
422
  * - OH_AGENT_SERVER_GIT_REF: Git commit SHA or branch name
422
- * - OH_AGENT_SERVER_VERSION: Specific PyPI version (e.g., "1.25.0")
423
+ * - OH_AGENT_SERVER_VERSION: Specific PyPI version (e.g., "1.26.0")
423
424
  *
424
425
  * If none are set, defaults to the released version specified by
425
426
  * DEFAULT_AGENT_SERVER_VERSION. Set OH_AGENT_SERVER_GIT_REF to use a
@@ -462,7 +463,7 @@ export function buildAgentServerCommand(env = process.env) {
462
463
  // All four must come from the same ref so inter-package APIs stay in sync.
463
464
  //
464
465
  // --reinstall is required because the git branch may carry the same version
465
- // string as the current PyPI release (e.g. both "1.25.0"). Without it, uv
466
+ // string as the current PyPI release (e.g. both "1.26.0"). Without it, uv
466
467
  // silently reuses the cached PyPI wheels and the git ref is never actually
467
468
  // used, even though it was explicitly requested.
468
469
  const baseGitUrl = `git+${AGENT_SERVER_GIT_REPO}@${gitRef}`;
@@ -834,13 +835,16 @@ function spawnProcess(command, args, options = {}) {
834
835
 
835
836
  child.once("error", (error) => {
836
837
  if (isEnoentError(error) && command === "uvx") {
837
- console.error(formatMissingUvxGuidance(options?.cwd));
838
+ const msg = formatMissingUvxGuidance(options?.cwd);
839
+ console.error(msg);
840
+ fileLog("error", stripAnsi(msg));
838
841
  } else if (isEnoentError(error)) {
839
- console.error(
840
- `Failed to start ${command}. Make sure it is installed and on your PATH.`,
841
- );
842
+ const msg = `Failed to start ${command}. Make sure it is installed and on your PATH.`;
843
+ console.error(msg);
844
+ fileLog("error", msg);
842
845
  } else {
843
846
  console.error(`Failed to start ${command}:`, error);
847
+ fileLog("error", `Failed to start ${command}: ${error.message}`);
844
848
  }
845
849
  });
846
850
 
@@ -849,9 +853,12 @@ function spawnProcess(command, args, options = {}) {
849
853
 
850
854
  async function main() {
851
855
  console.log("Starting isolated agent-server + frontend dev stack...");
856
+ fileLog("info", "Starting isolated agent-server + frontend dev stack...");
852
857
  validateFrontendDependencies();
853
858
  console.log("Frontend dependencies found.");
859
+ fileLog("info", "Frontend dependencies found.");
854
860
  console.log("Allocating ports...");
861
+ fileLog("info", "Allocating ports...");
855
862
 
856
863
  // Use async config builder with dynamic port allocation
857
864
  const config = await buildSafeDevConfigAsync();
@@ -890,6 +897,16 @@ async function main() {
890
897
  console.log(`- secret key: ${secretKeySource}`);
891
898
  console.log(`- session API key: ${sessionKeySource}`);
892
899
  console.log("");
900
+ fileLog(
901
+ "info",
902
+ [
903
+ "Agent-server stack config:",
904
+ ` agent-server: ${agentServerCmd.source}`,
905
+ ` backend: ${config.backendBaseUrl}`,
906
+ ` working dir: ${config.workingDir}`,
907
+ ` state dir: ${config.stateDir}`,
908
+ ].join("\n"),
909
+ );
893
910
 
894
911
  const backend = spawnProcess(
895
912
  agentServerCmd.command,
@@ -990,7 +1007,9 @@ async function main() {
990
1007
 
991
1008
  backend.once("exit", (code) => {
992
1009
  if (!shuttingDown) {
993
- console.error(`agent-server exited unexpectedly with code ${code ?? 0}`);
1010
+ const msg = `agent-server exited unexpectedly with code ${code ?? 0}`;
1011
+ console.error(msg);
1012
+ fileLog("error", msg);
994
1013
  shutdown();
995
1014
  process.exitCode = code ?? 1;
996
1015
  }
@@ -1077,7 +1096,12 @@ if (
1077
1096
  import.meta.url === pathToFileURL(process.argv[1]).href
1078
1097
  ) {
1079
1098
  main().catch((error) => {
1080
- console.error(error instanceof Error ? error.message : error);
1099
+ const msg = error instanceof Error ? error.message : String(error);
1100
+ console.error(msg);
1101
+ fileLog("error", `Fatal error: ${msg}`);
1102
+ if (error instanceof Error && error.stack) {
1103
+ fileLog("error", error.stack);
1104
+ }
1081
1105
  process.exit(1);
1082
1106
  });
1083
1107
  }
@@ -68,6 +68,7 @@ import {
68
68
  isProcessRunning,
69
69
  signalProcessTree,
70
70
  } from "./dev-process-utils.mjs";
71
+ import { fileLog, stripAnsi } from "./logger.mjs";
71
72
 
72
73
  const __dirname = dirname(fileURLToPath(import.meta.url));
73
74
  const projectRoot = resolve(__dirname, "..");
@@ -105,18 +106,22 @@ const c = {
105
106
  function logService(name, message, color = c.reset) {
106
107
  const ts = new Date().toISOString().split("T")[1].split(".")[0];
107
108
  console.log(`${c.dim}${ts}${c.reset} ${color}[${name}]${c.reset} ${message}`);
109
+ fileLog("info", `[${name}] ${stripAnsi(message)}`);
108
110
  }
109
111
 
110
112
  function logStep(step, message) {
111
113
  console.log(`${c.cyan}[${step}]${c.reset} ${message}`);
114
+ fileLog("info", `[${step}] ${message}`);
112
115
  }
113
116
 
114
117
  function logSuccess(message) {
115
118
  console.log(`${c.green}✓${c.reset} ${message}`);
119
+ fileLog("info", `✓ ${message}`);
116
120
  }
117
121
 
118
122
  function logError(message) {
119
123
  console.error(`${c.red}✗${c.reset} ${message}`);
124
+ fileLog("error", `✗ ${stripAnsi(message)}`);
120
125
  }
121
126
 
122
127
  /**
@@ -472,7 +477,9 @@ function checkPrerequisites({
472
477
 
473
478
  if (checkUvx) {
474
479
  if (!commandExists("uvx")) {
475
- console.error(formatMissingUvxGuidance(projectRoot));
480
+ const uvxGuidance = formatMissingUvxGuidance(projectRoot);
481
+ console.error(uvxGuidance);
482
+ fileLog("error", stripAnsi(uvxGuidance));
476
483
  process.exit(1);
477
484
  }
478
485
  logSuccess("uvx found");
@@ -862,6 +869,7 @@ function shutdown() {
862
869
 
863
870
  console.log("");
864
871
  console.log(`${c.yellow}Shutting down...${c.reset}`);
872
+ fileLog("info", "Shutting down...");
865
873
 
866
874
  for (const [name, proc] of processes) {
867
875
  logService(name, "Stopping...", c.dim);
@@ -1133,6 +1141,20 @@ function printBanner(config) {
1133
1141
  console.log(`${c.dim}State directory: ${config.stateDir}${c.reset}`);
1134
1142
  console.log(`${c.dim}Press Ctrl+C to stop${c.reset}`);
1135
1143
  console.log("");
1144
+
1145
+ // Write a compact plain-text summary to the log file.
1146
+ const summary = [
1147
+ `${stackName} — started`,
1148
+ ` Ingress: http://localhost:${config.ingressPort}/`,
1149
+ ...(config.launchFrontend
1150
+ ? [` Main UI: http://localhost:${config.ingressPort}/`]
1151
+ : []),
1152
+ ...(config.launchAutomation
1153
+ ? [` API Docs: http://localhost:${config.ingressPort}/api/automation/docs`]
1154
+ : []),
1155
+ ` State directory: ${config.stateDir}`,
1156
+ ];
1157
+ fileLog("info", summary.join("\n"));
1136
1158
  }
1137
1159
 
1138
1160
  async function main(options = {}) {
@@ -1186,6 +1208,7 @@ async function main(options = {}) {
1186
1208
  console.log("");
1187
1209
  console.log(`${c.cyan}${c.bold}${titleWithMode}${c.reset}`);
1188
1210
  console.log("");
1211
+ fileLog("info", titleWithMode);
1189
1212
 
1190
1213
  // Setup phase
1191
1214
  checkPrerequisites({
@@ -1397,6 +1420,7 @@ if (isMainModule) {
1397
1420
  logError(`Fatal error: ${err.message}`);
1398
1421
  if (err.stack) {
1399
1422
  console.error(c.dim + err.stack + c.reset);
1423
+ fileLog("error", err.stack);
1400
1424
  }
1401
1425
  process.exit(1);
1402
1426
  });
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Shared file logger for agent-canvas dev scripts.
3
+ *
4
+ * Writes log output to a daily-rotating file under <project-root>/logs/
5
+ * alongside the existing console output (which is unchanged).
6
+ *
7
+ * File naming: logs/agent-canvas.YYYY-MM-DD.log
8
+ * Retention: 7 days (files older than 7 days are automatically deleted)
9
+ */
10
+
11
+ import { mkdirSync } from "node:fs";
12
+ import { homedir } from "node:os";
13
+ import { join } from "node:path";
14
+ import process from "node:process";
15
+ import { createLogger, format } from "winston";
16
+ import DailyRotateFile from "winston-daily-rotate-file";
17
+
18
+ // Mirror the state-directory logic from dev-safe.mjs so log files live
19
+ // alongside all other agent-canvas runtime state (e.g. ~/.openhands/agent-canvas).
20
+ // The same env var (OH_CANVAS_SAFE_STATE_DIR) overrides both.
21
+ const stateDir =
22
+ process.env.OH_CANVAS_SAFE_STATE_DIR ||
23
+ join(homedir(), ".openhands", "agent-canvas");
24
+ const logDir = join(stateDir, "logs");
25
+
26
+ // Ensure the logs directory exists before the transport tries to open a file.
27
+ mkdirSync(logDir, { recursive: true });
28
+
29
+ // Matches any ANSI CSI escape sequence (colors, cursor movement, etc.).
30
+ const ANSI_RE = /\x1b\[[0-9;]*m/g;
31
+
32
+ /**
33
+ * Remove ANSI escape codes so log files contain clean plain text.
34
+ * @param {string} str
35
+ * @returns {string}
36
+ */
37
+ export function stripAnsi(str) {
38
+ return typeof str === "string" ? str.replace(ANSI_RE, "") : String(str);
39
+ }
40
+
41
+ const fileTransport = new DailyRotateFile({
42
+ dirname: logDir,
43
+ filename: "agent-canvas.%DATE%.log",
44
+ datePattern: "YYYY-MM-DD",
45
+ maxFiles: "7d",
46
+ // Audit file tracks which rotated files exist; kept alongside log files.
47
+ auditFile: join(logDir, ".log-audit.json"),
48
+ createSymlink: false,
49
+ });
50
+
51
+ const fileLogger = createLogger({
52
+ level: "debug",
53
+ format: format.combine(
54
+ format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
55
+ format.printf(
56
+ ({ timestamp, level, message }) =>
57
+ `${timestamp} [${level.toUpperCase().padEnd(5)}] ${message}`,
58
+ ),
59
+ ),
60
+ transports: [fileTransport],
61
+ });
62
+
63
+ // Swallow any transport-level errors (e.g. disk full) so a logging failure
64
+ // never crashes the dev server.
65
+ fileLogger.on("error", () => {});
66
+ fileTransport.on("error", () => {});
67
+
68
+ /**
69
+ * Write a message to the rotating log file.
70
+ * ANSI escape codes are stripped automatically; console output is unaffected.
71
+ *
72
+ * @param {'info' | 'warn' | 'error' | 'debug'} level
73
+ * @param {string} message
74
+ */
75
+ export function fileLog(level, message) {
76
+ fileLogger.log(level, stripAnsi(message));
77
+ }
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-BFRubm34.js";import{t}from"./react-CM_dJw1Z.js";import{t as n}from"./useMutation-7hG0GuPx.js";import{o as r,t as i}from"./declaration-IA661TBv.js";import{n as a}from"./QueryClientProvider-7oLZ1RtQ.js";import{t as o}from"./useTranslation-CbJtty1g.js";import{t as s}from"./retrieve-axios-error-message-DbnSBc_1.js";import{n as c,t as l}from"./vendor~root-layout~home~mcp~automations-list-DGOI7kQz.js";import{n as u,r as d}from"./custom-toast-handlers-fgD4IYsu.js";import{t as f}from"./utils-CVcuFUYj.js";import{n as p}from"./agent-server-client-options-Dvgeb3x4.js";import{t as m}from"./mcp-client-xEdbDxOL.js";import{a as h}from"./query-keys-CQaji0wJ.js";import{t as ee}from"./modal-backdrop-B1si6TUd.js";import{n as te}from"./modal-classes-9XTtWCtF.js";import{t as g}from"./brand-button-BoiPxAGm.js";import{t as _}from"./styled-tooltip-GXy1qxsO.js";import{t as ne}from"./modal-close-button-DY-rVmld.js";import{t as v}from"./settings-input-DsoZj8Dm.js";import{t as y}from"./v4-BygpdDmc.js";import{t as b}from"./settings-service.api-4u2RKC8k.js";import{a as x,i as S,r as C}from"./use-settings-0qFqC-r6.js";import{t as w}from"./secrets-service-rJqZtDmI.js";function T(e){return[...e.sse_servers.map((e,t)=>({id:`sse-${t}`,type:`sse`,url:typeof e==`string`?e:e.url,api_key:typeof e==`object`?e.api_key:void 0})),...e.stdio_servers.map((e,t)=>({id:`stdio-${t}`,type:`stdio`,name:e.name,command:e.command,args:e.args,env:e.env})),...e.shttp_servers.map((e,t)=>({id:`shttp-${t}`,type:`shttp`,url:typeof e==`string`?e:e.url,api_key:typeof e==`object`?e.api_key:void 0,timeout:typeof e==`object`?e.timeout:void 0}))]}var E=e(t(),1),D=r();function O(e){return e.connectionOptions.filter(e=>e.provider===`mcp`&&!!e.transport)}function k(e){let t=O(e);return t.find(t=>t.id===e.defaultConnectionOptionId)??t[0]}function A(e){return e.auth.strategy!==`oauth2`}function j(e){let t=O(e),n=t.find(t=>t.id===e.defaultConnectionOptionId);return n&&A(n)?n:t.find(A)}function M(e){return k(e)?.transport}var N=`https://mcp.linear.app/sse`,P=`https://mcp.linear.app/mcp`,re=`https://linear.app/docs/mcp`;function ie(e){return e.id===`linear`?{...e,docsUrl:re,installHint:`Authenticate with a Linear API key (Linear → Settings → Security & access) — sent as a Bearer token. Optional when the endpoint accepts your OAuth session.`,connectionOptions:e.connectionOptions.map(e=>e.transport?.kind===`sse`&&I(e.transport.url,N)?{...e,auth:{...e.auth,strategy:`bearer`},transport:{kind:`shttp`,url:P,apiKeyOptional:e.transport.apiKeyOptional}}:e)}:e}function ae(e){return e.map(ie).filter(e=>!!k(e))}var F=e=>{try{return new URL(e)}catch{return null}};function I(e,t){let n=typeof e==`string`?e:``,r=typeof t==`string`?t:``;if(!n||!r)return!1;let i=F(n),a=F(r);return!i||!a?n.replace(/\/+$/,``)===r.replace(/\/+$/,``):i.protocol===a.protocol&&i.host===a.host&&i.pathname.replace(/\/+$/,``)===a.pathname.replace(/\/+$/,``)}function oe(e,t){return t.find(t=>R(e,t))??null}function L(e,t){for(let n of O(e)){let e=oe(n.transport,t);if(e)return e}return null}function R(e,t){if(e.kind===`shttp`){let n=e.url;return t.type===`shttp`&&!!t.url&&I(t.url,n)}if(e.kind===`sse`){let n=e.url;return t.type===`sse`&&!!t.url&&I(t.url,n)}return t.type===`stdio`&&t.name===e.serverName}function z(e,t){return!e.runtimeAvailability||e.runtimeAvailability===`all`?!0:e.runtimeAvailability===t}function B(e){return e.trim().toLowerCase()}function V(e){return e.map((e,t)=>({entry:e,index:t})).sort((e,t)=>(t.entry.popularityRank??0)-(e.entry.popularityRank??0)||e.index-t.index).map(({entry:e})=>e)}function H(e,t){return t.find(t=>t.id===e)}function U(e,t){let n=B(t);return n?[e.name,e.description,e.id,...e.keywords??[]].join(` `).toLowerCase().includes(n):!0}function W(e,t,n){let r=B(n);return r?[e.type,`name`in e?e.name:void 0,`command`in e?e.command:void 0,`args`in e?e.args?.join(` `):void 0,`url`in e?e.url:void 0,t?.name,t?.description,t?.id,...t?.keywords??[]].filter(Boolean).join(` `).toLowerCase().includes(r):!0}function G(e,t){return t.find(t=>O(t).some(t=>R(t.transport,e)))}function K({fieldKey:e,checked:t,onToggle:n}){let{t:r}=o(`openhands`);return(0,D.jsxs)(`label`,{"data-testid":`mcp-install-save-secret-${e}`,className:f(`flex items-center gap-2 px-3 py-2 mt-0.5 rounded-lg border cursor-pointer transition-colors`,t?`border-green-500/35 bg-green-500/10`:`border-[var(--oh-border)] bg-transparent hover:bg-white/[0.03]`),children:[(0,D.jsx)(`input`,{className:`sr-only`,id:`mcp-save-secret-checkbox-${e}`,type:`checkbox`,checked:t,onChange:e=>n(e.target.checked)}),(0,D.jsx)(`span`,{"aria-hidden":`true`,className:f(`relative inline-flex h-[22px] w-[40px] shrink-0 items-center rounded-full border transition-colors duration-200`,t?`border-green-500 bg-green-500`:`border-[var(--oh-border)] bg-surface-raised`),children:(0,D.jsx)(`span`,{className:f(`inline-block size-4 rounded-full transition-transform duration-200`,t?`translate-x-[21px] bg-white`:`translate-x-[2px] bg-[var(--oh-muted)]`)})}),(0,D.jsx)(`span`,{className:`text-sm`,children:r(i.MCP$ALSO_SAVE_AS_SECRET)}),(0,D.jsx)(`code`,{className:f(`ml-auto text-[11px] font-mono tracking-tight border rounded px-1.5 py-0.5`,t?`text-green-500 border-green-500/35 bg-white/[0.04]`:`text-tertiary-alt border-[var(--oh-border)]`),children:e}),(0,D.jsx)(_,{content:r(i.MCP$SAVE_AS_SECRET_TOOLTIP),placement:`top`,children:(0,D.jsx)(`button`,{type:`button`,"aria-label":r(i.MCP$SAVE_AS_SECRET_TOOLTIP),className:`flex items-center justify-center size-[15px] shrink-0 rounded-full border border-[var(--oh-muted)] text-tertiary-alt text-[9px] font-bold cursor-help`,onClick:e=>e.preventDefault(),children:`?`})})]})}var se={xs:`h-4 w-4 rounded [&>svg]:h-2.5 [&>svg]:w-2.5`,sm:`h-5 w-5 rounded-md [&>svg]:h-3 [&>svg]:w-3`,md:`h-10 w-10 rounded-lg [&>svg]:h-5 [&>svg]:w-5`};function q({entry:e,size:t=`md`,className:n,fallback:r,testId:i}){return(0,D.jsx)(`span`,{"aria-hidden":`true`,title:e?.name,"data-testid":i,className:f(`inline-flex shrink-0 items-center justify-center overflow-hidden`,`border border-white/10 shadow-[inset_0_1px_0_rgba(255,255,255,0.18)]`,se[t],n),style:{backgroundColor:e?.iconBg??`var(--oh-color-tertiary)`,color:e?.iconColor??`#FFFFFF`},children:e?c[e.id]??r??l:r??l})}function J(){let e=a(),{data:t}=C();return n({mutationFn:async e=>{if(!t)return;let n=S(t.agent_settings?.mcp_config),r={sse_servers:[...n.sse_servers],stdio_servers:[...n.stdio_servers],shttp_servers:[...n.shttp_servers]};if(e.type===`sse`){let t={url:e.url,...e.api_key&&{api_key:e.api_key}};r.sse_servers.push(t)}else if(e.type===`stdio`){let t={name:e.name,command:e.command,...e.args&&{args:e.args},...e.env&&{env:e.env}};r.stdio_servers.push(t)}else if(e.type===`shttp`){let t={url:e.url,...e.api_key&&{api_key:e.api_key},...e.timeout!==void 0&&{timeout:e.timeout}};r.shttp_servers.push(t)}await b.saveSettings({agent_settings_diff:{mcp_config:x(r)}})},onSuccess:()=>{e.invalidateQueries({queryKey:h.personal()})}})}function ce(e){return e.type===`stdio`?{type:`stdio`,command:e.command,...e.args?.length&&{args:e.args},...e.env&&Object.keys(e.env).length>0&&{env:e.env}}:{type:e.type,url:e.url,...e.api_key?{api_key:e.api_key}:{}}}var le=class{static async testServer(e){let{host:t,apiKey:n}=p(),r=new m({host:t,...n?{apiKey:n}:{}});try{return await r.testServer({server:ce(e),...e.name?{name:e.name}:{},...e.timeout?{timeout:e.timeout}:{}})}finally{r.close()}}};function Y(){return n({mutationFn:e=>le.testServer(e)})}function X(e){return e.length<=3?e.join(`, `):`${e.slice(0,3).join(`, `)} … (+${e.length-3})`}function ue(){let{t:e}=o(`openhands`),t=a();return(0,E.useCallback)((n,r,a)=>{let o=n.filter(e=>a[e.key]&&(r[e.key]??``).trim());o.length!==0&&Promise.allSettled(o.map(e=>w.createSecret(e.key,r[e.key].trim(),e.label))).then(n=>{let r=o.filter((e,t)=>n[t].status===`fulfilled`).map(e=>e.key),a=o.filter((e,t)=>n[t].status===`rejected`).map(e=>e.key);r.length>0&&(t.invalidateQueries({queryKey:[`secrets-search`]}),t.invalidateQueries({queryKey:[`secrets`]}),d(e(i.MCP$SECRETS_SAVED,{keys:X(r)}))),a.length>0&&u(e(i.MCP$SECRETS_SAVE_FAILED,{keys:X(a)}))})},[e,t])}function Z(e){let t=/\[([^\]]+)\]\(([^)]+)\)/g,n=[],r=0;for(let i of e.matchAll(t))i.index>r&&n.push(e.slice(r,i.index)),n.push((0,D.jsx)(`a`,{href:/^https?:\/\//i.test(i[2])?i[2]:`#`,target:`_blank`,rel:`noreferrer`,className:`underline hover:text-white transition-colors`,children:i[1]},i.index)),r=i.index+i[0].length;return r<e.length&&n.push(e.slice(r)),n}function Q(e){return e?.transport.kind!==`shttp`&&e?.transport.kind!==`sse`?!1:[`api_key`,`bearer`,`basic`].includes(e.auth.strategy)}function $(e){return e.transport.kind===`stdio`?e.auth.apiKeyOptional??!1:e.auth.apiKeyOptional??e.transport.apiKeyOptional??!1}function de(e){let t={},n={},r=j(e),i=r?.transport;if(i?.kind===`stdio`){for(let e of i.envFields??[])t[e.key]=``,n[e.key]=e.type===`password`;for(let e of i.argFields??[])t[e.key]=``}else Q(r)&&(t.api_key=``);return{values:t,errors:{},savedAsSecret:n}}function fe({entry:e,onClose:t,onSuccess:n}){let{t:r}=o(`openhands`),{mutate:a,isPending:c}=J(),{mutate:l,isPending:u}=Y(),f=ue(),[p,m]=E.useState(()=>de(e)),h=E.useRef(p);h.current=p;let[_,b]=E.useState(null),x=j(e),S=x?.transport,C=u||c,w=(e,t)=>{m(n=>({...n,values:{...n.values,[e]:t},errors:{...n.errors,[e]:null}})),b(null)},T=(e,t)=>{m(n=>({...n,savedAsSecret:{...n.savedAsSecret,[e]:t}}))},O=e=>{switch(e.error_kind){case`timeout`:return r(i.MCP$TEST_ERROR_TIMEOUT);case`connection`:return r(i.MCP$TEST_ERROR_CONNECTION);default:return r(i.MCP$TEST_ERROR_UNKNOWN,{error:e.error})}},k=o=>{l(o,{onSuccess:c=>{if(!c.ok){b(O(c));return}a(o,{onSuccess:()=>{d(r(i.MCP$INSTALL_SUCCESS)),n?.(e),t(),S?.kind===`stdio`&&f(S.envFields??[],h.current.values,h.current.savedAsSecret)},onError:e=>{b(s(e)||r(i.ERROR$GENERIC))}})},onError:e=>{b(s(e)||r(i.ERROR$GENERIC))}})},A=()=>{if(S?.kind!==`shttp`&&S?.kind!==`sse`||!x)return;let e=p.values.api_key?.trim()??``,t=Q(x);if(t&&!$(x)&&!e){m(e=>({...e,errors:{api_key:r(i.MCP$ERROR_FIELD_REQUIRED)}}));return}k({id:`${S.kind}-${y()}`,type:S.kind,url:S.url,...t&&e&&{api_key:e}})},M=()=>{if(S?.kind!==`stdio`)return;let e=S,t={};for(let n of e.envFields??[])n.required&&!(p.values[n.key]??``).trim()&&(t[n.key]=r(i.MCP$ERROR_FIELD_REQUIRED));for(let n of e.argFields??[])n.required&&!(p.values[n.key]??``).trim()&&(t[n.key]=r(i.MCP$ERROR_FIELD_REQUIRED));if(Object.values(t).some(Boolean)){m(e=>({...e,errors:t}));return}let n={};for(let t of e.envFields??[]){let e=p.values[t.key]?.trim();e&&(n[t.key]=e)}let a=[];for(let t of e.argFields??[]){let e=p.values[t.key]?.trim();if(e)for(let t of e.split(/\s+/))t&&a.push(t)}k({id:`stdio-${y()}`,type:`stdio`,name:e.serverName,command:e.command,args:[...e.args,...a],...Object.keys(n).length>0&&{env:n}})};return(0,D.jsx)(ee,{onClose:t,"aria-label":e.name,children:(0,D.jsxs)(`form`,{"data-testid":`mcp-install-modal`,"data-marketplace-id":e.id,onSubmit:e=>(e.preventDefault(),b(null),S?.kind===`shttp`||S?.kind===`sse`?A():M()),className:`relative bg-base-secondary p-6 rounded-xl flex flex-col gap-4 border border-[var(--oh-border)] w-[520px] max-w-[90vw] max-h-[85vh] overflow-y-auto custom-scrollbar`,children:[(0,D.jsx)(ne,{onClose:t,testId:`mcp-install-modal-close`,disabled:C}),(0,D.jsxs)(`div`,{className:`flex items-start gap-3 pr-6`,children:[(0,D.jsx)(q,{entry:e}),(0,D.jsxs)(`div`,{className:`flex flex-col flex-1`,children:[(0,D.jsx)(`h2`,{className:te,children:e.name}),(0,D.jsx)(`p`,{className:`text-xs text-tertiary-light`,children:e.description})]})]}),e.installHint&&(0,D.jsx)(`p`,{className:`text-xs text-tertiary-light`,children:e.installHint}),e.docsUrl&&(0,D.jsx)(`a`,{href:e.docsUrl,target:`_blank`,rel:`noreferrer`,className:`text-xs text-[var(--oh-muted)] hover:text-white hover:underline self-start transition-colors`,children:r(i.MCP$VIEW_DOCS)}),(0,D.jsx)(`div`,{className:`flex flex-col gap-3`,children:(()=>{if(S?.kind===`shttp`||S?.kind===`sse`){let e=Q(x),t=x?$(x):!1;return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(v,{testId:`mcp-install-field-url`,name:`url`,type:`url`,label:r(i.SETTINGS$MCP_URL),value:S.url,onChange:()=>{},isDisabled:!0,className:`w-full`}),e?(0,D.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,D.jsx)(v,{testId:`mcp-install-field-api_key`,name:`api_key`,type:`password`,label:r(i.SETTINGS$MCP_API_KEY),value:p.values.api_key??``,onChange:e=>w(`api_key`,e),placeholder:r(i.SETTINGS$MCP_API_KEY_PLACEHOLDER),showOptionalTag:t,required:!t,className:`w-full`}),p.errors.api_key&&(0,D.jsx)(`p`,{className:`text-xs text-red-500`,children:p.errors.api_key})]}):null]})}if(S?.kind!==`stdio`)return null;let e=S;return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(v,{testId:`mcp-install-field-command-readonly`,name:`command-readonly`,type:`text`,label:r(i.MCP$COMMAND_LABEL),value:`${e.command} ${e.args.join(` `)}`.trim(),onChange:()=>{},isDisabled:!0,className:`w-full`}),(e.envFields??[]).map(e=>(0,D.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,D.jsx)(v,{testId:`mcp-install-field-${e.key}`,name:e.key,type:e.type===`password`?`password`:`text`,label:e.label,value:p.values[e.key]??``,onChange:t=>w(e.key,t),placeholder:e.placeholder,required:e.required,showOptionalTag:!e.required,className:`w-full`}),e.helperText&&(0,D.jsx)(`p`,{className:`text-xs text-tertiary-alt`,children:Z(e.helperText)}),p.errors[e.key]&&(0,D.jsx)(`p`,{className:`text-xs text-red-500`,children:p.errors[e.key]}),e.key in p.savedAsSecret&&(0,D.jsx)(K,{fieldKey:e.key,checked:p.savedAsSecret[e.key],onToggle:t=>T(e.key,t)})]},e.key)),(e.argFields??[]).map(e=>(0,D.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,D.jsx)(v,{testId:`mcp-install-field-${e.key}`,name:e.key,type:e.type===`password`?`password`:`text`,label:e.label,value:p.values[e.key]??``,onChange:t=>w(e.key,t),placeholder:e.placeholder,required:e.required,showOptionalTag:!e.required,className:`w-full`}),e.helperText&&(0,D.jsx)(`p`,{className:`text-xs text-tertiary-alt`,children:Z(e.helperText)}),p.errors[e.key]&&(0,D.jsx)(`p`,{className:`text-xs text-red-500`,children:p.errors[e.key]})]},e.key))]})})()}),_&&(0,D.jsx)(`p`,{"data-testid":`mcp-install-modal-error`,className:`text-sm text-red-500 whitespace-pre-wrap`,children:_}),(0,D.jsxs)(`div`,{className:`flex justify-end gap-2 mt-2`,children:[(0,D.jsx)(g,{type:`button`,variant:`secondary`,onClick:t,testId:`mcp-install-cancel`,children:r(i.BUTTON$CANCEL)}),(0,D.jsx)(g,{type:`submit`,variant:`primary`,isDisabled:C,testId:`mcp-install-submit`,children:r(u?i.MCP$VERIFYING:c?i.SETTINGS$SAVING:i.MCP$INSTALL_BUTTON)})]})]})})}export{G as a,V as c,W as d,z as f,q as i,H as l,T as m,Y as n,L as o,U as p,J as r,M as s,fe as t,ae as u};
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~lpdshwee-CTmh4bwd.js","assets/rolldown-runtime-BFRubm34.js"])))=>i.map(i=>d[i]);
2
- import{t as e}from"./preload-helper-CT1Z6Pdu.js";var t={name:`@openhands/agent-canvas`,version:`1.0.0-rc.3`,description:`Agent Canvas UI for OpenHands - run AI coding agents with a visual interface`,license:`MIT`,private:!1,type:`module`,repository:{type:`git`,url:`https://github.com/OpenHands/agent-canvas`},homepage:`https://github.com/OpenHands/agent-canvas#readme`,bugs:{url:`https://github.com/OpenHands/agent-canvas/issues`},bin:{"agent-canvas":`bin/agent-canvas.mjs`},engines:{node:`>=22.12.0`},dependencies:{"@heroui/react":`2.8.10`,"@microlink/react-json-view":`1.31.20`,"@monaco-editor/react":`4.7.0`,"@openhands/extensions":`github:OpenHands/extensions#8a6690071e0e9229ae70b30ff0352aff9e6fca21`,"@openhands/typescript-client":`1.24.3`,"@react-router/node":`7.14.2`,"@react-router/serve":`7.14.2`,"@tailwindcss/vite":`4.2.4`,"@tanstack/react-query":`5.100.9`,"@types/shell-quote":`^1.7.5`,"@uidotdev/usehooks":`2.4.1`,"@xterm/addon-fit":`0.11.0`,"@xterm/xterm":`6.0.0`,axios:`1.16.0`,"class-variance-authority":`0.7.1`,clsx:`2.1.1`,downshift:`9.3.2`,"framer-motion":`12.38.0`,i18next:`26.0.8`,"i18next-browser-languagedetector":`8.2.1`,"i18next-http-backend":`4.0.0`,isbot:`5.1.39`,"lucide-react":`1.14.0`,"monaco-editor":`0.55.1`,"posthog-js":`1.372.6`,react:`19.2.5`,"react-dom":`19.2.5`,"react-hot-toast":`2.6.0`,"react-i18next":`17.0.6`,"react-icons":`5.6.0`,"react-markdown":`10.1.0`,"react-router":`7.14.2`,"react-syntax-highlighter":`16.1.1`,"rehype-raw":`7.0.0`,"rehype-sanitize":`6.0.0`,"remark-breaks":`4.0.0`,"remark-gfm":`4.0.1`,"shell-quote":`^1.8.3`,"sirv-cli":`3.0.1`,"socket.io-client":`4.8.3`,"tailwind-merge":`3.5.0`,"tailwind-scrollbar":`4.0.2`,"unist-util-visit":`5.1.0`,uuid:`14.0.0`,vite:`8.0.10`,zustand:`5.0.12`},scripts:{dev:`node --env-file-if-exists=.env scripts/dev-with-automation.mjs`,"dev:static":`node --env-file-if-exists=.env scripts/dev-static.mjs`,"dev:extra-backend":`node --env-file-if-exists=.env scripts/dev-extra-backend.mjs`,"dev:minimal":`node --env-file-if-exists=.env scripts/dev-safe.mjs`,"dev:frontend":`npm run make-i18n && cross-env VITE_MOCK_API=false react-router dev`,"dev:mock":`npm run make-i18n && cross-env VITE_MOCK_API=true react-router dev`,build:`npm run build:app`,"build:mock":`npm run make-i18n && cross-env VITE_MOCK_API=true react-router build`,start:`npx sirv-cli build/ --single`,test:`npm run make-i18n && vitest run`,"test:e2e":`playwright test --pass-with-no-tests`,"test:e2e:live":`node --env-file-if-exists=.env tests/e2e/live/scripts/run-live-e2e.mjs`,"test:e2e:mock-llm":`playwright test --config=playwright.mock-llm.config.ts`,"test:e2e:mock-llm:docker":`playwright test --config=playwright.mock-llm-docker.config.ts`,"test:e2e:snapshots":`playwright test tests/e2e/snapshots --project=chromium --retries=0`,"test:e2e:snapshots:update":`playwright test tests/e2e/snapshots --project=chromium --update-snapshots`,"test:coverage":`npm run make-i18n && vitest run --coverage`,dev_wsl:`VITE_WATCH_USE_POLLING=true vite`,preview:`vite preview`,"make-i18n":`node scripts/make-i18n-translations.cjs`,prelint:`npm run make-i18n`,lint:`npm run typecheck && eslint src && prettier --check src/**/*.{ts,tsx}`,"lint:fix":`eslint src --fix && prettier --write src/**/*.{ts,tsx}`,prepare:`husky`,typecheck:`react-router typegen && tsc`,"typecheck:staged":`react-router typegen && npx tsc --noEmit --skipLibCheck`,"check-translation-completeness":`node scripts/check-translation-completeness.cjs`,"build:app":`npm run make-i18n && react-router build`,"build:lib":`npm run make-i18n && react-router typegen && cross-env BUILD_LIB=true VITE_APP_ENV=production vite build && tsc -p tsconfig.lib.json`,"build:docker":`node scripts/docker-build.mjs`},"lint-staged":{"src/**/*.{ts,tsx,js}":[`eslint --fix`,`prettier --write`],"src/**/*.{ts,tsx}":[`bash -c 'npm run typecheck:staged'`],"src/**/*":[`npm run check-translation-completeness`]},devDependencies:{"@eslint/eslintrc":`3.3.1`,"@eslint/js":`9.39.4`,"@mswjs/socket.io-binding":`0.2.0`,"@playwright/test":`1.59.1`,"@react-router/dev":`7.14.2`,"@tailwindcss/typography":`0.5.19`,"@tanstack/eslint-plugin-query":`5.100.9`,"@testing-library/dom":`10.4.1`,"@testing-library/jest-dom":`6.9.1`,"@testing-library/react":`16.3.2`,"@testing-library/user-event":`14.6.1`,"@types/mdast":`4.0.4`,"@types/node":`25.6.0`,"@types/react":`19.2.14`,"@types/react-dom":`19.2.3`,"@types/react-syntax-highlighter":`15.5.13`,"@typescript-eslint/eslint-plugin":`8.59.2`,"@typescript-eslint/parser":`8.59.2`,"@vercel/react-router":`1.3.0`,"@vitest/coverage-v8":`4.1.5`,"cross-env":`10.1.0`,eslint:`9.39.4`,"eslint-config-prettier":`10.1.8`,"eslint-import-resolver-typescript":`4.4.4`,"eslint-plugin-i18next":`6.1.4`,"eslint-plugin-import-x":`4.16.2`,"eslint-plugin-jsx-a11y":`6.10.2`,"eslint-plugin-prettier":`5.5.5`,"eslint-plugin-react":`7.37.5`,"eslint-plugin-react-hooks":`7.1.1`,"eslint-plugin-unused-imports":`4.4.1`,globals:`16.5.0`,husky:`9.1.7`,jsdom:`29.1.1`,"lint-staged":`16.4.0`,msw:`2.14.2`,"postcss-prefix-selector":`2.1.1`,prettier:`3.8.3`,tailwindcss:`4.2.4`,typescript:`6.0.3`,"vite-plugin-svgr":`5.2.0`,vitest:`4.1.5`},packageManager:`npm@10.5.0`,volta:{node:`22.12.0`},msw:{workerDirectory:[`public`]},overrides:{dompurify:`3.3.2`},main:`./dist/index.cjs`,module:`./dist/index.js`,types:`./dist/index.d.ts`,files:[`dist`,`bin`,`build`,`config`,`scripts`,`tools`],exports:{".":{types:`./dist/index.d.ts`,import:`./dist/index.js`,require:`./dist/index.cjs`},"./browser":{types:`./dist/components/browser/index.d.ts`,import:`./dist/components/browser/index.js`,require:`./dist/components/browser/index.cjs`},"./conversation":{types:`./dist/components/conversation/index.d.ts`,import:`./dist/components/conversation/index.js`,require:`./dist/components/conversation/index.cjs`},"./files":{types:`./dist/components/files/index.d.ts`,import:`./dist/components/files/index.js`,require:`./dist/components/files/index.cjs`},"./settings":{types:`./dist/components/settings/index.d.ts`,import:`./dist/components/settings/index.js`,require:`./dist/components/settings/index.cjs`},"./sidebar":{types:`./dist/components/sidebar/index.d.ts`,import:`./dist/components/sidebar/index.js`,require:`./dist/components/sidebar/index.cjs`},"./terminal":{types:`./dist/components/terminal/index.d.ts`,import:`./dist/components/terminal/index.js`,require:`./dist/components/terminal/index.cjs`},"./i18n":{types:`./dist/i18n/index.d.ts`,import:`./dist/i18n/index.js`,require:`./dist/i18n/index.cjs`},"./package.json":`./package.json`},peerDependencies:{react:`19.2.5`,"react-dom":`19.2.5`,"react-router":`7.14.2`}},n=`openhands-telemetry-consent`,r=`openhands-telemetry-first-use`,i=`openhands-telemetry-session`,a=`phc_kBtz5nKmxVRRQ7HtPwr2QX9eMC5j65zE86QKocVNwb4U`,o=`https://z.openhands.dev`,s=`https://us.posthog.com`,c=!1,l=null;function u(){return typeof window<`u`&&typeof localStorage<`u`}async function d(){if(!u())return null;if(l)return l;try{let{default:t}=await e(async()=>{let{default:e}=await import(`./vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~lpdshwee-CTmh4bwd.js`).then(e=>e.n);return{default:e}},__vite__mapDeps([0,1]));return l=t,t}catch{return null}}function f(){return typeof process<`u`&&{}?.DO_NOT_TRACK===`1`||typeof navigator<`u`&&(navigator.doNotTrack===`1`||typeof window<`u`&&window.doNotTrack===`1`)}async function p(e=!1){if(c)return l;let n=await d();return n?(n.init(a,{api_host:o,ui_host:s,opt_out_capturing_by_default:!e,capture_pageview:!1,autocapture:!1,persistence:`localStorage`,disable_session_recording:!0,loaded:e=>{e.register({package_name:t.name,package_version:t.version})}}),c=!0,n):null}function m(){if(!u())return`pending`;if(f())return`denied`;try{let e=localStorage.getItem(n);if(e===`granted`||e===`denied`)return e}catch{}return`pending`}async function h(e){if(u())try{localStorage.setItem(n,e);let t=await p();if(!t)return;e===`granted`?t.opt_in_capturing():t.opt_out_capturing()}catch{}}function g(){return m()===`granted`}function _(){if(!u())return!1;try{return localStorage.getItem(r)===`true`}catch{return!1}}function v(){if(u())try{localStorage.setItem(r,`true`)}catch{}}async function y(){if(f()||_())return;let e=await p(!0);e&&((e.has_opted_out_capturing?.()??!1)&&e.opt_in_capturing(),e.capture(`canvas_install`,{platform:typeof navigator<`u`?navigator.platform:`unknown`,user_agent:typeof navigator<`u`?navigator.userAgent:`unknown`,referrer:typeof document<`u`?document.referrer:``,url_origin:typeof window<`u`?window.location.origin:``,embedded:typeof window<`u`&&window.self!==window.top}),v(),m()!==`granted`&&e.opt_out_capturing())}function b(){if(!u())return!1;try{return sessionStorage.getItem(i)===`true`}catch{return!1}}function x(){if(u())try{sessionStorage.setItem(i,`true`)}catch{}}async function S(){if(!g()||b())return;let e=await p();e&&(e.capture(`canvas_new_session`,{is_first_use:!_()}),x())}async function C(e,t={}){if(!g())return;let n=await p();n&&n.capture(e,t)}async function w(){if(u())try{localStorage.removeItem(n),localStorage.removeItem(r),sessionStorage.removeItem(i),c&&l&&l.reset()}catch{}}export{y as a,C as i,m as n,S as o,h as r,w as t};