@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.
Files changed (818) hide show
  1. package/LICENSE +98 -0
  2. package/README.md +166 -0
  3. package/bin/omega +2 -0
  4. package/bin/omega-desktop +2 -0
  5. package/bin/omg +2 -0
  6. package/dist/assets/css/core/_fontawesome.scss +146 -0
  7. package/dist/assets/css/core/_initialize.scss +38 -0
  8. package/dist/assets/css/omega-desktop.scss +39 -0
  9. package/dist/assets/css/shell/_index.scss +207 -0
  10. package/dist/assets/css/tokens/_index.scss +166 -0
  11. package/dist/assets/js/bootstrap.bundle.js +1 -0
  12. package/dist/assets/js/core/app-shell.js +136 -0
  13. package/dist/assets/themes/_template/README.md +115 -0
  14. package/dist/assets/themes/_template/_config.scss +60 -0
  15. package/dist/assets/themes/_template/_theme.js +14 -0
  16. package/dist/assets/themes/_template/_theme.scss +28 -0
  17. package/dist/assets/themes/_template/css/base/_root.scss +19 -0
  18. package/dist/assets/themes/_template/css/components/_components.scss +23 -0
  19. package/dist/assets/themes/base/README.md +5 -0
  20. package/dist/assets/themes/base/_components/data/org-chart/component.html +33 -0
  21. package/dist/assets/themes/base/_components/data/org-chart/component.json5 +33 -0
  22. package/dist/assets/themes/base/_components/data/org-chart/component.scss +183 -0
  23. package/dist/assets/themes/base/_components/heading/masthead/component.html +22 -0
  24. package/dist/assets/themes/base/_components/heading/masthead/component.json5 +30 -0
  25. package/dist/assets/themes/base/_components/heading/section-head/component.html +18 -0
  26. package/dist/assets/themes/base/_components/heading/section-head/component.json5 +27 -0
  27. package/dist/assets/themes/base/_components/pricing/features/component.html +29 -0
  28. package/dist/assets/themes/base/_components/pricing/features/component.json5 +30 -0
  29. package/dist/assets/themes/base/_hero/orbit/index.html +30 -0
  30. package/dist/assets/themes/base/_hero/orbit/script.js +33 -0
  31. package/dist/assets/themes/base/_hero/orbit/style.scss +133 -0
  32. package/dist/assets/themes/base/_includes/admin/sections/sidebar.html +3 -0
  33. package/dist/assets/themes/base/_includes/admin/sections/topbar.html +3 -0
  34. package/dist/assets/themes/base/_includes/backend/sections/sidebar.html +3 -0
  35. package/dist/assets/themes/base/_includes/backend/sections/topbar.html +3 -0
  36. package/dist/assets/themes/base/_includes/frontend/components/connection-card.html +49 -0
  37. package/dist/assets/themes/base/_includes/frontend/components/post-card.html +54 -0
  38. package/dist/assets/themes/base/_includes/frontend/sections/account-connections.html +42 -0
  39. package/dist/assets/themes/base/_includes/frontend/sections/account-section-header.html +11 -0
  40. package/dist/assets/themes/base/_includes/frontend/sections/footer.html +154 -0
  41. package/dist/assets/themes/base/_includes/frontend/sections/nav.html +276 -0
  42. package/dist/assets/themes/base/_includes/global/sections/account.html +72 -0
  43. package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +248 -0
  44. package/dist/assets/themes/base/_includes/global/sections/app-topbar.html +228 -0
  45. package/dist/assets/themes/base/_includes/global/sections/page-header.html +99 -0
  46. package/dist/assets/themes/base/_layouts/admin/core/minimal-viewport-locked.html +22 -0
  47. package/dist/assets/themes/base/_layouts/admin/core/minimal.html +23 -0
  48. package/dist/assets/themes/base/_layouts/backend/core/base.html +57 -0
  49. package/dist/assets/themes/base/_layouts/backend/core/minimal-viewport-locked.html +32 -0
  50. package/dist/assets/themes/base/_layouts/backend/core/minimal.html +32 -0
  51. package/dist/assets/themes/base/_layouts/backend/pages/dashboard/index.html +230 -0
  52. package/dist/assets/themes/base/_layouts/frontend/core/base.html +31 -0
  53. package/dist/assets/themes/base/_layouts/frontend/core/cover.html +40 -0
  54. package/dist/assets/themes/base/_layouts/frontend/core/minimal.html +47 -0
  55. package/dist/assets/themes/base/_layouts/frontend/pages/404.html +54 -0
  56. package/dist/assets/themes/base/_layouts/frontend/pages/about.html +144 -0
  57. package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +2104 -0
  58. package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/alternative.html +319 -0
  59. package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +186 -0
  60. package/dist/assets/themes/base/_layouts/frontend/pages/app.html +142 -0
  61. package/dist/assets/themes/base/_layouts/frontend/pages/auth/reset.html +53 -0
  62. package/dist/assets/themes/base/_layouts/frontend/pages/auth/signin.html +90 -0
  63. package/dist/assets/themes/base/_layouts/frontend/pages/auth/signup.html +141 -0
  64. package/dist/assets/themes/base/_layouts/frontend/pages/auth/token.html +44 -0
  65. package/dist/assets/themes/base/_layouts/frontend/pages/blog/categories/category.html +88 -0
  66. package/dist/assets/themes/base/_layouts/frontend/pages/blog/categories/index.html +88 -0
  67. package/dist/assets/themes/base/_layouts/frontend/pages/blog/index.html +255 -0
  68. package/dist/assets/themes/base/_layouts/frontend/pages/blog/post.html +261 -0
  69. package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/index.html +84 -0
  70. package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/tag.html +88 -0
  71. package/dist/assets/themes/base/_layouts/frontend/pages/collection/category.html +72 -0
  72. package/dist/assets/themes/base/_layouts/frontend/pages/collection/document.html +54 -0
  73. package/dist/assets/themes/base/_layouts/frontend/pages/collection/index.html +84 -0
  74. package/dist/assets/themes/base/_layouts/frontend/pages/connections/callback.html +55 -0
  75. package/dist/assets/themes/base/_layouts/frontend/pages/contact.html +214 -0
  76. package/dist/assets/themes/base/_layouts/frontend/pages/download.html +793 -0
  77. package/dist/assets/themes/base/_layouts/frontend/pages/extension/index.html +253 -0
  78. package/dist/assets/themes/base/_layouts/frontend/pages/extension/installed.html +198 -0
  79. package/dist/assets/themes/base/_layouts/frontend/pages/feedback.html +171 -0
  80. package/dist/assets/themes/base/_layouts/frontend/pages/index.html +66 -0
  81. package/dist/assets/themes/base/_layouts/frontend/pages/legal/document.html +78 -0
  82. package/dist/assets/themes/base/_layouts/frontend/pages/payment/checkout.html +459 -0
  83. package/dist/assets/themes/base/_layouts/frontend/pages/payment/confirmation.html +131 -0
  84. package/dist/assets/themes/base/_layouts/frontend/pages/portal/email-preferences.html +104 -0
  85. package/dist/assets/themes/base/_layouts/frontend/pages/pricing.html +596 -0
  86. package/dist/assets/themes/base/_layouts/frontend/pages/status.html +361 -0
  87. package/dist/assets/themes/base/_layouts/frontend/pages/team/index.html +210 -0
  88. package/dist/assets/themes/base/_layouts/frontend/pages/team/member.html +125 -0
  89. package/dist/assets/themes/base/_layouts/frontend/pages/updates/index.html +119 -0
  90. package/dist/assets/themes/base/_layouts/frontend/pages/updates/update.html +118 -0
  91. package/dist/assets/themes/base/_sections/about/hero/section.html +68 -0
  92. package/dist/assets/themes/base/_sections/about/hero/section.json5 +58 -0
  93. package/dist/assets/themes/base/_sections/about/letter/section.html +60 -0
  94. package/dist/assets/themes/base/_sections/about/letter/section.json5 +56 -0
  95. package/dist/assets/themes/base/_sections/about/photo-band/section.html +24 -0
  96. package/dist/assets/themes/base/_sections/about/photo-band/section.json5 +23 -0
  97. package/dist/assets/themes/base/_sections/about/principles/section.html +17 -0
  98. package/dist/assets/themes/base/_sections/about/principles/section.json5 +34 -0
  99. package/dist/assets/themes/base/_sections/about/timeline/section.html +20 -0
  100. package/dist/assets/themes/base/_sections/about/timeline/section.json5 +34 -0
  101. package/dist/assets/themes/base/_sections/marketing/bento/section.html +91 -0
  102. package/dist/assets/themes/base/_sections/marketing/bento/section.json5 +152 -0
  103. package/dist/assets/themes/base/_sections/marketing/cta/section.html +44 -0
  104. package/dist/assets/themes/base/_sections/marketing/cta/section.json5 +47 -0
  105. package/dist/assets/themes/base/_sections/marketing/faq/section.html +52 -0
  106. package/dist/assets/themes/base/_sections/marketing/faq/section.json5 +68 -0
  107. package/dist/assets/themes/base/_sections/marketing/hero/section.html +349 -0
  108. package/dist/assets/themes/base/_sections/marketing/hero/section.json5 +335 -0
  109. package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.html +38 -0
  110. package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.js +86 -0
  111. package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.json5 +29 -0
  112. package/dist/assets/themes/base/_sections/marketing/pricing-cards/section.html +115 -0
  113. package/dist/assets/themes/base/_sections/marketing/pricing-cards/section.json5 +72 -0
  114. package/dist/assets/themes/base/_sections/marketing/product-demo/section.html +62 -0
  115. package/dist/assets/themes/base/_sections/marketing/product-demo/section.js +44 -0
  116. package/dist/assets/themes/base/_sections/marketing/product-demo/section.json5 +52 -0
  117. package/dist/assets/themes/base/_sections/marketing/prose/section.html +22 -0
  118. package/dist/assets/themes/base/_sections/marketing/prose/section.json5 +41 -0
  119. package/dist/assets/themes/base/_sections/marketing/showcase/section.html +35 -0
  120. package/dist/assets/themes/base/_sections/marketing/showcase/section.json5 +52 -0
  121. package/dist/assets/themes/base/_sections/marketing/stats/section.html +32 -0
  122. package/dist/assets/themes/base/_sections/marketing/stats/section.json5 +44 -0
  123. package/dist/assets/themes/base/_sections/marketing/testimonials/section.html +54 -0
  124. package/dist/assets/themes/base/_sections/marketing/testimonials/section.json5 +70 -0
  125. package/dist/assets/themes/base/_sections/marketing/trusted-by/section.html +30 -0
  126. package/dist/assets/themes/base/_sections/marketing/trusted-by/section.json5 +38 -0
  127. package/dist/assets/themes/base/_sections/verts/unit/section.html +7 -0
  128. package/dist/assets/themes/base/_sections/verts/unit/section.js +22 -0
  129. package/dist/assets/themes/base/_sections/verts/unit/section.json5 +24 -0
  130. package/dist/assets/themes/base/_sections/verts/unit/section.scss +24 -0
  131. package/dist/assets/themes/base/_theme.js +13 -0
  132. package/dist/assets/themes/base/_theme.scss +4 -0
  133. package/dist/assets/themes/bootstrap/_theme.js +16 -0
  134. package/dist/assets/themes/bootstrap/_theme.scss +11 -0
  135. package/dist/assets/themes/bootstrap/js/index.esm.js +19 -0
  136. package/dist/assets/themes/bootstrap/js/index.umd.js +34 -0
  137. package/dist/assets/themes/bootstrap/js/src/alert.js +87 -0
  138. package/dist/assets/themes/bootstrap/js/src/base-component.js +86 -0
  139. package/dist/assets/themes/bootstrap/js/src/button.js +72 -0
  140. package/dist/assets/themes/bootstrap/js/src/carousel.js +474 -0
  141. package/dist/assets/themes/bootstrap/js/src/collapse.js +297 -0
  142. package/dist/assets/themes/bootstrap/js/src/dom/data.js +55 -0
  143. package/dist/assets/themes/bootstrap/js/src/dom/event-handler.js +317 -0
  144. package/dist/assets/themes/bootstrap/js/src/dom/manipulator.js +71 -0
  145. package/dist/assets/themes/bootstrap/js/src/dom/selector-engine.js +126 -0
  146. package/dist/assets/themes/bootstrap/js/src/dropdown.js +458 -0
  147. package/dist/assets/themes/bootstrap/js/src/modal.js +378 -0
  148. package/dist/assets/themes/bootstrap/js/src/offcanvas.js +282 -0
  149. package/dist/assets/themes/bootstrap/js/src/popover.js +97 -0
  150. package/dist/assets/themes/bootstrap/js/src/scrollspy.js +296 -0
  151. package/dist/assets/themes/bootstrap/js/src/tab.js +315 -0
  152. package/dist/assets/themes/bootstrap/js/src/toast.js +224 -0
  153. package/dist/assets/themes/bootstrap/js/src/tooltip.js +632 -0
  154. package/dist/assets/themes/bootstrap/js/src/util/backdrop.js +151 -0
  155. package/dist/assets/themes/bootstrap/js/src/util/component-functions.js +35 -0
  156. package/dist/assets/themes/bootstrap/js/src/util/config.js +65 -0
  157. package/dist/assets/themes/bootstrap/js/src/util/focustrap.js +115 -0
  158. package/dist/assets/themes/bootstrap/js/src/util/index.js +306 -0
  159. package/dist/assets/themes/bootstrap/js/src/util/sanitizer.js +117 -0
  160. package/dist/assets/themes/bootstrap/js/src/util/scrollbar.js +114 -0
  161. package/dist/assets/themes/bootstrap/js/src/util/swipe.js +146 -0
  162. package/dist/assets/themes/bootstrap/js/src/util/template-factory.js +160 -0
  163. package/dist/assets/themes/bootstrap/overrides/_accordion.scss +21 -0
  164. package/dist/assets/themes/bootstrap/overrides/_avatars.scss +51 -0
  165. package/dist/assets/themes/bootstrap/overrides/_blog-images.scss +45 -0
  166. package/dist/assets/themes/bootstrap/overrides/_buttons-adaptive.scss +141 -0
  167. package/dist/assets/themes/bootstrap/overrides/_color-shades.scss +25 -0
  168. package/dist/assets/themes/bootstrap/overrides/_cursor-utilities.scss +13 -0
  169. package/dist/assets/themes/bootstrap/overrides/_index.scss +30 -0
  170. package/dist/assets/themes/bootstrap/overrides/_links.scss +26 -0
  171. package/dist/assets/themes/bootstrap/overrides/_soft-colors.scss +99 -0
  172. package/dist/assets/themes/bootstrap/overrides/_spacing-extended.scss +74 -0
  173. package/dist/assets/themes/bootstrap/overrides/_spinners.scss +22 -0
  174. package/dist/assets/themes/bootstrap/overrides/_typography-utilities.scss +40 -0
  175. package/dist/assets/themes/bootstrap/scss/_accordion.scss +153 -0
  176. package/dist/assets/themes/bootstrap/scss/_alert.scss +68 -0
  177. package/dist/assets/themes/bootstrap/scss/_badge.scss +38 -0
  178. package/dist/assets/themes/bootstrap/scss/_breadcrumb.scss +40 -0
  179. package/dist/assets/themes/bootstrap/scss/_button-group.scss +147 -0
  180. package/dist/assets/themes/bootstrap/scss/_buttons.scss +216 -0
  181. package/dist/assets/themes/bootstrap/scss/_card.scss +238 -0
  182. package/dist/assets/themes/bootstrap/scss/_carousel.scss +226 -0
  183. package/dist/assets/themes/bootstrap/scss/_close.scss +66 -0
  184. package/dist/assets/themes/bootstrap/scss/_containers.scss +41 -0
  185. package/dist/assets/themes/bootstrap/scss/_dropdown.scss +250 -0
  186. package/dist/assets/themes/bootstrap/scss/_forms.scss +9 -0
  187. package/dist/assets/themes/bootstrap/scss/_functions.scss +302 -0
  188. package/dist/assets/themes/bootstrap/scss/_grid.scss +39 -0
  189. package/dist/assets/themes/bootstrap/scss/_helpers.scss +12 -0
  190. package/dist/assets/themes/bootstrap/scss/_images.scss +42 -0
  191. package/dist/assets/themes/bootstrap/scss/_list-group.scss +199 -0
  192. package/dist/assets/themes/bootstrap/scss/_maps.scss +174 -0
  193. package/dist/assets/themes/bootstrap/scss/_mixins.scss +42 -0
  194. package/dist/assets/themes/bootstrap/scss/_modal.scss +240 -0
  195. package/dist/assets/themes/bootstrap/scss/_nav.scss +197 -0
  196. package/dist/assets/themes/bootstrap/scss/_navbar.scss +289 -0
  197. package/dist/assets/themes/bootstrap/scss/_offcanvas.scss +147 -0
  198. package/dist/assets/themes/bootstrap/scss/_pagination.scss +109 -0
  199. package/dist/assets/themes/bootstrap/scss/_placeholders.scss +51 -0
  200. package/dist/assets/themes/bootstrap/scss/_popover.scss +196 -0
  201. package/dist/assets/themes/bootstrap/scss/_progress.scss +68 -0
  202. package/dist/assets/themes/bootstrap/scss/_reboot.scss +611 -0
  203. package/dist/assets/themes/bootstrap/scss/_root.scss +187 -0
  204. package/dist/assets/themes/bootstrap/scss/_spinners.scss +85 -0
  205. package/dist/assets/themes/bootstrap/scss/_tables.scss +171 -0
  206. package/dist/assets/themes/bootstrap/scss/_toasts.scss +73 -0
  207. package/dist/assets/themes/bootstrap/scss/_tooltip.scss +119 -0
  208. package/dist/assets/themes/bootstrap/scss/_transitions.scss +27 -0
  209. package/dist/assets/themes/bootstrap/scss/_type.scss +106 -0
  210. package/dist/assets/themes/bootstrap/scss/_utilities.scss +806 -0
  211. package/dist/assets/themes/bootstrap/scss/_variables-dark.scss +102 -0
  212. package/dist/assets/themes/bootstrap/scss/_variables.scss +1753 -0
  213. package/dist/assets/themes/bootstrap/scss/bootstrap-grid.scss +62 -0
  214. package/dist/assets/themes/bootstrap/scss/bootstrap-reboot.scss +10 -0
  215. package/dist/assets/themes/bootstrap/scss/bootstrap-utilities.scss +19 -0
  216. package/dist/assets/themes/bootstrap/scss/bootstrap.scss +52 -0
  217. package/dist/assets/themes/bootstrap/scss/forms/_floating-labels.scss +97 -0
  218. package/dist/assets/themes/bootstrap/scss/forms/_form-check.scss +189 -0
  219. package/dist/assets/themes/bootstrap/scss/forms/_form-control.scss +214 -0
  220. package/dist/assets/themes/bootstrap/scss/forms/_form-range.scss +91 -0
  221. package/dist/assets/themes/bootstrap/scss/forms/_form-select.scss +80 -0
  222. package/dist/assets/themes/bootstrap/scss/forms/_form-text.scss +11 -0
  223. package/dist/assets/themes/bootstrap/scss/forms/_input-group.scss +132 -0
  224. package/dist/assets/themes/bootstrap/scss/forms/_labels.scss +36 -0
  225. package/dist/assets/themes/bootstrap/scss/forms/_validation.scss +12 -0
  226. package/dist/assets/themes/bootstrap/scss/helpers/_clearfix.scss +3 -0
  227. package/dist/assets/themes/bootstrap/scss/helpers/_color-bg.scss +7 -0
  228. package/dist/assets/themes/bootstrap/scss/helpers/_colored-links.scss +30 -0
  229. package/dist/assets/themes/bootstrap/scss/helpers/_focus-ring.scss +5 -0
  230. package/dist/assets/themes/bootstrap/scss/helpers/_icon-link.scss +25 -0
  231. package/dist/assets/themes/bootstrap/scss/helpers/_position.scss +36 -0
  232. package/dist/assets/themes/bootstrap/scss/helpers/_ratio.scss +26 -0
  233. package/dist/assets/themes/bootstrap/scss/helpers/_stacks.scss +15 -0
  234. package/dist/assets/themes/bootstrap/scss/helpers/_stretched-link.scss +15 -0
  235. package/dist/assets/themes/bootstrap/scss/helpers/_text-truncation.scss +7 -0
  236. package/dist/assets/themes/bootstrap/scss/helpers/_visually-hidden.scss +8 -0
  237. package/dist/assets/themes/bootstrap/scss/helpers/_vr.scss +8 -0
  238. package/dist/assets/themes/bootstrap/scss/mixins/_alert.scss +18 -0
  239. package/dist/assets/themes/bootstrap/scss/mixins/_backdrop.scss +14 -0
  240. package/dist/assets/themes/bootstrap/scss/mixins/_banner.scss +7 -0
  241. package/dist/assets/themes/bootstrap/scss/mixins/_border-radius.scss +78 -0
  242. package/dist/assets/themes/bootstrap/scss/mixins/_box-shadow.scss +18 -0
  243. package/dist/assets/themes/bootstrap/scss/mixins/_breakpoints.scss +127 -0
  244. package/dist/assets/themes/bootstrap/scss/mixins/_buttons.scss +70 -0
  245. package/dist/assets/themes/bootstrap/scss/mixins/_caret.scss +69 -0
  246. package/dist/assets/themes/bootstrap/scss/mixins/_clearfix.scss +9 -0
  247. package/dist/assets/themes/bootstrap/scss/mixins/_color-mode.scss +21 -0
  248. package/dist/assets/themes/bootstrap/scss/mixins/_color-scheme.scss +7 -0
  249. package/dist/assets/themes/bootstrap/scss/mixins/_container.scss +11 -0
  250. package/dist/assets/themes/bootstrap/scss/mixins/_deprecate.scss +10 -0
  251. package/dist/assets/themes/bootstrap/scss/mixins/_forms.scss +163 -0
  252. package/dist/assets/themes/bootstrap/scss/mixins/_gradients.scss +47 -0
  253. package/dist/assets/themes/bootstrap/scss/mixins/_grid.scss +151 -0
  254. package/dist/assets/themes/bootstrap/scss/mixins/_image.scss +16 -0
  255. package/dist/assets/themes/bootstrap/scss/mixins/_list-group.scss +26 -0
  256. package/dist/assets/themes/bootstrap/scss/mixins/_lists.scss +7 -0
  257. package/dist/assets/themes/bootstrap/scss/mixins/_pagination.scss +10 -0
  258. package/dist/assets/themes/bootstrap/scss/mixins/_reset-text.scss +17 -0
  259. package/dist/assets/themes/bootstrap/scss/mixins/_resize.scss +6 -0
  260. package/dist/assets/themes/bootstrap/scss/mixins/_table-variants.scss +24 -0
  261. package/dist/assets/themes/bootstrap/scss/mixins/_text-truncate.scss +8 -0
  262. package/dist/assets/themes/bootstrap/scss/mixins/_transition.scss +26 -0
  263. package/dist/assets/themes/bootstrap/scss/mixins/_utilities.scss +97 -0
  264. package/dist/assets/themes/bootstrap/scss/mixins/_visually-hidden.scss +38 -0
  265. package/dist/assets/themes/bootstrap/scss/tests/jasmine.js +16 -0
  266. package/dist/assets/themes/bootstrap/scss/tests/mixins/_auto-import-of-variables-dark.test.scss +7 -0
  267. package/dist/assets/themes/bootstrap/scss/tests/mixins/_color-modes.test.scss +69 -0
  268. package/dist/assets/themes/bootstrap/scss/tests/mixins/_media-query-color-mode-full.test.scss +8 -0
  269. package/dist/assets/themes/bootstrap/scss/tests/mixins/_utilities.test.scss +393 -0
  270. package/dist/assets/themes/bootstrap/scss/tests/sass-true/register.js +14 -0
  271. package/dist/assets/themes/bootstrap/scss/tests/sass-true/runner.js +17 -0
  272. package/dist/assets/themes/bootstrap/scss/tests/utilities/_api.test.scss +75 -0
  273. package/dist/assets/themes/bootstrap/scss/utilities/_api.scss +47 -0
  274. package/dist/assets/themes/bootstrap/scss/vendor/_rfs.scss +348 -0
  275. package/dist/assets/themes/classy/README.md +89 -0
  276. package/dist/assets/themes/classy/_config.scss +245 -0
  277. package/dist/assets/themes/classy/_theme.js +31 -0
  278. package/dist/assets/themes/classy/_theme.scss +57 -0
  279. package/dist/assets/themes/classy/css/app/_panels.scss +183 -0
  280. package/dist/assets/themes/classy/css/base/_fonts.scss +79 -0
  281. package/dist/assets/themes/classy/css/base/_no-raise.scss +49 -0
  282. package/dist/assets/themes/classy/css/base/_root.scss +113 -0
  283. package/dist/assets/themes/classy/css/base/_typography.scss +154 -0
  284. package/dist/assets/themes/classy/css/base/_utilities.scss +284 -0
  285. package/dist/assets/themes/classy/css/components/_alerts.scss +51 -0
  286. package/dist/assets/themes/classy/css/components/_badges.scss +46 -0
  287. package/dist/assets/themes/classy/css/components/_buttons.scss +175 -0
  288. package/dist/assets/themes/classy/css/components/_cards.scss +41 -0
  289. package/dist/assets/themes/classy/css/components/_dropdowns.scss +48 -0
  290. package/dist/assets/themes/classy/css/components/_forms.scss +171 -0
  291. package/dist/assets/themes/classy/css/components/_receipt.scss +45 -0
  292. package/dist/assets/themes/classy/css/layout/_footer.scss +298 -0
  293. package/dist/assets/themes/classy/css/layout/_general.scss +209 -0
  294. package/dist/assets/themes/classy/css/layout/_nav.scss +154 -0
  295. package/dist/assets/themes/classy/css/layout/_shell.scss +458 -0
  296. package/dist/assets/themes/classy/css/marketing/_bento.scss +238 -0
  297. package/dist/assets/themes/classy/css/marketing/_content.scss +1328 -0
  298. package/dist/assets/themes/classy/css/marketing/_downloads.scss +246 -0
  299. package/dist/assets/themes/classy/css/marketing/_hero.scss +311 -0
  300. package/dist/assets/themes/classy/css/marketing/_sections.scss +649 -0
  301. package/dist/assets/themes/classy/css/pages/404/index.scss +67 -0
  302. package/dist/assets/themes/classy/css/pages/_auth.scss +235 -0
  303. package/dist/assets/themes/classy/css/pages/admin/firebase/index.scss +22 -0
  304. package/dist/assets/themes/classy/css/pages/blog/[slug].scss +56 -0
  305. package/dist/assets/themes/classy/css/pages/cookies.scss +2 -0
  306. package/dist/assets/themes/classy/css/pages/dashboard/account/index.scss +31 -0
  307. package/dist/assets/themes/classy/css/pages/feedback/index.scss +39 -0
  308. package/dist/assets/themes/classy/css/pages/legal/_document.scss +192 -0
  309. package/dist/assets/themes/classy/css/pages/payment/checkout/index.scss +585 -0
  310. package/dist/assets/themes/classy/css/pages/payment/confirmation/index.scss +9 -0
  311. package/dist/assets/themes/classy/css/pages/privacy.scss +2 -0
  312. package/dist/assets/themes/classy/css/pages/status/index.scss +164 -0
  313. package/dist/assets/themes/classy/css/pages/terms.scss +2 -0
  314. package/dist/assets/themes/classy/css/pages/updates/index.scss +128 -0
  315. package/dist/assets/themes/classy/fonts/inter-italic-latin-ext.woff2 +0 -0
  316. package/dist/assets/themes/classy/fonts/inter-italic-latin.woff2 +0 -0
  317. package/dist/assets/themes/classy/fonts/inter-normal-latin-ext.woff2 +0 -0
  318. package/dist/assets/themes/classy/fonts/inter-normal-latin.woff2 +0 -0
  319. package/dist/assets/themes/classy/fonts/newsreader-italic-latin-ext.woff2 +0 -0
  320. package/dist/assets/themes/classy/fonts/newsreader-italic-latin.woff2 +0 -0
  321. package/dist/assets/themes/classy/fonts/newsreader-normal-latin-ext.woff2 +0 -0
  322. package/dist/assets/themes/classy/fonts/newsreader-normal-latin.woff2 +0 -0
  323. package/dist/assets/themes/classy/js/hero-demo-form.js +56 -0
  324. package/dist/assets/themes/neobrutalism/README.md +118 -0
  325. package/dist/assets/themes/neobrutalism/_config.scss +139 -0
  326. package/dist/assets/themes/neobrutalism/_layouts/frontend/core/base.html +30 -0
  327. package/dist/assets/themes/neobrutalism/_layouts/frontend/pages/index.html +275 -0
  328. package/dist/assets/themes/neobrutalism/_theme.js +24 -0
  329. package/dist/assets/themes/neobrutalism/_theme.scss +61 -0
  330. package/dist/assets/themes/neobrutalism/css/base/_mixins.scss +46 -0
  331. package/dist/assets/themes/neobrutalism/css/base/_root.scss +169 -0
  332. package/dist/assets/themes/neobrutalism/css/base/_typography.scss +61 -0
  333. package/dist/assets/themes/neobrutalism/css/base/_utilities.scss +89 -0
  334. package/dist/assets/themes/neobrutalism/css/components/_billing-toggle.scss +74 -0
  335. package/dist/assets/themes/neobrutalism/css/components/_buttons.scss +148 -0
  336. package/dist/assets/themes/neobrutalism/css/components/_cards.scss +47 -0
  337. package/dist/assets/themes/neobrutalism/css/components/_forms.scss +88 -0
  338. package/dist/assets/themes/neobrutalism/css/components/_marketing.scss +244 -0
  339. package/dist/assets/themes/neobrutalism/css/layout/_general.scss +213 -0
  340. package/dist/assets/themes/neobrutalism/css/layout/_navigation.scss +171 -0
  341. package/dist/assets/themes/neobrutalism/css/pages/index.scss +203 -0
  342. package/dist/assets/themes/neobrutalism/css/pages/pricing/index.scss +58 -0
  343. package/dist/assets/themes/neobrutalism/css/pages/test/libraries/layers/index.scss +7 -0
  344. package/dist/assets/themes/neobrutalism/js/pages/test/libraries/layers/index.js +9 -0
  345. package/dist/assets/themes/newsflash/README.md +117 -0
  346. package/dist/assets/themes/newsflash/_components/heading/lede/component.html +14 -0
  347. package/dist/assets/themes/newsflash/_components/heading/lede/component.json5 +23 -0
  348. package/dist/assets/themes/newsflash/_components/heading/rule-head/component.html +17 -0
  349. package/dist/assets/themes/newsflash/_components/heading/rule-head/component.json5 +23 -0
  350. package/dist/assets/themes/newsflash/_components/news/byline/component.html +12 -0
  351. package/dist/assets/themes/newsflash/_components/news/byline/component.json5 +18 -0
  352. package/dist/assets/themes/newsflash/_components/news/story-card/component.html +25 -0
  353. package/dist/assets/themes/newsflash/_components/news/story-card/component.json5 +21 -0
  354. package/dist/assets/themes/newsflash/_config.scss +147 -0
  355. package/dist/assets/themes/newsflash/_layouts/frontend/core/base.html +51 -0
  356. package/dist/assets/themes/newsflash/_layouts/frontend/pages/blog/index.html +299 -0
  357. package/dist/assets/themes/newsflash/_layouts/frontend/pages/blog/post.html +235 -0
  358. package/dist/assets/themes/newsflash/_layouts/frontend/pages/index.html +328 -0
  359. package/dist/assets/themes/newsflash/_sections/marketing/desks/section.html +39 -0
  360. package/dist/assets/themes/newsflash/_sections/marketing/desks/section.json5 +49 -0
  361. package/dist/assets/themes/newsflash/_sections/marketing/newsletter-cta/section.html +103 -0
  362. package/dist/assets/themes/newsflash/_sections/marketing/newsletter-cta/section.json5 +50 -0
  363. package/dist/assets/themes/newsflash/_sections/marketing/rundown/section.html +28 -0
  364. package/dist/assets/themes/newsflash/_sections/marketing/rundown/section.json5 +40 -0
  365. package/dist/assets/themes/newsflash/_theme.js +24 -0
  366. package/dist/assets/themes/newsflash/_theme.scss +70 -0
  367. package/dist/assets/themes/newsflash/css/base/_fonts.scss +80 -0
  368. package/dist/assets/themes/newsflash/css/base/_mixins.scss +51 -0
  369. package/dist/assets/themes/newsflash/css/base/_root.scss +257 -0
  370. package/dist/assets/themes/newsflash/css/base/_typography.scss +49 -0
  371. package/dist/assets/themes/newsflash/css/base/_utilities.scss +122 -0
  372. package/dist/assets/themes/newsflash/css/components/_badges.scss +65 -0
  373. package/dist/assets/themes/newsflash/css/components/_billing-toggle.scss +61 -0
  374. package/dist/assets/themes/newsflash/css/components/_buttons.scss +139 -0
  375. package/dist/assets/themes/newsflash/css/components/_cards.scss +47 -0
  376. package/dist/assets/themes/newsflash/css/components/_editorial.scss +173 -0
  377. package/dist/assets/themes/newsflash/css/components/_forms.scss +75 -0
  378. package/dist/assets/themes/newsflash/css/components/_infinite-scroll.scss +102 -0
  379. package/dist/assets/themes/newsflash/css/components/_panels.scss +156 -0
  380. package/dist/assets/themes/newsflash/css/components/_ticker.scss +67 -0
  381. package/dist/assets/themes/newsflash/css/layout/_general.scss +330 -0
  382. package/dist/assets/themes/newsflash/css/layout/_navigation.scss +168 -0
  383. package/dist/assets/themes/newsflash/css/pages/404/index.scss +79 -0
  384. package/dist/assets/themes/newsflash/css/pages/blog/[slug].scss +186 -0
  385. package/dist/assets/themes/newsflash/css/pages/blog/index.scss +17 -0
  386. package/dist/assets/themes/newsflash/css/pages/index.scss +157 -0
  387. package/dist/assets/themes/newsflash/css/pages/pricing/index.scss +55 -0
  388. package/dist/assets/themes/newsflash/css/pages/test/libraries/layers/index.scss +7 -0
  389. package/dist/assets/themes/newsflash/fonts/fraunces-italic-latin-ext.woff2 +0 -0
  390. package/dist/assets/themes/newsflash/fonts/fraunces-italic-latin.woff2 +0 -0
  391. package/dist/assets/themes/newsflash/fonts/fraunces-normal-latin-ext.woff2 +0 -0
  392. package/dist/assets/themes/newsflash/fonts/fraunces-normal-latin.woff2 +0 -0
  393. package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-italic-latin-ext.woff2 +0 -0
  394. package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-italic-latin.woff2 +0 -0
  395. package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-normal-latin-ext.woff2 +0 -0
  396. package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-normal-latin.woff2 +0 -0
  397. package/dist/assets/themes/newsflash/js/pages/blog/[slug].js +29 -0
  398. package/dist/assets/themes/newsflash/js/pages/test/libraries/layers/index.js +9 -0
  399. package/dist/build.js +249 -0
  400. package/dist/cli-run.js +34 -0
  401. package/dist/cli.js +49 -0
  402. package/dist/commands/build.js +32 -0
  403. package/dist/commands/cdp/capture.js +91 -0
  404. package/dist/commands/cdp/client.js +140 -0
  405. package/dist/commands/cdp/eval.js +20 -0
  406. package/dist/commands/cdp/quit.js +84 -0
  407. package/dist/commands/cdp/relaunch.js +62 -0
  408. package/dist/commands/cdp/shot.js +20 -0
  409. package/dist/commands/cdp/status.js +38 -0
  410. package/dist/commands/cdp/theme.js +21 -0
  411. package/dist/commands/cdp.js +53 -0
  412. package/dist/commands/clean.js +34 -0
  413. package/dist/commands/deploy.js +75 -0
  414. package/dist/commands/finalize-release.js +238 -0
  415. package/dist/commands/install.js +37 -0
  416. package/dist/commands/launch.js +150 -0
  417. package/dist/commands/lib/dependencies.js +35 -0
  418. package/dist/commands/lib/deploy-precheck.js +117 -0
  419. package/dist/commands/lib/ensure-target.js +300 -0
  420. package/dist/commands/logs.js +185 -0
  421. package/dist/commands/package.js +31 -0
  422. package/dist/commands/publish.js +34 -0
  423. package/dist/commands/push-secrets.js +141 -0
  424. package/dist/commands/release.js +286 -0
  425. package/dist/commands/runner.js +1874 -0
  426. package/dist/commands/sign-windows.js +563 -0
  427. package/dist/commands/test.js +121 -0
  428. package/dist/commands/update.js +21 -0
  429. package/dist/commands/validate-certs.js +238 -0
  430. package/dist/commands/version.js +9 -0
  431. package/dist/config/page-template.html +35 -0
  432. package/dist/defaults/.github/workflows/build.yml +276 -0
  433. package/dist/defaults/AGENTS.md +109 -0
  434. package/dist/defaults/CHANGELOG.md +15 -0
  435. package/dist/defaults/CLAUDE.md +1 -0
  436. package/dist/defaults/_.gitignore +24 -0
  437. package/dist/defaults/_mas/README.md +49 -0
  438. package/dist/defaults/_mas/entitlements.mas.inherit.plist +12 -0
  439. package/dist/defaults/_mas/entitlements.mas.loginhelper.plist +8 -0
  440. package/dist/defaults/_mas/entitlements.mas.plist +33 -0
  441. package/dist/defaults/config/certs/.gitkeep +0 -0
  442. package/dist/defaults/config/certs/README.md +60 -0
  443. package/dist/defaults/config/icons/macos/dmg.png +0 -0
  444. package/dist/defaults/config/icons/macos/icon.png +0 -0
  445. package/dist/defaults/config/icons/macos/tray.png +0 -0
  446. package/dist/defaults/config/icons/windows/icon.png +0 -0
  447. package/dist/defaults/config/omega.json5 +279 -0
  448. package/dist/defaults/docs/README.md +17 -0
  449. package/dist/defaults/gulpfile.js +6 -0
  450. package/dist/defaults/hooks/build/post.js +9 -0
  451. package/dist/defaults/hooks/build/pre.js +9 -0
  452. package/dist/defaults/hooks/notarize/post.js +16 -0
  453. package/dist/defaults/hooks/release/post.js +9 -0
  454. package/dist/defaults/hooks/release/pre.js +9 -0
  455. package/dist/defaults/src/assets/js/components/about/index.js +10 -0
  456. package/dist/defaults/src/assets/js/components/main/index.js +14 -0
  457. package/dist/defaults/src/assets/js/components/settings/index.js +10 -0
  458. package/dist/defaults/src/assets/scss/main.scss +34 -0
  459. package/dist/defaults/src/assets/scss/pages/about.scss +3 -0
  460. package/dist/defaults/src/assets/scss/pages/main.scss +4 -0
  461. package/dist/defaults/src/assets/scss/pages/settings.scss +3 -0
  462. package/dist/defaults/src/integrations/context-menu/index.js +60 -0
  463. package/dist/defaults/src/integrations/menu/index.js +58 -0
  464. package/dist/defaults/src/integrations/tray/index.js +60 -0
  465. package/dist/defaults/src/main.js +78 -0
  466. package/dist/defaults/src/preload.js +15 -0
  467. package/dist/defaults/src/views/about/index.html +3 -0
  468. package/dist/defaults/src/views/main/index.html +8 -0
  469. package/dist/defaults/src/views/settings/index.html +3 -0
  470. package/dist/defaults/test/README.md +41 -0
  471. package/dist/defaults/test/_init.js +10 -0
  472. package/dist/gulp/main.js +144 -0
  473. package/dist/gulp/tasks/audit.js +82 -0
  474. package/dist/gulp/tasks/build-config.js +445 -0
  475. package/dist/gulp/tasks/bundle.js +451 -0
  476. package/dist/gulp/tasks/defaults.js +20 -0
  477. package/dist/gulp/tasks/distribute.js +8 -0
  478. package/dist/gulp/tasks/html.js +95 -0
  479. package/dist/gulp/tasks/package-quick.js +102 -0
  480. package/dist/gulp/tasks/package.js +53 -0
  481. package/dist/gulp/tasks/release.js +57 -0
  482. package/dist/gulp/tasks/sass.js +82 -0
  483. package/dist/gulp/tasks/serve.js +191 -0
  484. package/dist/hooks/notarize.js +70 -0
  485. package/dist/index.js +14 -0
  486. package/dist/lib/_menu-mixin.js +199 -0
  487. package/dist/lib/analytics.js +360 -0
  488. package/dist/lib/app-state.js +220 -0
  489. package/dist/lib/auth-flow.js +160 -0
  490. package/dist/lib/auth-persistence.js +207 -0
  491. package/dist/lib/auto-updater.js +752 -0
  492. package/dist/lib/client-bridge.js +371 -0
  493. package/dist/lib/context-menu.js +302 -0
  494. package/dist/lib/context.js +162 -0
  495. package/dist/lib/deep-link.js +370 -0
  496. package/dist/lib/fontawesome.js +203 -0
  497. package/dist/lib/ipc.js +169 -0
  498. package/dist/lib/logger-lite.js +259 -0
  499. package/dist/lib/logger.js +4 -0
  500. package/dist/lib/menu.js +521 -0
  501. package/dist/lib/protocol.js +85 -0
  502. package/dist/lib/remote-config.js +224 -0
  503. package/dist/lib/remote-scripts.js +158 -0
  504. package/dist/lib/restart-manager/index.js +550 -0
  505. package/dist/lib/restart-manager/install.js +353 -0
  506. package/dist/lib/restart-manager/protocol.js +274 -0
  507. package/dist/lib/sign-helpers/auto-unlock.js +95 -0
  508. package/dist/lib/sign-helpers/entitlements.js +98 -0
  509. package/dist/lib/sign-helpers/resolve-icons.js +171 -0
  510. package/dist/lib/sign-helpers/sign-events.js +75 -0
  511. package/dist/lib/sign-helpers/update-info.js +186 -0
  512. package/dist/lib/startup.js +214 -0
  513. package/dist/lib/storage.js +193 -0
  514. package/dist/lib/templating.js +85 -0
  515. package/dist/lib/theme.js +173 -0
  516. package/dist/lib/tray.js +414 -0
  517. package/dist/lib/usage.js +141 -0
  518. package/dist/lib/window-manager.js +509 -0
  519. package/dist/main.js +542 -0
  520. package/dist/omega-bin.js +6 -0
  521. package/dist/preload.js +241 -0
  522. package/dist/renderer.js +456 -0
  523. package/dist/test/assert.js +4 -0
  524. package/dist/test/fixtures/consumer-app/config/omega.json5 +39 -0
  525. package/dist/test/fixtures/consumer-app/package.json +13 -0
  526. package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +11 -0
  527. package/dist/test/fixtures/consumer-app/src/assets/scss/main.scss +3 -0
  528. package/dist/test/fixtures/consumer-app/src/main.js +17 -0
  529. package/dist/test/fixtures/consumer-app/src/preload.js +4 -0
  530. package/dist/test/fixtures/consumer-app/src/views/main/index.html +4 -0
  531. package/dist/test/harness/boot-entry.js +237 -0
  532. package/dist/test/harness/main-entry.js +494 -0
  533. package/dist/test/harness/package.json +6 -0
  534. package/dist/test/harness/renderer-entry.js +173 -0
  535. package/dist/test/harness/renderer-preload.js +310 -0
  536. package/dist/test/harness/renderer.html +12 -0
  537. package/dist/test/index.js +65 -0
  538. package/dist/test/runner.js +99 -0
  539. package/dist/test/runners/boot.js +414 -0
  540. package/dist/test/runners/electron.js +92 -0
  541. package/dist/test/runners/render-event.js +46 -0
  542. package/dist/test/suites/boot/build-isolation.test.js +54 -0
  543. package/dist/test/suites/boot/consumer-app-boots.test.js +99 -0
  544. package/dist/test/suites/boot/restart-manager.test.js +38 -0
  545. package/dist/test/suites/boot/storage-bundled.test.js +59 -0
  546. package/dist/test/suites/boot/theme.test.js +68 -0
  547. package/dist/test/suites/boot/view-suite.test.js +47 -0
  548. package/dist/test/suites/build/attach-log-file.test.js +99 -0
  549. package/dist/test/suites/build/audit.test.js +271 -0
  550. package/dist/test/suites/build/boot-fixture.test.js +48 -0
  551. package/dist/test/suites/build/build-config.test.js +457 -0
  552. package/dist/test/suites/build/build-verbs.test.js +156 -0
  553. package/dist/test/suites/build/build-workflow-jobs.test.js +55 -0
  554. package/dist/test/suites/build/cdp.test.js +89 -0
  555. package/dist/test/suites/build/cli.test.js +135 -0
  556. package/dist/test/suites/build/config-schema.test.js +133 -0
  557. package/dist/test/suites/build/defaults-scaffold.test.js +192 -0
  558. package/dist/test/suites/build/deliver-certs.test.js +95 -0
  559. package/dist/test/suites/build/derive-signing-env.test.js +122 -0
  560. package/dist/test/suites/build/electron-node-version.test.js +49 -0
  561. package/dist/test/suites/build/electron-targets.test.js +92 -0
  562. package/dist/test/suites/build/ensure-target.test.js +131 -0
  563. package/dist/test/suites/build/entitlements.test.js +107 -0
  564. package/dist/test/suites/build/env-delivery.test.js +166 -0
  565. package/dist/test/suites/build/env-watch.test.js +86 -0
  566. package/dist/test/suites/build/exports.test.js +63 -0
  567. package/dist/test/suites/build/finalize-release.test.js +152 -0
  568. package/dist/test/suites/build/format-fetch-error.test.js +85 -0
  569. package/dist/test/suites/build/framework-deps.test.js +173 -0
  570. package/dist/test/suites/build/get-config.test.js +137 -0
  571. package/dist/test/suites/build/github-utils.test.js +54 -0
  572. package/dist/test/suites/build/icon-sheet.test.js +62 -0
  573. package/dist/test/suites/build/license-stamp.test.js +63 -0
  574. package/dist/test/suites/build/logger-lite.test.js +148 -0
  575. package/dist/test/suites/build/logs-command.test.js +226 -0
  576. package/dist/test/suites/build/manager.test.js +193 -0
  577. package/dist/test/suites/build/menu-mixin.test.js +130 -0
  578. package/dist/test/suites/build/merge-line-files.test.js +230 -0
  579. package/dist/test/suites/build/omega-shell.test.js +94 -0
  580. package/dist/test/suites/build/omega-tokens.test.js +64 -0
  581. package/dist/test/suites/build/project-scripts-deps.test.js +90 -0
  582. package/dist/test/suites/build/push-secrets.test.js +226 -0
  583. package/dist/test/suites/build/release-pipeline.test.js +365 -0
  584. package/dist/test/suites/build/renderer-auth-bridge.test.js +158 -0
  585. package/dist/test/suites/build/renderer-entry-key.test.js +37 -0
  586. package/dist/test/suites/build/renderer-node-shims.test.js +125 -0
  587. package/dist/test/suites/build/resolve-icons.test.js +296 -0
  588. package/dist/test/suites/build/resolve-signing-cert.test.js +342 -0
  589. package/dist/test/suites/build/restart-manager-install.test.js +178 -0
  590. package/dist/test/suites/build/restart-manager-protocol.test.js +158 -0
  591. package/dist/test/suites/build/run-consumer-hook.test.js +137 -0
  592. package/dist/test/suites/build/runner.test.js +2599 -0
  593. package/dist/test/suites/build/sanitize-signing-env.test.js +98 -0
  594. package/dist/test/suites/build/sanitize-url.test.js +78 -0
  595. package/dist/test/suites/build/secure-remote-url.test.js +42 -0
  596. package/dist/test/suites/build/sentry.test.js +89 -0
  597. package/dist/test/suites/build/serve-resolve-electron.test.js +58 -0
  598. package/dist/test/suites/build/setup-scripts.test.js +172 -0
  599. package/dist/test/suites/build/sign-events.test.js +90 -0
  600. package/dist/test/suites/build/sign-windows-e2e.test.js +302 -0
  601. package/dist/test/suites/build/sign-windows.test.js +313 -0
  602. package/dist/test/suites/build/strip-dev-blocks.test.js +116 -0
  603. package/dist/test/suites/build/templating.test.js +95 -0
  604. package/dist/test/suites/build/test-discovery.test.js +64 -0
  605. package/dist/test/suites/build/test-stealth.test.js +83 -0
  606. package/dist/test/suites/build/test-target-no-match.test.js +119 -0
  607. package/dist/test/suites/build/update-info.test.js +224 -0
  608. package/dist/test/suites/build/url-helpers.test.js +289 -0
  609. package/dist/test/suites/build/validate-certs.test.js +103 -0
  610. package/dist/test/suites/build/validate-config.test.js +90 -0
  611. package/dist/test/suites/build/verb-logs.test.js +43 -0
  612. package/dist/test/suites/build/wave5-pins.test.js +35 -0
  613. package/dist/test/suites/main/analytics.test.js +364 -0
  614. package/dist/test/suites/main/app-state.test.js +197 -0
  615. package/dist/test/suites/main/auth-flow.test.js +196 -0
  616. package/dist/test/suites/main/auth-persistence.test.js +167 -0
  617. package/dist/test/suites/main/auto-updater.test.js +1138 -0
  618. package/dist/test/suites/main/boot-sequence.test.js +77 -0
  619. package/dist/test/suites/main/client-bridge.integration.test.js +134 -0
  620. package/dist/test/suites/main/client-bridge.test.js +249 -0
  621. package/dist/test/suites/main/context-menu.test.js +365 -0
  622. package/dist/test/suites/main/context.test.js +155 -0
  623. package/dist/test/suites/main/deep-link.test.js +288 -0
  624. package/dist/test/suites/main/epipe-handler.test.js +40 -0
  625. package/dist/test/suites/main/fontawesome.test.js +147 -0
  626. package/dist/test/suites/main/harness-cdp.test.js +49 -0
  627. package/dist/test/suites/main/ipc.test.js +165 -0
  628. package/dist/test/suites/main/menu.test.js +419 -0
  629. package/dist/test/suites/main/protocol.test.js +77 -0
  630. package/dist/test/suites/main/remote-config.test.js +189 -0
  631. package/dist/test/suites/main/remote-scripts.test.js +276 -0
  632. package/dist/test/suites/main/restart-manager.test.js +328 -0
  633. package/dist/test/suites/main/startup-paths-and-ua.test.js +99 -0
  634. package/dist/test/suites/main/startup.test.js +129 -0
  635. package/dist/test/suites/main/stealth-window.test.js +74 -0
  636. package/dist/test/suites/main/storage.test.js +89 -0
  637. package/dist/test/suites/main/theme.test.js +137 -0
  638. package/dist/test/suites/main/tray.test.js +322 -0
  639. package/dist/test/suites/main/truncate-on-boot.test.js +22 -0
  640. package/dist/test/suites/main/url-helpers.test.js +429 -0
  641. package/dist/test/suites/main/usage.test.js +127 -0
  642. package/dist/test/suites/main/window-bounds.test.js +169 -0
  643. package/dist/test/suites/main/window-manager.test.js +233 -0
  644. package/dist/test/suites/renderer/analytics-bridge.test.js +128 -0
  645. package/dist/test/suites/renderer/cross-context-helpers.test.js +131 -0
  646. package/dist/test/suites/renderer/fontawesome.test.js +190 -0
  647. package/dist/test/suites/renderer/round-trip.test.js +107 -0
  648. package/dist/test/suites/renderer/theme.test.js +118 -0
  649. package/dist/test/suites/renderer/tooltips.test.js +166 -0
  650. package/dist/test/suites/renderer/verts.test.js +100 -0
  651. package/dist/test/suites/renderer/window-em-surface.test.js +107 -0
  652. package/dist/test/utils/dist-snapshot.js +36 -0
  653. package/dist/test/utils/extended-mode-warning.js +13 -0
  654. package/dist/utils/app-root.js +28 -0
  655. package/dist/utils/attach-log-file.js +4 -0
  656. package/dist/utils/build-pipeline.js +58 -0
  657. package/dist/utils/deliver-certs.js +69 -0
  658. package/dist/utils/derive-signing-env.js +56 -0
  659. package/dist/utils/dist-root.js +21 -0
  660. package/dist/utils/electron-node-version.js +48 -0
  661. package/dist/utils/electron-targets.js +72 -0
  662. package/dist/utils/format-fetch-error.js +38 -0
  663. package/dist/utils/github.js +73 -0
  664. package/dist/utils/load-consumer-file.js +26 -0
  665. package/dist/utils/merge-line-files.js +5 -0
  666. package/dist/utils/mode-helpers.js +147 -0
  667. package/dist/utils/resolve-signing-cert.js +175 -0
  668. package/dist/utils/run-consumer-hook.js +38 -0
  669. package/dist/utils/runner-env.js +687 -0
  670. package/dist/utils/safe-install.js +4 -0
  671. package/dist/utils/sanitize-signing-env.js +45 -0
  672. package/dist/utils/sanitize-url.js +28 -0
  673. package/dist/utils/secure-remote-url.js +25 -0
  674. package/dist/utils/stealth-window.js +37 -0
  675. package/dist/utils/test-stealth.js +29 -0
  676. package/dist/utils/url-helpers.js +169 -0
  677. package/dist/vendor/account/engine.js +182 -0
  678. package/dist/vendor/account/features.js +220 -0
  679. package/dist/vendor/account/index.js +53 -0
  680. package/dist/vendor/account/schema.js +272 -0
  681. package/dist/vendor/account/subscription.js +38 -0
  682. package/dist/vendor/analytics/adapters/ga4.js +26 -0
  683. package/dist/vendor/analytics/adapters/meta.js +26 -0
  684. package/dist/vendor/analytics/adapters/resolve.js +130 -0
  685. package/dist/vendor/analytics/adapters/tiktok.js +27 -0
  686. package/dist/vendor/analytics/catalog.js +908 -0
  687. package/dist/vendor/analytics/consent.js +49 -0
  688. package/dist/vendor/analytics/core.js +141 -0
  689. package/dist/vendor/analytics/identity.js +136 -0
  690. package/dist/vendor/analytics/index.js +170 -0
  691. package/dist/vendor/analytics/logger.js +40 -0
  692. package/dist/vendor/analytics/transports/browser.js +110 -0
  693. package/dist/vendor/config/company.js +31 -0
  694. package/dist/vendor/config/defaults.js +173 -0
  695. package/dist/vendor/config/demo.js +18 -0
  696. package/dist/vendor/config/desktop-artifacts.js +110 -0
  697. package/dist/vendor/config/edit.js +769 -0
  698. package/dist/vendor/config/env-delivery.js +145 -0
  699. package/dist/vendor/config/env-rules.js +93 -0
  700. package/dist/vendor/config/env-schema.js +1078 -0
  701. package/dist/vendor/config/env.js +445 -0
  702. package/dist/vendor/config/hooks.js +97 -0
  703. package/dist/vendor/config/index.js +237 -0
  704. package/dist/vendor/config/instances.js +208 -0
  705. package/dist/vendor/config/load.js +490 -0
  706. package/dist/vendor/config/merge.js +68 -0
  707. package/dist/vendor/config/order.js +139 -0
  708. package/dist/vendor/config/ports.js +374 -0
  709. package/dist/vendor/config/providers.js +32 -0
  710. package/dist/vendor/config/repo.js +142 -0
  711. package/dist/vendor/config/retired-keys.js +430 -0
  712. package/dist/vendor/config/schema.js +1610 -0
  713. package/dist/vendor/config/secrets.js +50 -0
  714. package/dist/vendor/config/seed.js +34 -0
  715. package/dist/vendor/config/site-global.js +205 -0
  716. package/dist/vendor/config/validate.js +554 -0
  717. package/dist/vendor/config/winback.js +61 -0
  718. package/dist/vendor/devkit/actions-secrets.js +145 -0
  719. package/dist/vendor/devkit/attach-log-file.js +262 -0
  720. package/dist/vendor/devkit/bundle.js +292 -0
  721. package/dist/vendor/devkit/certs.js +199 -0
  722. package/dist/vendor/devkit/ci-workflows.js +520 -0
  723. package/dist/vendor/devkit/clean-dirs.js +28 -0
  724. package/dist/vendor/devkit/cli-router.js +156 -0
  725. package/dist/vendor/devkit/defaults-engine.js +372 -0
  726. package/dist/vendor/devkit/deploy-precheck.js +54 -0
  727. package/dist/vendor/devkit/deploy-record.js +180 -0
  728. package/dist/vendor/devkit/deploy.js +286 -0
  729. package/dist/vendor/devkit/empty-modules-plugin.js +64 -0
  730. package/dist/vendor/devkit/env-watch.js +132 -0
  731. package/dist/vendor/devkit/framework-deps.js +46 -0
  732. package/dist/vendor/devkit/license.js +155 -0
  733. package/dist/vendor/devkit/local.js +1905 -0
  734. package/dist/vendor/devkit/logger.js +128 -0
  735. package/dist/vendor/devkit/merge-line-files.js +296 -0
  736. package/dist/vendor/devkit/npm-registry.js +52 -0
  737. package/dist/vendor/devkit/omega-bin.js +345 -0
  738. package/dist/vendor/devkit/prompt.js +187 -0
  739. package/dist/vendor/devkit/safe-install.js +18 -0
  740. package/dist/vendor/devkit/scaffold-guard.js +96 -0
  741. package/dist/vendor/devkit/stop-signals.js +28 -0
  742. package/dist/vendor/devkit/strip-dev-blocks-plugin.js +29 -0
  743. package/dist/vendor/devkit/strip-dev-blocks.js +32 -0
  744. package/dist/vendor/devkit/target-dependencies.js +137 -0
  745. package/dist/vendor/devkit/target-secrets.js +165 -0
  746. package/dist/vendor/devkit/test/assert.js +120 -0
  747. package/dist/vendor/devkit/test/define-cases.js +104 -0
  748. package/dist/vendor/devkit/test/extended-mode-warning.js +22 -0
  749. package/dist/vendor/devkit/test/runner-core.js +554 -0
  750. package/dist/vendor/devkit/test/scope.js +162 -0
  751. package/dist/vendor/devkit/update.js +569 -0
  752. package/dist/vendor/monitoring/core.js +180 -0
  753. package/dist/vendor/monitoring/env.js +49 -0
  754. package/dist/vendor/monitoring/index.js +28 -0
  755. package/dist/vendor/monitoring/logger.js +39 -0
  756. package/dist/vendor/monitoring/main.js +99 -0
  757. package/dist/vendor/monitoring/preload.js +45 -0
  758. package/dist/vendor/monitoring/renderer.js +87 -0
  759. package/docs/analytics.md +140 -0
  760. package/docs/app-state.md +92 -0
  761. package/docs/audit.md +69 -0
  762. package/docs/auto-updater.md +243 -0
  763. package/docs/boot-sequence.md +39 -0
  764. package/docs/build-system.md +161 -0
  765. package/docs/cdp-debugging.md +169 -0
  766. package/docs/client-bridge.md +267 -0
  767. package/docs/common-mistakes.md +21 -0
  768. package/docs/config-schema.md +120 -0
  769. package/docs/context-menu.md +112 -0
  770. package/docs/context.md +81 -0
  771. package/docs/css.md +84 -0
  772. package/docs/deep-link.md +178 -0
  773. package/docs/environment-detection.md +104 -0
  774. package/docs/fontawesome.md +107 -0
  775. package/docs/hooks.md +87 -0
  776. package/docs/icons.md +79 -0
  777. package/docs/index.md +279 -0
  778. package/docs/installer-options.md +162 -0
  779. package/docs/ipc.md +61 -0
  780. package/docs/lib-modules.md +53 -0
  781. package/docs/logging.md +229 -0
  782. package/docs/menu.md +160 -0
  783. package/docs/releasing.md +229 -0
  784. package/docs/remote-config.md +118 -0
  785. package/docs/remote-scripts.md +144 -0
  786. package/docs/restart-manager.md +144 -0
  787. package/docs/runner.md +253 -0
  788. package/docs/sentry.md +97 -0
  789. package/docs/shared/agent-docs.md +89 -0
  790. package/docs/shared/analytics.md +612 -0
  791. package/docs/shared/brands.md +51 -0
  792. package/docs/shared/breaking-changes.md +497 -0
  793. package/docs/shared/config.md +1387 -0
  794. package/docs/shared/deploys.md +215 -0
  795. package/docs/shared/icons.md +201 -0
  796. package/docs/shared/local-dev.md +147 -0
  797. package/docs/shared/logging.md +202 -0
  798. package/docs/shared/monitoring.md +153 -0
  799. package/docs/shared/publishing.md +183 -0
  800. package/docs/shared/rulings.md +34 -0
  801. package/docs/shared/testing.md +147 -0
  802. package/docs/shared/theming.md +604 -0
  803. package/docs/shared/translation.md +291 -0
  804. package/docs/shared/updates.md +61 -0
  805. package/docs/signing.md +267 -0
  806. package/docs/startup.md +142 -0
  807. package/docs/storage.md +59 -0
  808. package/docs/templating.md +101 -0
  809. package/docs/test-boot-layer.md +157 -0
  810. package/docs/test-framework.md +357 -0
  811. package/docs/themes.md +135 -0
  812. package/docs/tooltips.md +99 -0
  813. package/docs/tray.md +164 -0
  814. package/docs/usage.md +58 -0
  815. package/docs/verts.md +62 -0
  816. package/docs/windows.md +149 -0
  817. package/package.json +184 -0
  818. 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>