@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,752 @@
1
+ // Auto-updater — wraps electron-updater with these triggers:
2
+ //
3
+ // 1. Startup check — fires `startupDelayMs` after `whenReady` (default 10s, non-blocking).
4
+ // 2. Feed-check timer — every `feedCheckIntervalMs` (default 1h). HTTP-bound — hits the
5
+ // release feed. Hourly to match Discord/Slack/VS Code; running this
6
+ // every minute would hammer GitHub at 60× the necessary rate.
7
+ // 3. Idle-eval timer — every `idleEvalIntervalMs` (default 1m). In-process arithmetic only,
8
+ // no HTTP. Decides whether to install an already-downloaded update
9
+ // based on user idle time. Frequent so a downloaded update installs
10
+ // promptly when the user steps away (rather than waiting up to an
11
+ // hour for the next feed-check).
12
+ // 4. 30-day pending gate — once an update is downloaded, store `downloadedAt`. On every
13
+ // feed-check tick + at app start, if (now - downloadedAt) >= maxAgeMs
14
+ // (default 30d), force `quitAndInstall()`. Counter is set on the FIRST
15
+ // download and not reset by subsequent downloads — first one wins.
16
+ // Cleared only when the app actually launches at the
17
+ // pendingUpdate.version (i.e. install applied).
18
+ //
19
+ // State machine (broadcast to renderers as `desktop:auto-updater:status`):
20
+ // idle / checking / available / downloading / downloaded / not-available / error
21
+ //
22
+ // Dev simulation: set `OMEGA_DEV_UPDATE=available|unavailable|error` env var. The updater synthesizes
23
+ // the appropriate event sequence so you can test the UI flow without a real update server.
24
+ // `simulate(scenario)` is the same cascade on demand (View > Developer > Simulate update in the
25
+ // default menu), so a QA pass walks all three outcomes without relaunching per scenario.
26
+ //
27
+ // Renderer surface (added to preload.js as `window.desktop.autoUpdater`):
28
+ // getStatus() → { code, version, percent, error?, downloadedAt? }
29
+ // onStatus(fn) → unsubscribe fn; called on every state change.
30
+ // checkNow() → user-initiated check (shows dialogs on completion).
31
+ // installNow() → quitAndInstall() if status === 'downloaded'.
32
+
33
+ const LoggerLite = require('./logger-lite.js');
34
+ const logger = new LoggerLite('auto-updater');
35
+
36
+ const STORAGE_KEY = 'autoUpdater';
37
+
38
+ // Idle-aware install constant — hardcoded for now (not config-shaped). Tune here.
39
+ //
40
+ // A downloaded update no longer auto-installs after a flat 5s delay. Instead, the
41
+ // idle-eval timer (every `DEFAULTS.idleEvalIntervalMs`, default 1m) makes the
42
+ // install decision:
43
+ // 1. Any UI activity (mouse / keyboard / wheel / touch / window focus) bumps
44
+ // `_lastActivityAt = Date.now()`.
45
+ // 2. The idle-eval tick checks `state.code === 'downloaded'`:
46
+ // - If user idle ≥ IDLE_INSTALL_THRESHOLD_MS → installNow().
47
+ // - Else if we haven't prompted for this version yet → native dialog (once).
48
+ // 3. Dismissal ("Later") is "not now" — the idle-eval tick keeps polling and the
49
+ // install fires whenever the user eventually walks away. We never re-prompt
50
+ // for the same version (tracked via `_promptedForVersion`).
51
+ //
52
+ // Consumer hook: `manager.autoUpdater.markActive()` lets app code force-bump the
53
+ // activity timestamp from anywhere (e.g. just received an auth event, finished a
54
+ // long-running renderer task, etc.). Use sparingly — the built-in signals cover
55
+ // 99% of real activity.
56
+ //
57
+ // Test mode: when `manager.isTesting()` is true, the threshold collapses to 3s so
58
+ // integration tests can drive a real download → idle wait → install in ~5s instead
59
+ // of 15min. Both timers (feed-check + idle-eval) likewise drop to 500ms in tests so
60
+ // the full sequence fires inside a test run. Wired in `_idleThresholdMs()` and the
61
+ // initialize() timer setup based on the manager's `isTesting()` helper.
62
+ const IDLE_INSTALL_THRESHOLD_MS = 15 * 60 * 1000; // 15 min — production
63
+ const IDLE_INSTALL_THRESHOLD_MS_TESTING = 3 * 1000; // 3 sec — when isTesting()
64
+ const IDLE_TICK_MS_TESTING = 500; // 500ms periodic tick when testing
65
+
66
+ // The dev simulator's scenarios. Doubles as the OMEGA_DEV_UPDATE value set and the
67
+ // argument set simulate() accepts, so the env var and the menu trigger can never drift.
68
+ const SIMULATION_SCENARIOS = ['available', 'unavailable', 'error'];
69
+
70
+ // The version the simulator claims to have downloaded. A RESERVED sentinel: the
71
+ // reconciler discards any stored pendingUpdate carrying it (see _reconcilePendingUpdate),
72
+ // so an app must never ship a real release at this version.
73
+ const SIMULATED_VERSION = '999.0.0';
74
+
75
+ // Two separate timers, two different jobs:
76
+ //
77
+ // feedCheckIntervalMs — how often to hit the update feed (HTTP request). EXPENSIVE
78
+ // (network I/O against a third-party host every running app
79
+ // instance). Default 1h matches Discord/Slack/VS Code.
80
+ // idleEvalIntervalMs — how often to re-evaluate "is now a good time to install
81
+ // the downloaded update?" CHEAP (in-process arithmetic on
82
+ // _lastActivityAt + state check). Default 1min so a downloaded
83
+ // update installs promptly when the user steps away.
84
+ //
85
+ // They were briefly merged into a single timer in 1.2.38; that was a mistake — running
86
+ // the feed-check at idle-eval cadence (60s) was hammering GitHub at 60× the necessary
87
+ // rate. Restored as separate timers in 1.3.1.
88
+ const DEFAULTS = {
89
+ enabled: true,
90
+ channel: 'latest',
91
+ startupDelayMs: 10 * 1000, // 10s after whenReady
92
+ feedCheckIntervalMs: 60 * 60 * 1000, // 1h — feed poll cadence
93
+ idleEvalIntervalMs: 1 * 60 * 1000, // 1m — idle-install evaluator cadence
94
+ maxAgeMs: 30 * 24 * 60 * 60 * 1000, // 30 days
95
+ autoDownload: true,
96
+ };
97
+
98
+ // Fresh state object so a single `Object.assign` never bleeds between instances or test runs.
99
+ function freshState() {
100
+ return {
101
+ code: 'idle',
102
+ version: null,
103
+ percent: 0,
104
+ error: null,
105
+ downloadedAt: null,
106
+ lastCheckedAt: null,
107
+ };
108
+ }
109
+
110
+ const autoUpdater = {
111
+ _initialized: false,
112
+ _manager: null,
113
+ _library: null,
114
+ _options: null,
115
+ _state: freshState(),
116
+ _feedCheckIntervalId: null,
117
+ _idleEvalIntervalId: null,
118
+ _pendingTimers: [],
119
+ _userInitiated: false,
120
+ _devSimulating: false, // a cascade is running RIGHT NOW (re-entrancy guard)
121
+ _devSimulationSession: false, // this process has simulated at least once (see _isSimulating)
122
+
123
+ // Idle-aware install state.
124
+ _lastActivityAt: Date.now(), // bumped by markActive(); seed to "now" so we don't auto-install the instant we boot
125
+ _promptedForVersion: null, // version string we've already prompted about — never prompt twice for the same version
126
+ _activityHooksWired: false, // guard: only wire main-side activity listeners once per process
127
+
128
+ async initialize(manager) {
129
+ autoUpdater._manager = manager;
130
+ autoUpdater._initialized = true;
131
+ autoUpdater._state = freshState();
132
+
133
+ const cfg = (manager && manager.config && manager.config.autoUpdate) || {};
134
+ autoUpdater._options = { ...DEFAULTS, ...cfg };
135
+
136
+ if (autoUpdater._options.enabled === false) {
137
+ logger.log('auto-updater disabled via config.autoUpdate.enabled=false');
138
+ return;
139
+ }
140
+
141
+ // 1. Reconcile any pending update from a prior session.
142
+ autoUpdater._reconcilePendingUpdate();
143
+
144
+ // 2. Wire the electron-updater instance (or dev simulator).
145
+ if (autoUpdater._isSimulating()) {
146
+ logger.log(`Dev simulation mode active (OMEGA_DEV_UPDATE=${process.env.OMEGA_DEV_UPDATE})`);
147
+ autoUpdater._wireDevSimulator();
148
+ } else {
149
+ autoUpdater._wireElectronUpdater();
150
+ }
151
+
152
+ // 3. IPC: renderer status query + actions. Unhandle first so re-init is idempotent.
153
+ if (manager && manager.ipc) {
154
+ const channels = [
155
+ ['desktop:auto-updater:status', async () => autoUpdater.getStatus()],
156
+ ['desktop:auto-updater:check-now', async () => autoUpdater.checkNow({ userInitiated: true })],
157
+ ['desktop:auto-updater:install-now', async () => autoUpdater.installNow()],
158
+ ];
159
+ for (const [chan, fn] of channels) {
160
+ manager.ipc.unhandle(chan);
161
+ manager.ipc.handle(chan, fn);
162
+ }
163
+ // Activity ping from preload (debounced renderer-side mouse/keyboard/focus).
164
+ // Listener (not handle) — fire-and-forget, no response needed. Set-backed
165
+ // listener registry deduplicates same-fn re-adds, so re-init is safe.
166
+ if (typeof manager.ipc.on === 'function') {
167
+ manager.ipc.on('desktop:auto-updater:activity', autoUpdater._onActivityIpc);
168
+ }
169
+ }
170
+
171
+ // 3b. Wire main-side activity hooks (browser-window focus, tray clicks, menu
172
+ // invocations, deep-link arrivals — see _wireActivityHooks). One-shot per process.
173
+ autoUpdater._wireActivityHooks();
174
+
175
+ // 4. Schedule startup check (non-blocking).
176
+ const startupDelay = autoUpdater._options.startupDelayMs;
177
+ autoUpdater._pendingTimers.push(setTimeout(() => {
178
+ autoUpdater.checkNow({ userInitiated: false }).catch((e) => logger.warn(`startup check failed: ${e.message}`));
179
+ }, startupDelay));
180
+
181
+ // 5. Schedule TWO independent timers:
182
+ //
183
+ // a) Feed-check timer (EXPENSIVE — HTTP). Hits the GitHub release feed.
184
+ // Default 1h cadence. Also enforces the 30-day max-age gate as a safety net
185
+ // since this tick is when we'd notice a long-pending update.
186
+ //
187
+ // b) Idle-eval timer (CHEAP — in-process). Re-evaluates whether to install
188
+ // a downloaded update based on user idle time. Default 1m cadence so a
189
+ // downloaded update installs promptly when the user steps away.
190
+ //
191
+ // In tests (`manager.isTesting() === true`) both cadences collapse to
192
+ // IDLE_TICK_MS_TESTING (500ms) so an integration test sees the full sequence
193
+ // fire within seconds of a download.
194
+ const isTesting = manager.isTesting();
195
+ const feedInterval = isTesting ? IDLE_TICK_MS_TESTING : autoUpdater._options.feedCheckIntervalMs;
196
+ const idleInterval = isTesting ? IDLE_TICK_MS_TESTING : autoUpdater._options.idleEvalIntervalMs;
197
+
198
+ if (feedInterval > 0) {
199
+ autoUpdater._feedCheckIntervalId = setInterval(() => autoUpdater._feedCheckTick(), feedInterval);
200
+ }
201
+ if (idleInterval > 0) {
202
+ autoUpdater._idleEvalIntervalId = setInterval(() => autoUpdater._idleEvalTick(), idleInterval);
203
+ }
204
+
205
+ logger.log(`auto-updater initialized (feed-check=${feedInterval}ms, idle-eval=${idleInterval}ms, maxAge=${autoUpdater._options.maxAgeMs}ms, idle-install threshold=${autoUpdater._idleThresholdMs() / 1000}s${isTesting ? ' [testing]' : ''})`);
206
+ },
207
+
208
+ // Feed-check tick — hits the GitHub release feed. Expensive (HTTP). Also enforces
209
+ // the 30-day max-age gate since this is the slower-cadence tick.
210
+ async _feedCheckTick() {
211
+ try {
212
+ await autoUpdater.checkNow({ userInitiated: false });
213
+ } catch (e) {
214
+ logger.warn(`feed-check failed: ${e.message}`);
215
+ }
216
+ autoUpdater._enforceMaxAgeGate();
217
+ },
218
+
219
+ // Idle-eval tick — cheap, no network. Just decides whether to install the
220
+ // already-downloaded update. Runs frequently so a downloaded update installs
221
+ // promptly when the user steps away (rather than waiting for the next hourly
222
+ // feed-check).
223
+ _idleEvalTick() {
224
+ autoUpdater._evaluateIdleInstall();
225
+ },
226
+
227
+ // Public API ─────────────────────────────────────────────────────────────────────
228
+
229
+ getStatus() {
230
+ return { ...autoUpdater._state };
231
+ },
232
+
233
+ async checkNow(opts) {
234
+ opts = opts || {};
235
+ autoUpdater._state.lastCheckedAt = Date.now();
236
+
237
+ if (!autoUpdater._readyToCheck()) {
238
+ // Already mid-check or sitting on a downloaded update — return without mutating
239
+ // _userInitiated. Otherwise a user clicking "Check for Updates" while a periodic
240
+ // background check is in flight would flip _userInitiated=true, which then makes
241
+ // _evaluateIdleInstall() skip the auto-install path (see line ~303). The flag must
242
+ // only flip when we actually start a new check.
243
+ logger.log(`Skipping check — current state=${autoUpdater._state.code}`);
244
+ return autoUpdater.getStatus();
245
+ }
246
+ autoUpdater._userInitiated = !!opts.userInitiated;
247
+
248
+ if (autoUpdater._isSimulating()) {
249
+ autoUpdater._runDevSimulation();
250
+ return autoUpdater.getStatus();
251
+ }
252
+
253
+ if (!autoUpdater._library) {
254
+ logger.warn('checkNow() called before library wired.');
255
+ return autoUpdater.getStatus();
256
+ }
257
+
258
+ try {
259
+ await autoUpdater._library.checkForUpdates();
260
+ } catch (e) {
261
+ autoUpdater._setState({ code: 'error', error: { message: e.message } });
262
+ }
263
+ return autoUpdater.getStatus();
264
+ },
265
+
266
+ // Dev-only runtime trigger for the update simulator, wired to the default menu's
267
+ // View > Developer > Simulate update items. Runs the same synthetic cascade the
268
+ // OMEGA_DEV_UPDATE env var drives at boot, except per call, so update UX can be
269
+ // walked scenario by scenario without relaunching the app (or shipping a release).
270
+ // Resolves with the status once the cascade is running, exactly like checkNow();
271
+ // the terminal state arrives over the status broadcast a few hundred ms later.
272
+ async simulate(scenario) {
273
+ const name = String(scenario || '').toLowerCase();
274
+ if (!name) {
275
+ throw new Error(`simulate(): scenario required, one of ${SIMULATION_SCENARIOS.join('|')}`);
276
+ }
277
+ if (!SIMULATION_SCENARIOS.includes(name)) {
278
+ throw new Error(`simulate(): unknown scenario "${scenario}". Expected one of: ${SIMULATION_SCENARIOS.join(', ')}.`);
279
+ }
280
+
281
+ // Same doctrine as _isSimulating(): a packaged production build may simulate, but
282
+ // only when it was LAUNCHED for QA with OMEGA_DEV_UPDATE set. Without that opt-in a
283
+ // shipped binary must never be talked into faking an update it cannot deliver.
284
+ if (autoUpdater._manager.isProduction() && !autoUpdater._isSimulating()) {
285
+ throw new Error('simulate(): refused in a production build. Relaunch with OMEGA_DEV_UPDATE set to simulate updates.');
286
+ }
287
+
288
+ // A cascade runs on fire-and-forget timers, so a second one cannot share the state
289
+ // machine with the first: it would reset the state to idle underneath it and then
290
+ // lose its own scenario to _runDevSimulation's re-entrancy guard. Refuse loudly
291
+ // rather than accept a call that silently does nothing.
292
+ if (autoUpdater._devSimulating) {
293
+ logger.warn(`simulate(${name}): refused, a simulation is already running.`);
294
+ throw new Error('simulate(): a simulation is already running. Wait for it to finish before starting another.');
295
+ }
296
+
297
+ // Swap the real electron-updater instance out for the synthetic one and LEAVE it
298
+ // swapped for the rest of the session. Swapping back is not safe: the cascade is
299
+ // async and fire-and-forget (there is no moment we know it ended), and the real
300
+ // library's listeners are still attached to its singleton, so a feed check landing
301
+ // mid-cascade would overwrite the synthetic states. A session that has simulated is
302
+ // a QA session; relaunch to get the real updater back. Idempotent when the boot-time
303
+ // simulator is already wired.
304
+ autoUpdater._wireDevSimulator();
305
+
306
+ // Latch the session ON with the swap, never apart from it: the two facts (a
307
+ // synthetic library is wired / the updater is simulating) must not disagree.
308
+ autoUpdater._devSimulationSession = true;
309
+
310
+ // Clear the visible state so a second simulation does not inherit the version,
311
+ // percent, or error the previous one left behind. downloadedAt is deliberately
312
+ // kept: the 30-day pending-update record is not ours to erase.
313
+ autoUpdater._userInitiated = true; // keeps the idle-eval tick from installing a simulated download
314
+ autoUpdater._setState({ code: 'idle', version: null, percent: 0, error: null, lastCheckedAt: Date.now() });
315
+
316
+ logger.log(`simulate(${name}): running the dev update cascade`);
317
+ await autoUpdater._library.checkForUpdates(name);
318
+ return autoUpdater.getStatus();
319
+ },
320
+
321
+ // Bump the activity timestamp. Called automatically by the built-in activity hooks
322
+ // (renderer mouse/keyboard, browser-window focus). Consumer code can also call this
323
+ // directly from anywhere (`manager.autoUpdater.markActive()`) to force-bump on
324
+ // app-specific activity.
325
+ markActive() {
326
+ autoUpdater._lastActivityAt = Date.now();
327
+ },
328
+
329
+ // Named handler for the IPC activity listener so the listener registry's Set-based
330
+ // dedupe collapses repeated re-init calls into one entry.
331
+ _onActivityIpc() {
332
+ autoUpdater.markActive();
333
+ },
334
+
335
+ async installNow() {
336
+ if (autoUpdater._state.code !== 'downloaded') {
337
+ logger.log(`installNow ignored — state=${autoUpdater._state.code}`);
338
+ return false;
339
+ }
340
+ if (autoUpdater._isSimulating()) {
341
+ logger.log('Dev mode — skipping real quitAndInstall().');
342
+ return true;
343
+ }
344
+ // Flip the manager's quit flag so the window-manager close handler lets the
345
+ // close events through instead of trapping them with hide-on-close. Without
346
+ // this, quitAndInstall() fires before-quit but the BrowserWindow's close
347
+ // handler (which runs FIRST since it has its own listener) would call
348
+ // event.preventDefault() and the install would just hide the window.
349
+ if (autoUpdater._manager) {
350
+ autoUpdater._manager._allowQuit = true;
351
+ }
352
+ if (autoUpdater._library && typeof autoUpdater._library.quitAndInstall === 'function') {
353
+ autoUpdater._library.quitAndInstall();
354
+ return true;
355
+ }
356
+ return false;
357
+ },
358
+
359
+ // Lifecycle teardown — used by tests.
360
+ shutdown() {
361
+ if (autoUpdater._feedCheckIntervalId) clearInterval(autoUpdater._feedCheckIntervalId);
362
+ if (autoUpdater._idleEvalIntervalId) clearInterval(autoUpdater._idleEvalIntervalId);
363
+ autoUpdater._pendingTimers.forEach((t) => clearTimeout(t));
364
+ autoUpdater._feedCheckIntervalId = null;
365
+ autoUpdater._idleEvalIntervalId = null;
366
+ autoUpdater._pendingTimers = [];
367
+ autoUpdater._initialized = false;
368
+ autoUpdater._library = null;
369
+ autoUpdater._userInitiated = false;
370
+ autoUpdater._devSimulating = false;
371
+ autoUpdater._devSimulationSession = false;
372
+ autoUpdater._promptedForVersion = null;
373
+ autoUpdater._activityHooksWired = false;
374
+
375
+ const m = autoUpdater._manager;
376
+ if (m && m.ipc && typeof m.ipc.unhandle === 'function') {
377
+ ['desktop:auto-updater:status', 'desktop:auto-updater:check-now', 'desktop:auto-updater:install-now'].forEach((c) => {
378
+ m.ipc.unhandle(c);
379
+ });
380
+ }
381
+ },
382
+
383
+ // Internals ──────────────────────────────────────────────────────────────────────
384
+
385
+ // Auto-updater dev SIMULATION mode — controls whether checkForUpdates() is wired
386
+ // to electron-updater (real) or our synthetic event sequence (fake). Triggered by
387
+ // setting OMEGA_DEV_UPDATE=available|unavailable|error. NOT the same as
388
+ // `manager.isDevelopment()` (which is the runtime "are we packaged" signal); a
389
+ // packaged production build can absolutely run with OMEGA_DEV_UPDATE set for QA.
390
+ //
391
+ // The runtime simulate() latches `_devSimulationSession` for the rest of the process
392
+ // (cleared by shutdown()). It has to: simulate() leaves the synthetic library wired,
393
+ // so every LATER trigger drives the simulator too. The feed-check tick would then
394
+ // produce a fake 'downloaded' that this flag is the only thing keeping out of the
395
+ // real install path (_evaluateIdleInstall and installNow both bail on it). Reading
396
+ // only the env var here means a plain dev session could be talked into a native
397
+ // "restart to update" prompt, `_allowQuit = true`, and a stored pendingUpdate for a
398
+ // version that does not exist.
399
+ _isSimulating() {
400
+ return !!process.env.OMEGA_DEV_UPDATE || autoUpdater._devSimulationSession;
401
+ },
402
+
403
+ _idleThresholdMs() {
404
+ return autoUpdater._manager.isTesting() ? IDLE_INSTALL_THRESHOLD_MS_TESTING : IDLE_INSTALL_THRESHOLD_MS;
405
+ },
406
+
407
+ _readyToCheck() {
408
+ // Don't re-check while we're already mid-flight (checking/available/downloading) or sitting
409
+ // on a downloaded update waiting to install — re-checking would just re-download the same thing.
410
+ return ['idle', 'not-available', 'error'].includes(autoUpdater._state.code);
411
+ },
412
+
413
+ _setState(patch) {
414
+ const prevCode = autoUpdater._state.code;
415
+ autoUpdater._state = { ...autoUpdater._state, ...patch };
416
+ autoUpdater._broadcastStatus();
417
+
418
+ // No post-download install trigger here. All install-decision logic lives in the
419
+ // idle-eval tick (`_evaluateIdleInstall`). It runs every idleEvalIntervalMs
420
+ // (default 1m); first evaluation happens on the next tick after download
421
+ // completes (gives a user who's currently active a chance to reach a natural
422
+ // pause before any prompt fires).
423
+ },
424
+
425
+ // Evaluate whether to auto-install or prompt. Called from the idle-eval tick.
426
+ // The 30-day gate runs on the feed-check tick separately.
427
+ // - Only runs when state.code === 'downloaded' (i.e. an update is sitting ready).
428
+ // - Skips if the original check was user-initiated (consumer UI handles that path).
429
+ // - If user idle ≥ _idleThresholdMs() (15min in prod, 3s in tests) → installNow().
430
+ // - Else if we haven't prompted for this version yet → show native dialog.
431
+ // - Else: do nothing this tick. Try again next tick.
432
+ _evaluateIdleInstall() {
433
+ if (autoUpdater._state.code !== 'downloaded') return;
434
+ if (autoUpdater._userInitiated) return; // user-initiated path — consumer UI owns the install affordance
435
+ if (autoUpdater._isSimulating()) return; // dev simulator never really installs
436
+
437
+ const idleMs = Date.now() - autoUpdater._lastActivityAt;
438
+ const threshold = autoUpdater._idleThresholdMs();
439
+ if (idleMs >= threshold) {
440
+ logger.log(`User idle for ${Math.round(idleMs / 1000)}s (threshold=${Math.round(threshold / 1000)}s) — auto-installing update v${autoUpdater._state.version}.`);
441
+ // installNow is async; any internal throw becomes a rejection caught by
442
+ // the global unhandledRejection handler in main.js.
443
+ autoUpdater.installNow().catch((e) => logger.warn(`idle auto-install failed: ${e.message}`));
444
+ return;
445
+ }
446
+
447
+ // User is active — prompt once per version.
448
+ const v = autoUpdater._state.version;
449
+ if (v && autoUpdater._promptedForVersion !== v) {
450
+ autoUpdater._promptedForVersion = v;
451
+ autoUpdater._promptToInstall(v).catch((e) => logger.warn(`install prompt failed: ${e.message}`));
452
+ }
453
+ },
454
+
455
+ // Show a native dialog asking the user to restart now. Non-blocking (fire-and-forget).
456
+ // Dismissal ("Later") is fine — the watcher keeps polling and will auto-install once
457
+ // the user goes idle.
458
+ async _promptToInstall(version) {
459
+ // In test mode we short-circuit BEFORE invoking the real native dialog. The
460
+ // dialog is modal + blocking on a real desktop session and pops a window the
461
+ // user can't dismiss programmatically — exactly what we don't want firing
462
+ // during automated runs. Tests that want to assert prompt behavior should
463
+ // override `_promptToInstall` per-test (see auto-updater.test.js).
464
+ if (autoUpdater._manager.isTesting()) {
465
+ logger.log(`Test mode: _promptToInstall(${version}) — skipped native dialog.`);
466
+ return;
467
+ }
468
+
469
+ const { dialog, BrowserWindow } = require('electron');
470
+ if (!dialog) return; // renderer/preload context — no dialog API
471
+
472
+ const focusedWindow = BrowserWindow.getFocusedWindow();
473
+ const productName = autoUpdater._manager.config.app?.productName
474
+ || autoUpdater._manager.config.brand.name;
475
+
476
+ // showMessageBox CAN reject (e.g. dialog destroyed, no display) — wrap just
477
+ // the call. Synchronous setup above doesn't need a try.
478
+ let result;
479
+ try {
480
+ result = await dialog.showMessageBox(focusedWindow, {
481
+ type: 'info',
482
+ buttons: ['Restart Now', 'Later'],
483
+ defaultId: 0,
484
+ cancelId: 1,
485
+ title: 'Update Ready',
486
+ message: `${productName} is ready to install version ${version}.`,
487
+ detail: `Restart to apply the update now, or it will install automatically the next time you're idle.`,
488
+ });
489
+ } catch (e) {
490
+ logger.warn(`_promptToInstall: dialog.showMessageBox failed: ${e.message}`);
491
+ return;
492
+ }
493
+
494
+ if (result.response === 0) {
495
+ logger.log(`User accepted install prompt — installing v${version}.`);
496
+ autoUpdater.installNow();
497
+ } else {
498
+ logger.log(`User dismissed install prompt for v${version} — watcher continues.`);
499
+ // Bump activity so we don't re-prompt within the same tick window.
500
+ autoUpdater.markActive();
501
+ }
502
+ },
503
+
504
+ // Wire main-process activity hooks. Idempotent — only runs once per process.
505
+ // Renderer-side activity arrives via the 'desktop:auto-updater:activity' IPC listener
506
+ // wired in initialize() (mouse/keyboard/wheel/touch/focus debounced in preload).
507
+ // This method covers main-process signals that don't go through the renderer:
508
+ // - browser-window-focus: user alt-tabbed back, clicked a window from elsewhere,
509
+ // or surfaced the app via tray click / dock click — any path that gives the
510
+ // window focus fires this. Tray/menu clicks that show/focus a window are also
511
+ // covered by this transitively.
512
+ // Deep-link arrivals are a softer signal (the user might have clicked a link in a
513
+ // browser hours ago and walked away) — we deliberately don't bump activity from
514
+ // them. If a consumer wants to count something specific, they can call markActive().
515
+ _wireActivityHooks() {
516
+ if (autoUpdater._activityHooksWired) return;
517
+ autoUpdater._activityHooksWired = true;
518
+
519
+ const { app } = require('electron');
520
+ app.on('browser-window-focus', () => autoUpdater.markActive());
521
+ },
522
+
523
+ _broadcastStatus() {
524
+ const m = autoUpdater._manager;
525
+ if (m && m.ipc && typeof m.ipc.broadcast === 'function') {
526
+ m.ipc.broadcast('desktop:auto-updater:status', autoUpdater.getStatus());
527
+ }
528
+ autoUpdater._updateMenuItem();
529
+ autoUpdater._updateTrayItem();
530
+ logger.log(`status → ${autoUpdater._state.code}${autoUpdater._state.version ? ` v${autoUpdater._state.version}` : ''}${autoUpdater._state.percent ? ` (${autoUpdater._state.percent}%)` : ''}`);
531
+ },
532
+
533
+ // Compute the label + enabled fields for any "check for updates" UI item from current state.
534
+ // Used by both the menu and tray patchers so they stay in lockstep.
535
+ _menuItemFieldsForState() {
536
+ const s = autoUpdater._state;
537
+ let label, enabled = true;
538
+ switch (s.code) {
539
+ case 'checking': label = 'Checking for Updates...'; enabled = false; break;
540
+ case 'available': label = `Downloading Update v${s.version || ''}...`; enabled = false; break;
541
+ case 'downloading': label = `Downloading Update (${Math.round(s.percent)}%)`; enabled = false; break;
542
+ case 'downloaded': label = `Restart to Update v${s.version || ''}`; enabled = true; break;
543
+ case 'not-available': label = 'You\'re up to date'; enabled = true; break;
544
+ case 'error': label = 'Check for Updates...'; enabled = true; break;
545
+ case 'idle':
546
+ default: label = 'Check for Updates...'; enabled = true; break;
547
+ }
548
+ return { label, enabled };
549
+ },
550
+
551
+ // Reflect updater state into the @omega.js/desktop Check-for-Updates item. The item lives under
552
+ // `main/check-for-updates` on macOS (App menu) and `help/check-for-updates` on win/linux —
553
+ // we just patch whichever one exists. Consumer can remove either via
554
+ // manager.menu.remove('main/check-for-updates') in their integrations/menu/index.js.
555
+ _updateMenuItem() {
556
+ const m = autoUpdater._manager;
557
+ const { label, enabled } = autoUpdater._menuItemFieldsForState();
558
+
559
+ // Patch whichever id-path exists. .update() returns false (and warns) if missing,
560
+ // so try both without doubling up on warnings — silence by checking has() first.
561
+ if (m.menu.has('main/check-for-updates')) {
562
+ m.menu.update('main/check-for-updates', { label, enabled });
563
+ } else if (m.menu.has('help/check-for-updates')) {
564
+ m.menu.update('help/check-for-updates', { label, enabled });
565
+ }
566
+ },
567
+
568
+ // Reflect updater state into the tray's `check-for-updates` item, if present. Same
569
+ // label/enabled semantics as the menu item — keeps both UIs in lockstep.
570
+ _updateTrayItem() {
571
+ const m = autoUpdater._manager;
572
+ const { label, enabled } = autoUpdater._menuItemFieldsForState();
573
+
574
+ if (m.tray.has('check-for-updates')) {
575
+ m.tray.update('check-for-updates', { label, enabled });
576
+ }
577
+ },
578
+
579
+ // 30-day gate ────────────────────────────────────────────────────────────────────
580
+
581
+ _reconcilePendingUpdate() {
582
+ const m = autoUpdater._manager;
583
+ const pending = m.storage.get(`${STORAGE_KEY}.pendingUpdate`);
584
+ if (!pending || !pending.downloadedAt) return;
585
+
586
+ // A simulated record (written by a build from before the simulator stopped
587
+ // touching this key) can never be applied — nothing ships at the sentinel
588
+ // version, so the clear-on-apply check below would never match it. Discard
589
+ // it here, or its fake timestamp gets restored into _state.downloadedAt and
590
+ // force-installs the first REAL download the moment it lands.
591
+ if (pending.version === SIMULATED_VERSION) {
592
+ logger.log(`Discarding simulated pendingUpdate record (v${pending.version}) — the dev simulator never downloaded anything.`);
593
+ m.storage.set(`${STORAGE_KEY}.pendingUpdate`, null);
594
+ return;
595
+ }
596
+
597
+ const currentVersion = autoUpdater._manager.getVersion();
598
+ if (pending.version === currentVersion) {
599
+ logger.log(`Pending update v${pending.version} appears to be applied — clearing flag.`);
600
+ m.storage.set(`${STORAGE_KEY}.pendingUpdate`, null);
601
+ return;
602
+ }
603
+
604
+ autoUpdater._state.downloadedAt = pending.downloadedAt;
605
+ autoUpdater._state.version = pending.version;
606
+ logger.log(`Pending update v${pending.version} carried from prior session (downloadedAt=${new Date(pending.downloadedAt).toISOString()})`);
607
+ // The gate can't install HERE — electron-updater has no download this
608
+ // session (installNow() requires state 'downloaded'). The startup check
609
+ // (startupDelayMs) re-downloads; update-downloaded then enforces the gate
610
+ // against the restored original downloadedAt.
611
+ },
612
+
613
+ _recordDownloadedAt(version) {
614
+ // The simulator's download is fake, so its record must never reach the
615
+ // production key: a fake timestamp there outlives the QA session and seeds
616
+ // the first-download-wins timer for the next REAL download (a fake record
617
+ // older than maxAgeMs force-installs it on arrival). The in-memory stamp
618
+ // still happens, so the in-session UI flow reads exactly like a real one.
619
+ if (autoUpdater._isSimulating()) {
620
+ autoUpdater._state.downloadedAt = Date.now();
621
+ logger.log(`Dev simulation — skipping the pendingUpdate write for v${version}.`);
622
+ return;
623
+ }
624
+
625
+ const m = autoUpdater._manager;
626
+ if (!m || !m.storage) return;
627
+
628
+ const existing = m.storage.get(`${STORAGE_KEY}.pendingUpdate`);
629
+ // FIRST download wins for the TIMER — but the stored version must track the
630
+ // NEWEST download, or the clear-on-apply check (version === getVersion())
631
+ // never matches after the install and the stale flag force-installs every
632
+ // future download instantly, forever.
633
+ if (existing && existing.downloadedAt) {
634
+ logger.log(`pendingUpdate already recorded (v${existing.version} @ ${new Date(existing.downloadedAt).toISOString()}) — keeping existing timestamp.`);
635
+ if (existing.version !== version) {
636
+ m.storage.set(`${STORAGE_KEY}.pendingUpdate`, { version, downloadedAt: existing.downloadedAt });
637
+ }
638
+ autoUpdater._state.downloadedAt = existing.downloadedAt;
639
+ return;
640
+ }
641
+ const now = Date.now();
642
+ m.storage.set(`${STORAGE_KEY}.pendingUpdate`, { version, downloadedAt: now });
643
+ autoUpdater._state.downloadedAt = now;
644
+ logger.log(`Recorded pendingUpdate v${version} @ ${new Date(now).toISOString()}`);
645
+ },
646
+
647
+ _enforceMaxAgeGate() {
648
+ const downloadedAt = autoUpdater._state.downloadedAt;
649
+ if (!downloadedAt) return false;
650
+
651
+ const age = Date.now() - downloadedAt;
652
+ const max = autoUpdater._options.maxAgeMs;
653
+ if (age < max) return false;
654
+
655
+ logger.warn(`Pending update is ${Math.round(age / 86400000)}d old (>= ${Math.round(max / 86400000)}d) — forcing install.`);
656
+ autoUpdater.installNow();
657
+ return true;
658
+ },
659
+
660
+ // electron-updater wiring ────────────────────────────────────────────────────────
661
+
662
+ _wireElectronUpdater() {
663
+ let lib;
664
+ try {
665
+ lib = require('electron-updater').autoUpdater;
666
+ } catch (e) {
667
+ logger.warn(`electron-updater not available: ${e.message}`);
668
+ return;
669
+ }
670
+ autoUpdater._library = lib;
671
+ lib.autoDownload = autoUpdater._options.autoDownload !== false;
672
+
673
+ lib.on('checking-for-update', () => autoUpdater._setState({ code: 'checking', error: null }));
674
+ lib.on('update-available', (info) => autoUpdater._setState({ code: 'available', version: info?.version, error: null }));
675
+ lib.on('update-not-available', (info) => autoUpdater._setState({ code: 'not-available', version: info?.version, error: null }));
676
+ lib.on('download-progress', (p) => {
677
+ const percent = Math.min(100, parseFloat(((p && p.percent) || 0).toFixed(2)) || 0);
678
+ autoUpdater._setState({ code: 'downloading', percent });
679
+ });
680
+ lib.on('update-downloaded', (info) => {
681
+ autoUpdater._recordDownloadedAt(info?.version);
682
+ autoUpdater._setState({ code: 'downloaded', version: info?.version, percent: 100, error: null });
683
+ // A pending update carried from a prior session keeps its ORIGINAL
684
+ // downloadedAt (first-download-wins), so the 30-day gate can trip the
685
+ // moment the startup re-download lands — installNow() only works from
686
+ // the 'downloaded' state, which exists from this line on.
687
+ autoUpdater._enforceMaxAgeGate();
688
+ });
689
+ lib.on('error', (e) => {
690
+ const err = (e instanceof Error) ? e : new Error(String(e || 'Unknown auto-update error'));
691
+ autoUpdater._setState({ code: 'error', error: { message: err.message } });
692
+ });
693
+ },
694
+
695
+ // Dev simulation ─────────────────────────────────────────────────────────────────
696
+
697
+ _wireDevSimulator() {
698
+ autoUpdater._library = {
699
+ checkForUpdates: async (scenario) => autoUpdater._runDevSimulation(scenario),
700
+ quitAndInstall: () => logger.log('Dev simulator: quitAndInstall() called (no-op in dev).'),
701
+ autoDownload: autoUpdater._options.autoDownload !== false,
702
+ on: () => {},
703
+ };
704
+ },
705
+
706
+ // `scenario` is the per-call override simulate() passes. The boot-time path (checkNow
707
+ // while _isSimulating()) passes nothing and falls back to the OMEGA_DEV_UPDATE value
708
+ // that put the updater in simulation mode to begin with, so that path is unchanged.
709
+ _runDevSimulation(scenario) {
710
+ if (autoUpdater._devSimulating) return;
711
+ autoUpdater._devSimulating = true;
712
+
713
+ const name = (scenario || process.env.OMEGA_DEV_UPDATE || 'available').toLowerCase();
714
+ const NEW_VERSION = SIMULATED_VERSION;
715
+
716
+ autoUpdater._setState({ code: 'checking' });
717
+
718
+ setTimeout(() => {
719
+ if (name === 'unavailable') {
720
+ autoUpdater._setState({ code: 'not-available', version: NEW_VERSION });
721
+ autoUpdater._devSimulating = false;
722
+ return;
723
+ }
724
+ if (name === 'error') {
725
+ autoUpdater._setState({ code: 'error', error: { message: 'Simulated dev-update error' } });
726
+ autoUpdater._devSimulating = false;
727
+ return;
728
+ }
729
+
730
+ // 'available' → cascade through download progress → downloaded.
731
+ autoUpdater._setState({ code: 'available', version: NEW_VERSION });
732
+
733
+ let percent = 0;
734
+ const tick = () => {
735
+ percent = Math.min(100, percent + 25);
736
+ autoUpdater._setState({ code: 'downloading', version: NEW_VERSION, percent });
737
+ if (percent < 100) {
738
+ autoUpdater._pendingTimers.push(setTimeout(tick, 400));
739
+ } else {
740
+ autoUpdater._pendingTimers.push(setTimeout(() => {
741
+ autoUpdater._recordDownloadedAt(NEW_VERSION);
742
+ autoUpdater._setState({ code: 'downloaded', version: NEW_VERSION, percent: 100 });
743
+ autoUpdater._devSimulating = false;
744
+ }, 400));
745
+ }
746
+ };
747
+ autoUpdater._pendingTimers.push(setTimeout(tick, 400));
748
+ }, 400);
749
+ },
750
+ };
751
+
752
+ module.exports = autoUpdater;