Skip to content

Added xterm support for scrolling follow-along, fixed PVC leftovers after deleting STS. - #80

Merged
HUAHUAI23 merged 8 commits into
FullAgent:mainfrom
HUAHUAI23:feat
Nov 12, 2025
Merged

Added xterm support for scrolling follow-along, fixed PVC leftovers after deleting STS.#80
HUAHUAI23 merged 8 commits into
FullAgent:mainfrom
HUAHUAI23:feat

Conversation

@HUAHUAI23

Copy link
Copy Markdown
Contributor
  1. Added xterm support for scrolling follow-along,
  2. fixed PVC leftovers after deleting STS.

Copilot AI left a comment

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.

Pull Request Overview

This pull request adds xterm.js-based terminal support with scrolling follow-along functionality and fixes PVC cleanup issues in StatefulSet deletion.

Key changes:

  • Replaces iframe-based terminal with native xterm.js implementation featuring auto-scroll indicators
  • Implements automatic PVC deletion for StatefulSets with retention policy configuration
  • Enhances project filtering API with keyword search and date range capabilities

Reviewed Changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
package.json, pnpm-lock.yaml Adds xterm.js and related addon dependencies
lib/k8s/sandbox-manager.ts Adds PVC cleanup logic and retention policy configuration for StatefulSets
hooks/use-terminal.ts New hook for terminal WebSocket connection management (appears unused)
hooks/use-projects.ts Updates project filtering with keyword/date filters and changes default refetch behavior
components/terminal/xterm-terminal.tsx New xterm.js-based terminal component with scroll indicators
components/terminal/terminal-display.tsx Replaces iframe with XtermTerminal component
components/terminal/terminal-container.tsx Enhanced comments for tab management
app/projects/page.tsx Removes explicit namespace parameter from useProjects
app/api/projects/route.ts Implements keyword/date filtering and automatic namespace detection
app/globals.css Adds fade-in animation for scroll indicator
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread hooks/use-projects.ts
const { refetchInterval = 3000, refetchOnWindowFocus = false, namespace } = options;
const {
refetchInterval = 3000,
refetchOnWindowFocus = true,

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

The default value for refetchOnWindowFocus has changed from false to true. This behavioral change means projects will now automatically refetch when the window regains focus, which could cause unexpected API calls and affect user experience. Consider documenting this change in the PR description or reverting to the original default if this wasn't intentional.

Suggested change
refetchOnWindowFocus = true,
refetchOnWindowFocus = false,

Copilot uses AI. Check for mistakes.
Comment on lines +523 to +524
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wsUrl]);

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

The useEffect dependency array only includes wsUrl, but the effect uses several callback props (stableOnReady, stableOnConnected, stableOnDisconnected) and rendererType. While these are wrapped with useCallback, they should still be included in the dependency array or the eslint rule should not be disabled. The current implementation may cause stale closures if these callbacks change.

Suggested change
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wsUrl]);
}, [wsUrl, stableOnReady, stableOnConnected, stableOnDisconnected, rendererType]);

Copilot uses AI. Check for mistakes.
Comment on lines +625 to +628
persistentVolumeClaimRetentionPolicy: {
whenDeleted: 'Delete', // Delete PVCs when StatefulSet is deleted
whenScaled: 'Retain', // Keep PVCs when scaling down (for potential scale-up)
},

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

The persistentVolumeClaimRetentionPolicy requires Kubernetes 1.23+ as mentioned in the deletePVCs comment. This should be documented here as well to warn about potential compatibility issues with older clusters that may not support this field.

Copilot uses AI. Check for mistakes.
Comment thread app/api/projects/route.ts
Comment on lines +119 to +123
// If user doesn't have kubeconfig configured, log warning but don't fail
// Return empty array instead of filtering by namespace
logger.warn(
`User ${session.user.id} does not have KUBECONFIG configured, returning all projects`
)

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

The comment says 'Return empty array' but the code actually returns all projects without namespace filtering. This is misleading and potentially a security issue - users without kubeconfig will see projects from all namespaces instead of no projects. The behavior should either match the comment or the comment should be corrected to reflect the actual behavior.

Suggested change
// If user doesn't have kubeconfig configured, log warning but don't fail
// Return empty array instead of filtering by namespace
logger.warn(
`User ${session.user.id} does not have KUBECONFIG configured, returning all projects`
)
// If user doesn't have kubeconfig configured, log warning and return empty array
logger.warn(
`User ${session.user.id} does not have KUBECONFIG configured, returning empty array`
)
return NextResponse.json([])

Copilot uses AI. Check for mistakes.
Comment thread components/terminal/xterm-terminal.tsx
Comment on lines +464 to +467
let lineFeedTimeout: NodeJS.Timeout | null = null;
terminal.onLineFeed(() => {
if (lineFeedTimeout) clearTimeout(lineFeedTimeout);
lineFeedTimeout = setTimeout(() => {

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

The lineFeedTimeout variable is declared inside the init function but never cleaned up in the cleanup function. This could cause the timeout to fire after component unmount. Add if (lineFeedTimeout) clearTimeout(lineFeedTimeout) to the cleanup function at line 497.

Copilot uses AI. Check for mistakes.
Comment thread hooks/use-terminal.ts
Comment on lines +76 to +80
const handleConnected = useCallback(() => {
setStatus('connected')
shouldReconnectRef.current = autoReconnect
onConnected?.()
}, [autoReconnect, onConnected])

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

Unused variable handleConnected.

Suggested change
const handleConnected = useCallback(() => {
setStatus('connected')
shouldReconnectRef.current = autoReconnect
onConnected?.()
}, [autoReconnect, onConnected])

Copilot uses AI. Check for mistakes.
Comment thread hooks/use-terminal.ts
Comment on lines +82 to +95
const handleDisconnected = useCallback(() => {
setStatus('disconnected')
onDisconnected?.()

// Schedule reconnection if enabled
if (shouldReconnectRef.current && wsUrl) {
console.log(`[useTerminal] Reconnecting in ${reconnectDelay}ms...`)
reconnectTimeoutRef.current = setTimeout(() => {
setStatus('connecting')
// Trigger re-render to reconnect
setWsUrl((prev) => (prev ? `${prev}` : null))
}, reconnectDelay)
}
}, [wsUrl, reconnectDelay, onDisconnected])

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

Unused variable handleDisconnected.

Suggested change
const handleDisconnected = useCallback(() => {
setStatus('disconnected')
onDisconnected?.()
// Schedule reconnection if enabled
if (shouldReconnectRef.current && wsUrl) {
console.log(`[useTerminal] Reconnecting in ${reconnectDelay}ms...`)
reconnectTimeoutRef.current = setTimeout(() => {
setStatus('connecting')
// Trigger re-render to reconnect
setWsUrl((prev) => (prev ? `${prev}` : null))
}, reconnectDelay)
}
}, [wsUrl, reconnectDelay, onDisconnected])

Copilot uses AI. Check for mistakes.
@github-actions

github-actions Bot commented Nov 12, 2025

Copy link
Copy Markdown

✅ PR Check Results: Passed

Build Checks

Check Status
Lint & Build ✅ Passed
Docker Build ✅ Passed

✨ Great work!

All checks passed successfully. Your PR is ready for review.

Details:

  • ✅ Code quality verified (linting passed)
  • ✅ Build successful
  • ✅ Docker image build verified (linux/amd64)
    Commit: 373bc16ae0c31fe89bf51e06f85ec9f480410016
    Branch: feat

🔗 View Details:

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@HUAHUAI23
HUAHUAI23 merged commit b065428 into FullAgent:main Nov 12, 2025
7 checks passed
@HUAHUAI23
HUAHUAI23 deleted the feat branch November 12, 2025 07:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants