Skip to content

Conversation

@vultuk
Copy link
Owner

@vultuk vultuk commented Sep 13, 2025

This PR releases v2.10.0.

Highlights:

  • Tiled View (MVP): two sessions side-by-side, each with its own terminal/socket
  • Draggable splitter with persistent position
  • Per-pane session picker and close actions; layout persists across reloads
  • Settings font size applies to all panes

No API/CLI changes.

Copilot AI review requested due to automatic review settings September 13, 2025 20:51
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces a tiled view feature (v2.10.0) that allows users to view two sessions side-by-side, each with independent terminals and sockets.

  • Adds a new tiled interface with draggable splitter and persistent position
  • Implements per-pane session management with dropdowns and close actions
  • Extends font size settings to apply across all panes

Reviewed Changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/public/style.css Adds CSS for tile layout, pane styling, resizer, and tile controls
src/public/session-manager.js Adds hooks to refresh pane session selectors when sessions are loaded/updated
src/public/panes.js New file implementing ClaudePane and PaneManager classes for tiled view functionality
src/public/index.html Adds tiled view HTML structure, tile toggle button, and theme selection script
src/public/app.js Integrates PaneManager, adds tile view toggle handler, and extends settings for multi-pane support
package.json Updates version from 2.8.0 to 2.10.0
CHANGELOG.md Documents v2.9.0 theme changes and v2.10.0 tiled view features

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +463 to +465
width: 28px; height: 28px; display:flex; align-items:center; justify-content:center;
background: transparent; border: 1px solid var(--border); border-radius: 4px;
color: var(--text-secondary); cursor: pointer; transition: all .2s; flex-shrink: 0; margin-left: 4px;
Copy link

Copilot AI Sep 13, 2025

Choose a reason for hiding this comment

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

[nitpick] The .tab-tile styles are duplicated from .tab-new. Consider creating a shared base class to reduce code duplication and improve maintainability.

Copilot uses AI. Check for mistakes.
Comment on lines +918 to +933
.tiles-container { flex: 1; display: flex; min-height: 0; }
.tile-grid {
display: grid; grid-template-columns: 1fr 6px 1fr; grid-template-rows: 100%; width: 100%;
}
.tile-pane { display:flex; flex-direction: column; min-width: 0; border-left: 1px solid var(--border); }
.tile-pane:first-child { border-left: none; }
.tile-toolbar { display:flex; align-items:center; gap: 8px; padding: 6px 8px; background: var(--bg-secondary); border-bottom:1px solid var(--border); }
.tile-toolbar .spacer { flex:1; }
.tile-session-select { background: var(--bg-tertiary); color: var(--text-primary); border:1px solid var(--border); border-radius:6px; padding:6px 8px; font-family: var(--font-mono); font-size:12px; }
.tile-close { background: transparent; border:1px solid var(--border); border-radius:4px; color: var(--text-secondary); width:26px; height:26px; display:flex; align-items:center; justify-content:center; cursor:pointer; }
.tile-close:hover { background: var(--bg-tertiary); color: var(--text-primary); }
.tile-terminal { flex:1; min-height:0; position: relative; }
.tile-terminal .xterm { height: 100%; }

.resizer {
background: var(--border); cursor: col-resize; width: 6px; height: 100%;
Copy link

Copilot AI Sep 13, 2025

Choose a reason for hiding this comment

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

[nitpick] Multiple CSS rules are written on single lines making them difficult to read and maintain. Consider formatting these rules with proper line breaks and indentation for better readability.

Suggested change
.tiles-container { flex: 1; display: flex; min-height: 0; }
.tile-grid {
display: grid; grid-template-columns: 1fr 6px 1fr; grid-template-rows: 100%; width: 100%;
}
.tile-pane { display:flex; flex-direction: column; min-width: 0; border-left: 1px solid var(--border); }
.tile-pane:first-child { border-left: none; }
.tile-toolbar { display:flex; align-items:center; gap: 8px; padding: 6px 8px; background: var(--bg-secondary); border-bottom:1px solid var(--border); }
.tile-toolbar .spacer { flex:1; }
.tile-session-select { background: var(--bg-tertiary); color: var(--text-primary); border:1px solid var(--border); border-radius:6px; padding:6px 8px; font-family: var(--font-mono); font-size:12px; }
.tile-close { background: transparent; border:1px solid var(--border); border-radius:4px; color: var(--text-secondary); width:26px; height:26px; display:flex; align-items:center; justify-content:center; cursor:pointer; }
.tile-close:hover { background: var(--bg-tertiary); color: var(--text-primary); }
.tile-terminal { flex:1; min-height:0; position: relative; }
.tile-terminal .xterm { height: 100%; }
.resizer {
background: var(--border); cursor: col-resize; width: 6px; height: 100%;
.tiles-container {
flex: 1;
display: flex;
min-height: 0;
}
.tile-grid {
display: grid;
grid-template-columns: 1fr 6px 1fr;
grid-template-rows: 100%;
width: 100%;
}
.tile-pane {
display: flex;
flex-direction: column;
min-width: 0;
border-left: 1px solid var(--border);
}
.tile-pane:first-child {
border-left: none;
}
.tile-toolbar {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px;
background: var(--bg-secondary);
border-bottom: 1px solid var(--border);
}
.tile-toolbar .spacer {
flex: 1;
}
.tile-session-select {
background: var(--bg-tertiary);
color: var(--text-primary);
border: 1px solid var(--border);
border-radius: 6px;
padding: 6px 8px;
font-family: var(--font-mono);
font-size: 12px;
}
.tile-close {
background: transparent;
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text-secondary);
width: 26px;
height: 26px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.tile-close:hover {
background: var(--bg-tertiary);
color: var(--text-primary);
}
.tile-terminal {
flex: 1;
min-height: 0;
position: relative;
}
.tile-terminal .xterm {
height: 100%;
}
.resizer {
background: var(--border);
cursor: col-resize;
width: 6px;
height: 100%;

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +43
fit() {
try { this.fitAddon?.fit(); } catch (_) {}
}
Copy link

Copilot AI Sep 13, 2025

Choose a reason for hiding this comment

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

The empty catch block with underscore parameter suppresses all errors, which could hide important issues. Consider logging the error or handling specific expected exceptions.

Copilot uses AI. Check for mistakes.
Comment on lines +82 to +86
disconnect() {
try { this.socket?.close(); } catch (_) {}
this.socket = null;
try { this.terminal?.clear(); } catch (_) {}
}
Copy link

Copilot AI Sep 13, 2025

Choose a reason for hiding this comment

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

Empty catch blocks suppress all errors without logging. Consider logging errors or handling specific expected exceptions to aid debugging.

Copilot uses AI. Check for mistakes.
sessions: this.panes.map(p => p.sessionId)
};
localStorage.setItem('cc-web-tiles', JSON.stringify(state));
} catch (_) {}
Copy link

Copilot AI Sep 13, 2025

Choose a reason for hiding this comment

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

The empty catch block silently ignores localStorage errors. Consider logging the error as localStorage failures could indicate storage quota issues or privacy mode restrictions.

Suggested change
} catch (_) {}
} catch (err) {
console.error("Failed to persist pane state to localStorage:", err);
}

Copilot uses AI. Check for mistakes.
(st.sessions || []).forEach((id, i) => id && this.assignSession(i, id));
}, 500);
}
} catch (_) {}
Copy link

Copilot AI Sep 13, 2025

Choose a reason for hiding this comment

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

Empty catch block in restoreFromStorage() silently ignores parsing errors. Consider logging errors to help debug configuration restoration issues.

Suggested change
} catch (_) {}
} catch (err) {
console.error("Failed to restore pane configuration from storage:", err);
}

Copilot uses AI. Check for mistakes.
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