diff --git a/CHANGELOG.md b/CHANGELOG.md index 64537af..070a373 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.10.0] - 2025-09-13 + +### Added +- Tiled View (MVP): view two sessions side‑by‑side with independent terminals and sockets. +- Resizable splitter between panes with persistent split position. +- Per‑pane session picker and close controls; layout and assignments persist in localStorage. + +### Changed +- Settings font size now applies to all visible panes in tiled view. + +### Notes +- Client‑side only; no server/CLI changes required. Default remains single‑pane; toggle via new tile button in the top bar. + +## [2.9.0] - 2025-09-13 + +### Added +- Theme toggle in Settings with persistence (Dark/Light). +- Early theme application to avoid flash of incorrect theme on load. + +### Changed +- Default theme set to Dark; Light can be selected in Settings. + +### Notes +- UI-only change; no server/CLI APIs modified. + ## [2.8.0] - 2025-09-13 ### Added @@ -133,14 +158,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Startup logs show configured aliases. - README updated with alias usage examples. -## [2.9.0] - 2025-09-13 - -### Added -- Theme toggle in Settings with persistence (Dark/Light). -- Early theme application to avoid flash of incorrect theme on load. - -### Changed -- Default theme set to Dark; Light can be selected in Settings. - -### Notes -- UI-only change; no server/CLI APIs modified. diff --git a/package-lock.json b/package-lock.json index 1416143..79bfe83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-code-web", - "version": "2.9.0", + "version": "2.10.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-code-web", - "version": "2.9.0", + "version": "2.10.0", "license": "MIT", "dependencies": { "@ngrok/ngrok": "^1.4.0", diff --git a/package.json b/package.json index dbd5592..d0d2b6b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claude-code-web", - "version": "2.9.0", + "version": "2.10.0", "description": "Web-based interface for Claude Code CLI accessible via browser", "main": "src/server.js", "bin": { diff --git a/src/public/app.js b/src/public/app.js index 69bc850..5fad65e 100644 --- a/src/public/app.js +++ b/src/public/app.js @@ -32,6 +32,7 @@ class ClaudeCodeWebInterface { this.sessionTimer = null; this.sessionTimerInterval = null; + this.paneManager = null; this.init(); } @@ -72,6 +73,8 @@ class ClaudeCodeWebInterface { this.setupTerminal(); this.setupUI(); this.setupPlanDetector(); + // Pane manager after UI exists + this.paneManager = new PaneManager(this); this.loadSettings(); this.applyAliasesToUI(); this.disablePullToRefresh(); @@ -109,6 +112,7 @@ class ClaudeCodeWebInterface { window.addEventListener('resize', () => { this.fitTerminal(); + if (this.paneManager?.enabled) this.paneManager.panes.forEach(p => p.fit()); }); window.addEventListener('beforeunload', () => { @@ -151,7 +155,7 @@ class ClaudeCodeWebInterface { // Plan modal title const planTitle = document.querySelector('#planModal .modal-header h2'); - if (planTitle) planTitle.innerHTML = ` ${this.getAlias('claude')}'s Plan`; + if (planTitle) planTitle.innerHTML = `${window.icons?.clipboard?.(18) || ''} ${this.getAlias('claude')}'s Plan`; } detectMobile() { @@ -432,6 +436,19 @@ class ClaudeCodeWebInterface { if (settingsBtn) settingsBtn.addEventListener('click', () => this.showSettings()); if (retryBtn) retryBtn.addEventListener('click', () => this.reconnect()); + // Tile view toggle + const tileToggle = document.getElementById('tileViewToggle'); + if (tileToggle) { + tileToggle.addEventListener('click', () => { + if (!this.paneManager) return; + if (this.paneManager.enabled) { + this.paneManager.disable(); + } else { + this.paneManager.enable(); + } + }); + } + // Mobile menu event listeners if (closeMenuBtn) closeMenuBtn.addEventListener('click', () => this.closeMobileMenu()); if (settingsBtnMobile) { @@ -947,6 +964,8 @@ class ClaudeCodeWebInterface { message.plan, message.limits ); + // Also refresh pane session selectors when sessions list changes + if (this.paneManager) this.paneManager.refreshSessionSelects(); break; default: @@ -1155,6 +1174,7 @@ class ClaudeCodeWebInterface { } this.terminal.options.fontSize = settings.fontSize; + if (this.paneManager?.panes) this.paneManager.panes.forEach(p => { if (p.terminal) p.terminal.options.fontSize = settings.fontSize; p.fit();}); this.fitTerminal(); } @@ -2248,5 +2268,6 @@ document.head.appendChild(style); document.addEventListener('DOMContentLoaded', () => { const app = new ClaudeCodeWebInterface(); + window.app = app; app.startHeartbeat(); }); diff --git a/src/public/index.html b/src/public/index.html index f1b3fa2..b7b804c 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -106,12 +106,21 @@ - + + + @@ -130,7 +139,7 @@