diff --git a/CLAUDE.md b/CLAUDE.md index 3f481e73..50c5217c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -35,7 +35,7 @@ When user says "COM": 1. Increment version in BOTH `package.json` AND `CLAUDE.md` (verify they match with `grep version package.json && grep Version 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.1515 (must match `package.json` for npm publish) +**Version**: 0.1516 (must match `package.json` for npm publish) ## Project Overview diff --git a/package.json b/package.json index 3308b47f..b38a5441 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claudeman", - "version": "0.1515", + "version": "0.1516", "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 3b88d170..e59d5ef4 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -1472,6 +1472,15 @@ class ClaudemanApp { this.loadState(); this.loadQuickStartCases(); this.setupEventListeners(); + // Mobile settings gear: non-passive touchstart to prevent keyboard dismiss + const settingsBtn = document.querySelector('.btn-settings-mobile'); + if (settingsBtn) { + settingsBtn.addEventListener('touchstart', (e) => { + e.preventDefault(); + e.stopPropagation(); + app.openAppSettings(); + }, { passive: false }); + } // Start system stats polling this.startSystemStatsPolling(); // Setup online/offline detection @@ -14351,6 +14360,39 @@ class ClaudemanApp { const settings = this.getCaseSettings(caseName); settings.agentTeams = document.getElementById('caseAgentTeams').checked; this.saveCaseSettings(caseName, settings); + // Sync mobile checkbox + const mobileCheckbox = document.getElementById('caseAgentTeamsMobile'); + if (mobileCheckbox) mobileCheckbox.checked = settings.agentTeams; + } + + toggleCaseSettingsMobile() { + const popover = document.getElementById('caseSettingsPopoverMobile'); + if (popover.classList.contains('hidden')) { + const caseName = document.getElementById('quickStartCase').value || 'testcase'; + const settings = this.getCaseSettings(caseName); + document.getElementById('caseAgentTeamsMobile').checked = settings.agentTeams; + popover.classList.remove('hidden'); + + const closeHandler = (e) => { + if (!popover.contains(e.target) && !e.target.classList.contains('btn-case-settings-mobile')) { + popover.classList.add('hidden'); + document.removeEventListener('click', closeHandler); + } + }; + setTimeout(() => document.addEventListener('click', closeHandler), 0); + } else { + popover.classList.add('hidden'); + } + } + + onCaseSettingChangedMobile() { + const caseName = document.getElementById('quickStartCase').value || 'testcase'; + const settings = this.getCaseSettings(caseName); + settings.agentTeams = document.getElementById('caseAgentTeamsMobile').checked; + this.saveCaseSettings(caseName, settings); + // Sync desktop checkbox + const desktopCheckbox = document.getElementById('caseAgentTeams'); + if (desktopCheckbox) desktopCheckbox.checked = settings.agentTeams; } // ========== Create Case Modal ========== diff --git a/src/web/public/index.html b/src/web/public/index.html index d83c6b96..a628568b 100644 --- a/src/web/public/index.html +++ b/src/web/public/index.html @@ -303,11 +303,20 @@ Enable experimental Agent Teams for new sessions in this case - + + + +
diff --git a/src/web/public/mobile.css b/src/web/public/mobile.css index 058b5809..4948e156 100644 --- a/src/web/public/mobile.css +++ b/src/web/public/mobile.css @@ -221,15 +221,35 @@ height: 12px; } - /* Larger settings gear icon for visibility */ + /* Hide header settings gear on mobile - moved to toolbar */ .btn-icon-header.btn-settings { - width: 32px; - height: 32px; + display: none !important; } - .btn-icon-header.btn-settings svg { - width: 16px; - height: 16px; + /* Mobile app settings gear in toolbar - next to Run Claude */ + .btn-settings-mobile { + display: inline-flex !important; + align-items: center; + justify-content: center; + width: 26px; + height: 26px; + background: transparent; + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 4px; + color: #9ca3af; + cursor: pointer; + flex-shrink: 0; + order: 1; /* Right after Run Claude */ + } + + .btn-settings-mobile svg { + width: 13px; + height: 13px; + } + + .btn-settings-mobile:active { + background: rgba(255, 255, 255, 0.1); + color: #fff; } /* App container - prevent scrolling, strict layout */ @@ -469,6 +489,63 @@ max-width: 50px; } + /* Mobile case settings gear button */ + .btn-case-settings-mobile { + display: inline-flex !important; + align-items: center; + justify-content: center; + width: 26px; + height: 26px; + background: transparent; + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 4px; + color: #9ca3af; + font-size: 0.85rem; + cursor: pointer; + order: 3; + flex-shrink: 0; + position: relative; + } + + .btn-case-settings-mobile:active { + background: rgba(255, 255, 255, 0.1); + color: #fff; + } + + /* Mobile case settings popover */ + .case-settings-popover-mobile { + position: fixed; + bottom: calc(var(--safe-area-bottom) + 46px); + left: 8px; + right: 8px; + background: #1e1e1e; + border: 1px solid rgba(255, 255, 255, 0.15); + border-radius: 8px; + padding: 0.6rem 0.75rem; + z-index: 1000; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5); + display: block; + } + + .case-settings-popover-mobile.hidden { + display: none !important; + } + + .case-settings-popover-mobile .checkbox-inline { + display: flex; + align-items: center; + gap: 6px; + font-size: 0.75rem; + color: #e5e7eb; + } + + .case-settings-popover-mobile .form-hint { + display: block; + margin-top: 0.2rem; + font-size: 0.6rem; + color: #6b7280; + } + /* Keyboard Accessory Bar - quick actions above keyboard */ .keyboard-accessory-bar { display: none; diff --git a/src/web/public/styles.css b/src/web/public/styles.css index 8924e8a2..c09d52d2 100644 --- a/src/web/public/styles.css +++ b/src/web/public/styles.css @@ -1932,6 +1932,11 @@ body { color: #a8d8a8; } +/* Mobile app settings gear - hidden on desktop, shown on mobile */ +.btn-settings-mobile { + display: none; +} + /* Mobile case button - hidden on desktop, shown on mobile */ .btn-toolbar.btn-case-mobile { display: none; @@ -1957,6 +1962,19 @@ body { white-space: nowrap; } +/* Mobile case settings gear - hidden on desktop */ +.btn-case-settings-mobile { + display: none; +} + +.case-settings-popover-mobile { + display: none; +} + +.case-settings-popover-mobile.hidden { + display: none; +} + /* Button icon styling */ .btn-toolbar .btn-icon { display: inline-flex; @@ -8555,6 +8573,62 @@ kbd { max-width: 50px; } + /* Mobile case settings gear button */ + .btn-case-settings-mobile { + display: inline-flex !important; + align-items: center; + justify-content: center; + width: 26px; + height: 26px; + background: transparent; + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 4px; + color: #9ca3af; + font-size: 0.85rem; + cursor: pointer; + order: 3; + flex-shrink: 0; + position: relative; + } + + .btn-case-settings-mobile:active { + background: rgba(255, 255, 255, 0.1); + color: #fff; + } + + .case-settings-popover-mobile { + position: fixed; + bottom: calc(var(--safe-area-bottom) + 46px); + left: 8px; + right: 8px; + background: #1e1e1e; + border: 1px solid rgba(255, 255, 255, 0.15); + border-radius: 8px; + padding: 0.6rem 0.75rem; + z-index: 1000; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5); + display: block; + } + + .case-settings-popover-mobile.hidden { + display: none !important; + } + + .case-settings-popover-mobile .checkbox-inline { + display: flex; + align-items: center; + gap: 6px; + font-size: 0.75rem; + color: #e5e7eb; + } + + .case-settings-popover-mobile .form-hint { + display: block; + margin-top: 0.2rem; + font-size: 0.6rem; + color: #6b7280; + } + /* Keyboard Accessory Bar - quick actions above keyboard */ .keyboard-accessory-bar { display: none;