@lemoncat7/dsh-ssh 0.1.0-alpha.16 → 1.0.6
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/README.md +12 -1
- package/lib/activity-events.d.ts +26 -0
- package/lib/activity-events.d.ts.map +1 -0
- package/lib/activity-events.js +81 -0
- package/lib/activity-events.js.map +1 -0
- package/lib/api.d.ts +2 -0
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +29 -2
- package/lib/api.js.map +1 -1
- package/lib/client-api.d.ts +14 -3
- package/lib/client-api.d.ts.map +1 -1
- package/lib/client-api.js +13 -2
- package/lib/client-api.js.map +1 -1
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +228 -83
- package/lib/client.js.map +3 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -2
- package/lib/index.js.map +1 -1
- package/lib/terminal-io.d.ts +38 -0
- package/lib/terminal-io.d.ts.map +1 -0
- package/lib/terminal-io.js +83 -0
- package/lib/terminal-io.js.map +1 -0
- package/lib/terminal-stream.d.ts +9 -0
- package/lib/terminal-stream.d.ts.map +1 -0
- package/lib/terminal-stream.js +50 -0
- package/lib/terminal-stream.js.map +1 -0
- package/lib/terminal-transport.d.ts +29 -0
- package/lib/terminal-transport.d.ts.map +1 -0
- package/lib/terminal-transport.js +147 -0
- package/lib/terminal-transport.js.map +1 -0
- package/lib/terminal.d.ts +14 -11
- package/lib/terminal.d.ts.map +1 -1
- package/lib/terminal.js +42 -33
- package/lib/terminal.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -6138,6 +6138,21 @@ var import_react4 = require("react");
|
|
|
6138
6138
|
// node_modules/@lemoncat7/dsh-plugin-ui/lib/index.js
|
|
6139
6139
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
6140
6140
|
var import_react = require("react");
|
|
6141
|
+
var PLUGIN_WORKSPACE_ACTIVATE_EVENT = "@lemoncat7/dsh-plugin-ui/workspace-activate";
|
|
6142
|
+
function activatePluginWorkspace(pluginId) {
|
|
6143
|
+
window.dispatchEvent(new CustomEvent(PLUGIN_WORKSPACE_ACTIVATE_EVENT, {
|
|
6144
|
+
detail: { pluginId }
|
|
6145
|
+
}));
|
|
6146
|
+
}
|
|
6147
|
+
function observePluginWorkspace(pluginId, close) {
|
|
6148
|
+
const onActivate = (event) => {
|
|
6149
|
+
const detail = event.detail;
|
|
6150
|
+
if (detail?.pluginId !== pluginId)
|
|
6151
|
+
close();
|
|
6152
|
+
};
|
|
6153
|
+
window.addEventListener(PLUGIN_WORKSPACE_ACTIVATE_EVENT, onActivate);
|
|
6154
|
+
return () => window.removeEventListener(PLUGIN_WORKSPACE_ACTIVATE_EVENT, onActivate);
|
|
6155
|
+
}
|
|
6141
6156
|
function AdaptiveWorkspace({ className, toolbar, notice, navigation, navigationLabel, navigationIcon, inspector, inspectorLabel = "\u8BE6\u60C5", inspectorIcon, children }) {
|
|
6142
6157
|
const [panel, setPanel] = (0, import_react.useState)();
|
|
6143
6158
|
const controls = {
|
|
@@ -6390,7 +6405,7 @@ var xterm_default = `/**
|
|
|
6390
6405
|
`;
|
|
6391
6406
|
|
|
6392
6407
|
// src/client.css
|
|
6393
|
-
var client_default = '.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n.dsh-ssh-sidebar {\n box-sizing: border-box;\n flex: none;\n margin: 0 8px 8px 2px;\n padding: 4px 0 6px;\n border-bottom: 1px solid\n color-mix(in srgb, var(--dsw-alias-border-l2) 62%, transparent);\n color: var(--dsw-alias-label-primary);\n}\n.dsh-ssh-sidebar.is-rail {\n width: 36px;\n margin: 0 0 8px;\n padding: 0;\n border: 0;\n}\n.dsh-ssh-sidebar-heading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 32px;\n padding: 0 4px 0 5px;\n}\n.dsh-ssh-sidebar-title {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 5px;\n height: 28px;\n padding: 0 5px;\n color: var(--dsw-alias-label-secondary);\n border: 0;\n background: transparent;\n border-radius: 7px;\n font: 600 12px/1 var(--ds-font-family);\n cursor: pointer;\n}\n.dsh-ssh-sidebar-title:hover,\n.dsh-ssh-icon-button:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-disclosure {\n display: grid;\n place-items: center;\n transition: transform 0.16s ease;\n}\n.dsh-ssh-disclosure[data-open="false"] {\n transform: rotate(-90deg);\n}\n.dsh-ssh-icon-button {\n display: inline-grid;\n place-items: center;\n flex: none;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 0;\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n cursor: pointer;\n}\n.dsh-ssh-icon-button.is-danger {\n color: #a65d58;\n}\n.dsh-ssh-sidebar-list {\n display: grid;\n gap: 2px;\n padding: 2px 1px 0;\n}\n.dsh-ssh-sidebar-row,\n.dsh-ssh-sidebar-empty,\n.dsh-ssh-sidebar-more {\n box-sizing: border-box;\n width: 100%;\n border: 1px solid transparent;\n background: transparent;\n color: inherit;\n cursor: pointer;\n}\n.dsh-ssh-sidebar-row {\n display: grid;\n grid-template-columns: 12px minmax(0, 1fr) 18px;\n align-items: center;\n gap: 7px;\n min-height: 40px;\n padding: 4px 7px;\n border-radius: 9px;\n text-align: left;\n}\n.dsh-ssh-sidebar-row:hover {\n background: color-mix(\n in srgb,\n var(--dsw-alias-interactive-bg-hover) 70%,\n transparent\n );\n}\n.dsh-ssh-sidebar-row.is-active {\n background: color-mix(\n in srgb,\n var(--dsw-alias-interactive-bg-hover) 92%,\n transparent\n );\n border-color: color-mix(in srgb, var(--dsw-alias-border-l2) 50%, transparent);\n}\n.dsh-ssh-status-dot {\n display: block;\n width: 7px;\n height: 7px;\n margin: auto;\n border: 1px solid\n color-mix(in srgb, var(--dsw-alias-label-secondary) 62%, transparent);\n border-radius: 50%;\n}\n.dsh-ssh-status-dot.is-injected {\n border-color: #5b8f82;\n background: #5b8f82;\n box-shadow: 0 0 0 2px color-mix(in srgb, #5b8f82 14%, transparent);\n}\n.dsh-ssh-sidebar-copy {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n.dsh-ssh-sidebar-copy strong,\n.dsh-ssh-sidebar-copy small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-sidebar-copy strong {\n font-size: 13px;\n font-weight: 500;\n}\n.dsh-ssh-sidebar-copy small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n}\n.dsh-ssh-injected-mark {\n display: grid;\n place-items: center;\n color: #5b8f82;\n}\n.dsh-ssh-sidebar-empty,\n.dsh-ssh-sidebar-more {\n min-height: 34px;\n padding: 6px 10px;\n border-radius: 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n text-align: left;\n}\n.dsh-ssh-sidebar-empty:hover,\n.dsh-ssh-sidebar-more:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-rail-button {\n display: grid;\n place-items: center;\n width: 36px;\n height: 36px;\n padding: 0;\n border: 0;\n border-radius: 10px;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n cursor: pointer;\n}\n.dsh-ssh-rail-button:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-server-glyph {\n display: inline-grid;\n place-items: center;\n color: currentColor;\n}\n.dsh-ssh-workspace {\n --ssh-accent: #547d78;\n --ssh-accent-strong: #406e67;\n --ssh-danger: #9c504c;\n --ssh-warning: #927443;\n --ssh-surface: color-mix(\n in srgb,\n var(--dsw-alias-bg-base, #f7f8f7) 94%,\n transparent\n );\n --ssh-surface-raised: color-mix(\n in srgb,\n var(--dsw-alias-bg-base, #fff) 98%,\n var(--dsw-alias-label-primary) 2%\n );\n --ssh-border: color-mix(\n in srgb,\n var(--dsw-alias-label-primary) 10%,\n transparent\n );\n --dpu-navigation-width: 248px;\n --dpu-inspector-width: 292px;\n --dpu-border: var(--ssh-border);\n --dpu-accent: var(--ssh-accent);\n --dpu-accent-strong: var(--ssh-accent-strong);\n --dpu-raised-surface: var(--ssh-surface-raised);\n --dpu-toolbar-surface: color-mix(\n in srgb,\n var(--ssh-surface-raised) 88%,\n transparent\n );\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n color: var(--dsw-alias-label-primary);\n background: var(--ssh-surface);\n font-family:\n var(--ds-font-family),\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n}\n.dsh-ssh-toolbar {\n display: grid;\n grid-template-columns: minmax(180px, 1fr) auto minmax(180px, 1fr);\n align-items: center;\n gap: 16px;\n min-height: 64px;\n padding: 0 20px;\n border-bottom: 1px solid var(--ssh-border);\n background: color-mix(in srgb, var(--ssh-surface-raised) 88%, transparent);\n}\n.dsh-ssh-brand {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n}\n.dsh-ssh-brand-glyph {\n display: grid;\n place-items: center;\n width: 30px;\n height: 30px;\n border: 1px solid color-mix(in srgb, var(--ssh-accent) 28%, transparent);\n border-radius: 9px;\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-accent) 8%, transparent);\n}\n.dsh-ssh-brand > span:last-child {\n display: grid;\n gap: 1px;\n}\n.dsh-ssh-brand strong {\n font-size: 14px;\n font-weight: 650;\n}\n.dsh-ssh-brand small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n}\n.dsh-ssh-segments {\n display: flex;\n gap: 2px;\n padding: 3px;\n border: 1px solid color-mix(in srgb, var(--ssh-border) 80%, transparent);\n border-radius: 10px;\n background: color-mix(\n in srgb,\n var(--dsw-alias-label-primary) 3%,\n transparent\n );\n}\n.dsh-ssh-segments button {\n min-width: 74px;\n height: 28px;\n padding: 0 12px;\n border: 0;\n border-radius: 7px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n font-size: 12px;\n cursor: pointer;\n}\n.dsh-ssh-segments button:hover {\n color: var(--dsw-alias-label-primary);\n}\n.dsh-ssh-segments button.is-active {\n color: var(--dsw-alias-label-primary);\n background: var(--ssh-surface-raised);\n box-shadow: 0 1px 2px\n color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n.dsh-ssh-toolbar > .dsh-ssh-primary-button {\n justify-self: end;\n}\n.dsh-ssh-primary-button,\n.dsh-ssh-secondary-button,\n.dsh-ssh-danger-button,\n.dsh-ssh-small-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n min-height: 30px;\n padding: 0 12px;\n border-radius: 8px;\n font: 500 12px/1 var(--ds-font-family);\n cursor: pointer;\n}\n.dsh-ssh-primary-button,\n.dsh-ssh-small-primary {\n border: 1px solid\n color-mix(in srgb, var(--ssh-accent-strong) 64%, transparent);\n color: #f6fbf9;\n background: var(--ssh-accent-strong);\n}\n.dsh-ssh-primary-button:hover,\n.dsh-ssh-small-primary:hover {\n background: color-mix(in srgb, var(--ssh-accent-strong) 88%, #000);\n}\n.dsh-ssh-primary-button:disabled {\n opacity: 0.55;\n cursor: default;\n}\n.dsh-ssh-secondary-button {\n border: 1px solid var(--ssh-border);\n color: var(--dsw-alias-label-primary);\n background: var(--ssh-surface-raised);\n}\n.dsh-ssh-secondary-button:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-danger-button {\n border: 1px solid color-mix(in srgb, var(--ssh-danger) 28%, transparent);\n color: var(--ssh-danger);\n background: color-mix(in srgb, var(--ssh-danger) 7%, transparent);\n}\n.dsh-ssh-small-primary {\n min-height: 26px;\n padding: 0 9px;\n}\n.dsh-ssh-profile-panel,\n.dsh-ssh-inspector {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n background: color-mix(in srgb, var(--ssh-surface-raised) 72%, transparent);\n}\n.dsh-ssh-profile-panel {\n border-right: 1px solid var(--ssh-border);\n}\n.dsh-ssh-inspector {\n border-left: 1px solid var(--ssh-border);\n}\n.dsh-ssh-main-panel {\n min-width: 0;\n min-height: 0;\n overflow: auto;\n background: color-mix(in srgb, var(--ssh-surface) 88%, transparent);\n}\n.dsh-ssh-panel-heading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 58px;\n padding: 0 14px;\n border-bottom: 1px solid\n color-mix(in srgb, var(--ssh-border) 74%, transparent);\n}\n.dsh-ssh-panel-heading > span {\n display: grid;\n gap: 2px;\n}\n.dsh-ssh-panel-heading strong {\n font-size: 12px;\n font-weight: 650;\n}\n.dsh-ssh-panel-heading small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n}\n.dsh-ssh-search {\n padding: 10px 10px 6px;\n}\n.dsh-ssh-search input,\n.dsh-ssh-field input,\n.dsh-ssh-field select,\n.dsh-ssh-field textarea,\n.dsh-ssh-number-row input {\n box-sizing: border-box;\n width: 100%;\n border: 1px solid var(--ssh-border);\n border-radius: 8px;\n outline: 0;\n color: var(--dsw-alias-label-primary);\n background: color-mix(in srgb, var(--ssh-surface-raised) 92%, transparent);\n font: 400 12px/1.35 var(--ds-font-family);\n}\n.dsh-ssh-search input {\n height: 30px;\n padding: 0 10px;\n}\n.dsh-ssh-search input:focus,\n.dsh-ssh-field input:focus,\n.dsh-ssh-field select:focus,\n.dsh-ssh-field textarea:focus,\n.dsh-ssh-number-row input:focus {\n border-color: color-mix(in srgb, var(--ssh-accent) 65%, transparent);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--ssh-accent) 12%, transparent);\n}\n.dsh-ssh-profile-list {\n display: grid;\n align-content: start;\n gap: 3px;\n min-height: 0;\n overflow: auto;\n padding: 4px 7px 12px;\n}\n.dsh-ssh-profile-group {\n min-width: 0;\n}\n.dsh-ssh-profile-group-heading {\n display: grid;\n grid-template-columns: 14px 18px minmax(0, 1fr);\n align-items: center;\n gap: 5px;\n width: 100%;\n min-height: 34px;\n padding: 0 6px;\n border: 0;\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n text-align: left;\n cursor: pointer;\n}\n.dsh-ssh-profile-group-heading:hover {\n color: var(--dsw-alias-label-primary);\n background: color-mix(\n in srgb,\n var(--dsw-alias-interactive-bg-hover) 58%,\n transparent\n );\n}\n.dsh-ssh-profile-group-heading:focus-visible {\n outline: 2px solid color-mix(in srgb, var(--ssh-accent) 54%, transparent);\n outline-offset: -2px;\n}\n.dsh-ssh-profile-group-chevron {\n display: grid;\n place-items: center;\n transition: transform 160ms cubic-bezier(0.2, 0.8, 0.2, 1);\n}\n.dsh-ssh-profile-group-chevron[data-open="false"] {\n transform: rotate(-90deg);\n}\n.dsh-ssh-profile-group-folder {\n display: grid;\n place-items: center;\n color: color-mix(\n in srgb,\n var(--ssh-accent-strong) 72%,\n var(--dsw-alias-label-secondary)\n );\n}\n.dsh-ssh-profile-group-copy {\n display: flex;\n min-width: 0;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n.dsh-ssh-profile-group-copy strong {\n overflow: hidden;\n font-size: 11px;\n font-weight: 600;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-profile-group-copy small {\n display: grid;\n place-items: center;\n min-width: 16px;\n height: 16px;\n color: var(--dsw-alias-label-tertiary);\n font:\n 9px/1 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-profile-group-children {\n display: grid;\n gap: 1px;\n margin-left: 13px;\n padding-left: 6px;\n border-left: 1px solid color-mix(in srgb, var(--ssh-border) 66%, transparent);\n animation: dsh-ssh-group-open 140ms ease-out both;\n}\n.dsh-ssh-profile-empty {\n margin: 18px 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n text-align: center;\n}\n.dsh-ssh-profile-row {\n display: grid;\n grid-template-columns: 30px minmax(0, 1fr) 10px;\n align-items: center;\n gap: 9px;\n width: 100%;\n min-height: 48px;\n padding: 5px 7px;\n border: 1px solid transparent;\n border-radius: 9px;\n color: inherit;\n background: transparent;\n text-align: left;\n cursor: pointer;\n}\n.dsh-ssh-profile-row:hover {\n background: color-mix(\n in srgb,\n var(--dsw-alias-interactive-bg-hover) 74%,\n transparent\n );\n}\n.dsh-ssh-profile-row.is-active {\n border-color: color-mix(in srgb, var(--ssh-accent) 16%, transparent);\n background: color-mix(in srgb, var(--ssh-accent) 9%, transparent);\n}\n.dsh-ssh-host-monogram {\n display: grid;\n place-items: center;\n width: 28px;\n height: 28px;\n border: 1px solid var(--ssh-border);\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n background: var(--ssh-surface-raised);\n font-size: 11px;\n font-weight: 650;\n}\n.dsh-ssh-profile-row > span:nth-child(2) {\n display: grid;\n min-width: 0;\n gap: 3px;\n}\n.dsh-ssh-profile-row strong,\n.dsh-ssh-profile-row small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-profile-row strong {\n font-size: 12px;\n font-weight: 550;\n}\n.dsh-ssh-profile-row small {\n color: var(--dsw-alias-label-tertiary);\n font:\n 10px/1.2 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-credential-state {\n width: 6px;\n height: 6px;\n border: 1px solid var(--dsw-alias-label-tertiary);\n border-radius: 50%;\n}\n.dsh-ssh-credential-state.is-ready {\n border-color: #5c8a76;\n background: #5c8a76;\n}\n.dsh-ssh-terminal-pane,\n.dsh-ssh-forward-pane,\n.dsh-ssh-settings-pane {\n box-sizing: border-box;\n display: flex;\n min-width: 0;\n min-height: 100%;\n flex-direction: column;\n padding: 0 18px 18px;\n}\n.dsh-ssh-content-heading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 20px;\n min-height: 76px;\n}\n.dsh-ssh-content-heading h1 {\n margin: 0;\n font-size: 16px;\n font-weight: 650;\n letter-spacing: -0.01em;\n}\n.dsh-ssh-content-heading p {\n margin: 4px 0 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n.dsh-ssh-heading-actions {\n display: flex;\n align-items: center;\n gap: 7px;\n}\n.dsh-ssh-title-line {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dsh-ssh-live-dot {\n width: 7px;\n height: 7px;\n border: 1px solid var(--dsw-alias-label-tertiary);\n border-radius: 50%;\n}\n.dsh-ssh-live-dot.is-connected {\n border-color: #4d8d77;\n background: #4d8d77;\n box-shadow: 0 0 0 3px color-mix(in srgb, #4d8d77 12%, transparent);\n}\n.dsh-ssh-live-dot.is-connecting {\n border-color: #a27e45;\n background: #a27e45;\n}\n.dsh-ssh-live-dot.is-error {\n border-color: #a85a55;\n background: #a85a55;\n}\n.dsh-ssh-terminal-frame {\n display: flex;\n min-height: 360px;\n flex: 1;\n flex-direction: column;\n overflow: hidden;\n border: 1px solid color-mix(in srgb, #8ba49e 22%, #101817);\n border-radius: 12px;\n background: #111817;\n box-shadow: 0 10px 34px color-mix(in srgb, #0d1513 14%, transparent);\n}\n.dsh-ssh-xterm {\n min-height: 0;\n flex: 1;\n padding: 11px 11px 0;\n}\n.dsh-ssh-xterm .xterm {\n height: 100%;\n}\n.dsh-ssh-terminal-status {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 28px;\n padding: 0 11px;\n border-top: 1px solid #ffffff12;\n color: #879691;\n background: #0d1413;\n font:\n 10px/1 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-banner {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 8px 18px;\n border-bottom: 1px solid transparent;\n font-size: 11px;\n}\n.dsh-ssh-banner > span {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n.dsh-ssh-banner code {\n font-family: var(--ds-font-family-code), monospace;\n}\n.dsh-ssh-banner button:not(.dsh-ssh-small-primary) {\n display: grid;\n place-items: center;\n border: 0;\n color: inherit;\n background: transparent;\n}\n.dsh-ssh-banner.is-error {\n border-color: color-mix(in srgb, var(--ssh-danger) 22%, transparent);\n color: var(--ssh-danger);\n background: color-mix(in srgb, var(--ssh-danger) 7%, var(--ssh-surface));\n}\n.dsh-ssh-banner.is-warning {\n border-color: color-mix(in srgb, var(--ssh-warning) 22%, transparent);\n color: color-mix(\n in srgb,\n var(--ssh-warning) 85%,\n var(--dsw-alias-label-primary)\n );\n background: color-mix(in srgb, var(--ssh-warning) 8%, var(--ssh-surface));\n}\n.dsh-ssh-inline-error {\n margin: 0 0 10px;\n padding: 7px 9px;\n border-radius: 7px;\n color: var(--ssh-danger);\n background: color-mix(in srgb, var(--ssh-danger) 7%, transparent);\n font-size: 11px;\n}\n.dsh-ssh-empty-state {\n display: grid;\n place-items: center;\n align-content: center;\n min-height: 100%;\n padding: 40px;\n text-align: center;\n}\n.dsh-ssh-empty-state > span {\n display: grid;\n place-items: center;\n width: 48px;\n height: 48px;\n margin-bottom: 14px;\n border: 1px solid var(--ssh-border);\n border-radius: 14px;\n color: var(--ssh-accent);\n background: var(--ssh-surface-raised);\n}\n.dsh-ssh-empty-state h1 {\n margin: 0;\n font-size: 17px;\n}\n.dsh-ssh-empty-state p {\n max-width: 420px;\n margin: 8px 0 18px;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 1.6;\n}\n.dsh-ssh-inspector {\n overflow: auto;\n}\n.dsh-ssh-session-chip {\n display: flex;\n align-items: center;\n gap: 9px;\n margin: 12px 12px 4px;\n padding: 9px 10px;\n border: 1px solid var(--ssh-border);\n border-radius: 9px;\n background: color-mix(in srgb, var(--ssh-surface-raised) 86%, transparent);\n}\n.dsh-ssh-session-chip > span:nth-child(2) {\n display: grid;\n gap: 2px;\n}\n.dsh-ssh-session-chip strong {\n font-size: 11px;\n}\n.dsh-ssh-session-chip small {\n color: var(--dsw-alias-label-tertiary);\n font:\n 9px/1 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-session-pulse {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--ssh-accent);\n}\n.dsh-ssh-fieldset {\n display: grid;\n gap: 3px;\n margin: 13px 12px 0;\n padding: 0;\n border: 0;\n}\n.dsh-ssh-fieldset legend {\n margin-bottom: 5px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n font-weight: 600;\n}\n.dsh-ssh-check-row,\n.dsh-ssh-radio-row {\n display: flex;\n align-items: center;\n gap: 9px;\n min-height: 38px;\n padding: 3px 5px;\n border-radius: 8px;\n}\n.dsh-ssh-check-row:hover,\n.dsh-ssh-radio-row:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-check-row input,\n.dsh-ssh-radio-row input {\n accent-color: var(--ssh-accent);\n}\n.dsh-ssh-check-row > span,\n.dsh-ssh-radio-row > span {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n.dsh-ssh-check-row strong,\n.dsh-ssh-radio-row strong {\n font-size: 11px;\n font-weight: 550;\n}\n.dsh-ssh-check-row small,\n.dsh-ssh-radio-row small {\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-switch-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 20px;\n min-height: 48px;\n margin: 13px 12px 0;\n padding: 7px 9px;\n border: 1px solid var(--ssh-border);\n border-radius: 9px;\n}\n.dsh-ssh-switch-row > span {\n display: grid;\n gap: 3px;\n}\n.dsh-ssh-switch-row strong {\n font-size: 11px;\n font-weight: 550;\n}\n.dsh-ssh-switch-row small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n line-height: 1.35;\n}\n.dsh-ssh-switch-row input {\n width: 28px;\n height: 16px;\n accent-color: var(--ssh-accent);\n}\n.dsh-ssh-inspector-hint,\n.dsh-ssh-save-state {\n margin: 10px 12px 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n}\n.dsh-ssh-inspector-empty {\n margin: 14px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n line-height: 1.55;\n}\n.dsh-ssh-forward-list {\n display: grid;\n align-content: start;\n gap: 5px;\n}\n.dsh-ssh-forward-row {\n display: grid;\n grid-template-columns: 32px minmax(0, 1fr) auto 28px auto 28px;\n align-items: center;\n gap: 8px;\n min-height: 54px;\n padding: 6px 9px;\n border: 1px solid var(--ssh-border);\n border-radius: 10px;\n background: color-mix(in srgb, var(--ssh-surface-raised) 88%, transparent);\n}\n.dsh-ssh-forward-kind {\n display: grid;\n place-items: center;\n width: 28px;\n height: 28px;\n border: 1px solid var(--ssh-border);\n border-radius: 8px;\n color: var(--ssh-accent-strong);\n font:\n 600 11px/1 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-forward-copy {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n.dsh-ssh-forward-copy strong {\n font-size: 12px;\n}\n.dsh-ssh-forward-copy small {\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font:\n 10px/1 var(--ds-font-family-code),\n monospace;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-state-label {\n padding: 3px 7px;\n border-radius: 999px;\n color: var(--dsw-alias-label-tertiary);\n background: color-mix(\n in srgb,\n var(--dsw-alias-label-primary) 5%,\n transparent\n );\n font-size: 9px;\n}\n.dsh-ssh-state-label.is-running {\n color: #497967;\n background: color-mix(in srgb, #5d957f 10%, transparent);\n}\n.dsh-ssh-state-label.is-error {\n color: var(--ssh-danger);\n background: color-mix(in srgb, var(--ssh-danger) 8%, transparent);\n}\n.dsh-ssh-table-empty {\n display: grid;\n place-items: center;\n min-height: 180px;\n border: 1px dashed var(--ssh-border);\n border-radius: 12px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n}\n.dsh-ssh-settings-group {\n display: grid;\n max-width: 680px;\n gap: 8px;\n}\n.dsh-ssh-settings-group .dsh-ssh-switch-row {\n margin: 0;\n}\n.dsh-ssh-number-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 120px 32px;\n align-items: center;\n gap: 8px;\n min-height: 60px;\n padding: 6px 10px;\n border: 1px solid var(--ssh-border);\n border-radius: 10px;\n background: color-mix(in srgb, var(--ssh-surface-raised) 80%, transparent);\n}\n.dsh-ssh-number-row > span {\n display: grid;\n gap: 3px;\n}\n.dsh-ssh-number-row strong {\n font-size: 11px;\n}\n.dsh-ssh-number-row small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n}\n.dsh-ssh-number-row input {\n height: 30px;\n padding: 0 8px;\n}\n.dsh-ssh-number-row em {\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n font-style: normal;\n}\n.dsh-ssh-dialog-layer {\n position: fixed;\n z-index: 1000;\n inset: 0;\n display: grid;\n place-items: center;\n padding: 28px;\n background: color-mix(in srgb, #111817 28%, transparent);\n backdrop-filter: blur(3px);\n}\n.dsh-ssh-dialog {\n box-sizing: border-box;\n width: min(620px, calc(100vw - 40px));\n max-height: min(760px, calc(100vh - 40px));\n overflow: auto;\n border: 1px solid\n color-mix(in srgb, var(--dsw-alias-label-primary) 15%, transparent);\n border-radius: 14px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base, #f7f8f7);\n box-shadow: 0 24px 70px #07100d2e;\n}\n.dsh-ssh-dialog > header {\n position: sticky;\n z-index: 1;\n top: 0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 64px;\n padding: 0 18px;\n border-bottom: 1px solid\n var(\n --ssh-border,\n color-mix(in srgb, var(--dsw-alias-label-primary) 10%, transparent)\n );\n background: color-mix(\n in srgb,\n var(--dsw-alias-bg-base, #f7f8f7) 94%,\n transparent\n );\n backdrop-filter: blur(12px);\n}\n.dsh-ssh-dialog h2 {\n margin: 0;\n font-size: 17px;\n font-weight: 650;\n letter-spacing: -0.01em;\n}\n.dsh-ssh-dialog header p {\n margin: 3px 0 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n.dsh-ssh-form {\n --ssh-border: color-mix(\n in srgb,\n var(--dsw-alias-label-primary) 11%,\n transparent\n );\n --ssh-accent: #547d78;\n --ssh-accent-strong: #406e67;\n --ssh-danger: #9c504c;\n display: grid;\n gap: 15px;\n padding: 20px 18px 18px;\n}\n.dsh-ssh-form-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n}\n.dsh-ssh-form-grid.is-host {\n grid-template-columns: minmax(0, 1fr) 110px;\n}\n.dsh-ssh-field {\n display: grid;\n gap: 5px;\n min-width: 0;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n font-weight: 600;\n}\n.dsh-ssh-field input,\n.dsh-ssh-field select {\n height: 38px;\n padding: 0 10px;\n font-size: 13px;\n}\n.dsh-ssh-field textarea {\n padding: 9px 10px;\n font-size: 13px;\n line-height: 1.5;\n resize: vertical;\n font-family: var(--ds-font-family-code), monospace;\n}\n.dsh-ssh-field small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n line-height: 1.4;\n font-weight: 400;\n}\n.dsh-ssh-form-divider {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-top: 2px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n font-weight: 600;\n}\n.dsh-ssh-form-divider:after {\n height: 1px;\n flex: 1;\n background: var(--ssh-border);\n content: "";\n}\n.dsh-ssh-dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding-top: 5px;\n}\n.dsh-ssh-dialog-actions .dsh-ssh-primary-button,\n.dsh-ssh-dialog-actions .dsh-ssh-secondary-button {\n min-height: 34px;\n font-size: 13px;\n}\n.dsh-ssh-form .dsh-ssh-switch-row {\n margin: 0;\n}\n.dsh-ssh-form .dsh-ssh-inline-error {\n margin: 0;\n}\n@container dpu-workspace (max-width: 1120px) {\n .dsh-ssh-toolbar {\n grid-template-columns: 1fr auto auto;\n }\n .dsh-ssh-brand small {\n display: none;\n }\n}\n@container dpu-workspace (max-width: 820px) {\n .dsh-ssh-toolbar {\n grid-template-columns: 1fr auto;\n gap: 8px;\n padding: 0 12px;\n }\n .dsh-ssh-segments {\n grid-row: 2;\n grid-column: 1/-1;\n margin-bottom: 8px;\n overflow-x: auto;\n scrollbar-width: none;\n }\n .dsh-ssh-segments::-webkit-scrollbar {\n display: none;\n }\n .dsh-ssh-segments button {\n min-width: 72px;\n height: 36px;\n flex: none;\n }\n .dsh-ssh-toolbar {\n padding-top: 8px;\n }\n .dsh-ssh-content-heading {\n align-items: flex-start;\n flex-direction: column;\n padding: 14px 0;\n }\n .dsh-ssh-heading-actions {\n flex-wrap: wrap;\n }\n .dsh-ssh-forward-row {\n grid-template-columns: 32px minmax(0, 1fr) auto;\n }\n .dsh-ssh-forward-row > .dsh-ssh-icon-button,\n .dsh-ssh-forward-row > .dsh-ssh-small-primary {\n display: none;\n }\n}\n@container dpu-workspace (max-width: 520px) {\n .dsh-ssh-toolbar {\n padding-right: max(10px, env(safe-area-inset-right));\n padding-left: max(10px, env(safe-area-inset-left));\n }\n .dsh-ssh-toolbar > .dsh-ssh-primary-button {\n width: 40px;\n min-height: 40px;\n padding: 0;\n }\n .dsh-ssh-toolbar > .dsh-ssh-primary-button span {\n display: none;\n }\n .dsh-ssh-terminal-pane,\n .dsh-ssh-forward-pane,\n .dsh-ssh-settings-pane,\n .dsh-ssh-vault-pane,\n .dsh-ssh-proxy-pane,\n .dsh-ssh-profile-sftp-pane {\n padding-right: 10px;\n padding-left: 10px;\n }\n .dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-columns,\n .dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row {\n grid-template-columns: minmax(120px, 1fr) 64px;\n }\n .dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-columns > :nth-child(3),\n .dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row > :nth-child(3) {\n display: none;\n }\n .dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row {\n min-height: 44px;\n }\n .dsh-ssh-number-row {\n grid-template-columns: minmax(0, 1fr) 86px 28px;\n }\n}\n@media (max-width: 600px) {\n .dsh-ssh-dialog-layer {\n align-items: stretch;\n padding: 0;\n }\n .dsh-ssh-dialog {\n width: 100%;\n max-height: 100dvh;\n border: 0;\n border-radius: 0;\n }\n .dsh-ssh-form-grid,\n .dsh-ssh-form-grid.is-host {\n grid-template-columns: 1fr;\n }\n .dsh-ssh-dialog-actions {\n position: sticky;\n bottom: 0;\n flex-wrap: wrap;\n padding: 10px 0 max(10px, env(safe-area-inset-bottom));\n background: var(--dsw-alias-bg-base, #f7f8f7);\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .dsh-ssh-disclosure {\n transition: none;\n }\n}\n@media (prefers-reduced-transparency: reduce) {\n .dsh-ssh-dialog-layer {\n backdrop-filter: none;\n }\n .dsh-ssh-dialog > header {\n backdrop-filter: none;\n }\n}\n\n.dsh-ssh-activity-trigger {\n box-sizing: border-box;\n display: inline-grid;\n place-items: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 1px solid transparent;\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n cursor: pointer;\n}\n.dsh-ssh-activity-trigger:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-activity-trigger.is-active {\n border-color: color-mix(in srgb, var(--ssh-accent, #547d78) 16%, transparent);\n color: var(--ssh-accent-strong, #406e67);\n background: color-mix(in srgb, var(--ssh-accent, #547d78) 8%, transparent);\n}\n.dsh-ssh-panel-right-icon {\n transform: rotate(180deg);\n}\n.dsh-ssh-activity-trigger:focus-visible,\n.dsh-ssh-activity-tabs button:focus-visible,\n.dsh-ssh-sftp button:focus-visible,\n.dsh-ssh-sftp input:focus-visible,\n.dsh-ssh-sftp select:focus-visible {\n outline: 2px solid\n color-mix(in srgb, var(--ssh-accent, #547d78) 62%, transparent);\n outline-offset: 2px;\n}\n.dsh-ssh-activity-panel {\n --ssh-activity-border: color-mix(\n in srgb,\n var(--dsw-alias-label-primary) 10%,\n transparent\n );\n box-sizing: border-box;\n display: flex;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n color: var(--dsw-alias-label-primary);\n background: color-mix(\n in srgb,\n var(--dsw-alias-bg-base, #f7f8f7) 96%,\n transparent\n );\n font-family:\n var(--ds-font-family),\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n}\n.dsh-ssh-activity-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 58px;\n padding: 0 12px 0 14px;\n border-bottom: 1px solid var(--ssh-activity-border);\n background: color-mix(\n in srgb,\n var(--dsw-alias-bg-base, #f7f8f7) 88%,\n transparent\n );\n backdrop-filter: blur(10px);\n}\n.dsh-ssh-activity-header > span {\n display: grid;\n min-width: 0;\n gap: 3px;\n}\n.dsh-ssh-activity-header strong {\n font-size: 13px;\n font-weight: 650;\n}\n.dsh-ssh-activity-header small {\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font:\n 10px/1.2 var(--ds-font-family-code),\n monospace;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-activity-tabs {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 3px;\n margin: 10px 12px 0;\n padding: 3px;\n border: 1px solid var(--ssh-activity-border);\n border-radius: 10px;\n background: color-mix(\n in srgb,\n var(--dsw-alias-label-primary) 3%,\n transparent\n );\n}\n.dsh-ssh-activity-tabs button {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n min-height: 30px;\n padding: 0 9px;\n border: 0;\n border-radius: 7px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n font: 550 11px/1 var(--ds-font-family);\n cursor: pointer;\n}\n.dsh-ssh-activity-tabs button:hover {\n color: var(--dsw-alias-label-primary);\n}\n.dsh-ssh-activity-tabs button.is-active {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base, #f7f8f7);\n box-shadow: 0 1px 3px\n color-mix(in srgb, var(--dsw-alias-label-primary) 9%, transparent);\n}\n.dsh-ssh-activity-tabs button:only-child {\n grid-column: 1/-1;\n}\n.dsh-ssh-activity-body {\n display: flex;\n min-height: 0;\n flex: 1;\n overflow: hidden;\n padding: 14px 12px 18px;\n}\n.dsh-ssh-activity-body > * {\n width: 100%;\n}\n.dsh-ssh-activity-state {\n margin: 20px 4px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n.dsh-ssh-sftp {\n display: flex;\n min-height: 100%;\n flex-direction: column;\n}\n.dsh-ssh-sftp-hostbar {\n display: grid;\n grid-template-columns: 28px minmax(0, 1fr);\n align-items: center;\n gap: 8px;\n padding: 0 2px 10px;\n}\n.dsh-ssh-sftp-hostbar label {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n.dsh-ssh-sftp-hostbar select {\n min-width: 0;\n padding: 0;\n border: 0;\n outline: 0;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n font: 600 11px/1.25 var(--ds-font-family);\n cursor: pointer;\n}\n.dsh-ssh-sftp-hostbar small {\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font:\n 9px/1.2 var(--ds-font-family-code),\n monospace;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-sftp-pathbar {\n display: grid;\n grid-template-columns: 30px minmax(0, 1fr) 30px;\n gap: 5px;\n margin-bottom: 9px;\n}\n.dsh-ssh-sftp-pathbar.has-upload {\n grid-template-columns: 30px minmax(0, 1fr) 30px auto;\n}\n.dsh-ssh-sftp-pathbar button,\n.dsh-ssh-sftp-pathbar input {\n box-sizing: border-box;\n height: 30px;\n border: 1px solid var(--ssh-activity-border);\n border-radius: 8px;\n color: var(--dsw-alias-label-primary);\n background: color-mix(\n in srgb,\n var(--dsw-alias-bg-base, #fff) 86%,\n transparent\n );\n}\n.dsh-ssh-sftp-pathbar button {\n display: grid;\n place-items: center;\n padding: 0;\n cursor: pointer;\n}\n.dsh-ssh-sftp-pathbar button:disabled {\n opacity: 0.35;\n cursor: default;\n}\n.dsh-ssh-sftp-pathbar input {\n min-width: 0;\n padding: 0 9px;\n outline: 0;\n font:\n 9px/1 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-sftp-pathbar .dsh-ssh-sftp-upload-button {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 0 10px;\n color: #f6fbf9;\n background: var(--ssh-accent-strong, #406e67);\n font: 550 10px/1 var(--ds-font-family);\n}\n.dsh-ssh-directory-error {\n margin: 0 0 8px;\n padding: 7px 8px;\n border-radius: 7px;\n color: var(--ssh-danger, #9c504c);\n background: color-mix(in srgb, var(--ssh-danger, #9c504c) 7%, transparent);\n font-size: 10px;\n line-height: 1.4;\n}\n.dsh-ssh-sftp-table {\n min-height: 0;\n flex: 1;\n overflow: auto;\n border: 1px solid var(--ssh-activity-border);\n border-radius: 10px;\n background: color-mix(\n in srgb,\n var(--dsw-alias-bg-base, #fff) 70%,\n transparent\n );\n}\n.dsh-ssh-sftp-columns,\n.dsh-ssh-sftp-row {\n display: grid;\n grid-template-columns: minmax(120px, 1fr) 58px 72px;\n align-items: center;\n gap: 7px;\n}\n.dsh-ssh-sftp-columns {\n position: sticky;\n z-index: 1;\n top: 0;\n min-height: 28px;\n padding: 0 9px;\n border-bottom: 1px solid var(--ssh-activity-border);\n color: var(--dsw-alias-label-tertiary);\n background: color-mix(\n in srgb,\n var(--dsw-alias-bg-base, #f7f8f7) 94%,\n transparent\n );\n font-size: 8px;\n}\n.dsh-ssh-sftp-row {\n box-sizing: border-box;\n width: 100%;\n min-height: 34px;\n padding: 0 9px;\n border: 0;\n border-bottom: 1px solid\n color-mix(in srgb, var(--ssh-activity-border) 55%, transparent);\n color: var(--dsw-alias-label-primary);\n background: transparent;\n text-align: left;\n}\n.dsh-ssh-sftp-row:last-child {\n border-bottom: 0;\n}\n.dsh-ssh-sftp-row.is-directory {\n cursor: pointer;\n}\n.dsh-ssh-sftp-row.is-directory:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-sftp-row:disabled {\n opacity: 1;\n}\n.dsh-ssh-sftp-row > span {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 7px;\n}\n.dsh-ssh-sftp-row svg {\n flex: none;\n color: var(--dsw-alias-label-secondary);\n}\n.dsh-ssh-sftp-row.is-directory svg {\n color: var(--ssh-accent-strong, #406e67);\n}\n.dsh-ssh-sftp-row strong {\n overflow: hidden;\n font-size: 10px;\n font-weight: 500;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-sftp-row small {\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font:\n 8px/1.2 var(--ds-font-family-code),\n monospace;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-sftp-state {\n display: grid;\n place-items: center;\n min-height: 160px;\n margin: 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n}\n.dsh-ssh-activity-empty {\n display: grid;\n place-items: center;\n align-content: center;\n min-height: 240px;\n padding: 24px;\n text-align: center;\n}\n.dsh-ssh-activity-empty > svg {\n margin-bottom: 10px;\n color: var(--dsw-alias-label-tertiary);\n}\n.dsh-ssh-activity-empty strong {\n font-size: 12px;\n}\n.dsh-ssh-activity-empty p {\n max-width: 260px;\n margin: 7px 0 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n line-height: 1.5;\n}\n.dsh-ssh-terminal-observer {\n display: flex;\n height: 100%;\n min-height: 280px;\n overflow: hidden;\n flex-direction: column;\n border: 1px solid color-mix(in srgb, #8ba49e 22%, #101817);\n border-radius: 11px;\n background: #111817;\n}\n.dsh-ssh-terminal-observer-heading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 42px;\n padding: 0 10px;\n border-bottom: 1px solid #ffffff12;\n color: #dce5e1;\n background: #0d1413;\n}\n.dsh-ssh-terminal-observer-heading > span:first-child {\n display: grid;\n min-width: 0;\n gap: 3px;\n}\n.dsh-ssh-terminal-observer-heading strong,\n.dsh-ssh-terminal-observer-heading small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-terminal-observer-heading strong {\n font-size: 10px;\n}\n.dsh-ssh-terminal-observer-heading small {\n color: #879691;\n font:\n 8px/1 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-terminal-state {\n flex: none;\n color: #879691;\n font-size: 9px;\n}\n.dsh-ssh-terminal-state.is-running {\n color: #8fc0af;\n}\n.dsh-ssh-terminal-screen {\n box-sizing: border-box;\n min-height: 0;\n flex: 1;\n padding: 9px 8px 0;\n}\n.dsh-ssh-terminal-screen .xterm {\n height: 100%;\n}\n@media (prefers-reduced-transparency: reduce) {\n .dsh-ssh-activity-header {\n backdrop-filter: none;\n }\n}\n\n.dsh-ssh-sftp-row:not(.is-directory) {\n cursor: pointer;\n}\n.dsh-ssh-file-preview {\n display: flex;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n overflow: hidden;\n border: 1px solid var(--ssh-activity-border);\n border-radius: 10px;\n background: color-mix(\n in srgb,\n var(--dsw-alias-bg-base, #fff) 70%,\n transparent\n );\n}\n.dsh-ssh-file-preview > header {\n display: grid;\n grid-template-columns: 28px minmax(0, 1fr) 28px;\n align-items: center;\n gap: 7px;\n min-height: 42px;\n padding: 0 7px;\n border-bottom: 1px solid var(--ssh-activity-border);\n}\n.dsh-ssh-file-preview > header > span {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n.dsh-ssh-file-preview > header strong,\n.dsh-ssh-file-preview > header small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-file-preview > header strong {\n font-size: 10px;\n}\n.dsh-ssh-file-preview > header small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 8px;\n}\n.dsh-ssh-file-preview > header > a {\n display: grid;\n place-items: center;\n width: 28px;\n height: 28px;\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n text-decoration: none;\n}\n.dsh-ssh-file-preview > header > a:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-file-preview-body {\n display: flex;\n min-height: 0;\n flex: 1;\n overflow: auto;\n flex-direction: column;\n}\n.dsh-ssh-file-preview-body > pre {\n box-sizing: border-box;\n min-width: 100%;\n min-height: 100%;\n margin: 0;\n padding: 12px;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n font:\n 10px/1.55 var(--ds-font-family-code),\n monospace;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.dsh-ssh-file-preview-body > small {\n padding: 8px 12px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n}\n.dsh-ssh-file-preview-body > img {\n display: block;\n max-width: 100%;\n max-height: 100%;\n margin: auto;\n object-fit: contain;\n}\n.dsh-ssh-file-preview-body > iframe {\n width: 100%;\n height: 100%;\n min-height: 420px;\n border: 0;\n background: #fff;\n}\n.dsh-ssh-file-binary {\n display: grid;\n place-items: center;\n align-content: center;\n min-height: 240px;\n padding: 20px;\n text-align: center;\n}\n.dsh-ssh-file-binary > svg {\n margin-bottom: 9px;\n color: var(--dsw-alias-label-tertiary);\n}\n.dsh-ssh-file-binary strong {\n font-size: 11px;\n}\n.dsh-ssh-file-binary p {\n margin: 5px 0 12px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n}\n.dsh-ssh-file-binary a {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-height: 30px;\n padding: 0 10px;\n border: 1px solid var(--ssh-activity-border);\n border-radius: 8px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-button-elevated-fill);\n font-size: 10px;\n text-decoration: none;\n}\n.dsh-ssh-terminal-workbench {\n display: flex;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 7px;\n}\n.dsh-ssh-terminal-switcher {\n display: flex;\n flex: none;\n gap: 3px;\n overflow: auto;\n padding: 1px;\n}\n.dsh-ssh-terminal-switcher button {\n display: flex;\n min-width: 0;\n max-width: 150px;\n align-items: center;\n gap: 6px;\n height: 28px;\n padding: 0 8px;\n border: 1px solid transparent;\n border-radius: 7px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n font: 500 9px/1 var(--ds-font-family);\n white-space: nowrap;\n cursor: pointer;\n}\n.dsh-ssh-terminal-switcher button:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-terminal-switcher button.is-active {\n border-color: var(--ssh-activity-border);\n color: var(--dsw-alias-label-primary);\n background: color-mix(in srgb, var(--ssh-accent, #547d78) 8%, transparent);\n}\n.dsh-ssh-terminal-state-dot {\n width: 5px;\n height: 5px;\n flex: none;\n border: 1px solid #75827e;\n border-radius: 50%;\n}\n.dsh-ssh-terminal-state-dot.is-running {\n border-color: #6ca08d;\n background: #6ca08d;\n}\n.dsh-ssh-terminal-workbench .dsh-ssh-terminal-observer {\n height: auto;\n min-height: 0;\n flex: 1;\n}\n.dsh-ssh-terminal-input-error {\n margin: 0;\n padding: 6px 8px;\n border-radius: 6px;\n color: #d98e88;\n background: #351c1a;\n font-size: 9px;\n}\n\n.dsh-ssh-workspace::before {\n position: absolute;\n z-index: 0;\n inset: 0;\n pointer-events: none;\n background:\n radial-gradient(\n circle at 18% 12%,\n color-mix(in srgb, var(--ssh-accent) 7%, transparent),\n transparent 28%\n ),\n linear-gradient(\n 115deg,\n transparent 0 56%,\n color-mix(in srgb, var(--ssh-accent) 3%, transparent) 56.1% 56.35%,\n transparent 56.45% 100%\n );\n content: "";\n}\n.dsh-ssh-workspace > * {\n position: relative;\n z-index: 1;\n}\n.dsh-ssh-toolbar {\n box-shadow:\n inset 0 1px 0\n color-mix(in srgb, var(--dsw-alias-bg-base, #fff) 70%, transparent),\n 0 8px 28px\n color-mix(in srgb, var(--dsw-alias-label-primary) 3%, transparent);\n}\n.dsh-ssh-brand-glyph {\n position: relative;\n overflow: hidden;\n}\n.dsh-ssh-brand-glyph::after {\n position: absolute;\n width: 12px;\n height: 1px;\n left: 9px;\n bottom: 5px;\n border-radius: 1px;\n background: color-mix(in srgb, var(--ssh-accent) 66%, transparent);\n content: "";\n}\n.dsh-ssh-profile-row {\n position: relative;\n transition:\n background 140ms ease,\n border-color 140ms ease,\n transform 160ms cubic-bezier(0.2, 0.8, 0.2, 1);\n}\n.dsh-ssh-profile-row::before {\n position: absolute;\n width: 2px;\n left: 0;\n top: 11px;\n bottom: 11px;\n border-radius: 2px;\n background: var(--ssh-accent);\n opacity: 0;\n transform: scaleY(0.45);\n transition:\n opacity 140ms ease,\n transform 170ms cubic-bezier(0.2, 0.8, 0.2, 1);\n content: "";\n}\n.dsh-ssh-profile-row.is-active {\n transform: translateX(2px);\n}\n.dsh-ssh-profile-row.is-active::before {\n opacity: 0.8;\n transform: scaleY(1);\n}\n.dsh-ssh-profile-row:active,\n.dsh-ssh-sftp-row:active,\n.dsh-ssh-terminal-switcher button:active {\n transform: scale(0.985);\n}\n.dsh-ssh-activity-panel {\n animation: dsh-ssh-panel-enter 180ms cubic-bezier(0.2, 0.8, 0.2, 1) both;\n}\n.dsh-ssh-sftp-table,\n.dsh-ssh-file-preview,\n.dsh-ssh-terminal-observer {\n box-shadow:\n inset 0 1px 0\n color-mix(in srgb, var(--dsw-alias-bg-base, #fff) 8%, transparent),\n 0 10px 30px\n color-mix(in srgb, var(--dsw-alias-label-primary) 4%, transparent);\n}\n.dsh-ssh-sftp-row {\n transition:\n background 120ms ease,\n transform 120ms ease;\n}\n.dsh-ssh-file-preview-body {\n animation: dsh-ssh-content-enter 160ms ease-out both;\n}\n.dsh-ssh-terminal-switcher button {\n transition:\n color 120ms ease,\n background 120ms ease,\n border-color 120ms ease,\n transform 120ms ease;\n}\n.dsh-ssh-terminal-switcher button.is-active {\n box-shadow: inset 0 1px 0\n color-mix(in srgb, var(--dsw-alias-bg-base, #fff) 55%, transparent);\n}\n.dsh-ssh-vault-pane,\n.dsh-ssh-proxy-pane {\n box-sizing: border-box;\n display: flex;\n min-height: 100%;\n flex-direction: column;\n padding: 0 18px 18px;\n}\n.dsh-ssh-vault-list,\n.dsh-ssh-proxy-list {\n display: grid;\n align-content: start;\n gap: 5px;\n}\n.dsh-ssh-vault-row,\n.dsh-ssh-proxy-row {\n display: grid;\n grid-template-columns: 34px minmax(160px, 1fr) auto 70px 28px 28px;\n align-items: center;\n gap: 9px;\n min-height: 56px;\n padding: 5px 8px;\n border: 1px solid var(--ssh-border);\n border-radius: 10px;\n background: color-mix(in srgb, var(--ssh-surface-raised) 82%, transparent);\n transition:\n background 140ms ease,\n border-color 140ms ease,\n transform 150ms ease;\n}\n.dsh-ssh-vault-row:hover,\n.dsh-ssh-proxy-row:hover {\n border-color: color-mix(in srgb, var(--ssh-accent) 18%, var(--ssh-border));\n background: color-mix(in srgb, var(--ssh-surface-raised) 94%, transparent);\n transform: translateY(-1px);\n}\n.dsh-ssh-vault-glyph {\n display: grid;\n place-items: center;\n width: 30px;\n height: 30px;\n border: 1px solid color-mix(in srgb, var(--ssh-accent) 18%, var(--ssh-border));\n border-radius: 9px;\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-accent) 7%, transparent);\n}\n.dsh-ssh-vault-row > span:nth-child(2),\n.dsh-ssh-proxy-row > span:nth-child(2) {\n display: grid;\n min-width: 0;\n gap: 3px;\n}\n.dsh-ssh-vault-row strong,\n.dsh-ssh-vault-row small,\n.dsh-ssh-proxy-row strong,\n.dsh-ssh-proxy-row small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-vault-row strong,\n.dsh-ssh-proxy-row strong {\n font-size: 12px;\n font-weight: 600;\n}\n.dsh-ssh-vault-row small,\n.dsh-ssh-proxy-row small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n}\n.dsh-ssh-proxy-kind {\n padding: 3px 7px;\n border-radius: 6px;\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-accent) 9%, transparent);\n font: 600 9px/1 var(--ds-font-family-code), monospace;\n}\n.dsh-ssh-vault-state {\n padding: 3px 7px;\n border-radius: 6px;\n color: var(--ssh-danger);\n background: color-mix(in srgb, var(--ssh-danger) 7%, transparent);\n font-size: 9px;\n}\n.dsh-ssh-vault-state.is-ready {\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-accent) 9%, transparent);\n}\n.dsh-ssh-vault-empty {\n display: grid;\n place-items: center;\n align-content: center;\n min-height: 320px;\n text-align: center;\n}\n.dsh-ssh-vault-empty > span {\n display: grid;\n place-items: center;\n width: 46px;\n height: 46px;\n margin-bottom: 12px;\n border: 1px solid var(--ssh-border);\n border-radius: 14px;\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-surface-raised) 88%, transparent);\n box-shadow: 0 12px 30px\n color-mix(in srgb, var(--dsw-alias-label-primary) 5%, transparent);\n}\n.dsh-ssh-vault-empty strong {\n font-size: 13px;\n}\n.dsh-ssh-vault-empty p {\n max-width: 360px;\n margin: 7px 0 16px;\n color: var(--dsw-alias-label-secondary);\n font-size: 11px;\n line-height: 1.55;\n}\n.dsh-ssh-credential-reference {\n display: grid;\n grid-template-columns: 34px minmax(0, 1fr) auto;\n align-items: center;\n gap: 9px;\n min-height: 52px;\n padding: 5px 9px;\n border: 1px solid color-mix(in srgb, var(--ssh-accent) 18%, var(--ssh-border));\n border-radius: 10px;\n background: color-mix(\n in srgb,\n var(--ssh-accent) 6%,\n var(--ssh-surface-raised)\n );\n}\n.dsh-ssh-credential-reference > span:first-child {\n display: grid;\n place-items: center;\n width: 30px;\n height: 30px;\n border-radius: 8px;\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-accent) 9%, transparent);\n}\n.dsh-ssh-credential-reference > span:nth-child(2) {\n display: grid;\n gap: 3px;\n}\n.dsh-ssh-credential-reference strong {\n font-size: 11px;\n}\n.dsh-ssh-credential-reference small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n}\n.dsh-ssh-credential-reference em {\n color: var(--ssh-accent-strong);\n font-size: 9px;\n font-style: normal;\n}\n.dsh-ssh-jump-chain {\n display: grid;\n gap: 8px;\n margin: 0;\n padding: 10px;\n border: 1px solid var(--ssh-border);\n border-radius: 10px;\n background: color-mix(in srgb, var(--ssh-surface-raised) 72%, transparent);\n}\n.dsh-ssh-jump-chain legend {\n padding: 0 5px;\n color: var(--dsw-alias-label-secondary);\n font-size: 10px;\n font-weight: 600;\n}\n.dsh-ssh-jump-chain > p {\n margin: 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n}\n.dsh-ssh-jump-chain > div {\n display: grid;\n gap: 5px;\n}\n.dsh-ssh-jump-row {\n display: grid;\n grid-template-columns: 22px minmax(0, 1fr) 28px 28px 28px;\n align-items: center;\n gap: 4px;\n}\n.dsh-ssh-jump-row > em {\n display: grid;\n place-items: center;\n width: 20px;\n height: 20px;\n border-radius: 6px;\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-accent) 9%, transparent);\n font:\n 600 9px/1 var(--ds-font-family-code),\n monospace;\n font-style: normal;\n}\n.dsh-ssh-jump-row select {\n box-sizing: border-box;\n min-width: 0;\n height: 30px;\n padding: 0 8px;\n border: 1px solid var(--ssh-border);\n border-radius: 8px;\n color: var(--dsw-alias-label-primary);\n background: var(--ssh-surface-raised);\n font-size: 10px;\n}\n.dsh-ssh-jump-row .dsh-ssh-icon-button:disabled {\n opacity: 0.3;\n cursor: default;\n}\n.dsh-ssh-jump-empty {\n padding: 7px !important;\n border-radius: 7px;\n background: color-mix(in srgb, var(--ssh-warning) 7%, transparent);\n}\n.dsh-ssh-jump-chain > .dsh-ssh-secondary-button {\n justify-self: start;\n}\n@keyframes dsh-ssh-panel-enter {\n from {\n opacity: 0;\n transform: translateX(6px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n@keyframes dsh-ssh-content-enter {\n from {\n opacity: 0;\n transform: translateY(3px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n@keyframes dsh-ssh-group-open {\n from {\n opacity: 0;\n transform: translateY(-2px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n@media (max-width: 820px) {\n .dsh-ssh-vault-row,\n .dsh-ssh-proxy-row {\n grid-template-columns: 34px minmax(120px, 1fr) auto 28px;\n }\n .dsh-ssh-vault-row > small,\n .dsh-ssh-vault-row > .dsh-ssh-icon-button:last-child,\n .dsh-ssh-proxy-row > small,\n .dsh-ssh-proxy-row > .dsh-ssh-icon-button:last-child {\n display: none;\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .dsh-ssh-activity-panel,\n .dsh-ssh-file-preview-body,\n .dsh-ssh-profile-group-children {\n animation: none;\n }\n .dsh-ssh-profile-row,\n .dsh-ssh-profile-row::before,\n .dsh-ssh-profile-group-chevron,\n .dsh-ssh-vault-row,\n .dsh-ssh-proxy-row,\n .dsh-ssh-sftp-row,\n .dsh-ssh-terminal-switcher button {\n transition: none;\n }\n}\n.dsh-ssh-sidebar-panel {\n display: flex;\n align-items: center;\n gap: 7px;\n min-height: 34px;\n padding: 0 9px;\n border: 1px solid transparent;\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n font: 550 11px/1 var(--ds-font-family);\n text-align: left;\n cursor: pointer;\n}\n.dsh-ssh-sidebar-panel svg {\n color: #547d78;\n}\n.dsh-ssh-sidebar-panel:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-sidebar-panel:active {\n transform: scale(0.985);\n}\n.dsh-ssh-icon-button.is-active,\n.dsh-ssh-rail-button.is-active {\n color: #406e67;\n background: color-mix(in srgb, #547d78 9%, transparent);\n}\n.dsh-ssh-icon-button:disabled,\n.dsh-ssh-rail-button:disabled {\n opacity: 0.36;\n cursor: default;\n}\n.dsh-ssh-icon-button:disabled:hover,\n.dsh-ssh-rail-button:disabled:hover {\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n}\n.dsh-ssh-test-button {\n margin-right: auto;\n}\n.dsh-ssh-test-result {\n box-sizing: border-box;\n margin: 0;\n border-radius: 9px;\n font-size: 10px;\n}\n.dsh-ssh-test-result.is-warning {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 14px;\n padding: 9px 10px;\n border: 1px solid color-mix(in srgb, var(--ssh-warning) 22%, transparent);\n color: color-mix(\n in srgb,\n var(--ssh-warning) 82%,\n var(--dsw-alias-label-primary)\n );\n background: color-mix(in srgb, var(--ssh-warning) 7%, transparent);\n}\n.dsh-ssh-test-result.is-warning > span {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n.dsh-ssh-test-result.is-warning code {\n overflow: hidden;\n font:\n 9px/1.3 var(--ds-font-family-code),\n monospace;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-test-result.is-success {\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 8px 10px;\n color: #477565;\n background: color-mix(in srgb, #5c8a76 9%, transparent);\n}\n.dsh-ssh-sidebar-note {\n box-sizing: border-box;\n min-height: 32px;\n margin: 0;\n padding: 8px 9px;\n color: var(--dsw-alias-label-tertiary);\n font: 10px/1.4 var(--ds-font-family);\n}\n.dsh-ssh-profile-sftp-pane {\n box-sizing: border-box;\n display: flex;\n min-height: 100%;\n height: 100%;\n flex-direction: column;\n padding: 0 18px 18px;\n}\n.dsh-ssh-profile-sftp-pane > .dsh-ssh-content-heading {\n flex: none;\n}\n.dsh-ssh-sftp.is-workspace {\n --ssh-activity-border: var(--ssh-border);\n min-height: 0;\n flex: 1;\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-pathbar {\n margin-bottom: 10px;\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-columns,\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row {\n grid-template-columns: minmax(180px, 1fr) 90px 120px;\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-columns {\n min-height: 34px;\n padding: 0 12px;\n font-size: 9px;\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row {\n min-height: 40px;\n padding: 0 12px;\n cursor: pointer;\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row strong {\n font-size: 11px;\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row small {\n font-size: 9px;\n}\n.dsh-ssh-upload-conflict {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 9px;\n padding: 8px 10px;\n border: 1px solid\n color-mix(in srgb, var(--ssh-warning, #927443) 20%, transparent);\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n background: color-mix(in srgb, var(--ssh-warning, #927443) 7%, transparent);\n}\n.dsh-ssh-upload-conflict > span {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dsh-ssh-upload-conflict > span:first-child {\n min-width: 0;\n}\n.dsh-ssh-upload-conflict strong {\n font-size: 10px;\n}\n.dsh-ssh-upload-conflict small {\n overflow: hidden;\n max-width: 240px;\n color: var(--dsw-alias-label-tertiary);\n font:\n 9px/1 var(--ds-font-family-code),\n monospace;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-upload-conflict button {\n min-height: 26px;\n padding: 0 9px;\n border: 1px solid var(--ssh-border);\n border-radius: 7px;\n color: var(--dsw-alias-label-secondary);\n background: var(--ssh-surface-raised);\n font-size: 9px;\n cursor: pointer;\n}\n.dsh-ssh-upload-conflict button.is-primary {\n border-color: color-mix(in srgb, var(--ssh-accent-strong) 56%, transparent);\n color: #f6fbf9;\n background: var(--ssh-accent-strong);\n}\n';
|
|
6408
|
+
var client_default = '.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n.dsh-ssh-sidebar {\n box-sizing: border-box;\n flex: none;\n margin: 0 8px 8px 2px;\n padding: 4px 0 6px;\n border-bottom: 1px solid\n color-mix(in srgb, var(--dsw-alias-border-l2) 62%, transparent);\n color: var(--dsw-alias-label-primary);\n}\n.dsh-ssh-sidebar.is-rail {\n width: 36px;\n margin: 0 0 8px;\n padding: 0;\n border: 0;\n}\n.dsh-ssh-sidebar-heading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 32px;\n padding: 0 4px 0 5px;\n}\n.dsh-ssh-sidebar-title {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 5px;\n height: 28px;\n padding: 0 5px;\n color: var(--dsw-alias-label-secondary);\n border: 0;\n background: transparent;\n border-radius: 7px;\n font: 600 12px/1 var(--ds-font-family);\n cursor: pointer;\n}\n.dsh-ssh-sidebar-title:hover,\n.dsh-ssh-icon-button:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-disclosure {\n display: grid;\n place-items: center;\n transition: transform 0.16s ease;\n}\n.dsh-ssh-disclosure[data-open="false"] {\n transform: rotate(-90deg);\n}\n.dsh-ssh-icon-button {\n display: inline-grid;\n place-items: center;\n flex: none;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 0;\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n cursor: pointer;\n}\n.dsh-ssh-icon-button.is-danger {\n color: #a65d58;\n}\n.dsh-ssh-sidebar-list {\n display: grid;\n gap: 2px;\n padding: 2px 1px 0;\n}\n.dsh-ssh-sidebar-row,\n.dsh-ssh-sidebar-empty,\n.dsh-ssh-sidebar-more {\n box-sizing: border-box;\n width: 100%;\n border: 1px solid transparent;\n background: transparent;\n color: inherit;\n cursor: pointer;\n}\n.dsh-ssh-sidebar-row {\n display: grid;\n grid-template-columns: 12px minmax(0, 1fr) 18px;\n align-items: center;\n gap: 7px;\n min-height: 40px;\n padding: 4px 7px;\n border-radius: 9px;\n text-align: left;\n}\n.dsh-ssh-sidebar-row:hover {\n background: color-mix(\n in srgb,\n var(--dsw-alias-interactive-bg-hover) 70%,\n transparent\n );\n}\n.dsh-ssh-sidebar-row.is-active {\n background: color-mix(\n in srgb,\n var(--dsw-alias-interactive-bg-hover) 92%,\n transparent\n );\n border-color: color-mix(in srgb, var(--dsw-alias-border-l2) 50%, transparent);\n}\n.dsh-ssh-status-dot {\n display: block;\n width: 7px;\n height: 7px;\n margin: auto;\n border: 1px solid\n color-mix(in srgb, var(--dsw-alias-label-secondary) 62%, transparent);\n border-radius: 50%;\n}\n.dsh-ssh-status-dot.is-injected {\n border-color: #5b8f82;\n background: #5b8f82;\n box-shadow: 0 0 0 2px color-mix(in srgb, #5b8f82 14%, transparent);\n}\n.dsh-ssh-sidebar-copy {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n.dsh-ssh-sidebar-copy strong,\n.dsh-ssh-sidebar-copy small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-sidebar-copy strong {\n font-size: 13px;\n font-weight: 500;\n}\n.dsh-ssh-sidebar-copy small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n}\n.dsh-ssh-injected-mark {\n display: grid;\n place-items: center;\n color: #5b8f82;\n}\n.dsh-ssh-sidebar-empty,\n.dsh-ssh-sidebar-more {\n min-height: 34px;\n padding: 6px 10px;\n border-radius: 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n text-align: left;\n}\n.dsh-ssh-sidebar-empty:hover,\n.dsh-ssh-sidebar-more:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-rail-button {\n display: grid;\n place-items: center;\n width: 36px;\n height: 36px;\n padding: 0;\n border: 0;\n border-radius: 10px;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n cursor: pointer;\n}\n.dsh-ssh-rail-button:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-server-glyph {\n display: inline-grid;\n place-items: center;\n color: currentColor;\n}\n.dsh-ssh-workspace,\n.dsh-ssh-activity-panel {\n --ssh-accent: #547d78;\n --ssh-accent-strong: #406e67;\n --ssh-danger: #9c504c;\n --ssh-warning: #927443;\n --ssh-surface: var(--xiaohei-plugin-pane-fill, transparent);\n --ssh-surface-raised: var(\n --xiaohei-plugin-raised-fill,\n color-mix(in srgb, var(--dsw-alias-bg-layer-2, #fff) 76%, transparent)\n );\n --ssh-activity-surface: var(--ssh-surface);\n --ssh-activity-surface-raised: var(--ssh-surface-raised);\n --ssh-border: color-mix(\n in srgb,\n var(--dsw-alias-label-primary) 10%,\n transparent\n );\n --dpu-navigation-width: 248px;\n --dpu-inspector-width: 292px;\n --dpu-border: var(--ssh-border);\n --dpu-accent: var(--ssh-accent);\n --dpu-accent-strong: var(--ssh-accent-strong);\n --dpu-raised-surface: var(--ssh-surface-raised);\n --dpu-toolbar-surface: var(\n --xiaohei-plugin-control-fill,\n color-mix(in srgb, var(--ssh-surface-raised) 88%, transparent)\n );\n}\n.dsh-ssh-workspace {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n color: var(--dsw-alias-label-primary);\n background: var(--ssh-surface);\n font-family:\n var(--ds-font-family),\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n}\n.dsh-ssh-toolbar {\n display: grid;\n grid-template-columns: minmax(180px, 1fr) auto minmax(180px, 1fr);\n align-items: center;\n gap: 16px;\n min-height: 64px;\n padding: 0 20px;\n border-bottom: 1px solid var(--ssh-border);\n background: var(--dpu-toolbar-surface);\n}\n.dsh-ssh-brand {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n}\n.dsh-ssh-brand-glyph {\n display: grid;\n place-items: center;\n width: 30px;\n height: 30px;\n border: 1px solid color-mix(in srgb, var(--ssh-accent) 28%, transparent);\n border-radius: 9px;\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-accent) 8%, transparent);\n}\n.dsh-ssh-brand > span:last-child {\n display: grid;\n gap: 1px;\n}\n.dsh-ssh-brand strong {\n font-size: 14px;\n font-weight: 650;\n}\n.dsh-ssh-brand small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n}\n.dsh-ssh-segments {\n display: flex;\n gap: 2px;\n padding: 3px;\n border: 1px solid color-mix(in srgb, var(--ssh-border) 80%, transparent);\n border-radius: 10px;\n background: color-mix(\n in srgb,\n var(--dsw-alias-label-primary) 3%,\n transparent\n );\n}\n.dsh-ssh-segments button {\n min-width: 74px;\n height: 28px;\n padding: 0 12px;\n border: 0;\n border-radius: 7px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n font-size: 12px;\n cursor: pointer;\n}\n.dsh-ssh-segments button:hover {\n color: var(--dsw-alias-label-primary);\n}\n.dsh-ssh-segments button.is-active {\n color: var(--dsw-alias-label-primary);\n background: var(--ssh-surface-raised);\n box-shadow: 0 1px 2px\n color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n.dsh-ssh-toolbar > .dsh-ssh-primary-button {\n justify-self: end;\n}\n.dsh-ssh-primary-button,\n.dsh-ssh-secondary-button,\n.dsh-ssh-danger-button,\n.dsh-ssh-small-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n min-height: 30px;\n padding: 0 12px;\n border-radius: 8px;\n font: 500 12px/1 var(--ds-font-family);\n cursor: pointer;\n}\n.dsh-ssh-primary-button,\n.dsh-ssh-small-primary {\n border: 1px solid\n color-mix(in srgb, var(--ssh-accent-strong) 64%, transparent);\n color: #f6fbf9;\n background: var(--ssh-accent-strong);\n}\n.dsh-ssh-primary-button:hover,\n.dsh-ssh-small-primary:hover {\n background: color-mix(in srgb, var(--ssh-accent-strong) 88%, #000);\n}\n.dsh-ssh-primary-button:disabled {\n opacity: 0.55;\n cursor: default;\n}\n.dsh-ssh-secondary-button {\n border: 1px solid var(--ssh-border);\n color: var(--dsw-alias-label-primary);\n background: var(--ssh-surface-raised);\n}\n.dsh-ssh-secondary-button:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-danger-button {\n border: 1px solid color-mix(in srgb, var(--ssh-danger) 28%, transparent);\n color: var(--ssh-danger);\n background: color-mix(in srgb, var(--ssh-danger) 7%, transparent);\n}\n.dsh-ssh-small-primary {\n min-height: 26px;\n padding: 0 9px;\n}\n.dsh-ssh-profile-panel,\n.dsh-ssh-inspector {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n background: var(--ssh-surface-raised);\n}\n.dsh-ssh-profile-panel {\n border-right: 1px solid var(--ssh-border);\n}\n.dsh-ssh-inspector {\n border-left: 1px solid var(--ssh-border);\n}\n.dsh-ssh-main-panel {\n min-width: 0;\n min-height: 0;\n overflow: auto;\n background: var(--ssh-surface);\n}\n.dsh-ssh-panel-heading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 58px;\n padding: 0 14px;\n border-bottom: 1px solid\n color-mix(in srgb, var(--ssh-border) 74%, transparent);\n}\n.dsh-ssh-panel-heading > span {\n display: grid;\n gap: 2px;\n}\n.dsh-ssh-panel-heading strong {\n font-size: 12px;\n font-weight: 650;\n}\n.dsh-ssh-panel-heading small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n}\n.dsh-ssh-search {\n padding: 10px 10px 6px;\n}\n.dsh-ssh-search input,\n.dsh-ssh-field input,\n.dsh-ssh-field select,\n.dsh-ssh-field textarea,\n.dsh-ssh-number-row input {\n box-sizing: border-box;\n width: 100%;\n border: 1px solid var(--ssh-border);\n border-radius: 8px;\n outline: 0;\n color: var(--dsw-alias-label-primary);\n background: color-mix(in srgb, var(--ssh-surface-raised) 92%, transparent);\n font: 400 12px/1.35 var(--ds-font-family);\n}\n.dsh-ssh-search input {\n height: 30px;\n padding: 0 10px;\n}\n.dsh-ssh-search input:focus,\n.dsh-ssh-field input:focus,\n.dsh-ssh-field select:focus,\n.dsh-ssh-field textarea:focus,\n.dsh-ssh-number-row input:focus {\n border-color: color-mix(in srgb, var(--ssh-accent) 65%, transparent);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--ssh-accent) 12%, transparent);\n}\n.dsh-ssh-profile-list {\n display: grid;\n align-content: start;\n gap: 3px;\n min-height: 0;\n overflow: auto;\n padding: 4px 7px 12px;\n}\n.dsh-ssh-profile-group {\n min-width: 0;\n}\n.dsh-ssh-profile-group-heading {\n display: grid;\n grid-template-columns: 14px 18px minmax(0, 1fr);\n align-items: center;\n gap: 5px;\n width: 100%;\n min-height: 34px;\n padding: 0 6px;\n border: 0;\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n text-align: left;\n cursor: pointer;\n}\n.dsh-ssh-profile-group-heading:hover {\n color: var(--dsw-alias-label-primary);\n background: color-mix(\n in srgb,\n var(--dsw-alias-interactive-bg-hover) 58%,\n transparent\n );\n}\n.dsh-ssh-profile-group-heading:focus-visible {\n outline: 2px solid color-mix(in srgb, var(--ssh-accent) 54%, transparent);\n outline-offset: -2px;\n}\n.dsh-ssh-profile-group-chevron {\n display: grid;\n place-items: center;\n transition: transform 160ms cubic-bezier(0.2, 0.8, 0.2, 1);\n}\n.dsh-ssh-profile-group-chevron[data-open="false"] {\n transform: rotate(-90deg);\n}\n.dsh-ssh-profile-group-folder {\n display: grid;\n place-items: center;\n color: color-mix(\n in srgb,\n var(--ssh-accent-strong) 72%,\n var(--dsw-alias-label-secondary)\n );\n}\n.dsh-ssh-profile-group-copy {\n display: flex;\n min-width: 0;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n.dsh-ssh-profile-group-copy strong {\n overflow: hidden;\n font-size: 11px;\n font-weight: 600;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-profile-group-copy small {\n display: grid;\n place-items: center;\n min-width: 16px;\n height: 16px;\n color: var(--dsw-alias-label-tertiary);\n font:\n 9px/1 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-profile-group-children {\n display: grid;\n gap: 1px;\n margin-left: 13px;\n padding-left: 6px;\n border-left: 1px solid color-mix(in srgb, var(--ssh-border) 66%, transparent);\n animation: dsh-ssh-group-open 140ms ease-out both;\n}\n.dsh-ssh-profile-empty {\n margin: 18px 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n text-align: center;\n}\n.dsh-ssh-profile-row {\n display: grid;\n grid-template-columns: 30px minmax(0, 1fr) 10px;\n align-items: center;\n gap: 9px;\n width: 100%;\n min-height: 48px;\n padding: 5px 7px;\n border: 1px solid transparent;\n border-radius: 9px;\n color: inherit;\n background: transparent;\n text-align: left;\n cursor: pointer;\n}\n.dsh-ssh-profile-row:hover {\n background: color-mix(\n in srgb,\n var(--dsw-alias-interactive-bg-hover) 74%,\n transparent\n );\n}\n.dsh-ssh-profile-row.is-active {\n border-color: color-mix(in srgb, var(--ssh-accent) 16%, transparent);\n background: color-mix(in srgb, var(--ssh-accent) 9%, transparent);\n}\n.dsh-ssh-host-monogram {\n display: grid;\n place-items: center;\n width: 28px;\n height: 28px;\n border: 1px solid var(--ssh-border);\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n background: var(--ssh-surface-raised);\n font-size: 11px;\n font-weight: 650;\n}\n.dsh-ssh-profile-row > span:nth-child(2) {\n display: grid;\n min-width: 0;\n gap: 3px;\n}\n.dsh-ssh-profile-row strong,\n.dsh-ssh-profile-row small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-profile-row strong {\n font-size: 12px;\n font-weight: 550;\n}\n.dsh-ssh-profile-row small {\n color: var(--dsw-alias-label-tertiary);\n font:\n 10px/1.2 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-credential-state {\n width: 6px;\n height: 6px;\n border: 1px solid var(--dsw-alias-label-tertiary);\n border-radius: 50%;\n}\n.dsh-ssh-credential-state.is-ready {\n border-color: #5c8a76;\n background: #5c8a76;\n}\n.dsh-ssh-terminal-pane,\n.dsh-ssh-forward-pane,\n.dsh-ssh-settings-pane {\n box-sizing: border-box;\n display: flex;\n min-width: 0;\n min-height: 100%;\n flex-direction: column;\n padding: 0 18px 18px;\n}\n.dsh-ssh-content-heading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 20px;\n min-height: 76px;\n}\n.dsh-ssh-content-heading h1 {\n margin: 0;\n font-size: 16px;\n font-weight: 650;\n letter-spacing: -0.01em;\n}\n.dsh-ssh-content-heading p {\n margin: 4px 0 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n.dsh-ssh-heading-actions {\n display: flex;\n align-items: center;\n gap: 7px;\n}\n.dsh-ssh-title-line {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dsh-ssh-live-dot {\n width: 7px;\n height: 7px;\n border: 1px solid var(--dsw-alias-label-tertiary);\n border-radius: 50%;\n}\n.dsh-ssh-live-dot.is-connected {\n border-color: #4d8d77;\n background: #4d8d77;\n box-shadow: 0 0 0 3px color-mix(in srgb, #4d8d77 12%, transparent);\n}\n.dsh-ssh-live-dot.is-connecting {\n border-color: #a27e45;\n background: #a27e45;\n}\n.dsh-ssh-live-dot.is-error {\n border-color: #a85a55;\n background: #a85a55;\n}\n.dsh-ssh-terminal-frame {\n display: flex;\n min-height: 360px;\n flex: 1;\n flex-direction: column;\n overflow: hidden;\n border: 1px solid color-mix(in srgb, #8ba49e 22%, #101817);\n border-radius: 12px;\n background: #111817;\n box-shadow: 0 10px 34px color-mix(in srgb, #0d1513 14%, transparent);\n}\n.dsh-ssh-xterm {\n min-height: 0;\n flex: 1;\n padding: 11px 11px 0;\n}\n.dsh-ssh-xterm .xterm {\n height: 100%;\n}\n.dsh-ssh-terminal-status {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 28px;\n padding: 0 11px;\n border-top: 1px solid #ffffff12;\n color: #879691;\n background: #0d1413;\n font:\n 10px/1 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-banner {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 8px 18px;\n border-bottom: 1px solid transparent;\n font-size: 11px;\n}\n.dsh-ssh-banner > span {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n.dsh-ssh-banner code {\n font-family: var(--ds-font-family-code), monospace;\n}\n.dsh-ssh-banner button:not(.dsh-ssh-small-primary) {\n display: grid;\n place-items: center;\n border: 0;\n color: inherit;\n background: transparent;\n}\n.dsh-ssh-banner.is-error {\n border-color: color-mix(in srgb, var(--ssh-danger) 22%, transparent);\n color: var(--ssh-danger);\n background: color-mix(in srgb, var(--ssh-danger) 7%, var(--ssh-surface));\n}\n.dsh-ssh-banner.is-warning {\n border-color: color-mix(in srgb, var(--ssh-warning) 22%, transparent);\n color: color-mix(\n in srgb,\n var(--ssh-warning) 85%,\n var(--dsw-alias-label-primary)\n );\n background: color-mix(in srgb, var(--ssh-warning) 8%, var(--ssh-surface));\n}\n.dsh-ssh-inline-error {\n margin: 0 0 10px;\n padding: 7px 9px;\n border-radius: 7px;\n color: var(--ssh-danger);\n background: color-mix(in srgb, var(--ssh-danger) 7%, transparent);\n font-size: 11px;\n}\n.dsh-ssh-empty-state {\n display: grid;\n place-items: center;\n align-content: center;\n min-height: 100%;\n padding: 40px;\n text-align: center;\n}\n.dsh-ssh-empty-state > span {\n display: grid;\n place-items: center;\n width: 48px;\n height: 48px;\n margin-bottom: 14px;\n border: 1px solid var(--ssh-border);\n border-radius: 14px;\n color: var(--ssh-accent);\n background: var(--ssh-surface-raised);\n}\n.dsh-ssh-empty-state h1 {\n margin: 0;\n font-size: 17px;\n}\n.dsh-ssh-empty-state p {\n max-width: 420px;\n margin: 8px 0 18px;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 1.6;\n}\n.dsh-ssh-inspector {\n overflow: auto;\n}\n.dsh-ssh-session-chip {\n display: flex;\n align-items: center;\n gap: 9px;\n margin: 12px 12px 4px;\n padding: 9px 10px;\n border: 1px solid var(--ssh-border);\n border-radius: 9px;\n background: color-mix(in srgb, var(--ssh-surface-raised) 86%, transparent);\n}\n.dsh-ssh-session-chip > span:nth-child(2) {\n display: grid;\n gap: 2px;\n}\n.dsh-ssh-session-chip strong {\n font-size: 11px;\n}\n.dsh-ssh-session-chip small {\n color: var(--dsw-alias-label-tertiary);\n font:\n 9px/1 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-session-pulse {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--ssh-accent);\n}\n.dsh-ssh-fieldset {\n display: grid;\n gap: 3px;\n margin: 13px 12px 0;\n padding: 0;\n border: 0;\n}\n.dsh-ssh-fieldset legend {\n margin-bottom: 5px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n font-weight: 600;\n}\n.dsh-ssh-check-row,\n.dsh-ssh-radio-row {\n display: flex;\n align-items: center;\n gap: 9px;\n min-height: 38px;\n padding: 3px 5px;\n border-radius: 8px;\n}\n.dsh-ssh-check-row:hover,\n.dsh-ssh-radio-row:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-check-row input,\n.dsh-ssh-radio-row input {\n accent-color: var(--ssh-accent);\n}\n.dsh-ssh-check-row > span,\n.dsh-ssh-radio-row > span {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n.dsh-ssh-check-row strong,\n.dsh-ssh-radio-row strong {\n font-size: 11px;\n font-weight: 550;\n}\n.dsh-ssh-check-row small,\n.dsh-ssh-radio-row small {\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-switch-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 20px;\n min-height: 48px;\n margin: 13px 12px 0;\n padding: 7px 9px;\n border: 1px solid var(--ssh-border);\n border-radius: 9px;\n}\n.dsh-ssh-switch-row > span {\n display: grid;\n gap: 3px;\n}\n.dsh-ssh-switch-row strong {\n font-size: 11px;\n font-weight: 550;\n}\n.dsh-ssh-switch-row small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n line-height: 1.35;\n}\n.dsh-ssh-switch-row input {\n width: 28px;\n height: 16px;\n accent-color: var(--ssh-accent);\n}\n.dsh-ssh-inspector-hint,\n.dsh-ssh-save-state {\n margin: 10px 12px 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n}\n.dsh-ssh-inspector-empty {\n margin: 14px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n line-height: 1.55;\n}\n.dsh-ssh-forward-list {\n display: grid;\n align-content: start;\n gap: 5px;\n}\n.dsh-ssh-forward-row {\n display: grid;\n grid-template-columns: 32px minmax(0, 1fr) auto 28px auto 28px;\n align-items: center;\n gap: 8px;\n min-height: 54px;\n padding: 6px 9px;\n border: 1px solid var(--ssh-border);\n border-radius: 10px;\n background: color-mix(in srgb, var(--ssh-surface-raised) 88%, transparent);\n}\n.dsh-ssh-forward-kind {\n display: grid;\n place-items: center;\n width: 28px;\n height: 28px;\n border: 1px solid var(--ssh-border);\n border-radius: 8px;\n color: var(--ssh-accent-strong);\n font:\n 600 11px/1 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-forward-copy {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n.dsh-ssh-forward-copy strong {\n font-size: 12px;\n}\n.dsh-ssh-forward-copy small {\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font:\n 10px/1 var(--ds-font-family-code),\n monospace;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-state-label {\n padding: 3px 7px;\n border-radius: 999px;\n color: var(--dsw-alias-label-tertiary);\n background: color-mix(\n in srgb,\n var(--dsw-alias-label-primary) 5%,\n transparent\n );\n font-size: 9px;\n}\n.dsh-ssh-state-label.is-running {\n color: #497967;\n background: color-mix(in srgb, #5d957f 10%, transparent);\n}\n.dsh-ssh-state-label.is-error {\n color: var(--ssh-danger);\n background: color-mix(in srgb, var(--ssh-danger) 8%, transparent);\n}\n.dsh-ssh-table-empty {\n display: grid;\n place-items: center;\n min-height: 180px;\n border: 1px dashed var(--ssh-border);\n border-radius: 12px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n}\n.dsh-ssh-settings-group {\n display: grid;\n max-width: 680px;\n gap: 8px;\n}\n.dsh-ssh-settings-group .dsh-ssh-switch-row {\n margin: 0;\n}\n.dsh-ssh-number-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 120px 32px;\n align-items: center;\n gap: 8px;\n min-height: 60px;\n padding: 6px 10px;\n border: 1px solid var(--ssh-border);\n border-radius: 10px;\n background: color-mix(in srgb, var(--ssh-surface-raised) 80%, transparent);\n}\n.dsh-ssh-number-row > span {\n display: grid;\n gap: 3px;\n}\n.dsh-ssh-number-row strong {\n font-size: 11px;\n}\n.dsh-ssh-number-row small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n}\n.dsh-ssh-number-row input {\n height: 30px;\n padding: 0 8px;\n}\n.dsh-ssh-number-row em {\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n font-style: normal;\n}\n.dsh-ssh-dialog-layer {\n position: fixed;\n z-index: 1000;\n inset: 0;\n display: grid;\n place-items: center;\n padding: 28px;\n background: color-mix(in srgb, #111817 28%, transparent);\n backdrop-filter: blur(3px);\n}\n.dsh-ssh-dialog {\n box-sizing: border-box;\n width: min(620px, calc(100vw - 40px));\n max-height: min(760px, calc(100vh - 40px));\n overflow: auto;\n border: 1px solid\n color-mix(in srgb, var(--dsw-alias-label-primary) 15%, transparent);\n border-radius: 14px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base, #f7f8f7);\n box-shadow: 0 24px 70px #07100d2e;\n}\n.dsh-ssh-dialog > header {\n position: sticky;\n z-index: 1;\n top: 0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 64px;\n padding: 0 18px;\n border-bottom: 1px solid\n var(\n --ssh-border,\n color-mix(in srgb, var(--dsw-alias-label-primary) 10%, transparent)\n );\n background: color-mix(\n in srgb,\n var(--dsw-alias-bg-base, #f7f8f7) 94%,\n transparent\n );\n backdrop-filter: blur(12px);\n}\n.dsh-ssh-dialog h2 {\n margin: 0;\n font-size: 17px;\n font-weight: 650;\n letter-spacing: -0.01em;\n}\n.dsh-ssh-dialog header p {\n margin: 3px 0 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n.dsh-ssh-form {\n --ssh-border: color-mix(\n in srgb,\n var(--dsw-alias-label-primary) 11%,\n transparent\n );\n --ssh-accent: #547d78;\n --ssh-accent-strong: #406e67;\n --ssh-danger: #9c504c;\n display: grid;\n gap: 15px;\n padding: 20px 18px 18px;\n}\n.dsh-ssh-form-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n}\n.dsh-ssh-form-grid.is-host {\n grid-template-columns: minmax(0, 1fr) 110px;\n}\n.dsh-ssh-field {\n display: grid;\n gap: 5px;\n min-width: 0;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n font-weight: 600;\n}\n.dsh-ssh-field input,\n.dsh-ssh-field select {\n height: 38px;\n padding: 0 10px;\n font-size: 13px;\n}\n.dsh-ssh-field textarea {\n padding: 9px 10px;\n font-size: 13px;\n line-height: 1.5;\n resize: vertical;\n font-family: var(--ds-font-family-code), monospace;\n}\n.dsh-ssh-field small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n line-height: 1.4;\n font-weight: 400;\n}\n.dsh-ssh-form-divider {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-top: 2px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n font-weight: 600;\n}\n.dsh-ssh-form-divider:after {\n height: 1px;\n flex: 1;\n background: var(--ssh-border);\n content: "";\n}\n.dsh-ssh-dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding-top: 5px;\n}\n.dsh-ssh-dialog-actions .dsh-ssh-primary-button,\n.dsh-ssh-dialog-actions .dsh-ssh-secondary-button {\n min-height: 34px;\n font-size: 13px;\n}\n.dsh-ssh-form .dsh-ssh-switch-row {\n margin: 0;\n}\n.dsh-ssh-form .dsh-ssh-inline-error {\n margin: 0;\n}\n@container dpu-workspace (max-width: 1120px) {\n .dsh-ssh-toolbar {\n grid-template-columns: 1fr auto auto;\n }\n .dsh-ssh-brand small {\n display: none;\n }\n}\n@container dpu-workspace (max-width: 820px) {\n .dsh-ssh-toolbar {\n grid-template-columns: 1fr auto;\n gap: 8px;\n padding: 0 12px;\n }\n .dsh-ssh-segments {\n grid-row: 2;\n grid-column: 1/-1;\n margin-bottom: 8px;\n overflow-x: auto;\n scrollbar-width: none;\n }\n .dsh-ssh-segments::-webkit-scrollbar {\n display: none;\n }\n .dsh-ssh-segments button {\n min-width: 72px;\n height: 36px;\n flex: none;\n }\n .dsh-ssh-toolbar {\n padding-top: 8px;\n }\n .dsh-ssh-content-heading {\n align-items: flex-start;\n flex-direction: column;\n padding: 14px 0;\n }\n .dsh-ssh-heading-actions {\n flex-wrap: wrap;\n }\n .dsh-ssh-forward-row {\n grid-template-columns: 32px minmax(0, 1fr) auto;\n }\n .dsh-ssh-forward-row > .dsh-ssh-icon-button,\n .dsh-ssh-forward-row > .dsh-ssh-small-primary {\n display: none;\n }\n}\n@container dpu-workspace (max-width: 520px) {\n .dsh-ssh-toolbar {\n padding-right: max(10px, env(safe-area-inset-right));\n padding-left: max(10px, env(safe-area-inset-left));\n }\n .dsh-ssh-toolbar > .dsh-ssh-primary-button {\n width: 40px;\n min-height: 40px;\n padding: 0;\n }\n .dsh-ssh-toolbar > .dsh-ssh-primary-button span {\n display: none;\n }\n .dsh-ssh-terminal-pane,\n .dsh-ssh-forward-pane,\n .dsh-ssh-settings-pane,\n .dsh-ssh-vault-pane,\n .dsh-ssh-proxy-pane,\n .dsh-ssh-profile-sftp-pane {\n padding-right: 10px;\n padding-left: 10px;\n }\n .dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-columns,\n .dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row {\n grid-template-columns: minmax(120px, 1fr) 64px;\n }\n .dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-columns > :nth-child(3),\n .dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row > :nth-child(3) {\n display: none;\n }\n .dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row {\n min-height: 44px;\n }\n .dsh-ssh-number-row {\n grid-template-columns: minmax(0, 1fr) 86px 28px;\n }\n}\n@media (max-width: 600px) {\n .dsh-ssh-dialog-layer {\n align-items: stretch;\n padding: 0;\n }\n .dsh-ssh-dialog {\n width: 100%;\n max-height: 100dvh;\n border: 0;\n border-radius: 0;\n }\n .dsh-ssh-form-grid,\n .dsh-ssh-form-grid.is-host {\n grid-template-columns: 1fr;\n }\n .dsh-ssh-dialog-actions {\n position: sticky;\n bottom: 0;\n flex-wrap: wrap;\n padding: 10px 0 max(10px, env(safe-area-inset-bottom));\n background: var(--dsw-alias-bg-base, #f7f8f7);\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .dsh-ssh-disclosure {\n transition: none;\n }\n}\n@media (prefers-reduced-transparency: reduce) {\n .dsh-ssh-dialog-layer {\n backdrop-filter: none;\n }\n .dsh-ssh-dialog > header {\n backdrop-filter: none;\n }\n}\n\n.dsh-ssh-activity-trigger {\n box-sizing: border-box;\n display: inline-grid;\n place-items: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 1px solid transparent;\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n cursor: pointer;\n}\n.dsh-ssh-activity-trigger:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-activity-trigger.is-active {\n border-color: color-mix(in srgb, var(--ssh-accent, #547d78) 16%, transparent);\n color: var(--ssh-accent-strong, #406e67);\n background: color-mix(in srgb, var(--ssh-accent, #547d78) 8%, transparent);\n}\n.dsh-ssh-panel-right-icon {\n transform: rotate(180deg);\n}\n.dsh-ssh-activity-trigger:focus-visible,\n.dsh-ssh-activity-tabs button:focus-visible,\n.dsh-ssh-sftp button:focus-visible,\n.dsh-ssh-sftp input:focus-visible,\n.dsh-ssh-sftp select:focus-visible {\n outline: 2px solid\n color-mix(in srgb, var(--ssh-accent, #547d78) 62%, transparent);\n outline-offset: 2px;\n}\n.dsh-ssh-activity-panel {\n --ssh-activity-border: color-mix(\n in srgb,\n var(--dsw-alias-label-primary) 10%,\n transparent\n );\n box-sizing: border-box;\n display: flex;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n color: var(--dsw-alias-label-primary);\n background: var(--ssh-activity-surface);\n font-family:\n var(--ds-font-family),\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n}\n.dsh-ssh-activity-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 58px;\n padding: 0 12px 0 14px;\n border-bottom: 1px solid var(--ssh-activity-border);\n background: var(--ssh-activity-surface-raised);\n}\n.dsh-ssh-activity-header > span {\n display: grid;\n min-width: 0;\n gap: 3px;\n}\n.dsh-ssh-activity-header strong {\n font-size: 13px;\n font-weight: 650;\n}\n.dsh-ssh-activity-header small {\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font:\n 10px/1.2 var(--ds-font-family-code),\n monospace;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-activity-tabs {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 3px;\n margin: 10px 12px 0;\n padding: 3px;\n border: 1px solid var(--ssh-activity-border);\n border-radius: 10px;\n background: color-mix(\n in srgb,\n var(--dsw-alias-label-primary) 3%,\n transparent\n );\n}\n.dsh-ssh-activity-tabs button {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n min-height: 30px;\n padding: 0 9px;\n border: 0;\n border-radius: 7px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n font: 550 11px/1 var(--ds-font-family);\n cursor: pointer;\n}\n.dsh-ssh-activity-tabs button:hover {\n color: var(--dsw-alias-label-primary);\n}\n.dsh-ssh-activity-tabs button.is-active {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base, #f7f8f7);\n box-shadow: 0 1px 3px\n color-mix(in srgb, var(--dsw-alias-label-primary) 9%, transparent);\n}\n.dsh-ssh-activity-tabs button:only-child {\n grid-column: 1/-1;\n}\n.dsh-ssh-activity-body {\n display: flex;\n min-height: 0;\n flex: 1;\n overflow: hidden;\n padding: 14px 12px 18px;\n}\n.dsh-ssh-activity-body > * {\n width: 100%;\n}\n.dsh-ssh-activity-state {\n margin: 20px 4px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n}\n.dsh-ssh-sftp {\n display: flex;\n min-height: 100%;\n flex-direction: column;\n}\n.dsh-ssh-sftp-hostbar {\n display: grid;\n grid-template-columns: 28px minmax(0, 1fr);\n align-items: center;\n gap: 8px;\n padding: 0 2px 10px;\n}\n.dsh-ssh-sftp-hostbar label {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n.dsh-ssh-sftp-hostbar select {\n min-width: 0;\n padding: 0;\n border: 0;\n outline: 0;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n font: 600 11px/1.25 var(--ds-font-family);\n cursor: pointer;\n}\n.dsh-ssh-sftp-hostbar small {\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font:\n 9px/1.2 var(--ds-font-family-code),\n monospace;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-sftp-pathbar {\n display: grid;\n grid-template-columns: 30px minmax(0, 1fr) 30px;\n gap: 5px;\n margin-bottom: 9px;\n}\n.dsh-ssh-sftp-pathbar.has-upload {\n grid-template-columns: 30px minmax(0, 1fr) 30px auto;\n}\n.dsh-ssh-sftp-pathbar button,\n.dsh-ssh-sftp-pathbar input {\n box-sizing: border-box;\n height: 30px;\n border: 1px solid var(--ssh-activity-border);\n border-radius: 8px;\n color: var(--dsw-alias-label-primary);\n background: var(--ssh-activity-surface-raised);\n}\n.dsh-ssh-sftp-pathbar button {\n display: grid;\n place-items: center;\n padding: 0;\n cursor: pointer;\n}\n.dsh-ssh-sftp-pathbar button:disabled {\n opacity: 0.35;\n cursor: default;\n}\n.dsh-ssh-sftp-pathbar input {\n min-width: 0;\n padding: 0 9px;\n outline: 0;\n font:\n 9px/1 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-sftp-pathbar .dsh-ssh-sftp-upload-button {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 0 10px;\n color: #f6fbf9;\n background: var(--ssh-accent-strong, #406e67);\n font: 550 10px/1 var(--ds-font-family);\n}\n.dsh-ssh-directory-error {\n margin: 0 0 8px;\n padding: 7px 8px;\n border-radius: 7px;\n color: var(--ssh-danger, #9c504c);\n background: color-mix(in srgb, var(--ssh-danger, #9c504c) 7%, transparent);\n font-size: 10px;\n line-height: 1.4;\n}\n.dsh-ssh-sftp-table {\n min-height: 0;\n flex: 1;\n overflow: auto;\n border: 1px solid var(--ssh-activity-border);\n border-radius: 10px;\n background: var(--ssh-activity-surface-raised);\n}\n.dsh-ssh-sftp-columns,\n.dsh-ssh-sftp-row {\n display: grid;\n grid-template-columns: minmax(120px, 1fr) 58px 72px;\n align-items: center;\n gap: 7px;\n}\n.dsh-ssh-sftp-columns {\n position: sticky;\n z-index: 1;\n top: 0;\n min-height: 28px;\n padding: 0 9px;\n border-bottom: 1px solid var(--ssh-activity-border);\n color: var(--dsw-alias-label-tertiary);\n background: var(--ssh-activity-surface);\n font-size: 8px;\n}\n.dsh-ssh-sftp-row {\n box-sizing: border-box;\n width: 100%;\n min-height: 34px;\n padding: 0 9px;\n border: 0;\n border-bottom: 1px solid\n color-mix(in srgb, var(--ssh-activity-border) 55%, transparent);\n color: var(--dsw-alias-label-primary);\n background: transparent;\n text-align: left;\n}\n.dsh-ssh-sftp-row:last-child {\n border-bottom: 0;\n}\n.dsh-ssh-sftp-row.is-directory {\n cursor: pointer;\n}\n.dsh-ssh-sftp-row.is-directory:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-sftp-row:disabled {\n opacity: 1;\n}\n.dsh-ssh-sftp-row > span {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 7px;\n}\n.dsh-ssh-sftp-row svg {\n flex: none;\n color: var(--dsw-alias-label-secondary);\n}\n.dsh-ssh-sftp-row.is-directory svg {\n color: var(--ssh-accent-strong, #406e67);\n}\n.dsh-ssh-sftp-row strong {\n overflow: hidden;\n font-size: 11px;\n font-weight: 500;\n line-height: 1.3;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-sftp-row small {\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font:\n 8px/1.2 var(--ds-font-family-code),\n monospace;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-sftp-state {\n display: grid;\n place-items: center;\n min-height: 160px;\n margin: 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n}\n.dsh-ssh-activity-empty {\n display: grid;\n place-items: center;\n align-content: center;\n min-height: 240px;\n padding: 24px;\n text-align: center;\n}\n.dsh-ssh-activity-empty > svg {\n margin-bottom: 10px;\n color: var(--dsw-alias-label-tertiary);\n}\n.dsh-ssh-activity-empty strong {\n font-size: 12px;\n}\n.dsh-ssh-activity-empty p {\n max-width: 260px;\n margin: 7px 0 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n line-height: 1.5;\n}\n.dsh-ssh-terminal-observer {\n display: flex;\n height: 100%;\n min-height: 280px;\n overflow: hidden;\n flex-direction: column;\n border: 1px solid color-mix(in srgb, #8ba49e 22%, #101817);\n border-radius: 11px;\n background: #111817;\n}\n.dsh-ssh-terminal-observer-heading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 42px;\n padding: 0 10px;\n border-bottom: 1px solid #ffffff12;\n color: #dce5e1;\n background: #0d1413;\n}\n.dsh-ssh-terminal-observer-heading > span:first-child {\n display: grid;\n min-width: 0;\n gap: 3px;\n}\n.dsh-ssh-terminal-observer-heading strong,\n.dsh-ssh-terminal-observer-heading small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-terminal-observer-heading strong {\n font-size: 10px;\n}\n.dsh-ssh-terminal-observer-heading small {\n color: #879691;\n font:\n 8px/1 var(--ds-font-family-code),\n monospace;\n}\n.dsh-ssh-terminal-state {\n flex: none;\n color: #879691;\n font-size: 9px;\n}\n.dsh-ssh-terminal-state.is-running {\n color: #8fc0af;\n}\n.dsh-ssh-terminal-screen {\n box-sizing: border-box;\n min-height: 0;\n flex: 1;\n padding: 9px 8px 0;\n}\n.dsh-ssh-terminal-screen .xterm {\n height: 100%;\n}\n.dsh-ssh-sftp-row:not(.is-directory) {\n cursor: pointer;\n}\n.dsh-ssh-file-preview {\n display: flex;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n overflow: hidden;\n border: 1px solid var(--ssh-activity-border);\n border-radius: 10px;\n background: var(--ssh-activity-surface-raised);\n}\n.dsh-ssh-file-preview > header {\n display: grid;\n grid-template-columns: 28px minmax(0, 1fr) 28px;\n align-items: center;\n gap: 7px;\n min-height: 42px;\n padding: 0 7px;\n border-bottom: 1px solid var(--ssh-activity-border);\n}\n.dsh-ssh-file-preview > header > span {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n.dsh-ssh-file-preview > header strong,\n.dsh-ssh-file-preview > header small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-file-preview > header strong {\n font-size: 10px;\n}\n.dsh-ssh-file-preview > header small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 8px;\n}\n.dsh-ssh-file-preview > header > a {\n display: grid;\n place-items: center;\n width: 28px;\n height: 28px;\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n text-decoration: none;\n}\n.dsh-ssh-file-preview > header > a:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-file-preview-body {\n display: flex;\n min-height: 0;\n flex: 1;\n overflow: auto;\n flex-direction: column;\n}\n.dsh-ssh-file-preview-body > pre {\n box-sizing: border-box;\n min-width: 100%;\n min-height: 100%;\n margin: 0;\n padding: 12px;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n font:\n 10px/1.55 var(--ds-font-family-code),\n monospace;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.dsh-ssh-file-preview-body > small {\n padding: 8px 12px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n}\n.dsh-ssh-file-preview-body > img {\n display: block;\n max-width: 100%;\n max-height: 100%;\n margin: auto;\n object-fit: contain;\n}\n.dsh-ssh-file-preview-body > iframe {\n width: 100%;\n height: 100%;\n min-height: 420px;\n border: 0;\n background: #fff;\n}\n.dsh-ssh-file-binary {\n display: grid;\n place-items: center;\n align-content: center;\n min-height: 240px;\n padding: 20px;\n text-align: center;\n}\n.dsh-ssh-file-binary > svg {\n margin-bottom: 9px;\n color: var(--dsw-alias-label-tertiary);\n}\n.dsh-ssh-file-binary strong {\n font-size: 11px;\n}\n.dsh-ssh-file-binary p {\n margin: 5px 0 12px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n}\n.dsh-ssh-file-binary a {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-height: 30px;\n padding: 0 10px;\n border: 1px solid var(--ssh-activity-border);\n border-radius: 8px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-button-elevated-fill);\n font-size: 10px;\n text-decoration: none;\n}\n.dsh-ssh-terminal-workbench {\n display: flex;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 7px;\n}\n.dsh-ssh-terminal-switcher {\n display: flex;\n flex: none;\n gap: 3px;\n overflow: auto;\n padding: 1px;\n}\n.dsh-ssh-terminal-switcher button {\n display: flex;\n min-width: 0;\n max-width: 150px;\n align-items: center;\n gap: 6px;\n height: 28px;\n padding: 0 8px;\n border: 1px solid transparent;\n border-radius: 7px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n font: 500 9px/1 var(--ds-font-family);\n white-space: nowrap;\n cursor: pointer;\n}\n.dsh-ssh-terminal-switcher button:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-terminal-switcher button.is-active {\n border-color: var(--ssh-activity-border);\n color: var(--dsw-alias-label-primary);\n background: color-mix(in srgb, var(--ssh-accent, #547d78) 8%, transparent);\n}\n.dsh-ssh-terminal-state-dot {\n width: 5px;\n height: 5px;\n flex: none;\n border: 1px solid #75827e;\n border-radius: 50%;\n}\n.dsh-ssh-terminal-state-dot.is-running {\n border-color: #6ca08d;\n background: #6ca08d;\n}\n.dsh-ssh-terminal-workbench .dsh-ssh-terminal-observer {\n height: auto;\n min-height: 0;\n flex: 1;\n}\n.dsh-ssh-terminal-input-error {\n margin: 0;\n padding: 6px 8px;\n border-radius: 6px;\n color: #d98e88;\n background: #351c1a;\n font-size: 9px;\n}\n\n.dsh-ssh-workspace::before {\n position: absolute;\n z-index: 0;\n inset: 0;\n pointer-events: none;\n background:\n radial-gradient(\n circle at 18% 12%,\n color-mix(in srgb, var(--ssh-accent) 7%, transparent),\n transparent 28%\n ),\n linear-gradient(\n 115deg,\n transparent 0 56%,\n color-mix(in srgb, var(--ssh-accent) 3%, transparent) 56.1% 56.35%,\n transparent 56.45% 100%\n );\n content: "";\n}\n.dsh-ssh-workspace > * {\n position: relative;\n z-index: 1;\n}\n.dsh-ssh-toolbar {\n box-shadow:\n inset 0 1px 0\n color-mix(in srgb, var(--dsw-alias-bg-base, #fff) 70%, transparent),\n 0 8px 28px\n color-mix(in srgb, var(--dsw-alias-label-primary) 3%, transparent);\n}\n.dsh-ssh-brand-glyph {\n position: relative;\n overflow: hidden;\n}\n.dsh-ssh-brand-glyph::after {\n position: absolute;\n width: 12px;\n height: 1px;\n left: 9px;\n bottom: 5px;\n border-radius: 1px;\n background: color-mix(in srgb, var(--ssh-accent) 66%, transparent);\n content: "";\n}\n.dsh-ssh-profile-row {\n position: relative;\n transition:\n background 140ms ease,\n border-color 140ms ease,\n transform 160ms cubic-bezier(0.2, 0.8, 0.2, 1);\n}\n.dsh-ssh-profile-row::before {\n position: absolute;\n width: 2px;\n left: 0;\n top: 11px;\n bottom: 11px;\n border-radius: 2px;\n background: var(--ssh-accent);\n opacity: 0;\n transform: scaleY(0.45);\n transition:\n opacity 140ms ease,\n transform 170ms cubic-bezier(0.2, 0.8, 0.2, 1);\n content: "";\n}\n.dsh-ssh-profile-row.is-active {\n transform: translateX(2px);\n}\n.dsh-ssh-profile-row.is-active::before {\n opacity: 0.8;\n transform: scaleY(1);\n}\n.dsh-ssh-profile-row:active,\n.dsh-ssh-sftp-row:active,\n.dsh-ssh-terminal-switcher button:active {\n transform: scale(0.985);\n}\n.dsh-ssh-activity-panel {\n animation: dsh-ssh-panel-enter 180ms cubic-bezier(0.2, 0.8, 0.2, 1) both;\n}\n.dsh-ssh-sftp-table,\n.dsh-ssh-file-preview,\n.dsh-ssh-terminal-observer {\n box-shadow:\n inset 0 1px 0\n color-mix(in srgb, var(--dsw-alias-bg-base, #fff) 8%, transparent),\n 0 10px 30px\n color-mix(in srgb, var(--dsw-alias-label-primary) 4%, transparent);\n}\n.dsh-ssh-sftp-row {\n transition:\n background 120ms ease,\n transform 120ms ease;\n}\n.dsh-ssh-file-preview-body {\n animation: dsh-ssh-content-enter 160ms ease-out both;\n}\n.dsh-ssh-terminal-switcher button {\n transition:\n color 120ms ease,\n background 120ms ease,\n border-color 120ms ease,\n transform 120ms ease;\n}\n.dsh-ssh-terminal-switcher button.is-active {\n box-shadow: inset 0 1px 0\n color-mix(in srgb, var(--dsw-alias-bg-base, #fff) 55%, transparent);\n}\n.dsh-ssh-vault-pane,\n.dsh-ssh-proxy-pane {\n box-sizing: border-box;\n display: flex;\n min-height: 100%;\n flex-direction: column;\n padding: 0 18px 18px;\n}\n.dsh-ssh-vault-list,\n.dsh-ssh-proxy-list {\n display: grid;\n align-content: start;\n gap: 5px;\n}\n.dsh-ssh-vault-row,\n.dsh-ssh-proxy-row {\n display: grid;\n grid-template-columns: 34px minmax(160px, 1fr) auto 70px 28px 28px;\n align-items: center;\n gap: 9px;\n min-height: 56px;\n padding: 5px 8px;\n border: 1px solid var(--ssh-border);\n border-radius: 10px;\n background: color-mix(in srgb, var(--ssh-surface-raised) 82%, transparent);\n transition:\n background 140ms ease,\n border-color 140ms ease,\n transform 150ms ease;\n}\n.dsh-ssh-vault-row:hover,\n.dsh-ssh-proxy-row:hover {\n border-color: color-mix(in srgb, var(--ssh-accent) 18%, var(--ssh-border));\n background: color-mix(in srgb, var(--ssh-surface-raised) 94%, transparent);\n transform: translateY(-1px);\n}\n.dsh-ssh-vault-glyph {\n display: grid;\n place-items: center;\n width: 30px;\n height: 30px;\n border: 1px solid color-mix(in srgb, var(--ssh-accent) 18%, var(--ssh-border));\n border-radius: 9px;\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-accent) 7%, transparent);\n}\n.dsh-ssh-vault-row > span:nth-child(2),\n.dsh-ssh-proxy-row > span:nth-child(2) {\n display: grid;\n min-width: 0;\n gap: 3px;\n}\n.dsh-ssh-vault-row strong,\n.dsh-ssh-vault-row small,\n.dsh-ssh-proxy-row strong,\n.dsh-ssh-proxy-row small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-vault-row strong,\n.dsh-ssh-proxy-row strong {\n font-size: 12px;\n font-weight: 600;\n}\n.dsh-ssh-vault-row small,\n.dsh-ssh-proxy-row small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n}\n.dsh-ssh-proxy-kind {\n padding: 3px 7px;\n border-radius: 6px;\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-accent) 9%, transparent);\n font: 600 9px/1 var(--ds-font-family-code), monospace;\n}\n.dsh-ssh-vault-state {\n padding: 3px 7px;\n border-radius: 6px;\n color: var(--ssh-danger);\n background: color-mix(in srgb, var(--ssh-danger) 7%, transparent);\n font-size: 9px;\n}\n.dsh-ssh-vault-state.is-ready {\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-accent) 9%, transparent);\n}\n.dsh-ssh-vault-empty {\n display: grid;\n place-items: center;\n align-content: center;\n min-height: 320px;\n text-align: center;\n}\n.dsh-ssh-vault-empty > span {\n display: grid;\n place-items: center;\n width: 46px;\n height: 46px;\n margin-bottom: 12px;\n border: 1px solid var(--ssh-border);\n border-radius: 14px;\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-surface-raised) 88%, transparent);\n box-shadow: 0 12px 30px\n color-mix(in srgb, var(--dsw-alias-label-primary) 5%, transparent);\n}\n.dsh-ssh-vault-empty strong {\n font-size: 13px;\n}\n.dsh-ssh-vault-empty p {\n max-width: 360px;\n margin: 7px 0 16px;\n color: var(--dsw-alias-label-secondary);\n font-size: 11px;\n line-height: 1.55;\n}\n.dsh-ssh-credential-reference {\n display: grid;\n grid-template-columns: 34px minmax(0, 1fr) auto;\n align-items: center;\n gap: 9px;\n min-height: 52px;\n padding: 5px 9px;\n border: 1px solid color-mix(in srgb, var(--ssh-accent) 18%, var(--ssh-border));\n border-radius: 10px;\n background: color-mix(\n in srgb,\n var(--ssh-accent) 6%,\n var(--ssh-surface-raised)\n );\n}\n.dsh-ssh-credential-reference > span:first-child {\n display: grid;\n place-items: center;\n width: 30px;\n height: 30px;\n border-radius: 8px;\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-accent) 9%, transparent);\n}\n.dsh-ssh-credential-reference > span:nth-child(2) {\n display: grid;\n gap: 3px;\n}\n.dsh-ssh-credential-reference strong {\n font-size: 11px;\n}\n.dsh-ssh-credential-reference small {\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n}\n.dsh-ssh-credential-reference em {\n color: var(--ssh-accent-strong);\n font-size: 9px;\n font-style: normal;\n}\n.dsh-ssh-jump-chain {\n display: grid;\n gap: 8px;\n margin: 0;\n padding: 10px;\n border: 1px solid var(--ssh-border);\n border-radius: 10px;\n background: color-mix(in srgb, var(--ssh-surface-raised) 72%, transparent);\n}\n.dsh-ssh-jump-chain legend {\n padding: 0 5px;\n color: var(--dsw-alias-label-secondary);\n font-size: 10px;\n font-weight: 600;\n}\n.dsh-ssh-jump-chain > p {\n margin: 0;\n color: var(--dsw-alias-label-tertiary);\n font-size: 9px;\n}\n.dsh-ssh-jump-chain > div {\n display: grid;\n gap: 5px;\n}\n.dsh-ssh-jump-row {\n display: grid;\n grid-template-columns: 22px minmax(0, 1fr) 28px 28px 28px;\n align-items: center;\n gap: 4px;\n}\n.dsh-ssh-jump-row > em {\n display: grid;\n place-items: center;\n width: 20px;\n height: 20px;\n border-radius: 6px;\n color: var(--ssh-accent-strong);\n background: color-mix(in srgb, var(--ssh-accent) 9%, transparent);\n font:\n 600 9px/1 var(--ds-font-family-code),\n monospace;\n font-style: normal;\n}\n.dsh-ssh-jump-row select {\n box-sizing: border-box;\n min-width: 0;\n height: 30px;\n padding: 0 8px;\n border: 1px solid var(--ssh-border);\n border-radius: 8px;\n color: var(--dsw-alias-label-primary);\n background: var(--ssh-surface-raised);\n font-size: 10px;\n}\n.dsh-ssh-jump-row .dsh-ssh-icon-button:disabled {\n opacity: 0.3;\n cursor: default;\n}\n.dsh-ssh-jump-empty {\n padding: 7px !important;\n border-radius: 7px;\n background: color-mix(in srgb, var(--ssh-warning) 7%, transparent);\n}\n.dsh-ssh-jump-chain > .dsh-ssh-secondary-button {\n justify-self: start;\n}\n@keyframes dsh-ssh-panel-enter {\n from {\n opacity: 0;\n transform: translateX(6px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n@keyframes dsh-ssh-content-enter {\n from {\n opacity: 0;\n transform: translateY(3px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n@keyframes dsh-ssh-group-open {\n from {\n opacity: 0;\n transform: translateY(-2px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n@media (max-width: 820px) {\n .dsh-ssh-vault-row,\n .dsh-ssh-proxy-row {\n grid-template-columns: 34px minmax(120px, 1fr) auto 28px;\n }\n .dsh-ssh-vault-row > small,\n .dsh-ssh-vault-row > .dsh-ssh-icon-button:last-child,\n .dsh-ssh-proxy-row > small,\n .dsh-ssh-proxy-row > .dsh-ssh-icon-button:last-child {\n display: none;\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .dsh-ssh-activity-panel,\n .dsh-ssh-file-preview-body,\n .dsh-ssh-profile-group-children {\n animation: none;\n }\n .dsh-ssh-profile-row,\n .dsh-ssh-profile-row::before,\n .dsh-ssh-profile-group-chevron,\n .dsh-ssh-vault-row,\n .dsh-ssh-proxy-row,\n .dsh-ssh-sftp-row,\n .dsh-ssh-terminal-switcher button {\n transition: none;\n }\n}\n.dsh-ssh-sidebar-panel {\n display: flex;\n align-items: center;\n gap: 7px;\n min-height: 34px;\n padding: 0 9px;\n border: 1px solid transparent;\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n font: 550 11px/1 var(--ds-font-family);\n text-align: left;\n cursor: pointer;\n}\n.dsh-ssh-sidebar-panel svg {\n color: #547d78;\n}\n.dsh-ssh-sidebar-panel:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-sidebar-panel:active {\n transform: scale(0.985);\n}\n.dsh-ssh-icon-button.is-active,\n.dsh-ssh-rail-button.is-active {\n color: #406e67;\n background: color-mix(in srgb, #547d78 9%, transparent);\n}\n.dsh-ssh-icon-button:disabled,\n.dsh-ssh-rail-button:disabled {\n opacity: 0.36;\n cursor: default;\n}\n.dsh-ssh-icon-button:disabled:hover,\n.dsh-ssh-rail-button:disabled:hover {\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n}\n.dsh-ssh-test-button {\n margin-right: auto;\n}\n.dsh-ssh-test-result {\n box-sizing: border-box;\n margin: 0;\n border-radius: 9px;\n font-size: 10px;\n}\n.dsh-ssh-test-result.is-warning {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 14px;\n padding: 9px 10px;\n border: 1px solid color-mix(in srgb, var(--ssh-warning) 22%, transparent);\n color: color-mix(\n in srgb,\n var(--ssh-warning) 82%,\n var(--dsw-alias-label-primary)\n );\n background: color-mix(in srgb, var(--ssh-warning) 7%, transparent);\n}\n.dsh-ssh-test-result.is-warning > span {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n.dsh-ssh-test-result.is-warning code {\n overflow: hidden;\n font:\n 9px/1.3 var(--ds-font-family-code),\n monospace;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-test-result.is-success {\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 8px 10px;\n color: #477565;\n background: color-mix(in srgb, #5c8a76 9%, transparent);\n}\n.dsh-ssh-sidebar-note {\n box-sizing: border-box;\n min-height: 32px;\n margin: 0;\n padding: 8px 9px;\n color: var(--dsw-alias-label-tertiary);\n font: 10px/1.4 var(--ds-font-family);\n}\n.dsh-ssh-profile-sftp-pane {\n box-sizing: border-box;\n display: flex;\n min-height: 100%;\n height: 100%;\n flex-direction: column;\n padding: 0 18px 18px;\n}\n.dsh-ssh-profile-sftp-pane > .dsh-ssh-content-heading {\n flex: none;\n}\n.dsh-ssh-sftp.is-workspace {\n --ssh-activity-border: var(--ssh-border);\n min-height: 0;\n flex: 1;\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-pathbar {\n margin-bottom: 10px;\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-columns,\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row {\n grid-template-columns: minmax(180px, 1fr) 90px 120px;\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-columns {\n min-height: 34px;\n padding: 0 12px;\n font-size: 9px;\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row {\n min-height: 40px;\n padding: 0 12px;\n cursor: pointer;\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row strong {\n font-size: 11px;\n}\n.dsh-ssh-sftp.is-workspace .dsh-ssh-sftp-row small {\n font-size: 9px;\n}\n.dsh-ssh-upload-conflict {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 9px;\n padding: 8px 10px;\n border: 1px solid\n color-mix(in srgb, var(--ssh-warning, #927443) 20%, transparent);\n border-radius: 8px;\n color: var(--dsw-alias-label-secondary);\n background: color-mix(in srgb, var(--ssh-warning, #927443) 7%, transparent);\n}\n.dsh-ssh-upload-conflict > span {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dsh-ssh-upload-conflict > span:first-child {\n min-width: 0;\n}\n.dsh-ssh-upload-conflict strong {\n font-size: 10px;\n}\n.dsh-ssh-upload-conflict small {\n overflow: hidden;\n max-width: 240px;\n color: var(--dsw-alias-label-tertiary);\n font:\n 9px/1 var(--ds-font-family-code),\n monospace;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-ssh-upload-conflict button {\n min-height: 26px;\n padding: 0 9px;\n border: 1px solid var(--ssh-border);\n border-radius: 7px;\n color: var(--dsw-alias-label-secondary);\n background: var(--ssh-surface-raised);\n font-size: 9px;\n cursor: pointer;\n}\n.dsh-ssh-upload-conflict button.is-primary {\n border-color: color-mix(in srgb, var(--ssh-accent-strong) 56%, transparent);\n color: #f6fbf9;\n background: var(--ssh-accent-strong);\n}\n';
|
|
6394
6409
|
|
|
6395
6410
|
// src/client-api.ts
|
|
6396
6411
|
var SSH_API = "/ssh-local/v1";
|
|
@@ -6435,6 +6450,9 @@ function loadInjection(sessionId) {
|
|
|
6435
6450
|
function loadActivity(sessionId) {
|
|
6436
6451
|
return api(`/activity?sessionId=${encodeURIComponent(sessionId)}`);
|
|
6437
6452
|
}
|
|
6453
|
+
function activityEventStreamUrl(sessionId) {
|
|
6454
|
+
return `${SSH_API}/activity/events?sessionId=${encodeURIComponent(sessionId)}`;
|
|
6455
|
+
}
|
|
6438
6456
|
function loadSftpDirectory(sessionId, profileId, path) {
|
|
6439
6457
|
const query = new URLSearchParams({ sessionId, profileId });
|
|
6440
6458
|
if (path !== void 0) query.set("path", path);
|
|
@@ -6474,13 +6492,21 @@ async function uploadProfileSftpFile(profileId, directory, file, overwrite = fal
|
|
|
6474
6492
|
if (!response.ok) throw new ApiError(response.status, typeof body.error === "string" ? body.error : `HTTP ${response.status}`, body);
|
|
6475
6493
|
return body;
|
|
6476
6494
|
}
|
|
6477
|
-
function sendActivityTerminalInput(sessionId, terminalId, text) {
|
|
6478
|
-
return api(`/activity/terminals/${encodeURIComponent(terminalId)}/input`, { method: "POST", body: JSON.stringify({ sessionId, text }) });
|
|
6495
|
+
function sendActivityTerminalInput(sessionId, terminalId, text, sequence) {
|
|
6496
|
+
return api(`/activity/terminals/${encodeURIComponent(terminalId)}/input`, { method: "POST", body: JSON.stringify({ sessionId, text, sequence }) });
|
|
6479
6497
|
}
|
|
6480
6498
|
function readActivityTerminalOutput(sessionId, terminalId, cursor) {
|
|
6481
6499
|
const query = new URLSearchParams({ sessionId, cursor: String(cursor) });
|
|
6482
6500
|
return api(`/activity/terminals/${encodeURIComponent(terminalId)}/output?${query.toString()}`);
|
|
6483
6501
|
}
|
|
6502
|
+
function activityTerminalStreamUrl(sessionId, terminalId, cursor = 0) {
|
|
6503
|
+
const query = new URLSearchParams({ sessionId, cursor: String(cursor) });
|
|
6504
|
+
return `${SSH_API}/activity/terminals/${encodeURIComponent(terminalId)}/stream?${query.toString()}`;
|
|
6505
|
+
}
|
|
6506
|
+
function browserTerminalStreamUrl(terminalId, cursor = 0) {
|
|
6507
|
+
const query = new URLSearchParams({ cursor: String(cursor) });
|
|
6508
|
+
return `${SSH_API}/terminals/${encodeURIComponent(terminalId)}/stream?${query.toString()}`;
|
|
6509
|
+
}
|
|
6484
6510
|
function resizeActivityTerminal(sessionId, terminalId, cols, rows) {
|
|
6485
6511
|
return api(`/activity/terminals/${encodeURIComponent(terminalId)}/resize`, { method: "POST", body: JSON.stringify({ sessionId, cols, rows }) });
|
|
6486
6512
|
}
|
|
@@ -6747,6 +6773,125 @@ function errorMessage(error) {
|
|
|
6747
6773
|
return error instanceof Error ? error.message : String(error);
|
|
6748
6774
|
}
|
|
6749
6775
|
|
|
6776
|
+
// src/terminal-transport.ts
|
|
6777
|
+
var TerminalTransport = class {
|
|
6778
|
+
constructor(endpoints) {
|
|
6779
|
+
this.endpoints = endpoints;
|
|
6780
|
+
}
|
|
6781
|
+
input = "";
|
|
6782
|
+
inputSequence = 0;
|
|
6783
|
+
inputScheduled = false;
|
|
6784
|
+
disposed = false;
|
|
6785
|
+
sendInput(text, onError) {
|
|
6786
|
+
if (this.disposed || !text) return;
|
|
6787
|
+
this.input += text;
|
|
6788
|
+
if (this.inputScheduled) return;
|
|
6789
|
+
this.inputScheduled = true;
|
|
6790
|
+
queueMicrotask(() => {
|
|
6791
|
+
this.inputScheduled = false;
|
|
6792
|
+
if (this.disposed) return;
|
|
6793
|
+
const pending = this.input;
|
|
6794
|
+
this.input = "";
|
|
6795
|
+
if (!pending) return;
|
|
6796
|
+
const sequence = this.inputSequence++;
|
|
6797
|
+
this.deliverInput(pending, sequence, onError);
|
|
6798
|
+
});
|
|
6799
|
+
}
|
|
6800
|
+
observe(observer) {
|
|
6801
|
+
let stopped = false;
|
|
6802
|
+
let cursor = 0;
|
|
6803
|
+
let source;
|
|
6804
|
+
let streamWatchdog;
|
|
6805
|
+
let pollTimer;
|
|
6806
|
+
let streamConfirmed = false;
|
|
6807
|
+
const stop = () => {
|
|
6808
|
+
if (stopped) return;
|
|
6809
|
+
stopped = true;
|
|
6810
|
+
source?.close();
|
|
6811
|
+
if (streamWatchdog !== void 0) clearTimeout(streamWatchdog);
|
|
6812
|
+
if (pollTimer !== void 0) clearTimeout(pollTimer);
|
|
6813
|
+
};
|
|
6814
|
+
const accept = (value) => {
|
|
6815
|
+
if (stopped) return;
|
|
6816
|
+
cursor = value.cursor;
|
|
6817
|
+
observer.output(value);
|
|
6818
|
+
if (value.closed) stop();
|
|
6819
|
+
};
|
|
6820
|
+
const poll = async () => {
|
|
6821
|
+
if (stopped) return;
|
|
6822
|
+
try {
|
|
6823
|
+
const value = await this.endpoints.read(cursor);
|
|
6824
|
+
accept(value);
|
|
6825
|
+
if (!stopped) pollTimer = window.setTimeout(() => {
|
|
6826
|
+
void poll();
|
|
6827
|
+
}, document.hidden ? 500 : value.data ? 16 : 64);
|
|
6828
|
+
} catch (reason) {
|
|
6829
|
+
if (stopped) return;
|
|
6830
|
+
observer.error(reason);
|
|
6831
|
+
pollTimer = window.setTimeout(() => {
|
|
6832
|
+
void poll();
|
|
6833
|
+
}, 500);
|
|
6834
|
+
}
|
|
6835
|
+
};
|
|
6836
|
+
const startPolling = () => {
|
|
6837
|
+
if (stopped || pollTimer !== void 0) return;
|
|
6838
|
+
source?.close();
|
|
6839
|
+
source = void 0;
|
|
6840
|
+
void poll();
|
|
6841
|
+
};
|
|
6842
|
+
if (typeof EventSource === "undefined") {
|
|
6843
|
+
startPolling();
|
|
6844
|
+
return stop;
|
|
6845
|
+
}
|
|
6846
|
+
source = new EventSource(this.endpoints.streamUrl);
|
|
6847
|
+
source.onmessage = (event) => {
|
|
6848
|
+
try {
|
|
6849
|
+
const value = parseOutput(event.data);
|
|
6850
|
+
streamConfirmed = true;
|
|
6851
|
+
if (streamWatchdog !== void 0) {
|
|
6852
|
+
clearTimeout(streamWatchdog);
|
|
6853
|
+
streamWatchdog = void 0;
|
|
6854
|
+
}
|
|
6855
|
+
accept(value);
|
|
6856
|
+
} catch (reason) {
|
|
6857
|
+
observer.error(reason);
|
|
6858
|
+
startPolling();
|
|
6859
|
+
}
|
|
6860
|
+
};
|
|
6861
|
+
source.onerror = () => {
|
|
6862
|
+
if (!streamConfirmed && source?.readyState === EventSource.CLOSED) startPolling();
|
|
6863
|
+
};
|
|
6864
|
+
streamWatchdog = window.setTimeout(() => {
|
|
6865
|
+
if (!streamConfirmed) startPolling();
|
|
6866
|
+
}, 1500);
|
|
6867
|
+
return stop;
|
|
6868
|
+
}
|
|
6869
|
+
dispose() {
|
|
6870
|
+
this.disposed = true;
|
|
6871
|
+
this.input = "";
|
|
6872
|
+
}
|
|
6873
|
+
deliverInput(text, sequence, onError, attempt = 0) {
|
|
6874
|
+
void this.endpoints.send(text, sequence).catch((reason) => {
|
|
6875
|
+
if (this.disposed) return;
|
|
6876
|
+
if (attempt < 2 && isRetryable(reason)) {
|
|
6877
|
+
window.setTimeout(() => this.deliverInput(text, sequence, onError, attempt + 1), 60 * (attempt + 1));
|
|
6878
|
+
return;
|
|
6879
|
+
}
|
|
6880
|
+
onError(reason);
|
|
6881
|
+
});
|
|
6882
|
+
}
|
|
6883
|
+
};
|
|
6884
|
+
function parseOutput(value) {
|
|
6885
|
+
const parsed = JSON.parse(value);
|
|
6886
|
+
if (typeof parsed.data !== "string" || typeof parsed.cursor !== "number" || !Number.isSafeInteger(parsed.cursor) || parsed.cursor < 0 || typeof parsed.truncated !== "boolean" || typeof parsed.closed !== "boolean") throw new Error("SSH terminal stream returned an invalid event");
|
|
6887
|
+
return parsed;
|
|
6888
|
+
}
|
|
6889
|
+
function isRetryable(reason) {
|
|
6890
|
+
if (typeof reason !== "object" || reason === null || !("status" in reason)) return true;
|
|
6891
|
+
const status = Number(reason.status);
|
|
6892
|
+
return !Number.isFinite(status) || status >= 500;
|
|
6893
|
+
}
|
|
6894
|
+
|
|
6750
6895
|
// src/client.tsx
|
|
6751
6896
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
6752
6897
|
var PLUGIN_ID = "@lemoncat7/dsh-ssh";
|
|
@@ -6756,6 +6901,10 @@ function apply(ctx) {
|
|
|
6756
6901
|
ctx.effect(installStyles, "dsh-ssh: styles");
|
|
6757
6902
|
const activityController = createActivityController(ctx);
|
|
6758
6903
|
const controller = createController(ctx, () => activityController.close());
|
|
6904
|
+
ctx.effect(() => observePluginWorkspace(PLUGIN_ID, () => {
|
|
6905
|
+
controller.close();
|
|
6906
|
+
activityController.close();
|
|
6907
|
+
}), "dsh-ssh: exclusive workspace");
|
|
6759
6908
|
ctx.effect(() => () => {
|
|
6760
6909
|
controller.close();
|
|
6761
6910
|
activityController.close();
|
|
@@ -6786,6 +6935,7 @@ function createController(ctx, beforeOpen) {
|
|
|
6786
6935
|
beforeOpen();
|
|
6787
6936
|
if (profileId !== void 0) selected = profileId;
|
|
6788
6937
|
if (dispose === void 0) {
|
|
6938
|
+
activatePluginWorkspace(PLUGIN_ID);
|
|
6789
6939
|
dispose = ctx.slots.register({ name: "conversation", priority: -2 }, (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RemoteWorkspace, { ...props, controller }));
|
|
6790
6940
|
}
|
|
6791
6941
|
notify();
|
|
@@ -6814,21 +6964,25 @@ function createActivityController(ctx) {
|
|
|
6814
6964
|
const listeners = /* @__PURE__ */ new Set();
|
|
6815
6965
|
let openSessionId;
|
|
6816
6966
|
let selectedProfileId;
|
|
6967
|
+
let requestedView;
|
|
6817
6968
|
let dispose;
|
|
6818
6969
|
const notify = () => {
|
|
6819
6970
|
for (const listener of listeners) listener();
|
|
6820
6971
|
};
|
|
6821
6972
|
const controller = {
|
|
6822
|
-
open(sessionId, profileId) {
|
|
6973
|
+
open(sessionId, profileId, view) {
|
|
6823
6974
|
if (dispose !== void 0 && openSessionId === sessionId) {
|
|
6824
6975
|
if (profileId !== void 0) selectedProfileId = profileId;
|
|
6976
|
+
if (view !== void 0) requestedView = view;
|
|
6825
6977
|
ctx.layout.openDetails();
|
|
6826
6978
|
notify();
|
|
6827
6979
|
return;
|
|
6828
6980
|
}
|
|
6829
6981
|
controller.close();
|
|
6982
|
+
activatePluginWorkspace(PLUGIN_ID);
|
|
6830
6983
|
openSessionId = sessionId;
|
|
6831
6984
|
selectedProfileId = profileId;
|
|
6985
|
+
requestedView = view;
|
|
6832
6986
|
dispose = ctx.slots.register({ name: "details", priority: -2 }, (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SshActivityPanel, { ...props, controller }));
|
|
6833
6987
|
ctx.layout.openDetails();
|
|
6834
6988
|
notify();
|
|
@@ -6843,12 +6997,14 @@ function createActivityController(ctx) {
|
|
|
6843
6997
|
dispose = void 0;
|
|
6844
6998
|
openSessionId = void 0;
|
|
6845
6999
|
selectedProfileId = void 0;
|
|
7000
|
+
requestedView = void 0;
|
|
6846
7001
|
current?.();
|
|
6847
7002
|
if (current !== void 0) ctx.layout.closeDetails();
|
|
6848
7003
|
notify();
|
|
6849
7004
|
},
|
|
6850
7005
|
isOpen: (sessionId) => dispose !== void 0 && openSessionId === sessionId,
|
|
6851
7006
|
selected: (sessionId) => openSessionId === sessionId ? selectedProfileId : void 0,
|
|
7007
|
+
requestedView: (sessionId) => openSessionId === sessionId ? requestedView : void 0,
|
|
6852
7008
|
subscribe(listener) {
|
|
6853
7009
|
listeners.add(listener);
|
|
6854
7010
|
return () => listeners.delete(listener);
|
|
@@ -6859,10 +7015,14 @@ function createActivityController(ctx) {
|
|
|
6859
7015
|
function SshActivityPanel(props) {
|
|
6860
7016
|
const sessionId = String(props.sessionId);
|
|
6861
7017
|
const [activity, setActivity] = (0, import_react4.useState)();
|
|
6862
|
-
const [view, setView] = (0, import_react4.useState)("directory");
|
|
7018
|
+
const [view, setView] = (0, import_react4.useState)(() => props.controller.requestedView(sessionId) ?? "directory");
|
|
6863
7019
|
const [error, setError] = (0, import_react4.useState)();
|
|
6864
7020
|
const [, setRevision] = (0, import_react4.useState)(0);
|
|
6865
|
-
(0, import_react4.useEffect)(() => props.controller.subscribe(() =>
|
|
7021
|
+
(0, import_react4.useEffect)(() => props.controller.subscribe(() => {
|
|
7022
|
+
const requested = props.controller.requestedView(sessionId);
|
|
7023
|
+
if (requested !== void 0) setView(requested);
|
|
7024
|
+
setRevision((value) => value + 1);
|
|
7025
|
+
}), [props.controller, sessionId]);
|
|
6866
7026
|
const refresh = (0, import_react4.useCallback)(async () => {
|
|
6867
7027
|
try {
|
|
6868
7028
|
const next = await loadActivity(sessionId);
|
|
@@ -6880,7 +7040,7 @@ function SshActivityPanel(props) {
|
|
|
6880
7040
|
}, view === "terminals" ? 1800 : 2500);
|
|
6881
7041
|
return () => clearInterval(timer);
|
|
6882
7042
|
}, [refresh, view]);
|
|
6883
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "dsh-ssh-activity-panel", "aria-label": "SSH \u6D3B\u52A8", children: [
|
|
7043
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "dsh-ssh-activity-panel", "data-xiaohei-surface": "plugin-workspace", "aria-label": "SSH \u6D3B\u52A8", children: [
|
|
6884
7044
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "dsh-ssh-activity-header", children: [
|
|
6885
7045
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
|
|
6886
7046
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: "SSH \u6D3B\u52A8" }),
|
|
@@ -6955,7 +7115,6 @@ function TerminalActivity({ sessionId, terminals }) {
|
|
|
6955
7115
|
function InteractiveTerminal({ sessionId, terminal: activity, onError }) {
|
|
6956
7116
|
const hostRef = (0, import_react4.useRef)(null);
|
|
6957
7117
|
const terminalRef = (0, import_react4.useRef)();
|
|
6958
|
-
const inputQueueRef = (0, import_react4.useRef)(Promise.resolve());
|
|
6959
7118
|
(0, import_react4.useEffect)(() => {
|
|
6960
7119
|
const host = hostRef.current;
|
|
6961
7120
|
if (host === null) return;
|
|
@@ -6976,20 +7135,22 @@ function InteractiveTerminal({ sessionId, terminal: activity, onError }) {
|
|
|
6976
7135
|
fit.fit();
|
|
6977
7136
|
terminalRef.current = terminal;
|
|
6978
7137
|
terminal.focus();
|
|
6979
|
-
|
|
6980
|
-
|
|
7138
|
+
const transport = new TerminalTransport({
|
|
7139
|
+
streamUrl: activityTerminalStreamUrl(sessionId, activity.terminalId),
|
|
7140
|
+
read: (cursor) => readActivityTerminalOutput(sessionId, activity.terminalId, cursor),
|
|
7141
|
+
send: (text, sequence) => sendActivityTerminalInput(sessionId, activity.terminalId, text, sequence)
|
|
7142
|
+
});
|
|
6981
7143
|
let resizeTimer;
|
|
6982
7144
|
let lastSize = "";
|
|
6983
|
-
const
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
if (inputTimer === void 0) inputTimer = window.setTimeout(flushInput, 12);
|
|
7145
|
+
const input = terminal.onData((data) => transport.sendInput(data, (reason) => onError(message(reason))));
|
|
7146
|
+
const stopOutput = transport.observe({
|
|
7147
|
+
output: (value) => {
|
|
7148
|
+
if (value.truncated) terminal.reset();
|
|
7149
|
+
if (value.data) terminal.write(value.data);
|
|
7150
|
+
terminal.scrollToBottom();
|
|
7151
|
+
onError(void 0);
|
|
7152
|
+
},
|
|
7153
|
+
error: (reason) => onError(message(reason))
|
|
6993
7154
|
});
|
|
6994
7155
|
const syncSize = () => {
|
|
6995
7156
|
fit.fit();
|
|
@@ -7004,11 +7165,9 @@ function InteractiveTerminal({ sessionId, terminal: activity, onError }) {
|
|
|
7004
7165
|
});
|
|
7005
7166
|
resize.observe(host);
|
|
7006
7167
|
return () => {
|
|
7007
|
-
if (inputTimer !== void 0) {
|
|
7008
|
-
clearTimeout(inputTimer);
|
|
7009
|
-
flushInput();
|
|
7010
|
-
}
|
|
7011
7168
|
if (resizeTimer !== void 0) clearTimeout(resizeTimer);
|
|
7169
|
+
stopOutput();
|
|
7170
|
+
transport.dispose();
|
|
7012
7171
|
input.dispose();
|
|
7013
7172
|
resize.disconnect();
|
|
7014
7173
|
terminal.dispose();
|
|
@@ -7019,39 +7178,6 @@ function InteractiveTerminal({ sessionId, terminal: activity, onError }) {
|
|
|
7019
7178
|
const terminal = terminalRef.current;
|
|
7020
7179
|
if (terminal !== void 0) terminal.options.disableStdin = activity.status.kind !== "running";
|
|
7021
7180
|
}, [activity.status.kind]);
|
|
7022
|
-
(0, import_react4.useEffect)(() => {
|
|
7023
|
-
let disposed = false;
|
|
7024
|
-
let timer;
|
|
7025
|
-
let cursor = 0;
|
|
7026
|
-
const poll = async () => {
|
|
7027
|
-
try {
|
|
7028
|
-
const output = await readActivityTerminalOutput(sessionId, activity.terminalId, cursor);
|
|
7029
|
-
if (disposed) return;
|
|
7030
|
-
const terminal = terminalRef.current;
|
|
7031
|
-
if (terminal !== void 0) {
|
|
7032
|
-
if (output.truncated) terminal.reset();
|
|
7033
|
-
if (output.data) terminal.write(output.data);
|
|
7034
|
-
terminal.scrollToBottom();
|
|
7035
|
-
}
|
|
7036
|
-
cursor = output.cursor;
|
|
7037
|
-
onError(void 0);
|
|
7038
|
-
if (!output.closed) timer = window.setTimeout(() => {
|
|
7039
|
-
void poll();
|
|
7040
|
-
}, document.hidden ? 600 : 80);
|
|
7041
|
-
} catch (reason) {
|
|
7042
|
-
if (disposed) return;
|
|
7043
|
-
onError(message(reason));
|
|
7044
|
-
timer = window.setTimeout(() => {
|
|
7045
|
-
void poll();
|
|
7046
|
-
}, 600);
|
|
7047
|
-
}
|
|
7048
|
-
};
|
|
7049
|
-
void poll();
|
|
7050
|
-
return () => {
|
|
7051
|
-
disposed = true;
|
|
7052
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
7053
|
-
};
|
|
7054
|
-
}, [activity.terminalId, onError, sessionId]);
|
|
7055
7181
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: hostRef, className: "dsh-ssh-terminal-screen", "aria-label": "\u4EA4\u4E92\u5F0F SSH \u7EC8\u7AEF" });
|
|
7056
7182
|
}
|
|
7057
7183
|
function RemoteSidebar(props) {
|
|
@@ -7074,10 +7200,25 @@ function RemoteSidebar(props) {
|
|
|
7074
7200
|
const currentSessionId = sessionId === void 0 ? void 0 : String(sessionId);
|
|
7075
7201
|
const activityOpen = currentSessionId !== void 0 && props.activityController.isOpen(currentSessionId);
|
|
7076
7202
|
const availableProfiles = injection === null ? [] : injection.profileIds.map((profileId) => profiles.find((profile) => profile.id === profileId)).filter((profile) => profile !== void 0);
|
|
7203
|
+
(0, import_react4.useEffect)(() => {
|
|
7204
|
+
if (currentSessionId === void 0 || injection?.permission !== "terminal") return;
|
|
7205
|
+
const source = new EventSource(activityEventStreamUrl(currentSessionId));
|
|
7206
|
+
const opened = (raw) => {
|
|
7207
|
+
const event = parseTerminalOpenedEvent(raw);
|
|
7208
|
+
if (event === void 0 || event.sessionId !== currentSessionId) return;
|
|
7209
|
+
props.controller.close();
|
|
7210
|
+
props.activityController.open(currentSessionId, event.profileId, "terminals");
|
|
7211
|
+
};
|
|
7212
|
+
source.addEventListener("terminal-opened", opened);
|
|
7213
|
+
return () => {
|
|
7214
|
+
source.removeEventListener("terminal-opened", opened);
|
|
7215
|
+
source.close();
|
|
7216
|
+
};
|
|
7217
|
+
}, [currentSessionId, injection?.permission, props.activityController, props.controller]);
|
|
7077
7218
|
const openActivity = (profileId) => {
|
|
7078
7219
|
if (currentSessionId === void 0) return;
|
|
7079
7220
|
props.controller.close();
|
|
7080
|
-
props.activityController.open(currentSessionId, profileId);
|
|
7221
|
+
props.activityController.open(currentSessionId, profileId, "directory");
|
|
7081
7222
|
};
|
|
7082
7223
|
const toggleActivity = () => {
|
|
7083
7224
|
if (currentSessionId === void 0) return;
|
|
@@ -7160,7 +7301,7 @@ function RemoteWorkspace(props) {
|
|
|
7160
7301
|
const selected = profiles.find((item) => item.id === selectedId);
|
|
7161
7302
|
const toolbar = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "dsh-ssh-toolbar", children: [
|
|
7162
7303
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-ssh-brand", children: [
|
|
7163
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "dsh-ssh-icon-button", "aria-label": "\u8FD4\u56DE\u4F1A\u8BDD", title: "\u8FD4\u56DE\u4F1A\u8BDD", onClick: () => props.controller.close(), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_dsh_client_ui_primitives2.IconChevronLeftOutline14, { size: 15 }) }),
|
|
7304
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "dsh-ssh-icon-button", "data-xiaohei-workspace-close": true, "aria-label": "\u8FD4\u56DE\u4F1A\u8BDD", title: "\u8FD4\u56DE\u4F1A\u8BDD", onClick: () => props.controller.close(), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_dsh_client_ui_primitives2.IconChevronLeftOutline14, { size: 15 }) }),
|
|
7164
7305
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-ssh-brand-glyph", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ServerGlyph, {}) }),
|
|
7165
7306
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
|
|
7166
7307
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: "\u8FDC\u7AEF" }),
|
|
@@ -7189,6 +7330,7 @@ function RemoteWorkspace(props) {
|
|
|
7189
7330
|
AdaptiveWorkspace,
|
|
7190
7331
|
{
|
|
7191
7332
|
className: "dsh-ssh-workspace",
|
|
7333
|
+
"data-xiaohei-surface": "plugin-workspace",
|
|
7192
7334
|
toolbar,
|
|
7193
7335
|
notice,
|
|
7194
7336
|
navigationLabel: "\u4E3B\u673A",
|
|
@@ -7338,36 +7480,29 @@ function TerminalPane({ profile, onEdit }) {
|
|
|
7338
7480
|
if (terminalId === void 0) return;
|
|
7339
7481
|
const terminal = terminalRef.current;
|
|
7340
7482
|
if (terminal === void 0) return;
|
|
7341
|
-
const
|
|
7342
|
-
|
|
7483
|
+
const transport = new TerminalTransport({
|
|
7484
|
+
streamUrl: browserTerminalStreamUrl(terminalId),
|
|
7485
|
+
read: (cursor) => api(`/terminals/${terminalId}/output?cursor=${cursor}`),
|
|
7486
|
+
send: (text, sequence) => api(`/terminals/${terminalId}/input`, { method: "POST", body: JSON.stringify({ text, sequence }) })
|
|
7343
7487
|
});
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
if (output.truncated) terminal.write("\r\n\x1B[33m[\u8F83\u65E9\u8F93\u51FA\u5DF2\u622A\u65AD]\x1B[0m\r\n");
|
|
7351
|
-
if (output.data) terminal.write(output.data);
|
|
7352
|
-
cursor = output.cursor;
|
|
7353
|
-
if (output.closed) {
|
|
7488
|
+
const input = terminal.onData((data) => transport.sendInput(data, (reason) => setError(message(reason))));
|
|
7489
|
+
const stopOutput = transport.observe({
|
|
7490
|
+
output: (value) => {
|
|
7491
|
+
if (value.truncated) terminal.write("\r\n\x1B[33m[\u8F83\u65E9\u8F93\u51FA\u5DF2\u622A\u65AD]\x1B[0m\r\n");
|
|
7492
|
+
if (value.data) terminal.write(value.data);
|
|
7493
|
+
if (value.closed) {
|
|
7354
7494
|
setPhase("idle");
|
|
7355
7495
|
setTerminalId(void 0);
|
|
7356
|
-
return;
|
|
7357
|
-
}
|
|
7358
|
-
} catch (reason) {
|
|
7359
|
-
if (!stopped) {
|
|
7360
|
-
setError(message(reason));
|
|
7361
|
-
setPhase("error");
|
|
7362
7496
|
}
|
|
7497
|
+
},
|
|
7498
|
+
error: (reason) => {
|
|
7499
|
+
setError(message(reason));
|
|
7500
|
+
setPhase("error");
|
|
7363
7501
|
}
|
|
7364
|
-
|
|
7365
|
-
void poll();
|
|
7366
|
-
}, document.hidden ? 800 : 180);
|
|
7367
|
-
};
|
|
7368
|
-
void poll();
|
|
7502
|
+
});
|
|
7369
7503
|
return () => {
|
|
7370
|
-
|
|
7504
|
+
stopOutput();
|
|
7505
|
+
transport.dispose();
|
|
7371
7506
|
input.dispose();
|
|
7372
7507
|
};
|
|
7373
7508
|
}, [terminalId]);
|
|
@@ -8202,6 +8337,16 @@ function shortId(id) {
|
|
|
8202
8337
|
function message(error) {
|
|
8203
8338
|
return error instanceof Error ? error.message : String(error);
|
|
8204
8339
|
}
|
|
8340
|
+
function parseTerminalOpenedEvent(raw) {
|
|
8341
|
+
if (!(raw instanceof MessageEvent) || typeof raw.data !== "string") return void 0;
|
|
8342
|
+
try {
|
|
8343
|
+
const value = JSON.parse(raw.data);
|
|
8344
|
+
if (value.type !== "terminal-opened" || typeof value.sessionId !== "string" || typeof value.terminalId !== "string" || typeof value.profileId !== "string" || typeof value.createdAt !== "number") return void 0;
|
|
8345
|
+
return value;
|
|
8346
|
+
} catch {
|
|
8347
|
+
return void 0;
|
|
8348
|
+
}
|
|
8349
|
+
}
|
|
8205
8350
|
function forwardSummary(rule, status) {
|
|
8206
8351
|
const bind = `${rule.bindHost}:${status?.bindPort ?? rule.bindPort}`;
|
|
8207
8352
|
return rule.kind === "dynamic" ? `${bind} \u2192 SOCKS5` : `${bind} \u2192 ${rule.targetHost}:${rule.targetPort}`;
|