@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,563 @@
1
+ // Strategy-aware Windows code signer.
2
+ //
3
+ // Reads strategy from config platforms.win.signing.strategy:
4
+ // self-hosted — sign with signtool against an EV USB token (typically on a self-hosted runner)
5
+ // cloud — shell out to a cloud signing provider's CLI (Azure / SSL.com / DigiCert)
6
+ // local — no-op (developer signs manually on their own Windows box)
7
+ //
8
+ // Usage:
9
+ // npx omega sign-windows # sign every .exe/.msi under ./release
10
+ // npx omega sign-windows --in release/ --out release/signed/
11
+ // npx omega sign-windows --verify-only # don't sign, just verify existing signatures
12
+ // npx omega sign-windows --smoke # sign a 1-byte dummy .exe to validate the setup
13
+ // npx omega sign-windows --target some-binary.exe # sign a single specific file
14
+ //
15
+ // Cloud provider modules will live in src/lib/sign-providers/{azure,sslcom,digicert}.js
16
+ // (Pass 3 work). For now the cloud branch logs the intended provider command and exits cleanly.
17
+
18
+ const path = require('path');
19
+ const fs = require('fs');
20
+ const os = require('os');
21
+ const jetpack = require('fs-jetpack');
22
+ const { execute } = require('node-powertools');
23
+
24
+ const Manager = new (require('../build.js'));
25
+ const logger = Manager.logger('sign-windows');
26
+
27
+ // The box's own signing configuration (`<runner home>\.env`: the cert, the PIN,
28
+ // signtool) is read before anything below looks at process.env, so a manual
29
+ // sign, `--smoke` and the e2e suite work from any directory. A CI-delivered
30
+ // value wins over the file (utils/runner-env.js).
31
+ const runnerEnv = require('../utils/runner-env.js');
32
+ runnerEnv.loadRunnerEnv();
33
+ const attachLogFile = require('../utils/attach-log-file.js');
34
+
35
+ const { startAutoUnlock } = require('../lib/sign-helpers/auto-unlock.js');
36
+ const { writeUpdateInfo } = require('../lib/sign-helpers/update-info.js');
37
+ const signEvents = require('../lib/sign-helpers/sign-events.js');
38
+
39
+ module.exports = async function (options) {
40
+ options = options || {};
41
+
42
+ // The box's own record of what it signed, beside the install — the same file
43
+ // `omega runner` writes, since a sign is one of the things the box did. Its
44
+ // OWN tee, so an outer verb's log file survives this one's detach.
45
+ //
46
+ // `attachInCI` because this file is the BOX's, not the workspace's: the
47
+ // `windows-sign` job IS the run whose trail the box needs to keep. `append`
48
+ // because the `runner start` listener that spawned this holds the same file.
49
+ const logTarget = boxLogTarget();
50
+ const tee = attachLogFile.createTee();
51
+ if (logTarget) tee.attach(logTarget, { attachInCI: true, append: true });
52
+
53
+ const jobStart = Date.now();
54
+ // GITHUB_REPOSITORY is "<owner>/<repo>" inside a GH Actions runner — split for the
55
+ // monitor banner. GITHUB_REPOSITORY_OWNER is the same thing as the owner half but is
56
+ // sometimes the better source on org-vs-user runs. Both are provided automatically by
57
+ // actions/runner; only present when invoked from a workflow job.
58
+ const repoFull = process.env.GITHUB_REPOSITORY || '';
59
+ const [ghOwner, ghRepo] = repoFull.includes('/') ? repoFull.split('/') : [process.env.GITHUB_REPOSITORY_OWNER || null, null];
60
+ signEvents.emit('job-start', {
61
+ options: Object.fromEntries(Object.entries(options).filter(([k]) => k !== '_')),
62
+ runner_workspace: process.env.RUNNER_WORKSPACE || null,
63
+ github_run_id: process.env.GITHUB_RUN_ID || null,
64
+ github_workflow: process.env.GITHUB_WORKFLOW || null,
65
+ github_owner: ghOwner || null,
66
+ github_repo: ghRepo || null,
67
+ });
68
+ logger.log(`Signing event log: ${signEvents.getLogPath()}`);
69
+
70
+ try {
71
+ const result = await runSignCommand(options);
72
+ signEvents.emit('job-end', { ok: true, duration_ms: Date.now() - jobStart });
73
+ return result;
74
+ } catch (e) {
75
+ signEvents.emit('job-end', { ok: false, duration_ms: Date.now() - jobStart, error: e?.message || String(e) });
76
+ throw e;
77
+ } finally {
78
+ tee.detach();
79
+ }
80
+ };
81
+
82
+ async function runSignCommand(options) {
83
+ // Smoke test mode: create a 1-byte .exe in a temp dir, sign it, verify it, clean up.
84
+ // This is the fastest possible end-to-end check that the EV token, drivers, signtool,
85
+ // and password cache are all working — no @omega.js/desktop build required.
86
+ if (options.smoke) {
87
+ await runnerEnv.ensureRunnerConfig({ logger, scopes: ['signing'] });
88
+ return smokeTest();
89
+ }
90
+
91
+ const strategy = Manager.getWindowsSignStrategy();
92
+
93
+ const config = Manager.getConfig();
94
+ const projectRoot = process.cwd();
95
+
96
+ // Resolve --in and --out (CLI flags) → directories of unsigned / signed artifacts.
97
+ const inDir = options.in ? path.resolve(projectRoot, options.in) : path.join(projectRoot, 'release');
98
+ const outDir = options.out ? path.resolve(projectRoot, options.out) : path.join(projectRoot, 'release', 'signed');
99
+
100
+ // Single-target shortcut — useful for debugging a specific failure.
101
+ let targets;
102
+ if (options.target) {
103
+ const t = path.resolve(projectRoot, options.target);
104
+ if (!jetpack.exists(t)) throw new Error(`--target file does not exist: ${t}`);
105
+ targets = [t];
106
+ } else {
107
+ if (!jetpack.exists(inDir)) {
108
+ throw new Error(`Input directory does not exist: ${inDir}`);
109
+ }
110
+ targets = jetpack.find(inDir, { matching: ['*.exe', '*.msi'], recursive: true, files: true, directories: false });
111
+ if (targets.length === 0) {
112
+ logger.warn(`No .exe / .msi files found under ${inDir} — nothing to sign.`);
113
+ return;
114
+ }
115
+ }
116
+
117
+ // Signing HERE needs the box's cert, PIN and signtool: ask for what is missing
118
+ // in a terminal, refuse without one. The cloud strategy has no such needs.
119
+ // After the input checks on purpose: a mistyped --target fails before anyone
120
+ // is asked for a PIN.
121
+ if (strategy === 'self-hosted' || strategy === 'local') {
122
+ await runnerEnv.ensureRunnerConfig({ logger, scopes: ['signing'] });
123
+ }
124
+
125
+ // Verify-only mode: don't sign anything, just run signtool verify against each.
126
+ if (options['verify-only'] || options.verifyOnly) {
127
+ return verifyOnly(targets);
128
+ }
129
+
130
+ jetpack.dir(outDir);
131
+
132
+ logger.log(`Signing ${targets.length} artifact(s) — strategy=${strategy}, in=${path.relative(projectRoot, inDir)}, out=${path.relative(projectRoot, outDir)}`);
133
+
134
+ if (strategy === 'self-hosted' || strategy === 'local') {
135
+ if (strategy === 'local') {
136
+ logger.warn('strategy=local — this command will run signtool against whatever cert config the local box has. Make sure your EV token is plugged in.');
137
+ }
138
+ await signWithSigntool(targets, inDir, outDir);
139
+ return;
140
+ }
141
+
142
+ if (strategy === 'cloud') {
143
+ const provider = config.platforms?.win?.signing?.cloud?.provider;
144
+ if (!provider) {
145
+ throw new Error('strategy=cloud but no provider set (config platforms.win.signing.cloud.provider).');
146
+ }
147
+ await signWithCloudProvider(provider, targets, inDir, outDir);
148
+ return;
149
+ }
150
+
151
+ throw new Error(`Unknown Windows signing strategy: ${strategy}`);
152
+ }
153
+
154
+ // The runner log this run may tee to, or null.
155
+ //
156
+ // Off Windows there is no box home at all, so a manual mac/linux sign drops no
157
+ // `.gh-runners/` into the cwd. And from a TEST run the box's own record is off
158
+ // limits unless the home is a scratch one — a suite pointed at a real home
159
+ // writes nothing rather than overwriting what the box did
160
+ // ([#337](https://github.com/Omega-JS-Stack/omega/issues/337)).
161
+ //
162
+ // `env` and `platform` resolve the HOME (the test seam); whether this is a test
163
+ // run is read from process.env by isTestRun, always — never from an argument.
164
+ //
165
+ // @param {object} [env] - Environment the home is resolved from.
166
+ // @param {string} [platform] - Platform the default home is resolved for.
167
+ // @returns {string|null}
168
+ function boxLogTarget(env, platform) {
169
+ env = env || process.env;
170
+ platform = platform || process.platform;
171
+
172
+ const home = env.OMEGA_RUNNER_HOME
173
+ || (platform === 'win32' ? runnerEnv.defaultRunnerHome(platform, env) : null);
174
+ if (!home) return null;
175
+ if (runnerEnv.isTestRun() && !runnerEnv.isScratchRunnerHome(home)) return null;
176
+
177
+ return runnerEnv.runnerLogFile(home);
178
+ }
179
+
180
+ // signtool path (Windows SDK). Falls back to plain `signtool` on PATH.
181
+ function getSigntoolPath(env) {
182
+ env = env || process.env;
183
+ if (env.SIGNTOOL_PATH) return env.SIGNTOOL_PATH;
184
+ return 'signtool'; // assume on PATH; SDK installers add it
185
+ }
186
+
187
+ // Detect whether WIN_EV_TOKEN_PATH is a SHA1 thumbprint (40 hex chars, optional spaces)
188
+ // vs. a file path. SafeNet/eToken-managed certs live in the user store and are selected
189
+ // by thumbprint via /sha1; .pfx files are passed via /f + /p.
190
+ function isThumbprint(value) {
191
+ if (!value) return false;
192
+ const stripped = value.replace(/\s+/g, '');
193
+ return /^[0-9a-fA-F]{40}$/.test(stripped);
194
+ }
195
+
196
+ // Every signtool input, resolved from the environment in one place, with the
197
+ // loud named error when a required one is missing.
198
+ //
199
+ // WIN_EV_TOKEN_PATH is the ONE name for the certificate reference — the schema
200
+ // name ([#337](https://github.com/Omega-JS-Stack/omega/issues/337)). The old
201
+ // WIN_CSC_LINK alias is gone: two names for one key means two things to keep
202
+ // straight on a box nobody logs into.
203
+ function resolveSigntoolEnv(env) {
204
+ env = env || process.env;
205
+
206
+ const tokenRef = env.WIN_EV_TOKEN_PATH;
207
+ if (!tokenRef) {
208
+ throw new Error('WIN_EV_TOKEN_PATH not set — cannot sign. Set it to the EV cert SHA1 thumbprint (SafeNet/eToken) or a .pfx path.');
209
+ }
210
+
211
+ const password = env.WIN_CSC_KEY_PASSWORD;
212
+ const useThumbprint = isThumbprint(tokenRef);
213
+
214
+ // Thumbprint mode (SafeNet/eToken): signtool finds cert in user store, SafeNet handles auth.
215
+ // File mode (.pfx): /f + /p, password handed to signtool directly.
216
+ if (!useThumbprint && !password) {
217
+ throw new Error('WIN_CSC_KEY_PASSWORD not set — required when WIN_EV_TOKEN_PATH is a .pfx path.');
218
+ }
219
+
220
+ return {
221
+ tokenRef,
222
+ password,
223
+ useThumbprint,
224
+ signtool: getSigntoolPath(env),
225
+ timestampUrl: env.WIN_TIMESTAMP_URL || 'http://timestamp.sectigo.com',
226
+ };
227
+ }
228
+
229
+ // The `signtool sign` command line, as one string. Pure, so the exact argument
230
+ // order for both cert modes is provable without a Windows box.
231
+ //
232
+ // It ends in `2>&1` because signtool writes its diagnosis to stderr and the
233
+ // retry classifier below reads `e.message` — without the redirect a wrong PIN
234
+ // can arrive as a bare exit code and get retried three times.
235
+ function buildSignCommand({ signtool, tokenRef, password, timestampUrl, outPath }) {
236
+ const certArgs = isThumbprint(tokenRef)
237
+ ? [`/sha1 ${tokenRef.replace(/\s+/g, '')}`]
238
+ : [`/f "${tokenRef}"`, `/p "${password}"`];
239
+
240
+ return [
241
+ `"${signtool}"`,
242
+ 'sign',
243
+ ...certArgs,
244
+ `/tr "${timestampUrl}"`,
245
+ '/td sha256',
246
+ '/fd sha256',
247
+ `"${outPath}"`,
248
+ '2>&1',
249
+ ].join(' ');
250
+ }
251
+
252
+ // The `signtool verify` command line. Local-only, so it stays single-shot.
253
+ function buildVerifyCommand({ signtool, outPath }) {
254
+ return `"${signtool}" verify /pa "${outPath}"`;
255
+ }
256
+
257
+ // The sign call reaches a THIRD PARTY — the timestamp server — and that is the
258
+ // one part of signing that fails and then works seconds later (rate limit, 502,
259
+ // a dropped connection mid-handshake). So the sign call gets three attempts with
260
+ // a short backoff; verify is local and never retries.
261
+ const SIGN_ATTEMPTS = 3;
262
+ const SIGN_RETRY_DELAY_MS = 5000;
263
+
264
+ // node-powertools' `execute` with `log: false` — what this file passes — rejects
265
+ // with `new Error(stderr || 'Command failed with exit code N')`, and the sign
266
+ // command ends in `2>&1` (it runs through a shell), so BOTH of signtool's
267
+ // streams reach `e.message` and this is classifying on signtool's own words.
268
+ //
269
+ // Failures signtool NAMES as permanent. Retrying a wrong PIN walks the EV token
270
+ // toward a lockout, and no amount of waiting conjures a certificate that isn't
271
+ // in the store — so these stop on the first attempt. Anything else (including a
272
+ // bare exit code, where signtool told us nothing) is treated as transient and
273
+ // retried, because a lost timestamp round-trip looks exactly like that.
274
+ const NON_TRANSIENT_SIGN_FAILURES = [
275
+ /No certificates were found/i,
276
+ /password is not correct/i,
277
+ /token .{0,20}locked/i,
278
+ /hash on the file is malformed/i,
279
+ ];
280
+
281
+ function isTransientSignFailure(error) {
282
+ const message = String(error?.message || error || '');
283
+ return !NON_TRANSIENT_SIGN_FAILURES.some((re) => re.test(message));
284
+ }
285
+
286
+ // Run `cmd` with the retry policy above. Every attempt lands in the signing
287
+ // event log, so `runner monitor` shows the retries as they happen. Throws the
288
+ // last error when it gives up.
289
+ //
290
+ // `startUnlock` is called PER ATTEMPT and stopped the moment that attempt ends.
291
+ // SafeNet raises its "Token Logon" dialog on every signtool call, and the
292
+ // watcher returns as soon as it has typed once — so a single watcher wrapped
293
+ // around the whole loop leaves attempts 2 and 3 facing the dialog unattended,
294
+ // which is exactly the retry that was supposed to save the job.
295
+ async function signWithRetry(cmd, options) {
296
+ options = options || {};
297
+ const {
298
+ file,
299
+ attempts = SIGN_ATTEMPTS,
300
+ delayMs = SIGN_RETRY_DELAY_MS,
301
+ exec = (c) => execute(c, { log: false }),
302
+ sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
303
+ emit = signEvents.emit,
304
+ startUnlock = () => ({ stop: () => {} }),
305
+ } = options;
306
+
307
+ for (let attempt = 1; attempt <= attempts; attempt++) {
308
+ emit('sign-attempt', { file, attempt, of: attempts });
309
+
310
+ const unlock = startUnlock();
311
+ let failure;
312
+ try {
313
+ return await exec(cmd);
314
+ } catch (e) {
315
+ failure = e;
316
+ } finally {
317
+ // Stopped before the verdict and the backoff — nothing polls the desktop
318
+ // while we are only waiting.
319
+ unlock.stop();
320
+ }
321
+
322
+ if (attempt === attempts || !isTransientSignFailure(failure)) throw failure;
323
+ emit('sign-retry', {
324
+ file,
325
+ attempt,
326
+ of: attempts,
327
+ retry_in_ms: delayMs,
328
+ error: failure?.message || String(failure),
329
+ });
330
+ await sleep(delayMs);
331
+ }
332
+
333
+ // Unreachable: the loop returns on success and throws on the last attempt.
334
+ throw new Error(`signWithRetry exhausted ${attempts} attempts without a verdict`);
335
+ }
336
+
337
+ async function signWithSigntool(targets, inDir, outDir) {
338
+ const projectRoot = process.cwd();
339
+ const { tokenRef, password, useThumbprint, signtool, timestampUrl } = resolveSigntoolEnv();
340
+
341
+ // Track which signed installers are NSIS-style .exe so we can write latest.yml
342
+ // for them after the signing loop. .msi targets use Windows Installer's own
343
+ // update mechanism (not electron-updater) and don't need a yml.
344
+ const signedExes = [];
345
+
346
+ for (const target of targets) {
347
+ const rel = path.relative(inDir, target);
348
+ const outPath = path.join(outDir, rel);
349
+ jetpack.dir(path.dirname(outPath));
350
+
351
+ // Copy first, sign in place at the output location (signtool modifies in-place).
352
+ jetpack.copy(target, outPath, { overwrite: true });
353
+
354
+ const cmd = buildSignCommand({ signtool, tokenRef, password, timestampUrl, outPath });
355
+
356
+ logger.log(`Signing ${path.relative(projectRoot, outPath)}${useThumbprint ? ' (thumbprint mode)' : ''}...`);
357
+
358
+ const fileBytes = (() => { try { return fs.statSync(outPath).size; } catch (_) { return null; } })();
359
+ signEvents.emit('sign-start', {
360
+ file: path.basename(outPath),
361
+ out_path: outPath,
362
+ bytes: fileBytes,
363
+ mode: useThumbprint ? 'thumbprint' : 'pfx',
364
+ });
365
+
366
+ // In thumbprint mode against a SafeNet/eToken cert, signtool triggers a
367
+ // "Token Logon" dialog. signWithRetry starts one watcher per attempt to type
368
+ // the password into it, and stops each when that attempt ends.
369
+ const fileStart = Date.now();
370
+ try {
371
+ await signWithRetry(cmd, {
372
+ file: path.basename(outPath),
373
+ startUnlock: () => (useThumbprint ? startAutoUnlock({ password, logger }) : { stop: () => {} }),
374
+ });
375
+ } catch (e) {
376
+ signEvents.emit('sign-fail', {
377
+ file: path.basename(outPath),
378
+ duration_ms: Date.now() - fileStart,
379
+ phase: 'signtool',
380
+ error: e?.message || String(e),
381
+ });
382
+ throw e;
383
+ }
384
+
385
+ // Verify is a local check with no third party in it — one shot.
386
+ const verifyCmd = buildVerifyCommand({ signtool, outPath });
387
+ try {
388
+ await execute(verifyCmd, { log: false });
389
+ } catch (e) {
390
+ signEvents.emit('sign-fail', {
391
+ file: path.basename(outPath),
392
+ duration_ms: Date.now() - fileStart,
393
+ phase: 'verify',
394
+ error: e?.message || String(e),
395
+ });
396
+ throw e;
397
+ }
398
+ signEvents.emit('sign-done', {
399
+ file: path.basename(outPath),
400
+ duration_ms: Date.now() - fileStart,
401
+ });
402
+ logger.log(logger.format.green(`✓ Signed: ${path.relative(projectRoot, outPath)}`));
403
+
404
+ if (outPath.toLowerCase().endsWith('.exe')) {
405
+ signedExes.push({ filePath: outPath, urlName: path.basename(outPath) });
406
+ }
407
+ }
408
+
409
+ // Generate latest.yml + per-exe .blockmap for the signed NSIS installers. Without
410
+ // this, electron-updater on Windows clients has no way to discover the new release
411
+ // (mac/linux equivalents are produced by electron-builder during their publish step,
412
+ // but Windows is split into a post-build sign job so we have to write the yml here).
413
+ if (signedExes.length > 0) {
414
+ const pkg = Manager.getPackage('project') || {};
415
+ const version = pkg.version;
416
+ if (!version) {
417
+ logger.warn('Could not determine version from package.json — skipping latest.yml generation.');
418
+ } else {
419
+ logger.log(`Generating Windows auto-updater feed (latest.yml) for ${signedExes.length} installer(s)...`);
420
+ try {
421
+ await writeUpdateInfo({
422
+ signedExes,
423
+ outDir,
424
+ version,
425
+ logger,
426
+ });
427
+ } catch (e) {
428
+ // Don't fail the whole sign step if yml generation hits something unexpected —
429
+ // the signed exe is still valid + uploadable. But this IS a real problem
430
+ // because auto-updates won't work, so log loudly.
431
+ logger.error(`latest.yml generation failed: ${e.message}`);
432
+ logger.error(' Signed binary is OK but Windows auto-updater will not see this release.');
433
+ }
434
+ }
435
+ }
436
+ }
437
+
438
+ // Verify-only: run signtool verify /pa against each target, report whether it's signed.
439
+ // Doesn't fail if some are unsigned — reports each.
440
+ async function verifyOnly(targets) {
441
+ const signtool = getSigntoolPath();
442
+ let signed = 0;
443
+ let unsigned = 0;
444
+ let errored = 0;
445
+
446
+ for (const t of targets) {
447
+ try {
448
+ const out = await execute(`"${signtool}" verify /pa /v "${t}"`, { log: false });
449
+ const trimmed = String(out || '').trim();
450
+ // signtool prints things like "Successfully verified" or details about the chain.
451
+ if (/Successfully verified/i.test(trimmed)) {
452
+ logger.log(logger.format.green(`✓ Signed: ${t}`));
453
+ // Pull the subject CN out for visibility.
454
+ const cn = trimmed.match(/Issued to:\s*(.+)/i)?.[1];
455
+ if (cn) logger.log(` Subject: ${cn.trim()}`);
456
+ signed += 1;
457
+ } else {
458
+ logger.warn(`? Unclear verify output for: ${t}`);
459
+ logger.log(trimmed.split('\n').slice(0, 5).join('\n'));
460
+ errored += 1;
461
+ }
462
+ } catch (e) {
463
+ // signtool exits non-zero on unsigned files.
464
+ logger.warn(`✗ Unsigned or invalid: ${t}`);
465
+ const msg = String(e?.message || e).split('\n').slice(0, 3).join(' ');
466
+ logger.log(` ${msg}`);
467
+ unsigned += 1;
468
+ }
469
+ }
470
+
471
+ logger.log(`Verify summary: ${signed} signed, ${unsigned} unsigned, ${errored} unclear (of ${targets.length} total).`);
472
+ return { signed, unsigned, errored, total: targets.length };
473
+ }
474
+
475
+ // A real PE/COFF .exe to sign when there is no build to sign: %WINDIR%\System32\where.exe
476
+ // (small, always present, and copying it is fine). One home for that choice, so the smoke
477
+ // test and the Windows-gated end-to-end suite sign the same thing.
478
+ function copySampleExe(destPath, env) {
479
+ env = env || process.env;
480
+
481
+ const sourceExe = path.join(env.WINDIR || 'C:\\Windows', 'System32', 'where.exe');
482
+ if (!jetpack.exists(sourceExe)) {
483
+ throw new Error(`Could not find a sample .exe to sign at ${sourceExe}. Pass --target <path> instead.`);
484
+ }
485
+ jetpack.copy(sourceExe, destPath, { overwrite: true });
486
+
487
+ return destPath;
488
+ }
489
+
490
+ // Smoke test: write a 1-byte .exe to %TEMP%, run the full self-hosted signing flow against it.
491
+ // Validates that EV token, SafeNet drivers, signtool, and the password cache are all functional
492
+ // without needing an actual @omega.js/desktop build. Cleans up after itself.
493
+ async function smokeTest() {
494
+ if (process.platform !== 'win32') {
495
+ throw new Error('--smoke is Windows-only (signtool is required).');
496
+ }
497
+
498
+ const { tokenRef, useThumbprint } = resolveSigntoolEnv();
499
+
500
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'desktop-smoke-'));
501
+ const target = copySampleExe(path.join(tmp, 'desktop-smoke-test.exe'));
502
+
503
+ logger.log(`Smoke test: signing a temp copy of where.exe at ${target}`);
504
+ logger.log(`Cert ref: ${tokenRef}${useThumbprint ? ' (thumbprint mode — SafeNet handles auth)' : ' (file mode)'}`);
505
+
506
+ try {
507
+ await signWithSigntool([target], path.dirname(target), path.dirname(target));
508
+ logger.log(logger.format.green('✓ Smoke test passed — EV token + signtool + password cache all working.'));
509
+ } catch (e) {
510
+ logger.error(`Smoke test FAILED: ${e.message}`);
511
+ logger.log('Most common causes:');
512
+ logger.log(' • EV token not plugged in or not detected by SafeNet');
513
+ logger.log(' • SafeNet driver not installed');
514
+ logger.log(' • WIN_CSC_KEY_PASSWORD wrong or token locked (check tray icon)');
515
+ logger.log(' • signtool.exe not on PATH (Windows SDK or VS Build Tools required)');
516
+ throw e;
517
+ } finally {
518
+ try { jetpack.remove(tmp); } catch (e) { /* ignore */ }
519
+ }
520
+ }
521
+
522
+ async function signWithCloudProvider(provider, targets, inDir, outDir) {
523
+ // Provider modules live in src/lib/sign-providers/<name>.js. Each exports
524
+ // async function sign({ targets, inDir, outDir, projectRoot, env }) { ... }
525
+ let providerModule;
526
+ try {
527
+ providerModule = require(path.join(__dirname, '..', 'lib', 'sign-providers', `${provider}.js`));
528
+ } catch (e) {
529
+ throw new Error(`Cloud provider "${provider}" is not yet implemented (no src/lib/sign-providers/${provider}.js). Supported: azure, sslcom, digicert.`);
530
+ }
531
+
532
+ if (typeof providerModule.sign !== 'function') {
533
+ throw new Error(`sign-providers/${provider}.js does not export a sign() function.`);
534
+ }
535
+
536
+ await providerModule.sign({
537
+ targets,
538
+ inDir,
539
+ outDir,
540
+ projectRoot: process.cwd(),
541
+ env: process.env,
542
+ logger,
543
+ });
544
+ }
545
+
546
+ // Exports for testing — the pure halves of the signer: what the command line
547
+ // looks like, which env keys feed it, and when a failure is worth retrying.
548
+ module.exports.isThumbprint = isThumbprint;
549
+ module.exports.boxLogTarget = boxLogTarget;
550
+ module.exports.resolveSigntoolEnv = resolveSigntoolEnv;
551
+ module.exports.buildSignCommand = buildSignCommand;
552
+ module.exports.buildVerifyCommand = buildVerifyCommand;
553
+ module.exports.signWithRetry = signWithRetry;
554
+ module.exports.isTransientSignFailure = isTransientSignFailure;
555
+ module.exports.SIGN_ATTEMPTS = SIGN_ATTEMPTS;
556
+ module.exports.SIGN_RETRY_DELAY_MS = SIGN_RETRY_DELAY_MS;
557
+
558
+ // Exports for the Windows-gated end-to-end suite — the halves that shell out to
559
+ // signtool for real. They only run where signtool and the EV token are
560
+ // (suites/build/sign-windows-e2e.test.js gates on exactly that).
561
+ module.exports.signWithSigntool = signWithSigntool;
562
+ module.exports.verifyOnly = verifyOnly;
563
+ module.exports.copySampleExe = copySampleExe;
@@ -0,0 +1,121 @@
1
+ // Libraries
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+ const Manager = new (require('../build.js'));
5
+ const logger = Manager.logger('test');
6
+ const { run } = require('../test/runner.js');
7
+ const attachLogFile = require('../utils/attach-log-file.js');
8
+ const { EXTENDED_MODE_WARNING } = require('../test/utils/extended-mode-warning.js');
9
+ const { noMatchMessage, noMatchExitCode } = require('../vendor/devkit/test/scope.js');
10
+ const { ensureTarget } = require('./lib/ensure-target.js');
11
+
12
+ module.exports = async function (options) {
13
+ // This process is a TEST RUN, and everything it spawns inherits that. The box's
14
+ // mutating verbs read it and refuse to touch a real runner home
15
+ // ([#337](https://github.com/Omega-JS-Stack/omega/issues/337): a suite once ran
16
+ // a real `runner install` on the signing box). Deliberately NOT the canonical
17
+ // OMEGA_TEST_MODE, which means "the app under test runs in testing mode" and
18
+ // would change what the boot lane's production build compiles.
19
+ process.env.OMEGA_TEST_RUNNER = '1';
20
+
21
+ // Tee all test output to <projectRoot>/logs/test.log (ANSI-stripped) — mirrors
22
+ // @omega.js/backend's test.log and @omega.js/desktop's own dev.log pattern.
23
+ attachLogFile(path.join(process.cwd(), 'logs', 'test.log'));
24
+
25
+ // The local half of the retired `omega setup` (#675) — idempotent, offline,
26
+ // and quiet on a converged target. The gulp verbs get it from the `defaults`
27
+ // task; test runs no gulp, so it calls it here.
28
+ await ensureTarget({
29
+ projectDir: process.cwd(),
30
+ log: (line) => logger.log(line),
31
+ warn: (line) => logger.warn(line),
32
+ });
33
+
34
+ const layer = options.layer || 'all';
35
+ // Positional target: `npx omega test <target>` where target supports source
36
+ // prefixes — `project:`, `project:<path>`, `em:`, `em:<path>`, or a bare
37
+ // `<path>` (matches both sources). Selects which test FILES run.
38
+ const target = (options._ && options._[1]) || null;
39
+ // `--filter` flag: substring match on test NAMES/descriptions (orthogonal to target).
40
+ const filter = options.filter || null;
41
+ const reporter = options.reporter || 'pretty';
42
+ // Extended mode — opt into tests that hit REAL external services (Firebase, analytics,
43
+ // update feeds) instead of skipping them. Off by default so `npx omega test` stays fast and
44
+ // offline-safe. The canonical signal is the unprefixed `TEST_EXTENDED_MODE` env var — the
45
+ // SAME name across @omega.js/backend, @omega.js/extension, UJM, and @omega.js/desktop (cross-framework parity); `--extended` is the CLI
46
+ // shorthand. Once set on process.env it propagates to every spawned child (electron
47
+ // main/renderer/boot, the gulp boot build) automatically via `{ ...process.env }`.
48
+ const extended = options.extended === true
49
+ || options.extended === 'true'
50
+ || process.env.TEST_EXTENDED_MODE === 'true'
51
+ || process.env.TEST_EXTENDED_MODE === '1';
52
+
53
+ if (extended) {
54
+ process.env.TEST_EXTENDED_MODE = 'true';
55
+ }
56
+
57
+ // When @omega.js/desktop itself runs its own boot-layer tests (the cwd's package.json is @omega.js/desktop's), there's
58
+ // no real consumer app to boot. Point the boot runner at the fixture under
59
+ // dist/test/fixtures/consumer-app unless the caller has already set OMEGA_TEST_BOOT_PROJECT
60
+ // explicitly. Mirrors BXM's OMEGA_TEST_BOOT_PROJECT / UJM's UJ_TEST_BOOT_PROJECT.
61
+ if (!process.env.OMEGA_TEST_BOOT_PROJECT) {
62
+ try {
63
+ const cwdPkg = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf8'));
64
+ if (cwdPkg.name === '@omega.js/desktop') {
65
+ process.env.OMEGA_TEST_BOOT_PROJECT = path.join(__dirname, '..', 'test', 'fixtures', 'consumer-app');
66
+ }
67
+ } catch (_) { /* no package.json — leave unset */ }
68
+ }
69
+
70
+ if (reporter !== 'json') {
71
+ const parts = [`layer=${layer}`];
72
+ if (target) parts.push(`target="${target}"`);
73
+ if (filter) parts.push(`filter="${filter}"`);
74
+ if (extended) parts.push('+extended');
75
+ logger.log(`Running tests (${parts.join(' ')})`);
76
+ logger.log(`Test mode: ${extended ? 'extended (real external APIs)' : 'normal (external APIs skipped)'}`);
77
+ if (extended) {
78
+ logger.warn(EXTENDED_MODE_WARNING[0]);
79
+ EXTENDED_MODE_WARNING.slice(1).forEach((line) => logger.warn(line));
80
+ }
81
+ }
82
+
83
+ const result = await run({ layer, target, filter, reporter });
84
+
85
+ if (reporter === 'json') {
86
+ // Final machine-readable summary.
87
+ process.stdout.write(`${JSON.stringify({
88
+ event: 'summary',
89
+ passed: result.passed,
90
+ failed: result.failed,
91
+ skipped: result.skipped,
92
+ total: result.passed + result.failed + result.skipped,
93
+ })}\n`);
94
+ }
95
+
96
+ // A target that named files and matched none is a failed run, not an empty
97
+ // one: a typo'd path, or a suite renamed out from under it, used to report
98
+ // "0 passing" and exit 0
99
+ // ([#814](https://github.com/Omega-JS-Stack/omega/issues/814)).
100
+ if (result.noMatch) {
101
+ logger.error(noMatchMessage(result.noMatch));
102
+ // Standalone that is 1. Inside a brand-root fan-out the manager forwarded
103
+ // ONE target to every target, so a distinct code lets it count this as a
104
+ // miss rather than a failure (#814).
105
+ process.exitCode = noMatchExitCode();
106
+ await attachLogFile.detach();
107
+ return;
108
+ }
109
+
110
+ if (result.failed > 0) {
111
+ process.exitCode = 1;
112
+ await attachLogFile.detach();
113
+ throw new Error(`${result.failed} test(s) failed`);
114
+ }
115
+
116
+ // Close test.log before exiting. Nothing to flush: every write already went
117
+ // to the fd synchronously (#197), so the Results block survives the exit
118
+ // below whatever happens — detach() just closes the handle.
119
+ await attachLogFile.detach();
120
+ process.exit(0);
121
+ };