- Add restore.log file writing in restoreService.ts for progress tracking
- Create getRestoreProgress query endpoint for polling restore logs
- Implement polling-based progress updates in BackupsTab (1 second interval)
- Update LoadingModal to display all progress logs with auto-scroll
- Remove console.log debug output from restoreService
- Add static 'Restore in progress' text under spinner
- Show success checkmark when restore completes
- Prevent modal dismissal during restore, allow ESC/X button when complete
- Remove step prefixes from log messages for cleaner output
- Keep success/error modals open until user dismisses manually
- Add PBSStorageCredential model to database schema (fingerprint now required)
- Create PBS credentials API router with CRUD operations
- Add PBS login functionality to backup service before discovery
- Create PBSCredentialsModal component for managing credentials
- Integrate PBS credentials management into ServerStoragesModal
- Update storage service to extract PBS IP and datastore info
- Add helpful hint about finding fingerprint on PBS dashboard
- Auto-accept fingerprint during login using stored credentials
- Add Backup model to Prisma schema with fields for container_id, server_id, hostname, backup info
- Create backupService with discovery methods for local (/var/lib/vz/dump/) and storage (/mnt/pve/<storage>/dump/) backups
- Add database methods for backup CRUD operations and grouping by container
- Create backupsRouter with getAllBackupsGrouped and discoverBackups procedures
- Add BackupsTab component with collapsible cards grouped by CT_ID and hostname
- Integrate backups tab into main page navigation
- Filter storages by node hostname matching to only show applicable storages
- Skip PBS backups discovery (temporarily disabled)
- Add comprehensive logging for backup discovery process
- Add backup capability before updates or as standalone action
- Implement storage service to fetch and parse backup-capable storages from PVE nodes
- Add backup storage selection modal for user choice
- Support backup+update flow with sequential execution
- Add standalone backup option in Actions menu
- Add storage viewer in server section to show available storages
- Parse /etc/pve/storage.cfg to identify backup-capable storages
- Cache storage data for performance
- Handle backup failures gracefully (warn but allow update to proceed)
- Create filterUtils.ts with getDefaultFilters() and mergeFiltersWithDefaults()
- Update ScriptsGrid, DownloadedScriptsTab, and FilterBar to use utility functions
- Prevents crashes when loading old saved filters missing new properties
- Future-proof: new filter properties automatically get defaults
- Fixes TypeError: can't access property 'length', selectedRepositories is undefined
- Add Repository model to Prisma schema with migration
- Create repositoryService for managing repositories
- Add repositories API router with CRUD operations
- Update GitHubJsonService to support multiple repositories
- Update ScriptDownloaderService to use repository URL from scripts
- Add repository_url field to Script and ScriptCard types
- Add repository management UI tab to GeneralSettingsModal
- Display repository source on script cards and detail modal
- Implement repository deletion with JSON file cleanup
- Initialize default repositories (main and dev) on server startup
- Remove normalized slug/name matching fallback that caused false matches
- Use exact slug-to-slug matching as primary method
- Only use install basename matching for edge cases
- Prevents 'docker-vm' from appearing when only 'docker' is downloaded
- Updated validateServerAddress to handle IPv6 addresses with zone identifiers (e.g., fe80::...%eth0)
- Added validation for zone identifier (interface name)
- Updated placeholder text to include link-local address example
- Fixes issue where link-local addresses like fe80::be24:11ff:fe28:30db%eth0 were rejected
- Add 'Delete only from DB' option in Actions dropdown for SSH scripts with container_id
- Place option after 'Destroy' with separator to distinguish from destructive action
- Update handleDeleteScript to use confirmation modal for SSH scripts
- Modal clearly states it only deletes database record, container remains intact
- Allows users to clean up duplicate script entries without destroying containers
- Fixes issue where duplicates could only be removed by destroying the host
- Add version selection toggle (Default/Alpine) in TextViewer component
- Load both default and alpine versions of CT and install scripts
- Display correct script content based on selected version
- Pass script object to TextViewer to detect alpine variants
- Show toggle buttons only when alpine variant exists
- Download alpine install scripts (alpine-{slug}-install.sh) when alpine variant exists
- Add ScriptVersionModal component for version selection (default/alpine)
- Update ScriptDetailModal to show version selection before server selection
- Update script execution to use selected version type
- Support downloading both default and alpine variants of scripts
- Replace IPv4-only validation with comprehensive address validation
- Support IPv4 addresses (e.g., 192.168.1.1)
- Support IPv6 addresses including compressed format (e.g., ::1, 2001:db8::1)
- Support FQDN/hostnames (e.g., server.example.com, localhost)
- Update UI label from 'IP Address' to 'Host/IP Address'
- Update placeholder text with examples for all supported formats
- Update error messages to reflect new validation capabilities
- Add deleteScript method to ScriptDownloaderService (both .ts and .js)
- Add deleteScript API endpoint to scripts router
- Add delete button to ScriptDetailModal with confirmation modal
- Use ConfirmationModal component instead of plain window.confirm
- Delete button only shows when script files exist locally
- Includes proper error handling and success/error messages
- Removed size='icon' constraint that limited button height
- Changed positioning to use inset-y-0 with h-full to match input field height
- Added flex items-center justify-center for proper icon centering
- Fixes hover background height mismatch between light and dark themes
- Add minimize/collapse functionality to FilterBar component
- Add minimize/collapse functionality to Newest Scripts section
- Hide Newest Scripts section when user is searching, filtering, or viewing a category
- Both sections can now be minimized to save screen space
- Display port in header next to script name for better visibility
- Position port close to name/logo section
- Keep port display in Basic Information section as well
- Style port with badge-like appearance for prominence
- Improved cleanupOrphanedScripts to use pct list for more reliable container verification
- Added batch processing by server for better efficiency
- Added double-check with config file existence before deletion
- Added manual cleanup button in Installed Scripts tab for on-demand cleanup
- Improved error handling and logging throughout cleanup process
- Fixes issue where deleted containers (like Planka) were still showing in the UI
- Modified handleDownloadAllFiltered to combine filteredScripts and newestScripts when no filters are active
- Ensures all scripts including those in the 'Newest Scripts' carousel are downloaded
- Maintains existing behavior when filters are active
- Fixes issue where 'New' scripts were excluded from downloads
- Add specific error handling for GitHub API rate limit (403) errors
- Create RateLimitError with proper error name for identification
- Store last sync error and error time in settings for UI display
- Add error status display in autosync settings modal
- Show user-friendly error messages with GitHub token suggestion
- Clear error status on successful sync
- Update both GitHubJsonService and GitHubService with rate limit error handling
This provides better user feedback when GitHub API rate limits are exceeded
and guides users to set up a GitHub token for higher rate limits.
- Fix service instance management to use global instance for stopping autosync
- Add automatic saving when toggle is changed (no manual save required)
- Fix validation issue where custom sync type without cron expression caused 400 error
- Add comprehensive debugging and error handling
- Ensure .env file is properly updated with AUTO_SYNC_ENABLED value
- Improve service lifecycle management with proper state cleanup
- Add fallback logic for invalid sync interval configurations
Resolves issue where disabling autosync in GUI didn't update .env file or stop service
- Fix type signature mismatch in handleCardClick functions
- Updated ScriptsGrid.tsx and DownloadedScriptsTab.tsx to accept ScriptCardType instead of { slug: string }
- This resolves the modal not opening when clicking script cards
- Fix server-side import issues
- Updated autoSyncService.js to import from githubJsonService.ts instead of .js
- Fixed path aliases in githubJsonService.ts to use relative imports
- Updated scripts.ts to import from TypeScript service files directly
- Fix missing Install button
- Resolved scriptDownloaderService.checkScriptExists method not being available
- Install button now appears when script files exist locally
- Remove debug logging
- Cleaned up temporary console.log statements and debug UI elements
All script card interactions now work properly:
- Cards open detail modal when clicked
- Install button appears when appropriate
- Server-side API calls work correctly
- Fixed custom cron input field to be properly editable with autoFocus
- Added helpful cron examples and better validation feedback
- Fixed cron validation to work with 5-field expressions (node-cron format)
- Added auto-sync rescheduling when settings are saved via API route
- Improved user experience with better error handling and examples
The custom cron input now works properly and auto-sync will reschedule
immediately when settings are saved, including custom cron expressions.
- Darkened OFF state background (gray-300/gray-700)
- Added border to track for better definition
- Enhanced knob contrast with shadow
- Changed ON state to vibrant blue (blue-500/blue-600) for better visibility
- Makes toggle states immediately distinguishable at a glance
- Map 'turnkey' script type to 'ct' category in filtering logic
- Fixes issue where filtering by all 4 types showed 398/399 instead of 399/399
- Applied to both DownloadedScriptsTab and ScriptsGrid components
- TurnKey script is LXC-related so mapping to 'ct' is appropriate
- Add normalizeId helper to compare local filenames with script slugs/names
- Include install_basenames from install_methods for robust matching
- Fix false 'Not Downloaded' status for PVE Host scripts like 'PVE LXC Execute Command'
- Update DownloadedScriptsTab and ScriptsGrid to use normalized comparisons
- Resolves issue where scripts with underscores in filenames (e.g., pbs_microcode.sh)
weren't matching JSON slugs with hyphens (e.g., pbs-microcode)
* feat: implement light/dark mode theme system
- Add semantic color CSS variables (success, warning, info, error) for both themes
- Create ThemeProvider with React context and localStorage persistence
- Add ThemeToggle component with sun/moon icons for header region
- Add theme switcher in General Settings modal
- Replace 200+ hardcoded Tailwind colors with CSS variables across 30+ components
- Update layout.tsx to remove forced dark mode
- Keep terminal colors unchanged as requested
- Default to dark mode, with seamless light/dark switching
Components updated:
- High-priority: InstalledScriptsTab, ScriptInstallationCard, LXCSettingsModal, ScriptsGrid
- All remaining component files with hardcoded colors
- UI components: button, toggle, badge variants
- Modal components: ErrorModal, ConfirmationModal, AuthModal, SetupModal
- Form components: ServerForm, FilterBar, CategorySidebar
- Display components: ScriptCard, ScriptCardList, DiffViewer, TextViewer
Theme switchers:
- Header: Small nuanced toggle in top-right
- Settings: Detailed Light/Dark selection in General Settings
* fix: resolve ESLint warnings
- Fix missing dependencies in useCallback and useEffect hooks
- Prefix unused parameter with underscore to satisfy ESLint rules
- Build now completes without warnings
* fix: improve toggle component styling for better visibility
- Use explicit gray colors instead of CSS variables for toggle background
- Ensure proper contrast in both light and dark modes
- Toggle switches now display correctly with proper visual states
* fix: improve toggle visual states for better UX
- Use explicit conditional styling instead of peer classes
- Active toggles now clearly show primary color background
- Inactive toggles show gray background for clear distinction
- Much easier to tell which toggles are on/off at a glance
* fix: improve toggle contrast in dark mode
- Change inactive toggle background from gray-700 to gray-600 for better visibility
- Add darker border color (gray-500) for toggle handle in dark mode
- Toggles now have proper contrast against dark backgrounds
- Both light and dark modes now have clear visual distinction
* fix: resolve dependency loop and improve dropdown styling
- Fix circular dependency in InstalledScriptsTab status check
- Remove fetchContainerStatuses function and inline logic in useEffect
- Make all dropdown menu items grey with consistent hover effects
- Update both ScriptInstallationCard and InstalledScriptsTab dropdowns
- Remove unused useCallback import
- Build now completes without warnings or errors
* fix: restore proper button colors and eliminate dependency loop
- Restore red color for Stop/Destroy buttons and green for Start buttons
- Fix circular dependency by using ref for containerStatusMutation
- Update both InstalledScriptsTab and ScriptInstallationCard dropdowns
- Maintain grey color for other menu items (Update, Shell, Open UI, etc.)
- Build now completes without warnings or dependency loops
* feat: add missing hover utility classes for semantic colors
- Add hover states for success, warning, info, error colors
- Add hover:bg-success/20, hover:bg-error/20, etc. classes
- Add hover:text-success-foreground, hover:text-error-foreground classes
- Start/Stop and Destroy buttons now have proper hover effects
- All dropdown menu items now have consistent hover behavior
* feat: improve status cards with useful LXC container information
- Replace useless 'Successful/Failed/In Progress' cards with meaningful data
- Show 'Running LXC' count in green (actual running containers)
- Show 'Stopped LXC' count in red (actual stopped containers)
- Keep 'Total Installations' for overall count
- Change layout from 4 columns to 3 columns for better spacing
- Status cards now show real-time container states instead of installation status
* style: center content in status cards
- Add text-center class to each individual status card
- Numbers and labels now centered within each card
- Improves visual balance and readability
- All three cards (Total, Running LXC, Stopped LXC) now have centered content
- Add horizontal scrollable carousel for 6 newest scripts
- Only show when no filters are active to avoid duplication
- Exclude newest scripts from main grid when carousel is visible
- Add Clock icon and subtle left border accent for visual distinction
- Include NEW badges on script cards in carousel
- Responsive design for mobile, tablet, and desktop
- Sort by date_created field in descending order
* fix: increase IP input box width in installedScripts table
- Changed IP input field width from w-32 (128px) to w-40 (160px)
- Fixes truncation issue for IP addresses in format 123.123.123.123
- Affects Web UI column in desktop table view when editing scripts
* fix: improve SSH key handling and public key modal UX
- Fix SSH key import to automatically trim trailing whitespace and empty lines
- Add 'View Public Key' button in ServerForm for generated key pairs
- Reduce public key textarea size from 120px to 60px min-height
- Add quick command section with pre-filled echo command for authorized_keys
- Improve user experience with one-click copy functionality for both key and command
- Add automatic disk resizing when changing LXC disk size in settings
- Implement separate modal flow: confirmation -> loading -> result -> settings
- Add proper error detection for pct resize command (check both exit code and output)
- Add LVM fallback resize method when pct resize fails
- Implement configuration rollback on resize failure
- Update modal styling to use semantic color classes for proper dark mode support
- Add data refresh after result modal close to show updated values
- Remove success/error banners from settings modal for cleaner UI
* refactor: migrate from better-sqlite3 to Prisma
- Install Prisma dependencies and initialize with SQLite
- Create Prisma schema matching existing database structure
- Replace database.js with Prisma-based database service
- Update all API routes, tRPC routers, and WebSocket handler
- Convert TypeScript types to match Prisma schema
- Update build process to include Prisma migrations
- Remove better-sqlite3 dependency
All database operations now use Prisma while maintaining SQLite backend.
* fix: flatten server data in installed scripts API responses
- Transform Prisma nested server objects to flattened fields expected by frontend
- Update getAllInstalledScripts, getInstalledScriptsByServer, and getInstalledScriptById
- Server names should now display correctly in the installed scripts table
- Use nullish coalescing operators for better null handling
* fix: ensure DATABASE_URL is set in .env for Prisma during updates
- Add ensure_database_url() function to update.sh
- Function checks if .env exists and creates from .env.example if needed
- Automatically adds DATABASE_URL if not present
- Call function after restore_backup_files() in update flow
- Fixes Prisma client generation error during updates