Updates to terminals
This commit is contained in:
@@ -54,7 +54,7 @@ Copy `[.env.example](.env.example)` to `.env`. BareCloud reads `**BARECLOUD_*`**
|
||||
| `BARECLOUD_BARE_OS_NO_SPLASH` | Set `1` to hide bare-os boot splash in Pear. |
|
||||
| `BARE_OS_BOOT_TIMEOUT_MS` | Optional; forwarded from host env into Pear (bare-os boot wait). |
|
||||
| `BARECLOUD_TERMINAL_WS_PING_MS` | Browser WebSocket ping interval ms (`0` / empty rules → see `lib/terminal-proxy.ts`). |
|
||||
| `BARECLOUD_BOOTER_TERM`, `BARECLOUD_TMUX_HISTORY_LIMIT`, `NEXT_PUBLIC_TERMINAL_SCROLLBACK` | Default `TERM` for Pear PTY / tmux session, tmux pane history, and browser xterm scrollback. Scrollback defaults to 1,000,000 lines. |
|
||||
| `BARECLOUD_BOOTER_TERM`, `BARECLOUD_TMUX_HISTORY_LIMIT`, `NEXT_PUBLIC_TERMINAL_SCROLLBACK` | Default `TERM` for Pear PTY / tmux session (`xterm-256color`), tmux pane history (default 50,000; capped at 200,000), and browser xterm scrollback. Browser scrollback defaults to 1,000,000 lines. |
|
||||
| `BARECLOUD_TERMINAL_TMUX`, `BARECLOUD_TMUX_BIN` | Resumable console: `tmux` detached session (default **on** when `tmux` is on `PATH`; set `0` to force direct PTY only). Override binary path if needed. |
|
||||
| `BARECLOUD_TMUX_SOCKET` | Optional absolute path to a **dedicated tmux server socket** (`tmux -S …`). Use when the BareCloud host process inherits `TMUX` or you want Pear consoles isolated from your personal `tmux` server. |
|
||||
| `BARECLOUD_DELETE_CORESTORE_ON_REMOVE` | Set `0` / `false` / `no` to keep instance dirs on delete. |
|
||||
|
||||
@@ -650,7 +650,7 @@ export function Terminal({ booterId }: Props) {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="barecloud-xterm-host relative flex h-full min-h-0 w-full flex-col overflow-hidden rounded-2xl border border-white/10 bg-black/40 shadow-inner shadow-black/60"
|
||||
className="barecloud-xterm-host relative flex h-full min-h-0 w-full flex-col overflow-visible rounded-2xl border border-white/10 bg-black/40 shadow-inner shadow-black/60"
|
||||
aria-label="Bare OS console"
|
||||
onMouseDown={(e) => {
|
||||
if (e.button === 0) termRef.current?.focus();
|
||||
@@ -689,7 +689,7 @@ export function Terminal({ booterId }: Props) {
|
||||
)}
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="relative z-0 flex min-h-0 flex-1 flex-col overflow-x-hidden px-2"
|
||||
className="relative z-0 flex min-h-0 flex-1 flex-col overflow-visible px-2"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -193,7 +193,7 @@ export function BooterPage() {
|
||||
</header>
|
||||
|
||||
<div className="mx-auto flex min-h-0 w-full max-w-[1600px] flex-1 flex-col gap-4 overflow-visible px-3 py-3 sm:px-4 sm:py-4 lg:flex-row lg:items-stretch lg:gap-5 lg:overflow-hidden lg:px-5 lg:py-5">
|
||||
<section className="flex min-h-[min(58dvh,680px)] min-w-0 flex-1 flex-col gap-3 overflow-hidden lg:min-h-0">
|
||||
<section className="flex min-h-[min(58dvh,680px)] min-w-0 flex-1 flex-col gap-3 overflow-visible lg:min-h-0">
|
||||
<div className="flex shrink-0 flex-col gap-1 sm:flex-row sm:items-end sm:justify-between">
|
||||
<div>
|
||||
<h2 className="text-base font-semibold tracking-tight text-white">Console</h2>
|
||||
@@ -206,7 +206,7 @@ export function BooterPage() {
|
||||
Interactive
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="relative min-h-0 min-w-0 flex-1 overflow-hidden">
|
||||
<div className="relative min-h-0 min-w-0 flex-1 overflow-visible">
|
||||
<Terminal key={`${id}-${terminalResetKey}`} booterId={id} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
+6
-47
@@ -46,7 +46,7 @@ function tmuxAvailable(): boolean {
|
||||
|
||||
/** Default `TERM` for Pear in tmux / headless paths (matches terminal WebSocket stub). */
|
||||
export function defaultPearTermEnv(): string {
|
||||
return process.env.BARECLOUD_BOOTER_TERM?.trim() || process.env.TERM?.trim() || "xterm-256color";
|
||||
return process.env.BARECLOUD_BOOTER_TERM?.trim() || "xterm-256color";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,51 +92,18 @@ function tmuxExactSessionTarget(booterId: string): string {
|
||||
|
||||
function tmuxHistoryLimit(): number {
|
||||
const raw = process.env.BARECLOUD_TMUX_HISTORY_LIMIT?.trim();
|
||||
if (!raw) return 1_000_000;
|
||||
if (!raw) return 50_000;
|
||||
const n = Number.parseInt(raw, 10);
|
||||
if (!Number.isFinite(n) || n < 1_000) return 1_000_000;
|
||||
return Math.min(n, 1_000_000);
|
||||
}
|
||||
|
||||
function configureTmuxServerForWebTerminal(): void {
|
||||
const override = ",xterm*:smcup@:rmcup@";
|
||||
try {
|
||||
const current = execFileSync(tmuxBin(), [...tmuxSocketArgs(), "show-options", "-gqv", "terminal-overrides"], {
|
||||
env: tmuxClientEnv(process.env),
|
||||
encoding: "utf8",
|
||||
stdio: ["ignore", "pipe", "ignore"],
|
||||
});
|
||||
if (current.includes("xterm*") && current.includes("smcup@") && current.includes("rmcup@")) return;
|
||||
} catch {
|
||||
/* ignore and try to append below */
|
||||
}
|
||||
try {
|
||||
execFileSync(tmuxBin(), [...tmuxSocketArgs(), "set-option", "-g", "-a", "terminal-overrides", override], {
|
||||
stdio: "ignore",
|
||||
env: tmuxClientEnv(process.env),
|
||||
});
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
if (!Number.isFinite(n) || n < 1_000) return 50_000;
|
||||
return Math.min(n, 200_000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure managed BareCloud tmux sessions have wheel-friendly behavior:
|
||||
* - do not enable tmux mouse capture; the browser/xterm scrollbar owns wheel scrolling.
|
||||
* - suppress tmux's outer alternate-screen entry so xterm can accumulate normal-buffer scrollback.
|
||||
* - keep a large tmux history as a fallback for detached/resumed panes.
|
||||
* Keep managed BareCloud tmux sessions close to tmux defaults while retaining resumable pane history.
|
||||
* Browser/xterm owns scrolling; tmux keeps its normal mouse, alternate-screen, and terminal capability behavior.
|
||||
*/
|
||||
function configureTmuxSessionForWebTerminal(booterId: string): void {
|
||||
configureTmuxServerForWebTerminal();
|
||||
const target = tmuxExactSessionTarget(booterId);
|
||||
try {
|
||||
execFileSync(tmuxBin(), [...tmuxSocketArgs(), "set-option", "-t", target, "mouse", "off"], {
|
||||
stdio: "ignore",
|
||||
env: tmuxClientEnv(process.env),
|
||||
});
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
try {
|
||||
execFileSync(
|
||||
tmuxBin(),
|
||||
@@ -149,14 +116,6 @@ function configureTmuxSessionForWebTerminal(booterId: string): void {
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
try {
|
||||
execFileSync(tmuxBin(), [...tmuxSocketArgs(), "set-window-option", "-t", target, "alternate-screen", "off"], {
|
||||
stdio: "ignore",
|
||||
env: tmuxClientEnv(process.env),
|
||||
});
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
export function hasTmuxPearSession(booterId: string): boolean {
|
||||
|
||||
Reference in New Issue
Block a user