@omega.js/extension 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 (684) hide show
  1. package/LICENSE +98 -0
  2. package/README.md +194 -0
  3. package/bin/omega +2 -0
  4. package/bin/omega-extension +2 -0
  5. package/bin/omg +2 -0
  6. package/dist/assets/css/bundles/.gitkeep +0 -0
  7. package/dist/assets/css/components/content/index.scss +5 -0
  8. package/dist/assets/css/components/options/index.scss +9 -0
  9. package/dist/assets/css/components/pages/index.scss +5 -0
  10. package/dist/assets/css/components/popup/index.scss +9 -0
  11. package/dist/assets/css/core/_animations.scss +64 -0
  12. package/dist/assets/css/core/_fontawesome.scss +146 -0
  13. package/dist/assets/css/core/_initialize.scss +23 -0
  14. package/dist/assets/css/core/_utilities.scss +80 -0
  15. package/dist/assets/css/omega-extension.scss +43 -0
  16. package/dist/assets/css/shell/_index.scss +207 -0
  17. package/dist/assets/css/tokens/_index.scss +166 -0
  18. package/dist/assets/js/core/app-shell.js +136 -0
  19. package/dist/assets/js/libs/initialize-tooltips.js +31 -0
  20. package/dist/assets/js/libs/recaptcha.js +94 -0
  21. package/dist/assets/js/main.js +4 -0
  22. package/dist/assets/themes/_template/README.md +115 -0
  23. package/dist/assets/themes/_template/_config.scss +60 -0
  24. package/dist/assets/themes/_template/_theme.js +14 -0
  25. package/dist/assets/themes/_template/_theme.scss +28 -0
  26. package/dist/assets/themes/_template/css/base/_root.scss +19 -0
  27. package/dist/assets/themes/_template/css/components/_components.scss +23 -0
  28. package/dist/assets/themes/base/README.md +5 -0
  29. package/dist/assets/themes/base/_components/data/org-chart/component.html +33 -0
  30. package/dist/assets/themes/base/_components/data/org-chart/component.json5 +33 -0
  31. package/dist/assets/themes/base/_components/data/org-chart/component.scss +183 -0
  32. package/dist/assets/themes/base/_components/heading/masthead/component.html +22 -0
  33. package/dist/assets/themes/base/_components/heading/masthead/component.json5 +30 -0
  34. package/dist/assets/themes/base/_components/heading/section-head/component.html +18 -0
  35. package/dist/assets/themes/base/_components/heading/section-head/component.json5 +27 -0
  36. package/dist/assets/themes/base/_components/pricing/features/component.html +29 -0
  37. package/dist/assets/themes/base/_components/pricing/features/component.json5 +30 -0
  38. package/dist/assets/themes/base/_hero/orbit/index.html +30 -0
  39. package/dist/assets/themes/base/_hero/orbit/script.js +33 -0
  40. package/dist/assets/themes/base/_hero/orbit/style.scss +133 -0
  41. package/dist/assets/themes/base/_includes/admin/sections/sidebar.html +3 -0
  42. package/dist/assets/themes/base/_includes/admin/sections/topbar.html +3 -0
  43. package/dist/assets/themes/base/_includes/backend/sections/sidebar.html +3 -0
  44. package/dist/assets/themes/base/_includes/backend/sections/topbar.html +3 -0
  45. package/dist/assets/themes/base/_includes/frontend/components/connection-card.html +49 -0
  46. package/dist/assets/themes/base/_includes/frontend/components/post-card.html +54 -0
  47. package/dist/assets/themes/base/_includes/frontend/sections/account-connections.html +42 -0
  48. package/dist/assets/themes/base/_includes/frontend/sections/account-section-header.html +11 -0
  49. package/dist/assets/themes/base/_includes/frontend/sections/footer.html +154 -0
  50. package/dist/assets/themes/base/_includes/frontend/sections/nav.html +276 -0
  51. package/dist/assets/themes/base/_includes/global/sections/account.html +72 -0
  52. package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +248 -0
  53. package/dist/assets/themes/base/_includes/global/sections/app-topbar.html +228 -0
  54. package/dist/assets/themes/base/_includes/global/sections/page-header.html +99 -0
  55. package/dist/assets/themes/base/_layouts/admin/core/minimal-viewport-locked.html +22 -0
  56. package/dist/assets/themes/base/_layouts/admin/core/minimal.html +23 -0
  57. package/dist/assets/themes/base/_layouts/backend/core/base.html +57 -0
  58. package/dist/assets/themes/base/_layouts/backend/core/minimal-viewport-locked.html +32 -0
  59. package/dist/assets/themes/base/_layouts/backend/core/minimal.html +32 -0
  60. package/dist/assets/themes/base/_layouts/backend/pages/dashboard/index.html +230 -0
  61. package/dist/assets/themes/base/_layouts/frontend/core/base.html +31 -0
  62. package/dist/assets/themes/base/_layouts/frontend/core/cover.html +40 -0
  63. package/dist/assets/themes/base/_layouts/frontend/core/minimal.html +47 -0
  64. package/dist/assets/themes/base/_layouts/frontend/pages/404.html +54 -0
  65. package/dist/assets/themes/base/_layouts/frontend/pages/about.html +144 -0
  66. package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +2104 -0
  67. package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/alternative.html +319 -0
  68. package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +186 -0
  69. package/dist/assets/themes/base/_layouts/frontend/pages/app.html +142 -0
  70. package/dist/assets/themes/base/_layouts/frontend/pages/auth/reset.html +53 -0
  71. package/dist/assets/themes/base/_layouts/frontend/pages/auth/signin.html +90 -0
  72. package/dist/assets/themes/base/_layouts/frontend/pages/auth/signup.html +141 -0
  73. package/dist/assets/themes/base/_layouts/frontend/pages/auth/token.html +44 -0
  74. package/dist/assets/themes/base/_layouts/frontend/pages/blog/categories/category.html +88 -0
  75. package/dist/assets/themes/base/_layouts/frontend/pages/blog/categories/index.html +88 -0
  76. package/dist/assets/themes/base/_layouts/frontend/pages/blog/index.html +255 -0
  77. package/dist/assets/themes/base/_layouts/frontend/pages/blog/post.html +261 -0
  78. package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/index.html +84 -0
  79. package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/tag.html +88 -0
  80. package/dist/assets/themes/base/_layouts/frontend/pages/collection/category.html +72 -0
  81. package/dist/assets/themes/base/_layouts/frontend/pages/collection/document.html +54 -0
  82. package/dist/assets/themes/base/_layouts/frontend/pages/collection/index.html +84 -0
  83. package/dist/assets/themes/base/_layouts/frontend/pages/connections/callback.html +55 -0
  84. package/dist/assets/themes/base/_layouts/frontend/pages/contact.html +214 -0
  85. package/dist/assets/themes/base/_layouts/frontend/pages/download.html +793 -0
  86. package/dist/assets/themes/base/_layouts/frontend/pages/extension/index.html +253 -0
  87. package/dist/assets/themes/base/_layouts/frontend/pages/extension/installed.html +198 -0
  88. package/dist/assets/themes/base/_layouts/frontend/pages/feedback.html +171 -0
  89. package/dist/assets/themes/base/_layouts/frontend/pages/index.html +66 -0
  90. package/dist/assets/themes/base/_layouts/frontend/pages/legal/document.html +78 -0
  91. package/dist/assets/themes/base/_layouts/frontend/pages/payment/checkout.html +459 -0
  92. package/dist/assets/themes/base/_layouts/frontend/pages/payment/confirmation.html +131 -0
  93. package/dist/assets/themes/base/_layouts/frontend/pages/portal/email-preferences.html +104 -0
  94. package/dist/assets/themes/base/_layouts/frontend/pages/pricing.html +596 -0
  95. package/dist/assets/themes/base/_layouts/frontend/pages/status.html +361 -0
  96. package/dist/assets/themes/base/_layouts/frontend/pages/team/index.html +210 -0
  97. package/dist/assets/themes/base/_layouts/frontend/pages/team/member.html +125 -0
  98. package/dist/assets/themes/base/_layouts/frontend/pages/updates/index.html +119 -0
  99. package/dist/assets/themes/base/_layouts/frontend/pages/updates/update.html +118 -0
  100. package/dist/assets/themes/base/_sections/about/hero/section.html +68 -0
  101. package/dist/assets/themes/base/_sections/about/hero/section.json5 +58 -0
  102. package/dist/assets/themes/base/_sections/about/letter/section.html +60 -0
  103. package/dist/assets/themes/base/_sections/about/letter/section.json5 +56 -0
  104. package/dist/assets/themes/base/_sections/about/photo-band/section.html +24 -0
  105. package/dist/assets/themes/base/_sections/about/photo-band/section.json5 +23 -0
  106. package/dist/assets/themes/base/_sections/about/principles/section.html +17 -0
  107. package/dist/assets/themes/base/_sections/about/principles/section.json5 +34 -0
  108. package/dist/assets/themes/base/_sections/about/timeline/section.html +20 -0
  109. package/dist/assets/themes/base/_sections/about/timeline/section.json5 +34 -0
  110. package/dist/assets/themes/base/_sections/marketing/bento/section.html +91 -0
  111. package/dist/assets/themes/base/_sections/marketing/bento/section.json5 +152 -0
  112. package/dist/assets/themes/base/_sections/marketing/cta/section.html +44 -0
  113. package/dist/assets/themes/base/_sections/marketing/cta/section.json5 +47 -0
  114. package/dist/assets/themes/base/_sections/marketing/faq/section.html +52 -0
  115. package/dist/assets/themes/base/_sections/marketing/faq/section.json5 +68 -0
  116. package/dist/assets/themes/base/_sections/marketing/hero/section.html +349 -0
  117. package/dist/assets/themes/base/_sections/marketing/hero/section.json5 +335 -0
  118. package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.html +38 -0
  119. package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.js +86 -0
  120. package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.json5 +29 -0
  121. package/dist/assets/themes/base/_sections/marketing/pricing-cards/section.html +115 -0
  122. package/dist/assets/themes/base/_sections/marketing/pricing-cards/section.json5 +72 -0
  123. package/dist/assets/themes/base/_sections/marketing/product-demo/section.html +62 -0
  124. package/dist/assets/themes/base/_sections/marketing/product-demo/section.js +44 -0
  125. package/dist/assets/themes/base/_sections/marketing/product-demo/section.json5 +52 -0
  126. package/dist/assets/themes/base/_sections/marketing/prose/section.html +22 -0
  127. package/dist/assets/themes/base/_sections/marketing/prose/section.json5 +41 -0
  128. package/dist/assets/themes/base/_sections/marketing/showcase/section.html +35 -0
  129. package/dist/assets/themes/base/_sections/marketing/showcase/section.json5 +52 -0
  130. package/dist/assets/themes/base/_sections/marketing/stats/section.html +32 -0
  131. package/dist/assets/themes/base/_sections/marketing/stats/section.json5 +44 -0
  132. package/dist/assets/themes/base/_sections/marketing/testimonials/section.html +54 -0
  133. package/dist/assets/themes/base/_sections/marketing/testimonials/section.json5 +70 -0
  134. package/dist/assets/themes/base/_sections/marketing/trusted-by/section.html +30 -0
  135. package/dist/assets/themes/base/_sections/marketing/trusted-by/section.json5 +38 -0
  136. package/dist/assets/themes/base/_sections/verts/unit/section.html +7 -0
  137. package/dist/assets/themes/base/_sections/verts/unit/section.js +22 -0
  138. package/dist/assets/themes/base/_sections/verts/unit/section.json5 +24 -0
  139. package/dist/assets/themes/base/_sections/verts/unit/section.scss +24 -0
  140. package/dist/assets/themes/base/_theme.js +13 -0
  141. package/dist/assets/themes/base/_theme.scss +4 -0
  142. package/dist/assets/themes/bootstrap/_theme.js +16 -0
  143. package/dist/assets/themes/bootstrap/_theme.scss +11 -0
  144. package/dist/assets/themes/bootstrap/js/index.esm.js +19 -0
  145. package/dist/assets/themes/bootstrap/js/index.umd.js +34 -0
  146. package/dist/assets/themes/bootstrap/js/src/alert.js +87 -0
  147. package/dist/assets/themes/bootstrap/js/src/base-component.js +86 -0
  148. package/dist/assets/themes/bootstrap/js/src/button.js +72 -0
  149. package/dist/assets/themes/bootstrap/js/src/carousel.js +474 -0
  150. package/dist/assets/themes/bootstrap/js/src/collapse.js +297 -0
  151. package/dist/assets/themes/bootstrap/js/src/dom/data.js +55 -0
  152. package/dist/assets/themes/bootstrap/js/src/dom/event-handler.js +317 -0
  153. package/dist/assets/themes/bootstrap/js/src/dom/manipulator.js +71 -0
  154. package/dist/assets/themes/bootstrap/js/src/dom/selector-engine.js +126 -0
  155. package/dist/assets/themes/bootstrap/js/src/dropdown.js +458 -0
  156. package/dist/assets/themes/bootstrap/js/src/modal.js +378 -0
  157. package/dist/assets/themes/bootstrap/js/src/offcanvas.js +282 -0
  158. package/dist/assets/themes/bootstrap/js/src/popover.js +97 -0
  159. package/dist/assets/themes/bootstrap/js/src/scrollspy.js +296 -0
  160. package/dist/assets/themes/bootstrap/js/src/tab.js +315 -0
  161. package/dist/assets/themes/bootstrap/js/src/toast.js +224 -0
  162. package/dist/assets/themes/bootstrap/js/src/tooltip.js +632 -0
  163. package/dist/assets/themes/bootstrap/js/src/util/backdrop.js +151 -0
  164. package/dist/assets/themes/bootstrap/js/src/util/component-functions.js +35 -0
  165. package/dist/assets/themes/bootstrap/js/src/util/config.js +65 -0
  166. package/dist/assets/themes/bootstrap/js/src/util/focustrap.js +115 -0
  167. package/dist/assets/themes/bootstrap/js/src/util/index.js +306 -0
  168. package/dist/assets/themes/bootstrap/js/src/util/sanitizer.js +117 -0
  169. package/dist/assets/themes/bootstrap/js/src/util/scrollbar.js +114 -0
  170. package/dist/assets/themes/bootstrap/js/src/util/swipe.js +146 -0
  171. package/dist/assets/themes/bootstrap/js/src/util/template-factory.js +160 -0
  172. package/dist/assets/themes/bootstrap/overrides/_accordion.scss +21 -0
  173. package/dist/assets/themes/bootstrap/overrides/_avatars.scss +51 -0
  174. package/dist/assets/themes/bootstrap/overrides/_blog-images.scss +45 -0
  175. package/dist/assets/themes/bootstrap/overrides/_buttons-adaptive.scss +141 -0
  176. package/dist/assets/themes/bootstrap/overrides/_color-shades.scss +25 -0
  177. package/dist/assets/themes/bootstrap/overrides/_cursor-utilities.scss +13 -0
  178. package/dist/assets/themes/bootstrap/overrides/_index.scss +30 -0
  179. package/dist/assets/themes/bootstrap/overrides/_links.scss +26 -0
  180. package/dist/assets/themes/bootstrap/overrides/_soft-colors.scss +99 -0
  181. package/dist/assets/themes/bootstrap/overrides/_spacing-extended.scss +74 -0
  182. package/dist/assets/themes/bootstrap/overrides/_spinners.scss +22 -0
  183. package/dist/assets/themes/bootstrap/overrides/_typography-utilities.scss +40 -0
  184. package/dist/assets/themes/bootstrap/scss/_accordion.scss +153 -0
  185. package/dist/assets/themes/bootstrap/scss/_alert.scss +68 -0
  186. package/dist/assets/themes/bootstrap/scss/_badge.scss +38 -0
  187. package/dist/assets/themes/bootstrap/scss/_breadcrumb.scss +40 -0
  188. package/dist/assets/themes/bootstrap/scss/_button-group.scss +147 -0
  189. package/dist/assets/themes/bootstrap/scss/_buttons.scss +216 -0
  190. package/dist/assets/themes/bootstrap/scss/_card.scss +238 -0
  191. package/dist/assets/themes/bootstrap/scss/_carousel.scss +226 -0
  192. package/dist/assets/themes/bootstrap/scss/_close.scss +66 -0
  193. package/dist/assets/themes/bootstrap/scss/_containers.scss +41 -0
  194. package/dist/assets/themes/bootstrap/scss/_dropdown.scss +250 -0
  195. package/dist/assets/themes/bootstrap/scss/_forms.scss +9 -0
  196. package/dist/assets/themes/bootstrap/scss/_functions.scss +302 -0
  197. package/dist/assets/themes/bootstrap/scss/_grid.scss +39 -0
  198. package/dist/assets/themes/bootstrap/scss/_helpers.scss +12 -0
  199. package/dist/assets/themes/bootstrap/scss/_images.scss +42 -0
  200. package/dist/assets/themes/bootstrap/scss/_list-group.scss +199 -0
  201. package/dist/assets/themes/bootstrap/scss/_maps.scss +174 -0
  202. package/dist/assets/themes/bootstrap/scss/_mixins.scss +42 -0
  203. package/dist/assets/themes/bootstrap/scss/_modal.scss +240 -0
  204. package/dist/assets/themes/bootstrap/scss/_nav.scss +197 -0
  205. package/dist/assets/themes/bootstrap/scss/_navbar.scss +289 -0
  206. package/dist/assets/themes/bootstrap/scss/_offcanvas.scss +147 -0
  207. package/dist/assets/themes/bootstrap/scss/_pagination.scss +109 -0
  208. package/dist/assets/themes/bootstrap/scss/_placeholders.scss +51 -0
  209. package/dist/assets/themes/bootstrap/scss/_popover.scss +196 -0
  210. package/dist/assets/themes/bootstrap/scss/_progress.scss +68 -0
  211. package/dist/assets/themes/bootstrap/scss/_reboot.scss +611 -0
  212. package/dist/assets/themes/bootstrap/scss/_root.scss +187 -0
  213. package/dist/assets/themes/bootstrap/scss/_spinners.scss +85 -0
  214. package/dist/assets/themes/bootstrap/scss/_tables.scss +171 -0
  215. package/dist/assets/themes/bootstrap/scss/_toasts.scss +73 -0
  216. package/dist/assets/themes/bootstrap/scss/_tooltip.scss +119 -0
  217. package/dist/assets/themes/bootstrap/scss/_transitions.scss +27 -0
  218. package/dist/assets/themes/bootstrap/scss/_type.scss +106 -0
  219. package/dist/assets/themes/bootstrap/scss/_utilities.scss +806 -0
  220. package/dist/assets/themes/bootstrap/scss/_variables-dark.scss +102 -0
  221. package/dist/assets/themes/bootstrap/scss/_variables.scss +1753 -0
  222. package/dist/assets/themes/bootstrap/scss/bootstrap-grid.scss +62 -0
  223. package/dist/assets/themes/bootstrap/scss/bootstrap-reboot.scss +10 -0
  224. package/dist/assets/themes/bootstrap/scss/bootstrap-utilities.scss +19 -0
  225. package/dist/assets/themes/bootstrap/scss/bootstrap.scss +52 -0
  226. package/dist/assets/themes/bootstrap/scss/forms/_floating-labels.scss +97 -0
  227. package/dist/assets/themes/bootstrap/scss/forms/_form-check.scss +189 -0
  228. package/dist/assets/themes/bootstrap/scss/forms/_form-control.scss +214 -0
  229. package/dist/assets/themes/bootstrap/scss/forms/_form-range.scss +91 -0
  230. package/dist/assets/themes/bootstrap/scss/forms/_form-select.scss +80 -0
  231. package/dist/assets/themes/bootstrap/scss/forms/_form-text.scss +11 -0
  232. package/dist/assets/themes/bootstrap/scss/forms/_input-group.scss +132 -0
  233. package/dist/assets/themes/bootstrap/scss/forms/_labels.scss +36 -0
  234. package/dist/assets/themes/bootstrap/scss/forms/_validation.scss +12 -0
  235. package/dist/assets/themes/bootstrap/scss/helpers/_clearfix.scss +3 -0
  236. package/dist/assets/themes/bootstrap/scss/helpers/_color-bg.scss +7 -0
  237. package/dist/assets/themes/bootstrap/scss/helpers/_colored-links.scss +30 -0
  238. package/dist/assets/themes/bootstrap/scss/helpers/_focus-ring.scss +5 -0
  239. package/dist/assets/themes/bootstrap/scss/helpers/_icon-link.scss +25 -0
  240. package/dist/assets/themes/bootstrap/scss/helpers/_position.scss +36 -0
  241. package/dist/assets/themes/bootstrap/scss/helpers/_ratio.scss +26 -0
  242. package/dist/assets/themes/bootstrap/scss/helpers/_stacks.scss +15 -0
  243. package/dist/assets/themes/bootstrap/scss/helpers/_stretched-link.scss +15 -0
  244. package/dist/assets/themes/bootstrap/scss/helpers/_text-truncation.scss +7 -0
  245. package/dist/assets/themes/bootstrap/scss/helpers/_visually-hidden.scss +8 -0
  246. package/dist/assets/themes/bootstrap/scss/helpers/_vr.scss +8 -0
  247. package/dist/assets/themes/bootstrap/scss/mixins/_alert.scss +18 -0
  248. package/dist/assets/themes/bootstrap/scss/mixins/_backdrop.scss +14 -0
  249. package/dist/assets/themes/bootstrap/scss/mixins/_banner.scss +7 -0
  250. package/dist/assets/themes/bootstrap/scss/mixins/_border-radius.scss +78 -0
  251. package/dist/assets/themes/bootstrap/scss/mixins/_box-shadow.scss +18 -0
  252. package/dist/assets/themes/bootstrap/scss/mixins/_breakpoints.scss +127 -0
  253. package/dist/assets/themes/bootstrap/scss/mixins/_buttons.scss +70 -0
  254. package/dist/assets/themes/bootstrap/scss/mixins/_caret.scss +69 -0
  255. package/dist/assets/themes/bootstrap/scss/mixins/_clearfix.scss +9 -0
  256. package/dist/assets/themes/bootstrap/scss/mixins/_color-mode.scss +21 -0
  257. package/dist/assets/themes/bootstrap/scss/mixins/_color-scheme.scss +7 -0
  258. package/dist/assets/themes/bootstrap/scss/mixins/_container.scss +11 -0
  259. package/dist/assets/themes/bootstrap/scss/mixins/_deprecate.scss +10 -0
  260. package/dist/assets/themes/bootstrap/scss/mixins/_forms.scss +163 -0
  261. package/dist/assets/themes/bootstrap/scss/mixins/_gradients.scss +47 -0
  262. package/dist/assets/themes/bootstrap/scss/mixins/_grid.scss +151 -0
  263. package/dist/assets/themes/bootstrap/scss/mixins/_image.scss +16 -0
  264. package/dist/assets/themes/bootstrap/scss/mixins/_list-group.scss +26 -0
  265. package/dist/assets/themes/bootstrap/scss/mixins/_lists.scss +7 -0
  266. package/dist/assets/themes/bootstrap/scss/mixins/_pagination.scss +10 -0
  267. package/dist/assets/themes/bootstrap/scss/mixins/_reset-text.scss +17 -0
  268. package/dist/assets/themes/bootstrap/scss/mixins/_resize.scss +6 -0
  269. package/dist/assets/themes/bootstrap/scss/mixins/_table-variants.scss +24 -0
  270. package/dist/assets/themes/bootstrap/scss/mixins/_text-truncate.scss +8 -0
  271. package/dist/assets/themes/bootstrap/scss/mixins/_transition.scss +26 -0
  272. package/dist/assets/themes/bootstrap/scss/mixins/_utilities.scss +97 -0
  273. package/dist/assets/themes/bootstrap/scss/mixins/_visually-hidden.scss +38 -0
  274. package/dist/assets/themes/bootstrap/scss/tests/jasmine.js +16 -0
  275. package/dist/assets/themes/bootstrap/scss/tests/mixins/_auto-import-of-variables-dark.test.scss +7 -0
  276. package/dist/assets/themes/bootstrap/scss/tests/mixins/_color-modes.test.scss +69 -0
  277. package/dist/assets/themes/bootstrap/scss/tests/mixins/_media-query-color-mode-full.test.scss +8 -0
  278. package/dist/assets/themes/bootstrap/scss/tests/mixins/_utilities.test.scss +393 -0
  279. package/dist/assets/themes/bootstrap/scss/tests/sass-true/register.js +14 -0
  280. package/dist/assets/themes/bootstrap/scss/tests/sass-true/runner.js +17 -0
  281. package/dist/assets/themes/bootstrap/scss/tests/utilities/_api.test.scss +75 -0
  282. package/dist/assets/themes/bootstrap/scss/utilities/_api.scss +47 -0
  283. package/dist/assets/themes/bootstrap/scss/vendor/_rfs.scss +348 -0
  284. package/dist/assets/themes/classy/README.md +89 -0
  285. package/dist/assets/themes/classy/_config.scss +245 -0
  286. package/dist/assets/themes/classy/_theme.js +31 -0
  287. package/dist/assets/themes/classy/_theme.scss +57 -0
  288. package/dist/assets/themes/classy/css/app/_panels.scss +183 -0
  289. package/dist/assets/themes/classy/css/base/_fonts.scss +79 -0
  290. package/dist/assets/themes/classy/css/base/_no-raise.scss +49 -0
  291. package/dist/assets/themes/classy/css/base/_root.scss +113 -0
  292. package/dist/assets/themes/classy/css/base/_typography.scss +154 -0
  293. package/dist/assets/themes/classy/css/base/_utilities.scss +284 -0
  294. package/dist/assets/themes/classy/css/components/_alerts.scss +51 -0
  295. package/dist/assets/themes/classy/css/components/_badges.scss +46 -0
  296. package/dist/assets/themes/classy/css/components/_buttons.scss +175 -0
  297. package/dist/assets/themes/classy/css/components/_cards.scss +41 -0
  298. package/dist/assets/themes/classy/css/components/_dropdowns.scss +48 -0
  299. package/dist/assets/themes/classy/css/components/_forms.scss +171 -0
  300. package/dist/assets/themes/classy/css/components/_receipt.scss +45 -0
  301. package/dist/assets/themes/classy/css/layout/_footer.scss +298 -0
  302. package/dist/assets/themes/classy/css/layout/_general.scss +209 -0
  303. package/dist/assets/themes/classy/css/layout/_nav.scss +154 -0
  304. package/dist/assets/themes/classy/css/layout/_shell.scss +458 -0
  305. package/dist/assets/themes/classy/css/marketing/_bento.scss +238 -0
  306. package/dist/assets/themes/classy/css/marketing/_content.scss +1328 -0
  307. package/dist/assets/themes/classy/css/marketing/_downloads.scss +246 -0
  308. package/dist/assets/themes/classy/css/marketing/_hero.scss +311 -0
  309. package/dist/assets/themes/classy/css/marketing/_sections.scss +649 -0
  310. package/dist/assets/themes/classy/css/pages/404/index.scss +67 -0
  311. package/dist/assets/themes/classy/css/pages/_auth.scss +235 -0
  312. package/dist/assets/themes/classy/css/pages/admin/firebase/index.scss +22 -0
  313. package/dist/assets/themes/classy/css/pages/blog/[slug].scss +56 -0
  314. package/dist/assets/themes/classy/css/pages/cookies.scss +2 -0
  315. package/dist/assets/themes/classy/css/pages/dashboard/account/index.scss +31 -0
  316. package/dist/assets/themes/classy/css/pages/feedback/index.scss +39 -0
  317. package/dist/assets/themes/classy/css/pages/legal/_document.scss +192 -0
  318. package/dist/assets/themes/classy/css/pages/payment/checkout/index.scss +585 -0
  319. package/dist/assets/themes/classy/css/pages/payment/confirmation/index.scss +9 -0
  320. package/dist/assets/themes/classy/css/pages/privacy.scss +2 -0
  321. package/dist/assets/themes/classy/css/pages/status/index.scss +164 -0
  322. package/dist/assets/themes/classy/css/pages/terms.scss +2 -0
  323. package/dist/assets/themes/classy/css/pages/updates/index.scss +128 -0
  324. package/dist/assets/themes/classy/fonts/inter-italic-latin-ext.woff2 +0 -0
  325. package/dist/assets/themes/classy/fonts/inter-italic-latin.woff2 +0 -0
  326. package/dist/assets/themes/classy/fonts/inter-normal-latin-ext.woff2 +0 -0
  327. package/dist/assets/themes/classy/fonts/inter-normal-latin.woff2 +0 -0
  328. package/dist/assets/themes/classy/fonts/newsreader-italic-latin-ext.woff2 +0 -0
  329. package/dist/assets/themes/classy/fonts/newsreader-italic-latin.woff2 +0 -0
  330. package/dist/assets/themes/classy/fonts/newsreader-normal-latin-ext.woff2 +0 -0
  331. package/dist/assets/themes/classy/fonts/newsreader-normal-latin.woff2 +0 -0
  332. package/dist/assets/themes/classy/js/hero-demo-form.js +56 -0
  333. package/dist/assets/themes/neobrutalism/README.md +118 -0
  334. package/dist/assets/themes/neobrutalism/_config.scss +139 -0
  335. package/dist/assets/themes/neobrutalism/_layouts/frontend/core/base.html +30 -0
  336. package/dist/assets/themes/neobrutalism/_layouts/frontend/pages/index.html +275 -0
  337. package/dist/assets/themes/neobrutalism/_theme.js +24 -0
  338. package/dist/assets/themes/neobrutalism/_theme.scss +61 -0
  339. package/dist/assets/themes/neobrutalism/css/base/_mixins.scss +46 -0
  340. package/dist/assets/themes/neobrutalism/css/base/_root.scss +169 -0
  341. package/dist/assets/themes/neobrutalism/css/base/_typography.scss +61 -0
  342. package/dist/assets/themes/neobrutalism/css/base/_utilities.scss +89 -0
  343. package/dist/assets/themes/neobrutalism/css/components/_billing-toggle.scss +74 -0
  344. package/dist/assets/themes/neobrutalism/css/components/_buttons.scss +148 -0
  345. package/dist/assets/themes/neobrutalism/css/components/_cards.scss +47 -0
  346. package/dist/assets/themes/neobrutalism/css/components/_forms.scss +88 -0
  347. package/dist/assets/themes/neobrutalism/css/components/_marketing.scss +244 -0
  348. package/dist/assets/themes/neobrutalism/css/layout/_general.scss +213 -0
  349. package/dist/assets/themes/neobrutalism/css/layout/_navigation.scss +171 -0
  350. package/dist/assets/themes/neobrutalism/css/pages/index.scss +203 -0
  351. package/dist/assets/themes/neobrutalism/css/pages/pricing/index.scss +58 -0
  352. package/dist/assets/themes/neobrutalism/css/pages/test/libraries/layers/index.scss +7 -0
  353. package/dist/assets/themes/neobrutalism/js/pages/test/libraries/layers/index.js +9 -0
  354. package/dist/assets/themes/newsflash/README.md +117 -0
  355. package/dist/assets/themes/newsflash/_components/heading/lede/component.html +14 -0
  356. package/dist/assets/themes/newsflash/_components/heading/lede/component.json5 +23 -0
  357. package/dist/assets/themes/newsflash/_components/heading/rule-head/component.html +17 -0
  358. package/dist/assets/themes/newsflash/_components/heading/rule-head/component.json5 +23 -0
  359. package/dist/assets/themes/newsflash/_components/news/byline/component.html +12 -0
  360. package/dist/assets/themes/newsflash/_components/news/byline/component.json5 +18 -0
  361. package/dist/assets/themes/newsflash/_components/news/story-card/component.html +25 -0
  362. package/dist/assets/themes/newsflash/_components/news/story-card/component.json5 +21 -0
  363. package/dist/assets/themes/newsflash/_config.scss +147 -0
  364. package/dist/assets/themes/newsflash/_layouts/frontend/core/base.html +51 -0
  365. package/dist/assets/themes/newsflash/_layouts/frontend/pages/blog/index.html +299 -0
  366. package/dist/assets/themes/newsflash/_layouts/frontend/pages/blog/post.html +235 -0
  367. package/dist/assets/themes/newsflash/_layouts/frontend/pages/index.html +328 -0
  368. package/dist/assets/themes/newsflash/_sections/marketing/desks/section.html +39 -0
  369. package/dist/assets/themes/newsflash/_sections/marketing/desks/section.json5 +49 -0
  370. package/dist/assets/themes/newsflash/_sections/marketing/newsletter-cta/section.html +103 -0
  371. package/dist/assets/themes/newsflash/_sections/marketing/newsletter-cta/section.json5 +50 -0
  372. package/dist/assets/themes/newsflash/_sections/marketing/rundown/section.html +28 -0
  373. package/dist/assets/themes/newsflash/_sections/marketing/rundown/section.json5 +40 -0
  374. package/dist/assets/themes/newsflash/_theme.js +24 -0
  375. package/dist/assets/themes/newsflash/_theme.scss +70 -0
  376. package/dist/assets/themes/newsflash/css/base/_fonts.scss +80 -0
  377. package/dist/assets/themes/newsflash/css/base/_mixins.scss +51 -0
  378. package/dist/assets/themes/newsflash/css/base/_root.scss +257 -0
  379. package/dist/assets/themes/newsflash/css/base/_typography.scss +49 -0
  380. package/dist/assets/themes/newsflash/css/base/_utilities.scss +122 -0
  381. package/dist/assets/themes/newsflash/css/components/_badges.scss +65 -0
  382. package/dist/assets/themes/newsflash/css/components/_billing-toggle.scss +61 -0
  383. package/dist/assets/themes/newsflash/css/components/_buttons.scss +139 -0
  384. package/dist/assets/themes/newsflash/css/components/_cards.scss +47 -0
  385. package/dist/assets/themes/newsflash/css/components/_editorial.scss +173 -0
  386. package/dist/assets/themes/newsflash/css/components/_forms.scss +75 -0
  387. package/dist/assets/themes/newsflash/css/components/_infinite-scroll.scss +102 -0
  388. package/dist/assets/themes/newsflash/css/components/_panels.scss +156 -0
  389. package/dist/assets/themes/newsflash/css/components/_ticker.scss +67 -0
  390. package/dist/assets/themes/newsflash/css/layout/_general.scss +330 -0
  391. package/dist/assets/themes/newsflash/css/layout/_navigation.scss +168 -0
  392. package/dist/assets/themes/newsflash/css/pages/404/index.scss +79 -0
  393. package/dist/assets/themes/newsflash/css/pages/blog/[slug].scss +186 -0
  394. package/dist/assets/themes/newsflash/css/pages/blog/index.scss +17 -0
  395. package/dist/assets/themes/newsflash/css/pages/index.scss +157 -0
  396. package/dist/assets/themes/newsflash/css/pages/pricing/index.scss +55 -0
  397. package/dist/assets/themes/newsflash/css/pages/test/libraries/layers/index.scss +7 -0
  398. package/dist/assets/themes/newsflash/fonts/fraunces-italic-latin-ext.woff2 +0 -0
  399. package/dist/assets/themes/newsflash/fonts/fraunces-italic-latin.woff2 +0 -0
  400. package/dist/assets/themes/newsflash/fonts/fraunces-normal-latin-ext.woff2 +0 -0
  401. package/dist/assets/themes/newsflash/fonts/fraunces-normal-latin.woff2 +0 -0
  402. package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-italic-latin-ext.woff2 +0 -0
  403. package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-italic-latin.woff2 +0 -0
  404. package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-normal-latin-ext.woff2 +0 -0
  405. package/dist/assets/themes/newsflash/fonts/schibsted-grotesk-normal-latin.woff2 +0 -0
  406. package/dist/assets/themes/newsflash/js/pages/blog/[slug].js +29 -0
  407. package/dist/assets/themes/newsflash/js/pages/test/libraries/layers/index.js +9 -0
  408. package/dist/background.js +684 -0
  409. package/dist/build.js +268 -0
  410. package/dist/cli-run.js +25 -0
  411. package/dist/cli.js +30 -0
  412. package/dist/commands/build.js +67 -0
  413. package/dist/commands/clean.js +29 -0
  414. package/dist/commands/deploy.js +97 -0
  415. package/dist/commands/install.js +58 -0
  416. package/dist/commands/lib/dependencies.js +33 -0
  417. package/dist/commands/lib/deploy-precheck.js +57 -0
  418. package/dist/commands/lib/ensure-target.js +151 -0
  419. package/dist/commands/lib/push-secrets.js +60 -0
  420. package/dist/commands/migrate.js +77 -0
  421. package/dist/commands/test.js +110 -0
  422. package/dist/commands/update.js +21 -0
  423. package/dist/commands/version.js +12 -0
  424. package/dist/config/manifest.json +117 -0
  425. package/dist/config/page-template.html +21 -0
  426. package/dist/content.js +37 -0
  427. package/dist/defaults/.github/workflows/publish.yml +86 -0
  428. package/dist/defaults/.nvmrc +1 -0
  429. package/dist/defaults/.vscode/settings.json +8 -0
  430. package/dist/defaults/AGENTS.md +113 -0
  431. package/dist/defaults/CHANGELOG.md +15 -0
  432. package/dist/defaults/CLAUDE.md +1 -0
  433. package/dist/defaults/_.gitignore +75 -0
  434. package/dist/defaults/config/description.md +46 -0
  435. package/dist/defaults/config/messages.json +20 -0
  436. package/dist/defaults/config/omega.json5 +64 -0
  437. package/dist/defaults/docs/README.md +17 -0
  438. package/dist/defaults/gulpfile.js +6 -0
  439. package/dist/defaults/hooks/build/post.js +8 -0
  440. package/dist/defaults/hooks/build/pre.js +8 -0
  441. package/dist/defaults/src/assets/css/bundles/.gitkeep +0 -0
  442. package/dist/defaults/src/assets/css/components/content/index.scss +11 -0
  443. package/dist/defaults/src/assets/css/components/offscreen/index.scss +4 -0
  444. package/dist/defaults/src/assets/css/components/options/index.scss +14 -0
  445. package/dist/defaults/src/assets/css/components/pages/index.scss +10 -0
  446. package/dist/defaults/src/assets/css/components/popup/index.scss +10 -0
  447. package/dist/defaults/src/assets/css/components/sidepanel/index.scss +6 -0
  448. package/dist/defaults/src/assets/css/main.scss +32 -0
  449. package/dist/defaults/src/assets/images/.gitkeep +0 -0
  450. package/dist/defaults/src/assets/js/components/background/index.js +25 -0
  451. package/dist/defaults/src/assets/js/components/content/index.js +22 -0
  452. package/dist/defaults/src/assets/js/components/offscreen/index.js +25 -0
  453. package/dist/defaults/src/assets/js/components/options/index.js +22 -0
  454. package/dist/defaults/src/assets/js/components/pages/index.js +22 -0
  455. package/dist/defaults/src/assets/js/components/popup/index.js +22 -0
  456. package/dist/defaults/src/assets/js/components/sidepanel/index.js +20 -0
  457. package/dist/defaults/src/assets/vendor/.gitkeep +0 -0
  458. package/dist/defaults/src/manifest.json +131 -0
  459. package/dist/defaults/src/views/offscreen/index.html +3 -0
  460. package/dist/defaults/src/views/options/index.html +8 -0
  461. package/dist/defaults/src/views/pages/index.html +10 -0
  462. package/dist/defaults/src/views/popup/index.html +4 -0
  463. package/dist/defaults/src/views/sidepanel/index.html +4 -0
  464. package/dist/defaults/test/README.md +41 -0
  465. package/dist/defaults/test/_init.js +10 -0
  466. package/dist/defaults/test/boot/externally-connectable.test.js +28 -0
  467. package/dist/gulp/config/locales.js +12 -0
  468. package/dist/gulp/main.js +78 -0
  469. package/dist/gulp/tasks/_.js +18 -0
  470. package/dist/gulp/tasks/audit.js +222 -0
  471. package/dist/gulp/tasks/bundle.js +687 -0
  472. package/dist/gulp/tasks/defaults.js +281 -0
  473. package/dist/gulp/tasks/distribute.js +172 -0
  474. package/dist/gulp/tasks/fontawesome.js +25 -0
  475. package/dist/gulp/tasks/html.js +163 -0
  476. package/dist/gulp/tasks/icons.js +126 -0
  477. package/dist/gulp/tasks/package.js +742 -0
  478. package/dist/gulp/tasks/publish.js +417 -0
  479. package/dist/gulp/tasks/sass.js +252 -0
  480. package/dist/gulp/tasks/serve.js +103 -0
  481. package/dist/gulp/tasks/translate.js +252 -0
  482. package/dist/gulp/tasks/utils/build-json.js +43 -0
  483. package/dist/gulp/tasks/utils/template-transform.js +50 -0
  484. package/dist/gulp/templates/BUILD_INSTRUCTIONS.md +69 -0
  485. package/dist/index.js +46 -0
  486. package/dist/lib/affiliatizer.js +224 -0
  487. package/dist/lib/analytics.js +26 -0
  488. package/dist/lib/auth-helpers.js +213 -0
  489. package/dist/lib/extension.js +116 -0
  490. package/dist/lib/icons.js +36 -0
  491. package/dist/lib/logger-lite.js +35 -0
  492. package/dist/lib/logger.js +4 -0
  493. package/dist/lib/messaging.js +48 -0
  494. package/dist/lib/safe-install.js +4 -0
  495. package/dist/lib/theme.js +73 -0
  496. package/dist/lib/verts.js +68 -0
  497. package/dist/offscreen.js +31 -0
  498. package/dist/omega-bin.js +6 -0
  499. package/dist/options.js +80 -0
  500. package/dist/page.js +80 -0
  501. package/dist/popup.js +80 -0
  502. package/dist/sidepanel.js +80 -0
  503. package/dist/test/assert.js +4 -0
  504. package/dist/test/fixtures/consumer-extension/dist/background.js +23 -0
  505. package/dist/test/fixtures/consumer-extension/dist/manifest.json +20 -0
  506. package/dist/test/fixtures/consumer-extension/dist/options.html +10 -0
  507. package/dist/test/fixtures/consumer-extension/dist/popup.bundle.js +5 -0
  508. package/dist/test/fixtures/consumer-extension/dist/popup.html +12 -0
  509. package/dist/test/harness/extension/background.js +26 -0
  510. package/dist/test/harness/extension/manifest.json +27 -0
  511. package/dist/test/harness/extension/options.html +12 -0
  512. package/dist/test/harness/extension/popup.html +12 -0
  513. package/dist/test/harness/extension/sidepanel.html +12 -0
  514. package/dist/test/index.js +63 -0
  515. package/dist/test/runner.js +99 -0
  516. package/dist/test/runners/boot.js +221 -0
  517. package/dist/test/runners/chromium.js +391 -0
  518. package/dist/test/runners/helpers.js +24 -0
  519. package/dist/test/suites/background/messaging.test.js +44 -0
  520. package/dist/test/suites/background/storage.test.js +46 -0
  521. package/dist/test/suites/background/sw-context.test.js +49 -0
  522. package/dist/test/suites/boot/build-json-bake.test.js +80 -0
  523. package/dist/test/suites/boot/extension-loads.test.js +58 -0
  524. package/dist/test/suites/build/affiliatizer.test.js +64 -0
  525. package/dist/test/suites/build/app-launch.test.js +65 -0
  526. package/dist/test/suites/build/attach-log-file.test.js +99 -0
  527. package/dist/test/suites/build/auth-emulator-gate.test.js +118 -0
  528. package/dist/test/suites/build/auth-triggers.test.js +71 -0
  529. package/dist/test/suites/build/boot-discovery.test.js +134 -0
  530. package/dist/test/suites/build/boot-timeout.test.js +92 -0
  531. package/dist/test/suites/build/build-error-notification.test.js +122 -0
  532. package/dist/test/suites/build/build-json-bake.test.js +302 -0
  533. package/dist/test/suites/build/build-verb.test.js +138 -0
  534. package/dist/test/suites/build/bundle-targets.test.js +66 -0
  535. package/dist/test/suites/build/cache-warming.test.js +44 -0
  536. package/dist/test/suites/build/cli.test.js +150 -0
  537. package/dist/test/suites/build/default-boot-test.test.js +100 -0
  538. package/dist/test/suites/build/defaults-scaffold.test.js +287 -0
  539. package/dist/test/suites/build/deploy-dispatch.test.js +76 -0
  540. package/dist/test/suites/build/distribute-task.test.js +111 -0
  541. package/dist/test/suites/build/ensure-target.test.js +141 -0
  542. package/dist/test/suites/build/env-delivery.test.js +239 -0
  543. package/dist/test/suites/build/env-watch.test.js +86 -0
  544. package/dist/test/suites/build/expect.test.js +48 -0
  545. package/dist/test/suites/build/exports.test.js +53 -0
  546. package/dist/test/suites/build/extension-fallback.test.js +82 -0
  547. package/dist/test/suites/build/framework-deps.test.js +176 -0
  548. package/dist/test/suites/build/global-handlers.test.js +70 -0
  549. package/dist/test/suites/build/icon-sheet.test.js +74 -0
  550. package/dist/test/suites/build/logger-lite.test.js +61 -0
  551. package/dist/test/suites/build/manager.test.js +249 -0
  552. package/dist/test/suites/build/mode-helpers.test.js +136 -0
  553. package/dist/test/suites/build/omega-shell.test.js +103 -0
  554. package/dist/test/suites/build/omega-tokens.test.js +76 -0
  555. package/dist/test/suites/build/package-task.test.js +831 -0
  556. package/dist/test/suites/build/setup-scripts.test.js +172 -0
  557. package/dist/test/suites/build/strip-dev-blocks.test.js +122 -0
  558. package/dist/test/suites/build/template-replace.test.js +116 -0
  559. package/dist/test/suites/build/test-discovery.test.js +64 -0
  560. package/dist/test/suites/build/test-target-no-match.test.js +119 -0
  561. package/dist/test/suites/build/theme-resolve.test.js +115 -0
  562. package/dist/test/suites/build/translate.test.js +85 -0
  563. package/dist/test/suites/build/url-helpers.test.js +119 -0
  564. package/dist/test/suites/build/verb-logs.test.js +43 -0
  565. package/dist/test/suites/build/verts-binding.test.js +67 -0
  566. package/dist/test/suites/build/wakeup-ping.test.js +90 -0
  567. package/dist/test/suites/build/wave5-messenger.test.js +80 -0
  568. package/dist/test/suites/view/options-and-sidepanel.test.js +16 -0
  569. package/dist/test/suites/view/popup-context.test.js +53 -0
  570. package/dist/test/suites/view/sidepanel.test.js +16 -0
  571. package/dist/test/utils/extended-mode-warning.js +13 -0
  572. package/dist/utils/attach-log-file.js +4 -0
  573. package/dist/utils/mode-helpers.js +117 -0
  574. package/dist/utils/url-helpers.js +69 -0
  575. package/dist/vendor/account/engine.js +182 -0
  576. package/dist/vendor/account/features.js +220 -0
  577. package/dist/vendor/account/index.js +53 -0
  578. package/dist/vendor/account/schema.js +272 -0
  579. package/dist/vendor/account/subscription.js +38 -0
  580. package/dist/vendor/config/company.js +31 -0
  581. package/dist/vendor/config/defaults.js +173 -0
  582. package/dist/vendor/config/demo.js +18 -0
  583. package/dist/vendor/config/desktop-artifacts.js +110 -0
  584. package/dist/vendor/config/edit.js +769 -0
  585. package/dist/vendor/config/env-delivery.js +145 -0
  586. package/dist/vendor/config/env-rules.js +93 -0
  587. package/dist/vendor/config/env-schema.js +1078 -0
  588. package/dist/vendor/config/env.js +445 -0
  589. package/dist/vendor/config/hooks.js +97 -0
  590. package/dist/vendor/config/index.js +237 -0
  591. package/dist/vendor/config/instances.js +208 -0
  592. package/dist/vendor/config/load.js +490 -0
  593. package/dist/vendor/config/merge.js +68 -0
  594. package/dist/vendor/config/order.js +139 -0
  595. package/dist/vendor/config/ports.js +374 -0
  596. package/dist/vendor/config/providers.js +32 -0
  597. package/dist/vendor/config/repo.js +142 -0
  598. package/dist/vendor/config/retired-keys.js +430 -0
  599. package/dist/vendor/config/schema.js +1610 -0
  600. package/dist/vendor/config/secrets.js +50 -0
  601. package/dist/vendor/config/seed.js +34 -0
  602. package/dist/vendor/config/site-global.js +205 -0
  603. package/dist/vendor/config/validate.js +554 -0
  604. package/dist/vendor/config/winback.js +61 -0
  605. package/dist/vendor/devkit/actions-secrets.js +145 -0
  606. package/dist/vendor/devkit/attach-log-file.js +262 -0
  607. package/dist/vendor/devkit/bundle.js +292 -0
  608. package/dist/vendor/devkit/ci-workflows.js +520 -0
  609. package/dist/vendor/devkit/clean-dirs.js +28 -0
  610. package/dist/vendor/devkit/cli-router.js +156 -0
  611. package/dist/vendor/devkit/defaults-engine.js +372 -0
  612. package/dist/vendor/devkit/deploy-precheck.js +54 -0
  613. package/dist/vendor/devkit/deploy-record.js +180 -0
  614. package/dist/vendor/devkit/deploy.js +286 -0
  615. package/dist/vendor/devkit/empty-modules-plugin.js +64 -0
  616. package/dist/vendor/devkit/env-watch.js +132 -0
  617. package/dist/vendor/devkit/framework-deps.js +46 -0
  618. package/dist/vendor/devkit/icons.js +178 -0
  619. package/dist/vendor/devkit/license.js +155 -0
  620. package/dist/vendor/devkit/local.js +1905 -0
  621. package/dist/vendor/devkit/logger.js +128 -0
  622. package/dist/vendor/devkit/merge-line-files.js +296 -0
  623. package/dist/vendor/devkit/npm-registry.js +52 -0
  624. package/dist/vendor/devkit/omega-bin.js +345 -0
  625. package/dist/vendor/devkit/safe-install.js +18 -0
  626. package/dist/vendor/devkit/scaffold-guard.js +96 -0
  627. package/dist/vendor/devkit/strip-dev-blocks-plugin.js +29 -0
  628. package/dist/vendor/devkit/strip-dev-blocks.js +32 -0
  629. package/dist/vendor/devkit/target-dependencies.js +137 -0
  630. package/dist/vendor/devkit/target-secrets.js +165 -0
  631. package/dist/vendor/devkit/test/assert.js +120 -0
  632. package/dist/vendor/devkit/test/define-cases.js +104 -0
  633. package/dist/vendor/devkit/test/extended-mode-warning.js +22 -0
  634. package/dist/vendor/devkit/test/runner-core.js +554 -0
  635. package/dist/vendor/devkit/test/scope.js +162 -0
  636. package/dist/vendor/devkit/translate/cache.js +84 -0
  637. package/dist/vendor/devkit/translate/engine.js +243 -0
  638. package/dist/vendor/devkit/translate/index.js +49 -0
  639. package/dist/vendor/devkit/translate/languages.js +134 -0
  640. package/dist/vendor/devkit/translate/providers.js +188 -0
  641. package/dist/vendor/devkit/update.js +569 -0
  642. package/docs/affiliatizer.md +81 -0
  643. package/docs/audit.md +67 -0
  644. package/docs/auth.md +149 -0
  645. package/docs/build-system.md +176 -0
  646. package/docs/cdp-debugging.md +42 -0
  647. package/docs/cli.md +73 -0
  648. package/docs/common-mistakes.md +10 -0
  649. package/docs/components.md +87 -0
  650. package/docs/css.md +133 -0
  651. package/docs/defaults.md +72 -0
  652. package/docs/environment-detection.md +79 -0
  653. package/docs/extension.md +93 -0
  654. package/docs/hooks.md +111 -0
  655. package/docs/icons.md +47 -0
  656. package/docs/index.md +291 -0
  657. package/docs/logging.md +33 -0
  658. package/docs/managers.md +100 -0
  659. package/docs/offscreen.md +57 -0
  660. package/docs/publishing.md +182 -0
  661. package/docs/shared/agent-docs.md +89 -0
  662. package/docs/shared/analytics.md +612 -0
  663. package/docs/shared/brands.md +51 -0
  664. package/docs/shared/breaking-changes.md +497 -0
  665. package/docs/shared/config.md +1387 -0
  666. package/docs/shared/deploys.md +215 -0
  667. package/docs/shared/icons.md +201 -0
  668. package/docs/shared/local-dev.md +147 -0
  669. package/docs/shared/logging.md +202 -0
  670. package/docs/shared/monitoring.md +153 -0
  671. package/docs/shared/publishing.md +183 -0
  672. package/docs/shared/rulings.md +34 -0
  673. package/docs/shared/testing.md +147 -0
  674. package/docs/shared/theming.md +604 -0
  675. package/docs/shared/translation.md +291 -0
  676. package/docs/shared/updates.md +61 -0
  677. package/docs/templating.md +66 -0
  678. package/docs/test-boot-layer.md +143 -0
  679. package/docs/test-framework.md +411 -0
  680. package/docs/themes.md +89 -0
  681. package/docs/translations.md +73 -0
  682. package/docs/verts.md +67 -0
  683. package/docs/xss-prevention.md +95 -0
  684. package/package.json +159 -0
@@ -0,0 +1,769 @@
1
+ /**
2
+ * Comment-preserving omega.json5 edits — the config-writeback engine.
3
+ *
4
+ * Services resolve IDs against external APIs (SendGrid list, Beehiiv
5
+ * publication, payment product IDs, the Firebase SDK config) and write them
6
+ * back into config/omega.json5, the file's ONE authoritative home. The file
7
+ * is human-edited JSON5 — comments, blank lines, key order, and quote style
8
+ * all carry meaning — so writeback is surgical text surgery, not a
9
+ * re-stringify: only the edited value spans change; every other byte
10
+ * survives. (omega-manager's serializer re-stringified the whole config and
11
+ * lost comments; this replaces it outright.)
12
+ *
13
+ * Mechanics: tokenize (strings / punctuation / atoms; comments and
14
+ * whitespace are never tokenized, so they persist implicitly) → recursive
15
+ * descent builds a span tree with absolute offsets → each edit either
16
+ * replaces the leaf's value span or inserts a new property (missing
17
+ * intermediate objects are created inside the inserted text). Edits whose
18
+ * value already matches are skipped entirely, so reruns are byte-identical.
19
+ * After every edit the result must JSON5-parse and carry the requested value
20
+ * at the requested path — any miss throws, so callers can never write a
21
+ * corrupted config.
22
+ *
23
+ * Paths are dot-notation; numeric segments index arrays, and a matcher
24
+ * segment selects an array element by one of its own keys —
25
+ * `payment.products[id=plus].stripe.productId` — so writes self-locate in
26
+ * the file being edited instead of trusting an index computed from a merged
27
+ * config. Array elements are user-authored and never created here. Inserted
28
+ * text uses the house style: unquoted keys, JSON.stringify strings,
29
+ * multi-line objects with trailing commas.
30
+ */
31
+
32
+ const fs = require('node:fs');
33
+ const { isDeepStrictEqual } = require('node:util');
34
+ const JSON5 = require('json5');
35
+
36
+ const { resolveConfigPath, FILE_NAME } = require('./load.js');
37
+
38
+ const IDENTIFIER_KEY = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
39
+ const MATCHER_SEGMENT = /^([^[]+)\[([A-Za-z0-9_$]+)=([^\]]*)\]$/;
40
+ const DEFAULT_INDENT_UNIT = ' ';
41
+ // Where a guiding comment wraps — the whole line, indent and `// ` included.
42
+ const COMMENT_WIDTH = 80;
43
+
44
+ /**
45
+ * Parse a dot-path into walk steps. A `name[key=value]` segment expands to a
46
+ * key step plus an array-matcher step.
47
+ * @param {string} path - e.g. 'payment.products[id=plus].stripe.productId'
48
+ * @returns {Array<{ type: 'plain', name: string } | { type: 'match', key: string, value: string }>}
49
+ */
50
+ function parsePath(path) {
51
+ const steps = [];
52
+ for (const raw of path.split('.')) {
53
+ const matcher = raw.match(MATCHER_SEGMENT);
54
+ if (matcher) {
55
+ steps.push({ type: 'plain', name: matcher[1] });
56
+ steps.push({ type: 'match', key: matcher[2], value: matcher[3] });
57
+ } else {
58
+ steps.push({ type: 'plain', name: raw });
59
+ }
60
+ }
61
+ return steps;
62
+ }
63
+
64
+ // ─── Tokenizer ───────────────────────────────────────────────────────────────
65
+
66
+ /**
67
+ * Tokenize JSON5 source into structural tokens with absolute spans.
68
+ * Comments and whitespace produce no tokens — edits splice around them.
69
+ * @param {string} source - JSON5 text (already known to parse).
70
+ * @returns {Array<{ type: string, start: number, end: number }>}
71
+ */
72
+ function tokenize(source) {
73
+ const tokens = [];
74
+ let i = 0;
75
+
76
+ while (i < source.length) {
77
+ const ch = source[i];
78
+
79
+ if (/\s/.test(ch)) {
80
+ i += 1;
81
+ continue;
82
+ }
83
+
84
+ if (ch === '/' && source[i + 1] === '/') {
85
+ const lineEnd = source.indexOf('\n', i);
86
+ i = lineEnd === -1 ? source.length : lineEnd;
87
+ continue;
88
+ }
89
+
90
+ if (ch === '/' && source[i + 1] === '*') {
91
+ const blockEnd = source.indexOf('*/', i + 2);
92
+ i = blockEnd === -1 ? source.length : blockEnd + 2;
93
+ continue;
94
+ }
95
+
96
+ if (ch === '"' || ch === "'") {
97
+ const start = i;
98
+ i += 1;
99
+ while (i < source.length) {
100
+ if (source[i] === '\\') {
101
+ i += 2;
102
+ continue;
103
+ }
104
+ if (source[i] === ch) {
105
+ i += 1;
106
+ break;
107
+ }
108
+ i += 1;
109
+ }
110
+ tokens.push({ type: 'string', start, end: i });
111
+ continue;
112
+ }
113
+
114
+ if ('{}[]:,'.includes(ch)) {
115
+ tokens.push({ type: ch, start: i, end: i + 1 });
116
+ i += 1;
117
+ continue;
118
+ }
119
+
120
+ const start = i;
121
+ while (i < source.length && !/[\s{}[\]:,'"/]/.test(source[i])) {
122
+ i += 1;
123
+ }
124
+ tokens.push({ type: 'atom', start, end: i });
125
+ }
126
+
127
+ return tokens;
128
+ }
129
+
130
+ // ─── Span-tree parser ────────────────────────────────────────────────────────
131
+
132
+ /**
133
+ * Decode a key token to its property name ('brand' from brand, 'a b' from 'a b').
134
+ */
135
+ function decodeKey(source, token) {
136
+ const text = source.slice(token.start, token.end);
137
+ return token.type === 'string' ? JSON5.parse(text) : text;
138
+ }
139
+
140
+ /**
141
+ * Recursive descent over tokens; returns { node, next }. Nodes carry
142
+ * absolute spans: objects list entries (key span, value node, trailing
143
+ * comma), arrays list item nodes, primitives are a single span.
144
+ */
145
+ function parseValue(source, tokens, index) {
146
+ const token = tokens[index];
147
+
148
+ if (!token) {
149
+ throw new Error('Unexpected end of config while parsing');
150
+ }
151
+
152
+ if (token.type === '{') {
153
+ const node = { kind: 'object', start: token.start, end: null, closeStart: null, entries: [] };
154
+ let i = index + 1;
155
+
156
+ while (tokens[i] && tokens[i].type !== '}') {
157
+ const keyToken = tokens[i];
158
+ if (keyToken.type !== 'atom' && keyToken.type !== 'string') {
159
+ throw new Error(`Expected object key at offset ${keyToken.start}`);
160
+ }
161
+ if (tokens[i + 1]?.type !== ':') {
162
+ throw new Error(`Expected ':' after key at offset ${keyToken.start}`);
163
+ }
164
+
165
+ const { node: valueNode, next } = parseValue(source, tokens, i + 2);
166
+ const entry = { key: decodeKey(source, keyToken), keyStart: keyToken.start, valueNode, hasComma: false, commaEnd: valueNode.end };
167
+ i = next;
168
+
169
+ if (tokens[i]?.type === ',') {
170
+ entry.hasComma = true;
171
+ entry.commaEnd = tokens[i].end;
172
+ i += 1;
173
+ }
174
+ node.entries.push(entry);
175
+ }
176
+
177
+ if (!tokens[i]) {
178
+ throw new Error('Unclosed object in config');
179
+ }
180
+ node.closeStart = tokens[i].start;
181
+ node.end = tokens[i].end;
182
+ return { node, next: i + 1 };
183
+ }
184
+
185
+ if (token.type === '[') {
186
+ const node = { kind: 'array', start: token.start, end: null, closeStart: null, items: [] };
187
+ let i = index + 1;
188
+
189
+ while (tokens[i] && tokens[i].type !== ']') {
190
+ const { node: itemNode, next } = parseValue(source, tokens, i);
191
+ node.items.push(itemNode);
192
+ i = next;
193
+ if (tokens[i]?.type === ',') {
194
+ i += 1;
195
+ }
196
+ }
197
+
198
+ if (!tokens[i]) {
199
+ throw new Error('Unclosed array in config');
200
+ }
201
+ node.closeStart = tokens[i].start;
202
+ node.end = tokens[i].end;
203
+ return { node, next: i + 1 };
204
+ }
205
+
206
+ if (token.type === 'string' || token.type === 'atom') {
207
+ return { node: { kind: 'primitive', start: token.start, end: token.end }, next: index + 1 };
208
+ }
209
+
210
+ throw new Error(`Unexpected token '${token.type}' at offset ${token.start}`);
211
+ }
212
+
213
+ /**
214
+ * Parse the root object of a config source into a span tree.
215
+ */
216
+ function parseRoot(source) {
217
+ const tokens = tokenize(source);
218
+ const { node } = parseValue(source, tokens, 0);
219
+ if (node.kind !== 'object') {
220
+ throw new Error('Config root must be an object');
221
+ }
222
+ return node;
223
+ }
224
+
225
+ // ─── House-style serializer (inserted text only) ─────────────────────────────
226
+
227
+ /**
228
+ * Serialize a key in house style — unquoted when identifier-safe.
229
+ */
230
+ function serializeKey(key) {
231
+ return IDENTIFIER_KEY.test(key) ? key : JSON.stringify(key);
232
+ }
233
+
234
+ /**
235
+ * Serialize a value for insertion. `indent` is the indentation of the line
236
+ * the value starts on; nested lines add `unit` per depth. `comments` +
237
+ * `path` document the keys INSIDE the inserted value: every key whose full
238
+ * dot-path is in the map gets its comment on the line(s) above it (#478 — a
239
+ * materialized block arrives with the schema's guidance beside each key).
240
+ * Array items carry no path, so nothing inside one is documented.
241
+ */
242
+ function serializeValue(value, indent, unit, comments, path) {
243
+ if (value === null || typeof value !== 'object') {
244
+ return JSON.stringify(value);
245
+ }
246
+
247
+ if (Array.isArray(value)) {
248
+ if (value.length === 0) {
249
+ return '[]';
250
+ }
251
+ const allPrimitives = value.every((item) => item === null || typeof item !== 'object');
252
+ if (allPrimitives) {
253
+ return `[${value.map((item) => JSON.stringify(item)).join(', ')}]`;
254
+ }
255
+ const inner = indent + unit;
256
+ const lines = value.map((item) => `${inner}${serializeValue(item, inner, unit)},`);
257
+ return `[\n${lines.join('\n')}\n${indent}]`;
258
+ }
259
+
260
+ const entries = Object.entries(value);
261
+ if (entries.length === 0) {
262
+ return '{}';
263
+ }
264
+ const inner = indent + unit;
265
+ const lines = entries.map(([key, entry]) => {
266
+ const childPath = path ? `${path}.${key}` : null;
267
+ const doc = childPath && comments ? commentBlock(comments[childPath], inner) : '';
268
+ return `${doc}${inner}${serializeKey(key)}: ${serializeValue(entry, inner, unit, comments, childPath)},`;
269
+ });
270
+ return `{\n${lines.join('\n')}\n${indent}}`;
271
+ }
272
+
273
+ /**
274
+ * Single-line serialization for insertions into single-line objects —
275
+ * `{ id: 'plus' }` gains `stripe: { productId: "prod_X" }` without exploding
276
+ * into a block mid-line.
277
+ */
278
+ function serializeValueInline(value) {
279
+ if (value === null || typeof value !== 'object') {
280
+ return JSON.stringify(value);
281
+ }
282
+ if (Array.isArray(value)) {
283
+ return `[${value.map(serializeValueInline).join(', ')}]`;
284
+ }
285
+ const entries = Object.entries(value);
286
+ if (entries.length === 0) {
287
+ return '{}';
288
+ }
289
+ return `{ ${entries.map(([key, entry]) => `${serializeKey(key)}: ${serializeValueInline(entry)}`).join(', ')} }`;
290
+ }
291
+
292
+ /**
293
+ * Nest the remaining key names into an object so a whole missing branch
294
+ * inserts as one property (marketing → { campaigns: { listId: value } }).
295
+ */
296
+ function nestValue(names, value) {
297
+ return names.reduceRight((acc, name) => ({ [name]: acc }), value);
298
+ }
299
+
300
+ // ─── Layout helpers ──────────────────────────────────────────────────────────
301
+
302
+ /**
303
+ * The whitespace indentation of the line containing `pos`.
304
+ */
305
+ function lineIndentAt(source, pos) {
306
+ const lineStart = source.lastIndexOf('\n', pos - 1) + 1;
307
+ const match = source.slice(lineStart, pos).match(/^[ \t]*/);
308
+ return match ? match[0] : '';
309
+ }
310
+
311
+ /**
312
+ * Detect the file's indent unit from its first indented line (' ' default).
313
+ */
314
+ function detectIndentUnit(source) {
315
+ const match = source.match(/\n([ \t]+)\S/);
316
+ return match ? match[1] : DEFAULT_INDENT_UNIT;
317
+ }
318
+
319
+ // ─── Single-edit application ─────────────────────────────────────────────────
320
+
321
+ /**
322
+ * Wrap a guiding comment into `// ` lines at the given indent (#478 — the
323
+ * manage-run heal documents each block it materializes with the schema's own
324
+ * description). Returns text ending in a newline, or '' when there is nothing
325
+ * to say.
326
+ */
327
+ function commentBlock(text, indent) {
328
+ if (!text) {
329
+ return '';
330
+ }
331
+
332
+ const lines = [];
333
+ let line = '';
334
+
335
+ for (const word of String(text).split(/\s+/).filter(Boolean)) {
336
+ const candidate = line ? `${line} ${word}` : word;
337
+ if (line && `${indent}// ${candidate}`.length > COMMENT_WIDTH) {
338
+ lines.push(`${indent}// ${line}`);
339
+ line = word;
340
+ } else {
341
+ line = candidate;
342
+ }
343
+ }
344
+ if (line) {
345
+ lines.push(`${indent}// ${line}`);
346
+ }
347
+
348
+ return lines.map((entry) => `${entry}\n`).join('');
349
+ }
350
+
351
+ /**
352
+ * Insert a missing property (possibly a nested branch) into an object node.
353
+ * The remaining steps must all be plain keys — a matcher below a missing key
354
+ * would mean creating an array element, which writeback never does.
355
+ * `comments` (dot-path → text) documents the inserted property on its own
356
+ * line(s) above it, and every key inside the inserted value — multi-line
357
+ * objects only, since a `//` line cannot ride inside `{ a: 1 }`.
358
+ * Returns the new source.
359
+ */
360
+ function insertProperty(source, node, path, steps, value, unit, comments) {
361
+ if (steps.some((step) => step.type !== 'plain')) {
362
+ throw new Error(`Cannot set '${path}': the branch is missing and a [key=value] matcher cannot create array elements`);
363
+ }
364
+
365
+ const names = steps.map((step) => step.name);
366
+ const key = serializeKey(names[0]);
367
+ const nested = nestValue(names.slice(1), value);
368
+ // The full dot-path of the property being inserted: the edit's path minus
369
+ // the branch nestValue() just wrapped around the value.
370
+ const segments = path.split('.');
371
+ const propertyPath = segments.slice(0, segments.length - names.length + 1).join('.');
372
+ const comment = comments ? comments[propertyPath] : undefined;
373
+
374
+ // Empty object with nothing but whitespace inside → rewrite as a block
375
+ const innerText = source.slice(node.start + 1, node.closeStart);
376
+ if (node.entries.length === 0 && /^\s*$/.test(innerText)) {
377
+ const closeIndent = lineIndentAt(source, node.start);
378
+ const childIndent = closeIndent + unit;
379
+ const block = `{\n${commentBlock(comment, childIndent)}${childIndent}${key}: ${serializeValue(nested, childIndent, unit, comments, propertyPath)},\n${closeIndent}}`;
380
+ return source.slice(0, node.start) + block + source.slice(node.end);
381
+ }
382
+
383
+ const isSingleLine = !source.slice(node.start, node.end).includes('\n');
384
+
385
+ if (isSingleLine) {
386
+ if (node.entries.length > 0) {
387
+ // { a: 1 } → { a: 1, key: value }
388
+ const last = node.entries[node.entries.length - 1];
389
+ const insertion = `, ${key}: ${serializeValueInline(nested)}`;
390
+ return source.slice(0, last.valueNode.end) + insertion + source.slice(last.valueNode.end);
391
+ }
392
+ // No entries but comments inside (whitespace-only was rewritten above)
393
+ const insertion = `${key}: ${serializeValueInline(nested)} `;
394
+ return source.slice(0, node.closeStart) + insertion + source.slice(node.closeStart);
395
+ }
396
+
397
+ // Multi-line object: new property goes on its own line, right before the
398
+ // closing brace's line, so trailing comments stay with what they document.
399
+ const braceLineStart = source.lastIndexOf('\n', node.closeStart - 1) + 1;
400
+ const childIndent = node.entries.length > 0
401
+ ? lineIndentAt(source, node.entries[0].keyStart)
402
+ : lineIndentAt(source, node.closeStart) + unit;
403
+ const propertyLine = `${commentBlock(comment, childIndent)}${childIndent}${key}: ${serializeValue(nested, childIndent, unit, comments, propertyPath)},\n`;
404
+
405
+ let result = source.slice(0, braceLineStart) + propertyLine + source.slice(braceLineStart);
406
+
407
+ // The previous last entry needs a trailing comma to stay parseable
408
+ const last = node.entries[node.entries.length - 1];
409
+ if (last && !last.hasComma) {
410
+ result = `${result.slice(0, last.valueNode.end)},${result.slice(last.valueNode.end)}`;
411
+ }
412
+
413
+ return result;
414
+ }
415
+
416
+ /**
417
+ * True when an object item node carries `key: value` where value is a
418
+ * primitive whose parsed form stringifies to the matcher's value.
419
+ */
420
+ function matchesElement(source, item, step) {
421
+ if (item.kind !== 'object') {
422
+ return false;
423
+ }
424
+ const entry = [...item.entries].reverse().find((candidate) => candidate.key === step.key);
425
+ if (!entry || entry.valueNode.kind !== 'primitive') {
426
+ return false;
427
+ }
428
+ return String(JSON5.parse(source.slice(entry.valueNode.start, entry.valueNode.end))) === step.value;
429
+ }
430
+
431
+ /**
432
+ * Apply one dot-path edit to the source. Walks the span tree; replaces the
433
+ * leaf's value span when the path exists, inserts the missing branch when it
434
+ * doesn't (documented from `comments`, which an existing key never gets). Throws
435
+ * when an intermediate value isn't a container, an array index is out of
436
+ * range, or a [key=value] matcher finds no element.
437
+ */
438
+ function applySingleEdit(source, path, value, comments) {
439
+ const steps = parsePath(path);
440
+ const unit = detectIndentUnit(source);
441
+ let node = parseRoot(source);
442
+
443
+ const replaceSpan = (target, indent) =>
444
+ source.slice(0, target.start) + serializeValue(value, indent, unit) + source.slice(target.end);
445
+
446
+ for (let i = 0; i < steps.length; i++) {
447
+ const step = steps[i];
448
+ const isLast = i === steps.length - 1;
449
+ const walked = steps.slice(0, i)
450
+ .map((prior) => (prior.type === 'match' ? `[${prior.key}=${prior.value}]` : prior.name))
451
+ .join('.') || '(root)';
452
+
453
+ if (step.type === 'match') {
454
+ if (node.kind !== 'array') {
455
+ throw new Error(`Cannot set '${path}': a [${step.key}=${step.value}] matcher needs an array`);
456
+ }
457
+ const item = node.items.find((candidate) => matchesElement(source, candidate, step));
458
+ if (!item) {
459
+ throw new Error(`Cannot set '${path}': no array element with ${step.key}=${step.value} (elements are never created by writeback)`);
460
+ }
461
+ if (isLast) {
462
+ return replaceSpan(item, lineIndentAt(source, item.start));
463
+ }
464
+ node = item;
465
+ continue;
466
+ }
467
+
468
+ if (node.kind === 'array') {
469
+ if (!/^\d+$/.test(step.name)) {
470
+ throw new Error(`Cannot set '${path}': '${walked}' is an array (expected a numeric index or [key=value] matcher, got '${step.name}')`);
471
+ }
472
+ const item = node.items[Number(step.name)];
473
+ if (!item) {
474
+ throw new Error(`Cannot set '${path}': index ${step.name} is out of range (array elements are never created by writeback)`);
475
+ }
476
+ if (isLast) {
477
+ return replaceSpan(item, lineIndentAt(source, item.start));
478
+ }
479
+ node = item;
480
+ continue;
481
+ }
482
+
483
+ if (node.kind !== 'object') {
484
+ throw new Error(`Cannot set '${path}': '${walked}' is not an object`);
485
+ }
486
+
487
+ // Duplicate keys: JSON5 keeps the last one, so edit the last one
488
+ const entry = [...node.entries].reverse().find((candidate) => candidate.key === step.name);
489
+
490
+ if (!entry) {
491
+ return insertProperty(source, node, path, steps.slice(i), value, unit, comments);
492
+ }
493
+
494
+ if (isLast) {
495
+ return replaceSpan(entry.valueNode, lineIndentAt(source, entry.keyStart));
496
+ }
497
+
498
+ node = entry.valueNode;
499
+ }
500
+
501
+ throw new Error(`Cannot set '${path}': empty path`);
502
+ }
503
+
504
+ // ─── Public API ──────────────────────────────────────────────────────────────
505
+
506
+ /**
507
+ * Read a dot-path from a parsed config (numeric segments index arrays,
508
+ * [key=value] matchers select array elements).
509
+ */
510
+ function getAtPath(parsed, path) {
511
+ let current = parsed;
512
+ for (const step of parsePath(path)) {
513
+ if (current === null || current === undefined) {
514
+ return undefined;
515
+ }
516
+ if (step.type === 'match') {
517
+ if (!Array.isArray(current)) {
518
+ return undefined;
519
+ }
520
+ current = current.find((element) => element && typeof element === 'object' && String(element[step.key]) === step.value);
521
+ } else {
522
+ current = current[step.name];
523
+ }
524
+ }
525
+ return current;
526
+ }
527
+
528
+ /**
529
+ * The subset of edits whose target path doesn't already hold the value —
530
+ * the skip that makes reruns byte-identical.
531
+ */
532
+ function pendingEdits(parsed, edits) {
533
+ return Object.entries(edits).filter(([path, value]) => !isDeepStrictEqual(getAtPath(parsed, path), value));
534
+ }
535
+
536
+ /**
537
+ * Apply dot-path edits to JSON5 source text, preserving every byte outside
538
+ * the edited spans. Verifies its own output: the result must parse and hold
539
+ * each requested value, or this throws and nothing is returned.
540
+ *
541
+ * @param {string} source - omega.json5 text.
542
+ * @param {Object<string, *>} edits - Dot-path → value (JSON-serializable).
543
+ * @param {object} [options]
544
+ * @param {Object<string, string>} [options.comments] - Dot-path → guiding
545
+ * comment, written above the property when the path is INSERTED (#478). A
546
+ * path that already exists keeps its own documentation.
547
+ * @returns {string} The edited source.
548
+ */
549
+ function applyConfigEdits(source, edits, { comments = {} } = {}) {
550
+ let current = source;
551
+ let parsed = JSON5.parse(source);
552
+
553
+ for (const [path, value] of pendingEdits(parsed, edits)) {
554
+ current = applySingleEdit(current, path, value, comments);
555
+ try {
556
+ parsed = JSON5.parse(current);
557
+ } catch (e) {
558
+ throw new Error(`Config edit '${path}' produced unparseable output — nothing written: ${e.message}`);
559
+ }
560
+ }
561
+
562
+ for (const [path, value] of Object.entries(edits)) {
563
+ if (!isDeepStrictEqual(getAtPath(parsed, path), value)) {
564
+ throw new Error(`Config edit '${path}' did not land — nothing written`);
565
+ }
566
+ }
567
+
568
+ return current;
569
+ }
570
+
571
+ /**
572
+ * Apply edits to a project's omega.json5 on disk. Resolves the file via the
573
+ * standard locations, skips the write entirely when nothing changes, and
574
+ * reports which paths were actually edited. `dryRun` computes everything
575
+ * (including the full edit + verification) but never writes.
576
+ *
577
+ * @param {string} projectDir - Project root (brand root in a brand monorepo).
578
+ * @param {Object<string, *>} edits - Dot-path → value.
579
+ * @param {{ dryRun?: boolean, comments?: Object<string, string> }} [options]
580
+ * @returns {{ path: string, changed: boolean, applied: string[] }}
581
+ */
582
+ function writeConfigValues(projectDir, edits, { dryRun = false, comments = {} } = {}) {
583
+ const configPath = resolveConfigPath(projectDir);
584
+ if (!configPath) {
585
+ throw new Error(`No ${FILE_NAME} found under ${projectDir} — cannot write config values`);
586
+ }
587
+
588
+ const source = fs.readFileSync(configPath, 'utf8');
589
+ const applied = pendingEdits(JSON5.parse(source), edits).map(([path]) => path);
590
+ // Every writeback also normalizes top-level key order (comments travel
591
+ // with their keys) — lazy require: order.js depends on this module
592
+ const { applyCanonicalOrder } = require('./order.js');
593
+ const next = applyCanonicalOrder(applyConfigEdits(source, edits, { comments }));
594
+
595
+ if (next !== source && !dryRun) {
596
+ fs.writeFileSync(configPath, next);
597
+ }
598
+
599
+ return { path: configPath, changed: next !== source, applied };
600
+ }
601
+
602
+ // ─── Removal (#612) ──────────────────────────────────────────────────────────
603
+
604
+ /**
605
+ * Walk to the object entry a dot-path names. Returns null when any step is
606
+ * missing — a removal with nothing to remove is a no-op, never an error.
607
+ * Throws when the path names an ARRAY ELEMENT: elements are user-authored and
608
+ * writeback neither creates nor deletes them.
609
+ */
610
+ function locateEntry(source, path) {
611
+ const steps = parsePath(path);
612
+ let node = parseRoot(source);
613
+
614
+ for (let i = 0; i < steps.length; i++) {
615
+ const step = steps[i];
616
+ const isLast = i === steps.length - 1;
617
+ const elementError = () => new Error(`Cannot remove '${path}': it names an array element (elements are never removed by writeback)`);
618
+
619
+ if (step.type === 'match') {
620
+ if (node.kind !== 'array') return null;
621
+ const item = node.items.find((candidate) => matchesElement(source, candidate, step));
622
+ if (!item) return null;
623
+ if (isLast) throw elementError();
624
+ node = item;
625
+ continue;
626
+ }
627
+
628
+ if (node.kind === 'array') {
629
+ if (!/^\d+$/.test(step.name)) return null;
630
+ const item = node.items[Number(step.name)];
631
+ if (!item) return null;
632
+ if (isLast) throw elementError();
633
+ node = item;
634
+ continue;
635
+ }
636
+
637
+ if (node.kind !== 'object') return null;
638
+
639
+ // Duplicate keys: JSON5 keeps the last one, so remove the last one
640
+ const entry = [...node.entries].reverse().find((candidate) => candidate.key === step.name);
641
+ if (!entry) return null;
642
+ if (isLast) return entry;
643
+ node = entry.valueNode;
644
+ }
645
+
646
+ return null;
647
+ }
648
+
649
+ /**
650
+ * The source span one entry occupies, comments included.
651
+ *
652
+ * A property on its own line takes its whole line(s) — the `//` comment block
653
+ * documenting it above, and a trailing comment on its own line — because that
654
+ * comment describes the key being deleted and would otherwise dangle over the
655
+ * next one. A property sharing its line (`{ a: 1, b: 2 }`) takes only itself
656
+ * plus the separator that held it: the space after when it carries a comma,
657
+ * the comma before when it is the last one.
658
+ */
659
+ function removalSpan(source, entry) {
660
+ const lineStart = source.lastIndexOf('\n', entry.keyStart - 1) + 1;
661
+ const ownsLine = /^[ \t]*$/.test(source.slice(lineStart, entry.keyStart));
662
+ const after = source.slice(entry.commaEnd);
663
+ const tail = after.match(/^[ \t]*(\/\/[^\n]*)?\n/);
664
+
665
+ if (ownsLine && tail) {
666
+ let start = lineStart;
667
+ while (start > 0) {
668
+ const previousStart = source.lastIndexOf('\n', start - 2) + 1;
669
+ if (!/^[ \t]*\/\//.test(source.slice(previousStart, start))) break;
670
+ start = previousStart;
671
+ }
672
+
673
+ let end = entry.commaEnd + tail[0].length;
674
+ // Two blank lines back to back is the removal's own litter, not the
675
+ // author's formatting — one of them goes with it.
676
+ const blankBefore = /(^|\n)[ \t]*\n$/.test(source.slice(0, start));
677
+ const blankAfter = source.slice(end).match(/^[ \t]*\n/);
678
+ if (blankBefore && blankAfter) {
679
+ end += blankAfter[0].length;
680
+ }
681
+
682
+ return { start, end };
683
+ }
684
+
685
+ if (entry.hasComma) {
686
+ return { start: entry.keyStart, end: entry.commaEnd + (after.match(/^[ \t]*/) || [''])[0].length };
687
+ }
688
+
689
+ // Last property on the line: the comma that separated it goes too
690
+ let start = entry.keyStart;
691
+ while (start > 0 && /[ \t]/.test(source[start - 1])) start -= 1;
692
+ if (source[start - 1] === ',') start -= 1;
693
+
694
+ return { start, end: entry.commaEnd };
695
+ }
696
+
697
+ /**
698
+ * Delete dot-paths from JSON5 source text, preserving every byte outside the
699
+ * removed spans. Absent paths are skipped, so reruns are byte-identical.
700
+ * Verifies its own output after each removal: the result must parse and the
701
+ * path must be gone, or this throws and nothing is returned.
702
+ *
703
+ * @param {string} source - omega.json5 text.
704
+ * @param {string[]} paths - Dot-paths to delete (see the edit-path grammar).
705
+ * @returns {string} The edited source.
706
+ */
707
+ function applyConfigRemovals(source, paths) {
708
+ let current = source;
709
+ let parsed = JSON5.parse(source);
710
+
711
+ for (const path of paths) {
712
+ // A duplicated key hides a second copy behind the first — keep cutting
713
+ // until the path reads undefined, which is what the file MEANS.
714
+ while (getAtPath(parsed, path) !== undefined) {
715
+ const entry = locateEntry(current, path);
716
+ if (!entry) {
717
+ throw new Error(`Config removal '${path}' resolves to a value with no property to delete — nothing written`);
718
+ }
719
+
720
+ const { start, end } = removalSpan(current, entry);
721
+ const next = current.slice(0, start) + current.slice(end);
722
+
723
+ try {
724
+ parsed = JSON5.parse(next);
725
+ } catch (e) {
726
+ throw new Error(`Config removal '${path}' produced unparseable output — nothing written: ${e.message}`);
727
+ }
728
+
729
+ current = next;
730
+ }
731
+ }
732
+
733
+ return current;
734
+ }
735
+
736
+ /**
737
+ * Delete paths from a project's omega.json5 on disk. Resolves the file via
738
+ * the standard locations, skips the write when nothing changes, and reports
739
+ * which paths were actually there. `dryRun` computes everything (including
740
+ * the removal + verification) but never writes.
741
+ *
742
+ * Unlike writeConfigValues this does NOT normalize top-level key order: a
743
+ * deletion is surgical, and re-sorting a hand-authored file around it would
744
+ * bury the one line the caller means to report.
745
+ *
746
+ * @param {string} projectDir - Project root (brand root in a brand monorepo).
747
+ * @param {string[]} paths - Dot-paths to delete.
748
+ * @param {{ dryRun?: boolean }} [options]
749
+ * @returns {{ path: string, changed: boolean, removed: string[] }}
750
+ */
751
+ function removeConfigValues(projectDir, paths, { dryRun = false } = {}) {
752
+ const configPath = resolveConfigPath(projectDir);
753
+ if (!configPath) {
754
+ throw new Error(`No ${FILE_NAME} found under ${projectDir} — cannot remove config values`);
755
+ }
756
+
757
+ const source = fs.readFileSync(configPath, 'utf8');
758
+ const parsed = JSON5.parse(source);
759
+ const removed = paths.filter((path) => getAtPath(parsed, path) !== undefined);
760
+ const next = applyConfigRemovals(source, paths);
761
+
762
+ if (next !== source && !dryRun) {
763
+ fs.writeFileSync(configPath, next);
764
+ }
765
+
766
+ return { path: configPath, changed: next !== source, removed };
767
+ }
768
+
769
+ module.exports = { applyConfigEdits, writeConfigValues, applyConfigRemovals, removeConfigValues, parseRoot };