ds-harness-remote 0.3.34 → 0.3.36

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.
package/dist/client.js CHANGED
@@ -1626,10 +1626,13 @@ Minimum version required to store current data is: ` + bestVersion + `.
1626
1626
  function shouldUseRemoteFileViewer(status) {
1627
1627
  return status.mode === "remote" && status.remoteFeatures?.fileViewer === !0;
1628
1628
  }
1629
- var REMOTE_FILE_SAVE_AS_MAX_BYTES = 100 * 1024 * 1024;
1629
+ var REMOTE_FILE_SAVE_AS_MAX_BYTES = 100 * 1024 * 1024, REMOTE_FILE_FAST_SAVE_AS_MAX_BYTES = 1024 * 1024 * 1024;
1630
1630
  function shouldAllowRemoteFileSaveAs(status) {
1631
1631
  return shouldUseRemoteFileViewer(status) && (status.transport === "LAN" || status.transport === "P2P" || status.transport === "TURN");
1632
1632
  }
1633
+ function remoteFileSaveAsMaxBytes(status) {
1634
+ return status.transport === "LAN" || status.transport === "P2P" ? REMOTE_FILE_FAST_SAVE_AS_MAX_BYTES : REMOTE_FILE_SAVE_AS_MAX_BYTES;
1635
+ }
1633
1636
  function createRemoteFileContentProvider(call, options = {}) {
1634
1637
  return {
1635
1638
  id: "dsh-remote-files",
@@ -1637,7 +1640,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
1637
1640
  supports: () => !0,
1638
1641
  saveAsAllowed: () => ({
1639
1642
  allowed: currentSaveAsAllowed(options.saveAsAllowed),
1640
- maxBytes: options.saveAsMaxBytes ?? REMOTE_FILE_SAVE_AS_MAX_BYTES
1643
+ maxBytes: currentSaveAsMaxBytes(options.saveAsMaxBytes)
1641
1644
  }),
1642
1645
  async stat(locator, signal) {
1643
1646
  let value = await call("fileviewer.stat", { path: locator }, signal);
@@ -1681,6 +1684,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
1681
1684
  function currentSaveAsAllowed(value) {
1682
1685
  return typeof value == "function" ? value() : value === !0;
1683
1686
  }
1687
+ function currentSaveAsMaxBytes(value) {
1688
+ return typeof value == "function" ? value() : value ?? REMOTE_FILE_SAVE_AS_MAX_BYTES;
1689
+ }
1684
1690
  function decodeBase64(value) {
1685
1691
  let binary = atob(value), bytes = new Uint8Array(binary.length);
1686
1692
  for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
@@ -1737,6 +1743,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
1737
1743
  switchTarget: "Switch Local / Remote Harness target",
1738
1744
  harnessTarget: "Harness target",
1739
1745
  close: "Close",
1746
+ refreshRemote: "Refresh remote hosts",
1747
+ refreshRemoteShort: "Refresh",
1740
1748
  local: "Local",
1741
1749
  remoteTarget: "Remote \xB7 {name}",
1742
1750
  thisMachineLocal: "This machine (Local)",
@@ -1932,6 +1940,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
1932
1940
  switchTarget: "\u5207\u6362\u672C\u5730\u6216\u8FDC\u7A0B Harness",
1933
1941
  harnessTarget: "Harness \u76EE\u6807",
1934
1942
  close: "\u5173\u95ED",
1943
+ refreshRemote: "\u5237\u65B0\u8FDC\u7A0B\u4E3B\u673A",
1944
+ refreshRemoteShort: "\u5237\u65B0",
1935
1945
  local: "\u672C\u5730",
1936
1946
  remoteTarget: "\u8FDC\u7A0B \xB7 {name}",
1937
1947
  thisMachineLocal: "\u6B64\u8BBE\u5907\uFF08\u672C\u5730\uFF09",
@@ -2070,7 +2080,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
2070
2080
  signInClientDescription: "\u4E00\u6B21\u8FDE\u63A5\uFF0C\u968F\u65F6\u53EF\u7528\u3002",
2071
2081
  startSignIn: "\u5F00\u59CB\u767B\u5F55",
2072
2082
  allowControlCurrentDevice: "\u5141\u8BB8\u63A7\u5236\u5F53\u524D\u8BBE\u5907",
2073
- exitRemoteAccount: "\u9000\u51FA",
2083
+ exitRemoteAccount: "\u9000\u51FA\u8D26\u53F7",
2074
2084
  githubLogin: "GitHub \u626B\u7801",
2075
2085
  zhihuLogin: "\u77E5\u4E4E\u626B\u7801",
2076
2086
  scanWithGitHub: "\u4F7F\u7528 GitHub \u626B\u7801\u767B\u5F55",
@@ -2085,6 +2095,12 @@ Minimum version required to store current data is: ` + bestVersion + `.
2085
2095
  function normalizedPreferredTransports(value) {
2086
2096
  return value === void 0 || value.length === 0 ? [...defaultPreferredTransports] : [...value];
2087
2097
  }
2098
+ function initialProbeTransports(value) {
2099
+ let transports = normalizedPreferredTransports(value);
2100
+ if (transports.length === 1) return transports;
2101
+ let directTransports = transports.filter((transport) => transport === "lan" || transport === "p2p");
2102
+ return directTransports.length > 0 ? directTransports : transports.includes("turn") ? ["turn"] : ["relay"];
2103
+ }
2088
2104
  function formatLocalTime(value) {
2089
2105
  let date = new Date(value);
2090
2106
  return Number.isNaN(date.getTime()) ? "\u2014" : date.toLocaleString();
@@ -2115,7 +2131,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
2115
2131
  return value === "lan" ? { label: "remoteProgressProbeLan", detail: "remoteProgressProbeLanDetail" } : value === "p2p" ? { label: "remoteProgressProbeP2p", detail: "remoteProgressProbeP2pDetail" } : value === "turn" ? { label: "remoteProgressProbeTurn", detail: "remoteProgressProbeTurnDetail" } : { label: "remoteProgressProbeRelay", detail: "remoteProgressProbeRelayDetail" };
2116
2132
  }
2117
2133
  function connectHostProgressSteps(preferredTransports) {
2118
- let transports = normalizedPreferredTransports(preferredTransports), probeTransports = transports.filter((transport) => transport !== "relay" || transports.length === 1);
2134
+ let transports = normalizedPreferredTransports(preferredTransports), probeTransports = initialProbeTransports(preferredTransports);
2119
2135
  return [
2120
2136
  { label: "remoteProgressCheckingHost", detail: "remoteProgressCheckingHostDetail", percent: 12 },
2121
2137
  { label: "remoteProgressAuthorizingPeer", detail: "remoteProgressAuthorizingPeerDetail", percent: 30, delayMs: 280 },
@@ -2448,7 +2464,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
2448
2464
  );
2449
2465
  }
2450
2466
  function RemoteWorkspaceAction(props) {
2451
- let { t } = props, [open, setOpen] = React.useState(!1), [status, setStatus] = React.useState(void 0), [devices, setDevices] = React.useState([]), [selectedHost, setSelectedHost] = React.useState(void 0), [workspaces, setWorkspaces] = React.useState([]), [directory, setDirectory] = React.useState(void 0), [path, setPath] = React.useState(""), [addingWorkspace, setAddingWorkspace] = React.useState(!1), [busy, setBusy] = React.useState(!1), [needsAuthorization, setNeedsAuthorization] = React.useState(!1), [email, setEmail] = React.useState(""), [password, setPassword] = React.useState(""), [loginMethod, setLoginMethod] = React.useState(props.preferredQrProvider), [loginMethodManuallySelected, setLoginMethodManuallySelected] = React.useState(!1), [qrSession, setQrSession] = React.useState(void 0), [qrImage, setQrImage] = React.useState(void 0), [qrExpired, setQrExpired] = React.useState(!1), [progress, setProgress] = React.useState(void 0), progressRun = React.useRef(0), [notice, setNotice] = React.useState(void 0), [error, setError] = React.useState(void 0);
2467
+ let { t } = props, [open, setOpen] = React.useState(!1), [status, setStatus] = React.useState(void 0), [devices, setDevices] = React.useState([]), [selectedHost, setSelectedHost] = React.useState(void 0), [workspaces, setWorkspaces] = React.useState([]), [directory, setDirectory] = React.useState(void 0), [path, setPath] = React.useState(""), [addingWorkspace, setAddingWorkspace] = React.useState(!1), [busy, setBusy] = React.useState(!1), [needsAuthorization, setNeedsAuthorization] = React.useState(!1), [email, setEmail] = React.useState(""), [password, setPassword] = React.useState(""), [loginMethod, setLoginMethod] = React.useState(props.preferredQrProvider), [loginMethodManuallySelected, setLoginMethodManuallySelected] = React.useState(!1), [qrSession, setQrSession] = React.useState(void 0), [qrImage, setQrImage] = React.useState(void 0), [qrExpired, setQrExpired] = React.useState(!1), [progress, setProgress] = React.useState(void 0), progressRun = React.useRef(0), qrFlowRun = React.useRef(0), [notice, setNotice] = React.useState(void 0), [error, setError] = React.useState(void 0);
2452
2468
  React.useEffect(() => {
2453
2469
  if (!open) return;
2454
2470
  let closeOnEscape = (event) => {
@@ -2465,6 +2481,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
2465
2481
  };
2466
2482
  }, [status?.mode]);
2467
2483
  let startQrLogin = async (provider) => {
2484
+ let run = ++qrFlowRun.current;
2468
2485
  setBusy(!0), setError(void 0), setQrExpired(!1);
2469
2486
  try {
2470
2487
  let session = await props.control("client.account.qr.start", { provider }), image = await import_qrcode.default.toDataURL(session.scanUrl, {
@@ -2472,34 +2489,49 @@ Minimum version required to store current data is: ` + bestVersion + `.
2472
2489
  margin: 1,
2473
2490
  errorCorrectionLevel: "L"
2474
2491
  });
2492
+ if (run !== qrFlowRun.current) return;
2475
2493
  setQrSession(session), setQrImage(image);
2476
2494
  } catch (reason) {
2477
- setError(messageOf(reason));
2495
+ run === qrFlowRun.current && setError(messageOf(reason));
2478
2496
  } finally {
2479
- setBusy(!1);
2497
+ run === qrFlowRun.current && setBusy(!1);
2480
2498
  }
2481
2499
  };
2482
2500
  React.useEffect(() => {
2483
2501
  !open || !needsAuthorization || loginMethod === "password" || qrSession !== void 0 || qrExpired || startQrLogin(loginMethod);
2484
2502
  }, [open, needsAuthorization, loginMethod, qrSession, qrExpired]), React.useEffect(() => {
2485
2503
  if (!open || loginMethod === "password" || qrSession === void 0) return;
2486
- let active = !0, poll = () => {
2487
- props.control("client.account.qr.poll", { qrId: qrSession.qrId }).then(async (result) => {
2488
- active && (result.status === "complete" ? (setDevices(await props.control("devices")), setStatus(await props.control("status")), setNeedsAuthorization(!1), setQrSession(void 0), setQrImage(void 0)) : result.status === "expired" && (setQrExpired(!0), setQrSession(void 0), setQrImage(void 0)));
2504
+ let active = !0, polling = !1, settled = !1, run = qrFlowRun.current, timer, poll = () => {
2505
+ polling || settled || (polling = !0, props.control("client.account.qr.poll", { qrId: qrSession.qrId }).then(async (result) => {
2506
+ if (!(!active || settled || run !== qrFlowRun.current))
2507
+ if (result.status === "complete") {
2508
+ settled = !0, timer !== void 0 && window.clearInterval(timer), setBusy(!0), setError(void 0), setQrExpired(!1), setNeedsAuthorization(!1);
2509
+ try {
2510
+ let [nextDevices, nextStatus] = await Promise.all([
2511
+ props.control("devices"),
2512
+ props.control("status")
2513
+ ]);
2514
+ active && run === qrFlowRun.current && (setDevices(nextDevices), setStatus(nextStatus));
2515
+ } catch (reason) {
2516
+ active && run === qrFlowRun.current && setError(messageOf(reason));
2517
+ } finally {
2518
+ run === qrFlowRun.current && (setQrSession(void 0), setQrImage(void 0), setBusy(!1));
2519
+ }
2520
+ } else result.status === "expired" && (settled = !0, timer !== void 0 && window.clearInterval(timer), setQrExpired(!0), setQrSession(void 0), setQrImage(void 0));
2489
2521
  }).catch((reason) => {
2490
- active && setError(messageOf(reason));
2491
- });
2522
+ active && !settled && run === qrFlowRun.current && setError(messageOf(reason));
2523
+ }).finally(() => {
2524
+ polling = !1;
2525
+ }));
2492
2526
  };
2493
- poll();
2494
- let timer = window.setInterval(poll, 1500);
2495
- return () => {
2496
- active = !1, window.clearInterval(timer);
2527
+ return poll(), timer = window.setInterval(poll, 1500), () => {
2528
+ active = !1, timer !== void 0 && window.clearInterval(timer);
2497
2529
  };
2498
2530
  }, [open, loginMethod, qrSession]), React.useEffect(() => {
2499
- loginMethodManuallySelected || loginMethod === props.preferredQrProvider || (setLoginMethod(props.preferredQrProvider), setQrSession(void 0), setQrImage(void 0), setQrExpired(!1), setError(void 0));
2531
+ loginMethodManuallySelected || loginMethod === props.preferredQrProvider || (qrFlowRun.current += 1, setLoginMethod(props.preferredQrProvider), setQrSession(void 0), setQrImage(void 0), setQrExpired(!1), setError(void 0));
2500
2532
  }, [props.preferredQrProvider, loginMethodManuallySelected]);
2501
2533
  let selectLoginMethod = (method) => {
2502
- setLoginMethodManuallySelected(!0), method !== loginMethod && (setLoginMethod(method), setQrSession(void 0), setQrImage(void 0), setQrExpired(!1), setError(void 0));
2534
+ setLoginMethodManuallySelected(!0), method !== loginMethod && (qrFlowRun.current += 1, setLoginMethod(method), setQrSession(void 0), setQrImage(void 0), setQrExpired(!1), setError(void 0));
2503
2535
  }, orderedQrProviders = props.preferredQrProvider === "zhihu" ? ["zhihu", "github"] : ["github", "zhihu"], qrLoginTab = (provider) => React.createElement("button", {
2504
2536
  key: provider,
2505
2537
  type: "button",
@@ -2545,21 +2577,30 @@ Minimum version required to store current data is: ` + bestVersion + `.
2545
2577
  setBusy(!1);
2546
2578
  }
2547
2579
  }
2548
- }, show = async () => {
2549
- setOpen(!0), setBusy(!0), setNotice(void 0), setError(void 0);
2580
+ }, refreshRemote = async () => {
2581
+ setBusy(!0), setNotice(void 0), setError(void 0);
2550
2582
  try {
2551
2583
  let nextStatus = await props.control("status");
2552
- if (setStatus(nextStatus), nextStatus.available)
2553
- try {
2554
- setDevices(await props.control("devices")), setNeedsAuthorization(!1);
2555
- } catch {
2556
- setNeedsAuthorization(!0);
2584
+ if (setStatus(nextStatus), !nextStatus.available) {
2585
+ setDevices([]), setNeedsAuthorization(!1), setSelectedHost(void 0), setWorkspaces([]), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
2586
+ return;
2587
+ }
2588
+ try {
2589
+ let nextDevices = await props.control("devices");
2590
+ if (setDevices(nextDevices), setNeedsAuthorization(!1), selectedHost !== void 0) {
2591
+ let nextSelectedHost = nextDevices.find((device) => device.deviceId === selectedHost.deviceId);
2592
+ nextSelectedHost === void 0 ? (setSelectedHost(void 0), setWorkspaces([]), setPath(""), setAddingWorkspace(!1), setDirectory(void 0)) : setSelectedHost(nextSelectedHost);
2557
2593
  }
2594
+ } catch {
2595
+ setDevices([]), setNeedsAuthorization(!0), setSelectedHost(void 0), setWorkspaces([]), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
2596
+ }
2558
2597
  } catch (reason) {
2559
2598
  setError(messageOf(reason));
2560
2599
  } finally {
2561
2600
  setBusy(!1);
2562
2601
  }
2602
+ }, show = async () => {
2603
+ setOpen(!0), await refreshRemote();
2563
2604
  }, signInClient = async () => {
2564
2605
  if (!(email.trim() === "" || password === "")) {
2565
2606
  setBusy(!0), setError(void 0);
@@ -2667,7 +2708,19 @@ Minimum version required to store current data is: ` + bestVersion + `.
2667
2708
  React.createElement("strong", null, t("remoteTitle")),
2668
2709
  React.createElement("p", null, t("remoteDescription"))
2669
2710
  ),
2670
- React.createElement("button", { type: "button", onClick: () => setOpen(!1), "aria-label": t("close") }, "\xD7")
2711
+ React.createElement(
2712
+ "div",
2713
+ { className: "dshRemotePageActions" },
2714
+ React.createElement("button", {
2715
+ type: "button",
2716
+ className: "dshRemotePageRefresh",
2717
+ disabled: busy,
2718
+ title: t("refreshRemote"),
2719
+ "aria-label": t("refreshRemote"),
2720
+ onClick: () => void refreshRemote()
2721
+ }, t("refreshRemoteShort")),
2722
+ React.createElement("button", { type: "button", onClick: () => setOpen(!1), "aria-label": t("close") }, "\xD7")
2723
+ )
2671
2724
  ),
2672
2725
  React.createElement(
2673
2726
  "main",
@@ -3267,7 +3320,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
3267
3320
  ".dshRemoteSessionHeader{left:auto;right:148px;transform:none;max-width:calc(100vw - 420px)}@media(max-width:760px){.dshRemoteSessionHeader{left:auto;right:104px;transform:none;max-width:calc(100vw - 124px)}}",
3268
3321
  ".dshRemoteModeButton:focus-visible,.dshRemotePage button:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}",
3269
3322
  ".dshRemotePage{width:min(720px,100%);max-height:min(760px,calc(100vh - 40px));display:flex;flex-direction:column;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:14px;overflow:hidden;animation:dshRemotePageIn .18s cubic-bezier(.25,1,.5,1)}",
3270
- ".dshRemotePageHeader{min-height:72px;display:flex;align-items:center;justify-content:space-between;gap:24px;padding:14px 24px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dshRemotePageIntro{min-width:0;flex:1}.dshRemotePageHeader strong{display:block;font-size:18px;line-height:1.4}.dshRemotePageHeader p{min-width:0;max-width:70ch;margin:3px 0 0;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.5}.dshRemotePageHeader>button{width:40px;height:40px;flex:0 0 auto;border:0;border-radius:8px;background:transparent;color:inherit;font-size:24px;cursor:pointer}.dshRemotePageHeader>button:hover{background:var(--dsw-alias-interactive-bg-hover)}",
3323
+ ".dshRemotePageHeader{min-height:72px;display:flex;align-items:center;justify-content:space-between;gap:24px;padding:14px 24px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dshRemotePageIntro{min-width:0;flex:1}.dshRemotePageHeader strong{display:block;font-size:18px;line-height:1.4}.dshRemotePageHeader p{min-width:0;max-width:70ch;margin:3px 0 0;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.5}.dshRemotePageActions{flex:0 0 auto;display:flex;align-items:center;gap:4px}.dshRemotePageActions>button{height:40px;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;border:0;border-radius:8px;background:transparent;color:inherit;line-height:1;cursor:pointer}.dshRemotePageActions>button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.dshRemotePageActions>button:disabled{opacity:.45;cursor:default}.dshRemotePageRefresh{min-width:48px;padding:0 10px;font:inherit;font-size:13px}.dshRemotePageActions>button:not(.dshRemotePageRefresh){width:40px;padding:0;font-size:24px}",
3271
3324
  ".dshRemotePageBody{padding:24px;overflow:auto;display:flex;flex-direction:column;gap:24px}.dshRemotePageBody button{font:inherit;color:inherit}",
3272
3325
  ".dshRemoteSectionHeading{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:10px}.dshRemoteSectionTitle{min-width:0;display:flex;align-items:center;gap:10px}.dshRemoteSectionTitle>strong{font-size:14px}.dshRemoteSectionActions{display:flex;align-items:center;gap:14px}.dshRemoteSectionActions>button{border:0;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;padding:5px 0;font-size:12px}.dshRemoteSectionActions>button:hover:not(:disabled){color:var(--dsw-alias-label-primary);text-decoration:underline}",
3273
3326
  ".dshRemoteSectionHeading>.dshRemoteAddWorkspace{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;padding:0;border-radius:50%;font-size:20px;line-height:1}.dshRemoteSectionHeading>.dshRemoteAddWorkspace:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}",
@@ -3279,11 +3332,11 @@ Minimum version required to store current data is: ` + bestVersion + `.
3279
3332
  ".dshRemoteFolderBrowser{margin-top:14px}.dshRemoteFolderBrowser>p,.dshRemoteFolderList>p{margin:12px 0;color:var(--dsw-alias-label-secondary);font-size:13px}.dshRemoteFolderList{max-height:260px;overflow:auto;border-block:1px solid var(--dsw-alias-border-l2)}.dshRemoteFolderList>button{width:100%;min-height:42px;display:flex;align-items:center;gap:9px;border:0;border-bottom:1px solid var(--dsw-alias-border-l2);background:transparent;padding:7px 6px;text-align:left;cursor:pointer}.dshRemoteFolderList>button:hover{background:var(--dsw-alias-interactive-bg-hover)}.dshRemoteFolderBrowser>small{display:block;margin-top:8px;color:var(--dsw-alias-state-warn-label)}",
3280
3333
  ".dshRemotePathField{display:flex;flex-direction:column;gap:6px;margin-top:20px}.dshRemotePathField>span{font-size:13px;font-weight:600}.dshRemotePathField>input{min-height:40px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3);color:inherit;padding:0 12px;font:inherit}.dshRemotePathField>small{color:var(--dsw-alias-label-secondary)}",
3281
3334
  ".dshRemoteOpenBar{position:sticky;bottom:-96px;display:flex;align-items:center;justify-content:space-between;gap:20px;margin-top:20px;padding:14px 0;background:var(--dsw-alias-bg-layer-1);border-top:1px solid var(--dsw-alias-border-l2)}.dshRemoteOpenBar>div{min-width:0;display:flex;flex-direction:column;gap:3px}.dshRemoteOpenBar span{color:var(--dsw-alias-label-secondary);font-size:12px}.dshRemoteOpenBar strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.dshRemoteOpenBar>button,.dshRemoteEnable>button{min-height:40px;flex:0 0 auto;border:0;border-radius:8px;background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-1);padding:8px 16px;cursor:pointer}.dshRemoteOpenBar>button:disabled,.dshRemoteEnable>button:disabled{opacity:.5;cursor:default}",
3282
- ".dshRemoteEnable{max-width:600px;display:flex;flex-direction:column;align-items:flex-start;gap:10px}.dshRemoteEnable p{margin:0;color:var(--dsw-alias-label-secondary);line-height:1.5}",
3335
+ ".dshRemoteEnable{box-sizing:border-box;width:min(440px,100%);max-width:100%;min-height:388px;margin:0 auto;display:flex;flex-direction:column;align-items:stretch;gap:10px}.dshRemoteEnable p{margin:0;color:var(--dsw-alias-label-secondary);line-height:1.5}",
3283
3336
  '.dshRemoteLoginTabs{width:min(440px,100%);display:flex;border-bottom:1px solid var(--dsw-alias-border-l2)}.dshRemoteLoginTabs>button{position:relative;min-height:38px;border:0;background:transparent;color:var(--dsw-alias-label-secondary);padding:6px 14px;font:inherit;font-size:13px;cursor:pointer}.dshRemoteLoginTabs>button:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.dshRemoteLoginTabs>button.isActive{color:var(--dsw-alias-label-primary);font-weight:600}.dshRemoteLoginTabs>button.isActive::after{content:"";position:absolute;right:12px;bottom:-1px;left:12px;height:2px;border-radius:2px 2px 0 0;background:var(--dsw-alias-brand-primary)}.dshRemoteLoginTabs>button:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px;border-radius:6px}',
3284
3337
  ".dshRemoteClientLogin{width:min(440px,100%);display:flex;flex-direction:column;gap:8px}.dshRemoteClientLogin input{min-height:40px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3);color:inherit;padding:0 12px;font:inherit}.dshRemoteClientLogin button{align-self:flex-start;min-height:40px;border:0;border-radius:8px;background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-1);padding:8px 16px;cursor:pointer}",
3285
3338
  ".dshRemoteQrLogin{width:min(440px,100%);display:flex;flex-direction:column;align-items:center;gap:8px;padding:6px 0 2px;text-align:center}.dshRemoteQrLogin img,.dshRemoteQrPlaceholder{box-sizing:border-box;width:200px;height:200px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:#fff;padding:8px}.dshRemoteQrOpen{display:flex;flex-direction:column;align-items:center;gap:5px;color:var(--dsw-alias-label-secondary);font-size:12px;text-decoration:none}.dshRemoteQrOpen:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.dshRemoteQrOpen:hover img{border-color:var(--dsw-alias-label-dimmed)}.dshRemoteQrOpen:focus-visible{border-radius:12px;outline:2px solid var(--dsw-alias-brand-primary);outline-offset:3px}.dshRemoteQrPlaceholder{display:flex;align-items:center;justify-content:center;color:var(--dsw-alias-label-secondary)}.dshRemoteQrLogin>strong{font-size:14px}.dshRemoteQrLogin>p{max-width:48ch;margin:0;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5}.dshRemoteQrLogin>.dshRemoteServiceAddress{margin-top:2px;color:var(--dsw-alias-label-tertiary)}.dshRemoteServiceAddress>a{color:var(--dsw-alias-label-secondary);text-decoration:none}.dshRemoteServiceAddress>a:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.dshRemoteQrLogin>button,.dshRemoteClientLogin>.dshRemoteLoginSwitch{min-height:32px;border:0;background:transparent;color:var(--dsw-alias-label-secondary);padding:4px 8px;font:inherit;font-size:12px;cursor:pointer}.dshRemoteQrLogin>button:hover,.dshRemoteClientLogin>.dshRemoteLoginSwitch:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.dshRemoteClientLogin>.dshRemoteLoginSwitch{align-self:flex-start;background:transparent;color:var(--dsw-alias-label-secondary);padding-left:0}",
3286
- ".dshRemoteEnable{box-sizing:border-box;width:100%;min-height:388px}.dshRemoteLoginHeading{max-width:100%;display:flex;align-items:baseline;gap:10px;overflow:hidden;white-space:nowrap}.dshRemoteLoginTitle{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dshRemoteLoginHeading>span{flex:0 0 auto;color:var(--dsw-alias-label-secondary);font-size:13px;font-weight:400}.dshRemoteLoginTabs{width:100%}.dshRemoteLoginTabs>button{min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dshRemoteLoginTabs>button.isActive::after{right:0;left:0;border-radius:0}.dshRemoteClientLogin,.dshRemoteQrLogin{box-sizing:border-box;width:min(440px,100%);height:300px;min-height:300px;align-self:center}.dshRemoteClientLogin{align-items:stretch;padding-top:16px}.dshRemoteClientLogin>button{align-self:stretch;width:100%}.dshRemoteQrLogin{padding-top:12px}",
3339
+ ".dshRemoteLoginHeading{box-sizing:border-box;width:100%;display:flex;align-items:baseline;gap:10px;overflow:hidden;white-space:nowrap}.dshRemoteLoginTitle{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dshRemoteLoginHeading>span{flex:0 0 auto;color:var(--dsw-alias-label-secondary);font-size:13px;font-weight:400}.dshRemoteLoginTabs{box-sizing:border-box;width:100%}.dshRemoteLoginTabs>button{min-width:0;flex:1;display:flex;align-items:center;justify-content:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.dshRemoteLoginTabs>button.isActive::after{right:0;left:0;border-radius:0}.dshRemoteClientLogin,.dshRemoteQrLogin{box-sizing:border-box;width:100%;height:300px;min-height:300px}.dshRemoteClientLogin{align-items:stretch;padding-top:16px}.dshRemoteClientLogin>button{align-self:stretch;width:100%}.dshRemoteQrLogin{padding-top:12px}",
3287
3340
  '.dshRemoteHostControlToggle{display:flex;align-items:center;gap:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px;white-space:nowrap;cursor:default}.dshRemoteHostControlToggle>input{appearance:none;box-sizing:border-box;position:relative;width:32px;height:18px;flex:0 0 auto;margin:0;border:1px solid var(--dsw-alias-label-secondary);border-radius:999px;background:var(--dsw-alias-bg-layer-3);cursor:pointer;box-shadow:inset 0 0 0 1px var(--dsw-alias-border-l2);transition:background .16s ease-out,border-color .16s ease-out,box-shadow .16s ease-out}.dshRemoteHostControlToggle>input::after{content:"";position:absolute;top:2px;left:2px;width:12px;height:12px;border-radius:50%;background:var(--dsw-alias-label-secondary);transition:transform .16s ease-out,background .16s ease-out}.dshRemoteHostControlToggle>input:checked{border-color:var(--dsw-alias-state-success-primary);background:var(--dsw-alias-state-success-primary);box-shadow:none}.dshRemoteHostControlToggle>input:checked::after{transform:translateX(14px);background:var(--dsw-alias-bg-layer-1)}.dshRemoteHostControlToggle>input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.dshRemoteHostControlToggle>input:disabled{opacity:.5;cursor:default}@media(prefers-reduced-motion:reduce){.dshRemoteHostControlToggle>input,.dshRemoteHostControlToggle>input::after{transition:none}}',
3288
3341
  ".dshRemoteAccountExit{flex:0 0 auto;border:0;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;padding:5px 0;font-size:12px;line-height:1.5;white-space:nowrap}.dshRemoteAccountExit:hover:not(:disabled){color:var(--dsw-alias-label-primary);text-decoration:underline}.dshRemoteAccountExit:disabled{opacity:.5;cursor:default;text-decoration:none}",
3289
3342
  ".dshRemoteLocalLink{align-self:flex-start;border:0;background:transparent;color:var(--dsw-alias-label-secondary);padding:4px 0;cursor:pointer}.dshRemoteLocalLink:hover{color:var(--dsw-alias-label-primary)}",
@@ -3348,15 +3401,15 @@ Minimum version required to store current data is: ` + bestVersion + `.
3348
3401
  }, "ds-harness-remote: resume selected workspace"), ctx.inject(["fileViewer"], (fileViewerContext) => {
3349
3402
  let viewer = fileViewerContext.get("fileViewer");
3350
3403
  viewer !== void 0 && fileViewerContext.effect(() => {
3351
- let active = !0, unregister, latestSaveAsAllowed = !1, sync = async () => {
3404
+ let active = !0, unregister, latestSaveAsAllowed = !1, latestSaveAsMaxBytes = REMOTE_FILE_SAVE_AS_MAX_BYTES, sync = async () => {
3352
3405
  try {
3353
3406
  let status = await control("status");
3354
3407
  if (!active) return;
3355
3408
  let supported = shouldUseRemoteFileViewer(status);
3356
- latestSaveAsAllowed = shouldAllowRemoteFileSaveAs(status), supported && unregister === void 0 ? unregister = viewer.registerContentProvider(createRemoteFileContentProvider(
3409
+ latestSaveAsAllowed = shouldAllowRemoteFileSaveAs(status), latestSaveAsMaxBytes = remoteFileSaveAsMaxBytes(status), supported && unregister === void 0 ? unregister = viewer.registerContentProvider(createRemoteFileContentProvider(
3357
3410
  (endpoint, payload) => control(endpoint, payload),
3358
- { saveAsAllowed: () => latestSaveAsAllowed, saveAsMaxBytes: REMOTE_FILE_SAVE_AS_MAX_BYTES }
3359
- )) : !supported && unregister !== void 0 && (unregister(), unregister = void 0, latestSaveAsAllowed = !1);
3411
+ { saveAsAllowed: () => latestSaveAsAllowed, saveAsMaxBytes: () => latestSaveAsMaxBytes }
3412
+ )) : !supported && unregister !== void 0 && (unregister(), unregister = void 0, latestSaveAsAllowed = !1, latestSaveAsMaxBytes = REMOTE_FILE_SAVE_AS_MAX_BYTES);
3360
3413
  } catch {
3361
3414
  }
3362
3415
  };