diff --git a/src/routes/containers/+page.svelte b/src/routes/containers/+page.svelte index f890a26..a0663b9 100644 --- a/src/routes/containers/+page.svelte +++ b/src/routes/containers/+page.svelte @@ -134,6 +134,9 @@ // Derived: current environment details for reactive port URL generation const currentEnvDetails = $derived($environments.find(e => e.id === $currentEnvironment?.id) ?? null); + // hawser-edge exposes an exec-only terminal protocol (the agent has no attach path), + // so don't offer Attach there - the server would reject it anyway. + const attachSupported = $derived(currentEnvDetails?.connectionType !== 'hawser-edge'); // Search and sort state - initialize from URL for persistence across navigation const initialSearch = $page.url.searchParams.get('search') @@ -1124,23 +1127,22 @@ const savedUser = getSavedUser(container.id); terminalUser = savedUser ?? 'root'; terminalCustomUsers = getCustomUsers(); - // Default a fresh session to exec so a prior container's Attach choice - // (terminalMode is shared) doesn't carry over to this one. - terminalMode = 'exec'; // Show popover to configure new terminal terminalPopoverStates[container.id] = true; } } function startTerminal(container: ContainerInfo) { - if (terminalMode === 'exec') saveUserForContainer(container.id, terminalUser); + // Edge is exec-only; never start an attach session there even if a stale mode lingers. + const mode: TerminalMode = attachSupported ? terminalMode : 'exec'; + if (mode === 'exec') saveUserForContainer(container.id, terminalUser); terminalCustomUsers = getCustomUsers(); const terminal: ActiveTerminal = { containerId: container.id, containerName: container.name, shell: terminalShell, user: terminalUser, - mode: terminalMode + mode }; activeTerminals = [...activeTerminals, terminal]; currentTerminalContainerId = container.id; @@ -2167,7 +2169,15 @@ {:else} { terminalPopoverStates[container.id] = open; - if (open && terminalMode === 'exec') detectContainerShells(container.id); + if (open) { + // Default each freshly-opened session to exec so a prior container's + // Attach choice (terminalMode is shared) doesn't carry over, and the + // picker/shell controls always render. Restore this container's saved user. + terminalMode = 'exec'; + terminalUser = getSavedUser(container.id) ?? 'root'; + terminalCustomUsers = getCustomUsers(); + detectContainerShells(container.id); + } }}> e.stopPropagation()} @@ -2195,6 +2205,8 @@ {:else}
+ + {#if attachSupported}
{ @@ -2222,6 +2234,7 @@
+ {/if} {#if terminalMode === 'exec'}
diff --git a/src/routes/terminal/+page.svelte b/src/routes/terminal/+page.svelte index 32e9e46..6c8b27f 100644 --- a/src/routes/terminal/+page.svelte +++ b/src/routes/terminal/+page.svelte @@ -33,6 +33,11 @@ let shellDetection = $state(null); let detectingShells = $state(false); + // hawser-edge exposes an exec-only terminal protocol, so attach isn't offered there. + const attachSupported = $derived( + ($environments.find(e => e.id === $currentEnvironment?.id)?.connectionType ?? 'socket') !== 'hawser-edge' + ); + // Shell/user options let terminalMode = $state('exec'); let selectedShell = $state('/bin/bash'); @@ -216,7 +221,7 @@ onMount(async () => { customUsers = getCustomUsers(); - if ($page.url.searchParams.get('mode') === 'attach') { + if ($page.url.searchParams.get('mode') === 'attach' && attachSupported) { terminalMode = 'attach'; } await fetchContainers(); @@ -311,6 +316,8 @@
{/if}
+ + {#if attachSupported}
terminalMode = value as TerminalMode}> @@ -335,6 +342,7 @@
+ {/if} {#if selectedContainer}