@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,92 @@
1
+ # App State
2
+
3
+ Storage-backed launch flags + crash sentinel. Tells you *whether* this is the first launch ever, *how many* times the app has launched, *whether* the previous run crashed, and *whether* the version changed.
4
+
5
+ ## Public API on `manager.appState`
6
+
7
+ ```js
8
+ manager.appState.isFirstLaunch() // boolean — true ONLY on the very first boot
9
+ manager.appState.getLaunchCount() // number — total successful launches (including this one)
10
+ manager.appState.getInstalledAt() // Date — first ever launch timestamp
11
+ manager.appState.getLastLaunchAt() // Date | null — previous launch (null on first)
12
+ manager.appState.getLastQuitAt() // Date | null — previous graceful quit; null if it crashed
13
+ manager.appState.recoveredFromCrash() // boolean — previous run did not exit cleanly
14
+
15
+ manager.appState.getVersion() // string | null — package version of this launch
16
+ manager.appState.getPreviousVersion() // string | null — version before this launch
17
+ manager.appState.wasUpgraded() // boolean — true if THIS launch's version differs from the prior
18
+
19
+ manager.appState.launchedAtLogin() // boolean — OS booted us via openAtLogin
20
+ manager.appState.launchedFromDeepLink() // boolean — argv had a deep-link payload (set by lib/deep-link)
21
+
22
+ manager.appState.reset() // wipe persisted state (test helper / factory-reset command)
23
+ ```
24
+
25
+ ## Storage shape (key `appState`)
26
+
27
+ ```js
28
+ {
29
+ installedAt: 1700000000000, // first ever boot timestamp (ms epoch)
30
+ launchCount: 42,
31
+ lastLaunchAt: 1700000123456, // THIS launch's timestamp; previous launch's value exposed via getLastLaunchAt()
32
+ lastQuitAt: null, // null while running; set on graceful quit
33
+ version: '1.2.3',
34
+ previousVersion: '1.2.2', // preserved across no-change launches (see "Upgrade detection")
35
+ sentinel: true // true while running, cleared on graceful quit
36
+ }
37
+ ```
38
+
39
+ ## Crash detection
40
+
41
+ - On every boot, `appState.initialize()` reads the previous `sentinel` and `lastQuitAt` values BEFORE overwriting them.
42
+ - If `sentinel === true` AND `lastQuitAt === null`, the previous run never made it to `before-quit` / `will-quit` → it crashed. `recoveredFromCrash()` returns `true` for this launch only.
43
+ - First launch is exempt (no prior state to compare).
44
+ - Graceful-quit cleanup is wired up via `app.on('before-quit')` and `app.on('will-quit')`. Both fire under different shutdown paths; either one clears the sentinel and writes `lastQuitAt`.
45
+
46
+ ## Upgrade detection
47
+
48
+ `wasUpgraded()` is true **only** if THIS launch's version differs from the prior launch's version. Subsequent launches at the same version return `false`, but `getPreviousVersion()` keeps returning the historical value so you can show a "what's new" UI on the second launch too.
49
+
50
+ ```js
51
+ // install 1.0.0
52
+ appState.wasUpgraded() // false (first launch)
53
+ appState.getPreviousVersion() // null
54
+
55
+ // upgrade to 1.0.1, launch again
56
+ appState.wasUpgraded() // true
57
+ appState.getPreviousVersion() // '1.0.0'
58
+
59
+ // launch again at 1.0.1, no change
60
+ appState.wasUpgraded() // false
61
+ appState.getPreviousVersion() // '1.0.0' (preserved — useful for "what's new" UIs)
62
+ ```
63
+
64
+ ## Common patterns
65
+
66
+ ### Show onboarding on first launch
67
+
68
+ ```js
69
+ if (manager.appState.isFirstLaunch()) {
70
+ manager.windows.show('onboarding');
71
+ }
72
+ ```
73
+
74
+ ### Crash report ping
75
+
76
+ ```js
77
+ if (manager.appState.recoveredFromCrash()) {
78
+ manager.sentry.captureMessage('recovered from crash', 'warning');
79
+ }
80
+ ```
81
+
82
+ ### What's new modal after upgrade
83
+
84
+ ```js
85
+ if (manager.appState.wasUpgraded()) {
86
+ manager.windows.show('changelog');
87
+ }
88
+ ```
89
+
90
+ ## Test helper
91
+
92
+ `appState.reset()` wipes the persisted state and resets the in-memory snapshot. Useful in test suites and as a real `Settings → Reset to factory defaults` command.
package/docs/audit.md ADDED
@@ -0,0 +1,69 @@
1
+ # Audit Workflow
2
+
3
+ Full-project audit for @omega.js/desktop — runs against a CONSUMER project or the FRAMEWORK repo itself (scope auto-detected). Invoked via the `omega:desktop` skill (`/omega:desktop audit`) or any "audit this app/project" request.
4
+
5
+ Every check has a stable ID, a severity, and a scope. Findings are reported as `ID @ file:line`, fixed one at a time, then re-verified. The tables below do NOT restate the rules — each check links to the doc that owns the rule and the fix.
6
+
7
+ ## Protocol
8
+
9
+ 1. **Detect scope** — read `package.json`: `name` is `@omega.js/desktop` → **framework audit** (U + @omega.js/desktop + F checks); `@omega.js/desktop` in (dev)dependencies → **consumer audit** (U + @omega.js/desktop checks).
10
+ 2. **Run the catalog** — every check matching the scope. Search with Grep/Glob/Read over `src/` (+ `test/`, `config/`, `hooks/`); ALWAYS exclude `dist/`, `release/`, `node_modules/`, `_legacy/`, `_backup/`, `.cache/`. Record each finding as `ID @ file:line` + a one-line description.
11
+ 3. **Persist the report** — write the findings list to `.temp/audit/claude-audit.md` (create the dir; add `.temp/` to `.gitignore` if missing) so a long fix loop survives session breaks. Summarize counts by severity in chat.
12
+ 4. **Fix loop** — TodoWrite per finding, highest severity first, ONE at a time: mark in-progress → root cause → fix → verify → complete. Ask before structural or destructive fixes (file deletions, lib restructures, config reshapes).
13
+ 5. **Re-verify** — re-run every check that produced findings until clean; finish with `npx omega test` (must be green).
14
+ 6. **Doc parity** — if fixes changed behavior, update README / the framework guide / `docs/<topic>.md` / CHANGELOG in the same change set.
15
+
16
+ Severity: **CRIT** security or broken functionality · **HIGH** hard-rule violation · **MED** convention drift · **LOW** optional improvement.
17
+ Scope: **C** consumer · **F** framework repo · **B** both.
18
+
19
+ ## Universal checks (U-xx)
20
+
21
+ Mirrored across all four OMEGA frameworks (UJM / @omega.js/backend / BXM / @omega.js/desktop) — same ID means the same check everywhere.
22
+
23
+ | ID | Sev | Scope | Check |
24
+ |----|-----|-------|-------|
25
+ | U-01 | HIGH | B | Every feature has tests at EVERY layer it surfaces (build / main / renderer / boot) — never mocked, real harness only ([test-framework.md](test-framework.md)) |
26
+ | U-02 | HIGH | B | Test hygiene — real-external-API tests gated behind `TEST_EXTENDED_MODE` in-source (not mocked); no tests that assert nothing ([test-framework.md](test-framework.md)) |
27
+ | U-03 | CRIT | B | XSS — renderer DOM sinks escape untrusted values inline via `omega.utilities().escapeHTML(value)` (+ `sanitizeURL` for URL sinks); zero local escape helpers (rules mirror UJM/BXM `docs/xss-prevention.md`; see also DSK-01 for navigation sinks) |
28
+ | U-04 | HIGH | B | @omega.js/client owns Firebase — never `require('firebase')`; renderers use `omega.auth()` / `.firestore()`, main uses `manager.omega` ([common-mistakes.md](common-mistakes.md), [client-bridge.md](client-bridge.md)) |
29
+ | U-05 | HIGH | C | No @omega.js/desktop transitive deps installed in the consumer `package.json` (`firebase`, `@omega.js/client`, `fs-jetpack`, …) — the bundle task's framework-deps hook resolves them ([common-mistakes.md](common-mistakes.md)) |
30
+ | U-06 | HIGH | B | Env behavior gated on the INTENTIONAL check — `isProduction()` or `isDevelopment() \|\| isTesting()`, never `!isDevelopment()`; no ad-hoc `process.env.EM_*` reads where a helper exists ([environment-detection.md](environment-detection.md)) |
31
+ | U-07 | HIGH | B | Config canon — `config/omega.json5` validates against the schema (boot validator green); canonical cross-framework blocks (`brand`, `app`, `cloud.{provider,config}`, `monitoring`, `analytics`, `payment`) not reinvented ([config-schema.md](config-schema.md)) |
32
+ | U-08 | CRIT | B | No private credentials committed — signing certs (`config/certs/` gitignored), `.env` secrets, tokens, API secret keys ([signing.md](signing.md)). (The Firebase WEB `apiKey` is public by design — do NOT flag it.) |
33
+ | U-09 | HIGH | B | Source discipline — nothing edited in `dist/` or generated files (`dist/electron-builder.yml`, entitlements plist); no live code referencing `_legacy/` / `_backup/` ([build-system.md](build-system.md), [common-mistakes.md](common-mistakes.md)) |
34
+ | U-10 | MED | B | Doc parity — README / the framework guide / `docs/` / CHANGELOG match shipped behavior; the docs index lists every `docs/*.md`; no stale names for renamed commands/patterns |
35
+ | U-11 | MED | B | SSOT/DRY — no duplicated constants/config/logic; one authoritative home per value, imported everywhere else |
36
+ | U-12 | MED | B | JS conventions — file structure, JSDoc, short-circuit returns, leading logical operators, `fs-jetpack`, one `module.exports` per file (global `js:patterns` skill + [the framework guide](../../../docs/desktop/index.md) §File Conventions) |
37
+ | U-13 | MED | B | Dead code & stale patterns — no orphaned `src/` files nothing imports; no unused views/components/integrations; inventory TODO/FIXME (report only) |
38
+ | U-14 | LOW | B | Dependency health — review `npm outdated` / `npm audit`; apply fixes via the `general:update-packages` workflow (includes supply-chain checks) |
39
+
40
+ ## desktop-specific checks
41
+
42
+ | ID | Sev | Scope | Check |
43
+ |----|-----|-------|-------|
44
+ | DSK-01 | CRIT | B | Zero-trust URLs — every DYNAMIC URL is gated through `sanitize-url.js` before `shell.openExternal` / `BrowserWindow.loadURL` / `window.location.href =` (hardcoded internal-scheme URLs bypass) ([the framework guide](../../../docs/desktop/index.md) §File Conventions, [common-mistakes.md](common-mistakes.md)) |
45
+ | DSK-02 | HIGH | B | Path resolution — `app.getAppPath()` / `utils/app-root.js`, never `process.cwd()`, in runtime code (it's `/` in packaged apps) ([common-mistakes.md](common-mistakes.md)) |
46
+ | DSK-03 | HIGH | C | Windows — every `windows.create()` is `await`ed; the `main` window is ALWAYS created (even hidden launches, with `show: false`) so activate/second-instance can surface UI ([windows.md](windows.md), [common-mistakes.md](common-mistakes.md)) |
47
+ | DSK-04 | HIGH | B | Zero-trust IPC — all channels go through `manager.ipc` (never raw `ipcMain`); handlers validate payload content before acting, especially in apps embedding remote web content ([ipc.md](ipc.md#zero-trust-payloads)) |
48
+ | DSK-05 | MED | C | Icons — one native-size PNG per slot (no `@2x` siblings), macOS tray source named `tray.png` (@omega.js/desktop owns the `Template` rename), no `app.icons` config block ([icons.md](icons.md)) |
49
+ | DSK-06 | HIGH | C | File-based integrations — tray/menu/context-menu logic lives in `src/integrations/<name>/index.js`, never expressed in config JSON ([tray.md](tray.md), [menu.md](menu.md), [context-menu.md](context-menu.md)) |
50
+ | DSK-07 | HIGH | B | Presence-driven feature flags — credentials enable features (`monitoring.providers.sentry.dsn`, `analytics.providers.google.id`, `cloud.config`); no invented `enabled:` toggles ([config-schema.md](config-schema.md)) |
51
+ | DSK-08 | MED | B | Accessibility basics in renderer views — meaningful `alt` text, labeled form fields, real `<button>`/`<a>` elements (no clickable `div`s) |
52
+
53
+ ## Framework-repo checks (F-xx)
54
+
55
+ Only when auditing the @omega.js/desktop repo itself. Mirrored across the four frameworks.
56
+
57
+ | ID | Sev | Check |
58
+ |----|-----|-------|
59
+ | F-01 | MED | Sister parity — mirrored sections (config shapes, test contract, guide skeleton, shared env/test conventions) in sync with UJM / @omega.js/backend / BXM; deviations are deliberate and documented |
60
+ | F-02 | HIGH | Consumer-shipped defaults in sync — what `ensureTarget()` scaffolds (`src/defaults/`, every verb) matches current conventions and docs |
61
+ | F-03 | MED | Docs completeness — every `docs/*.md` indexed in the framework guide; every lib module has a doc; no "(planned)" links for things that have shipped |
62
+ | F-04 | HIGH | `npx omega test mgr:` green before treating the audit as complete |
63
+
64
+ ## See also
65
+
66
+ - [common-mistakes.md](common-mistakes.md) — the canonical anti-pattern list behind several checks
67
+ - [ipc.md](ipc.md#zero-trust-payloads) — the payload rules behind DSK-04
68
+ - [config-schema.md](config-schema.md) — the validator behind U-07 / DSK-07
69
+ - [test-framework.md](test-framework.md) — the layers behind U-01 / U-02
@@ -0,0 +1,243 @@
1
+ # Auto-updater
2
+
3
+ Wraps `electron-updater` with three triggers: startup check, periodic check, and a 30-day max-age gate that force-installs pending updates that have been ignored too long.
4
+
5
+ ## Triggers
6
+
7
+ | Trigger | When | Behavior |
8
+ |---|---|---|
9
+ | **Startup check** | `startupDelayMs` after `app.whenReady()` (default 10s) | Non-blocking. Fires once. |
10
+ | **Feed check** | Every `feedCheckIntervalMs` (default 1h) | HTTP poll of the release feed; also re-evaluates the 30-day gate each tick. |
11
+ | **Idle evaluation** | Every `idleEvalIntervalMs` (default 60s) | Cheap in-process check: install a downloaded update once the user has been idle long enough. |
12
+ | **30-day gate** | When a download lands + every feed tick | If a pending update was downloaded ≥ `maxAgeMs` ago (default 30 days), force `quitAndInstall()`. A pending update carried from a prior session keeps its original `downloadedAt`, so the gate trips as soon as the startup check re-downloads it. |
13
+ | **Manual check** | `manager.autoUpdater.checkNow()` (main) or `window.desktop.autoUpdater.checkNow()` (renderer) | Same as a periodic check but `userInitiated: true`. |
14
+
15
+ ## State machine
16
+
17
+ `status.code` is one of:
18
+
19
+ ```
20
+ idle — nothing happening
21
+ checking — checking the feed
22
+ available — feed says an update exists
23
+ downloading — download in progress (status.percent updated)
24
+ downloaded — fully downloaded; ready to install. Also: pendingUpdate.downloadedAt is set in storage.
25
+ not-available — feed says no update
26
+ error — checkForUpdates() or download failed; status.error.message has details
27
+ ```
28
+
29
+ ## Config (`config/omega.json5`)
30
+
31
+ ```jsonc
32
+ autoUpdate: {
33
+ enabled: true,
34
+ channel: 'latest', // latest / beta / alpha
35
+ startupDelayMs: 10000, // 10s after whenReady
36
+ feedCheckIntervalMs: 3600000, // 1h — release-feed poll cadence (HTTP; also re-checks the 30-day gate)
37
+ idleEvalIntervalMs: 60000, // 60s — idle-install evaluator cadence (in-process)
38
+ maxAgeMs: 2592000000, // 30 days; if pendingUpdate is older, force install
39
+ autoDownload: true, // electron-updater downloads automatically
40
+ }
41
+ ```
42
+
43
+ ## 30-day max-age gate
44
+
45
+ The problem: if a user keeps their app open for weeks, an update may download but never apply. Eventually their version is dangerously stale (e.g. an unpatched security issue).
46
+
47
+ The gate:
48
+
49
+ 1. **First download wins.** When `update-downloaded` fires, @omega.js/desktop stores `pendingUpdate = { version, downloadedAt: Date.now() }` to `storage.autoUpdater.pendingUpdate`.
50
+ 2. **Subsequent downloads do NOT reset the timer.** If a newer update downloads later, `downloadedAt` stays at the original time. (Otherwise the user could keep dodging by triggering re-checks.)
51
+ 3. **When a download lands + every feed tick**, @omega.js/desktop checks if `Date.now() - downloadedAt >= maxAgeMs`. If yes → `quitAndInstall()`. Force. (At init the artifact isn't re-downloaded yet — the restored `downloadedAt` makes the gate trip the moment the startup check's download completes.)
52
+ 4. **Cleared on apply.** When the app next launches and `app.getVersion() === pendingUpdate.version`, the flag is cleared automatically (the user successfully restarted into the new version).
53
+
54
+ This guarantees no app on @omega.js/desktop stays > maxAgeMs days behind a downloaded update — provided `autoDownload` stays on (default): the cross-session gate enforces when the startup check's re-download lands, so with `autoDownload: false` it waits for the next download, whenever the consumer triggers one.
55
+
56
+ ## Idle-aware install (15-min default)
57
+
58
+ When an update finishes downloading via a background poll (NOT a user-initiated check), @omega.js/desktop does NOT immediately quit-and-install. Two independent timers own the decision: the feed-check timer (`feedCheckIntervalMs`, HTTP, also enforces the 30-day gate) and the idle-eval timer (`idleEvalIntervalMs`, cheap in-process arithmetic) which installs the downloaded update once the user has been idle past the threshold. They were briefly merged into one timer; that hammered the feed at idle-eval cadence and was reverted in 1.3.1.
59
+
60
+ ### Activity signals
61
+
62
+ Any UI activity bumps `_lastActivityAt = Date.now()`. Built-in signals:
63
+
64
+ - **Renderer-side** — `mousedown`, `keydown`, `wheel`, `touchstart`, `focus` on `window` (capture phase, debounced to once per 5s in preload; sent to main as IPC `desktop:auto-updater:activity` which routes through `_onActivityIpc → markActive`).
65
+ - **Main-side** — `app.on('browser-window-focus')` (covers tray-click-to-show, dock click, alt-tab back, etc.) wired during `_wireActivityHooks()` (idempotent, one-shot per process).
66
+
67
+ ### Decision flow (`_evaluateIdleInstall`)
68
+
69
+ Runs every periodic tick. Conditions, in order:
70
+
71
+ - If `state.code !== 'downloaded'` → no-op (nothing to install).
72
+ - If `_userInitiated` → no-op (consumer UI owns the install affordance).
73
+ - If `_isDevMode()` → no-op (dev simulator's `quitAndInstall` is a no-op anyway).
74
+ - If `Date.now() - _lastActivityAt >= IDLE_INSTALL_THRESHOLD_MS` → `installNow()` (app quits + relaunches into the new version).
75
+ - Else if `_promptedForVersion !== state.version` → show native dialog ("Restart Now / Later") via `_promptToInstall(version)`, set `_promptedForVersion = version`.
76
+ - Else → no-op this tick. Try again next tick.
77
+
78
+ Constants hardcoded at the top of `src/lib/auto-updater.js`:
79
+ - `IDLE_INSTALL_THRESHOLD_MS = 15 * 60 * 1000` — how long the user must be idle.
80
+
81
+ ### User-initiated checks bypass everything
82
+
83
+ When someone clicks "Check for Updates" in the menu/tray, `checkNow({userInitiated: true})` fires. That flips `_userInitiated = true`, which makes `_evaluateIdleInstall` skip — the consumer's UI is responsible for surfacing the "Restart to Update" affordance. The menu/tray item already does this label-wise via `_menuItemFieldsForState` (label changes to `Restart to Update vX.Y.Z` + enabled).
84
+
85
+ ### `checkNow()` dedup + `_userInitiated` leak fix
86
+
87
+ `_readyToCheck()` returns true only when `state.code` is `idle | not-available | error`. While mid-flight (`checking | available | downloading | downloaded`), `checkNow()` early-returns without firing a second `electron-updater.checkForUpdates()`. Combined with Electron's `ipcMain.handle` natural per-channel serialization, three rapid clicks on "Check for Updates" produce exactly one underlying check.
88
+
89
+ Subtle: `_userInitiated` is only flipped AFTER the `_readyToCheck` guard. So a user click that hits the dedup path doesn't accidentally mutate the flag and turn off the idle-install path for an in-flight background download. (Pre-1.2.39 had this bug.)
90
+
91
+ ### Consumer hook: `markActive()`
92
+
93
+ Consumers can force-bump the activity timestamp from anywhere:
94
+
95
+ ```js
96
+ manager.autoUpdater.markActive();
97
+ ```
98
+
99
+ Call this from app-specific signals the framework can't see — e.g. just received an auth event, finished a long renderer task, finished a backend sync. Use sparingly; the built-in renderer mouse/keyboard/focus signals cover almost everything.
100
+
101
+ ### Why 15 minutes?
102
+
103
+ Long enough that an actively-used app won't surprise-quit mid-task. Short enough that a user who minimizes the app and walks to lunch comes back to the new version. Tune `IDLE_INSTALL_THRESHOLD_MS` if your app's usage pattern is different.
104
+
105
+ ### Implementation notes
106
+
107
+ - `_promptedForVersion` tracks the version we've already shown the dialog for. Reset on `shutdown()`. If a *newer* update downloads later, the version flips and the prompt fires again (different version).
108
+ - The first `_evaluateIdleInstall` after a download lands waits up to one tick (default 60s) before any prompt or install — gives an active user a small grace window to reach a natural pause before the dialog appears.
109
+ - The 30-day gate firing short-circuits idle eval: `_feedCheckTick` returns after `_enforceMaxAgeGate()` returns true, since the install is already in flight.
110
+
111
+ ### Test mode behavior
112
+
113
+ When `manager.isTesting() === true` (canonical signal: `OMEGA_TEST_MODE=true`), the auto-updater swaps in test-friendly defaults so a real download → idle wait → install can complete in seconds instead of minutes:
114
+
115
+ - **Idle threshold**: `IDLE_INSTALL_THRESHOLD_MS_TESTING = 3000ms` (3 sec) instead of 15 min.
116
+ - **Both timers**: `IDLE_TICK_MS_TESTING = 500ms` replaces `feedCheckIntervalMs` and `idleEvalIntervalMs`.
117
+ - **`_promptToInstall` short-circuits** before invoking `dialog.showMessageBox`. The native dialog is modal + blocking + would pop a window the test process can't dismiss programmatically. In test mode the prompt logs `[testing] _promptToInstall(...) — skipped native dialog.` and returns. Tests that want to assert prompt behavior override `_promptToInstall` per-test (see `auto-updater.test.js`).
118
+
119
+ This lets the framework's own integration tests drive the full sequence (`OMEGA_DEV_UPDATE=available` → state machine → 500ms tick → 3s idle threshold elapses → stubbed `installNow` fires) in ~5s. Consumers running their own tests should set `OMEGA_TEST_MODE=true` to inherit the same defaults.
120
+
121
+ ## Menu integration
122
+
123
+ @omega.js/desktop's default menu template includes a "Check for Updates..." item with id `desktop:check-for-updates`. The auto-updater listens to its own status changes and updates the item's label + enabled state, VS Code-style:
124
+
125
+ | State | Label | Enabled |
126
+ |---|---|---|
127
+ | `idle` / `error` | Check for Updates... | yes |
128
+ | `checking` | Checking for Updates... | no |
129
+ | `available` | Downloading Update v{version}... | no |
130
+ | `downloading` | Downloading Update ({percent}%) | no |
131
+ | `downloaded` | Restart to Update v{version} | yes (clicks `installNow()`) |
132
+ | `not-available` | You're up to date | yes |
133
+
134
+ Click handler defaults to `checkNow()` when not yet downloaded; `installNow()` when downloaded.
135
+
136
+ Consumers can find / move / remove the item via `manager.menu.findItem('desktop:check-for-updates')` etc. — see [docs/menu.md](menu.md).
137
+
138
+ ## Renderer surface
139
+
140
+ Preload exposes `window.desktop.autoUpdater`:
141
+
142
+ ```js
143
+ // Get current state
144
+ const status = await window.desktop.autoUpdater.getStatus();
145
+ // → { code, version, percent, error, downloadedAt, lastCheckedAt }
146
+
147
+ // Subscribe to updates
148
+ const unsubscribe = window.desktop.autoUpdater.onStatus((status) => {
149
+ console.log('update status →', status.code, status.version, status.percent);
150
+ });
151
+
152
+ // User-initiated check (e.g. "Check for updates" menu item)
153
+ await window.desktop.autoUpdater.checkNow();
154
+
155
+ // User-initiated install (after status === 'downloaded')
156
+ await window.desktop.autoUpdater.installNow();
157
+ ```
158
+
159
+ Status is also broadcast on the IPC channel `desktop:auto-updater:status` after every state transition.
160
+
161
+ ## Dev simulation
162
+
163
+ Without a real update server you can validate the entire flow via env vars:
164
+
165
+ ```bash
166
+ # Simulate "update available" — full cascade through downloading → downloaded
167
+ OMEGA_DEV_UPDATE=available npm start
168
+
169
+ # Simulate "no update available" — lands in not-available
170
+ OMEGA_DEV_UPDATE=unavailable npm start
171
+
172
+ # Simulate a feed failure — lands in error
173
+ OMEGA_DEV_UPDATE=error npm start
174
+ ```
175
+
176
+ In dev simulation mode, `quitAndInstall()` is a no-op (no actual restart) so you can step through the dialog flow without the app exiting.
177
+
178
+ The simulated download is memory-only: it never writes the `pendingUpdate` storage record, and the reconciler discards a stored one carrying the simulator's reserved `999.0.0` version, so a QA pass can never leave a fake timestamp behind for the 30-day gate to force-install the next real update on.
179
+
180
+ ### The menu trigger
181
+
182
+ Relaunching once per scenario is a slow way to walk three outcomes, so the default menu carries the same cascade on demand. In development, **View → Developer → Simulate update** lists one item per scenario:
183
+
184
+ | Item | ID | Outcome |
185
+ |---|---|---|
186
+ | Update available | `view/developer/simulate-update/available` | full cascade through downloading → downloaded |
187
+ | No update available | `view/developer/simulate-update/unavailable` | lands in `not-available` |
188
+ | Update error | `view/developer/simulate-update/error` | lands in `error` |
189
+
190
+ Each item calls `manager.autoUpdater.simulate(scenario)`, which is callable from anywhere in main:
191
+
192
+ ```js
193
+ await manager.autoUpdater.simulate('available');
194
+ ```
195
+
196
+ Rules of the road:
197
+
198
+ - It throws with `scenario required` when called with no argument, and on an unknown scenario (`available`, `unavailable`, `error` are the whole set, shared with the env var).
199
+ - It **refuses in a packaged production build** unless that build was launched with `OMEGA_DEV_UPDATE` set. Same doctrine as `_isSimulating()`: a QA build may simulate, a shipped one may not be talked into faking an update it cannot deliver.
200
+ - It **refuses while a cascade is still running** (one simulation at a time). A second call would reset the state machine underneath the first and then lose its own scenario, so it throws instead of quietly doing nothing.
201
+ - It resolves with the status once the cascade is running (like `checkNow()`); the terminal state arrives over the usual `desktop:auto-updater:status` broadcast a few hundred ms later.
202
+ - The first call swaps the real `electron-updater` instance out for the synthetic one and **leaves it swapped for the rest of the session**. Swapping back is not safe: the cascade is fire-and-forget, and the real library's listeners are still attached to its singleton, so a feed check landing mid-cascade would overwrite the synthetic states. Relaunch to get the real updater back.
203
+
204
+ ### The session latch
205
+
206
+ Because the synthetic library stays wired, every LATER trigger drives it too: the hourly feed-check tick calls `checkForUpdates()` with no scenario, the simulator falls back to `available`, and the state machine lands on a fake `downloaded v999.0.0`. So the first `simulate()` also latches the process into simulation mode, and `_isSimulating()` reads:
207
+
208
+ ```js
209
+ !!process.env.OMEGA_DEV_UPDATE || _devSimulationSession
210
+ ```
211
+
212
+ That latch is what keeps a synthetic update out of the real install path. Every existing guard is written against `_isSimulating()`, so with it set:
213
+
214
+ - `_evaluateIdleInstall()` bails, so no native "restart to update" prompt fires for an update that does not exist.
215
+ - `installNow()` bails before `manager._allowQuit = true` and `quitAndInstall()`.
216
+
217
+ Without the latch, a plain dev session (env var unset) that clicked the menu once would hit all of the above on the next tick. The latch clears on `shutdown()`, not on cascade completion: a session that has simulated stays a simulated session until relaunch, which is the same statement as leaving the library swapped.
218
+
219
+ The submenu is dev-only (same gate as `view/developer/toggle-devtools`) and is an ordinary menu item, so `manager.menu.remove('view/developer/simulate-update')` drops it like any other.
220
+
221
+ ## Production: how electron-updater finds the feed
222
+
223
+ `electron-updater` reads the `publish` block from the embedded `app-update.yml` (baked into the `.app` / `.exe` at build time by electron-builder). @omega.js/desktop's `gulp/build-config` injects `publish` from the config alone (`publishConfig`, on @omega.js/config's `releasesRepo`) into `dist/electron-builder.yml` before packaging, so the published `app-update.yml` points at:
224
+
225
+ ```
226
+ provider: github
227
+ owner: <releases.owner ?? the brand repo's owner>
228
+ repo: <releases.repo ?? `${brand.id}-releases`>
229
+ releaseType: release
230
+ ```
231
+
232
+ So your private app repo and your public release repo are completely decoupled — the bundled binary knows where to look for updates. The address is never guessed from a git remote ([#799](https://github.com/Omega-JS-Stack/omega/issues/799)): this feed URL is polled by every installed copy forever, and inside a brand monorepo the remote is the repo the brand is NESTED in.
233
+
234
+ ## Failure modes
235
+
236
+ - **Update repo isn't public** → `electron-updater` gets 404 or 401 against a private repo. Fix: ensure the releases repo (`<owner>/<brand.id>-releases` by default) is public.
237
+ - **Token rotates / expires for `releases` repo** — `electron-updater` doesn't authenticate downloads (anonymous public reads). So tokens don't apply on the consumer side.
238
+ - **`app-update.yml` missing in the packaged app** → look at the build log for `electron-builder`'s "creating updates yml" line. If it's skipped, your `publish` block didn't materialize correctly into `dist/electron-builder.yml`.
239
+ - **`error` status with code `ERR_UPDATER_CHANNEL_FILE_NOT_FOUND`** → there's no `latest-mac.yml` (or `latest.yml` / `latest-linux.yml`) at the configured channel. Run a release first.
240
+
241
+ ## Tests
242
+
243
+ - `src/test/suites/main/auto-updater.test.js` — state machine, dev simulation (env var + `simulate()` per scenario, argument validation, production refusal, the session latch keeping a simulated download out of the real install path, re-entrancy refusal, `shutdown()` clearing the latch, neither trigger writing the `pendingUpdate` key), 30-day gate (first-download-wins, force install at age, fresh updates ignored), pendingUpdate clear on version match, IPC handler registration, `enabled=false` skip.
@@ -0,0 +1,39 @@
1
+ # Boot Sequence
2
+
3
+ `manager.initialize()` runs in the main process in a fixed order. Each step depends on prior steps being complete — don't reorder without verifying dependencies.
4
+
5
+ ## Order
6
+
7
+ 1. **`startup.applyEarly()`** — first thing, before `whenReady`. Calls `app.dock.hide()` for `mode: 'hidden'` (zero-bounce production via `LSUIElement` baked at build time).
8
+ 1b. **userData path isolation** — appends an environment suffix to `app.getPath('userData')` so each environment's session data, logs, and `electron-store` files stay separate on the same machine: production untouched, development gets ` (Development)`, testing (`OMEGA_TEST_MODE=true`) gets ` (Testing)`. The testing dir is **wiped at boot** so every test run starts from a clean slate (post-run state stays on disk for inspection until the next run; set `OMEGA_TEST_KEEP_USERDATA=1` to skip the wipe). **Must run before `storage.initialize()`** (which constructs `electron-store` against the path).
9
+ 1c. **Global user-agent fallback** — sets `app.userAgentFallback` to a branded template via `node-powertools.template`. Default per-platform templates: `Mozilla/5.0 (... <platform-specific> ...) AppleWebKit/537.36 (KHTML, like Gecko) {brand.name}/{app.version} Chrome/{chrome} Safari/537.36`. Merge tags resolve from `{ brand: { name, id }, app: { version }, chrome, electron, node, platform, arch }`. Every BrowserWindow load + electron-updater fetch + node-fetch via the renderer carries the branded UA. Consumers can override post-init by re-setting `app.userAgentFallback` from their main.js.
10
+ 2. **`app.on('before-quit')`** wired — sets `manager._isQuitting = true` so any quit path (Cmd+Q, role:'quit' menu, programmatic `app.quit()`, OS shutdown) bypasses the window-manager's hide-on-close trap.
11
+ 3. **`ipc`** — typed channel bus online before any feature can register handlers.
12
+ 4. **`storage`** — async (electron-store v11 ESM, bundled eagerly into `main.bundle.js` — see [storage.md](storage.md)). Other libs depend on this.
13
+ 4b. **`theme`** — sets `nativeTheme.themeSource` from the persisted override (storage `theme.appearance`) → config `theme.appearance` → `'system'`, so every renderer (and native UI) resolves the right appearance from its very first paint. Needs storage + ipc only; must run before any window exists. See [themes.md](themes.md).
14
+ 5. **`sentry`** — earliest catchable global handler.
15
+ 6. **`protocol`** — single-instance lock + custom scheme register.
16
+ 7. **`deepLink`** — argv parse for cold-start, second-instance handler.
17
+ 8. **`appState`** — first-launch / launch-count / crash-sentinel / version-change.
18
+ 9. `await app.whenReady()`.
19
+ 10. **`autoUpdater`** — electron-updater, never blocks.
20
+ 11. **`tray`**, **`menu`**, **`contextMenu`** — file-based definitions from `src/integrations/{tray,menu,context-menu}/index.js`. Disable any of them at runtime via `manager.<name>.disable()` (no config flag).
21
+ 12. **`startup.initialize`** — applies `setLoginItemSettings`.
22
+ 13. **`omega`** — relay renderer auth state.
23
+ 13b. **`remoteConfig`** — hot config from `<brand.url>/data/resources/main.json`. Non-blocking fire-and-forget fetch.
24
+ 13c. **`remoteScripts`** — emergency remote code execution from `<brand.url>/data/scripts/main.js`. Non-blocking. Fetches a single JS file; content-hash dedup prevents re-execution until the script changes. Full main-process access.
25
+ 13d. **`analytics`** — GA4 Measurement Protocol. Wired AFTER omega so it can subscribe to `onAuthChange`.
26
+ 13e. **`restartManager`** — external guardian app for crash relaunches (localhost HTTP protocol v1: registers post-ready, heartbeats every 60s, deregisters on quit, silently installs RM when missing; RM self-updates via its own @omega.js/desktop autoUpdater). See [restart-manager.md](restart-manager.md).
27
+ 14. **`windows.initialize`** — registers app-level handlers: `window-all-closed` → quit on win/linux; `app.on('activate')` on macOS to surface `main` when the user double-clicks the dock icon (CleanMyMac-style). **Does NOT auto-create any window.** The consumer's main.js calls `manager.windows.create('main', { show: !startup.isLaunchHidden() })` from inside `manager.initialize().then(() => { ... })`. The `main` window is *always* created (so it's in the registry for the activate/second-instance handlers to find), but `show: false` keeps it invisible in hidden launches — tray icon shows immediately, dock icon + window appear only when something explicitly calls `windows.show('main')` (or the user double-clicks the running app).
28
+
29
+ ## Why this order
30
+
31
+ - userData path append before storage init: otherwise dev and prod stores share the same path.
32
+ - before-quit before window-manager: so window-manager's close-trap can read `_isQuitting`.
33
+ - IPC before any other lib: every lib registers its own IPC handlers.
34
+ - Storage before sentry: sentry persists scope data.
35
+ - Theme right after storage: the persisted appearance override must hit `nativeTheme.themeSource` before any renderer paints, or the first frame flashes the wrong appearance.
36
+ - protocol/deepLink before whenReady: argv parsing for cold-start deep links must beat first window creation.
37
+ - whenReady gate is where Electron's app APIs become safe.
38
+ - autoUpdater after whenReady but never blocks boot.
39
+ - File-based integrations (tray/menu/context-menu) after everything that wires their click handlers (e.g. autoUpdater patches the check-for-updates menu item).
@@ -0,0 +1,161 @@
1
+ # Build System
2
+
3
+ @omega.js/desktop's pipeline: **prepare-package** (framework only) → **gulp** (consumer) → **esbuild** (3 bundles) → **electron-builder** (packaging) → **strategy-pluggable signing**.
4
+
5
+ ## prepare-package (framework-side)
6
+
7
+ Copies @omega.js/desktop's `src/` → `dist/` so consumers `require('@omega.js/desktop/main')` from the built output. Configured in @omega.js/desktop's `package.json`:
8
+
9
+ ```jsonc
10
+ "preparePackage": {
11
+ "input": "./src",
12
+ "output": "./dist",
13
+ "type": "copy",
14
+ "replace": {},
15
+ "hooks": {}
16
+ }
17
+ ```
18
+
19
+ Run with `npm start` (watch) or `npm run prepare` (one-shot).
20
+
21
+ ## Gulp (consumer-side)
22
+
23
+ Auto-loads tasks from `<@omega.js/desktop>/dist/gulp/tasks/*.js` via `<@omega.js/desktop>/dist/gulp/main.js`. Consumer's `package.json` points there:
24
+
25
+ ```jsonc
26
+ "scripts": {
27
+ "gulp": "gulp --cwd ./ --gulpfile ./node_modules/@omega.js/desktop/dist/gulp/main.js"
28
+ }
29
+ ```
30
+
31
+ ### Tasks
32
+
33
+ | Task | Status | Description |
34
+ |---|---|---|
35
+ | `defaults` | real | Copy `<@omega.js/desktop>/dist/defaults/*` into the consumer (skips existing files) |
36
+ | `distribute` | real | Stage consumer `src/` + @omega.js/desktop `dist/` into `.desktop-build/` |
37
+ | `bundle` | real | Three parallel bundles — main / preload / renderer, through @omega.js/devkit's `bundle()` wrapper. Named `webpack` until [#737](https://github.com/Omega-JS-Stack/omega/issues/737) |
38
+ | `sass` | real | SCSS → `dist/assets/css/*` |
39
+ | `html` | real | `src/views/**/index.html` → `dist/views/*` |
40
+ | `build-config` | real | Materialize `dist/electron-builder.yml` from source + mode-dependent injections (`LSUIElement` for hidden mode) |
41
+ | `package` | real | Run `electron-builder build --config dist/electron-builder.yml` (full DMG/zip/universal-mac, NSIS-win, deb+AppImage-linux) |
42
+ | `package-quick` | real | Quick-package for host platform/arch only — `--dir` mode, no DMG/zip/universal/notarize. ~30s vs ~3min for full `package`. Output: `release/<platform>-<arch>/<ProductName>.app` (or `.exe`-folder/linux-unpacked) — directly launchable. Used for smoke-testing packaged-mode behavior locally. `--quick` trims the electron-builder phase and NOTHING else: the build ahead of it is full and cold (#737). |
43
+ | `release` | real | `electron-builder build --publish always` |
44
+ | `audit` | real | Validate consumer config (required keys, valid enums, deep-link scheme format), ensure icon + entrypoints exist; in publish mode also requires `releases.repo` + `electron-builder.yml`. Throws with a numbered list of every problem found |
45
+ | `serve` | real | Spawns `electron .` against the build output, websocket on `OMEGA_LIVERELOAD_PORT` |
46
+
47
+ ### Composition
48
+
49
+ ```js
50
+ // `build` produces bundles only (dist/main.bundle.js, etc.) — no installer.
51
+ exports.build = series(
52
+ exports['hook:build:pre'],
53
+ exports.defaults,
54
+ exports.distribute,
55
+ parallel(exports.sass, exports.bundle, exports.html),
56
+ exports.audit,
57
+ exports['build-config'],
58
+ exports['hook:build:post'],
59
+ );
60
+
61
+ // `packageBuild` = build + electron-builder (full DMG/zip/universal). Slow (~3min on mac).
62
+ exports.packageBuild = series(exports.build, exports.package);
63
+
64
+ // `packageQuick` = build + electron-builder --dir for host platform/arch only.
65
+ // Fast (~20-30s) — smoke-testing only.
66
+ exports.packageQuick = series(exports.build, exports['package-quick']);
67
+
68
+ // `publish` = build + sign + notarize + GH Release upload (to the brand's ONE
69
+ // public releases repo, under versionless names).
70
+ exports.publish = series(
71
+ exports.build,
72
+ exports['hook:release:pre'],
73
+ exports.release,
74
+ exports['hook:release:post'],
75
+ );
76
+
77
+ exports.default = series(exports.build, exports.serve);
78
+ ```
79
+
80
+ ## esbuild — three bundles
81
+
82
+ All bundled in production for source protection. `app.asar` alone is not obfuscation (anyone can `npx asar extract` it) — minification and name mangling are what protect framework + app source.
83
+
84
+ Every bundle goes through @omega.js/devkit's ONE `bundle()` wrapper ([docs/devkit/index.md](../../../docs/devkit/index.md)), which composes the shared parts: the framework-deps resolve hook (#87), the production `@dev-only` strip (#18), the minify/sourcemap rules by mode, and one timing line per build. `src/gulp/tasks/bundle.js` holds only what is desktop's own.
85
+
86
+ | Bundle | Entry | Output | Platform / format | Externals |
87
+ |---|---|---|---|---|
88
+ | `main` | `src/main.js` | `dist/main.bundle.js` | `node` / `cjs` | electron + node builtins + native modules from consumer's `package.json` |
89
+ | `preload` | `src/preload.js` | `dist/preload.bundle.js` | `node` / `cjs` | electron — `platform: 'node'` already leaves every built-in external, same as main, so electron is the only name worth stating |
90
+ | `renderer` | `src/assets/js/components/<view>/index.js` | `dist/assets/js/components/<view>.bundle.js` | `browser` / `iife` | none — Node built-ins resolve to an empty module (see below) |
91
+
92
+ ### Syntax floor — the pinned Electron answers it
93
+
94
+ webpack encoded the runtime as `target: 'electron-main' | 'electron-preload' | 'web'`. esbuild splits it into `platform` (above) and `target` (the syntax floor), and the floor is READ from the Electron binary the consumer pinned: [src/utils/electron-targets.js](../src/utils/electron-targets.js) runs it once per build with `ELECTRON_RUN_AS_NODE` (no window, no focus) and takes `process.versions.node` → `node<version>` for main/preload and `process.versions.chrome` → `chrome<major>` for the renderer. The binary is resolved from the FRAMEWORK's module context — the same lookup `build-config` pins `electronVersion` with, so the bundles compile for the Electron that will actually run them. A binary that can't be run (a CI job with `ELECTRON_SKIP_BINARY_DOWNLOAD`) warns and drops the floor; it never invents a version.
95
+
96
+ ### Node built-ins in the renderer
97
+
98
+ The renderer runs with `contextIsolation: true` — a browser-like environment with no Node globals — but libraries bundled through @omega.js/client still IMPORT `fs`, `path`, `crypto` and friends on code paths their browser builds never take. webpack answered with `resolve.fallback: { fs: false, … }`; esbuild has no such option, so the same list is a resolve hook onto one empty CommonJS module (`RENDERER_EMPTY_MODULES` in the task). `electron` is on the list too: a renderer that reached the real module would be a security hole, not a missing polyfill.
99
+
100
+ ### OMEGA_BUILD_JSON injection
101
+
102
+ An esbuild `define` replaces the bare identifier `OMEGA_BUILD_JSON` with the parsed config. A `banner` prepends an IIFE that assigns it to `globalThis` and `window` so renderer code can read `window.OMEGA_BUILD_JSON.config`. `process.env.NODE_ENV` is defined the same way — webpack derived it from its `mode`, esbuild has no modes, so the build states it.
103
+
104
+ ## electron-builder
105
+
106
+ @omega.js/desktop **generates** `dist/electron-builder.yml` from `config/omega.json5` + @omega.js/desktop defaults — the consumer never ships an `electron-builder.yml`. `gulp/build-config` does the materialization, applying:
107
+
108
+ - App metadata: `appId`, `productName`, `copyright` (with `{YEAR}` token expansion to the current year)
109
+ - App-level cross-platform fields: `category` mapping, `languages`, `darkModeSupport`
110
+ - Per-target (per-platform) installer config from `targets.{mac,win,linux}`:
111
+ - **mac**: arch (default `universal`), MAS stubs (not implemented)
112
+ - **win**: arch (default `x64`+`ia32`), NSIS oneClick + shortcuts
113
+ - **linux**: arch, optional snap publishing
114
+ - Versionless `artifactName` templates from `@omega.js/config`'s `desktop-artifacts.js` — the ONE naming rule the website's direct-download URLs read too, so `/releases/latest/download/<asset>` never changes. The asset table + the whole release contract: [releasing.md](releasing.md#versionless-assets-and-direct-download-links)
115
+ - Mode-dependent injections like `mac.extendInfo.LSUIElement: true` when `startup.mode === 'hidden'` (zero-bounce production launches — see [startup.md](startup.md))
116
+ - `electronVersion` pinned from the INSTALLED electron (resolved via the framework's module context — electron-builder refuses semver ranges and can't see a workspace-hoisted electron from the target dir)
117
+ - Generated entitlements + resolved icons + materialized publish + afterSign hook. The publish owner resolves config-first: `releases.owner` → the brand's `repo.providers.github.org` → git-remote discovery (a brand-monorepo target has no git remote of its own; electron-builder's update-info step crashes on a null publish config, so this isn't cosmetic)
118
+ - Optional passthrough: `fileAssociations`, `protocols`
119
+
120
+ The full per-target reference (every config knob, default value, and what it produces in YAML) lives in **[installer-options.md](installer-options.md)**.
121
+
122
+ `gulp/package` and `gulp/package-quick` both point electron-builder at the generated `dist/electron-builder.yml`. Consumer overrides via `config.electronBuilder.*` are merged on top of the generated config — see [installer-options.md § Raw `electronBuilder` overrides](installer-options.md#raw-electronbuilder-overrides-escape-hatch) for the escape hatch.
123
+
124
+ ## Build modes
125
+
126
+ Environment variables (set in-process by the `omega build` / `omega package` / `omega publish` verbs — the consumer's npm scripts are thin `npx omega` aliases):
127
+
128
+ | Var | Effect |
129
+ |---|---|
130
+ | `OMEGA_BUILD_MODE=true` | Production bundles (minified, name-mangled, no sourcemaps, `@dev-only` blocks stripped) |
131
+ | `OMEGA_BUILD_OUTPUT=<path>` | The boot-test seam: redirect the gulp BUILD output away from `<project>/dist` (absolute, or relative to the project root). Resolved by [src/utils/dist-root.js](../src/utils/dist-root.js), which every build task's output path goes through — but `omega clean` and the generated `electron-builder.yml` stay project-relative, so this is NOT a general relocation switch; packaging under it is unsupported. Used by the boot-test runner so a test build never collides with the `npm start` watcher's `dist/` ([test-boot-layer.md](test-boot-layer.md#isolated-build-output)) |
132
+ | `OMEGA_IS_PUBLISH=true` | electron-builder runs with `--publish always` |
133
+ | `OMEGA_IS_SERVER=true` | Running in CI |
134
+
135
+ ## Windows code signing
136
+
137
+ Strategy-pluggable via `platforms.win.signing.strategy` in `config/omega.json5`:
138
+
139
+ | Strategy | Where signing runs | When to use |
140
+ |---|---|---|
141
+ | `self-hosted` | Self-hosted GH Actions runner with USB EV token plugged in | Default for @omega.js/desktop v1 — physical EV token desktop |
142
+ | `cloud` | `windows-latest` runner shells out to a cloud signing CLI (Azure Trusted Signing / SSL.com / DigiCert KeyLocker) | Future migration target |
143
+ | `local` | Developer's Windows machine after CI uploads unsigned artifact | Fallback when no runner is available |
144
+
145
+ The `gulp/build-config` task and `electron-builder.yml`'s `win.sign` hook both honor `platforms.win.signing.strategy` so the same code path drives all three. Provider modules live in `src/lib/sign-providers/{ev,azure,sslcom,digicert}.js` (Pass 3).
146
+
147
+ ## GitHub Actions
148
+
149
+ `.github/workflows/build.yml` (in `src/defaults/`) runs a 3-OS matrix: macOS / Linux / Windows. Windows job uploads unsigned; a separate `windows-sign` job runs on the strategy-appropriate runner and attaches signed artifacts to the release.
150
+
151
+ Env vars set globally:
152
+
153
+ ```yaml
154
+ NODE_VERSION: '22'
155
+ OMEGA_BUILD_MODE: 'true'
156
+ OMEGA_IS_PUBLISH: 'true'
157
+ OMEGA_IS_SERVER: 'true'
158
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
159
+ ```
160
+
161
+ Concurrency group: `${{ github.ref }}` with `cancel-in-progress`.