diff --git a/CLAUDE.md b/CLAUDE.md index 058d1bad..6904c541 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,7 +16,7 @@ When user says "COM": 1. Increment version in BOTH `package.json` AND `CLAUDE.md` 2. Run: `git add -A && git commit -m "chore: bump version to X.XXXX" && git push && npm run build && systemctl --user restart claudeman-web` -**Version**: 0.1457 (must match `package.json`) +**Version**: 0.1458 (must match `package.json`) ## Project Overview diff --git a/package.json b/package.json index 965cef77..a33cef39 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claudeman", - "version": "0.1457", + "version": "0.1458", "description": "The missing control plane for Claude Code - run 20 autonomous agents with real-time monitoring and session persistence", "type": "module", "main": "dist/index.js", diff --git a/src/web/public/app.js b/src/web/public/app.js index 9c99ec67..e4b47158 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -185,13 +185,19 @@ function getEventCoords(e) { /** * KeyboardHandler - Simple handler to scroll inputs into view when keyboard appears. * Uses focusin event and scrollIntoView - keeps it simple and reliable. + * Also handles terminal scrolling via visualViewport API. */ const KeyboardHandler = { + lastViewportHeight: 0, + keyboardVisible: false, + /** Initialize keyboard handling */ init() { // Only initialize on touch devices if (!MobileDetection.isTouchDevice()) return; + this.lastViewportHeight = window.visualViewport?.height || window.innerHeight; + // Simple focus handler - scroll input into view after keyboard appears document.addEventListener('focusin', (e) => { const target = e.target; @@ -202,6 +208,44 @@ const KeyboardHandler = { this.scrollInputIntoView(target); }, 400); }); + + // Use visualViewport to detect keyboard for terminal scrolling + if (window.visualViewport) { + window.visualViewport.addEventListener('resize', () => { + this.handleViewportResize(); + }); + } + }, + + /** Handle viewport resize (keyboard show/hide) */ + handleViewportResize() { + const currentHeight = window.visualViewport?.height || window.innerHeight; + const heightDiff = this.lastViewportHeight - currentHeight; + + // Keyboard appeared (viewport shrunk by more than 150px) + if (heightDiff > 150 && !this.keyboardVisible) { + this.keyboardVisible = true; + this.onKeyboardShow(); + } + // Keyboard hidden (viewport grew back) + else if (heightDiff < -150 && this.keyboardVisible) { + this.keyboardVisible = false; + } + + this.lastViewportHeight = currentHeight; + }, + + /** Called when keyboard appears */ + onKeyboardShow() { + // Scroll active terminal to bottom so input line is visible + setTimeout(() => { + if (typeof app !== 'undefined' && app.activeSessionId) { + const sessionData = app.sessions.get(app.activeSessionId); + if (sessionData?.terminal) { + sessionData.terminal.scrollToBottom(); + } + } + }, 100); }, /** Check if element is an input that triggers keyboard (excludes terminal) */