diff --git a/packages/coding-agent/src/core/export-html/template.css b/packages/coding-agent/src/core/export-html/template.css
index 6ef5d3976..311af7f74 100644
--- a/packages/coding-agent/src/core/export-html/template.css
+++ b/packages/coding-agent/src/core/export-html/template.css
@@ -9,6 +9,10 @@
:root {
--line-height: 18px; /* 12px font * 1.5 */
+ --sidebar-width: 400px;
+ --sidebar-min-width: 240px;
+ --sidebar-max-width: 840px;
+ --sidebar-resizer-width: 6px;
}
body {
@@ -19,6 +23,11 @@
background: var(--body-bg);
}
+ body.sidebar-resizing {
+ cursor: col-resize;
+ user-select: none;
+ }
+
#app {
display: flex;
min-height: 100vh;
@@ -26,7 +35,9 @@
/* Sidebar */
#sidebar {
- width: 400px;
+ width: var(--sidebar-width);
+ min-width: var(--sidebar-width);
+ max-width: var(--sidebar-width);
background: var(--container-bg);
flex-shrink: 0;
display: flex;
@@ -37,6 +48,24 @@
border-right: 1px solid var(--dim);
}
+ #sidebar-resizer {
+ width: var(--sidebar-resizer-width);
+ flex-shrink: 0;
+ position: sticky;
+ top: 0;
+ height: 100vh;
+ cursor: col-resize;
+ touch-action: none;
+ background: transparent;
+ border-right: 1px solid transparent;
+ }
+
+ #sidebar-resizer:hover,
+ body.sidebar-resizing #sidebar-resizer {
+ background: var(--selectedBg);
+ border-right-color: var(--dim);
+ }
+
.sidebar-header {
padding: 8px 12px;
flex-shrink: 0;
@@ -213,6 +242,7 @@
/* Main content */
#content {
flex: 1;
+ min-width: 0;
overflow-y: auto;
padding: var(--line-height) calc(var(--line-height) * 2);
display: flex;
@@ -923,17 +953,24 @@
@media (max-width: 900px) {
#sidebar {
position: fixed;
- left: -400px;
- width: 400px;
+ left: 0;
+ width: min(var(--sidebar-width), 100vw);
+ min-width: min(var(--sidebar-width), 100vw);
+ max-width: min(var(--sidebar-width), 100vw);
top: 0;
bottom: 0;
height: 100vh;
z-index: 99;
- transition: left 0.3s;
+ transform: translateX(-100%);
+ transition: transform 0.3s;
}
#sidebar.open {
- left: 0;
+ transform: translateX(0);
+ }
+
+ #sidebar-resizer {
+ display: none;
}
#sidebar-overlay.open {
@@ -957,15 +994,8 @@
}
}
- @media (max-width: 500px) {
- #sidebar {
- width: 100vw;
- left: -100vw;
- }
- }
-
@media print {
- #sidebar, #sidebar-toggle { display: none !important; }
+ #sidebar, #sidebar-resizer, #sidebar-toggle { display: none !important; }
body { background: white; color: black; }
#content { max-width: none; }
}
diff --git a/packages/coding-agent/src/core/export-html/template.html b/packages/coding-agent/src/core/export-html/template.html
index 42f2a45b0..c1d678a0a 100644
--- a/packages/coding-agent/src/core/export-html/template.html
+++ b/packages/coding-agent/src/core/export-html/template.html
@@ -29,6 +29,7 @@
+
diff --git a/packages/coding-agent/src/core/export-html/template.js b/packages/coding-agent/src/core/export-html/template.js
index e170d7a6b..6b53516b1 100644
--- a/packages/coding-agent/src/core/export-html/template.js
+++ b/packages/coding-agent/src/core/export-html/template.js
@@ -1510,6 +1510,113 @@
const sidebar = document.getElementById('sidebar');
const overlay = document.getElementById('sidebar-overlay');
const hamburger = document.getElementById('hamburger');
+ const sidebarResizer = document.getElementById('sidebar-resizer');
+ const SIDEBAR_WIDTH_STORAGE_KEY = 'pi-share:v1:sidebar-width';
+ const MIN_CONTENT_WIDTH = 320;
+
+ function isMobileLayout() {
+ return window.matchMedia('(max-width: 900px)').matches;
+ }
+
+ function getSidebarBounds() {
+ const rootStyles = getComputedStyle(document.documentElement);
+ const minWidth = parseFloat(rootStyles.getPropertyValue('--sidebar-min-width')) || 240;
+ const maxWidth = parseFloat(rootStyles.getPropertyValue('--sidebar-max-width')) || 720;
+ const viewportMaxWidth = window.innerWidth - MIN_CONTENT_WIDTH;
+ return {
+ minWidth,
+ maxWidth: Math.max(minWidth, Math.min(maxWidth, viewportMaxWidth))
+ };
+ }
+
+ function clampSidebarWidth(width) {
+ const { minWidth, maxWidth } = getSidebarBounds();
+ return Math.max(minWidth, Math.min(maxWidth, width));
+ }
+
+ function applySidebarWidth(width) {
+ document.documentElement.style.setProperty('--sidebar-width', `${Math.round(clampSidebarWidth(width))}px`);
+ }
+
+ function loadSidebarWidth() {
+ try {
+ const raw = localStorage.getItem(SIDEBAR_WIDTH_STORAGE_KEY);
+ if (raw === null) return null;
+ const width = Number(raw);
+ return Number.isFinite(width) ? width : null;
+ } catch {
+ return null;
+ }
+ }
+
+ function saveSidebarWidth(width) {
+ try {
+ localStorage.setItem(SIDEBAR_WIDTH_STORAGE_KEY, String(Math.round(clampSidebarWidth(width))));
+ } catch {
+ // Ignore storage failures (e.g. private browsing restrictions)
+ }
+ }
+
+ function setupSidebarResize() {
+ const savedWidth = loadSidebarWidth();
+ if (savedWidth !== null) {
+ applySidebarWidth(savedWidth);
+ }
+
+ if (!sidebarResizer) return;
+
+ let cleanupDrag = null;
+
+ const stopDrag = (pointerId) => {
+ if (cleanupDrag) {
+ cleanupDrag(pointerId);
+ cleanupDrag = null;
+ }
+ };
+
+ sidebarResizer.addEventListener('pointerdown', (e) => {
+ if (isMobileLayout()) return;
+
+ e.preventDefault();
+ const startX = e.clientX;
+ const startWidth = sidebar.getBoundingClientRect().width;
+ document.body.classList.add('sidebar-resizing');
+ sidebarResizer.setPointerCapture?.(e.pointerId);
+
+ const onPointerMove = (event) => {
+ applySidebarWidth(startWidth + (event.clientX - startX));
+ };
+
+ cleanupDrag = (pointerIdToRelease) => {
+ document.body.classList.remove('sidebar-resizing');
+ sidebarResizer.releasePointerCapture?.(pointerIdToRelease);
+ window.removeEventListener('pointermove', onPointerMove);
+ window.removeEventListener('pointerup', onPointerUp);
+ window.removeEventListener('pointercancel', onPointerCancel);
+ saveSidebarWidth(sidebar.getBoundingClientRect().width);
+ };
+
+ const onPointerUp = (event) => stopDrag(event.pointerId);
+ const onPointerCancel = (event) => stopDrag(event.pointerId);
+
+ window.addEventListener('pointermove', onPointerMove);
+ window.addEventListener('pointerup', onPointerUp);
+ window.addEventListener('pointercancel', onPointerCancel);
+ });
+
+ sidebarResizer.addEventListener('dblclick', () => {
+ if (isMobileLayout()) return;
+ applySidebarWidth(400);
+ saveSidebarWidth(400);
+ });
+
+ window.addEventListener('resize', () => {
+ if (isMobileLayout()) return;
+ applySidebarWidth(sidebar.getBoundingClientRect().width);
+ });
+ }
+
+ setupSidebarResize();
hamburger.addEventListener('click', () => {
sidebar.classList.add('open');