Conversation
Introduce a full-featured GeneratorTab component for building and exporting script configuration (script selector, CPU/RAM/Disk sliders, advanced networking/features, generate/copy/export/import, and execute). Apply visual and structural UI refactors: new glass-card styles across ScriptCard, ScriptCardList, ScriptDetailModal, Terminal and Footer; update button variants and interaction classes; add Heart icon and extra footer links; update layout to use Manrope + JetBrains Mono fonts, sticky navbar, ambient backgrounds and metadata tweaks. Wire GeneratorTab into the main page and add related icon imports. Misc: small code-style/formatting adjustments and improved deriveScriptPath / handler signatures for clarity.
Add persistent script notes and server presets, plus APT proxy settings and various UI/behavior improvements. - DB: new migration adds script_notes and server_presets tables and indexes; Prisma schema updated with ScriptNote and ServerPreset models. - Notes: new client component ScriptNotesPanel with CRUD using a new TRPC router (scriptNotes) and integration into ScriptDetailModal to show/manage private/shared notes. - APT proxy: new Next.js API route /api/settings/apt-proxy that reads/writes .env vars; GeneralSettingsModal and ConfigurationModal load/save the proxy and pre-fill advanced install vars. - UX/UI: add copyable install command, version badges on script cards/detail, container ID input in advanced configuration, and styling tweaks (glass-card-static). - Server/script detection: installedScripts router now attempts to resolve the actual Proxmox node name via SSH and relaxes ID parsing to numeric-only. - Notifications: appriseService extended to support Gotify endpoints and allow gotify:// scheme, and URL validation adjusted accordingly. These changes enable user-maintained notes/presets, persistent APT-cacher defaults, improved install UX, better server detection, and additional notification backend support.
Introduce server presets and silent batch update support across API, server, and UI. Added a new serverPresets TRPC router and wired it into the API root. ConfigurationModal now lets users save/load/delete presets tied to a server. InstalledScriptsTab adds a "Silent update" option, a sequential "Update All Containers" batch flow that runs updates with PHS_SILENT=1, and passes envVars into update executions. ScriptExecutionHandler (server.js) now accepts envVars for updates and injects export commands into both local and SSH update flows so environment flags (e.g. PHS_SILENT) are honored. Also added "updated" sort handling in ScriptsGrid, DownloadedScriptsTab and FilterBar, and small typing fixes in appriseService.
Replace usage of the shared prisma import with per-router PrismaClient instances configured with @prisma/adapter-better-sqlite3. Add getNotesDb/getPresetsDb helpers (with DATABASE_URL fallback) and update scriptNotes and serverPresets to use the new client. Also add error handling in read endpoints to return empty arrays on DB failures and ensure create/update/delete use the new client.
Convert HelpButton, ResyncButton, ServerSettingsButton and SettingsButton from labeled outline controls to compact ghost icon-only buttons with aria-labels and smaller icons/spinners for a more compact header UI. Simplify ResyncButton markup (smaller spinner/SVG, removed extra contextual text/lastSync layout) and tweak sync message styling. Add Server icon import in ServerSettingsButton. In serverPresets router, replace direct prisma calls with getPresetsDb() and use the returned db instance for all queries and mutations to support the presets DB connection.
Introduce quick filter support and visual indicators for developer/ARM scripts. Added QuickFilter type and quickFilter to FilterState (getDefaultFilters/mergeFiltersWithDefaults) and a quick-filter UI in FilterBar (All, New, Updated, In Dev, ARM). Implemented filtering logic in ScriptsGrid and added category dev counts to surface per-category "dev" counts in CategorySidebar. Added DevBadge and ArmBadge components, used in ScriptCard and ScriptDetailModal; ScriptCard also gets a subtle violet highlight when script.is_dev is true. Fixed script path generation in GeneratorTab to include a `scripts/` prefix. Minor dark-theme adjustments to .glass-card/.glass-card-static background and border-color for improved contrast.
Introduce an Appearance tab in the Settings modal to control theme, text size and layout width (default vs wide). Preferences are saved to localStorage and applied immediately via helper functions (applyTextSize/applyLayoutWidth) and a small inline script injected into <head> to apply saved settings on first paint. Add CSS utility classes for text-size variants and wire up theme buttons (using lucide icons). Also include minor cleanup: optional chaining fix in CategorySidebar and removal of an unused import in ResyncButton.
Apply consistent formatting across several components: convert single quotes to double quotes, reformat the QuickFilter union type and quick-filters array in FilterBar, adjust JSX prop and className string formatting in HelpButton, ScriptCard, ServerSettingsButton, and SettingsButton. These are cosmetic/formatting changes only and do not alter runtime behavior.
Normalize formatting and strengthen typings for Badge; convert single quotes to double, expand variant/type unions, and tidy JSX/props and helper badge components. Rework CategorySidebar: refactor CategoryIcon SVGs for readability, standardize className usage, improve collapsed-state layout and buttons, and ensure categories are filtered/sorted by count with correct icon mapping and counts display. Overall cleanup improves consistency, readability, and type safety across these components.
Introduce a modal stacking system and portal to ensure modals escape parent stacking contexts. ModalStackProvider now computes a zIndex for each registered modal and returns an unregister handle; useRegisterModal returns the zIndex. A ModalPortal component (createPortal to document.body) was added and all modal components were updated to: capture the returned zIndex, wrap their markup in <ModalPortal>, and apply the dynamic zIndex instead of a hardcoded z-50 class. This improves correct layering of multiple modals and avoids backdrop-filter / transform stacking issues.
Use ModalPortal and zIndex values from useRegisterModal across modal components to avoid hardcoded z-50 stacking. Updated ExecutionModeModal, LXCSettingsModal, PublicKeyModal, ReleaseNotesModal, SetupModal, StorageSelectionModal, and TextViewer to import ModalPortal, capture the zIndex returned by useRegisterModal, wrap modal markup in <ModalPortal>, and apply style={{ zIndex }} to backdrops; LXC result overlay uses zIndex + 10 for proper stacking. Also changed LoadingOverlay in VersionDisplay to render with createPortal(document.body) and added the import. These changes centralize stacking behavior and prevent z-index conflicts when multiple modals/overlays are present.
Update CategorySidebar.tsx to derive non-selected icon color classes from categoryIconColorMap for both the "template" and per-category icons. Selected icons still use text-primary; fallbacks preserve previous muted and group-hover classes to retain existing styling when a mapping is absent.
Refactor modal markup across many components to use a consistent wrapper structure and unified Tailwind utility ordering (moved zIndex to outer container, standardized backdrop and centering). Clean up form layouts: align icons, labels and inputs, normalize spacing, error styling, and button variants (including icon/ghost adjustments). Improve AuthModal and CloneCountInputModal UX (loading/error states, closer placement, validation), and normalize BackupWarningModal and other modal presentations. Update ConfigurationModal advanced UI: reorganize network fields and add/handle extra options (IPv6 static, gateway, MTU, MAC, VLAN, DNS), refine presets save/cancel flow, and apply general formatting/whitespace cleanups.
Fix shell escaping when building env export commands by escaping backslashes and quotes (prevents broken exported values) in ScriptExecutionHandler (two locations). Update app metadata to point to favicon files under /favicon, add site manifest, and replace the header Package icon with a next/image using the android-chrome PNG (import Image and adjust markup) for consistent asset handling.
Replace legacy root favicon.png with a full favicon set under public/favicon (android-chrome 192/512, apple-touch-icon, favicon-16x16, favicon-32x32, favicon.ico, favicon.png) and add site.webmanifest. Also add public/logo.png. This organizes favicon assets for multiple platforms and adds a webmanifest for PWA/icon declarations.
Render the script selector dropdown into document.body via createPortal to escape stacking/overflow contexts. Add triggerRef/dropdownRef, compute fixed position from the trigger on open, and attach an outside-click handler to close the dropdown. Also import useRef/useEffect and createPortal; preserve existing search, selection, and reset behaviors while adjusting z-index/positioning.
Replace favicon and logo image files with updated versions to refresh branding. Updated files: public/favicon/android-chrome-192x192.png, public/favicon/android-chrome-512x512.png, public/favicon/apple-touch-icon.png, public/favicon/favicon-16x16.png, public/favicon/favicon-32x32.png, public/favicon/favicon.ico, public/logo.png.
Add an AppearanceModal and AppearanceButton to let users change theme, text size and layout width (persisted in localStorage). Enhance FilterBar with category filtering (selectedCategory, dropdown UI, counts, and outside-click handling). Heavily refactor ScriptDetailModal: layout and visual refresh, new icons, better loading/update/delete/install flows, memoized install command, improved copy behavior, keyboard navigation between scripts (using orderedSlugs + onSelectSlug), clearer status/messages, and various performance/UX tweaks. Wire DownloadedScriptsTab to pass orderedSlugs and onSelectSlug into the ScriptDetailModal. Overall small UI/UX and state-management improvements across components.
Performance and UX improvements: memoize computed values in InstalledScriptsTab (scriptsWithStatus, filteredScripts, uniqueServers) and use useCallback/useMemo in ScriptsGrid to avoid unnecessary re-renders. Memoize ScriptCard and ScriptCardList components and tighten their ScriptCard type alias. Introduce a new SyncModal (ResyncButton) component to run/resync scripts with a progress UI and retry/close behavior, and replace the previous ResyncButton import in page.tsx. Lazy-load heavy tab components (Downloaded, Installed, Backups, Generator) with next/dynamic and add a TabSkeleton loader; consolidate tab definitions into a memoized tabs array. Misc: small prop/prop-name fixes and minor JSX formatting adjustments.
Multiple changes improving UX, reliability, and CI permissions: - Add scripts/tools/addon/arcane.sh: installer/update/uninstall helper for Arcane (Docker Compose), creates update helper and generates secrets. - Add ServerStatusIndicator component and integrate into header (src/app/_components/ServerStatusIndicator.tsx, src/app/page.tsx); adjust hero/layout to accommodate inline version + status. - Enhance GeneratorTab (src/app/_components/GeneratorTab.tsx): fetch full script details by slug, derive and apply default resource values from install_methods, and show an App Defaults info panel. - Harden repo provider detection (src/server/lib/repositoryUrlValidation.js/.ts): use URL parsing for hostname matching with safe fallback to 'custom'. - Tune client caching (src/trpc/query-client.ts): increase staleTime to 30min, set gcTime to 1h, and disable automatic refetches on mount/window focus/reconnect. - Update GitHub Actions permissions: node.js.yml grants contents: read; release-drafter.yml grants contents: write and pull-requests: read. These changes aim to provide better default resource handling for scripts, visible server reachability, more robust URL parsing, improved client-side cache behavior, and explicit workflow permissions.
Add the React prop suppressHydrationWarning to the <html> element in RootLayout (src/app/layout.tsx) to suppress hydration mismatch warnings. This helps avoid noisy console warnings when server-rendered markup and client rendering differ (e.g., due to dynamic font class injection or other runtime-only differences).
Rework GeneratorTab rendering and small UI/format fixes: tidy the scriptDetail useMemo formatting and restructure the Script Defaults block so defaults (CPU, RAM, HDD) are always shown and OS/version/variant badges render correctly. Minor formatting change to ServerStatusIndicator's fetch call and a small spacing fix on the home page title. Also add imports for getSSHService and the Server type to servers router in preparation for SSH-related functionality.
Annotate the `servers` variable with an explicit array type (id, name, ip, online) and cast `data?.servers` to that type, defaulting to an empty array. This clarifies TypeScript inference and prevents `servers` from being undefined for downstream logic without changing runtime behavior.
….log, lighten glass-card, fix dev badge
Replace the large inline SVG icon map with a compact iconPaths mapping and fallback path, simplifying CategoryIcon rendering. Tighten the dev-count badge markup/styles for better layout. Remove leftover console.debug/log statements from InstalledScriptsTab and LXCSettingsModal. Pin Next.js version to 16.2.1 in package.json (deps and devDeps). Slightly adjust dark glass-card background opacity/hover values in globals.css.
…ecific data - getAllInstalledScripts: removed SSH batchDetectContainerTypes, use DB-only heuristic (lxc_config presence) for VM/LXC detection - Defer installedScripts + backups queries until their tab is activated - Initial batch now only fires 3 fast DB queries instead of 7 (incl. SSH)
- Use splitLink to route servers.checkServersStatus through a separate non-batched httpLink. SSH queries no longer block fast DB queries from returning (was causing 14s+ batch response holding all data hostage). - Add initialization refs in ScriptsGrid and DownloadedScriptsTab so save-filter/view-mode POST effects skip their first fire after load, eliminating 2-4 unnecessary network requests per tab mount.
…unts - Restore batchDetectContainerTypes SSH calls in getAllInstalledScripts (shows real VM/LXC state, not just DB heuristic) - Route getAllInstalledScripts through splitLink (non-batched) so SSH never blocks fast DB queries - Cache installed/backups badge counts in localStorage so tabs show last-known counts instantly, updated when fresh data arrives - Query still deferred until tab is visited (no eager SSH on page load)
Make several small refactors and updates across the app: - Expand single-line early-return checks into multi-line blocks in DownloadedScriptsTab and ScriptsGrid for clarity when skipping initial effect triggers. - Update Footer links: add separate GitHub (ProxmoxVE-Local) and GitHub (ProxmoxVE) buttons and change the site link to community-scripts.org. - Minor formatting tweaks in page.tsx (useState initializer and backups ternary) for readability. - In the scripts API router, fetch script cards and metadata in parallel via Promise.all to reduce latency and return both together. These changes improve readability and slightly optimize the scripts fetch path.
Introduce a simple server-side in-memory cache for PocketBase data with a 10-minute TTL to reduce PB requests for rarely-changing data. Adds getCached/setCache helpers and a shared _cache store, and exports invalidatePbCache() to clear cached entries. Apply caching to getScriptCards, getCategories, and getScriptTypes, and call invalidatePbCache() in the resyncScripts mutation so fresh data is fetched after a resync.
GeneratorTab: add detection of locally downloaded scripts (query + mutation), compute a slug set for O(1) lookup, and gate selection/execution on download state. Update script list UI to indicate downloadable items, grayscale/opacity non-downloaded entries, and show a download confirmation modal that triggers loadScript mutation and invalidates cache. Add Loader2 and AlertTriangle icons and disable Execute when the selected script isn't downloaded. ServerStatusIndicator: change from a single aggregate dot to per-node indicators showing each host name and status (green online with ping animation, red offline). Improve handling of loading vs no-configured-servers states and update tooltip/title text for clarity.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

✍️ Description
V.1.0.0 —
Closes Issues
ServerPresetswith full CRUD, DB migration, per-server templatesScriptNotesPanel,scriptNotestRPC router,script_notesDB table/api/settings/apt-proxyrouteFilterBarwith sort options (name, date, updated)VersionDisplayin navbar with GitHub release comparisonPartially Addresses
batchDetectContainerTypesrestored with DB-only fallback heuristic; now runs non-blocking viasplitLinkNew Features
Generator Tab
install_methodswhen selecting an existing scriptScript Notes
scriptNotestRPC routerScriptNotesPanelcomponent on script detail viewscript_notesDB table (Prisma migration20260401113636)Server Presets
serverPresetstRPC router with full CRUDserver_presetsDB table (same migration)/api/settings/apt-proxyroute)Sync Modal
SyncModalwith real-time progress, stats, and retry capabilityResyncButtonAppearance Modal
SettingsModalinto standaloneAppearanceModalServer Status Indicator
ServerStatusIndicatorcomponent in navbar showing live Proxmox host reachabilitycheckServersStatustRPC procedure via SSH connectivity checkVersion Display & Release Notes
VersionDisplayin navbar with update detectionReleaseNotesModalauto-shows after version changegetVersionStatusqueries GitHub API for latest release comparisonBranding & Favicon
logo.pngassetfavicon.pngArcane Script
scripts/tools/addon/arcane.sh(220 lines)Performance Optimizations
tRPC Split Link Architecture
httpBatchLinkwithsplitLinkroutingcheckServersStatus,getAllInstalledScripts) and external API calls (getVersionStatus) route through separate non-batchedhttpLinkServer-Side PocketBase Cache
getScriptCards,getCategories,getScriptTypesPromise.all(was sequential)Deferred Tab Queries
getAllInstalledScriptsandgetAllBackupsGroupedonly fire when their tab is visitedlocalStorage— show last-known count immediately, update on tab visitLazy-Loaded Tabs
DownloadedScriptsTab,InstalledScriptsTab,BackupsTab,GeneratorTabloaded vianext/dynamicComponent Memoization
ScriptCardandScriptCardListwrapped inReact.memouseCallbackfor event handlers,useMemofor computed values throughoutpage.tsxQuery Client Tuning
staleTime: 30 min (was 5 min)gcTime: 1 hourrefetchOnWindowFocus,refetchOnMount,refetchOnReconnectall disabledEliminated Save-on-Mount
ScriptsGridandDownloadedScriptsTabno longer POSTsave-filter/view-modeback to server on mountCategorySidebar Icon Optimization
iconPaths: Record<string, string>map at module scopeUI/UX Improvements
Compact Header
Script Detail Modal Rewrite
Modal System Overhaul
ModalStackProviderwith portal support and proper z-index stackingFilter Bar Enhancements
Theme & Styling
TextViewerdark mode fix: usesvscDarkPlustheme (was invisibletomorrowtheme)Footer
Accessibility
role="button"andaria-labelonScriptCardrole="checkbox"+aria-checkedon selection checkboxesaria-labelon close buttons in 8 modals:ScriptDetailModal,ConfigurationModal,GeneralSettingsModal,HelpModal,LXCSettingsModal,AppearanceModal,DiffViewer,TextViewerSecurity
CodeQL Fixes (pushed to main)
string.includes('github.com')tonew URL().hostname === 'github.com'in both.tsand.jsfiles (fixed alerts build(deps): Bump react and @types/react #5, Wishes from Tremor #6, Add GitHub templates and configuration #7)permissions: contents: readtonode.js.yml,permissions: contents: write, pull-requests: readtorelease-drafter.yml(fixed alerts build(deps): Bump @tanstack/react-query from 5.87.4 to 5.90.2 #1, build(deps): Bump @trpc/react-query from 11.5.1 to 11.6.0 #3)Hydration Fix
suppressHydrationWarningto<html>tag inlayout.tsxCode Quality
Structured Logger Migration
console.log/console.error→logger.info/logger.errorin 5 server TS files:scripts.ts,github.ts,githubJsonService.ts,repositoryService.ts,db.tsClient Console Cleanup
console.logcalls from client componentsDependency Pinning
16.2.1(was>=16.2.1)Database Changes
New Migration:
20260401113636_add_notes_and_presetsscript_notestable: per-script notes with sharing supportserver_presetstable: reusable server configuration templatesscript_slugandserver_idSchema Additions
ScriptNoteandServerPresetmodels inschema.prismaBackend / API
New tRPC Routers
scriptNotes— CRUD for script notesserverPresets— CRUD for server presetsservers.checkServersStatus— SSH-based server reachabilityNew API Routes
GET/POST /api/settings/apt-proxy— APT proxy configurationModified Routers
scripts.getScriptCardsWithCategories— parallelized PB queriesscripts.resyncScripts— invalidates server-side PB cacheinstalledScripts.getAllInstalledScripts— SSH batch detection restored, routed non-batchedFile Summary
New files:
AppearanceModal,AppearanceButton,GeneratorTab,ScriptNotesPanel,ServerStatusIndicator,SyncModal,filterUtils.ts,scriptNotes.tsrouter,serverPresets.tsrouter,apt-proxy/route.ts, favicon assets,logo.png,arcane.shMajor rewrites:
ScriptDetailModal,ConfigurationModal,LXCSettingsModal,InstalledScriptsTab,CategorySidebar,page.tsx,globals.css🔗 Related PR / Issue
Fixes: #
✅ Prerequisites (X in brackets)
Screenshot for frontend Change
🛠️ Type of Change (X in brackets)