@omega.js/desktop 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +98 -0
- package/README.md +166 -0
- package/bin/omega +2 -0
- package/bin/omega-desktop +2 -0
- package/bin/omg +2 -0
- package/dist/assets/css/core/_fontawesome.scss +146 -0
- package/dist/assets/css/core/_initialize.scss +38 -0
- package/dist/assets/css/omega-desktop.scss +39 -0
- package/dist/assets/css/shell/_index.scss +207 -0
- package/dist/assets/css/tokens/_index.scss +166 -0
- package/dist/assets/js/bootstrap.bundle.js +1 -0
- package/dist/assets/js/core/app-shell.js +136 -0
- package/dist/assets/themes/_template/README.md +115 -0
- package/dist/assets/themes/_template/_config.scss +60 -0
- package/dist/assets/themes/_template/_theme.js +14 -0
- package/dist/assets/themes/_template/_theme.scss +28 -0
- package/dist/assets/themes/_template/css/base/_root.scss +19 -0
- package/dist/assets/themes/_template/css/components/_components.scss +23 -0
- package/dist/assets/themes/base/README.md +5 -0
- package/dist/assets/themes/base/_components/data/org-chart/component.html +33 -0
- package/dist/assets/themes/base/_components/data/org-chart/component.json5 +33 -0
- package/dist/assets/themes/base/_components/data/org-chart/component.scss +183 -0
- package/dist/assets/themes/base/_components/heading/masthead/component.html +22 -0
- package/dist/assets/themes/base/_components/heading/masthead/component.json5 +30 -0
- package/dist/assets/themes/base/_components/heading/section-head/component.html +18 -0
- package/dist/assets/themes/base/_components/heading/section-head/component.json5 +27 -0
- package/dist/assets/themes/base/_components/pricing/features/component.html +29 -0
- package/dist/assets/themes/base/_components/pricing/features/component.json5 +30 -0
- package/dist/assets/themes/base/_hero/orbit/index.html +30 -0
- package/dist/assets/themes/base/_hero/orbit/script.js +33 -0
- package/dist/assets/themes/base/_hero/orbit/style.scss +133 -0
- package/dist/assets/themes/base/_includes/admin/sections/sidebar.html +3 -0
- package/dist/assets/themes/base/_includes/admin/sections/topbar.html +3 -0
- package/dist/assets/themes/base/_includes/backend/sections/sidebar.html +3 -0
- package/dist/assets/themes/base/_includes/backend/sections/topbar.html +3 -0
- package/dist/assets/themes/base/_includes/frontend/components/connection-card.html +49 -0
- package/dist/assets/themes/base/_includes/frontend/components/post-card.html +54 -0
- package/dist/assets/themes/base/_includes/frontend/sections/account-connections.html +42 -0
- package/dist/assets/themes/base/_includes/frontend/sections/account-section-header.html +11 -0
- package/dist/assets/themes/base/_includes/frontend/sections/footer.html +154 -0
- package/dist/assets/themes/base/_includes/frontend/sections/nav.html +276 -0
- package/dist/assets/themes/base/_includes/global/sections/account.html +72 -0
- package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +248 -0
- package/dist/assets/themes/base/_includes/global/sections/app-topbar.html +228 -0
- package/dist/assets/themes/base/_includes/global/sections/page-header.html +99 -0
- package/dist/assets/themes/base/_layouts/admin/core/minimal-viewport-locked.html +22 -0
- package/dist/assets/themes/base/_layouts/admin/core/minimal.html +23 -0
- package/dist/assets/themes/base/_layouts/backend/core/base.html +57 -0
- package/dist/assets/themes/base/_layouts/backend/core/minimal-viewport-locked.html +32 -0
- package/dist/assets/themes/base/_layouts/backend/core/minimal.html +32 -0
- package/dist/assets/themes/base/_layouts/backend/pages/dashboard/index.html +230 -0
- package/dist/assets/themes/base/_layouts/frontend/core/base.html +31 -0
- package/dist/assets/themes/base/_layouts/frontend/core/cover.html +40 -0
- package/dist/assets/themes/base/_layouts/frontend/core/minimal.html +47 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/404.html +54 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/about.html +144 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +2104 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/alternative.html +319 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +186 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/app.html +142 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/auth/reset.html +53 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/auth/signin.html +90 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/auth/signup.html +141 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/auth/token.html +44 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/categories/category.html +88 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/categories/index.html +88 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/index.html +255 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/post.html +261 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/index.html +84 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/tag.html +88 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/collection/category.html +72 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/collection/document.html +54 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/collection/index.html +84 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/connections/callback.html +55 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/contact.html +214 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/download.html +793 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/extension/index.html +253 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/extension/installed.html +198 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/feedback.html +171 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/index.html +66 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/legal/document.html +78 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/payment/checkout.html +459 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/payment/confirmation.html +131 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/portal/email-preferences.html +104 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/pricing.html +596 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/status.html +361 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/team/index.html +210 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/team/member.html +125 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/updates/index.html +119 -0
- package/dist/assets/themes/base/_layouts/frontend/pages/updates/update.html +118 -0
- package/dist/assets/themes/base/_sections/about/hero/section.html +68 -0
- package/dist/assets/themes/base/_sections/about/hero/section.json5 +58 -0
- package/dist/assets/themes/base/_sections/about/letter/section.html +60 -0
- package/dist/assets/themes/base/_sections/about/letter/section.json5 +56 -0
- package/dist/assets/themes/base/_sections/about/photo-band/section.html +24 -0
- package/dist/assets/themes/base/_sections/about/photo-band/section.json5 +23 -0
- package/dist/assets/themes/base/_sections/about/principles/section.html +17 -0
- package/dist/assets/themes/base/_sections/about/principles/section.json5 +34 -0
- package/dist/assets/themes/base/_sections/about/timeline/section.html +20 -0
- package/dist/assets/themes/base/_sections/about/timeline/section.json5 +34 -0
- package/dist/assets/themes/base/_sections/marketing/bento/section.html +91 -0
- package/dist/assets/themes/base/_sections/marketing/bento/section.json5 +152 -0
- package/dist/assets/themes/base/_sections/marketing/cta/section.html +44 -0
- package/dist/assets/themes/base/_sections/marketing/cta/section.json5 +47 -0
- package/dist/assets/themes/base/_sections/marketing/faq/section.html +52 -0
- package/dist/assets/themes/base/_sections/marketing/faq/section.json5 +68 -0
- package/dist/assets/themes/base/_sections/marketing/hero/section.html +349 -0
- package/dist/assets/themes/base/_sections/marketing/hero/section.json5 +335 -0
- package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.html +38 -0
- package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.js +86 -0
- package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.json5 +29 -0
- package/dist/assets/themes/base/_sections/marketing/pricing-cards/section.html +115 -0
- package/dist/assets/themes/base/_sections/marketing/pricing-cards/section.json5 +72 -0
- package/dist/assets/themes/base/_sections/marketing/product-demo/section.html +62 -0
- package/dist/assets/themes/base/_sections/marketing/product-demo/section.js +44 -0
- package/dist/assets/themes/base/_sections/marketing/product-demo/section.json5 +52 -0
- package/dist/assets/themes/base/_sections/marketing/prose/section.html +22 -0
- package/dist/assets/themes/base/_sections/marketing/prose/section.json5 +41 -0
- package/dist/assets/themes/base/_sections/marketing/showcase/section.html +35 -0
- package/dist/assets/themes/base/_sections/marketing/showcase/section.json5 +52 -0
- package/dist/assets/themes/base/_sections/marketing/stats/section.html +32 -0
- package/dist/assets/themes/base/_sections/marketing/stats/section.json5 +44 -0
- package/dist/assets/themes/base/_sections/marketing/testimonials/section.html +54 -0
- package/dist/assets/themes/base/_sections/marketing/testimonials/section.json5 +70 -0
- package/dist/assets/themes/base/_sections/marketing/trusted-by/section.html +30 -0
- package/dist/assets/themes/base/_sections/marketing/trusted-by/section.json5 +38 -0
- package/dist/assets/themes/base/_sections/verts/unit/section.html +7 -0
- package/dist/assets/themes/base/_sections/verts/unit/section.js +22 -0
- package/dist/assets/themes/base/_sections/verts/unit/section.json5 +24 -0
- package/dist/assets/themes/base/_sections/verts/unit/section.scss +24 -0
- package/dist/assets/themes/base/_theme.js +13 -0
- package/dist/assets/themes/base/_theme.scss +4 -0
- package/dist/assets/themes/bootstrap/_theme.js +16 -0
- package/dist/assets/themes/bootstrap/_theme.scss +11 -0
- package/dist/assets/themes/bootstrap/js/index.esm.js +19 -0
- package/dist/assets/themes/bootstrap/js/index.umd.js +34 -0
- package/dist/assets/themes/bootstrap/js/src/alert.js +87 -0
- package/dist/assets/themes/bootstrap/js/src/base-component.js +86 -0
- package/dist/assets/themes/bootstrap/js/src/button.js +72 -0
- package/dist/assets/themes/bootstrap/js/src/carousel.js +474 -0
- package/dist/assets/themes/bootstrap/js/src/collapse.js +297 -0
- package/dist/assets/themes/bootstrap/js/src/dom/data.js +55 -0
- package/dist/assets/themes/bootstrap/js/src/dom/event-handler.js +317 -0
- package/dist/assets/themes/bootstrap/js/src/dom/manipulator.js +71 -0
- package/dist/assets/themes/bootstrap/js/src/dom/selector-engine.js +126 -0
- package/dist/assets/themes/bootstrap/js/src/dropdown.js +458 -0
- package/dist/assets/themes/bootstrap/js/src/modal.js +378 -0
- package/dist/assets/themes/bootstrap/js/src/offcanvas.js +282 -0
- package/dist/assets/themes/bootstrap/js/src/popover.js +97 -0
- package/dist/assets/themes/bootstrap/js/src/scrollspy.js +296 -0
- package/dist/assets/themes/bootstrap/js/src/tab.js +315 -0
- package/dist/assets/themes/bootstrap/js/src/toast.js +224 -0
- package/dist/assets/themes/bootstrap/js/src/tooltip.js +632 -0
- package/dist/assets/themes/bootstrap/js/src/util/backdrop.js +151 -0
- package/dist/assets/themes/bootstrap/js/src/util/component-functions.js +35 -0
- package/dist/assets/themes/bootstrap/js/src/util/config.js +65 -0
- package/dist/assets/themes/bootstrap/js/src/util/focustrap.js +115 -0
- package/dist/assets/themes/bootstrap/js/src/util/index.js +306 -0
- package/dist/assets/themes/bootstrap/js/src/util/sanitizer.js +117 -0
- package/dist/assets/themes/bootstrap/js/src/util/scrollbar.js +114 -0
- package/dist/assets/themes/bootstrap/js/src/util/swipe.js +146 -0
- package/dist/assets/themes/bootstrap/js/src/util/template-factory.js +160 -0
- package/dist/assets/themes/bootstrap/overrides/_accordion.scss +21 -0
- package/dist/assets/themes/bootstrap/overrides/_avatars.scss +51 -0
- package/dist/assets/themes/bootstrap/overrides/_blog-images.scss +45 -0
- package/dist/assets/themes/bootstrap/overrides/_buttons-adaptive.scss +141 -0
- package/dist/assets/themes/bootstrap/overrides/_color-shades.scss +25 -0
- package/dist/assets/themes/bootstrap/overrides/_cursor-utilities.scss +13 -0
- package/dist/assets/themes/bootstrap/overrides/_index.scss +30 -0
- package/dist/assets/themes/bootstrap/overrides/_links.scss +26 -0
- package/dist/assets/themes/bootstrap/overrides/_soft-colors.scss +99 -0
- package/dist/assets/themes/bootstrap/overrides/_spacing-extended.scss +74 -0
- package/dist/assets/themes/bootstrap/overrides/_spinners.scss +22 -0
- package/dist/assets/themes/bootstrap/overrides/_typography-utilities.scss +40 -0
- package/dist/assets/themes/bootstrap/scss/_accordion.scss +153 -0
- package/dist/assets/themes/bootstrap/scss/_alert.scss +68 -0
- package/dist/assets/themes/bootstrap/scss/_badge.scss +38 -0
- package/dist/assets/themes/bootstrap/scss/_breadcrumb.scss +40 -0
- package/dist/assets/themes/bootstrap/scss/_button-group.scss +147 -0
- package/dist/assets/themes/bootstrap/scss/_buttons.scss +216 -0
- package/dist/assets/themes/bootstrap/scss/_card.scss +238 -0
- package/dist/assets/themes/bootstrap/scss/_carousel.scss +226 -0
- package/dist/assets/themes/bootstrap/scss/_close.scss +66 -0
- package/dist/assets/themes/bootstrap/scss/_containers.scss +41 -0
- package/dist/assets/themes/bootstrap/scss/_dropdown.scss +250 -0
- package/dist/assets/themes/bootstrap/scss/_forms.scss +9 -0
- package/dist/assets/themes/bootstrap/scss/_functions.scss +302 -0
- package/dist/assets/themes/bootstrap/scss/_grid.scss +39 -0
- package/dist/assets/themes/bootstrap/scss/_helpers.scss +12 -0
- package/dist/assets/themes/bootstrap/scss/_images.scss +42 -0
- package/dist/assets/themes/bootstrap/scss/_list-group.scss +199 -0
- package/dist/assets/themes/bootstrap/scss/_maps.scss +174 -0
- package/dist/assets/themes/bootstrap/scss/_mixins.scss +42 -0
- package/dist/assets/themes/bootstrap/scss/_modal.scss +240 -0
- package/dist/assets/themes/bootstrap/scss/_nav.scss +197 -0
- package/dist/assets/themes/bootstrap/scss/_navbar.scss +289 -0
- package/dist/assets/themes/bootstrap/scss/_offcanvas.scss +147 -0
- package/dist/assets/themes/bootstrap/scss/_pagination.scss +109 -0
- package/dist/assets/themes/bootstrap/scss/_placeholders.scss +51 -0
- package/dist/assets/themes/bootstrap/scss/_popover.scss +196 -0
- package/dist/assets/themes/bootstrap/scss/_progress.scss +68 -0
- package/dist/assets/themes/bootstrap/scss/_reboot.scss +611 -0
- package/dist/assets/themes/bootstrap/scss/_root.scss +187 -0
- package/dist/assets/themes/bootstrap/scss/_spinners.scss +85 -0
- package/dist/assets/themes/bootstrap/scss/_tables.scss +171 -0
- package/dist/assets/themes/bootstrap/scss/_toasts.scss +73 -0
- package/dist/assets/themes/bootstrap/scss/_tooltip.scss +119 -0
- package/dist/assets/themes/bootstrap/scss/_transitions.scss +27 -0
- package/dist/assets/themes/bootstrap/scss/_type.scss +106 -0
- package/dist/assets/themes/bootstrap/scss/_utilities.scss +806 -0
- package/dist/assets/themes/bootstrap/scss/_variables-dark.scss +102 -0
- package/dist/assets/themes/bootstrap/scss/_variables.scss +1753 -0
- package/dist/assets/themes/bootstrap/scss/bootstrap-grid.scss +62 -0
- package/dist/assets/themes/bootstrap/scss/bootstrap-reboot.scss +10 -0
- package/dist/assets/themes/bootstrap/scss/bootstrap-utilities.scss +19 -0
- package/dist/assets/themes/bootstrap/scss/bootstrap.scss +52 -0
- package/dist/assets/themes/bootstrap/scss/forms/_floating-labels.scss +97 -0
- package/dist/assets/themes/bootstrap/scss/forms/_form-check.scss +189 -0
- package/dist/assets/themes/bootstrap/scss/forms/_form-control.scss +214 -0
- package/dist/assets/themes/bootstrap/scss/forms/_form-range.scss +91 -0
- package/dist/assets/themes/bootstrap/scss/forms/_form-select.scss +80 -0
- package/dist/assets/themes/bootstrap/scss/forms/_form-text.scss +11 -0
- package/dist/assets/themes/bootstrap/scss/forms/_input-group.scss +132 -0
- package/dist/assets/themes/bootstrap/scss/forms/_labels.scss +36 -0
- package/dist/assets/themes/bootstrap/scss/forms/_validation.scss +12 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_clearfix.scss +3 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_color-bg.scss +7 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_colored-links.scss +30 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_focus-ring.scss +5 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_icon-link.scss +25 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_position.scss +36 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_ratio.scss +26 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_stacks.scss +15 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_stretched-link.scss +15 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_text-truncation.scss +7 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_visually-hidden.scss +8 -0
- package/dist/assets/themes/bootstrap/scss/helpers/_vr.scss +8 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_alert.scss +18 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_backdrop.scss +14 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_banner.scss +7 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_border-radius.scss +78 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_box-shadow.scss +18 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_breakpoints.scss +127 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_buttons.scss +70 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_caret.scss +69 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_clearfix.scss +9 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_color-mode.scss +21 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_color-scheme.scss +7 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_container.scss +11 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_deprecate.scss +10 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_forms.scss +163 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_gradients.scss +47 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_grid.scss +151 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_image.scss +16 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_list-group.scss +26 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_lists.scss +7 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_pagination.scss +10 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_reset-text.scss +17 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_resize.scss +6 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_table-variants.scss +24 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_text-truncate.scss +8 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_transition.scss +26 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_utilities.scss +97 -0
- package/dist/assets/themes/bootstrap/scss/mixins/_visually-hidden.scss +38 -0
- package/dist/assets/themes/bootstrap/scss/tests/jasmine.js +16 -0
- package/dist/assets/themes/bootstrap/scss/tests/mixins/_auto-import-of-variables-dark.test.scss +7 -0
- package/dist/assets/themes/bootstrap/scss/tests/mixins/_color-modes.test.scss +69 -0
- package/dist/assets/themes/bootstrap/scss/tests/mixins/_media-query-color-mode-full.test.scss +8 -0
- package/dist/assets/themes/bootstrap/scss/tests/mixins/_utilities.test.scss +393 -0
- package/dist/assets/themes/bootstrap/scss/tests/sass-true/register.js +14 -0
- package/dist/assets/themes/bootstrap/scss/tests/sass-true/runner.js +17 -0
- package/dist/assets/themes/bootstrap/scss/tests/utilities/_api.test.scss +75 -0
- package/dist/assets/themes/bootstrap/scss/utilities/_api.scss +47 -0
- package/dist/assets/themes/bootstrap/scss/vendor/_rfs.scss +348 -0
- package/dist/assets/themes/classy/README.md +89 -0
- package/dist/assets/themes/classy/_config.scss +245 -0
- package/dist/assets/themes/classy/_theme.js +31 -0
- package/dist/assets/themes/classy/_theme.scss +57 -0
- package/dist/assets/themes/classy/css/app/_panels.scss +183 -0
- package/dist/assets/themes/classy/css/base/_fonts.scss +79 -0
- package/dist/assets/themes/classy/css/base/_no-raise.scss +49 -0
- package/dist/assets/themes/classy/css/base/_root.scss +113 -0
- package/dist/assets/themes/classy/css/base/_typography.scss +154 -0
- package/dist/assets/themes/classy/css/base/_utilities.scss +284 -0
- package/dist/assets/themes/classy/css/components/_alerts.scss +51 -0
- package/dist/assets/themes/classy/css/components/_badges.scss +46 -0
- package/dist/assets/themes/classy/css/components/_buttons.scss +175 -0
- package/dist/assets/themes/classy/css/components/_cards.scss +41 -0
- package/dist/assets/themes/classy/css/components/_dropdowns.scss +48 -0
- package/dist/assets/themes/classy/css/components/_forms.scss +171 -0
- package/dist/assets/themes/classy/css/components/_receipt.scss +45 -0
- package/dist/assets/themes/classy/css/layout/_footer.scss +298 -0
- package/dist/assets/themes/classy/css/layout/_general.scss +209 -0
- package/dist/assets/themes/classy/css/layout/_nav.scss +154 -0
- package/dist/assets/themes/classy/css/layout/_shell.scss +458 -0
- package/dist/assets/themes/classy/css/marketing/_bento.scss +238 -0
- package/dist/assets/themes/classy/css/marketing/_content.scss +1328 -0
- package/dist/assets/themes/classy/css/marketing/_downloads.scss +246 -0
- package/dist/assets/themes/classy/css/marketing/_hero.scss +311 -0
- package/dist/assets/themes/classy/css/marketing/_sections.scss +649 -0
- package/dist/assets/themes/classy/css/pages/404/index.scss +67 -0
- package/dist/assets/themes/classy/css/pages/_auth.scss +235 -0
- package/dist/assets/themes/classy/css/pages/admin/firebase/index.scss +22 -0
- package/dist/assets/themes/classy/css/pages/blog/[slug].scss +56 -0
- package/dist/assets/themes/classy/css/pages/cookies.scss +2 -0
- package/dist/assets/themes/classy/css/pages/dashboard/account/index.scss +31 -0
- package/dist/assets/themes/classy/css/pages/feedback/index.scss +39 -0
- package/dist/assets/themes/classy/css/pages/legal/_document.scss +192 -0
- package/dist/assets/themes/classy/css/pages/payment/checkout/index.scss +585 -0
- package/dist/assets/themes/classy/css/pages/payment/confirmation/index.scss +9 -0
- package/dist/assets/themes/classy/css/pages/privacy.scss +2 -0
- package/dist/assets/themes/classy/css/pages/status/index.scss +164 -0
- package/dist/assets/themes/classy/css/pages/terms.scss +2 -0
- package/dist/assets/themes/classy/css/pages/updates/index.scss +128 -0
- package/dist/assets/themes/classy/fonts/inter-italic-latin-ext.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/inter-italic-latin.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/inter-normal-latin-ext.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/inter-normal-latin.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/newsreader-italic-latin-ext.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/newsreader-italic-latin.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/newsreader-normal-latin-ext.woff2 +0 -0
- package/dist/assets/themes/classy/fonts/newsreader-normal-latin.woff2 +0 -0
- package/dist/assets/themes/classy/js/hero-demo-form.js +56 -0
- package/dist/assets/themes/neobrutalism/README.md +118 -0
- package/dist/assets/themes/neobrutalism/_config.scss +139 -0
- package/dist/assets/themes/neobrutalism/_layouts/frontend/core/base.html +30 -0
- package/dist/assets/themes/neobrutalism/_layouts/frontend/pages/index.html +275 -0
- package/dist/assets/themes/neobrutalism/_theme.js +24 -0
- package/dist/assets/themes/neobrutalism/_theme.scss +61 -0
- package/dist/assets/themes/neobrutalism/css/base/_mixins.scss +46 -0
- package/dist/assets/themes/neobrutalism/css/base/_root.scss +169 -0
- package/dist/assets/themes/neobrutalism/css/base/_typography.scss +61 -0
- package/dist/assets/themes/neobrutalism/css/base/_utilities.scss +89 -0
- package/dist/assets/themes/neobrutalism/css/components/_billing-toggle.scss +74 -0
- package/dist/assets/themes/neobrutalism/css/components/_buttons.scss +148 -0
- package/dist/assets/themes/neobrutalism/css/components/_cards.scss +47 -0
- package/dist/assets/themes/neobrutalism/css/components/_forms.scss +88 -0
- package/dist/assets/themes/neobrutalism/css/components/_marketing.scss +244 -0
- package/dist/assets/themes/neobrutalism/css/layout/_general.scss +213 -0
- package/dist/assets/themes/neobrutalism/css/layout/_navigation.scss +171 -0
- package/dist/assets/themes/neobrutalism/css/pages/index.scss +203 -0
- package/dist/assets/themes/neobrutalism/css/pages/pricing/index.scss +58 -0
- package/dist/assets/themes/neobrutalism/css/pages/test/libraries/layers/index.scss +7 -0
- package/dist/assets/themes/neobrutalism/js/pages/test/libraries/layers/index.js +9 -0
- package/dist/assets/themes/newsflash/README.md +117 -0
- package/dist/assets/themes/newsflash/_components/heading/lede/component.html +14 -0
- package/dist/assets/themes/newsflash/_components/heading/lede/component.json5 +23 -0
- package/dist/assets/themes/newsflash/_components/heading/rule-head/component.html +17 -0
- package/dist/assets/themes/newsflash/_components/heading/rule-head/component.json5 +23 -0
- package/dist/assets/themes/newsflash/_components/news/byline/component.html +12 -0
- package/dist/assets/themes/newsflash/_components/news/byline/component.json5 +18 -0
- package/dist/assets/themes/newsflash/_components/news/story-card/component.html +25 -0
- package/dist/assets/themes/newsflash/_components/news/story-card/component.json5 +21 -0
- package/dist/assets/themes/newsflash/_config.scss +147 -0
- package/dist/assets/themes/newsflash/_layouts/frontend/core/base.html +51 -0
- package/dist/assets/themes/newsflash/_layouts/frontend/pages/blog/index.html +299 -0
- package/dist/assets/themes/newsflash/_layouts/frontend/pages/blog/post.html +235 -0
- package/dist/assets/themes/newsflash/_layouts/frontend/pages/index.html +328 -0
- package/dist/assets/themes/newsflash/_sections/marketing/desks/section.html +39 -0
- package/dist/assets/themes/newsflash/_sections/marketing/desks/section.json5 +49 -0
- package/dist/assets/themes/newsflash/_sections/marketing/newsletter-cta/section.html +103 -0
- package/dist/assets/themes/newsflash/_sections/marketing/newsletter-cta/section.json5 +50 -0
- package/dist/assets/themes/newsflash/_sections/marketing/rundown/section.html +28 -0
- package/dist/assets/themes/newsflash/_sections/marketing/rundown/section.json5 +40 -0
- package/dist/assets/themes/newsflash/_theme.js +24 -0
- package/dist/assets/themes/newsflash/_theme.scss +70 -0
- package/dist/assets/themes/newsflash/css/base/_fonts.scss +80 -0
- package/dist/assets/themes/newsflash/css/base/_mixins.scss +51 -0
- package/dist/assets/themes/newsflash/css/base/_root.scss +257 -0
- package/dist/assets/themes/newsflash/css/base/_typography.scss +49 -0
- package/dist/assets/themes/newsflash/css/base/_utilities.scss +122 -0
- package/dist/assets/themes/newsflash/css/components/_badges.scss +65 -0
- package/dist/assets/themes/newsflash/css/components/_billing-toggle.scss +61 -0
- package/dist/assets/themes/newsflash/css/components/_buttons.scss +139 -0
- package/dist/assets/themes/newsflash/css/components/_cards.scss +47 -0
- package/dist/assets/themes/newsflash/css/components/_editorial.scss +173 -0
- package/dist/assets/themes/newsflash/css/components/_forms.scss +75 -0
- package/dist/assets/themes/newsflash/css/components/_infinite-scroll.scss +102 -0
- package/dist/assets/themes/newsflash/css/components/_panels.scss +156 -0
- package/dist/assets/themes/newsflash/css/components/_ticker.scss +67 -0
- package/dist/assets/themes/newsflash/css/layout/_general.scss +330 -0
- package/dist/assets/themes/newsflash/css/layout/_navigation.scss +168 -0
- package/dist/assets/themes/newsflash/css/pages/404/index.scss +79 -0
- package/dist/assets/themes/newsflash/css/pages/blog/[slug].scss +186 -0
- package/dist/assets/themes/newsflash/css/pages/blog/index.scss +17 -0
- package/dist/assets/themes/newsflash/css/pages/index.scss +157 -0
- package/dist/assets/themes/newsflash/css/pages/pricing/index.scss +55 -0
- package/dist/assets/themes/newsflash/css/pages/test/libraries/layers/index.scss +7 -0
- package/dist/assets/themes/newsflash/fonts/fraunces-italic-latin-ext.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/fraunces-italic-latin.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/fraunces-normal-latin-ext.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/fraunces-normal-latin.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-italic-latin-ext.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-italic-latin.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-normal-latin-ext.woff2 +0 -0
- package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-normal-latin.woff2 +0 -0
- package/dist/assets/themes/newsflash/js/pages/blog/[slug].js +29 -0
- package/dist/assets/themes/newsflash/js/pages/test/libraries/layers/index.js +9 -0
- package/dist/build.js +249 -0
- package/dist/cli-run.js +34 -0
- package/dist/cli.js +49 -0
- package/dist/commands/build.js +32 -0
- package/dist/commands/cdp/capture.js +91 -0
- package/dist/commands/cdp/client.js +140 -0
- package/dist/commands/cdp/eval.js +20 -0
- package/dist/commands/cdp/quit.js +84 -0
- package/dist/commands/cdp/relaunch.js +62 -0
- package/dist/commands/cdp/shot.js +20 -0
- package/dist/commands/cdp/status.js +38 -0
- package/dist/commands/cdp/theme.js +21 -0
- package/dist/commands/cdp.js +53 -0
- package/dist/commands/clean.js +34 -0
- package/dist/commands/deploy.js +75 -0
- package/dist/commands/finalize-release.js +238 -0
- package/dist/commands/install.js +37 -0
- package/dist/commands/launch.js +150 -0
- package/dist/commands/lib/dependencies.js +35 -0
- package/dist/commands/lib/deploy-precheck.js +117 -0
- package/dist/commands/lib/ensure-target.js +300 -0
- package/dist/commands/logs.js +185 -0
- package/dist/commands/package.js +31 -0
- package/dist/commands/publish.js +34 -0
- package/dist/commands/push-secrets.js +141 -0
- package/dist/commands/release.js +286 -0
- package/dist/commands/runner.js +1874 -0
- package/dist/commands/sign-windows.js +563 -0
- package/dist/commands/test.js +121 -0
- package/dist/commands/update.js +21 -0
- package/dist/commands/validate-certs.js +238 -0
- package/dist/commands/version.js +9 -0
- package/dist/config/page-template.html +35 -0
- package/dist/defaults/.github/workflows/build.yml +276 -0
- package/dist/defaults/AGENTS.md +109 -0
- package/dist/defaults/CHANGELOG.md +15 -0
- package/dist/defaults/CLAUDE.md +1 -0
- package/dist/defaults/_.gitignore +24 -0
- package/dist/defaults/_mas/README.md +49 -0
- package/dist/defaults/_mas/entitlements.mas.inherit.plist +12 -0
- package/dist/defaults/_mas/entitlements.mas.loginhelper.plist +8 -0
- package/dist/defaults/_mas/entitlements.mas.plist +33 -0
- package/dist/defaults/config/certs/.gitkeep +0 -0
- package/dist/defaults/config/certs/README.md +60 -0
- package/dist/defaults/config/icons/macos/dmg.png +0 -0
- package/dist/defaults/config/icons/macos/icon.png +0 -0
- package/dist/defaults/config/icons/macos/tray.png +0 -0
- package/dist/defaults/config/icons/windows/icon.png +0 -0
- package/dist/defaults/config/omega.json5 +279 -0
- package/dist/defaults/docs/README.md +17 -0
- package/dist/defaults/gulpfile.js +6 -0
- package/dist/defaults/hooks/build/post.js +9 -0
- package/dist/defaults/hooks/build/pre.js +9 -0
- package/dist/defaults/hooks/notarize/post.js +16 -0
- package/dist/defaults/hooks/release/post.js +9 -0
- package/dist/defaults/hooks/release/pre.js +9 -0
- package/dist/defaults/src/assets/js/components/about/index.js +10 -0
- package/dist/defaults/src/assets/js/components/main/index.js +14 -0
- package/dist/defaults/src/assets/js/components/settings/index.js +10 -0
- package/dist/defaults/src/assets/scss/main.scss +34 -0
- package/dist/defaults/src/assets/scss/pages/about.scss +3 -0
- package/dist/defaults/src/assets/scss/pages/main.scss +4 -0
- package/dist/defaults/src/assets/scss/pages/settings.scss +3 -0
- package/dist/defaults/src/integrations/context-menu/index.js +60 -0
- package/dist/defaults/src/integrations/menu/index.js +58 -0
- package/dist/defaults/src/integrations/tray/index.js +60 -0
- package/dist/defaults/src/main.js +78 -0
- package/dist/defaults/src/preload.js +15 -0
- package/dist/defaults/src/views/about/index.html +3 -0
- package/dist/defaults/src/views/main/index.html +8 -0
- package/dist/defaults/src/views/settings/index.html +3 -0
- package/dist/defaults/test/README.md +41 -0
- package/dist/defaults/test/_init.js +10 -0
- package/dist/gulp/main.js +144 -0
- package/dist/gulp/tasks/audit.js +82 -0
- package/dist/gulp/tasks/build-config.js +445 -0
- package/dist/gulp/tasks/bundle.js +451 -0
- package/dist/gulp/tasks/defaults.js +20 -0
- package/dist/gulp/tasks/distribute.js +8 -0
- package/dist/gulp/tasks/html.js +95 -0
- package/dist/gulp/tasks/package-quick.js +102 -0
- package/dist/gulp/tasks/package.js +53 -0
- package/dist/gulp/tasks/release.js +57 -0
- package/dist/gulp/tasks/sass.js +82 -0
- package/dist/gulp/tasks/serve.js +191 -0
- package/dist/hooks/notarize.js +70 -0
- package/dist/index.js +14 -0
- package/dist/lib/_menu-mixin.js +199 -0
- package/dist/lib/analytics.js +360 -0
- package/dist/lib/app-state.js +220 -0
- package/dist/lib/auth-flow.js +160 -0
- package/dist/lib/auth-persistence.js +207 -0
- package/dist/lib/auto-updater.js +752 -0
- package/dist/lib/client-bridge.js +371 -0
- package/dist/lib/context-menu.js +302 -0
- package/dist/lib/context.js +162 -0
- package/dist/lib/deep-link.js +370 -0
- package/dist/lib/fontawesome.js +203 -0
- package/dist/lib/ipc.js +169 -0
- package/dist/lib/logger-lite.js +259 -0
- package/dist/lib/logger.js +4 -0
- package/dist/lib/menu.js +521 -0
- package/dist/lib/protocol.js +85 -0
- package/dist/lib/remote-config.js +224 -0
- package/dist/lib/remote-scripts.js +158 -0
- package/dist/lib/restart-manager/index.js +550 -0
- package/dist/lib/restart-manager/install.js +353 -0
- package/dist/lib/restart-manager/protocol.js +274 -0
- package/dist/lib/sign-helpers/auto-unlock.js +95 -0
- package/dist/lib/sign-helpers/entitlements.js +98 -0
- package/dist/lib/sign-helpers/resolve-icons.js +171 -0
- package/dist/lib/sign-helpers/sign-events.js +75 -0
- package/dist/lib/sign-helpers/update-info.js +186 -0
- package/dist/lib/startup.js +214 -0
- package/dist/lib/storage.js +193 -0
- package/dist/lib/templating.js +85 -0
- package/dist/lib/theme.js +173 -0
- package/dist/lib/tray.js +414 -0
- package/dist/lib/usage.js +141 -0
- package/dist/lib/window-manager.js +509 -0
- package/dist/main.js +542 -0
- package/dist/omega-bin.js +6 -0
- package/dist/preload.js +241 -0
- package/dist/renderer.js +456 -0
- package/dist/test/assert.js +4 -0
- package/dist/test/fixtures/consumer-app/config/omega.json5 +39 -0
- package/dist/test/fixtures/consumer-app/package.json +13 -0
- package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +11 -0
- package/dist/test/fixtures/consumer-app/src/assets/scss/main.scss +3 -0
- package/dist/test/fixtures/consumer-app/src/main.js +17 -0
- package/dist/test/fixtures/consumer-app/src/preload.js +4 -0
- package/dist/test/fixtures/consumer-app/src/views/main/index.html +4 -0
- package/dist/test/harness/boot-entry.js +237 -0
- package/dist/test/harness/main-entry.js +494 -0
- package/dist/test/harness/package.json +6 -0
- package/dist/test/harness/renderer-entry.js +173 -0
- package/dist/test/harness/renderer-preload.js +310 -0
- package/dist/test/harness/renderer.html +12 -0
- package/dist/test/index.js +65 -0
- package/dist/test/runner.js +99 -0
- package/dist/test/runners/boot.js +414 -0
- package/dist/test/runners/electron.js +92 -0
- package/dist/test/runners/render-event.js +46 -0
- package/dist/test/suites/boot/build-isolation.test.js +54 -0
- package/dist/test/suites/boot/consumer-app-boots.test.js +99 -0
- package/dist/test/suites/boot/restart-manager.test.js +38 -0
- package/dist/test/suites/boot/storage-bundled.test.js +59 -0
- package/dist/test/suites/boot/theme.test.js +68 -0
- package/dist/test/suites/boot/view-suite.test.js +47 -0
- package/dist/test/suites/build/attach-log-file.test.js +99 -0
- package/dist/test/suites/build/audit.test.js +271 -0
- package/dist/test/suites/build/boot-fixture.test.js +48 -0
- package/dist/test/suites/build/build-config.test.js +457 -0
- package/dist/test/suites/build/build-verbs.test.js +156 -0
- package/dist/test/suites/build/build-workflow-jobs.test.js +55 -0
- package/dist/test/suites/build/cdp.test.js +89 -0
- package/dist/test/suites/build/cli.test.js +135 -0
- package/dist/test/suites/build/config-schema.test.js +133 -0
- package/dist/test/suites/build/defaults-scaffold.test.js +192 -0
- package/dist/test/suites/build/deliver-certs.test.js +95 -0
- package/dist/test/suites/build/derive-signing-env.test.js +122 -0
- package/dist/test/suites/build/electron-node-version.test.js +49 -0
- package/dist/test/suites/build/electron-targets.test.js +92 -0
- package/dist/test/suites/build/ensure-target.test.js +131 -0
- package/dist/test/suites/build/entitlements.test.js +107 -0
- package/dist/test/suites/build/env-delivery.test.js +166 -0
- package/dist/test/suites/build/env-watch.test.js +86 -0
- package/dist/test/suites/build/exports.test.js +63 -0
- package/dist/test/suites/build/finalize-release.test.js +152 -0
- package/dist/test/suites/build/format-fetch-error.test.js +85 -0
- package/dist/test/suites/build/framework-deps.test.js +173 -0
- package/dist/test/suites/build/get-config.test.js +137 -0
- package/dist/test/suites/build/github-utils.test.js +54 -0
- package/dist/test/suites/build/icon-sheet.test.js +62 -0
- package/dist/test/suites/build/license-stamp.test.js +63 -0
- package/dist/test/suites/build/logger-lite.test.js +148 -0
- package/dist/test/suites/build/logs-command.test.js +226 -0
- package/dist/test/suites/build/manager.test.js +193 -0
- package/dist/test/suites/build/menu-mixin.test.js +130 -0
- package/dist/test/suites/build/merge-line-files.test.js +230 -0
- package/dist/test/suites/build/omega-shell.test.js +94 -0
- package/dist/test/suites/build/omega-tokens.test.js +64 -0
- package/dist/test/suites/build/project-scripts-deps.test.js +90 -0
- package/dist/test/suites/build/push-secrets.test.js +226 -0
- package/dist/test/suites/build/release-pipeline.test.js +365 -0
- package/dist/test/suites/build/renderer-auth-bridge.test.js +158 -0
- package/dist/test/suites/build/renderer-entry-key.test.js +37 -0
- package/dist/test/suites/build/renderer-node-shims.test.js +125 -0
- package/dist/test/suites/build/resolve-icons.test.js +296 -0
- package/dist/test/suites/build/resolve-signing-cert.test.js +342 -0
- package/dist/test/suites/build/restart-manager-install.test.js +178 -0
- package/dist/test/suites/build/restart-manager-protocol.test.js +158 -0
- package/dist/test/suites/build/run-consumer-hook.test.js +137 -0
- package/dist/test/suites/build/runner.test.js +2599 -0
- package/dist/test/suites/build/sanitize-signing-env.test.js +98 -0
- package/dist/test/suites/build/sanitize-url.test.js +78 -0
- package/dist/test/suites/build/secure-remote-url.test.js +42 -0
- package/dist/test/suites/build/sentry.test.js +89 -0
- package/dist/test/suites/build/serve-resolve-electron.test.js +58 -0
- package/dist/test/suites/build/setup-scripts.test.js +172 -0
- package/dist/test/suites/build/sign-events.test.js +90 -0
- package/dist/test/suites/build/sign-windows-e2e.test.js +302 -0
- package/dist/test/suites/build/sign-windows.test.js +313 -0
- package/dist/test/suites/build/strip-dev-blocks.test.js +116 -0
- package/dist/test/suites/build/templating.test.js +95 -0
- package/dist/test/suites/build/test-discovery.test.js +64 -0
- package/dist/test/suites/build/test-stealth.test.js +83 -0
- package/dist/test/suites/build/test-target-no-match.test.js +119 -0
- package/dist/test/suites/build/update-info.test.js +224 -0
- package/dist/test/suites/build/url-helpers.test.js +289 -0
- package/dist/test/suites/build/validate-certs.test.js +103 -0
- package/dist/test/suites/build/validate-config.test.js +90 -0
- package/dist/test/suites/build/verb-logs.test.js +43 -0
- package/dist/test/suites/build/wave5-pins.test.js +35 -0
- package/dist/test/suites/main/analytics.test.js +364 -0
- package/dist/test/suites/main/app-state.test.js +197 -0
- package/dist/test/suites/main/auth-flow.test.js +196 -0
- package/dist/test/suites/main/auth-persistence.test.js +167 -0
- package/dist/test/suites/main/auto-updater.test.js +1138 -0
- package/dist/test/suites/main/boot-sequence.test.js +77 -0
- package/dist/test/suites/main/client-bridge.integration.test.js +134 -0
- package/dist/test/suites/main/client-bridge.test.js +249 -0
- package/dist/test/suites/main/context-menu.test.js +365 -0
- package/dist/test/suites/main/context.test.js +155 -0
- package/dist/test/suites/main/deep-link.test.js +288 -0
- package/dist/test/suites/main/epipe-handler.test.js +40 -0
- package/dist/test/suites/main/fontawesome.test.js +147 -0
- package/dist/test/suites/main/harness-cdp.test.js +49 -0
- package/dist/test/suites/main/ipc.test.js +165 -0
- package/dist/test/suites/main/menu.test.js +419 -0
- package/dist/test/suites/main/protocol.test.js +77 -0
- package/dist/test/suites/main/remote-config.test.js +189 -0
- package/dist/test/suites/main/remote-scripts.test.js +276 -0
- package/dist/test/suites/main/restart-manager.test.js +328 -0
- package/dist/test/suites/main/startup-paths-and-ua.test.js +99 -0
- package/dist/test/suites/main/startup.test.js +129 -0
- package/dist/test/suites/main/stealth-window.test.js +74 -0
- package/dist/test/suites/main/storage.test.js +89 -0
- package/dist/test/suites/main/theme.test.js +137 -0
- package/dist/test/suites/main/tray.test.js +322 -0
- package/dist/test/suites/main/truncate-on-boot.test.js +22 -0
- package/dist/test/suites/main/url-helpers.test.js +429 -0
- package/dist/test/suites/main/usage.test.js +127 -0
- package/dist/test/suites/main/window-bounds.test.js +169 -0
- package/dist/test/suites/main/window-manager.test.js +233 -0
- package/dist/test/suites/renderer/analytics-bridge.test.js +128 -0
- package/dist/test/suites/renderer/cross-context-helpers.test.js +131 -0
- package/dist/test/suites/renderer/fontawesome.test.js +190 -0
- package/dist/test/suites/renderer/round-trip.test.js +107 -0
- package/dist/test/suites/renderer/theme.test.js +118 -0
- package/dist/test/suites/renderer/tooltips.test.js +166 -0
- package/dist/test/suites/renderer/verts.test.js +100 -0
- package/dist/test/suites/renderer/window-em-surface.test.js +107 -0
- package/dist/test/utils/dist-snapshot.js +36 -0
- package/dist/test/utils/extended-mode-warning.js +13 -0
- package/dist/utils/app-root.js +28 -0
- package/dist/utils/attach-log-file.js +4 -0
- package/dist/utils/build-pipeline.js +58 -0
- package/dist/utils/deliver-certs.js +69 -0
- package/dist/utils/derive-signing-env.js +56 -0
- package/dist/utils/dist-root.js +21 -0
- package/dist/utils/electron-node-version.js +48 -0
- package/dist/utils/electron-targets.js +72 -0
- package/dist/utils/format-fetch-error.js +38 -0
- package/dist/utils/github.js +73 -0
- package/dist/utils/load-consumer-file.js +26 -0
- package/dist/utils/merge-line-files.js +5 -0
- package/dist/utils/mode-helpers.js +147 -0
- package/dist/utils/resolve-signing-cert.js +175 -0
- package/dist/utils/run-consumer-hook.js +38 -0
- package/dist/utils/runner-env.js +687 -0
- package/dist/utils/safe-install.js +4 -0
- package/dist/utils/sanitize-signing-env.js +45 -0
- package/dist/utils/sanitize-url.js +28 -0
- package/dist/utils/secure-remote-url.js +25 -0
- package/dist/utils/stealth-window.js +37 -0
- package/dist/utils/test-stealth.js +29 -0
- package/dist/utils/url-helpers.js +169 -0
- package/dist/vendor/account/engine.js +182 -0
- package/dist/vendor/account/features.js +220 -0
- package/dist/vendor/account/index.js +53 -0
- package/dist/vendor/account/schema.js +272 -0
- package/dist/vendor/account/subscription.js +38 -0
- package/dist/vendor/analytics/adapters/ga4.js +26 -0
- package/dist/vendor/analytics/adapters/meta.js +26 -0
- package/dist/vendor/analytics/adapters/resolve.js +130 -0
- package/dist/vendor/analytics/adapters/tiktok.js +27 -0
- package/dist/vendor/analytics/catalog.js +908 -0
- package/dist/vendor/analytics/consent.js +49 -0
- package/dist/vendor/analytics/core.js +141 -0
- package/dist/vendor/analytics/identity.js +136 -0
- package/dist/vendor/analytics/index.js +170 -0
- package/dist/vendor/analytics/logger.js +40 -0
- package/dist/vendor/analytics/transports/browser.js +110 -0
- package/dist/vendor/config/company.js +31 -0
- package/dist/vendor/config/defaults.js +173 -0
- package/dist/vendor/config/demo.js +18 -0
- package/dist/vendor/config/desktop-artifacts.js +110 -0
- package/dist/vendor/config/edit.js +769 -0
- package/dist/vendor/config/env-delivery.js +145 -0
- package/dist/vendor/config/env-rules.js +93 -0
- package/dist/vendor/config/env-schema.js +1078 -0
- package/dist/vendor/config/env.js +445 -0
- package/dist/vendor/config/hooks.js +97 -0
- package/dist/vendor/config/index.js +237 -0
- package/dist/vendor/config/instances.js +208 -0
- package/dist/vendor/config/load.js +490 -0
- package/dist/vendor/config/merge.js +68 -0
- package/dist/vendor/config/order.js +139 -0
- package/dist/vendor/config/ports.js +374 -0
- package/dist/vendor/config/providers.js +32 -0
- package/dist/vendor/config/repo.js +142 -0
- package/dist/vendor/config/retired-keys.js +430 -0
- package/dist/vendor/config/schema.js +1610 -0
- package/dist/vendor/config/secrets.js +50 -0
- package/dist/vendor/config/seed.js +34 -0
- package/dist/vendor/config/site-global.js +205 -0
- package/dist/vendor/config/validate.js +554 -0
- package/dist/vendor/config/winback.js +61 -0
- package/dist/vendor/devkit/actions-secrets.js +145 -0
- package/dist/vendor/devkit/attach-log-file.js +262 -0
- package/dist/vendor/devkit/bundle.js +292 -0
- package/dist/vendor/devkit/certs.js +199 -0
- package/dist/vendor/devkit/ci-workflows.js +520 -0
- package/dist/vendor/devkit/clean-dirs.js +28 -0
- package/dist/vendor/devkit/cli-router.js +156 -0
- package/dist/vendor/devkit/defaults-engine.js +372 -0
- package/dist/vendor/devkit/deploy-precheck.js +54 -0
- package/dist/vendor/devkit/deploy-record.js +180 -0
- package/dist/vendor/devkit/deploy.js +286 -0
- package/dist/vendor/devkit/empty-modules-plugin.js +64 -0
- package/dist/vendor/devkit/env-watch.js +132 -0
- package/dist/vendor/devkit/framework-deps.js +46 -0
- package/dist/vendor/devkit/license.js +155 -0
- package/dist/vendor/devkit/local.js +1905 -0
- package/dist/vendor/devkit/logger.js +128 -0
- package/dist/vendor/devkit/merge-line-files.js +296 -0
- package/dist/vendor/devkit/npm-registry.js +52 -0
- package/dist/vendor/devkit/omega-bin.js +345 -0
- package/dist/vendor/devkit/prompt.js +187 -0
- package/dist/vendor/devkit/safe-install.js +18 -0
- package/dist/vendor/devkit/scaffold-guard.js +96 -0
- package/dist/vendor/devkit/stop-signals.js +28 -0
- package/dist/vendor/devkit/strip-dev-blocks-plugin.js +29 -0
- package/dist/vendor/devkit/strip-dev-blocks.js +32 -0
- package/dist/vendor/devkit/target-dependencies.js +137 -0
- package/dist/vendor/devkit/target-secrets.js +165 -0
- package/dist/vendor/devkit/test/assert.js +120 -0
- package/dist/vendor/devkit/test/define-cases.js +104 -0
- package/dist/vendor/devkit/test/extended-mode-warning.js +22 -0
- package/dist/vendor/devkit/test/runner-core.js +554 -0
- package/dist/vendor/devkit/test/scope.js +162 -0
- package/dist/vendor/devkit/update.js +569 -0
- package/dist/vendor/monitoring/core.js +180 -0
- package/dist/vendor/monitoring/env.js +49 -0
- package/dist/vendor/monitoring/index.js +28 -0
- package/dist/vendor/monitoring/logger.js +39 -0
- package/dist/vendor/monitoring/main.js +99 -0
- package/dist/vendor/monitoring/preload.js +45 -0
- package/dist/vendor/monitoring/renderer.js +87 -0
- package/docs/analytics.md +140 -0
- package/docs/app-state.md +92 -0
- package/docs/audit.md +69 -0
- package/docs/auto-updater.md +243 -0
- package/docs/boot-sequence.md +39 -0
- package/docs/build-system.md +161 -0
- package/docs/cdp-debugging.md +169 -0
- package/docs/client-bridge.md +267 -0
- package/docs/common-mistakes.md +21 -0
- package/docs/config-schema.md +120 -0
- package/docs/context-menu.md +112 -0
- package/docs/context.md +81 -0
- package/docs/css.md +84 -0
- package/docs/deep-link.md +178 -0
- package/docs/environment-detection.md +104 -0
- package/docs/fontawesome.md +107 -0
- package/docs/hooks.md +87 -0
- package/docs/icons.md +79 -0
- package/docs/index.md +279 -0
- package/docs/installer-options.md +162 -0
- package/docs/ipc.md +61 -0
- package/docs/lib-modules.md +53 -0
- package/docs/logging.md +229 -0
- package/docs/menu.md +160 -0
- package/docs/releasing.md +229 -0
- package/docs/remote-config.md +118 -0
- package/docs/remote-scripts.md +144 -0
- package/docs/restart-manager.md +144 -0
- package/docs/runner.md +253 -0
- package/docs/sentry.md +97 -0
- package/docs/shared/agent-docs.md +89 -0
- package/docs/shared/analytics.md +612 -0
- package/docs/shared/brands.md +51 -0
- package/docs/shared/breaking-changes.md +497 -0
- package/docs/shared/config.md +1387 -0
- package/docs/shared/deploys.md +215 -0
- package/docs/shared/icons.md +201 -0
- package/docs/shared/local-dev.md +147 -0
- package/docs/shared/logging.md +202 -0
- package/docs/shared/monitoring.md +153 -0
- package/docs/shared/publishing.md +183 -0
- package/docs/shared/rulings.md +34 -0
- package/docs/shared/testing.md +147 -0
- package/docs/shared/theming.md +604 -0
- package/docs/shared/translation.md +291 -0
- package/docs/shared/updates.md +61 -0
- package/docs/signing.md +267 -0
- package/docs/startup.md +142 -0
- package/docs/storage.md +59 -0
- package/docs/templating.md +101 -0
- package/docs/test-boot-layer.md +157 -0
- package/docs/test-framework.md +357 -0
- package/docs/themes.md +135 -0
- package/docs/tooltips.md +99 -0
- package/docs/tray.md +164 -0
- package/docs/usage.md +58 -0
- package/docs/verts.md +62 -0
- package/docs/windows.md +149 -0
- package/package.json +184 -0
- package/scripts/sync-nvmrc.js +100 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Releasing — From `.env` to GitHub Release
|
|
2
|
+
|
|
3
|
+
End-to-end walkthrough for cutting a signed + notarized + published release of an OMEGA Desktop app.
|
|
4
|
+
|
|
5
|
+
## Repo layout (private app, ONE public releases repo)
|
|
6
|
+
|
|
7
|
+
@omega.js/desktop separates the app from its binaries:
|
|
8
|
+
|
|
9
|
+
| Repo | Visibility | Purpose |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| `<owner>/<app>` | usually **private** | the app source code |
|
|
12
|
+
| `<owner>/<brand.id>-releases` | **public** | release artifacts + auto-update feed (`latest-mac.yml` etc.) — AND the marketing site's direct-download links |
|
|
13
|
+
|
|
14
|
+
Why: auto-update feeds and marketing downloads MUST be publicly accessible (no auth headers in `electron-updater` or in an `<a href>`). Your app source can stay private; the public repo contains only binaries.
|
|
15
|
+
|
|
16
|
+
ONE public repo answers both ([#620](https://github.com/Omega-JS-Stack/omega/issues/620)), because the assets carry no version — see [Versionless assets](#versionless-assets-and-direct-download-links) below.
|
|
17
|
+
|
|
18
|
+
**Its address has ONE home** ([#799](https://github.com/Omega-JS-Stack/omega/issues/799)): `@omega.js/config`'s `releasesRepo`, which defaults the name to `<brand.id>-releases` and the owner to the brand repo's own owner. Every reader takes it from there: the electron-builder publish block the build bakes into `app-update.yml`, the deploy precheck's repo provisioning, `finalize-release`'s uploads, and the website's download buttons. Nothing reads a git remote, so a target inside a brand monorepo (and a brand nested in another repo) addresses its own repo rather than the enclosing one.
|
|
19
|
+
|
|
20
|
+
`npx omega deploy`'s precheck auto-creates the public repo if it doesn't exist (uses `GH_TOKEN`). Override the defaults in `config/omega.json5` only if you need to:
|
|
21
|
+
|
|
22
|
+
```jsonc
|
|
23
|
+
releases: {
|
|
24
|
+
enabled: true,
|
|
25
|
+
// owner: null, // null = the brand repo's owner
|
|
26
|
+
// repo: 'myapp-releases', // default: `<brand.id>-releases`
|
|
27
|
+
},
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Versionless assets and direct-download links
|
|
31
|
+
|
|
32
|
+
Every artifact name is **stable across releases** — no version in it:
|
|
33
|
+
|
|
34
|
+
| Platform | Artifact | Asset name |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| macOS | `universal` (dmg) | `<Product>-mac-universal.dmg` |
|
|
37
|
+
| macOS | auto-update zip | `<Product>-mac-universal.zip` |
|
|
38
|
+
| Windows | `universal` (NSIS) | `<Product>-windows-universal.exe` |
|
|
39
|
+
| Linux | `debian` | `<Product>-linux-debian.deb` |
|
|
40
|
+
| Linux | `appimage` | `<Product>-linux-appimage.AppImage` |
|
|
41
|
+
|
|
42
|
+
`<Product>` is `app.productName` (← `brand.name`) with non-filename characters hyphenated. The rule has ONE home — `@omega.js/config`'s `desktop-artifacts.js` — which `gulp/build-config` writes into `dist/electron-builder.yml`'s artifactName templates and the website reads to build its buttons. Never spell an asset name anywhere else.
|
|
43
|
+
|
|
44
|
+
Because the names never change, GitHub's latest-release redirect is a permanent direct-download URL:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
https://github.com/<owner>/<brand.id>-releases/releases/latest/download/<asset>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
That is what `site.targets.desktop.downloads[platform][artifact]` derives (see [docs/shared/config.md](../../../docs/shared/config.md#the-site-global-the-curated-targets-view-85-610) in the Omega repo), what the `/download` page's buttons link, and what every `/download/<platform>[/<artifact>]` shortlink redirects to. **Releasing a desktop version never touches the website**, and the published URLs never change.
|
|
51
|
+
|
|
52
|
+
Auto-update is unaffected: `electron-updater` reads the feed files (`latest-mac.yml`, `latest.yml`, `latest-linux.yml`), which name whatever artifact the build produced.
|
|
53
|
+
|
|
54
|
+
Because the names carry no arch either, they support exactly the default build: a **universal** mac, a **single** linux arch, and windows' multi-arch NSIS installer (one file for every arch). Nothing appends an arch back — `gulp/build-config` REFUSES a `platforms.mac.arch` that is not universal, and a `platforms.linux.arch` with more than one arch, rather than let two builds overwrite one name. Per-arch names are a future additive change.
|
|
55
|
+
|
|
56
|
+
### Moving the releases repo
|
|
57
|
+
|
|
58
|
+
If the releases repo has to move (rename or transfer), the rules are:
|
|
59
|
+
|
|
60
|
+
- **The existing repo is the survivor** — transfer it, never build a fresh one. GitHub keeps redirects for the web pages, git remotes, the API and release-asset URLs, and `electron-updater` follows them, so every already-installed app (its feed URL is baked into `app-update.yml` at build time) keeps updating.
|
|
61
|
+
- **Never reuse the old org/name.** A new repo created at the old path takes the redirect over and silently steals every installed app's update feed and every published download link.
|
|
62
|
+
- Update `releases.repo` (and `releases.owner` if the owner changed) in `config/omega.json5`. The website's URLs re-derive from that on its next build; the asset names do not change.
|
|
63
|
+
- **Fallback only** — if the surviving repo were a *different* repo, installed apps would need a bridge release: build once with the new feed baked in and publish it to the OLD repo, so clients update themselves onto the new feed before it is retired.
|
|
64
|
+
|
|
65
|
+
> The `downloads:` block (the `download-server` mirror at tag `installer`, `gulp/mirror-downloads`) predated this: it existed only to give marketing a fixed filename, which the versionless names made free. It is GONE ([#799](https://github.com/Omega-JS-Stack/omega/issues/799)): the task, the `publish` step, the finalize-release mirror and the second repo's provisioning are deleted, and `downloads.enabled|owner|repo|tag` are retired config keys a brand still carrying them fails validation on. One public repo, one set of assets.
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
## Prerequisites
|
|
69
|
+
|
|
70
|
+
1. **Apple Developer membership** ($99/year) with a Developer ID Application certificate exported as `.p12`.
|
|
71
|
+
2. **App Store Connect API key** (`AuthKey_*.p8`) — generate at App Store Connect → Users and Access → Keys.
|
|
72
|
+
3. **GitHub Personal Access Token** with `repo` scope (for publishing releases + pushing CI secrets).
|
|
73
|
+
4. **Apple Team ID** — visible on developer.apple.com membership page.
|
|
74
|
+
5. (Optional) **Windows EV USB code-signing token** if you target Windows.
|
|
75
|
+
|
|
76
|
+
See [`docs/signing.md`](signing.md) for full cert setup details.
|
|
77
|
+
|
|
78
|
+
## One-time setup (per app)
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
cd <your-app>
|
|
82
|
+
npm i @omega.js/desktop --save-dev
|
|
83
|
+
npx omega build
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Every verb runs `ensureTarget()` first ([#675](https://github.com/Omega-JS-Stack/omega/issues/675)):
|
|
87
|
+
1. Ensures peer deps (`gulp`, `electron`, `electron-builder`) are installed.
|
|
88
|
+
2. Writes @omega.js/desktop's `projectScripts` into your `package.json` (`start`, `build`, `release`, `test`).
|
|
89
|
+
3. Copies framework defaults (config, builder yml, hooks, scaffold src/, build/) — merging `.env` and `.gitignore` so user customizations are preserved.
|
|
90
|
+
|
|
91
|
+
`npx omega deploy` adds the network half as a precheck (`--no-secrets` opts out):
|
|
92
|
+
|
|
93
|
+
- Validates signing prereqs (warns if missing — non-fatal).
|
|
94
|
+
- Pushes the composed `.env` → GitHub Actions secrets over the `gh` CLI (`gh auth login`; a CI run, an empty cascade, no remote, or a checkout that is not the brand's declared repo skips loudly).
|
|
95
|
+
|
|
96
|
+
Now drop your cert files:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
cp ~/Downloads/developer-id-application.p12 config/certs/
|
|
100
|
+
cp ~/Downloads/AuthKey_XXXXXXXXXX.p8 config/certs/
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Edit `.env`:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
GH_TOKEN="ghp_..."
|
|
107
|
+
OMEGA_ADMIN_KEY="..."
|
|
108
|
+
|
|
109
|
+
CSC_LINK="config/certs/developer-id-application.p12"
|
|
110
|
+
CSC_KEY_PASSWORD="<password>"
|
|
111
|
+
|
|
112
|
+
APPLE_API_KEY="config/certs/AuthKey_XXXXXXXXXX.p8"
|
|
113
|
+
APPLE_API_KEY_ID="XXXXXXXXXX"
|
|
114
|
+
APPLE_API_ISSUER="00000000-0000-0000-0000-000000000000"
|
|
115
|
+
APPLE_TEAM_ID="XXXXXXXXXX"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Deploy to push the now-populated secrets to GitHub:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
npx omega deploy
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
You should see ✓ for each secret in the output.
|
|
125
|
+
|
|
126
|
+
## Local release (manual, single-platform)
|
|
127
|
+
|
|
128
|
+
For testing the full sign + notarize + publish flow on your own machine:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npm run release
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
This runs as a **single gulp invocation** (`gulp publish` with `OMEGA_BUILD_MODE=true OMEGA_IS_PUBLISH=true`):
|
|
135
|
+
1. **build** — defaults → distribute → bundle/sass/html → audit → build-config (materializes `dist/electron-builder.yml` with mode-dependent injections like `LSUIElement` for tray-only)
|
|
136
|
+
2. **release** — `electron-builder build --publish always`
|
|
137
|
+
- Signs the `.app` with your Developer ID Application cert
|
|
138
|
+
- Calls @omega.js/desktop's built-in `afterSign` hook which submits to Apple notarytool via the API key (consumer can extend via `hooks/notarize/post.js`)
|
|
139
|
+
- Stapling + final `.dmg` / `.zip` packaging
|
|
140
|
+
- Uploads to GitHub Releases (using `GH_TOKEN`)
|
|
141
|
+
|
|
142
|
+
The pipeline performs **one** sign+notarize cycle per architecture. (`npm run build` separately runs build + electron-builder package only — no publish, no GH upload — for local smoke-test artifacts.)
|
|
143
|
+
|
|
144
|
+
A successful release on macOS prints something like:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
[notarize] Notarizing MyApp via App Store Connect API key (XXXXXXXXXX)...
|
|
148
|
+
[notarize] Done in 84s.
|
|
149
|
+
[release] Released 2 artifact(s):
|
|
150
|
+
• release/MyApp-mac-universal.dmg
|
|
151
|
+
• release/MyApp-mac-universal.zip
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The release will appear on the GitHub repo's Releases page (as a draft if `releaseType: draft` is set in `electron-builder.yml`, or published if `release`).
|
|
155
|
+
|
|
156
|
+
## Multi-platform release via CI
|
|
157
|
+
|
|
158
|
+
CI handles the cross-platform matrix. The scaffolded workflow is `build.yml`, dispatched by `npx omega release` / `npx omega deploy`:
|
|
159
|
+
|
|
160
|
+
**Standalone the file is `.github/workflows/build.yml`; inside a brand monorepo it is the brand root's `.github/workflows/desktop-build.yml`** ([#265](https://github.com/Omega-JS-Stack/omega/issues/265), [#799](https://github.com/Omega-JS-Stack/omega/issues/799)): GitHub runs workflows from the repo root only, so `ensureTarget` composes the target's copy there and the dispatching verbs ask `@omega.js/devkit/ci-workflows`'s `composedWorkflowName` for the name, the same helper the web and extension deploy verbs use.
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
setup resolves the `platforms` input ('all' by default) into a build matrix
|
|
164
|
+
plus per-platform flags
|
|
165
|
+
build needs setup; matrix over the resolved OSes: npm ci, then
|
|
166
|
+
`npm run release:local` on mac and linux (sign, notarize, and
|
|
167
|
+
electron-builder publishes the DRAFT release in the brand's releases
|
|
168
|
+
repo), and `npm run package` on windows, whose unsigned output uploads
|
|
169
|
+
as the `windows-unsigned` artifact
|
|
170
|
+
windows-strategy needs [setup, build]; reads platforms.win.signing.strategy from config
|
|
171
|
+
(only when windows is in the matrix)
|
|
172
|
+
windows-sign the self-hosted EV-token box, hosted windows-latest for the cloud
|
|
173
|
+
strategy, skipped for local: `omega sign-windows`, then
|
|
174
|
+
`omega finalize-release --signed-dir` attaches the signed installers
|
|
175
|
+
to that same draft
|
|
176
|
+
finalize needs [setup, build, windows-sign] under always(), gated on the build
|
|
177
|
+
having succeeded: `omega finalize-release --publish` flips the draft to
|
|
178
|
+
published, and only on an all-platforms run (a partial run leaves the
|
|
179
|
+
draft standing for the next one to fill in)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The macOS step decodes `secrets.CSC_LINK` and `secrets.APPLE_API_KEY` (uploaded by `npx omega push-secrets` as base64-encoded file contents) back to disk before running `npm run release:local`.
|
|
183
|
+
|
|
184
|
+
**Dispatch only, never a push trigger** ([#802](https://github.com/Omega-JS-Stack/omega/issues/802)): the workflow declares `workflow_dispatch` alone, so no commit and no tag releases anything ([docs/shared/deploys.md](../../../docs/shared/deploys.md) in the Omega repo is the contract for all four frameworks). It runs no tests either: the suites run on the developer's machine and the commit gate runs the battery at ship.
|
|
185
|
+
|
|
186
|
+
To release:
|
|
187
|
+
1. Bump the version in `package.json`.
|
|
188
|
+
2. `npx omega release` dispatches the workflow and streams the run's logs; `--platforms windows` (or `mac,linux`) narrows the matrix. `npx omega deploy` is the same dispatch behind the network prechecks.
|
|
189
|
+
3. Watch the streamed output, or the run at `https://github.com/<owner>/<repo>/actions`.
|
|
190
|
+
|
|
191
|
+
## Windows signing strategies
|
|
192
|
+
|
|
193
|
+
Set `platforms.win.signing.strategy` in `config/omega.json5`:
|
|
194
|
+
|
|
195
|
+
| Strategy | What runs | When to use |
|
|
196
|
+
|---|---|---|
|
|
197
|
+
| `self-hosted` (default) | Self-hosted runner with EV USB token; `npx omega sign-windows` drives `signtool` | You own the EV token |
|
|
198
|
+
| `cloud` | Hosted `windows-latest`; `npx omega sign-windows` shells out to provider CLI (Azure / SSL.com / DigiCert) | Future cloud-signing migration |
|
|
199
|
+
| `local` | CI uploads unsigned; you sign manually on your Windows box | No runner, no cloud — fallback |
|
|
200
|
+
|
|
201
|
+
For details see [`docs/signing.md`](signing.md#windows-setup).
|
|
202
|
+
|
|
203
|
+
## Troubleshooting
|
|
204
|
+
|
|
205
|
+
### "No notarytool API key" error
|
|
206
|
+
- Confirm `APPLE_API_KEY`, `APPLE_API_KEY_ID`, `APPLE_API_ISSUER` are all set.
|
|
207
|
+
- The key file's filename should match the pattern `AuthKey_<KEY_ID>.p8` and `<KEY_ID>` should equal `APPLE_API_KEY_ID`.
|
|
208
|
+
|
|
209
|
+
### "Could not find Developer ID Application certificate"
|
|
210
|
+
- Run `security find-identity -v -p codesigning` on macOS.
|
|
211
|
+
- If absent, re-import your `.p12` to Keychain Access (must include the private key).
|
|
212
|
+
|
|
213
|
+
### Notarization hangs / times out
|
|
214
|
+
- Apple's notarytool can take 1–10 minutes. The hook waits.
|
|
215
|
+
- Check the App Store Connect notarization history at https://appstoreconnect.apple.com/apps for status / errors.
|
|
216
|
+
|
|
217
|
+
### "Hardened runtime requires entitlements"
|
|
218
|
+
- @omega.js/desktop generates `dist/config/entitlements.mac.plist` at build time from defaults + your `entitlements.mac` overrides in `config/omega.json5`.
|
|
219
|
+
- For extra capabilities (camera, mic, etc.), add keys to `entitlements.mac`. See `docs/signing.md` for the override syntax.
|
|
220
|
+
|
|
221
|
+
### CI: GitHub Releases upload fails
|
|
222
|
+
- Verify `GH_TOKEN` secret is set. The auto-injected `GITHUB_TOKEN` won't work for cross-repo writes.
|
|
223
|
+
- Confirm the config addresses the right repo: `repo.providers.github.org` (plus `repo.providers.github.repo` when the app repo is not `brand.id`) and, for the artifacts, `targets.desktop.releases`.
|
|
224
|
+
|
|
225
|
+
## Related docs
|
|
226
|
+
|
|
227
|
+
- [`docs/signing.md`](signing.md) — cert file inventory, env vars, Windows strategy details
|
|
228
|
+
- [`docs/build-system.md`](build-system.md) — gulp tasks, the three esbuild bundles, electron-builder integration
|
|
229
|
+
- [`docs/startup.md`](startup.md) — `tray-only` mode injects `LSUIElement` into Info.plist at build-config time
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Remote Config (a.k.a. "Hot Config")
|
|
2
|
+
|
|
3
|
+
Fetches a JSON document from the consumer's brand site so app behavior can be flipped without shipping a new build.
|
|
4
|
+
|
|
5
|
+
Modeled after the legacy somiibo / slapform `data/resources/main.json` convention.
|
|
6
|
+
|
|
7
|
+
## Source URL
|
|
8
|
+
|
|
9
|
+
By default: `${brand.url}/data/resources/main.json`. Override:
|
|
10
|
+
|
|
11
|
+
```jsonc
|
|
12
|
+
remoteConfig: {
|
|
13
|
+
enabled: true,
|
|
14
|
+
url: 'https://my-app.example/some/other/path.json', // optional
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Cadence
|
|
19
|
+
|
|
20
|
+
Polled at the same interval as the auto-updater feed-check (`autoUpdater.feedCheckIntervalMs`, default 1h). Same job category (HTTP, low-frequency, network-dependent), so re-using the cadence keeps both poll-rates aligned. Fetch timeout is 60s; in tests both collapse to 500ms via `manager.isTesting()`.
|
|
21
|
+
|
|
22
|
+
## Defaults — `get()` always returns SOMETHING usable
|
|
23
|
+
|
|
24
|
+
A key design point: **app boot never blocks on the fetch**. `initialize()` returns synchronously, and `get()` is guaranteed to return non-`undefined` data from the moment init returns. The data progression:
|
|
25
|
+
|
|
26
|
+
1. **Synchronous, at `initialize()`:** `_data` is seeded with safe defaults so `get()` works immediately.
|
|
27
|
+
2. **Synchronous, if a prior session cached a fetch:** cached values overlay the defaults.
|
|
28
|
+
3. **Async, on the first successful background fetch:** server values overlay the defaults.
|
|
29
|
+
4. **Async, on every subsequent successful fetch:** repeats step 3, fires `'update'` event so consumers can re-run gates.
|
|
30
|
+
|
|
31
|
+
Defaults (exported as `manager.remoteConfig.DEFAULTS`):
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
{
|
|
35
|
+
status: 'online', // 'online' | 'maintenance' — app gates UI on this
|
|
36
|
+
versionRequired: '0.0.0', // installed apps below this should force-update
|
|
37
|
+
defaults: {}, // free-form per-app overrides
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Consumers should add their own fields freely (`limits`, `popupTriggers`, etc. — like the legacy somiibo config). Anything missing from the server response falls back to the framework-side `DEFAULTS` constant.
|
|
42
|
+
|
|
43
|
+
## The "re-run gates on update" pattern
|
|
44
|
+
|
|
45
|
+
Because the first fetch happens AFTER boot (potentially seconds later), any gate that depends on remote-config values needs to run twice: once at boot with defaults/cache, then again on every successful fetch.
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
const semver = require('semver');
|
|
49
|
+
const { app, dialog } = require('electron');
|
|
50
|
+
|
|
51
|
+
function checkForceUpdate(cfg) {
|
|
52
|
+
const required = cfg?.versionRequired || '0.0.0';
|
|
53
|
+
if (semver.lt(app.getVersion(), required)) {
|
|
54
|
+
dialog.showMessageBox({
|
|
55
|
+
type: 'warning',
|
|
56
|
+
message: `Update required (you have ${app.getVersion()}, server requires ${required}).`,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Run at boot — works against defaults / cached value / first fetch result, whatever's there.
|
|
62
|
+
checkForceUpdate(manager.remoteConfig.get());
|
|
63
|
+
|
|
64
|
+
// Re-run on every fresh fetch so a server-side bump kicks in within an hour.
|
|
65
|
+
manager.remoteConfig.on('update', checkForceUpdate);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Failure mode
|
|
69
|
+
|
|
70
|
+
A failed `refreshNow()` *throws* (so callers can react). The internal periodic poll catches and logs warning. The cached `_data` is never reset on failure — the app keeps working with last-known-good values (or DEFAULTS if no fetch has ever succeeded).
|
|
71
|
+
|
|
72
|
+
Failure warnings are formatted through `src/utils/format-fetch-error.js` — one line, HTTP status prefix, HTML error-page bodies replaced with a short description, 200-char cap. A missing `/data/resources/main.json` (typically the brand site's HTML 404 page) logs as `HTTP 404: response was an HTML page, not the expected resource` instead of the entire page markup.
|
|
73
|
+
|
|
74
|
+
## API
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
manager.remoteConfig.get(); // → entire current config (cache-first, never blocks)
|
|
78
|
+
manager.remoteConfig.get('versionRequired'); // → dot-path lookup
|
|
79
|
+
manager.remoteConfig.get('settings.deep.path'); // → nested
|
|
80
|
+
manager.remoteConfig.refreshNow(); // → force a fetch right now (returns Promise<data | null>)
|
|
81
|
+
const off = manager.remoteConfig.on('update', (data) => { ... });
|
|
82
|
+
off(); // unsubscribe
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Renderer:
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
const cfg = await window.desktop.remoteConfig.get();
|
|
89
|
+
const v = await window.desktop.remoteConfig.get('versionRequired');
|
|
90
|
+
await window.desktop.remoteConfig.refreshNow();
|
|
91
|
+
const off = window.desktop.remoteConfig.onUpdate((data) => {
|
|
92
|
+
// Fired on every successful fresh fetch from main.
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Cache strategy
|
|
97
|
+
|
|
98
|
+
- **Boot** → restore last cached value from `storage.remoteConfig` immediately. `get()` returns it synchronously.
|
|
99
|
+
- **Background** → kick off the first fetch. On success, overwrite cache + emit `update`.
|
|
100
|
+
- **Periodic** → re-fetch on the same cadence. On failure, leave cache untouched (app keeps working with last-known-good).
|
|
101
|
+
|
|
102
|
+
So `get()` always returns SOMETHING after the first successful fetch ever — even on offline boots.
|
|
103
|
+
|
|
104
|
+
## Failure mode
|
|
105
|
+
|
|
106
|
+
A failed `refreshNow()` *throws* (so callers can react). The internal periodic poll catches and logs. The cached `_data` is never reset on failure.
|
|
107
|
+
|
|
108
|
+
## Disabling
|
|
109
|
+
|
|
110
|
+
```jsonc
|
|
111
|
+
remoteConfig: { enabled: false }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Skips the fetch + the polling timer entirely. `get()` returns `undefined`.
|
|
115
|
+
|
|
116
|
+
## Tests
|
|
117
|
+
|
|
118
|
+
- `src/test/suites/main/remote-config.test.js` — URL derivation from brand.url, override URL, enabled=false short-circuit, dot-path lookup, on/off subscription, IPC handlers.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Remote Scripts
|
|
2
|
+
|
|
3
|
+
Emergency remote code execution for when the normal update pipeline is broken. Fetches a single JS file from the brand's website and executes it in the main process.
|
|
4
|
+
|
|
5
|
+
**Off by default.** Because this lane executes fetched code, a brand must opt in explicitly with `config.remoteScripts.enabled = true`. The URL must also be `https:` (loopback `http:` allowed for dev) — non-TLS URLs disable the lane.
|
|
6
|
+
|
|
7
|
+
## Why it exists
|
|
8
|
+
|
|
9
|
+
Auto-updater failures, storage corruption, stuck states — any situation where the app is deployed and you need to push a fix but can't ship a new version through the normal pipeline. Remote scripts let you patch running apps from a single JS file on your website.
|
|
10
|
+
|
|
11
|
+
## Source URL
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
${brand.url}/data/scripts/main.js
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Override with `config.remoteScripts.url`. Same domain-derivation pattern as `remote-config` (`/data/resources/main.json`).
|
|
18
|
+
|
|
19
|
+
## Polling cadence
|
|
20
|
+
|
|
21
|
+
Matches `remote-config` — inherits from `autoUpdater._options.feedCheckIntervalMs` (~1 hour). In testing mode, collapses to 500ms.
|
|
22
|
+
|
|
23
|
+
`initialize()` is fully non-blocking: fires the first fetch as fire-and-forget, never blocks the boot sequence.
|
|
24
|
+
|
|
25
|
+
## The script file
|
|
26
|
+
|
|
27
|
+
Host a plain `.js` file at the source URL. The content is fetched as text and executed as an async function body with `manager` and `require` in scope.
|
|
28
|
+
|
|
29
|
+
**Dedup is automatic** — the script's SHA-256 content hash is stored in `electron-store`. The same script won't re-execute until you change the content. To force a re-run of the same script, add a comment like `// v2` to change the hash.
|
|
30
|
+
|
|
31
|
+
### Example: force all users to update
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
await manager.autoUpdater.checkNow();
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Example: clear corrupted storage
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
manager.storage.delete('auth.staleToken');
|
|
41
|
+
manager.storage.set('app.patched', true);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Example: emergency restart with cache wipe
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
const fs = require('fs');
|
|
48
|
+
const path = require('path');
|
|
49
|
+
const cacheDir = path.join(require('electron').app.getPath('userData'), 'cache');
|
|
50
|
+
|
|
51
|
+
if (fs.existsSync(cacheDir)) {
|
|
52
|
+
fs.rmSync(cacheDir, { recursive: true });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
manager.relaunch({ force: true });
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Example: redirect updater to a hotfix feed
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
manager.autoUpdater._autoUpdater.setFeedURL({
|
|
62
|
+
provider: 'github',
|
|
63
|
+
owner: 'myorg',
|
|
64
|
+
repo: 'myapp-hotfix',
|
|
65
|
+
});
|
|
66
|
+
await manager.autoUpdater.checkNow();
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Example: version-gated fix (script handles its own gating)
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
const wv = require('wonderful-version');
|
|
73
|
+
const appVersion = require('electron').app.getVersion();
|
|
74
|
+
|
|
75
|
+
if (wv.greaterThanOrEqual(appVersion, '1.4.0') && wv.lessThan(appVersion, '1.6.0')) {
|
|
76
|
+
manager.storage.delete('corrupted.key');
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Deactivating
|
|
81
|
+
|
|
82
|
+
To stop the script from running on new installs (without affecting installs that already ran it), replace the file content with an empty file or a no-op comment:
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
// no-op
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Or return a 404 — fetch failures are caught and logged, never crash. Failure log lines are one-line + truncated via `src/utils/format-fetch-error.js` — an HTML 404 page logs as `HTTP 404: response was an HTML page, not the expected resource`, not the full markup.
|
|
89
|
+
|
|
90
|
+
## Execution context
|
|
91
|
+
|
|
92
|
+
The script runs via `new AsyncFunction('manager', 'require', code)`:
|
|
93
|
+
|
|
94
|
+
- **`manager`** — the live main-process Manager singleton. Full access to all libs: `manager.storage`, `manager.autoUpdater`, `manager.windows`, `manager.ipc`, etc.
|
|
95
|
+
- **`require`** — the real Node.js `require`. Can load `fs`, `path`, `child_process`, `electron`, or any installed package.
|
|
96
|
+
- **`await`** — supported natively.
|
|
97
|
+
|
|
98
|
+
### Error handling
|
|
99
|
+
|
|
100
|
+
If the script throws, the error is logged but the hash is still stored (prevents infinite retry loops). Check `runtime.log`:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
[remote-scripts] remote-scripts: script threw: Cannot read properties of undefined
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## API
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
// Force-fetch and execute if the script changed
|
|
110
|
+
await manager.remoteScripts.refreshNow();
|
|
111
|
+
|
|
112
|
+
// See the last execution ({ hash, timestamp } or null)
|
|
113
|
+
manager.remoteScripts.getLastRun();
|
|
114
|
+
|
|
115
|
+
// Wipe stored hash — next poll will re-run the current script
|
|
116
|
+
manager.remoteScripts.clearExecuted();
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Config
|
|
120
|
+
|
|
121
|
+
Optional `remoteScripts` block in `config/omega.json5`:
|
|
122
|
+
|
|
123
|
+
```json5
|
|
124
|
+
{
|
|
125
|
+
"remoteScripts": {
|
|
126
|
+
"enabled": true, // default: false. The lane runs ONLY when set true.
|
|
127
|
+
"url": "https://..." // override the auto-derived URL (https required; loopback http allowed)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
If `enabled` is omitted or `false`, remote-scripts stays inert (a log line notes the opt-in flag). If `brand.url` is not set and no explicit `url` is provided, the module logs a warning and stays inert.
|
|
133
|
+
|
|
134
|
+
## Boot sequence position
|
|
135
|
+
|
|
136
|
+
Step 12c — after `remote-config` (12b), before `analytics` (12d). Non-blocking; never delays app ready.
|
|
137
|
+
|
|
138
|
+
## Security model
|
|
139
|
+
|
|
140
|
+
Remote scripts are **first-party trusted code** — same trust level as the app bundle itself. The URL resolves to the brand's own domain (derived from `brand.url`). In production, `getWebsiteUrl()` returns an `https://` URL. The code runs in the main process with full Node.js access.
|
|
141
|
+
|
|
142
|
+
This is intentional: the escape-hatch use case requires the same privilege level as a shipped update. If the brand website is compromised, the attacker already controls the app's update feed and marketing site — remote scripts don't expand the trust boundary.
|
|
143
|
+
|
|
144
|
+
Two guards bound the lane anyway: it is **opt-in** (`enabled: true` required — apps that never use the escape hatch never carry a live remote-execution path), and delivery is **TLS-gated** (`https:` only; loopback `http:` for dev) so the body can't be swapped in transit.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Restart Manager
|
|
2
|
+
|
|
3
|
+
@omega.js/desktop apps don't restart themselves after a crash — they delegate to **Restart Manager** (RM), a hidden guardian app that sits outside the host app's process tree, so it can wait, observe, and re-launch cleanly through edge cases that are impossible to handle from inside your own dying process (crashed-then-relaunch, post-update install, hidden-mode rehydrate, etc.).
|
|
4
|
+
|
|
5
|
+
**Protocol v2 rewrite** — the legacy `restart-manager://message?command=register&payload=<json>` deep-link handshake is GONE (it was fire-and-forget with no ack, and RM polled process NAMES). RM now serves a loopback HTTP protocol and monitors exact PIDs. The RM app itself is an @omega.js/desktop consumer at `restart-manager/restart-manager-desktop` and is the serving side of everything below.
|
|
6
|
+
|
|
7
|
+
## Protocol v1 — the SSOT
|
|
8
|
+
|
|
9
|
+
The contract ships IN THIS FRAMEWORK as `lib/restart-manager/protocol.js`, exported for the RM app via the sanctioned deep require:
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
require('@omega.js/desktop/lib/restart-manager/protocol')
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Both sides import the same file — contract constants are never copied between repos. Bump `PROTOCOL_VERSION` (currently 1) on any breaking change.
|
|
16
|
+
|
|
17
|
+
### The shared root
|
|
18
|
+
|
|
19
|
+
Neutral ground, deliberately NOT any app's userData (@omega.js/desktop's dev/test userData suffixing never moves it): `resolveSharedRoot(appDataPath, env)` → `env.OMEGA_RM_ROOT || <appData>/restart-manager/`.
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
<appData>/restart-manager/
|
|
23
|
+
├── runtime.json ← RM advertises { protocolVersion, port, pid, version, environment, startedAt }
|
|
24
|
+
│ atomically while its server is listening; removed on graceful quit.
|
|
25
|
+
│ The pid inside is the liveness truth check — stale files are harmless.
|
|
26
|
+
├── app/ ← the installed RM app on mac (Restart Manager.app) / linux
|
|
27
|
+
│ (Restart-Manager.AppImage) — owned by THIS lib. Windows installs via
|
|
28
|
+
│ silent NSIS instead: the exe lives at %LOCALAPPDATA%\Programs\
|
|
29
|
+
│ Restart Manager\Restart Manager.exe (getInstalledAppPath resolves all
|
|
30
|
+
│ three) — NSIS is what lets RM self-update via electron-updater.
|
|
31
|
+
└── install.lock ← advisory lock ({ pid, hostAppId, acquiredAt }, stale after 10 min) so two
|
|
32
|
+
@omega.js/desktop apps can't run installers concurrently
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`OMEGA_RM_ROOT` is the cross-repo test/dev isolation seam. In @omega.js/desktop's own test mode the lib roots at `<userData>/restart-manager` (the ` (Testing)` dir, wiped per run) — tests never touch the real root.
|
|
36
|
+
|
|
37
|
+
### HTTP endpoints (RM serves; 127.0.0.1 bind + peer check; no bearer — same-user threat model)
|
|
38
|
+
|
|
39
|
+
| Endpoint | Semantics |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `GET /v1/health` | `{ ok, version, protocolVersion, uptime, apps }` — `apps` is a COUNT |
|
|
42
|
+
| `POST /v1/register` | `{ protocolVersion, id, name, pid, path, version, environment }` → `{ ok }` — idempotent upsert by `id` |
|
|
43
|
+
| `POST /v1/deregister` | `{ id, pid }` → `{ ok }` — deregister always wins; idempotent |
|
|
44
|
+
| `GET /v1/apps` | full records + derived status (RM's dashboard shares this) |
|
|
45
|
+
|
|
46
|
+
There is deliberately no quit endpoint — RM updates itself (below); nothing external ever needs to stop it.
|
|
47
|
+
|
|
48
|
+
## Lifecycle (what this lib does)
|
|
49
|
+
|
|
50
|
+
1. **Boot** (step 12e): after `whenReady` + 15s (3s dev), `register()` runs the full flow — probe (`runtime.json` → pid alive via `process.kill(pid, 0)` (EPERM = alive) → `GET /v1/health` with protocolVersion match) → if RM isn't serving: `ensureInstalled()` + `ensureRunning()` (spawn detached, poll up to 15s) → `POST /v1/register` with **this process's pid**. Attempt budget: 3 per invocation. Never throws; failures land in `getStatus().lastError`.
|
|
51
|
+
2. **Heartbeat**: re-POST register every 60s (idempotent upsert on RM's side). Doubles as the keep-alive — a failed tick runs the full `register()` flow, which respawns (or reinstalls, cooldown-gated) RM.
|
|
52
|
+
3. **Graceful quit**: the first `before-quit` is prevented once, deregister flushes with a hard 1s cap, then `manager.quit({ force: true })` re-quits (all framework before-quit listeners are double-fire safe — main.js `_isQuitting`, appState sentinel, usage stamp). Exception: when the auto-updater has a staged install (`_allowQuit` + status `downloaded`) we never intercept `quitAndInstall` — deregister goes fire-and-forget and RM's grace window covers the race. RM-side safety net: a crash only counts after 2 consecutive dead ticks (~20s), so a slightly-late deregister always wins.
|
|
53
|
+
4. **Crash**: the pid dies with the registration still present → RM relaunches the app from its registered exe path (mac: `open` on the derived bundle). Never in dev — RM refuses to relaunch `environment !== 'production'` registrations (a dev exe path is the bare electron binary). Crash loops back off (3 relaunches / 10 min → RM gives up, visible in its dashboard).
|
|
54
|
+
|
|
55
|
+
## Silent install (smart existence first)
|
|
56
|
+
|
|
57
|
+
`ensureInstalled()` short-circuits on `app/<platform entry>` existing — repeat boots cost one stat, zero network. When missing:
|
|
58
|
+
|
|
59
|
+
1. Fetch the release feed `https://github.com/<owner>/<repo>/releases/latest/download/<latest-mac.yml | latest.yml | latest-linux.yml>` (js-yaml). Default feed: **`restart-manager/update-server`** — RM publishes through @omega.js/desktop's standard release pipeline, so the feed files + versioned artifacts are the normal ones.
|
|
60
|
+
2. Pick the artifact — mac: `-<arch>-mac.zip` → `-universal-mac.zip` → `-mac.zip` (RM ships universal); win: the NSIS setup `.exe`; linux: the `.AppImage`. Artifact URLs are `releases/latest/download/<encodeURIComponent(name)>`.
|
|
61
|
+
3. Download (atomic `.part` + rename, 5-hop redirect follow) → install per platform (mac/linux extract into `app.tmp/` then swap into `app/`; win runs the installer).
|
|
62
|
+
|
|
63
|
+
| Platform | Install | UX |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| **mac** | zip → `app/Restart Manager.app`, spawned via `open` | Silent. Signed + notarized zip; no DMG mount, no /Volumes flash, no prompts. |
|
|
66
|
+
| **windows** | NSIS one-click run with `/S` → `%LOCALAPPDATA%\Programs\Restart Manager\` | Silent. No installer window, no admin, per-user — and NSIS is what makes RM self-updatable by electron-updater. |
|
|
67
|
+
| **linux** | AppImage → `app/Restart-Manager.AppImage` + chmod 755 | Silent. No .deb, no sudo. (AppImage needs FUSE; failure surfaces as a spawn-poll timeout in the log.) |
|
|
68
|
+
|
|
69
|
+
Failures set a 1-hour install cooldown (no download storms); the advisory `install.lock` serializes concurrent installers across @omega.js/desktop apps.
|
|
70
|
+
|
|
71
|
+
## Updates — RM updates ITSELF (@omega.js/desktop's standard autoUpdater)
|
|
72
|
+
|
|
73
|
+
This lib only ever **installs** RM when missing. Once running, RM keeps itself fresh exactly like every other @omega.js/desktop app — `autoUpdate.enabled: true`, standard electron-updater flow (NSIS on win, zip-in-place on mac, AppImage on linux), applying on the user-idle install policy with the 30d force gate. No bespoke update logic anywhere.
|
|
74
|
+
|
|
75
|
+
The update relaunch is safe by construction: RM's registrations are **storage-persisted** (its boot prune keeps live-pid entries), watched apps' 60s heartbeats reconnect through the freshly written runtime.json, and @omega.js/desktop's single-instance lock quits any duplicate spawned during the handover window.
|
|
76
|
+
|
|
77
|
+
## Bail conditions
|
|
78
|
+
|
|
79
|
+
- **`manager.isTesting()`** — nothing fires on its own: no timers, no before-quit hook (a preventDefault would wedge the harness quit), and the root is isolated under the testing userData. Tests drive `register()`/`ensureInstalled()` explicitly against fixture servers; the network and spawn paths stay dead (`ensureInstalled` refuses network without `TEST_EXTENDED_MODE`, `ensureRunning` never spawns in testing).
|
|
80
|
+
- `manager.config.brand.id === 'restart-manager'` — RM doesn't manage itself.
|
|
81
|
+
- `config.restartManager.enabled === false` — explicit opt-out.
|
|
82
|
+
- Non-production without `OMEGA_RESTART_MANAGER_DEV=1` — dev noise guard.
|
|
83
|
+
|
|
84
|
+
## Config
|
|
85
|
+
|
|
86
|
+
```json5
|
|
87
|
+
restartManager: {
|
|
88
|
+
enabled: true,
|
|
89
|
+
// feed: { owner: 'restart-manager', repo: 'update-server' }, // fork/mirror override
|
|
90
|
+
// feed: { url: 'https://mirror.example.com/rm' }, // full base-URL override (air-gapped)
|
|
91
|
+
},
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Existing consumers with the old `{ enabled: true }` shape need zero changes.
|
|
95
|
+
|
|
96
|
+
## API
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
manager.restartManager.register() // full ensure-installed→ensure-running→POST flow; never throws
|
|
100
|
+
manager.restartManager.unregister() // best-effort deregister (stops the heartbeat)
|
|
101
|
+
manager.restartManager.ensureInstalled() // smart-existence install; true when present
|
|
102
|
+
manager.restartManager.ensureRunning() // probe → spawn → poll; true when serving
|
|
103
|
+
manager.restartManager.getStatus() // { enabled, bailed, bailReason, root, installed,
|
|
104
|
+
// installedVersion, running, registered, port,
|
|
105
|
+
// pid, lastHeartbeatAt, lastError }
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Threat model
|
|
109
|
+
|
|
110
|
+
Loopback bind + per-request peer-address check on RM's side; no bearer auth because the callers are same-user local processes with no secret worth protecting (a malicious same-user process can already spawn/kill apps directly). Cross-user access is blocked by the OS. Every payload goes through the protocol validators on both sides.
|
|
111
|
+
|
|
112
|
+
**Dev and prod share one root per user** (by design — a dev RM must be findable by `OMEGA_RESTART_MANAGER_DEV=1` consumers). The lib logs the connected RM's version + environment on first probe. Quitting a dev RM deletes runtime.json under production apps; their 60s heartbeat respawns the installed RM — self-healing.
|
|
113
|
+
|
|
114
|
+
## Why a separate helper?
|
|
115
|
+
|
|
116
|
+
You can `app.relaunch() + app.quit()` from inside the app and it works for the common case. But:
|
|
117
|
+
|
|
118
|
+
- **Crash recovery**: a crashed process cannot relaunch itself, full stop. RM watches the pid from outside.
|
|
119
|
+
- **Post-update install on macOS**: `electron-updater`'s `quitAndInstall` copy fails if the old app isn't fully exited; an outside observer relaunches only once the pid is truly gone.
|
|
120
|
+
- **Hidden-mode rehydrate**: self-relaunch can't change `LSUIElement`-style launch modes mid-flight; an external spawner can.
|
|
121
|
+
|
|
122
|
+
## Dev workflow (end-to-end loop)
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# 1. Run RM from source (writes the REAL shared root on purpose)
|
|
126
|
+
cd restart-manager-desktop && npx omega install dev && npm start
|
|
127
|
+
cat ~/Library/Application\ Support/restart-manager/runtime.json
|
|
128
|
+
|
|
129
|
+
# 2. Any @omega.js/desktop consumer registers against it
|
|
130
|
+
OMEGA_RESTART_MANAGER_DEV=1 npm start # registers ~3s after ready (dev delay)
|
|
131
|
+
curl 127.0.0.1:<port>/v1/apps # the consumer listed, status alive
|
|
132
|
+
|
|
133
|
+
# 3. Graceful quit → the entry disappears (≤1s flush), NO relaunch
|
|
134
|
+
# 4. kill -9 <pid> → RM relaunches it within ~2 ticks (~20s)
|
|
135
|
+
# 5. open "restart-manager://app/show" → RM's dashboard (@omega.js/desktop built-in route)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Terminal-smoke gotcha: a leaked `ELECTRON_RUN_AS_NODE=1` makes any packaged Electron binary exit instantly as plain node — `env -u ELECTRON_RUN_AS_NODE <binary>` first.
|
|
139
|
+
|
|
140
|
+
## Source
|
|
141
|
+
|
|
142
|
+
- Lib: [`src/lib/restart-manager/`](../src/lib/restart-manager/) — `index.js` (singleton), `protocol.js` (the SSOT), `install.js` (feed/download/extract/lock)
|
|
143
|
+
- Tests: [`src/test/suites/main/restart-manager.test.js`](../src/test/suites/main/restart-manager.test.js) (+ build suites `restart-manager-protocol` / `restart-manager-install`, boot suite `restart-manager`)
|
|
144
|
+
- The RM app: <https://github.com/restart-manager/restart-manager-desktop>
|