@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,357 @@
1
+ # Test Framework
2
+
3
+ Built-in test framework for both @omega.js/desktop itself and consumer projects. Jest-like assertion syntax (`expect(actual).toBe(expected)`), layered runners, @omega.js/backend-style output.
4
+
5
+ ## 🚫 NEVER mock — test against the real harness (HARD RULE)
6
+
7
+ **Do NOT hand-roll fake/stub/mock objects** — no `mockManager`, fake `ipc`/`storage`/`window`/`tray`, stubbed `app`/`BrowserWindow`, or fake IPC channels. Every test gets the **real** framework context:
8
+
9
+ - `build` runs real @omega.js/desktop helper code in plain Node.
10
+ - `main` / `renderer` / `boot` run inside a **real spawned Electron process**, where `ctx.manager` (and boot's `inspect({ manager })`) is the **real booted Manager** — real `manager.storage`, `manager.ipc`, `manager.tray`, `manager.windows`, etc. Use them; exercise the code the way production does.
11
+
12
+ **Pure functions are the ONLY exception.** A function with zero I/O (config-defaults merge, icon-path resolver, schema validator, CLI alias resolver, a string/number transform) can be `require()`d and called directly with plain inputs — that's not mocking, there's nothing to mock. The moment a function touches `app.*` / `BrowserWindow` / `ipcMain` / `Tray` / the real bundle / an external service, it MUST run against the real harness in the appropriate layer (`main` / `renderer` / `boot`), not a stub.
13
+
14
+ **Real external APIs are gated behind extended mode (`TEST_EXTENDED_MODE`), NOT mocked** (see [Extended vs normal mode](#extended-vs-normal-mode) below). Normal mode skips them *in the source*; extended mode runs them for real. The test never fakes them. **Anything an extended test creates in a real external system MUST be cleaned up** by the test (via the suite's `cleanup(ctx)` hook) — external systems are not reset between runs.
15
+
16
+ If you find yourself writing `const mockX = {...}` to satisfy code under test, STOP — pass the real `ctx.manager` (or its real sub-object), or, if the function is genuinely pure, call it directly with plain data.
17
+
18
+ ### The ONLY two exceptions where a narrow stub is allowed
19
+
20
+ Mock **nothing** by default. There are exactly two cases where the real dependency genuinely cannot run in the test environment — and even then, stub the *smallest possible seam* (one method / one object), restore it immediately, and comment *why*:
21
+
22
+ 1. **A side effect that would destroy the test run itself.** If the real call would kill or corrupt the harness — `app.quit()`, a process-exit, `autoUpdater.quitAndInstall()`, a destructive wipe — stub *that one call* to a no-op, assert the surrounding decision logic (e.g. that `_allowQuit` was set first), then restore. You are preventing the harness from terminating mid-assertion, not faking behavior. (Examples: `window-manager.test.js` stubs `app.quit`; `auto-updater.test.js` stubs `installNow`/`_promptToInstall`.)
23
+ 2. **A real dependency the test environment can't provide.** When the real object only exists from infra you can't stand up in a unit test (e.g. a live `webContents` from a not-yet-created window, a second running app instance), a unit test may hand a minimal stub to verify a *narrow side effect* (e.g. that `attach()` registers the right listener). Prefer obtaining the real object from the harness if you can; only stub when you genuinely can't.
24
+
25
+ If you can run it for real, you must. These exceptions are not a license to unit-test in isolation when a real-harness layer (`main`/`renderer`/`boot`) would work.
26
+
27
+ ## Test coverage — every surface gets a test (HARD RULE)
28
+
29
+ A feature is not done when it works — it's done when every surface it exposes is covered in the layer that owns that surface:
30
+
31
+ | Coverage | Layer | Proves |
32
+ |---|---|---|
33
+ | **Logic** | `build` / `main` | The feature's functions do the right thing when called directly (real Manager, real storage, real IPC) |
34
+ | **UI** | `renderer` | The feature's interface is WIRED — a real event on the real DOM triggers the behavior and the visible result appears |
35
+ | **End-to-end** | `boot` | The feature survives in the consumer's actual built bundle (extend the boot suite's `inspect` assertions) |
36
+
37
+ **Skipping a layer is the exception, not the default.** A layer may be skipped ONLY when the feature genuinely has no surface there — a pure build-time utility has no UI; a CSS-only tweak has no logic to call. Convenience is never a reason: "the logic test already covers it" does NOT excuse the UI test — logic tests prove the logic, UI tests prove the wiring (a button can come unhooked while every logic test stays green), boot tests prove the packaging. When in doubt, write the test.
38
+
39
+ ## Running tests
40
+
41
+ ```bash
42
+ npx omega test # consumer: runs YOUR project suites (bare runs never include the framework corpus)
43
+ npx omega test --layer=main # only main-process suites (also: build, renderer, all)
44
+ npx omega test --filter="storage" # only suites/tests whose name contains "storage"
45
+ npx omega test --extended # opt into extended mode — real external APIs (also: TEST_EXTENDED_MODE=true)
46
+ npx omega test --reporter=json # pretty output + machine-readable {"event":"summary",...} line
47
+ OMEGA_TEST_DEBUG=1 npx omega test # see Electron stderr (otherwise drained silently)
48
+ ```
49
+
50
+ In @omega.js/desktop itself, `npm test` runs the framework's own suite — the self-test context flips the no-target default.
51
+
52
+ ### Filtering tests
53
+
54
+ Pass a path (relative to `test/`) as a positional **target** to select which test FILES run:
55
+
56
+ ```bash
57
+ # Run project test files under a path (a bare path binds to the PROJECT source)
58
+ npx omega test build/config
59
+
60
+ # Run BOTH sources — reaching the framework suite is always an explicit choice
61
+ npx omega test full:
62
+ npx omega test full:build/config
63
+
64
+ # Run ONLY consumer project tests (no framework suites at all)
65
+ npx omega test project:
66
+
67
+ # Run a single project test file
68
+ npx omega test project:main/tab-manager
69
+
70
+ # Run ONLY framework tests (universal cross-framework alias)
71
+ npx omega test mgr:
72
+
73
+ # Run ONLY @omega.js/desktop framework tests (desktop-specific aliases, equivalent to mgr:)
74
+ npx omega test desktop:
75
+ npx omega test framework:
76
+
77
+ # Run framework tests matching a path
78
+ npx omega test mgr:build/config
79
+ npx omega test desktop:build/config
80
+
81
+ # Combine with extended mode
82
+ TEST_EXTENDED_MODE=true npx omega test build/config
83
+ ```
84
+
85
+ The target matches against the test file path. The source prefix scopes selection to framework-only or project-only tests — a prefixed target excludes the other source entirely:
86
+
87
+ - `mgr:` — the **universal cross-framework alias** for "the manager's own tests" (framework-only). Works identically in @omega.js/desktop, BXM, UJM, and @omega.js/backend.
88
+ - `desktop:` / `framework:` — desktop-specific aliases for framework-only tests, equivalent to `mgr:`.
89
+ - `project:` — consumer project tests only.
90
+
91
+ A bare prefix (`mgr:` / `desktop:` / `project:` with no path) runs every test in that source. A bare path (no prefix) binds to the PROJECT source; `full:<path>` searches both sources by path.
92
+
93
+ A target that names a path and matches NO file is a hard error: the run prints `No test file matches "<target>"` and exits 1, so a typo'd path, or a suite renamed out from under a target, can never run silently green ([#814](https://github.com/Omega-JS-Stack/omega/issues/814)). A run that named no file (bare, or a bare source prefix) still exits 0 when there is nothing to run. Inside a brand-root fan-out the manager sets `OMEGA_TEST_FANOUT=1` on every forwarded run, and the same miss answers with exit 3 instead: a path another target carries is a no-op here, and the brand run fails only when EVERY target missed ([docs/shared/testing.md](../../../docs/shared/testing.md#brand-root-cp94b)).
94
+
95
+ > **Target vs `--filter`.** The positional target selects test FILES (by path + source). The `--filter=<substring>` flag is orthogonal: it matches test NAMES/descriptions within the selected files. Use them together, e.g. `npx omega test project: --filter="reorder"`.
96
+
97
+ ### Layers
98
+
99
+ - **build** — runs in plain Node. Fast.
100
+ - **main** — spawns Electron and runs inside the main process. Required for anything touching `app`/`ipcMain`/`BrowserWindow`.
101
+ - **renderer** — runs inside a hidden `BrowserWindow` spawned by the main harness. Test functions are serialized + reconstructed via `new Function('ctx', body)`, so they only have access to `ctx` and the page's globals (`window`, `document`, `window.desktop.*`). No closures over module scope.
102
+ - **boot** — rebuilds the project and spawns Electron against the real bundle. The build goes to a staged app root of its own (`<project>/.omega/test-app/`, via `OMEGA_BUILD_OUTPUT`), never the project's `dist/` — so a boot-test run and a live `npm start` watcher never write the same tree. See [test-boot-layer.md](test-boot-layer.md).
103
+ - **all** (default) — build, then main, then renderer in a single Electron boot.
104
+
105
+ ### Extended vs normal mode
106
+
107
+ Suites that hit a live backend (Firebase Auth admin SDK, real GitHub API, etc.) are gated behind **extended mode** — `npx omega test --extended` or `TEST_EXTENDED_MODE=true`. `TEST_EXTENDED_MODE` is the **shared, unprefixed env var across @omega.js/backend, @omega.js/extension, UJM, and @omega.js/desktop** (cross-framework parity) — once set on `process.env` it propagates to every spawned test environment (the Electron main/renderer/boot children, the gulp boot build) automatically via `{ ...process.env }`. These external calls are **skipped in-source, NOT mocked** — the suite short-circuits / `ctx.skip()`s when `TEST_EXTENDED_MODE` is unset; with it set, it calls the real service. Default is to skip them so `npx omega test` is fast + green offline, and a warning prints when extended mode is on. The CI workflow runs normal mode by default; add a separate workflow that sets `TEST_EXTENDED_MODE: 'true'` for extended coverage.
108
+
109
+ Anything an extended suite creates externally must be torn down in its `cleanup(ctx)` — the harness only resets local Electron state between runs, never external systems.
110
+
111
+ ### `OMEGA_TEST_MODE=true` — the canonical "we're in tests" signal
112
+
113
+ Both @omega.js/desktop test runners (`runners/electron.js`, `runners/boot.js`) set `OMEGA_TEST_MODE=true` in the spawned child env. That powers `manager.isTesting()` (and `Manager.isTesting()` static) — the cross-context helper everything in @omega.js/desktop checks when it needs to behave differently in tests:
114
+
115
+ - `auto-updater` flips its idle threshold from 15min → 3s and its periodic tick from 60s → 500ms, AND short-circuits the native install-prompt dialog (so tests don't pop modal windows).
116
+ - **Every BrowserWindow surfaces stealth** — named windows via `window-manager._surface()` AND raw `new BrowserWindow()` ones (e.g. a consumer's automation popup) via a global `browser-window-created` hook registered in `main.js` step 1a-ii. The shared recipe lives in `src/utils/stealth-window.js`: shown INACTIVE (keyboard focus never leaves your editor), opacity 0, click-through (`setIgnoreMouseEvents`), and raw windows get `show()` rerouted to `showInactive()` + `focus()` no-op'd — a test run never interrupts you, and a stray real click physically can't land in the app, while synthetic test input (`executeJavaScript`, `sendInputEvent`, CDP) is unaffected. **`webContents.focus()` is suppressed separately** (a global `web-contents-created` hook in the same main.js block): it bypasses the window-level patches — it's a different object whose `focus()` reaches the native window directly and makes the invisible window KEY, grabbing the keyboard mid-typing even under the accessory policy (which only prevents *launch* activation, not key-window steals). Consumers call it legitimately (e.g. address-bar focus on tab select), so it's no-op'd per-contents under the same predicate. Set **`OMEGA_TEST_SHOW=1`** to surface windows normally and watch a run live (the predicate is evaluated per window, so flipping it mid-run works). Deliberately NOT `hide()`/`minimize()`: occluded windows get throttled by Chromium (`requestAnimationFrame` pauses, `document.visibilityState` flips to `hidden`) — tests would exercise a DIFFERENT runtime, whereas an opacity-0 shown-inactive window renders and behaves identically to a visible one. See [windows.md](windows.md).
117
+ - **App-level activation is suppressed too (macOS).** Launching a regular-policy app activates it — the menu bar and keyboard focus switch to the test process at launch even though every window surfaces inactive. Under the same stealth predicate (`src/utils/test-stealth.js` — Testing mode + `OMEGA_TEST_SHOW` unset), `main.js` (step 1a, before app ready) and the spawned test harness flip the app to the **accessory activation policy** (`app.dock.hide()` — the same switch `LSUIElement` bakes for packaged hidden-mode apps): the process never activates, never shows a dock icon, and never steals focus, while windows still render identically. `OMEGA_TEST_SHOW=1` restores normal activation along with visible windows. Verified by frontmost-app sampling across a full run: zero focus changes (previously four steals per run).
118
+ - `main.js#initialize` isolates userData per environment: testing runs get `<userData> (Testing)` — **wiped at boot**, so every test run starts from a clean slate (post-run state stays on disk for inspection until the next run; set `OMEGA_TEST_KEEP_USERDATA=1` to skip the wipe). Dev runs get ` (Development)`; production is untouched. See [boot-sequence.md](boot-sequence.md).
119
+ - **The main-layer harness exposes a CDP endpoint.** `test/harness/main-entry.js` appends `--remote-debugging-port=0` at require time (loopback-only, OS-assigned port) and publishes the resolved port as **`process.env.OMEGA_CDP_PORT`** before suites run (read from Chromium's `DevToolsActivePort` file; any value inherited from your shell is overwritten — that one points at your dev app, not the harness). Consumer suites can drive real browser automation against the harness Electron itself, e.g. `playwright-core`'s `connectOverCDP('http://127.0.0.1:' + process.env.OMEGA_CDP_PORT)`. Covered by `suites/main/harness-cdp.test.js`.
120
+ - Other lib code can branch on `manager.isTesting()` to suppress dock bounce, login-item changes, OS protocol-handler registration, etc.
121
+
122
+ Consumers writing their own tests should set `OMEGA_TEST_MODE=true` in their test runner so the same signal applies — for example, in `package.json`:
123
+ ```json
124
+ "test": "OMEGA_TEST_MODE=true vitest"
125
+ ```
126
+ Then in your code, gate test-only behavior on `manager.isTesting()` instead of inventing yet another env var.
127
+
128
+ ## Test discovery
129
+
130
+ - **Framework defaults**: `<@omega.js/desktop>/dist/test/suites/**/*.js`
131
+ - **Consumer suites**: `<cwd>/test/**/*.js`
132
+
133
+ **The underscore convention** (`DISCOVERY_IGNORE` in `src/test/runner.js`): `_`-prefixed FILES (`test/_init.js`, `test/main/_helper.js`) and everything under a `_`-prefixed DIRECTORY at **any depth** (`test/_fixtures/**`, `test/boot/_private/**`) are excluded from suite discovery. Put shared helpers, fixture data, and non-test support files in `_`-prefixed paths — e.g. `test/_fixtures/`, `test/_helpers/`. The runner still specifically loads `test/_init.js` as the lifecycle hook. Matches the same convention in @omega.js/backend/BXM/UJM. Files load alphabetically (sorted globally per source).
134
+
135
+ **Framework boot suites are scoped to @omega.js/desktop self-test runs only.** When a consumer runs `npx omega test`, the framework's `dist/test/suites/boot/**` is excluded from discovery — those tests are meant to assert on @omega.js/desktop's own internal fixtures and would fail noisily against a real consumer app. Detection: the runner checks `cwd`'s `package.json#name === '@omega.js/desktop'`. Consumers write their own boot tests under `<cwd>/test/boot/`. Matches the same exclusion pattern in BXM and UJM. See [test-boot-layer.md](test-boot-layer.md).
136
+
137
+ ## `test/_init.js` — pre-test lifecycle hook
138
+
139
+ The runner loads an optional `test/_init.js` from **both** test roots — the framework (`<@omega.js/desktop>/test/_init.js`) and the consumer project (`<cwd>/test/_init.js`) — and runs it **once, before any suite** (it is NOT itself run as a test; the `_`-prefix keeps it out of discovery). Mirrors the same hook in @omega.js/backend/UJM/BXM so all four frameworks share one shape.
140
+
141
+ The module **must export a function** — `module.exports = (ctx) => ({ ... })` — called with `{ projectRoot }` and returning the hook object. It may declare:
142
+
143
+ - `async setup({ projectRoot })` — runs once before the suites, e.g. to scaffold a fixture file the boot layer needs.
144
+
145
+ There is **no `cleanup` hook** and **no `accounts` field** (unlike @omega.js/backend — these frameworks have no auth/user system): tests clean up after themselves, so there is nothing project-level to tear down.
146
+
147
+ ```javascript
148
+ // <cwd>/test/_init.js
149
+ const fs = require('fs');
150
+ const path = require('path');
151
+
152
+ module.exports = ({ projectRoot }) => ({
153
+ async setup() {
154
+ // Seed any fixture a suite needs before it runs.
155
+ fs.mkdirSync(path.join(projectRoot, '.temp'), { recursive: true });
156
+ },
157
+ });
158
+ ```
159
+
160
+ ## Test file shapes
161
+
162
+ Three forms — pick whichever fits.
163
+
164
+ ### Suite (sequential, share state, stop on first failure)
165
+
166
+ ```js
167
+ module.exports = {
168
+ type: 'suite',
169
+ layer: 'main', // 'build' | 'main' | 'renderer'
170
+ description: 'storage (main)',
171
+ cleanup: async (ctx) => { // runs after the last test
172
+ ctx.manager.storage.clear();
173
+ },
174
+ tests: [
175
+ {
176
+ name: 'set + get round-trip',
177
+ run: (ctx) => {
178
+ ctx.manager.storage.set('hello', 'world');
179
+ ctx.expect(ctx.manager.storage.get('hello')).toBe('world');
180
+ },
181
+ },
182
+ {
183
+ name: 'has reflects presence',
184
+ run: (ctx) => { /* ... */ },
185
+ cleanup: (ctx) => { /* ... */ }, // per-test cleanup
186
+ skip: 'reason', // skip this test
187
+ },
188
+ ],
189
+ };
190
+ ```
191
+
192
+ Tests share `ctx.state` across the suite. If one fails, remaining tests are skipped (`stopOnFailure: false` to disable).
193
+
194
+ ### Group (parallel-ish, share state, run all regardless of failures)
195
+
196
+ ```js
197
+ module.exports = {
198
+ type: 'group',
199
+ layer: 'main',
200
+ description: 'boot sequence (main)',
201
+ tests: [ /* same shape as suite */ ],
202
+ };
203
+ ```
204
+
205
+ Same shape as suite, but all tests run even if some fail.
206
+
207
+ ### Standalone (single test per file)
208
+
209
+ ```js
210
+ module.exports = {
211
+ layer: 'build',
212
+ description: 'CLI alias resolves to a command file',
213
+ run: (ctx) => { /* ... */ },
214
+ cleanup: (ctx) => { /* ... */ },
215
+ timeout: 10000,
216
+ skip: false,
217
+ };
218
+ ```
219
+
220
+ ### Array shorthand (group of tests, no metadata)
221
+
222
+ ```js
223
+ module.exports = [
224
+ { name: 'A', run: (ctx) => { /* ... */ } },
225
+ { name: 'B', run: (ctx) => { /* ... */ } },
226
+ ];
227
+ ```
228
+
229
+ ## Layers
230
+
231
+ | Layer | Where it runs | Use for |
232
+ |---|---|---|
233
+ | `build` | Plain Node | CLI, package.json, config schema, gulp tasks |
234
+ | `main` | Spawned Electron main process | Manager init, lib modules, IPC, windows |
235
+ | `renderer` | Hidden BrowserWindow: the framework's harness page by default, one of the project's own `src/views/` when the suite declares `view: '<name>'` | `window.desktop.*`, preload bridge, UI logic, your own views |
236
+
237
+ The runner partitions test files by layer at discovery time. The build layer runs inline; the main layer spawns Electron once with all main suites and parses JSON-line stdout.
238
+
239
+ ## ctx (context object)
240
+
241
+ Every test fn receives a `ctx`:
242
+
243
+ ```js
244
+ ctx.expect(actual) // Jest-compatible expect()
245
+ ctx.state // shared object across tests in a suite/group
246
+ ctx.layer // 'build' | 'main' | 'renderer'
247
+ ctx.skip(reason) // skip from inside the test
248
+ ctx.manager // (main layer only) the booted @omega.js/desktop Manager
249
+ ```
250
+
251
+ ## expect() matchers
252
+
253
+ Jest-compatible subset:
254
+
255
+ ```js
256
+ .toBe(expected) // ===
257
+ .toEqual(expected) // deep equal
258
+ .toBeTruthy() / .toBeFalsy()
259
+ .toBeDefined() / .toBeUndefined() / .toBeNull()
260
+ .toContain(item) // array.includes / string.includes
261
+ .toHaveProperty(key)
262
+ .toMatch(regex)
263
+ .toBeInstanceOf(class)
264
+ .toBeGreaterThan(n) / .toBeLessThan(n)
265
+ .toThrow(regex|string) // also accepts async fns
266
+
267
+ .not.<anything> // negate any matcher
268
+ ```
269
+
270
+ ## Output
271
+
272
+ ```
273
+ OMEGA Desktop Tests
274
+
275
+ Framework Tests
276
+ ⤷ storage (main)
277
+ ✓ set + get round-trip (7ms)
278
+ ✓ has reflects presence (8ms)
279
+ ...
280
+
281
+ Results
282
+ 149 passing
283
+
284
+ Total: 149 tests in 1850ms
285
+ ```
286
+
287
+ All test output is also teed (ANSI-stripped) to `<projectRoot>/logs/test.log`, truncated fresh on each run — same pattern as `dev.log` (and @omega.js/backend's `test.log`). Grep it after a run instead of scrolling terminal output.
288
+
289
+ ## Test harness internals (main layer)
290
+
291
+ - `runners/electron.js` spawns Electron with `harness/main-entry.js` as the app.
292
+ - `harness/main-entry.js` boots Manager with `skipWindowCreation: true`, runs the suites, emits results via `__EM_TEST__{json}\n` lines on stdout.
293
+ - The runner parses those lines and renders @omega.js/backend-style output.
294
+ - stderr is always drained (otherwise the pipe fills and the harness blocks); printed only when `OMEGA_TEST_DEBUG=1`.
295
+ - `ELECTRON_RUN_AS_NODE` is stripped from the spawn env (would otherwise make Electron behave as Node and break the harness).
296
+ - **Consumer-scheme containment.** The consumer's `main.js` — where the real `protocol.handle('<brand.id>', …)` lives — never runs in this harness, so `brand://` URLs loaded by main-layer suites would be UNHANDLED. Chromium treats a load on an unhandled scheme as an *external protocol* and hands it to the OS — and if an installed copy of the app owns the scheme (e.g. `/Applications/Brand.app` on macOS, registered via its `Info.plist`), Launch Services launches the installed production app mid-test-run. The harness contains this two ways after Manager boots: (1) it registers a stub handler for the consumer's brand scheme (read from `<cwd>/config/omega.json5`) on the default session, so `brand://` loads commit in-process as a blank page; (2) it denies the `openExternal` permission on the default session and every session created after it (partitions included), so no navigation can hand ANY scheme to the OS during a test run. Suites that need real page content for `brand://` URLs belong in the boot layer, where the real app (and its real protocol handler) runs. A main-layer suite that genuinely needs its OWN handler for the brand scheme must call `protocol.unhandle(brand.id)` first — the harness stub holds the scheme on the default session.
297
+
298
+ ## Writing consumer tests
299
+
300
+ In a consumer project, drop files in `test/` (or `test/**`):
301
+
302
+ ```js
303
+ // test/login-flow.test.js
304
+ module.exports = {
305
+ type: 'suite',
306
+ layer: 'main',
307
+ description: 'login flow',
308
+ tests: [
309
+ {
310
+ name: 'storage starts empty',
311
+ run: (ctx) => {
312
+ ctx.expect(ctx.manager.storage.get('user')).toBeUndefined();
313
+ },
314
+ },
315
+ ],
316
+ };
317
+ ```
318
+
319
+ `npx omega test` runs your project suites; scope `framework:` or `full:` to reach the framework's own.
320
+
321
+ ### Testing your own views
322
+
323
+ A `renderer` suite that declares **`view: '<name>'`** runs against `src/views/<name>/` of YOUR app instead of the framework's harness page:
324
+
325
+ ```js
326
+ // test/renderer/main-view.test.js
327
+ module.exports = {
328
+ type: 'group',
329
+ layer: 'renderer',
330
+ view: 'main', // <- src/views/main/, as built
331
+ description: 'the main view',
332
+ tests: [
333
+ {
334
+ name: 'the heading renders the product name',
335
+ run: (ctx) => {
336
+ ctx.expect(document.querySelector('h1').textContent.trim()).toBe('My App');
337
+ },
338
+ },
339
+ {
340
+ name: 'the preload reached the page',
341
+ run: (ctx) => {
342
+ ctx.expect(typeof window.desktop).toBe('object');
343
+ },
344
+ },
345
+ ],
346
+ };
347
+ ```
348
+
349
+ Such a suite rides the **boot lane**, because only that lane stages and builds the real app (`<project>/.omega/test-app/`) before running: the page gets the project's real `dist/preload.bundle.js`, the real IPC handlers of the booted main process, and the real config. The window is created through the app's own window manager (hidden, no bounds persistence) and destroyed when the suite ends. Cost is the boot lane's: one build (~10-30s) shared with your boot tests.
350
+
351
+ Consequences worth knowing:
352
+
353
+ - **`--layer=renderer` does NOT run a view suite** (it needs the boot). `--layer=boot` and the default `--layer=all` do.
354
+ - The test bodies still run as `new Function` inside the page: no closures over module scope, only `ctx` (`expect`, `state`, `layer`, `skip`) and the page globals (`window`, `document`, `window.desktop.*`).
355
+ - Without `view`, nothing changes: the suite runs on the harness page in the main test Electron, as it always has.
356
+ - A view that fails to load fails every test of the suite with `view "<name>" did not load`, rather than reporting an empty page.
357
+ - Each view suite has a hard 60 s ceiling for the whole suite (the same ceiling the harness page uses); a suite's own `timeout` applies per test underneath it.
package/docs/themes.md ADDED
@@ -0,0 +1,135 @@
1
+ # Themes
2
+
3
+ @omega.js/desktop ships the **classy** theme (built on Bootstrap 5) so consumer apps look polished out of the box. Variables are fully customizable via `@use 'omega-desktop' as * with (...)` — same pattern as UJM and BXM.
4
+
5
+ ## How it works
6
+
7
+ @omega.js/desktop carries @omega.js/web's FULL theme tree in `<em>/dist/assets/themes/` — vendored from the resolved `@omega.js/web` devDependency at every prepare via the declared-assets channel (C4 cp104/cp109), never hand-copied:
8
+
9
+ | Theme | Base | Use case |
10
+ |---|---|---|
11
+ | `classy` (default) | Bootstrap 5.3 + OMEGA design system | Polished, modern app shell |
12
+ | `bootstrap` | Plain Bootstrap 5.3 | Minimal, vanilla Bootstrap |
13
+ | `neobrutalism` / `newsflash` | Bootstrap 5.3 | Alternate skins (universal `theme.id`) |
14
+
15
+ The active theme is selected via `config.theme.id` (default `'classy'`). The `gulp/sass` task adds `<em>/dist/assets/themes/<theme>` to its sass `loadPaths` so the bare `@use 'theme'` import inside `@omega.js/desktop.scss` resolves to the active theme.
16
+
17
+ ## Consumer setup
18
+
19
+ Your `src/assets/scss/main.scss` becomes:
20
+
21
+ ```scss
22
+ @use 'omega-desktop' as * with (
23
+ $primary: #2563EB,
24
+ // $secondary: #6C757D,
25
+ // $border-radius: 0.5rem,
26
+ );
27
+
28
+ // Custom global styles below...
29
+ main {
30
+ padding: 2rem;
31
+ }
32
+ ```
33
+
34
+ That single import gives you:
35
+ - Full Bootstrap 5 (utilities, components, grid, etc.)
36
+ - Classy theme overlays (typography, animations, refined spacing)
37
+ - @omega.js/desktop's `_initialize.scss` (desktop-specific defaults — full-window body, app-region drag classes)
38
+
39
+ ## Per-page CSS
40
+
41
+ @omega.js/desktop compiles per-page bundles in addition to the shared `main.bundle.css`:
42
+
43
+ ```
44
+ src/assets/scss/main.scss → dist/assets/css/main.bundle.css (every page)
45
+ src/assets/scss/pages/main.scss → dist/assets/css/components/main.bundle.css (main window only)
46
+ src/assets/scss/pages/settings.scss → dist/assets/css/components/settings.bundle.css (settings window only)
47
+ src/assets/scss/pages/about.scss → dist/assets/css/components/about.bundle.css (about window only)
48
+ ```
49
+
50
+ The page template auto-loads both: `main.bundle.css` is on every HTML page, and `components/<page.name>.bundle.css` is loaded only on its specific page. To add styles for a new page, drop a new file at `src/assets/scss/pages/<view>.scss` — it'll auto-compile and auto-inject.
51
+
52
+ Per-page bundles can themselves `@use 'omega-desktop' as *;` if they need access to theme variables. Just be aware this means re-emitting some shared CSS — for very small per-page tweaks, prefer plain selectors that ride on the shared `main.bundle.css`.
53
+
54
+ ## Customizable variables
55
+
56
+ The full classy variable list lives at `<em>/dist/assets/themes/classy/_config.scss`. ~60 variables you can override via the `@use ... with ()` form:
57
+
58
+ **Colors:** `$primary`, `$secondary`, `$success`, `$info`, `$warning`, `$danger`, `$light`, `$dark`
59
+ **Backgrounds (light mode):** `$classy-bg-light`, `$classy-bg-light-secondary`, `$classy-bg-light-tertiary`
60
+ **Backgrounds (dark mode):** `$classy-bg-dark`, `$classy-bg-dark-secondary`, `$classy-bg-dark-tertiary`
61
+ **Typography:** `$font-family-sans-serif`, `$font-family-base`, `$headings-font-weight`, `$classy-font-mono`, `$classy-font-accent`
62
+ **Border radius:** `$border-radius`, `$border-radius-sm/lg/xl/2xl/pill`
63
+ **Spacing, transitions, shadows** — see `_config.scss`
64
+
65
+ ## Switching themes
66
+
67
+ Set `config.theme.id` in `config/omega.json5`:
68
+
69
+ ```jsonc
70
+ theme: {
71
+ id: 'bootstrap', // 'classy' (default) | 'bootstrap'
72
+ appearance: 'system', // 'system' (default) | 'light' | 'dark'
73
+ }
74
+ ```
75
+
76
+ ## Appearance (light / dark / system) — `manager.theme`
77
+
78
+ @omega.js/desktop owns appearance at runtime. `config.theme.appearance` is only the **app default**; the resolved appearance is applied and kept live by the theme lib:
79
+
80
+ - **`'system'` (default)** follows the OS preference **live** — when the OS flips, every page updates without a reload or restart.
81
+ - **`'light'` / `'dark'`** are explicit overrides.
82
+ - A user's runtime choice (`manager.theme.set(...)`) is **persisted in `manager.storage`** (`theme.appearance`) and wins over the config default on every boot.
83
+
84
+ ### How it propagates
85
+
86
+ Everything rides on Electron's `nativeTheme.themeSource` (same three values). Setting it flips `prefers-color-scheme` in **every renderer of the app — BrowserWindows AND embedded WebContentsViews** — and @omega.js/desktop's preload applier listens via `matchMedia` and rewrites `<html data-bs-theme>` to the **resolved** value (`'light'`/`'dark'`) live. No IPC fan-out, no per-window wiring; native UI (menus, dialogs) follows too.
87
+
88
+ The applier is **opt-in by presence**: it only manages pages whose `<html>` already carries `data-bs-theme` (stamped by the page template at build). External sites loaded in a consumer's embedded web views get the same preload but are never touched.
89
+
90
+ ### API
91
+
92
+ ```js
93
+ // Main
94
+ manager.theme.get(); // 'system' | 'light' | 'dark' (the chosen source)
95
+ manager.theme.resolved(); // 'light' | 'dark' (what's showing)
96
+ manager.theme.set('dark'); // apply + persist (throws on invalid values)
97
+ const unsub = manager.theme.onChange(({ source, resolved }) => { ... });
98
+
99
+ // Renderer (any page with the @omega.js/desktop preload)
100
+ await window.desktop.theme.get(); // { source, resolved }
101
+ await window.desktop.theme.set('dark'); // → { source, resolved }
102
+ const unsub = window.desktop.theme.onChange(({ resolved }) => { ... }); // matchMedia-powered
103
+ ```
104
+
105
+ Main also broadcasts `desktop:theme:changed { source, resolved }` to BrowserWindows as a courtesy — but renderers should rely on `onChange`/matchMedia, which works in every context.
106
+
107
+ ### Declarative controls
108
+
109
+ Any element with `data-omega-theme-set` becomes a theme switch (wired by the renderer Manager's initialize — event-delegated, so late-rendered controls work):
110
+
111
+ ```html
112
+ <button data-omega-theme-set="light">Day</button>
113
+ <button data-omega-theme-set="dark">Dusk</button>
114
+ <button data-omega-theme-set="system">Auto</button>
115
+ ```
116
+
117
+ ### Build-time stamp
118
+
119
+ `data-bs-theme="{{ theme.appearance }}"` is still stamped into every page at build. For `'light'`/`'dark'` the stamp is already correct; `'system'` stamps an inert value that the preload applier replaces with the resolved appearance at `DOMContentLoaded` (Bootstrap treats unknown values as light for the instant before that).
120
+
121
+ ## Where the themes live
122
+
123
+ The SSOT is **`@omega.js/web/themes/`** — one theme tree for web, desktop, and extension (C4 cp109: the classy triplication is dead). @omega.js/desktop declares `omega.vendorAssets` in its package.json, and every `prepare-package` run copies the resolved web package's `themes/` into `<em>/dist/assets/themes/`. Consumers import via the sass `loadPaths` mechanism — **nothing is ever copied into the consumer's tree**. Desktop-specific theme bits (the `.omega-titlebar` component, the `$min-contrast-ratio` knob) were upstreamed INTO the shared classy rather than kept as a fork.
124
+
125
+ ## Updating themes
126
+
127
+ A theme change lands once in `packages/web/themes/` and rides into desktop + extension on their next prepare. There is no sync step and no version skew — dist is rebuilt from the resolved web package every time. (A standalone `@omega.js/themes` package was considered and rejected for now: the vendor channel gives one-source semantics without another publishable surface.)
128
+
129
+ ## Gotchas
130
+
131
+ ### Sass `@import` deprecation warnings
132
+ Classy's `_theme.scss` uses `@import` (Sass's legacy module system) for its own internal layout. You'll see a deprecation warning during compile. UJM has the same warning. Functional today; will be migrated when classy upgrades to fully-modular `@use`/`@forward`.
133
+
134
+ ### Per-page CSS bundles are 0 bytes by default
135
+ Empty `pages/<name>.scss` produces empty bundles. That's fine — the page template still loads them, the browser just gets a 200 with no rules. Adding any selector populates it.
@@ -0,0 +1,99 @@
1
+ # Bootstrap JS & Tooltips
2
+
3
+ @omega.js/desktop ships **Bootstrap's JavaScript** (v5.3, Popper inlined) as a prebuilt bundle
4
+ — `assets/js/bootstrap.bundle.js` — loaded by the renderer
5
+ bootstrap. Consumers add **zero setup** and never vendor Bootstrap JS
6
+ themselves.
7
+
8
+ ## Tooltips (auto-initialized)
9
+
10
+ Bootstrap makes tooltips opt-in (they need a JS instance per element); @omega.js/desktop does
11
+ the opt-in for you. Any element carrying the standard Bootstrap markup gets a
12
+ live tooltip:
13
+
14
+ ```html
15
+ <button class="btn btn-primary" data-bs-toggle="tooltip" data-bs-title="Saves and continues">
16
+ Save
17
+ </button>
18
+ ```
19
+
20
+ The renderer bootstrap (`renderer.js _wireTooltips`) initializes every
21
+ `[data-bs-toggle="tooltip"]` present at init and watches the DOM:
22
+
23
+ - elements **inserted later** get their tooltip on arrival,
24
+ - **`data-bs-title` / `title` changes** update the live instance in place
25
+ (emptying the title disposes it — no tooltip is a valid state),
26
+ - **removed elements** have their instance disposed — no orphaned tips.
27
+
28
+ Plain-`title` hosts work: Bootstrap's constructor MOVES `title` into
29
+ `data-bs-original-title`, and the observer reads that bookkeeping as a live
30
+ title source. (It must — reading only `title`/`data-bs-title` made the
31
+ observer dispose the instance, dispose restored `title`, re-init removed it
32
+ again: an infinite MutationObserver microtask loop that froze the whole
33
+ renderer. Found by Somiibo's session-limits boot suite; regression-tested in
34
+ the tooltips suite.) One knock-on: a title-only host can't be disposed by
35
+ emptying its title — remove `data-bs-toggle` instead (prefer `data-bs-title`
36
+ for dynamic tooltips).
37
+
38
+ All the standard Bootstrap `data-bs-*` options work (`data-bs-placement`,
39
+ `data-bs-delay`, …).
40
+
41
+ ### Disabled controls
42
+
43
+ Bootstrap's own caveat: disabled elements don't fire hover events. Wrap the
44
+ control and put the tooltip on the wrapper:
45
+
46
+ ```html
47
+ <span data-bs-toggle="tooltip" data-bs-title="Requires the Pro plan">
48
+ <button class="btn btn-primary" disabled>Bulk import</button>
49
+ </span>
50
+ ```
51
+
52
+ ## The rest of Bootstrap's JS
53
+
54
+ The full namespace is exposed at **`window.bootstrap`** (and
55
+ `manager.bootstrap`) — `Tooltip`, `Popover`, `Collapse`, `Dropdown`, `Modal`,
56
+ `Offcanvas`, `Tab`, `Toast`, `Alert`, `Button`, `Carousel`, `ScrollSpy`. Only
57
+ tooltips are auto-initialized; the other components' standard **data-api**
58
+ works out of the box on plain Bootstrap markup (e.g.
59
+ `data-bs-toggle="collapse"`), and everything is available for manual control:
60
+
61
+ ```js
62
+ const collapse = window.bootstrap.Collapse.getOrCreateInstance(el);
63
+ collapse.show();
64
+ ```
65
+
66
+ ## Rebuilding the bundle
67
+
68
+ `assets/js/bootstrap.bundle.js` is a COMMITTED prebuilt artifact — no gulp task
69
+ rebuilds it, so a normal build never regenerates it. The checked-in bytes are a
70
+ legacy webpack UMD build, from before [#737](https://github.com/Omega-JS-Stack/omega/issues/737)
71
+ took webpack out of desktop.
72
+
73
+ Rebuild only when the vendored Bootstrap source is upgraded, with esbuild — the
74
+ one bundler desktop still has. The input is @omega.js/desktop's vendored
75
+ Bootstrap 5.3 source (the vendored themes tree) plus `@popperjs/core` (an
76
+ @omega.js/desktop dependency), and the output has to keep the contract its two
77
+ consumers rely on: `require()` hands back the Bootstrap namespace
78
+ (`renderer.js` reads `.Tooltip` off it and assigns `window.bootstrap` itself),
79
+ so the format is CommonJS:
80
+
81
+ ```bash
82
+ esbuild bootstrap.js --bundle --minify --format=cjs \
83
+ --outfile=src/assets/js/bootstrap.bundle.js
84
+ ```
85
+
86
+ Use `--format=iife --global-name=bootstrap` only if the bundle is ever loaded by
87
+ a plain `<script>` tag instead — nothing does that today.
88
+
89
+ Note: the bundle reads `document.documentElement` at import time — the renderer
90
+ bootstrap defers loading it until the document exists (relevant when wiring
91
+ runs from a preload, e.g. the test harness).
92
+
93
+ ## Testing
94
+
95
+ - `src/test/suites/renderer/tooltips.test.js` — bundle loads, auto-init on
96
+ insertion, live retitle, dispose-on-removal, tip cleanup. (The harness wires
97
+ the renderer Manager in the preload world — see the suite header for the
98
+ world-split notes; single-world hover behavior is covered by consumer boot
99
+ suites.)