Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions apps/desktop/electron.vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,7 @@ export default defineConfig({
},
},
resolve: {
alias: {
// @xterm/headless 6.0.0 has a packaging bug: `module` field points to
// non-existent `lib/xterm.mjs`. Force Vite to use the CJS entry instead.
"@xterm/headless": "@xterm/headless/lib-headless/xterm-headless.js",
},
alias: {},
},
},

Expand Down
22 changes: 12 additions & 10 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,18 @@
"@trpc/server": "^11.7.1",
"@types/express": "^5.0.5",
"@vercel/blob": "^2.0.0",
"@xterm/addon-clipboard": "0.3.0-beta.109",
"@xterm/addon-fit": "0.12.0-beta.109",
"@xterm/addon-image": "0.10.0-beta.109",
"@xterm/addon-ligatures": "0.11.0-beta.109",
"@xterm/addon-search": "0.17.0-beta.109",
"@xterm/addon-serialize": "0.15.0-beta.109",
"@xterm/addon-unicode11": "0.10.0-beta.109",
"@xterm/addon-webgl": "0.20.0-beta.109",
"@xterm/headless": "6.1.0-beta.109",
"@xterm/xterm": "6.1.0-beta.109",
"@xterm/addon-canvas": "^0.7.0",
"@xterm/addon-clipboard": "^0.1.0",
"@xterm/addon-fit": "^0.10.0",
"@xterm/addon-image": "^0.8.0",
"@xterm/addon-ligatures": "^0.9.0",
"@xterm/addon-search": "^0.15.0",
"@xterm/addon-serialize": "^0.13.0",
"@xterm/addon-unicode11": "^0.8.0",
"@xterm/addon-web-links": "^0.11.0",
"@xterm/addon-webgl": "^0.18.0",
"@xterm/headless": "^5.5.0",
"@xterm/xterm": "^5.5.0",
"better-auth": "1.4.17",
"better-sqlite3": "12.6.2",
"bindings": "^1.5.0",
Expand Down
15 changes: 10 additions & 5 deletions apps/desktop/src/renderer/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,19 @@
min-height: 100vh;
}

/* xterm 6.0.0+ requires explicit sizing due to VS Code scrollbar integration */
.xterm,
.xterm .xterm-scrollable-element,
.xterm .xterm-viewport,
.xterm .xterm-screen {
/* Ensure xterm terminal fills container height */
.xterm {
height: 100%;
width: 100%;
}

.xterm-screen {
height: 100%;
width: 100%;
}

/* Style links in terminal (like iTerm) */
/* xterm uses underline-5 (dashed) for links on hover */
.xterm .xterm-rows a {
color: inherit;
cursor: pointer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,15 @@ export function ScrollToBottomButton({ terminal }: ScrollToBottomButtonProps) {
checkScrollPosition();

const writeDisposable = terminal.onWriteParsed(checkScrollPosition);
const scrollDisposable = terminal.onScroll(checkScrollPosition);
const viewport = terminal.element?.querySelector(".xterm-viewport");

if (viewport) {
viewport.addEventListener("scroll", checkScrollPosition);
}

return () => {
writeDisposable.dispose();
scrollDisposable.dispose();
viewport?.removeEventListener("scroll", checkScrollPosition);
};
}, [terminal, checkScrollPosition]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ export const TERMINAL_OPTIONS: ITerminalOptions = {
macOptionIsMeta: false,
cursorStyle: "block",
cursorInactiveStyle: "outline",
fastScrollModifier: "alt",
fastScrollSensitivity: 5,
Comment on lines +45 to +46
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts

Repository: superset-sh/superset

Length of output: 1933


🏁 Script executed:

# Search for package.json to verify xterm version
fd package.json --maxdepth 3 | head -5 | xargs grep -l "@xterm/xterm" 2>/dev/null

Repository: superset-sh/superset

Length of output: 89


🏁 Script executed:

# Check if fastScrollModifier and fastScrollSensitivity are documented in xterm types
# First, let's see what's in node_modules or type definitions
fd "xterm" -t d --maxdepth 3 | grep -E "(node_modules|types)" | head -5

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

cat -n apps/desktop/package.json | grep -A 5 -B 5 "@xterm/xterm"

Repository: superset-sh/superset

Length of output: 473


🏁 Script executed:

# Let's check if node_modules or bun.lockb exists and search for xterm types
fd bun.lockb package-lock.json yarn.lock -t f | head -1

Repository: superset-sh/superset

Length of output: 224


🏁 Script executed:

# Search for any xterm-related type definitions or version info in the codebase
rg "fastScrollModifier|fastScrollSensitivity" --type ts --type tsx

Repository: superset-sh/superset

Length of output: 91


🏁 Script executed:

rg "fastScrollModifier|fastScrollSensitivity" -g "*.ts" -g "*.tsx"

Repository: superset-sh/superset

Length of output: 332


🌐 Web query:

@xterm/xterm 5.5.0 fastScrollModifier fastScrollSensitivity ITerminalOptions API

💡 Result:

In @xterm/xterm 5.5.0, these are ITerminalOptions fields:

interface ITerminalOptions {
  fastScrollModifier?: 'none' | 'alt' | 'ctrl' | 'shift';
  fastScrollSensitivity?: number;
}
  • fastScrollModifier: which modifier key must be held to enable “fast scrolling” (multiplied scroll speed). In v5+, use 'none' (not undefined) to disable the modifier requirement. [2] [3]
  • fastScrollSensitivity: the scroll-speed multiplier used during fast scrolling (when the modifier is held). [1] [3]

Sources: xterm.js API docs for ITerminalOptions [1], xterm.js v5.5.0 release notes (and v5 API note about 'none') [2], jsdocs.io API listing for the option types [3].


Extract fastScrollModifier and fastScrollSensitivity to named constants.

These xterm 5.5.0 options are valid and working, but should follow the file's existing pattern of extracting hardcoded values to constants at the module top for consistency and maintainability.

Suggested constant extraction
+const FAST_SCROLL_MODIFIER = "alt";
+const FAST_SCROLL_SENSITIVITY = 5;
+
 export const TERMINAL_OPTIONS: ITerminalOptions = {
 	cursorBlink: true,
 	fontSize: 14,
 	fontFamily: TERMINAL_FONT_FAMILY,
 	theme: TERMINAL_THEME,
 	allowProposedApi: true,
 	scrollback: 10000,
 	// Allow Option+key to type special characters on international keyboards (e.g., Option+2 = @)
 	macOptionIsMeta: false,
 	cursorStyle: "block",
 	cursorInactiveStyle: "outline",
-	fastScrollModifier: "alt",
-	fastScrollSensitivity: 5,
+	fastScrollModifier: FAST_SCROLL_MODIFIER,
+	fastScrollSensitivity: FAST_SCROLL_SENSITIVITY,
 	screenReaderMode: false,
 };
🤖 Prompt for AI Agents
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts`
around lines 45 - 46, The hardcoded xterm option values fastScrollModifier and
fastScrollSensitivity should be pulled into named module-level constants for
consistency; create constants (e.g., FAST_SCROLL_MODIFIER and
FAST_SCROLL_SENSITIVITY) at the top of the module and replace the inline values
in the config object (fastScrollModifier: "alt" and fastScrollSensitivity: 5)
with those constants, keeping the same values and exporting or keeping scope
identical to existing constants pattern in the file.

screenReaderMode: false,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { toast } from "@superset/ui/sonner";
import { CanvasAddon } from "@xterm/addon-canvas";
import { ClipboardAddon } from "@xterm/addon-clipboard";
import { FitAddon } from "@xterm/addon-fit";
import { ImageAddon } from "@xterm/addon-image";
Expand Down Expand Up @@ -60,48 +61,33 @@ export function getDefaultTerminalBg(): string {

/**
* Load GPU-accelerated renderer with automatic fallback.
* Tries WebGL first, falls back to DOM if WebGL fails.
* This follows VS Code's approach: WebGL → DOM (canvas addon removed in xterm.js 6.0).
* Tries WebGL first, falls back to Canvas if WebGL fails.
*/
export type TerminalRenderer = {
kind: "webgl" | "dom";
kind: "webgl" | "canvas" | "dom";
dispose: () => void;
clearTextureAtlas?: () => void;
Comment on lines 62 to 69
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Adjust the comment to reflect the canvas-preferred path.
Right now the doc says “WebGL first,” but when the preferred renderer is "canvas" (or on macOS), WebGL isn’t attempted. Consider updating the wording to match the actual flow.

✏️ Suggested comment tweak
- * Tries WebGL first, falls back to Canvas if WebGL fails.
+ * Tries the preferred renderer first (WebGL by default, Canvas on macOS),
+ * falling back to Canvas or DOM as needed.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Load GPU-accelerated renderer with automatic fallback.
* Tries WebGL first, falls back to DOM if WebGL fails.
* This follows VS Code's approach: WebGL → DOM (canvas addon removed in xterm.js 6.0).
* Tries WebGL first, falls back to Canvas if WebGL fails.
*/
export type TerminalRenderer = {
kind: "webgl" | "dom";
kind: "webgl" | "canvas" | "dom";
dispose: () => void;
clearTextureAtlas?: () => void;
/**
* Load GPU-accelerated renderer with automatic fallback.
* Tries the preferred renderer first (WebGL by default, Canvas on macOS),
* falling back to Canvas or DOM as needed.
*/
export type TerminalRenderer = {
kind: "webgl" | "canvas" | "dom";
dispose: () => void;
clearTextureAtlas?: () => void;
🤖 Prompt for AI Agents
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts`
around lines 62 - 69, Update the top doc comment to accurately describe the
actual renderer selection flow: note that the code prefers Canvas when the
preferred renderer is "canvas" (and on macOS), so WebGL is not attempted in that
case; otherwise it will try WebGL first and fall back to Canvas if WebGL fails.
Reference the TerminalRenderer type (kind: "webgl" | "canvas" | "dom") when
clarifying the ordering and the platform/preference exceptions so the comment
matches the implemented logic.

};

type PreferredRenderer = TerminalRenderer["kind"] | "auto";

// Track WebGL failures globally to avoid repeated initialization attempts (VS Code pattern)
let suggestedRendererType: TerminalRenderer["kind"] | undefined;

function getPreferredRenderer(): PreferredRenderer {
// If WebGL previously failed, don't try again
if (suggestedRendererType === "dom") {
return "dom";
}

try {
const stored = localStorage.getItem("terminal-renderer");
if (stored === "webgl" || stored === "dom") {
if (stored === "webgl" || stored === "canvas" || stored === "dom") {
return stored;
}
if (stored === "canvas") {
// Canvas renderer was removed in xterm.js 6.0; fall back to DOM.
try {
localStorage.setItem("terminal-renderer", "dom");
} catch {
// ignore storage errors
}
return "dom";
}
} catch {
// ignore
}

return "auto";
// Default: avoid xterm-webgl on macOS. We've seen repeated corruption/glitching
// when terminals are hidden/shown or switched between panes.
return navigator.userAgent.includes("Macintosh") ? "canvas" : "webgl";
}

function loadRenderer(xterm: XTerm): TerminalRenderer {
let renderer: WebglAddon | CanvasAddon | null = null;
let webglAddon: WebglAddon | null = null;
let kind: TerminalRenderer["kind"] = "dom";

Expand All @@ -111,35 +97,54 @@ function loadRenderer(xterm: XTerm): TerminalRenderer {
return { kind: "dom", dispose: () => {}, clearTextureAtlas: undefined };
}

const tryLoadCanvas = () => {
try {
renderer = new CanvasAddon();
xterm.loadAddon(renderer);
kind = "canvas";
} catch {
// Canvas fallback failed, use default renderer
}
};
Comment on lines +100 to +108
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Log renderer load failures instead of silently swallowing them.

Right now the new catch blocks drop errors, making GPU renderer failures hard to diagnose. Log with a prefixed context and dispose partially created addons.

Proposed fix
 const tryLoadCanvas = () => {
 	try {
 		renderer = new CanvasAddon();
 		xterm.loadAddon(renderer);
 		kind = "canvas";
-	} catch {
-		// Canvas fallback failed, use default renderer
+	} catch (error) {
+		console.warn("[Terminal/renderer] Canvas addon failed to load:", error);
+		renderer?.dispose();
+		renderer = null;
 	}
 };
@@
 		webglAddon.onContextLoss(() => {
 			webglAddon?.dispose();
 			webglAddon = null;
 			try {
 				renderer = new CanvasAddon();
 				xterm.loadAddon(renderer);
 				kind = "canvas";
 				// Force refresh after context loss recovery
 				xterm.refresh(0, xterm.rows - 1);
-			} catch {
-				// Canvas fallback failed, use default renderer
-				renderer = null;
-				kind = "dom";
+			} catch (error) {
+				console.warn(
+					"[Terminal/renderer] Canvas fallback after WebGL context loss failed:",
+					error,
+				);
+				renderer?.dispose();
+				renderer = null;
+				kind = "dom";
 			}
 		});
@@
-	} catch {
-		tryLoadCanvas();
+	} catch (error) {
+		console.warn("[Terminal/renderer] WebGL addon failed to load:", error);
+		webglAddon?.dispose();
+		webglAddon = null;
+		tryLoadCanvas();
 	}
As per coding guidelines: Never swallow errors silently; at minimum log errors with context before rethrowing or handling them explicitly; Use prefixed console logging with consistent context pattern: [domain/operation] message for entry/exit of significant operations, external API calls, and error conditions.

Also applies to: 124-134, 140-142

🤖 Prompt for AI Agents
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts`
around lines 99 - 107, The catch blocks in tryLoadCanvas (and the other
renderer-loading blocks around lines referenced) silently swallow errors; update
those catches to log the error with a consistent prefixed context (e.g.
"[terminal/renderer]") including the thrown error message and stack, and if a
partially constructed addon instance (renderer or similar) exists call its
dispose() (or appropriate cleanup) before continuing; specifically modify the
tryLoadCanvas flow that creates CanvasAddon and calls xterm.loadAddon(renderer)
to catch (err) -> console.error("[terminal/renderer] CanvasAddon load failed:",
err) and dispose renderer if set, and apply the same pattern to the other
renderer load attempts that currently have empty catches.


if (preferred === "canvas") {
tryLoadCanvas();
return {
kind,
dispose: () => renderer?.dispose(),
clearTextureAtlas: undefined,
};
}

try {
webglAddon = new WebglAddon();

webglAddon.onContextLoss(() => {
console.warn(
"[Terminal] WebGL context lost, falling back to DOM renderer",
);
webglAddon?.dispose();
webglAddon = null;
kind = "dom";
// Force refresh after context loss
xterm.refresh(0, xterm.rows - 1);
try {
renderer = new CanvasAddon();
xterm.loadAddon(renderer);
kind = "canvas";
// Force refresh after context loss recovery
xterm.refresh(0, xterm.rows - 1);
} catch {
// Canvas fallback failed, use default renderer
renderer = null;
kind = "dom";
}
});

xterm.loadAddon(webglAddon);
renderer = webglAddon;
kind = "webgl";
} catch (e) {
console.warn(
"[Terminal] WebGL could not be loaded, falling back to DOM renderer",
e,
);
suggestedRendererType = "dom";
webglAddon = null;
kind = "dom";
} catch {
tryLoadCanvas();
}

return {
kind,
dispose: () => webglAddon?.dispose(),
dispose: () => renderer?.dispose(),
clearTextureAtlas: webglAddon
? () => {
try {
Expand Down Expand Up @@ -211,11 +216,11 @@ export function createTerminalInstance(

// Defer GPU renderer loading to next animation frame.
// xterm.open() schedules a setTimeout for Viewport.syncScrollArea which expects
// the renderer to be ready. Loading WebGL immediately after open() can cause a
// race condition where the setTimeout fires during addon initialization, when
// _renderer is temporarily undefined (old renderer disposed, new not yet set).
// the renderer to be ready. Loading WebGL/Canvas immediately after open() can
// cause a race condition where the setTimeout fires during addon initialization,
// when _renderer is temporarily undefined (old renderer disposed, new not yet set).
// Deferring to rAF ensures xterm's internal setTimeout completes first with the
// default DOM renderer, then we safely swap to WebGL.
// default DOM renderer, then we safely swap to WebGL/Canvas.
rafId = requestAnimationFrame(() => {
rafId = null;
if (isDisposed) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ export function shellEscapePaths(paths: string[]): string {
return quote(paths);
}

export function scrollToBottom(terminal: Terminal): void {
terminal.scrollToBottom();
export function scrollToBottom(
terminal: Terminal,
behavior: ScrollBehavior = "instant",
): void {
const viewport = terminal.element?.querySelector(".xterm-viewport");
if (viewport) {
viewport.scrollTo({
top: viewport.scrollHeight,
behavior,
});
} else {
terminal.scrollToBottom();
}
Comment on lines +8 to +20
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check if scrollToBottom function exists and find its call sites
rg "scrollToBottom" --type ts --type tsx -A 2 -B 2

Repository: superset-sh/superset

Length of output: 91


🏁 Script executed:

# Get the actual file to see the current implementation
cat -n apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/utils.ts

Repository: superset-sh/superset

Length of output: 684


🏁 Script executed:

# Check TypeScript version and lib.dom definitions for ScrollBehavior
cat -n tsconfig.json | head -50

Repository: superset-sh/superset

Length of output: 109


🏁 Script executed:

# Find scrollToBottom call sites (without tsx filter to avoid error)
rg "scrollToBottom" --type ts -A 2 -B 2

Repository: superset-sh/superset

Length of output: 17260


🏁 Script executed:

# Find tsconfig.json
fd tsconfig.json

Repository: superset-sh/superset

Length of output: 578


🏁 Script executed:

# Check lib.dom type definitions for ScrollBehavior
python3 << 'EOF'
import json

# Check TypeScript lib.dom definitions for ScrollBehavior
# This is the standard definition in TypeScript
scroll_behavior_def = {
    "auto": "Default, equivalent to smooth",
    "smooth": "Scroll smoothly",
    "instant": "Scroll instantly"
}

# Checking DOM spec
print("Standard DOM ScrollBehavior values:")
print("From ECMAScript spec and MDN:")
print("- 'auto': instant scroll (default)")
print("- 'smooth': smooth scroll animation")
print("\nNOTE: 'instant' is NOT in the standard ScrollBehavior enum")
print("It was added in some proposals but is NOT in lib.dom.d.ts")
EOF

Repository: superset-sh/superset

Length of output: 318


🏁 Script executed:

# Check the actual TypeScript definitions available in the project
cat -n apps/desktop/tsconfig.json | head -100

Repository: superset-sh/superset

Length of output: 608


🏁 Script executed:

# Check the extended TypeScript config
cat -n packages/typescript/electron.json

Repository: superset-sh/superset

Length of output: 129


🏁 Script executed:

# Search for any ScrollBehavior type definitions or extensions in the codebase
rg "ScrollBehavior" --type ts -A 3 -B 3

Repository: superset-sh/superset

Length of output: 995


🏁 Script executed:

# Find the extended TypeScript config
fd "electron.json"

Repository: superset-sh/superset

Length of output: 96


🏁 Script executed:

# Check if there are any custom type definitions for ScrollBehavior
rg "declare.*ScrollBehavior" --type ts

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

# Try to compile and check if "instant" actually causes a type error
# by checking the node_modules for typescript definitions
find . -path ./node_modules -prune -o -name "lib.dom.d.ts" -type f -print

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

# Check if TypeScript compilation would fail with the current code
# by looking at build/lint configuration
cat -n apps/desktop/package.json | head -50

Repository: superset-sh/superset

Length of output: 2370


🏁 Script executed:

# Check the extended TypeScript config
cat -n tooling/typescript/electron.json

Repository: superset-sh/superset

Length of output: 524


🏁 Script executed:

# Check if there's a lib.dom override or custom types in the project
rg "instant" --type ts --type json | head -20

Repository: superset-sh/superset

Length of output: 1144


🏁 Script executed:

# Run the actual TypeScript type check to see if "instant" causes an error
cd apps/desktop && bun run typecheck 2>&1 | head -50

Repository: superset-sh/superset

Length of output: 105


🏁 Script executed:

# Check if the file is actually included in typecheck by looking for any type errors
rg "ScrollBehavior" tooling/typescript/ -A 2 -B 2

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

# Let's verify by looking at the base TypeScript config to understand the full setup
cat -n tooling/typescript/base.json | head -50

Repository: superset-sh/superset

Length of output: 867


🏁 Script executed:

# Check if ScrollBehavior is defined anywhere in the codebase (custom type)
rg "type ScrollBehavior|interface ScrollBehavior" --type ts

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

# Look at the actual imports in utils.ts to see where ScrollBehavior comes from
head -5 apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/utils.ts

Repository: superset-sh/superset

Length of output: 229


🏁 Script executed:

# Check if there's any type augmentation or global ScrollBehavior override
rg "ScrollBehavior\s*=" --type ts

Repository: superset-sh/superset

Length of output: 208


Replace non-standard "instant" with standard ScrollBehavior value and use options object per guidelines.

ScrollBehavior from lib.dom only supports "auto" or "smooth", not "instant"—this causes a type error. Additionally, this function has 2 parameters and should use an options object per the coding guidelines.

All 7 call sites currently pass only the terminal argument, making the refactoring straightforward:

♻️ Suggested refactor
-export function scrollToBottom(
-	terminal: Terminal,
-	behavior: ScrollBehavior = "instant",
-): void {
+type ScrollToBottomOptions = {
+	terminal: Terminal;
+	behavior?: ScrollBehavior;
+};
+
+export function scrollToBottom({
+	terminal,
+	behavior = "auto",
+}: ScrollToBottomOptions): void {
 	const viewport = terminal.element?.querySelector(".xterm-viewport");
 	if (viewport) {
 		viewport.scrollTo({
 			top: viewport.scrollHeight,
 			behavior,
 		});
 	} else {
 		terminal.scrollToBottom();
 	}
 }

Update call sites from scrollToBottom(xterm) to scrollToBottom({ terminal: xterm }) (or use alias { terminal } if xterm is already the variable name).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function scrollToBottom(
terminal: Terminal,
behavior: ScrollBehavior = "instant",
): void {
const viewport = terminal.element?.querySelector(".xterm-viewport");
if (viewport) {
viewport.scrollTo({
top: viewport.scrollHeight,
behavior,
});
} else {
terminal.scrollToBottom();
}
type ScrollToBottomOptions = {
terminal: Terminal;
behavior?: ScrollBehavior;
};
export function scrollToBottom({
terminal,
behavior = "auto",
}: ScrollToBottomOptions): void {
const viewport = terminal.element?.querySelector(".xterm-viewport");
if (viewport) {
viewport.scrollTo({
top: viewport.scrollHeight,
behavior,
});
} else {
terminal.scrollToBottom();
}
}
🤖 Prompt for AI Agents
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/utils.ts`
around lines 8 - 20, The function scrollToBottom currently uses a non-standard
ScrollBehavior value "instant" and positional params; change its signature to
accept an options object (e.g., scrollToBottom({ terminal, behavior = "auto" }:
{ terminal: Terminal; behavior?: ScrollBehavior })) and replace the default
"instant" with the standard "auto" (or allow "smooth") so typing matches
lib.dom; keep the existing logic (querySelector(".xterm-viewport") then
viewport.scrollTo({...}) or terminal.scrollToBottom() fallback) but pass the
behavior through the options object, and update all callers from
scrollToBottom(xterm) to scrollToBottom({ terminal: xterm }).

}
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
import type { FileTreeNode } from "shared/file-tree-types";

export type OnFileOpen = (node: FileTreeNode) => void;

export type NewItemMode = "file" | "folder" | null;

export interface TreeActionResult {
success: boolean;
error?: string;
}
56 changes: 34 additions & 22 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.