Commit Graph

189 Commits

Author SHA1 Message Date
alex 7282b91d99 Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter into dev 2026-05-24 17:58:49 +00:00
alex 9ad11a021c feat: add config profiles
- Add ConfigProfile and ConfigProfileInclude data models with migrations
- Implement profile resolver service with ordered includes and merge rules
- Add profile CRUD API with validation, compatibility, and cycle detection
- Add instance API plumbing for profile selection on create/start/restart
- Add resolved profile preview and default resolution APIs
- Add frontend config profile API client and management UI
- Add launch/restart profile selection UI
- Add backend integration and unit tests (31 passing)

OpenSpec: add-config-profiles
Quality gates: ruff, TypeScript compile, 31 tests passing
2026-05-24 17:58:39 +00:00
Fusion 3092038e40 debug: add console logging for terminal resize debugging 2026-05-24 19:44:21 +02:00
Fusion 738e01bb7c fix: add window resize fallback and delay refresh to next frame
- Add window resize listener as fallback for ResizeObserver
- Use 250ms debounce to avoid early layout reads
- Delay term.refresh() to next animation frame so renderer
  can process resize before we force redraw
- Clean up window resize listener on unmount
2026-05-24 19:31:15 +02:00
Fusion 85f04447ea fix: force xterm.js canvas redraw on resize via internal renderer 2026-05-24 18:51:15 +02:00
Fusion d931f3071d Revert "fix: add window resize listener and refresh on font size change"
This reverts commit 4a356fe88e.
2026-05-24 18:42:14 +02:00
Fusion 4a356fe88e fix: add window resize listener and refresh on font size change
- Add window resize listener to complement ResizeObserver
- Clear window resize timeout on cleanup
- Force term.refresh() after font size changes
- Send resize message after font size change
2026-05-24 18:18:41 +02:00
Fusion 4de312c170 fix: terminal resize propagation and redraw
- Frontend: Add ResizeObserver with dimension tracking for accurate resize detection
- Frontend: Fix cleanup function to properly disconnect ResizeObserver
- Frontend: Use CSS grid for terminal wrapper layout
- Backend: Add duplicate dimension check to avoid unnecessary resizes
- Backend: Ensure stty command is sent correctly to container shell
2026-05-24 17:44:00 +02:00
Fusion e7a89a853f fix: ensure terminal container fills viewport and redraws on resize
Issues fixed:
1. Terminal container now has explicit width: 100% and height: 100%
2. Added term.refresh() after fit() to force redraw when dimensions change
3. Changed shell-body from min-height to height for definite sizing
4. Added .xterm-viewport width: 100% to ensure proper filling

This ensures the terminal properly fills the viewport and redraws
content when the window is resized.
2026-05-24 17:12:32 +02:00
Fusion 7b23618ae7 fix: use requestAnimationFrame before fit() on window resize
When window resize fires, CSS layout hasn't settled yet. Adding
requestAnimationFrame ensures the browser has calculated new sizes
before xterm.js fit() reads the container dimensions. Reduced
debounce from 250ms to 100ms since rAF handles the layout timing.
2026-05-24 17:03:25 +02:00
Fusion f37813a317 revert: remove ResizeObserver and stty-on-every-resize to fix infinite loop
The ResizeObserver detected size changes caused by the stty command
output appearing in the terminal, creating an infinite resize loop:
1. Resize detected -> fit() -> send resize to backend
2. Backend sends stty command through PTY
3. stty text appears in terminal output
4. ResizeObserver detects content height change
5. fit() calculates new rows -> send resize
6. Loop continues forever

Reverted to:
- Window resize event instead of ResizeObserver
- stty command only sent once on first resize

This means the container shell stays at the initial size and won't
dynamically resize when the browser window changes, but prevents
the infinite loop.
2026-05-24 16:54:05 +02:00
Fusion 6e600fdbcd fix: use ResizeObserver for more reliable terminal resize detection
Window resize events fire before CSS layout settles, so FitAddon
was reading stale container dimensions. ResizeObserver fires after
the element actually changes size, ensuring fit() gets correct
dimensions. Reduced debounce from 250ms to 100ms for snappier response.
2026-05-24 16:50:34 +02:00
Fusion f4211ad452 chore: remove debug console.log statements from terminal component 2026-05-24 16:40:05 +02:00
Fusion 5500552993 fix: send terminal resize immediately on WebSocket connect
- Backend PTY starts with default 80x24 dimensions
- Previous code only sent resize during layout changes
- Now sends current terminal size immediately when WebSocket opens
- Ensures PTY is properly sized before shell starts rendering
2026-05-24 15:42:22 +02:00
Fusion fed49dba6d debug: add logging and simplify fit logic
- Simplified fit logic: just fit after open, after fonts load, and on resize
- Added console logging to debug what FitAddon calculates
- Single fitTerminal() function used everywhere
- Removed complex retry logic that wasn't working
2026-05-24 15:30:34 +02:00
Fusion fa17b13413 fix: wait for fonts and retry fit until proper dimensions
- Wait for document.fonts.ready before fitting (ensures correct cell metrics)
- Retry fit every 100ms if rows <= 1 or cols <= 10 (layout still settling)
- Up to 30 retries (3 seconds) for layout to stabilize
- Remove redundant delayed fits, keep only header auto-hide fit at 4s
2026-05-24 15:25:47 +02:00
Fusion 38185b9659 fix: remove container ResizeObserver causing infinite growth loop
- Container-level ResizeObserver created feedback loop with fitAddon.fit()
- Removed it, kept initialization-time dimension check only
- Rely on window resize listener for viewport changes
2026-05-24 15:19:31 +02:00
Fusion 07e7c6ea0f fix: wait for container dimensions before xterm init
- xterm docs require parent to have dimensions when open() is called
- Added ResizeObserver to wait for non-zero dimensions before initializing
- Added container ResizeObserver to handle resizes (header hide, keyboard)
- Fixed cleanup to properly disconnect observers and handle uninitialized ws
2026-05-24 15:16:11 +02:00
Fusion b638dccd36 Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter into dev 2026-05-24 15:02:56 +02:00
Fusion 8f7e19fdb1 fix: remove conflicting CSS that broke terminal sizing
- Remove second .terminal-wrapper.mobile definition that overrode position:absolute
- Add flex display to .xterm for proper viewport filling
- Add position:relative to mobile terminal-container
- Remove manual dimension setting workaround from terminal.tsx
- Root cause: CSS specificity conflict caused FitAddon to read height=0
2026-05-24 15:02:40 +02:00
alex ba76f09a1c Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter into dev 2026-05-24 12:59:36 +00:00
alex 8b08c3886c fix: prevent reconnection loop on concurrent connection close
- Don't reconnect when server closes old connection with code 4000
- Code 4000 means new connection was established, not an error
- Prevents infinite reconnection loop between old/new connections

Refs: terminal switching between 4000 error and connected
2026-05-24 12:59:28 +00:00
Fusion 5577e19782 fix: set explicit container dimensions before xterm init
- Measure parent dimensions and set them on container before term.open()
- Ensures FitAddon gets correct dimensions on initialization
- Prevents 1-row/1-col calculation that breaks scrolling and sizing
2026-05-24 14:57:03 +02:00
alex 073013bc61 feat: add heartbeat/ping to terminal WebSocket
- Backend: Send ping every 30s from WebSocket endpoint
- Frontend: Respond to pings with pongs, detect missed pings (60s timeout)
- Update type definitions to include 'resetting' status

Refs: persistent-terminal-sessions task 6.4
2026-05-24 12:45:50 +00:00
alex d1c187ab16 feat: implement persistent terminal sessions
- Terminal sessions now persist across WebSocket disconnections
- Added circular output buffer (10KB) for replay on reconnect
- Added idle timeout cleanup (30 minutes)
- Added reset functionality via WebSocket message and HTTP endpoint
- Concurrent connections close old WebSocket when new one connects
- Frontend: Added reset button with confirmation dialog
- Frontend: Handle resetting status and reconnection

Refs: persistent-terminal-sessions
2026-05-24 12:35:52 +00:00
alex 7cb88a3163 Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter into dev 2026-05-24 12:07:54 +00:00
alex ce1a73abce feat: add styles and polish for unified session list components
- Add CSS styles for SessionCard and SessionList components
- Add responsive styles for mobile viewport
- Fix TypeScript errors (remove unused port property)
- Fix ESLint errors (remove unused imports and variables)

Refs: session-list-overhaul tasks 5-6
2026-05-24 12:07:37 +00:00
Fusion 5fddc65468 Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter into dev 2026-05-24 14:05:38 +02:00
Fusion f065e2b8c0 fix: terminal sizing and container overflow
- Change .terminal-wrapper.mobile from height:100% to flex:1 for proper flex behavior
- Add explicit width/height to xterm-viewport and xterm-screen to prevent overflow
- Add delayed fit() at 4s to resize after mobile header auto-hides
- Remove min-height:100% which caused overflow issues
2026-05-24 14:05:23 +02:00
alex f4cf286bb5 Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter into dev 2026-05-24 12:03:34 +00:00
alex 549d13f469 feat: implement unified session list components
- Add SessionCard component with status indicators, actions, and confirmation dialogs
- Add SessionList component with grouping (active/recent) and filtering
- Refactor dashboard.tsx to use unified components
- Refactor sessions.tsx to use unified components
- Remove duplicated session rendering logic from both pages

Refs: session-list-overhaul tasks 1-4
2026-05-24 12:03:16 +00:00
Fusion 030a39dd5a fix: send resize message when font size changes
- After changing font size and calling fit(), send resize message to WebSocket
- OpenCode now receives correct terminal dimensions after font size adjustment
- Fixes issue where OpenCode UI didn't fill available space after font resize
2026-05-24 13:57:22 +02:00
Fusion e265c86997 fix: use flex layout for terminal container to ensure proper sizing
- Remove ResizeObserver that was causing infinite resize loop
- Add display: flex to terminal-container for proper child sizing
- Use flex: 1 on .xterm element instead of height: 100%
- Remove explicit height/width from xterm-viewport and xterm-screen
- Let flexbox handle the layout naturally
2026-05-24 13:47:40 +02:00
Fusion 74c65068c8 fix: add ResizeObserver and delayed fit for terminal sizing
- Add ResizeObserver to watch terminal container and trigger fit() on size changes
- Add delayed second fit() call 500ms after initialization
- Remove initial setTimeout resize in favor of ResizeObserver
- Ensure resizeObserver is cleaned up on unmount
2026-05-24 13:42:39 +02:00
Fusion caf11cdb8a fix: improve terminal sizing with delayed fit and flex layout
- Use double requestAnimationFrame before initial fitAddon.fit() to ensure DOM is settled
- Add display: flex to mobile-terminal-content for proper child sizing
- Add width: 100% to terminal-wrapper.mobile
- Ensure terminal fills parent container both horizontally and vertically
2026-05-24 13:38:15 +02:00
Fusion 9afd559394 fix: reduce minimum font size and prevent reconnection on font size change
- Reduce MIN_FONT_SIZE from 16 to 10 for better range
- Remove calculateFontSize from useEffect dependencies to prevent
  terminal re-initialization when font size changes
- Font size changes now update xterm options directly without
  disposing/recreating the terminal (no WebSocket reconnection)
2026-05-24 13:20:49 +02:00
Fusion 457f0d29ae fix: add safety guards to font size change and show buttons on all screen sizes
- Add null checks and try/catch around fitAddon.fit() to prevent viewport errors
- Use requestAnimationFrame to ensure DOM is stable before fitting
- Remove isMobile condition from font size buttons in TerminalComponent
- Font size controls now visible on both mobile and desktop terminals
2026-05-24 13:15:29 +02:00
Fusion 4571bebf8e feat: add font size controls to mobile terminal header and fix auto-hide space reclamation
- TerminalComponent: expose changeFontSize via onTerminalReady callback
- MobileTerminalWrapper: pass changeFontSize to header
- MobileTerminalHeader: add A- and A+ font size buttons
- CSS: collapse header height/padding/margin/border when hidden to reclaim space
2026-05-24 13:10:07 +02:00
Fusion e555561a2d fix: lift modifier state to MobileTerminalWrapper for virtual keyboard integration
- Remove useSpecialKeys hook state, export pure utility functions instead
- MobileTerminalWrapper now owns activeModifier state
- SpecialKeysStrip and SpecialKeysPanel receive modifier via props
- TerminalComponent applies modifier to virtual keyboard input via activeModifier prop
- Modifier now works with both special keys AND virtual keyboard input
- Modifier clears after any key press (special or virtual keyboard)
2026-05-24 12:45:07 +02:00
Fusion 12378def4d feat: implement one-shot modifier keys for mobile terminal
- Redesign useSpecialKeys hook with modifier state tracking
- Add one-shot activation for Ctrl and Alt keys
- Visual feedback: active modifiers shown with yellow highlight
- Fix focusInput to use term.focus() instead of hidden input
- Always refocus terminal after sending any special key
- Add requestAnimationFrame for reliable focus restoration
2026-05-24 12:28:36 +02:00
Fusion 4f9aa7e3c2 Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter into dev 2026-05-24 12:17:50 +02:00
Fusion cb25b94cb7 fix: prevent special key buttons from stealing focus
- Add tabIndex={-1} to all special key buttons to prevent focus
- Add onFocus handler to immediately blur if focused
- Terminal focus stays intact when tapping special keys
2026-05-24 12:17:35 +02:00
alex 01aaf4c78f Merge remote dev and resolve conflicts in CreateSessionForm 2026-05-24 10:16:27 +00:00
alex 96c8dd7402 feat: make session creation a sequential workflow
- Refactor CreateSessionForm into step-by-step workflow
- Steps unlock sequentially: Project → Repository → Tool → Clone Mode → Branch
- Add visual step indicators with numbered badges
- Disable controls until prerequisites are met
- Add CSS for workflow step styling
2026-05-24 10:14:39 +00:00
Fusion f5c2c95af0 fix: focus xterm terminal on tap instead of hidden input
- Use term.focus() instead of hidden input focus
- This ensures keyboard opens properly when tapping anywhere on terminal
2026-05-24 12:14:11 +02:00
Fusion 06fe8623bc fix: move hidden input off-screen and fix branch loading
- Move terminal hidden input to off-screen position (-9999px) to prevent
  text selection/caret visibility on mobile
- Add user-select: none to prevent any selection UI
- Fix create-session-form to use new listRepositoryBranches API signature
  (projectId, repoId) and access response.branches/default_branch
2026-05-24 12:11:53 +02:00
Fusion f2fed518f0 Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter into dev 2026-05-24 12:06:38 +02:00
Fusion cc2a638c76 feat: always show special keys strip on mobile terminal
- Remove auto-hide behavior for special keys strip
- Keep header auto-hide functionality
- Special keys are now always visible for quick access
2026-05-24 12:06:22 +02:00
alex 5cec4a7a6f Merge branch 'feat/session-branch-selection' into dev
Resolved conflicts:
- Moved branch selection UI from inline sessions.tsx to CreateSessionForm component
- Integrated branch dropdown and new branch creation into CreateSessionForm
- Removed duplicate branch state management from sessions.tsx

All branch selection tests pass (7/7).
2026-05-24 10:06:14 +00:00
Fusion 7e0df57f8c fix: keep virtual keyboard open when tapping special keys
- Use onPointerDown with preventDefault() instead of onClick
- Add onKeepFocus callback to SpecialKeysStrip and SpecialKeysPanel
- Expose focusInput via onTerminalReady in TerminalComponent
- MobileTerminalWrapper passes focus callback to keep keyboard open
2026-05-24 11:57:55 +02:00