Commit Graph

379 Commits

Author SHA1 Message Date
Fusion fc41b51bf0 Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter into dev 2026-05-24 19:59:49 +02:00
Fusion 3dbb6321fc fix: force explicit resize and add delayed refit after WebSocket connect 2026-05-24 19:59:35 +02:00
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 ca22e9c9d2 fix: reset xterm position to relative on mobile to prevent layout issues 2026-05-24 18:13:28 +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 8b4e1a7428 fix: ensure shell-content fills available viewport height
The terminal page uses height: 100% but parent .shell-content didn't
have explicit height, so the terminal couldn't fill the viewport.

Changes:
- .shell-content: added height: 100%
- .shell-body: added flex: 1 to fill flex parent
- Mobile .shell-content: added height: 100%

This ensures the terminal wrapper can properly calculate and fill
the available viewport space.
2026-05-24 17:01:15 +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 058c501e4a fix: prevent terminal from growing beyond viewport on resize
Added max-height constraints at multiple levels:
- .mobile-terminal-wrapper: max-height 100vh/100dvh
- .mobile-terminal-content: max-height 100%, min-height 0
- .terminal-container: max-height 100%
- .xterm: max-height 100%
- .xterm-viewport: max-height 100% + overflow-y auto

This prevents xterm.js from expanding the container when fit() adds rows,
which was causing an infinite growth loop on window resize.
2026-05-24 16:37:18 +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 09938bede4 Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter into dev 2026-05-24 12:45:59 +00: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
Fusion 865b9411da fix: add 'resetting' status to terminal callback types
TypeScript build failed because 'resetting' status was not included
in the onTerminalReady callback type definition.

Updated types in:
- TerminalComponent props
- MobileTerminalWrapper state and callback
- MobileTerminalHeader props
2026-05-24 14:43:27 +02:00
Fusion 48d1a7d05c Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter into dev 2026-05-24 14:39:20 +02:00
Fusion ab1d3a6aa1 fix: use CSS Grid for mobile terminal layout
Replace flexbox chains with CSS Grid to give content area definite height:
- grid-template-rows: auto 1fr auto for header/content/keys
- Use 100dvh for proper mobile viewport handling
- Terminal fills content area with position: absolute
- Remove mobile-terminal-shell wrapper (redundant)
- Content area gets real height from grid, fixing FitAddon calculations
2026-05-24 14:39:06 +02: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
Fusion 39cf01c3c9 fix: use absolute positioning for xterm.js to fill container
- Make .terminal-container position: relative with overflow: hidden
- Make xterm element absolutely positioned to fill container
- This ensures xterm.js always has concrete dimensions for fitAddon
- Remove conflicting height: 100% !important overrides
- Terminal now properly fills available space and calculates correct rows
2026-05-24 14:28:03 +02:00
Fusion c49bb028c4 fix: remove ResizeObserver to prevent infinite resize loop
The ResizeObserver triggered fit() which changed canvas dimensions,
triggering the observer again in an infinite loop. We already have
window resize handling and delayed fit() calls, so the observer was
redundant.
2026-05-24 14:23:34 +02:00
Fusion 0baf7f7750 Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter 2026-05-24 14:15:26 +02:00
Fusion 6e496e102d fix: terminal sizing and newline rendering issues
- Add ResizeObserver to terminal container for responsive sizing
  (catches keyboard open/close, header auto-hide, layout changes)
- Remove padding from mobile terminal container to maximize space
- Fix CSS: ensure xterm viewport fills container height properly
- Fix session-card.tsx TypeScript error (removed non-existent port field)
- Remove explicit xterm-viewport/xterm-screen width overrides that
  interfered with xterm.js canvas sizing
2026-05-24 14:14:45 +02: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 2f44306089 fix: ensure terminal fills entire viewport on mobile
- Add width: 100% to xterm, xterm-viewport, and xterm-screen
- Add explicit canvas display: block for proper sizing
- Remove padding from terminal-container on mobile
- Add min-height: 100% to terminal-wrapper.mobile
- Ensure xterm.js internal elements fill parent container
2026-05-24 13:31:46 +02:00
Fusion 6173d42ddf fix: allow terminal page to fill available space instead of using 100vh
- Change .terminal-page height from 100vh to 100% to fit within shell layout
- Add display: flex and min-height: 0 to .shell-content to allow flex children to expand
- Terminal container now properly fills available vertical space
2026-05-24 13:24:21 +02:00