Commit Graph

91 Commits

Author SHA1 Message Date
Alex Blank 874873541d fix: xterm.js mobile touch scrolling via viewport CSS and stopPropagation
- Add full mobile viewport CSS: overflow-y scroll, -webkit-overflow-scrolling
  touch, overscroll-behavior-y contain, translate3d hardware accel,
  scroll-behavior smooth, touch-action pan-y
- After term.open(), find .xterm-viewport and add passive touch listeners
  that call stopPropagation() (not preventDefault) — this lets the browser
  handle native touch scrolling while preventing xterm.js internal handlers
  from interfering
- Based on xterm.js known issue #5489 and SCROLLING_FIX.md approach
2026-05-29 20:16:12 +02:00
Alex Blank ef9ac76f06 fix: remove all touch interception, let browser scroll xterm viewport natively
- xterm.js has zero touch event handlers (verified: only 1 'touch' ref in
  entire library), so it wasn't intercepting anything
- Our touch-action: none + preventDefault() combo was blocking the browser
  from scrolling the .xterm-viewport natively
- Removed all custom touch event handlers from terminal.tsx
- Removed touch-action: none from .terminal-container
- Added touch-action: pan-y to .xterm-viewport so browser allows vertical pan
- Body scroll lock (terminal-page-open) prevents page from scrolling
2026-05-29 20:08:58 +02:00
Alex Blank ca9db195de fix: document-level capture touch listeners for mobile terminal scroll
- Attach touch listeners to document with capture:true instead of container
- Check if touch target is inside terminal container before handling
- This runs before xterm.js internal handlers, giving us full control
- Add touch-action: none to terminal container to prevent browser gestures
- Lower threshold to 3px, 20px per line for responsive scrolling
2026-05-29 20:03:11 +02:00
Alex Blank c1e16f2163 fix: lock body scroll and re-add programmatic terminal touch scroll
- Add body.terminal-page-open { overflow: hidden } to prevent page scroll
- TerminalPage adds/removes 'terminal-page-open' class on body when mounted
- Re-add capture-phase touch listeners in terminal.tsx with low 3px threshold
- Call e.preventDefault() immediately when vertical gesture is detected,
  before browser compositor commits to page scroll
- Remove CSS touch-action overrides on xterm viewport (now handled in JS)
- Scroll forwarded via term.scrollLines() with 24px per line sensitivity
2026-05-29 19:57:48 +02:00
Alex Blank 61d32fa00f fix: enable native touch scrolling on xterm.js viewport for mobile
- Remove all custom touch event interception code from terminal.tsx
- After term.open(), find the internal .xterm-viewport element and set
  touchAction=pan-y and overscrollBehavior=contain via inline styles
- Add CSS targeting .xterm-viewport on mobile with touch-action: pan-y,
  -webkit-overflow-scrolling: touch, and overflow-y: auto
- Let the browser handle vertical touch panning natively instead of
  trying to intercept and manually forward events
2026-05-29 19:41:23 +02:00
Alex Blank cddb3f8ccf fix: mobile terminal scroll via capture-phase touch listeners
- Attach touch listeners to container wrapper in CAPTURE phase so they run
  before xterm.js internals stop propagation
- Add e.stopPropagation() in touchmove after handling scroll to prevent
  xterm.js from conflicting with our scroll
- Add wheel event fallback for mobile browsers that synthesize wheel from touch
- Remove touch-action: none CSS which was blocking native xterm viewport scroll
2026-05-29 19:35:42 +02:00
Alex Blank 87a938fe58 fix: mobile terminal touch scrolling direction and target
- Attach touch listeners to term.element (xterm root) instead of wrapper
- Fix scroll direction: swipe up now scrolls up (shows older buffer)
- Remove RAF indirection; scroll applied synchronously in touchmove
- Accumulate delta between events for smoother scrolling
- Lower threshold to 6px and px-per-line to 16 for better responsiveness
- Add touch-action: none to terminal container on mobile
2026-05-29 19:29:29 +02:00
Alex Blank 946ac6f66a fix: remove mobile terminal pull handle, tap terminal to toggle overlay 2026-05-29 17:29:14 +02:00
Alex Blank d713bfc5f9 fix: mobile terminal overlay status bar with auto-hide
- Replace inline header+tabs layout with position:absolute overlay
- Overlay contains: back button, session name, status dot, A-/A+ font size, exit
- Session tabs live inside the overlay below the toolbar
- Auto-hides after 3s; clicking terminal content hides it immediately
- Pull handle at top edge appears when overlay is hidden to restore it
- Terminal content always fills full viewport; overlay never resizes container
- Pass showControls=false to TerminalComponent on mobile to avoid double headers
2026-05-29 17:20:15 +02:00
Alex Blank 2b5223097f feat: filter notifications to warnings/errors/ready only and add clear-all button
Notification filtering:
- lifecycle_hooks.py: only instance.error and instance.health_changed
  with status=running generate notifications. All other lifecycle events
  (created, started, stopped, restarted, deleted) are filtered out.
- health_monitor.py: only error and unhealthy states generate notifications.
  Running/recovered state no longer creates info notifications.
- _derive_title now maps instance.health_changed to "Container ready".

Clear-all button:
- Added dismiss_all() to NotificationService
- Added DELETE /notifications endpoint for bulk dismiss
- Frontend: clearAllNotifications API, clearAll in notification context,
  "Clear all" button in notification drawer alongside "Mark all as read"
- Added CSS for .notification-clear-all with danger hover state
- Updated notification-center tests

Quality gates: pytest (21 passed), vitest (11 passed)
2026-05-29 16:42:31 +02:00
alex 2bec205a30 feat: notification center frontend core (PR-3)
- Bell icon in icon registry (Phosphor Bell)
- NotificationProvider context with polling (15s unread / 30s list)
- useNotifications() hook with optimistic updates
- NotificationCenter component: bell + badge + dropdown panel
- NotificationItem component: severity icon, title, relative time, actions
- AppShell integration: mount in header-actions, hidden on mobile
- CSS styles: dropdown, items, unread/read states, empty state
- formatRelativeTime utility (custom, no new deps)
- 25 frontend tests (9 hook + 6 item + 10 center)

Quality gates: vitest 25 passed, tsc clean, eslint clean
2026-05-29 13:17:22 +02:00
Alex Blank fe98f966d6 fix: allow Escape in terminal, exit fullscreen on click outside
- Remove global Escape key listener that intercepted Escape before
  xterm.js could receive it, breaking vim/tmux/etc.
- Add click-outside-to-exit for fullscreen: clicking on the padding
  area around .terminal-page-content or .terminal-fullscreen-header
  exits fullscreen. Clicks inside content or header are ignored.
- Add 8px padding/gap to .terminal-page.fullscreen to create a
  clickable border area around the terminal.
- Keep Exit button and Alt+Shift+F as explicit exit methods.

Quality gates: tsc --noEmit (clean), pytest (208 passed, 6 pre-existing)
2026-05-29 11:11:03 +02:00
Alex Blank f728011b2a fix: prevent cumulative terminal shrinkage in fullscreen mode
When switching terminal sessions in fullscreen mode, the viewport
shrank cumulatively because .terminal-wrapper uses
grid-template-rows: auto 1fr. With showControls=false, the single
child (.terminal-container) landed in the auto track instead of 1fr,
creating a feedback loop with xterm fit().

- Add .terminal-wrapper.no-controls with grid-template-rows: 1fr
  so the container fills the wrapper when the header is hidden.
- Apply no-controls class in TerminalComponent when showControls=false.
- Replace setTimeout(50) with double requestAnimationFrame in
  TerminalPage for more reliable fit() timing after tab switches.

Quality gates: tsc --noEmit (clean), pytest (208 passed, 6 pre-existing)
2026-05-29 10:53:02 +02:00
Alex Blank 569876538a Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter into dev 2026-05-29 10:35:47 +02:00
Alex Blank 8926152fca fix: unified fullscreen terminal header
- Add showControls prop to TerminalComponent to optionally hide internal header
- Add reset() method to TerminalRef for external reset control
- TerminalPage now renders a unified fullscreen header bar combining:
  - Session tabs (TerminalSessionTabs)
  - Terminal controls (status dot, A-, A+, Reset, Exit Fullscreen)
- Unified header is always visible in fullscreen (no hover-to-reveal)
- TerminalComponent internal header hidden when in fullscreen mode
- Remove old CSS that hid session tabs with opacity:0 until hover

Quality gates: pytest 188 passed, frontend typecheck clean

Fixes: terminal-fullscreen-unified-header
2026-05-29 10:34:31 +02:00
alex f13a63dc2f feat: container monitoring frontend UI (PR-2)
- Custom ToastContext + ToastProvider + ToastContainer (~170 lines, no deps)
- useEvents() SSE hook with exponential backoff reconnect
- EventProvider context for app-wide SSE stream sharing
- Event-to-toast bridge with severity mapping and deduplication
- Real-time status badge updates replacing 30s polling
- EventSource auth probe (401/429 detection via fetch)
- 14 frontend tests (useEvents + toast-rules)

Quality gates: vitest 14 passed, tsc clean, eslint clean
2026-05-29 10:25:00 +02:00
alex c2c983a01e fix(alembic): bridge ghost migration 2026_05_28_add_tool_definition_manifests
The production database was stamped with a migration that no longer exists
in the codebase (created on another branch, applied, then removed). This
adds a no-op bridge migration so Alembic can reconcile the DB state.

- Create bridge migration 2026_05_28_add_tool_definition_manifests (no-op)
- Re-chain terminal_sessions migration to depend on the bridge
- Fixes startup failure: Can't locate revision identified by ...
2026-05-28 14:45:15 +02:00
alex 8eb851793d feat: mobile auto-hide header and tabs for multi-session terminal
- Add useAutoHide hook to TerminalPage for mobile header/tab strip
- Header and tabs auto-hide after 3s, tap to reveal
- Add CSS transitions for smooth show/hide on mobile
- Fullscreen mobile mode hides header and tabs completely
2026-05-28 14:10:06 +02:00
alex 143a254b0c chore: add pi cache dirs to .gitignore and mobile terminal styles 2026-05-28 13:49:46 +02:00
alex 62d1bdc462 feat: multi-session terminal frontend UI + tests (PR 3)
- Add TerminalSessionTabs component with status dots, rename, close, max-5 limit
- Add 7 component tests for tab rendering, selection, close, rename
- TerminalComponent: sessionId prop, forwardRef with fit() method
- TerminalPage: multi-session orchestration, tab switching, auto-create default
- Fullscreen mode: Alt+Shift+F toggle, auto-hide tabs, Esc exit
- Keyboard shortcuts: Alt+Shift+N/W/ArrowLeft/ArrowRight/R
- Add CSS for tabs, fullscreen, mobile responsive
- Update useTerminalSessions hook for session CRUD
- terminal_manager.py: lookup by internal session_id fallback

Quality gates: tsc --noEmit clean, vitest (7/7 new tests passed), pytest (182 passed)
2026-05-28 13:35:45 +02:00
Alex Blank baabd1fa62 feat: allow creating external repositories directly from git mount editor
- Add createExternalRepository API function
- Update GitMountEditor with "+ Add new repository..." option
- Show form to enter repo name and remote URL
- Auto-create external repo and refresh list on success
- Update config-profiles page to pass onCreateRepository handler
2026-05-27 11:17:27 +02:00
Alex Blank 4c11163bff feat: implement config profile git mounts
- Add git_mounts column to config_profiles table (JSONB)
- Create GitMount Pydantic models with validation
- Add repo validation in create/update endpoints
- Update profile resolver to merge git mounts from includes
- Implement auto-clone, branch checkout, and glob expansion
- Add parallel processing for git mount resolution
- Create GitMountEditor frontend component
- Update TypeScript types and API clients
- Add CSS styles for git mount UI
- Frontend type check and build pass

Implements tasks 1.1-7.9 of config-profile-git-mounts spec
2026-05-26 22:27:04 +02:00
Alex Blank 187193fa6e fix: terminal block character rendering by setting lineHeight to 1.0 and removing container padding 2026-05-26 19:09:06 +02:00
Alex Blank cd9c9539a2 fix: improve terminal rendering by removing CSS overrides and increasing minimum font size
- Remove CSS overrides that interfere with xterm.js internal sizing
- Increase MIN_FONT_SIZE from 10 to 12 to prevent broken character rendering
- Increase default font sizes from 10/12 to 12/14 (desktop/mobile)
- Add clamping for stored font size values to prevent old tiny values
- Remove !important rules on xterm-viewport that could cause clipping
2026-05-26 16:20:22 +02:00
Alex Blank bc5e80c954 fix: add missing mobile bottom sheet styles for Tools menu 2026-05-26 12:21:52 +02:00
Alex Blank a905cf729e fix: restore original CSS and combine with mobile styles
- Restored original desktop CSS that was accidentally overwritten
- Added back all mobile-specific styles
- CSS file now 3945 lines (original + mobile styles)
- Build passes successfully
2026-05-25 13:00:47 +02:00
Alex Blank b363d89768 feat: mobile repo workspace with tabbed navigation
- Add mobile viewport detection to RepoWorkspace
- Implement bottom tab navigation (Files, Editor, Git, Terminal)
- Add repository and branch selectors for mobile
- Create mobile workspace layout with tab bar
- Add CSS styles for mobile workspace components
- Desktop layout remains unchanged
2026-05-25 12:49:15 +02:00
Alex Blank e8d5b16acc feat: mobile tool workshop with list-detail pattern
- Add mobile viewport detection to ToolWorkshopPage
- Implement mobile list view with MobileListView component
- Implement mobile detail view with MobileDetailView component
- Implement mobile edit view with MobileEditView component
- Add MobileFAB for creating new tool types
- Fix IconName type issues in mobile components
- TypeScript check passes, build succeeds
2026-05-25 12:18:24 +02:00
Fusion adaedb70ef feat: implement mobile app usability improvements
Mobile Navigation:
- Add MobileNav component with bottom tab bar
- Show mobile nav on small screens, hide desktop sidebar
- Add session count badge to Sessions tab
- Add safe area padding for notched devices

Session Management:
- Redesign SessionCard for mobile with action menu
- Add MobileActionSheet for session actions
- Keep primary action prominent

Forms & Dialogs:
- Stack form fields vertically on mobile
- Ensure 44px minimum touch targets
- Update dialogs for 320px viewport

Responsive Layout:
- Add MobilePageHeader with back button
- Reduce page padding on mobile
- Stack multi-column grids vertically

Touch & Interaction:
- Add active states to interactive elements
- Ensure 8px spacing between touch targets

Complex Pages:
- Update Repo Workspace for mobile
- Update Tool Workshop and Config Profiles

Build: TypeScript check passes, production build succeeds
2026-05-25 11:20:25 +02:00
Fusion 8fb4b67372 fix: enable terminal scrolling on mobile
- Add overflow-y: auto and -webkit-overflow-scrolling: touch to xterm-viewport
- Change touch-action from 'none' to 'pan-y' on mobile terminal wrapper and container
- This allows vertical scrolling through terminal output history while preventing zoom
2026-05-24 23:35:05 +02:00
Fusion fbd41e3eb4 fix: mobile terminal container height - use flexbox throughout
- Change .mobile-terminal-content to display: flex with flex-direction: column
- Change .terminal-wrapper.mobile to use flex: 1 instead of position: absolute
- Change .terminal-container to use flex: 1 instead of height: 100%
- Ensures proper height calculation in flex layout chain
2026-05-24 23:25:42 +02:00
Fusion 84b7b64ec0 fix: change mobile terminal wrapper from grid to flexbox
Grid layout was not properly sizing the content area, causing 0 height.
Flexbox with flex: 1 on content area ensures proper filling.
2026-05-24 23:20:51 +02:00
Fusion 245d79569e fix: use CSS Grid for mobile terminal layout to fix 0 height issue 2026-05-24 23:07:13 +02:00
Fusion 21285498ae fix: mobile terminal black screen - replace grid with flexbox layout
- Root cause: CSS Grid 1fr row got 0 height inside flex parent
- Fix: Replace grid layout with flexbox column for mobile terminal wrapper
- Header and keys strip use flex-shrink: 0
- Content area uses flex: 1 to fill remaining space
- Remove debug logging
2026-05-24 23:00:32 +02:00
Fusion 612217ad89 fix: mobile terminal black screen - grid cell had 0 height
- Root cause: .mobile-terminal-wrapper used height: 100vh inside flex parent
- Fix: Use flex: 1 instead so grid properly allocates 1fr height to content
- Add .shell.mobile-terminal-shell CSS to ensure full viewport coverage
- Remove debug logging
2026-05-24 22:51:31 +02:00
alex d8f220d825 fix: unify session loading states across pages
- Add per-item busy overlay to SessionCard component
- Remove full-screen loading overlay from sessions page
- Remove loadingAction state, use per-item busy state only
- Add handleStart to sessions page for consistency
- Add session-card CSS for busy overlay positioning
- Both home and sessions pages now use same per-item loading pattern
2026-05-24 19:33:38 +00:00
alex 760369b102 fix: constrain loading overlays to components
- Add position: relative to create-session-form-wrapper so overlay fills only the form
- Remove text from instance busy overlay, show only spinner
- Delete progress indicator now fills only the target card
2026-05-24 19:25:42 +00:00
alex 869efda214 fix: per-item loading animations in instance list
- Replace full-screen loading with per-instance busy state
- Add busy overlay with spinner to instance cards
- Disable action buttons while instance is busy
- Add CSS for visual dimming and overlay positioning

Fixes add-config-profiles: instance UI polish
2026-05-24 19:20:21 +00:00
Fusion 1060cb60ed fix: remove position override on mobile xterm to prevent layout issues 2026-05-24 20:03:56 +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 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 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 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
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 0baf7f7750 Merge branch 'dev' of ssh://git.commumedia.org:2222/alex/headquarter 2026-05-24 14:15:26 +02:00