diff --git a/apps/web/app/gen2/workspace.css b/apps/web/app/gen2/workspace.css index 6446d30f4..99796610b 100644 --- a/apps/web/app/gen2/workspace.css +++ b/apps/web/app/gen2/workspace.css @@ -1098,7 +1098,10 @@ --ss-muted: #2a2827; --ss-muted-foreground: #a8a5a3; --ss-border: #2a2827; - min-height: 100dvh; + display: flex; + flex-direction: column; + height: 100dvh; + min-height: 0; background: var(--ss-background); color: var(--ss-foreground); font-family: var(--font-geist-sans), Arial, sans-serif; @@ -1203,12 +1206,20 @@ font-size: 0.8125rem; } +.gen2-superset-workspace-content { + flex: 1; + min-height: 0; +} + .gen2-superset-files-panel .gen2-superset-file-pane { - min-height: calc(100dvh - 48px); + height: 100%; + min-height: 0; } .gen2-superset-tool-panel { - min-height: calc(100dvh - 48px); + box-sizing: border-box; + height: 100%; + min-height: 0; padding: 16px; background: var(--ss-background); } diff --git a/apps/web/components/gen2/superset-workspace-shell.tsx b/apps/web/components/gen2/superset-workspace-shell.tsx index 6719e50b1..4babb285d 100644 --- a/apps/web/components/gen2/superset-workspace-shell.tsx +++ b/apps/web/components/gen2/superset-workspace-shell.tsx @@ -341,42 +341,44 @@ export function SupersetWorkspaceShell({ {notice}

) : null} - - - ); } diff --git a/apps/web/components/gen2/terminal-pane.tsx b/apps/web/components/gen2/terminal-pane.tsx index 830494e13..19479b5b0 100644 --- a/apps/web/components/gen2/terminal-pane.tsx +++ b/apps/web/components/gen2/terminal-pane.tsx @@ -32,6 +32,7 @@ export function Gen2TerminalPane({ const fitRef = useRef(null); const sessionRef = useRef(null); const afterRef = useRef(0); + const dimensionsRef = useRef(""); const [status, setStatus] = useState<"idle" | "starting" | "live" | "ended">( "idle", ); @@ -80,6 +81,7 @@ export function Gen2TerminalPane({ term.loadAddon(fit); term.open(host); if (host.clientWidth > 0 && host.clientHeight > 0) fit.fit(); + dimensionsRef.current = `${term.rows}:${term.cols}`; termRef.current = term; fitRef.current = fit; @@ -170,6 +172,12 @@ export function Gen2TerminalPane({ onExit(); return; } + // The legacy guest endpoint parks this request, while the Superset + // bridge returns an immediate snapshot. Yield between idle snapshots + // so an open shell cannot turn into a tight browser request loop. + if (result.chunks.length === 0) { + await new Promise((resolve) => setTimeout(resolve, 150)); + } } catch { if (cancelled) return; networkFailures += 1; @@ -203,6 +211,9 @@ export function Gen2TerminalPane({ // A hidden pane measures zero; fitting against that throws. if (host.clientWidth === 0 || host.clientHeight === 0) return; fitRef.current?.fit(); + const dimensions = `${term.rows}:${term.cols}`; + if (dimensions === dimensionsRef.current) return; + dimensionsRef.current = dimensions; void post({ action: "resize", sessionId, diff --git a/infra/runtime/scripts/bootstrap-host.sh b/infra/runtime/scripts/bootstrap-host.sh index 33bc96128..c78e194d2 100755 --- a/infra/runtime/scripts/bootstrap-host.sh +++ b/infra/runtime/scripts/bootstrap-host.sh @@ -732,6 +732,16 @@ if ! grep -q '^codev-shell:' "${work_dir}/rootfs/etc/shadow"; then echo 'codev-shell:!:20000::::::' >>"${work_dir}/rootfs/etc/shadow" fi +# Interactive terminals intentionally run as codev-shell while the checkout is +# assembled by root. Trust only this workspace and its managed worktrees at the +# protected system-config scope; a shell user must not have to weaken Git's +# ownership protection with a global wildcard before `git status` can work. +cat >>"${work_dir}/rootfs/etc/gitconfig" <<'GITCONFIG' +[safe] + directory = /workspace + directory = /workspace/* +GITCONFIG + cat >"${work_dir}/rootfs/etc/systemd/system/workspace.mount" <<'UNIT' [Unit] Description=CoDev workspace disk diff --git a/infra/runtime/scripts/provision-host-image.sh b/infra/runtime/scripts/provision-host-image.sh index 898222891..f055a8864 100755 --- a/infra/runtime/scripts/provision-host-image.sh +++ b/infra/runtime/scripts/provision-host-image.sh @@ -246,6 +246,15 @@ cp -a "/usr/lib/${guest_lib_dir}/." \ install -d -m 0755 "${work_dir}/rootfs/workspace" install -d -m 0755 "${work_dir}/rootfs/etc/systemd/system/multi-user.target.wants" +# The interactive shell is unprivileged while CoDev assembles the checkout as +# root. Trust this checkout and its managed worktrees without making every +# path trusted for a terminal user. +cat >>"${work_dir}/rootfs/etc/gitconfig" <<'GITCONFIG' +[safe] + directory = /workspace + directory = /workspace/* +GITCONFIG + cat >"${work_dir}/rootfs/etc/systemd/system/workspace.mount" <<'UNIT' [Unit] Description=CoDev workspace disk