@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,112 @@
1
+ # Context Menu (Right-Click)
2
+
3
+ File-based context menu. Unlike tray and application menu (called once at boot), the context-menu definition is called **every time the user right-clicks** — so it gets fresh `params` each time and can vary the menu by selection.
4
+
5
+ ## Config
6
+
7
+ No config block. Path is conventional: `src/integrations/context-menu/index.js`. To opt out, call `manager.contextMenu.disable()` from your main entry — after that, right-click events are silently swallowed.
8
+
9
+ ## Definition file
10
+
11
+ ```js
12
+ // src/integrations/context-menu/index.js
13
+ module.exports = ({ manager, menu, params, webContents }) => {
14
+ // Easiest: start from @omega.js/desktop's defaults, then customize per event.
15
+ menu.useDefaults();
16
+
17
+ // Add a "Search Google" entry when text is selected:
18
+ if (params.selectionText) {
19
+ menu.insertAfter('copy', {
20
+ id: 'search-google',
21
+ label: `Search "${params.selectionText.slice(0, 20)}"`,
22
+ click: () => require('electron').shell.openExternal(
23
+ `https://google.com/search?q=${encodeURIComponent(params.selectionText)}`,
24
+ ),
25
+ });
26
+ }
27
+
28
+ // Hide the dev-tools entries even in development:
29
+ menu.remove('toggle-devtools');
30
+ };
31
+ ```
32
+
33
+ Calling no `menu.*` methods (or `menu.clear()` after `useDefaults()` with nothing added) **suppresses the popup** entirely.
34
+
35
+ ## Builder API (per event)
36
+
37
+ ```js
38
+ menu.item(descriptor)
39
+ menu.separator()
40
+ menu.submenu(label, items)
41
+ menu.useDefaults() // populate with @omega.js/desktop's defaults based on params
42
+ menu.clear() // wipe items added so far this event
43
+ ```
44
+
45
+ ## Id-path API (per event)
46
+
47
+ Same shape across menu / tray / context-menu. Available **inside the definition fn** on the `menu` builder. Operates on the items being built for the current right-click event:
48
+
49
+ ```js
50
+ .find(idPath)
51
+ .has(idPath)
52
+ .update(idPath, patch)
53
+ .remove(idPath)
54
+ .enable(idPath, bool = true)
55
+ .show(idPath, bool = true)
56
+ .hide(idPath)
57
+ .insertBefore(idPath, item)
58
+ .insertAfter(idPath, item)
59
+ .appendTo(idPath, item)
60
+ ```
61
+
62
+ Context-menu ids are **flat** — no `context/` prefix needed (the lib namespace is implicit). Submenus you build with `menu.submenu(...)` are addressable as `parent/child` paths via the resolver.
63
+
64
+ (Runtime-on-`manager.contextMenu` mutators don't apply here — items are rebuilt every event. Mutate inside the definition fn instead.)
65
+
66
+ ## Default template ids
67
+
68
+ @omega.js/desktop's `useDefaults()` populates items based on `params`. Every default item carries an id you can target:
69
+
70
+ | ID | When it appears |
71
+ |---|---|
72
+ | `undo`, `redo` | `params.editFlags.canUndo` / `canRedo` |
73
+ | `cut`, `copy`, `paste`, `paste-and-match-style`, `select-all` | `params.isEditable` |
74
+ | `copy` | `params.selectionText` (read-only) |
75
+ | `open-link`, `copy-link` | `params.linkURL` |
76
+ | `reload` | always |
77
+ | `inspect`, `toggle-devtools` | `manager.isDevelopment()` only |
78
+
79
+ ## Definition fn arguments
80
+
81
+ | Arg | Description |
82
+ |---|---|
83
+ | `manager` | The running @omega.js/desktop Manager |
84
+ | `menu` | Per-event builder + id-path API |
85
+ | `params` | Electron's [`ContextMenuParams`](https://www.electronjs.org/docs/latest/api/web-contents#event-context-menu) — `selectionText`, `isEditable`, `linkURL`, `srcURL`, `mediaType`, `editFlags`, `x`, `y`, etc. |
86
+ | `webContents` | The `webContents` that fired the event |
87
+
88
+ ## Auto-attach
89
+
90
+ Every window created via `manager.windows.createNamed()` is automatically wired up with the context-menu listener. Idempotent per `webContents` (uses a `WeakSet`). For windows you create directly with `new BrowserWindow()`, call:
91
+
92
+ ```js
93
+ manager.contextMenu.attach(win.webContents);
94
+ ```
95
+
96
+ ## Runtime API on `manager.contextMenu`
97
+
98
+ ```js
99
+ manager.contextMenu.define(fn) // replace the definition at runtime
100
+ manager.contextMenu.disable() // ignore future right-click events (idempotent)
101
+ manager.contextMenu.attach(webContents) // manual attach
102
+ manager.contextMenu.buildItems(params, wc) // run the definition without popping a menu (useful for tests)
103
+ manager.contextMenu.hasCustomDefinition() // false → using the built-in default fn
104
+ ```
105
+
106
+ ## Default fn
107
+
108
+ Without a consumer file, @omega.js/desktop uses a built-in fallback that just calls `useDefaults()` — sensible undo/redo/cut/copy/paste/link/reload/inspect baseline. Same behavior as the default scaffold.
109
+
110
+ ## Default scaffold
111
+
112
+ The scaffold every verb runs ships `src/integrations/context-menu/index.js` calling `menu.useDefaults()` plus commented-out examples covering insertAfter, remove, hide, enable, and building from scratch.
@@ -0,0 +1,81 @@
1
+ # Context
2
+
3
+ Runtime info block. Mirrors @omega.js/backend's `assistant.request.{geolocation,client}` shape so @omega.js/desktop apps + sister projects (@omega.js/backend, UJM, @omega.js/client) all reference the same property paths when reading user info.
4
+
5
+ Populated asynchronously during `manager.initialize()`.
6
+
7
+ ## Shape
8
+
9
+ ```js
10
+ manager.context.geolocation = {
11
+ ip: '203.0.113.42', // async-fetched via ipify
12
+ country: null, // future enhancement
13
+ region: null,
14
+ city: null,
15
+ };
16
+
17
+ manager.context.client = {
18
+ userAgent: 'Mozilla/5.0 ...', // app.userAgentFallback
19
+ locale: 'en-US', // app.getLocale()
20
+ platform: 'darwin', // os.platform()
21
+ arch: 'arm64', // os.arch()
22
+ mobile: false, // always false on @omega.js/desktop (desktop framework)
23
+ };
24
+
25
+ manager.context.session = {
26
+ id: '<uuid>', // fresh per launch (crypto.randomUUID)
27
+ startTime: '2026-05-08T...', // ISO at boot
28
+ deviceId: '<uuid or MAC>', // stable per-machine
29
+ };
30
+
31
+ manager.context.app = {
32
+ version: '1.2.3', // manager.getVersion()
33
+ environment: 'production', // manager.getEnvironment()
34
+ isPackaged: true, // app.isPackaged
35
+ };
36
+ ```
37
+
38
+ ## Device ID resolution
39
+
40
+ The walk itself is the shared one — `@omega.js/analytics`' `deriveDeviceId({ get, set, seed })`, the same call `@omega.js/client` makes on a page ([#396](https://github.com/Omega-JS-Stack/omega/issues/396)). What this module supplies is desktop's own world: electron-store, and the MAC as the seed. Order:
41
+
42
+ 1. **Storage** — already persisted from a prior boot. Wins so we're stable across NIC swaps / VPN changes.
43
+ 2. **First non-internal MAC** from `os.networkInterfaces()`, the injected seed. Stable on a stable rig, and it hands a reinstalled app the id it had before its storage was wiped.
44
+ 3. **A generated UUID** — the shared derivation's floor. Persisted on first launch.
45
+
46
+ Once resolved on first launch it never changes. This is the input to `analytics._clientId = uuidv5(deviceId, projectIdNamespace)`, and it is desktop's alone: a browser on the same machine derives its own id from its own localStorage.
47
+
48
+ ## Geolocation
49
+
50
+ `geolocation.ip` is fetched in the background via `https://api.ipify.org?format=json`. Cached to `storage.context.geolocation` so the next launch has last-known-good values even if offline. The `country/region/city` fields are reserved for a future enrichment provider.
51
+
52
+ Failure mode: a failed ipify fetch leaves the previous cached value untouched. The app keeps working with last-known-good.
53
+
54
+ ## API
55
+
56
+ ```js
57
+ manager.context.geolocation.ip // direct read
58
+ manager.context.session.deviceId // direct read
59
+ const snap = manager.context.toJSON(); // structured-cloneable snapshot
60
+ ```
61
+
62
+ Renderer:
63
+
64
+ ```js
65
+ const snap = await window.desktop.context.get();
66
+ console.log(snap.session.deviceId);
67
+ ```
68
+
69
+ ## Why the @omega.js/backend shape
70
+
71
+ Sister projects (@omega.js/backend, @omega.js/client, UJM) all reference paths like `assistant.request.geolocation.country` and `assistant.request.client.userAgent`. @omega.js/desktop matches the leaf names so consumer code can write logic that works across all four runtimes:
72
+
73
+ ```js
74
+ const country = manager.context.geolocation.country
75
+ || assistant.request.geolocation.country // @omega.js/backend
76
+ || omega.context.geolocation.country;
77
+ ```
78
+
79
+ ## Tests
80
+
81
+ - `src/test/suites/main/context.test.js` — session shape, deviceId stability across re-init, the injected seed + persistence of the shared derivation, client info, IPC handler, JSON-roundtrippability.
package/docs/css.md ADDED
@@ -0,0 +1,84 @@
1
+ # CSS Architecture
2
+
3
+ @omega.js/desktop styles are SCSS, compiled by the pipeline's `sass` task into per-window bundles on top of a shared base. Bootstrap 5 (via @omega.js/desktop's classy theme) is the foundation — consumers restyle Bootstrap, they don't replace it.
4
+
5
+ ## Main entry
6
+
7
+ `<consumer>/src/assets/scss/main.scss` — loaded by EVERY window. It configures the theme via `@use ... with (...)`:
8
+
9
+ ```scss
10
+ @use 'omega-desktop' as * with (
11
+ $primary: #2563EB,
12
+ $dark: #1a1a2e,
13
+ $classy-bg-dark: #0f0f1a,
14
+ $classy-bg-dark-secondary: #161628,
15
+ $classy-bg-dark-tertiary: #1e1e38,
16
+ );
17
+
18
+ // Custom global styles below
19
+ ```
20
+
21
+ Compiles to `dist/assets/css/main.bundle.css` (Bootstrap + classy theme + your globals).
22
+
23
+ ## Per-window styles
24
+
25
+ `src/assets/scss/pages/<window>.scss` → `dist/assets/css/components/<window>.bundle.css`, loaded ONLY on that window's page. One file per window (`main.scss`, `settings.scss`, …) — page-specific chrome lives here, shared styles live in the main entry.
26
+
27
+ ## Theme integration
28
+
29
+ The `@use 'omega-desktop'` entry pulls in Bootstrap 5 + @omega.js/desktop's classy theme. Appearance (`system`/`light`/`dark`) defaults from `config.theme.appearance` and is applied + kept live on `<html data-bs-theme>` by `manager.theme` (OS-following, runtime-switchable, persisted override — see [themes.md](themes.md)). Theme variables (`$primary`, `$dark`, `$classy-bg-*`, typography, borders) are overridable via the `with (...)` block. See [themes.md](themes.md) for the full variable reference.
30
+
31
+ ## Icon presentation
32
+
33
+ Icon CSS is ONE sheet for every omega target, vendored from @omega.js/web at prepare (package.json `omega.vendorAssets` → `dist/assets/css/core/_fontawesome.scss`) and loaded by the `omega-desktop` entry. It ships the square glyph-centered box every rendered `<i>` gets, the `fa-2xs`…`fa-6xl` size scale, and the `fa-spin` / `fa-bounce` / `fa-beat` utilities (each parked under `prefers-reduced-motion`). Nothing to import and nothing to hand-fix. See [shared/icons.md](shared/icons.md).
34
+
35
+ ## App shell
36
+
37
+ Dashboard/admin windows use the `.omega-shell` layout — a sidebar + topbar + main grid with a collapsible desktop rail and a mobile drawer. Two layers ship, both vendored from @omega.js/web at prepare: the MECHANICS (`dist/assets/css/shell/_index.scss` — the grid, region geometry, states, and the `--omega-shell-*` tokens, loaded by the `omega-desktop` entry before the theme) and the theme's SKIN (`dist/assets/themes/<theme-id>/css/layout/_shell.scss`, layered over it). Nothing to import — `@use 'omega-desktop'` gets both.
38
+
39
+ Emit this markup in the window's HTML:
40
+
41
+ ```html
42
+ <div class="omega-shell" data-omega-shell>
43
+ <aside class="omega-shell__sidebar" id="app-sidebar">
44
+ <!-- pinned head (brand, selector) sits here, outside the scroll region -->
45
+ <div class="omega-shell__sidebar-scroll">
46
+ <!-- nav scrolls HERE (the rail itself clips nothing, so popovers can
47
+ escape); text that should hide in the collapsed rail wears
48
+ .omega-shell__label -->
49
+ </div>
50
+ </aside>
51
+
52
+ <header class="omega-shell__topbar">
53
+ <div class="omega-shell__topbar-start">
54
+ <button data-shell-toggle="drawer" aria-expanded="false" aria-controls="app-sidebar">☰</button>
55
+ <button data-shell-toggle="collapse" aria-expanded="true" aria-controls="app-sidebar">⇤</button>
56
+ </div>
57
+ <div class="omega-shell__topbar-end"><!-- account menu, actions --></div>
58
+ </header>
59
+
60
+ <main class="omega-shell__main"><!-- page content --></main>
61
+
62
+ <div class="omega-shell__scrim" data-shell-dismiss></div>
63
+ </div>
64
+ ```
65
+
66
+ Wire the behavior from a renderer component (`src/assets/js/components/<window>/index.js`) — `__main_assets__` is the build alias for @omega.js/desktop's vendored core assets:
67
+
68
+ ```js
69
+ import appShell from '__main_assets__/js/core/app-shell.js';
70
+
71
+ appShell();
72
+ ```
73
+
74
+ The module is delegated and declarative: `[data-shell-toggle="collapse"]` toggles the rail, `[data-shell-toggle="drawer"]` toggles the mobile drawer, `[data-shell-dismiss]` (and Escape) closes it. It stamps the state on the container — `data-shell-collapsed="true"` (persisted under the `shell.collapsed` storage key) and `data-shell-open="true"` — which is what the CSS keys off; the API is also registered at `omega._library.appShell`. Add `.omega-shell--locked` when `main` should never scroll (the page manages its own interior scroll).
75
+
76
+ ## Bootstrap-first convention
77
+
78
+ NEVER create custom classes for things Bootstrap already provides — use `btn`, `card`, `form-*`, `d-flex`, `gap-*`, `rounded-*`, `bg-body-*`, `text-*` natively, and use `bg-body` variants (not `bg-light`/`bg-dark`) so dark mode adapts. Theme SCSS overrides how Bootstrap components LOOK; custom CSS is only for genuinely novel components with no Bootstrap equivalent. Same rule in BXM and UJM.
79
+
80
+ ## See also
81
+
82
+ - [themes.md](themes.md) — theme variables, appearance modes
83
+ - [build-system.md](build-system.md) — where the `sass` task runs in the pipeline
84
+ - [templating.md](templating.md) — the page template that loads the bundles
@@ -0,0 +1,178 @@
1
+ # Deep Links
2
+
3
+ Cross-platform deep-link handling that's simple to use and hard to get wrong. @omega.js/desktop owns all the OS plumbing (single-instance lock, scheme registration, argv parsing, second-instance routing, focus-on-warm-start) and gives you one unified event API regardless of how the link arrived.
4
+
5
+ ## Config
6
+
7
+ ```jsonc
8
+ "deepLinks": {
9
+ "schemes": ["myapp"] // urls like myapp://...
10
+ }
11
+ ```
12
+
13
+ @omega.js/desktop registers each scheme with the OS via `app.setAsDefaultProtocolClient` so the system routes matching URLs to your app. Registration is **production-only** — dev/test runs never claim OS-wide protocol handlers for unpackaged Electron binaries. In dev, exercise your handlers with `manager.deepLink.dispatch(url)` instead.
14
+
15
+ ## How it works (so you don't have to think about it)
16
+
17
+ | Platform | Cold-start (app not running) | Warm-start (app already running) |
18
+ |---|---|---|
19
+ | **macOS** | `app.on('open-url')` — queued before `whenReady`, drained after | `app.on('open-url')` |
20
+ | **Windows** | URL appended to `process.argv`; @omega.js/desktop extracts it | OS forwards argv to the existing instance via `app.on('second-instance')` |
21
+ | **Linux** | Same as Windows | Same as Windows |
22
+
23
+ @omega.js/desktop handles all of these and dispatches them through the same `manager.deepLink.on()` event registry. Your code looks identical regardless of platform or cold/warm start. Single-instance lock is acquired automatically (via `lib/protocol.js`); duplicate launches exit cleanly and forward their argv to the original instance.
24
+
25
+ ## Public API
26
+
27
+ ```js
28
+ manager.deepLink.on(pattern, handler) // register a handler. Returns unsubscribe fn.
29
+ manager.deepLink.off(pattern, handler)
30
+ manager.deepLink.dispatch(url) // manually fire (testing, custom triggers)
31
+ manager.deepLink.getColdStartUrl() // the URL the app was launched with, or null
32
+ ```
33
+
34
+ ## Patterns
35
+
36
+ ```
37
+ 'auth/token' // exact match
38
+ 'user/profile/:id' // named param → ctx.params.id
39
+ 'org/:slug/repo/:repo' // multiple params
40
+ '*' // wildcard catch-all (only fires when no concrete handler matched)
41
+ ```
42
+
43
+ ## Handler signature
44
+
45
+ ```js
46
+ manager.deepLink.on('user/profile/:id', (ctx) => {
47
+ ctx.url // 'myapp://user/profile/42?ref=tray'
48
+ ctx.scheme // 'myapp'
49
+ ctx.route // 'user/profile/42'
50
+ ctx.pattern // 'user/profile/:id'
51
+ ctx.params // { id: '42' }
52
+ ctx.query // { ref: 'tray' }
53
+ ctx.source // 'cold-start' | 'warm-start' | 'manual'
54
+ ctx.argv // process.argv (cold) or second-instance argv (warm)
55
+ ctx.cwd // working directory
56
+ ctx.handled // mutable: set true to suppress remaining handlers (including built-ins)
57
+ });
58
+ ```
59
+
60
+ ## Built-in routes
61
+
62
+ @omega.js/desktop ships with handlers for common patterns. They run AFTER consumer handlers, so you can shadow any of them by registering your own handler at the same pattern.
63
+
64
+ | Route | Default behavior |
65
+ |---|---|
66
+ | `auth/token` | Calls `manager.omega.handleAuthToken(query.authToken)` — the receiving end of the `manager.openAuthFlow()` sign-in round-trip. MODERN shape only (`?authToken=`, what the website's token page sends); legacy-app formats (`?token=`, `?payload=`) are UJM's concern and are ignored. In production the URL arrives via the OS scheme; in dev/test `lib/auth-flow.js`'s loopback listener dispatches the same URL manually (the scheme isn't OS-registered in dev — protocol.js registers only in production, and macOS can't runtime-register unlisted schemes at all) |
67
+ | `app/show` | `manager.windows.show(query.window || 'main')` |
68
+ | `app/quit` | `app.quit()` |
69
+
70
+ ### Overriding a built-in
71
+
72
+ ```js
73
+ // Replace the built-in app/show with custom logic.
74
+ manager.deepLink.on('app/show', (ctx) => {
75
+ if (ctx.query.window === 'admin' && !manager.appState.isAdminUser()) {
76
+ showError('not authorized');
77
+ ctx.handled = true; // suppress built-in
78
+ return;
79
+ }
80
+ // Otherwise let the built-in run normally.
81
+ });
82
+ ```
83
+
84
+ ## Resolution order
85
+
86
+ For each incoming URL, @omega.js/desktop walks handlers in this order:
87
+
88
+ 1. **Consumer concrete handlers** (any non-wildcard pattern you registered with `.on()`)
89
+ 2. **Built-in concrete handlers** (`auth/token`, `app/show`, `app/quit`)
90
+ 3. **Wildcard handlers** (`'*'`) — only if NO concrete handler matched
91
+
92
+ Setting `ctx.handled = true` in any handler stops the cascade. Within a single tier, handlers fire in registration order. Errors in a handler are caught and logged — they don't stop subsequent handlers.
93
+
94
+ ## Common patterns
95
+
96
+ ### Route to a window + send IPC
97
+
98
+ ```js
99
+ manager.deepLink.on('user/profile/:id', (ctx) => {
100
+ manager.windows.show('main');
101
+ manager.windows.get('main').webContents.send('navigate', {
102
+ to: `/profile/${ctx.params.id}`,
103
+ });
104
+ });
105
+ ```
106
+
107
+ ### Catch-all logger
108
+
109
+ ```js
110
+ manager.deepLink.on('*', (ctx) => {
111
+ manager.logger.warn(`Unrouted deep link: ${ctx.url}`);
112
+ });
113
+ ```
114
+
115
+ ### Cold-start branching
116
+
117
+ ```js
118
+ const coldUrl = manager.deepLink.getColdStartUrl();
119
+ if (coldUrl) {
120
+ manager.logger.log(`Launched from deep link: ${coldUrl}`);
121
+ // appState.launchedFromDeepLink() is also set automatically
122
+ }
123
+ ```
124
+
125
+ ### Manually dispatching (e.g. from a tray click)
126
+
127
+ ```js
128
+ tray.item({
129
+ label: 'Open Profile',
130
+ click: () => manager.deepLink.dispatch('myapp://user/profile/me'),
131
+ });
132
+ ```
133
+
134
+ ## Boot queueing
135
+
136
+ Every dispatch is held until `manager.initialize()` completes (main.js calls `deepLink.markManagerReady()` as its last step). A cold-start `auth/token` link — the OS launching the app from the sign-in round trip — therefore never fires before client-bridge has Firebase up; it queues and drains the moment the manager is ready. Warm-start dispatches on a running app pass straight through.
137
+
138
+ ## Single-instance behavior
139
+
140
+ @omega.js/desktop acquires the OS-level single-instance lock during `protocol.initialize()` (boot step 5, before deep-link inits). If another copy of the app is already running:
141
+
142
+ 1. The new instance loses the lock.
143
+ 2. The OS forwards its argv to the original instance.
144
+ 3. The new instance's `Manager.initialize()` returns early (after `protocol.hasSingleInstanceLock() === false`).
145
+ 4. The original instance's `app.on('second-instance')` fires with the new argv.
146
+ 5. @omega.js/desktop extracts the deep-link URL from that argv and dispatches normally — but as `source: 'warm-start'`.
147
+ 6. @omega.js/desktop also focuses the existing main window automatically (consumer can override by registering a route handler that does its own thing).
148
+
149
+ ## Linking with `appState`
150
+
151
+ When a deep link is detected at cold-start, @omega.js/desktop calls `manager.appState.setLaunchedFromDeepLink(true)`. This means:
152
+
153
+ ```js
154
+ if (manager.appState.launchedFromDeepLink()) {
155
+ // user clicked a link to launch the app — handle differently than a tray click or login launch
156
+ }
157
+ ```
158
+
159
+ Combine with `appState.isFirstLaunch()` to detect "first launch via deep link" (e.g. from an onboarding flow on your website).
160
+
161
+ ## Testing
162
+
163
+ The dispatch pipeline is unit-testable without actually triggering an OS event:
164
+
165
+ ```js
166
+ manager.deepLink.dispatch('myapp://auth/token?token=test');
167
+ // Fires source='manual'. Handlers run synchronously.
168
+ ```
169
+
170
+ See `src/test/suites/main/deep-link.test.js` for the full coverage.
171
+
172
+ ## Implementation notes
173
+
174
+ - `lib/protocol.js` owns the single-instance lock + scheme registration; `lib/deep-link.js` owns the dispatch pipeline. They're separate modules but tightly coupled.
175
+ - OS scheme registration is gated on `manager.isProduction()` (in `lib/protocol.js`) — unpackaged dev/test binaries are never registered as system protocol handlers (unconditional registration also intermittently triggered macOS Launch Services `-600` dialogs during test runs).
176
+ - On Windows/Linux, scheme registration uses `app.setAsDefaultProtocolClient(scheme, process.execPath, [process.cwd()])` so `app.exe scheme://...` style invocations route argv correctly.
177
+ - macOS open-url events that arrive before `whenReady` are queued internally and drained on `deepLink.initialize()`.
178
+ - Argv extraction walks backward from the end of argv (where the URL typically sits) and matches against registered schemes.
@@ -0,0 +1,104 @@
1
+ # Environment Detection
2
+
3
+ `getEnvironment()` returns exactly ONE of three mutually-exclusive, exhaustive values:
4
+
5
+ ```javascript
6
+ Manager.getEnvironment() // 'development' | 'testing' | 'production'
7
+
8
+ Manager.isDevelopment() // true ONLY in development
9
+ Manager.isTesting() // true ONLY in testing
10
+ Manager.isProduction() // true ONLY in production
11
+ ```
12
+
13
+ **The Manager is the single source of truth.** `getEnvironment()` is the ONLY function that reads the raw signals (`OMEGA_TEST_MODE` / Electron `app.isPackaged` / `config.em.environment` / `OMEGA_BUILD_MODE` / `NODE_ENV`). The three `is*()` checks **derive** from it live on every call — they never read raw signals themselves, so they can never disagree with `getEnvironment()`.
14
+
15
+ **One implementation, mixed into all four Managers.** @omega.js/desktop has four Manager entry points (main / renderer / preload / build). The helpers are defined once in [src/utils/mode-helpers.js](../src/utils/mode-helpers.js) and mixed into each via `attachTo(Manager)`, available as both prototype methods (`manager.isTesting()`) and statics (`Manager.isTesting()`).
16
+
17
+ ```javascript
18
+ manager.getEnvironment() // same answer in main / renderer / preload / build
19
+ Manager.isTesting() // static form, for build-time scripts
20
+ ```
21
+
22
+ **Resolution order:** testing wins first, then production, else development. The three checks are mutually exclusive — exactly one is true. `isDevelopment()` is **false** during testing, and `isProduction()` is a real positive check (it is NOT `!isDevelopment()`).
23
+
24
+ ## Available helpers
25
+
26
+ | Helper | Returns |
27
+ |---|---|
28
+ | `getEnvironment()` | `'development' \| 'testing' \| 'production'` — the SSOT resolver; the only reader of raw signals. |
29
+ | `isDevelopment()` | `true` ONLY in development (running unpackaged / `electron .` / dev), and NOT testing. Derives from `getEnvironment()`. |
30
+ | `isTesting()` | `true` ONLY in testing (`OMEGA_TEST_MODE === 'true'`). **Takes precedence** — a test run is unpackaged, but it's a test, not development. |
31
+ | `isProduction()` | `true` ONLY in production (packaged & distributed, `app.isPackaged === true`). A **real positive check** — NOT `!isDevelopment()`. |
32
+
33
+ ## Gating side effects — use the INTENTIONAL check
34
+
35
+ Because there are three environments, never gate a side effect on a two-value assumption. State what you mean:
36
+
37
+ ```javascript
38
+ // Production-only (skip OS side effects / real telemetry in dev AND testing):
39
+ if (isProduction()) { /* do the real thing */ }
40
+ if (!isProduction()) { /* skip / use the safe local behavior */ }
41
+
42
+ // Local-or-test (anything that should run in BOTH dev and testing):
43
+ if (isDevelopment() || isTesting()) { /* localhost URL, isolate userData, suppress login items */ }
44
+ ```
45
+
46
+ **Avoid** `if (!isDevelopment())` or `if (env !== 'development')` to gate production behavior — those wrongly include `testing` as production and leak real side effects (login items, telemetry, auto-update) during test runs. This is the bug class that motivated the 3-value model. (A genuinely dev-only feature like live-reload is the exception: `env !== 'development'` correctly skips it in both testing and production.)
47
+
48
+ ## URL helpers
49
+
50
+ ```javascript
51
+ Manager.getApiUrl() // the app's API URL — the SSOT for calling the backend
52
+ ```
53
+
54
+ `getApiUrl()` / `getFunctionsUrl()` / `getWebsiteUrl()` resolve to **local** URLs (`http://localhost:5002` / `http://localhost:5001/<projectId>/us-central1` / `https://localhost:4000`) in development OR testing, and to production (`https://api.<brand.url host>` etc.) otherwise. They route through `this.getEnvironment()`, so they're correct everywhere without an argument — call them directly. Pass an explicit `env` arg (`getApiUrl('production')`) only to force a specific environment regardless of the current one — rarely needed, and mainly used by tests to pin a specific environment's mapping.
55
+
56
+ `getAuthUrl()` builds the **sign-in URL that round-trips an auth token back to the app**: `<site>/signin?authReturnUrl=<site>/token?authReturnUrl=<brand.id>://auth/token`, where `<site>` is `getWebsiteUrl()` (same env split). The UJM website's `/signin` page logs the user in (or bounces straight through if already signed in), its `/token` page mints a Firebase custom token via the backend, and the final redirect (`?authToken=<token>` — the ONE shape; legacy-app formats live in UJM, not @omega.js/desktop) deep-links the token into the app's built-in `auth/token` route → `omega.handleAuthToken()` → `signInWithCustomToken`. Use it for EVERY "Sign in" affordance an app exposes — never link the bare `/signin` page, which strands the login in the browser. Requires `brand.id` (the deep-link scheme) in config; throws when missing. The optional second arg `getAuthUrl(env, returnUrl)` overrides the chain's final hop — that's how `lib/auth-flow.js` swaps in its dev loopback return.
57
+
58
+ **Apps should launch the flow through `manager.openAuthFlow()` (main process), not by opening `getAuthUrl()` themselves**: production opens `getAuthUrl()` externally as-is (the OS routes the custom scheme back), while dev/test — where the scheme is NOT OS-registered (protocol.js registers only in production, and macOS can't runtime-register schemes missing from the bundle's Info.plist) — swap the final hop for a one-shot, nonce-checked loopback HTTP listener (RFC 8252 §7.3) that feeds the token into the SAME deep-link pipeline. Sign-in always happens in the user's REAL default browser (their existing session/SSO), never an embedded window. Requires @omega.js/client ≥ 4.3.4 on the website (`isValidRedirectUrl` accepts loopback hosts while the SITE runs in dev). See [src/lib/auth-flow.js](../src/lib/auth-flow.js).
59
+
60
+ All three local helpers resolve from whichever channel the process has: the `OMEGA_*_PORT` env vars (the CLI that booted the stack publishes them), the `dev` map the bundle baked into `OMEGA_BUILD_JSON` (a packaged main process has no parent env, so a bumped emulator port reaches it only this way, [#745](https://github.com/Omega-JS-Stack/omega/issues/745)), and the classic default. `getApiUrl()` and `getFunctionsUrl()` read them in exactly that order; `getWebsiteUrl()` takes its baked cell first, for the reason under the table:
61
+
62
+ | Helper | Env channel | Baked channel | Classic |
63
+ |---|---|---|---|
64
+ | `getApiUrl()` | `OMEGA_HTTPS_PORT`, else `OMEGA_HOSTING_PORT` | `dev.ports.https`, else `dev.ports.hosting` | 5002 |
65
+ | `getFunctionsUrl()` | `OMEGA_FUNCTIONS_PORT` | `dev.ports.functions` | 5001 |
66
+ | `getWebsiteUrl()` | `OMEGA_WEBSITE_PORT`, composed as `https://localhost:<port>` | `dev.origin` (the whole origin) first, else `dev.ports.website` | `https://localhost:4000` |
67
+
68
+ The first two rows are port chains: each cell names a port, and the helper builds the URL around it. The website row is an ORIGIN chain ([#747](https://github.com/Omega-JS-Stack/omega/issues/747)): the baked `dev.origin` the live website published carries scheme, host AND port, so it is the complete fact and outranks both port cells; only when it is absent does a port compose an origin, over **https**, because `omega dev` fronts its public port with the mkcert proxy by default and a port number alone can never say the scheme. Whenever the website published an origin, that is the same answer `@omega.js/client`'s `getDevWebsiteOrigin()` gives every other surface ([#262](https://github.com/Omega-JS-Stack/omega/issues/262)), and `getAuthUrl()` inherits it by construction.
69
+
70
+ A resolved `OMEGA_HTTPS_PORT` (or a baked `dev.ports.https`) means `omega serve`'s mkcert proxy is up, so the api URL is https. That is the same three-step chain @omega.js/extension's `getApiUrl()` walks, and the same one client-bridge uses for the auth emulator port (`OMEGA_AUTH_PORT` → `dev.ports.auth` → 9099, [client-bridge.md](client-bridge.md)).
71
+
72
+ Resolving local in test mode is required because tests hit the local emulator — without it, the app (and tests calling `getApiUrl()`) would leak to the live production server.
73
+
74
+ > The URL helpers live in [src/utils/url-helpers.js](../src/utils/url-helpers.js) and depend on `this.getEnvironment()` (from mode-helpers.js) being mixed in — both `attachTo` calls run at the bottom of every Manager entry point.
75
+
76
+ ## Where they live
77
+
78
+ Source: [src/utils/mode-helpers.js](../src/utils/mode-helpers.js) for `getEnvironment()` + `is*()` + `getVersion()`; [src/utils/url-helpers.js](../src/utils/url-helpers.js) for the URL builders. Each module exposes the functions plus an `attachTo(Manager)` mixin. Attached at the bottom of all four Manager files: [main.js](../src/main.js), [renderer.js](../src/renderer.js), [preload.js](../src/preload.js), [build.js](../src/build.js) — mode-helpers first (so `getEnvironment` exists), then url-helpers.
79
+
80
+ ## How detection works
81
+
82
+ `getEnvironment()` resolves in this precedence order:
83
+
84
+ 1. **Testing** — `process.env.OMEGA_TEST_MODE === 'true'` (set by @omega.js/desktop's test runners). A test run is a test run regardless of packaged state.
85
+ 2. **Config override** — `config.em.environment` (`'development'` / `'testing'` / `'production'`), the consumer's explicit choice. It beats the auto-detected `app.isPackaged` below.
86
+ 3. **Production / Development (runtime)** — Electron `app.isPackaged`: packaged → production, unpackaged → development. This is the authoritative runtime signal in the main process. In renderer / preload / plain Node, `app` is unavailable, so it falls through.
87
+ 4. **Build-time signals** — `OMEGA_BUILD_MODE === 'true'` → production; `NODE_ENV === 'development'` → development.
88
+ 5. **Default** — production. @omega.js/desktop's deployed *runtime* can reach here without a dev signal (a packaged binary whose `app.isPackaged` didn't resolve is still a shipped app), so production is the safe assumption. (Contrast UJM/BXM, whose deployed artifacts always carry their signal baked in, so they default to **development** — a bare context there is just build tooling. @omega.js/backend defaults to production for the same reason as @omega.js/desktop.)
89
+
90
+ ## Adding a new helper
91
+
92
+ Write the function in a `src/utils/<topic>-helpers.js` module, expose `attachTo(Manager)`, then call `attachTo` at the bottom of all four Manager files. Don't define helpers on individual Manager prototypes — that path leads to duplicated semantics (the old `getEnvironment` collision between main.js and build.js). For anything environment-derived, derive from `getEnvironment()` rather than reading `process.env` / `app.*` directly, so there is one source of truth and no chance of drift.
93
+
94
+ ## Why this matters
95
+
96
+ **One signal, used everywhere.** The test runner sets `OMEGA_TEST_MODE=true`; every piece of code that calls `isTesting()` (framework or consumer) then sees `true` — no need to invent a per-module env var.
97
+
98
+ **Sub-modules check the same signal.** When framework code (an auto-update poll, a restart-manager registration) needs to skip side effects in tests, it checks `isTesting()` — the same answer the consumer's own code gets. No drift.
99
+
100
+ **`is*()` can never disagree with `getEnvironment()`.** Because the checks derive from the single resolver instead of reading raw signals (`app.isPackaged` vs `OMEGA_BUILD_MODE`), there is exactly one definition of "what environment is this," and a wrong-but-confident gate is structurally impossible.
101
+
102
+ ## See also
103
+
104
+ - [test-framework.md](test-framework.md) — `OMEGA_TEST_MODE` is set automatically by the test runners; extended mode (`--extended` / `TEST_EXTENDED_MODE`) gates real external APIs.