Skip to content

Bootstrap / jQuery Update & Fluid Infusion Removal#2915

Draft
Naenyn wants to merge 28 commits intouPortal-Project:masterfrom
Naenyn:remove_fluid
Draft

Bootstrap / jQuery Update & Fluid Infusion Removal#2915
Naenyn wants to merge 28 commits intouPortal-Project:masterfrom
Naenyn:remove_fluid

Conversation

@Naenyn
Copy link
Contributor

@Naenyn Naenyn commented Dec 24, 2025

This is a WIP PR that handles the Bootstrap & jQuery updates for uPortal. This PR also includes the removal of Fluid Infusion.

@Naenyn Naenyn marked this pull request as draft December 24, 2025 22:34
@ChristianMurphy ChristianMurphy requested a review from Copilot March 11, 2026 19:20
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This WIP PR updates uPortal’s front-end stack for Bootstrap/jQuery changes and removes Fluid Infusion by replacing legacy Fluid-based UI components with “modern” vanilla/Bootstrap 5 equivalents.

Changes:

  • Removed multiple legacy Fluid-based JavaScript components and introduced modern replacements (no-Fluid).
  • Updated many JSP/XSL templates from Bootstrap 3-era markup/classes and jQuery patterns to Bootstrap 5-compatible equivalents.
  • Switched skin build tooling from LESS to SCSS (Sass) and adjusted Gradle/WebJar resource staging.

Reviewed changes

Copilot reviewed 147 out of 193 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/up-showHideToggle.js Removed legacy Fluid-based show/hide toggle component.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/up-rating-option.js Removed legacy rating modal implementation (Fluid/old Bootstrap patterns).
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/up-parameter-editor.js Removed legacy Fluid ParameterEditor implementation.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/up-layout-selector.js Removed legacy Fluid layout selector implementation.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/up-layout-persistence.js Removed legacy Fluid layout persistence implementation.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/up-favorite.js Removed legacy jQuery-based favorites implementation.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/up-entity-registry.js Removed legacy Fluid entity registry implementation.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/up-config-lightbox.js Removed legacy jQuery config lightbox implementation.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/up-autocomplete.js Removed legacy Fluid autocomplete implementation.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/prevent-component-reload.js Added stub script placeholder for removed instrumentation.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/modern-util.js Added utility helpers intended to replace Fluid-dependent helpers.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/modern-url-provider.js Replaced legacy tooltip-conflict code with a modern URL provider and compatibility wrapper.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/modern-show-hide-toggle.js Added modern replacement for show/hide toggle with a backward-compatible up.showHideToggle.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/modern-portlet-registry.js Added modern portlet registry implementation using fetch and a small event system.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/modern-layout-preferences-persistence.js Added modern layout persistence implementation using fetch and DOM updates.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/modern-flyout-nav.js Added modern flyout navigation implementation (hover interactions).
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/modern-favorite.js Added modern favorites manager (fetch-based) with compatibility functions.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/modern-config-lightbox.js Added modern config lightbox implementation using fetch + Bootstrap Modal.
uPortal-webapp/src/main/webapp/media/skins/common/javascript/uportal/flyout-nav.js Removed legacy Fluid flyout navigation implementation.
uPortal-webapp/src/main/webapp/media/skins/common/css/modern-uploader.css Added Bootstrap-compatible uploader CSS replacement.
uPortal-webapp/src/main/webapp/media/skins/common/css/modern-portlet-list.css Added portlet list layout CSS to match expected gallery/list rendering.
uPortal-webapp/src/main/webapp/media/skins/common/css/modern-pager.css Added Bootstrap-compatible pager CSS replacement.
uPortal-webapp/src/main/webapp/media/skins/common/common_skin.xml Switched skin resources to modern JS/CSS set and removed legacy includes.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Translator/translator.jsp Updated markup/classes to Bootstrap 5 card/forms/buttons.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/TenantManager/tenantManager.jsp Converted panels/pull-right to cards/float utilities and button sizing.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/TenantManager/tenantDetails.jsp Updated validation/Bootstrap classes and layout grid usage.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/TenantManager/report.jsp Converted panels to cards and labels to badges; updated float utilities.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/TenantManager/addTenant.jsp Updated form layout and validation classes for Bootstrap 5.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Statistics/reportList.jsp Updated portlet wrapper classes to Bootstrap 5 card structure.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Statistics/reportGraph.jsp Updated portlet wrapper classes and modernized jQuery event binding.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/SqlQuery/results.jsp Updated portlet wrapper classes and replaced column filter widgets with SearchPanes.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/SqlQuery/googleLineChart.jsp Updated portlet wrapper classes to Bootstrap 5 card structure.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/SqlQuery/googleColumnChart.jsp Updated portlet wrapper classes to Bootstrap 5 card structure.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/SqlQuery/config.jsp Updated portlet wrapper classes and form layout for Bootstrap 5.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/SessionTimeout/body.jsp Updated modal dismiss attribute to data-bs-dismiss and button classes.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Search/searchRest.jsp Updated tab markup to Bootstrap 5 nav/tab patterns and float utilities.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Search/searchLauncher.jsp Updated search launcher markup and modernized submit handler binding.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Search/search.jsp Updated search portlet card layout and modernized submit handler binding.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/PortletError/maintenance.jsp Replaced Bootstrap 3 jumbotron with Bootstrap 5 equivalent container styling.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/PortletError/generic.jsp Converted legacy widget titlebar to Bootstrap 5 card and breadcrumb classes.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/PortletError/detailed.jsp Converted to Bootstrap 5 card layout and updated show/hide toggle initialization.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/PopularPortlets/listPortlets.jsp Updated card markup, label styling, pager class, and SearchPanes integration.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Marketplace/portlet/view.jsp Updated panel markup/buttons/grid classes and modernized click handlers.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Invoker/sitemap.jsp Reduced UI error surface area and changed logging behavior on sitemap failure.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Invoker/logout.jsp Updated button sizing from btn-xs to btn-sm.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Invoker/login.jsp Modernized login markup and button styling.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Invoker/greeting.jsp Updated responsive utility classes to Bootstrap 5 equivalents.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/ImportExportPortlet/export.jsp Converted portlet wrapper to card layout and updated form layout classes.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/ImportExportPortlet/delete.jsp Converted portlet wrapper to card layout and modernized submit handler binding.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/GoogleAnalytics/config.jsp Updated labels to Bootstrap 5 form-label styling.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/FragmentAdministration/index.jsp Converted portlet wrapper to card layout and updated nav list classes.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Favorites/view_zero.jsp Updated float utility class to Bootstrap 5 equivalent.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Favorites/view.jsp Updated navbar markup to Bootstrap 5 and modernized event binding.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Favorites/edit_zero.jsp Updated alert close button to Bootstrap 5 btn-close and dismiss attributes.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Favorites/edit.jsp Updated alert close button and tooltip data attributes; modernized event binding.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/DynamicRespondrSkin/skinConfig.jsp Updated Bootstrap form classes and modernized jQuery submission handling.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Directory/mobileDirectory.jsp Removed Fluid reference and modernized binding/unbinding patterns.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Directory/directory.jsp Converted portlet wrapper to card structure and updated label styling.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/BackgroundPreference/viewBackgroundPreference.jsp Updated layout utility classes and modernized event binding.
uPortal-webapp/src/main/webapp/WEB-INF/jsp/Activity/activity.jsp Updated spelling in comment and modernized event binding; converted wrapper to card.
uPortal-webapp/src/main/webapp/WEB-INF/flows/user-manager/viewUserDetails.jsp Updated markup for Bootstrap 5 and ensured impersonation POST uses preventDefault + DOM submit.
uPortal-webapp/src/main/webapp/WEB-INF/flows/user-manager/viewPermissions.jsp Updated wrapper to card layout and replaced filter widgets with SearchPanes.
uPortal-webapp/src/main/webapp/WEB-INF/flows/user-manager/selectUserAction.jsp Converted panel list to card list and updated wrapper/content classes.
uPortal-webapp/src/main/webapp/WEB-INF/flows/user-manager/confirmRemove.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/update-password/success.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/update-password/enterPassword.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/toggle-resources-aggregation/toggle-aggregation.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/snooper/snooper.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/self-edit-account/viewAccountDetails.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/self-edit-account/success.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/self-edit-account/enterPassword.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/self-edit-account/editLocalAccount.jsp Switched ParameterEditor usage to modern editor and updated form submit binding.
uPortal-webapp/src/main/webapp/WEB-INF/flows/reset-user-layout/reset-result.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/reset-user-layout/reset-confirm.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/reset-password/invalidLoginToken.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/reset-password/createPasswordSuccess.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/reset-password/createPassword.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/reset-my-layout/reset-begin.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/portlet-manager/confirmRemove.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/portal-administration/administrativeLinks.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/permissions-administration/showActivity.jsp Converted wrapper/content to card layout and replaced filter widgets with SearchPanes.
uPortal-webapp/src/main/webapp/WEB-INF/flows/permissions-administration/selectTarget.jsp Converted wrapper/content to card layout and migrated to ModernAutocomplete.
uPortal-webapp/src/main/webapp/WEB-INF/flows/permissions-administration/permissionLookupResult.jsp Converted wrapper/content to card layout and replaced filter widgets with SearchPanes.
uPortal-webapp/src/main/webapp/WEB-INF/flows/permissions-administration/listOwners.jsp Converted wrapper/content to card layout; migrated to ModernAutocomplete; updated form layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/permissions-administration/listActivities.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/permissions-administration/deletePermission.jsp Converted wrapper/content to card layout and modernized click binding.
uPortal-webapp/src/main/webapp/WEB-INF/flows/locale-selector/selectLocale.jsp Converted wrapper/content to card layout and updated form label classes.
uPortal-webapp/src/main/webapp/WEB-INF/flows/local-login/loginForm.jsp Converted wrapper/content to card layout and updated form grid classes.
uPortal-webapp/src/main/webapp/WEB-INF/flows/groups-manager/selectGroupType.jsp Converted panel list to card list and updated wrapper/content classes.
uPortal-webapp/src/main/webapp/WEB-INF/flows/fragment-audit/fragment-audit.jsp Converted wrapper/content to card layout and updated hidden template markup.
uPortal-webapp/src/main/webapp/WEB-INF/flows/fragment-administration/select-fragment-form.jsp Converted wrapper/content to card layout and updated form layout utilities.
uPortal-webapp/src/main/webapp/WEB-INF/flows/forgot-password/sendTokenSuccess.jsp Converted wrapper/content to card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/forgot-password/forgotPassword.jsp Converted wrapper/content to card layout and updated label styling.
uPortal-webapp/src/main/webapp/WEB-INF/flows/exit-fragment-administration/logout-view.jsp Updated form layout utilities and button styling.
uPortal-webapp/src/main/webapp/WEB-INF/flows/edit-portlet/configMode.jsp Converted wrapper/content to card layout and added explicit save/cancel navigation buttons.
uPortal-webapp/src/main/webapp/WEB-INF/flows/edit-portlet/chooseType.jsp Converted wrapper/content to card layout and updated form labels.
uPortal-webapp/src/main/webapp/WEB-INF/flows/edit-portlet/choosePortlet.jsp Converted wrapper/title/content to card markup and updated grid utility classes.
uPortal-webapp/src/main/webapp/WEB-INF/flows/edit-permission/editPermission.jsp Converted wrapper/content to card layout and shortened ready handler usage.
uPortal-webapp/src/main/webapp/WEB-INF/flows/edit-group/viewGroupPermissions.jsp Converted wrapper/content to card layout and replaced filter widgets with SearchPanes.
uPortal-webapp/src/main/webapp/WEB-INF/flows/edit-group/reviewGroup.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/edit-group/editDetails.jsp Converted wrapper/content to card layout and updated labels.
uPortal-webapp/src/main/webapp/WEB-INF/flows/edit-group/confirmRemove.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/edit-account/editLocalAccount.jsp Switched ParameterEditor usage to modern editor and updated label styling.
uPortal-webapp/src/main/webapp/WEB-INF/flows/cache-manager/confirm-flush.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/cache-manager/confirm-flush-all.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/cache-manager/cache-statistics.jsp Converted wrapper/content to Bootstrap 5 card layout.
uPortal-webapp/src/main/webapp/WEB-INF/flows/cache-manager/cache-list.jsp Converted wrapper/content to Bootstrap 5 card layout and updated table sizing classes.
uPortal-webapp/src/main/webapp/WEB-INF/flows/attribute-swapper/attributesForm.jsp Converted wrapper/content to Bootstrap 5 card layout and updated label classes.
uPortal-webapp/src/main/resources/properties/portal.properties Enabled flyout menus by default.
uPortal-webapp/src/main/resources/layout/theme/respondr/respondr.xsl Removed Fluid global wiring, updated event listeners, and adjusted fragment admin UI hooks.
uPortal-webapp/src/main/resources/layout/theme/respondr/regions.xsl Updated Bootstrap 5 classes and modal/hover behavior wiring.
uPortal-webapp/src/main/resources/layout/theme/respondr/navigation.xsl Updated dropdown/toggle attributes and responsive utility classes for Bootstrap 5.
uPortal-webapp/src/main/resources/layout/theme/respondr/content.xsl Updated dropdown/modal attributes for Bootstrap 5 and modernized favorites click binding.
uPortal-webapp/package.json Replaced LESS build script with Sass SCSS compilation for skin build.
uPortal-webapp/build.gradle Updated WebJar dependencies and skin aggregation pipeline; added bootstrap webjar; SCSS compilation integration.
uPortal-utils/uPortal-utils-core/build.gradle Updated resource-server dependency exclusions to avoid logging/spring conflicts.
uPortal-api/uPortal-api-internal/src/main/java/org/apereo/portal/portlets/groupadmin/GroupAdministrationHelper.java Added argument validation and guardrails around GroupService lookup.
package.json Migrated stylelint setup from LESS to SCSS.
gradle.properties Updated project version suffix and bumped Bootstrap/resource-server versions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +63 to +69
openFlyout() {
if (this.isOpen) return;

this.calculatePosition();
this.flyoutMenu.style.display = 'block';
this.isOpen = true;
}
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calculatePosition() measures this.flyoutMenu while it is still hidden (display: none), so getBoundingClientRect() will often return 0×0 and produce incorrect positioning. Set the menu to a measurable state before measuring (e.g., temporarily display: block with visibility: hidden, then position it, then show it), or measure using an approach that doesn't depend on display state.

Copilot uses AI. Check for mistakes.
<c:if test="${not empty successMessageCode}">
<div class="alert alert-success alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-hidden="true">&times;</button>
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bootstrap 5 btn-close buttons should not include &times; inner content; they render via CSS. Leaving &times; in the button can create duplicate/odd visuals and may be announced unexpectedly by assistive tech. Remove the inner text and rely on aria-label (or allow Bootstrap’s default styling) for a correct close control.

Copilot uses AI. Check for mistakes.
Comment on lines +158 to +159
// Silently fail - don't add error message to DOM or do anything that might trigger reload
console.error('Sitemap generation failed:', error.message);
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes failure handling from user-visible feedback to a silent UI failure. If the sitemap is a user-facing navigation feature, this can increase support burden because the UI will appear broken with no on-screen explanation. Consider restoring a minimal, non-intrusive message in the DOM (or an ARIA live-region alert) while still avoiding any reload-triggering behavior.

Copilot uses AI. Check for mistakes.
## render it on a maximized window state.
##
org.apereo.portal.layout.useFlyoutMenus=false
org.apereo.portal.layout.useFlyoutMenus=true
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flips the default for flyout menus from false to true, which is a user-visible behavior change and not mentioned in the PR description (Bootstrap/jQuery update + Fluid removal). If this is intentional, it should be called out explicitly (and ideally gated/migrated), otherwise consider keeping the existing default to avoid unexpected UI changes during the upgrade.

Copilot uses AI. Check for mistakes.
Comment on lines +123 to +131
// Stage 3: Copy rs directory from resource-server-content for SCSS compilation
if (webjarName == 'resource-server-content') {
doLast {
copy {
from "${buildDir}/webjars/${webjarName}-${webjarVersion}/rs"
into "${buildDir}/generated-sources/skin/main/webapp/rs"
}
}
}
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The copy source path ${buildDir}/webjars/... does not match the earlier unpack destination shown in this task (which stages WebJars under ${buildDir}/generated-sources/skin/main/webapp/webjars/...). This is likely to fail at build time (missing directory) and prevent SCSS compilation. Adjust the from path to the actual unpack location and consider avoiding nested doLast inside the dependency loop to keep task actions deterministic.

Copilot uses AI. Check for mistakes.
webjars "org.webjars.npm:regenerator-runtime:${regeneratorRuntimeVersion}"
webjars "org.webjars.npm:webcomponents__webcomponentsjs:${webComponentPolyfillVersion}"
webjars "org.webjars.npm:whatwg-fetch:${whatwgFetchPolyfillVersion}"
webjars "org.webjars:bootstrap:5.3.8"
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bootstrap is declared here with a hard-coded version, while gradle.properties already tracks bootstrapVersion. Hard-coding risks drift (e.g., SCSS paths and dependency versions diverging). Prefer using the existing version property so upgrades remain single-sourced.

Copilot uses AI. Check for mistakes.
@Naenyn Naenyn requested a review from bjagg March 16, 2026 22:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants