@omega.js/desktop 0.53.0 → 0.54.1

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 (161) hide show
  1. package/README.md +38 -38
  2. package/dist/cli-run.js +4 -1
  3. package/dist/cli.js +2 -2
  4. package/dist/commands/cdp/client.js +1 -1
  5. package/dist/commands/cdp.js +1 -1
  6. package/dist/commands/clean.js +2 -3
  7. package/dist/commands/dev.js +25 -0
  8. package/dist/commands/lib/ensure-target.js +12 -17
  9. package/dist/commands/lib/migrate.js +17 -0
  10. package/dist/commands/logs.js +1 -1
  11. package/dist/commands/release.js +1 -1
  12. package/dist/commands/test.js +4 -4
  13. package/dist/commands/update.js +5 -4
  14. package/dist/defaults/.github/workflows/build.yml +18 -18
  15. package/dist/defaults/_.gitignore +0 -2
  16. package/dist/defaults/_mas/README.md +3 -3
  17. package/dist/defaults/config/certs/README.md +1 -1
  18. package/dist/defaults/config/omega.json5 +36 -36
  19. package/dist/defaults/docs/README.md +3 -3
  20. package/dist/defaults/gulpfile.js +1 -1
  21. package/dist/defaults/hooks/build/post.js +1 -1
  22. package/dist/defaults/hooks/build/pre.js +1 -1
  23. package/dist/defaults/hooks/notarize/post.js +2 -2
  24. package/dist/defaults/hooks/release/post.js +1 -1
  25. package/dist/defaults/hooks/release/pre.js +1 -1
  26. package/dist/defaults/src/assets/scss/pages/about.scss +1 -1
  27. package/dist/defaults/src/assets/scss/pages/main.scss +1 -1
  28. package/dist/defaults/src/assets/scss/pages/settings.scss +1 -1
  29. package/dist/defaults/src/integrations/context-menu/index.js +11 -11
  30. package/dist/defaults/src/integrations/menu/index.js +5 -5
  31. package/dist/defaults/src/integrations/tray/index.js +9 -9
  32. package/dist/defaults/src/main.js +2 -2
  33. package/dist/defaults/src/preload.js +1 -1
  34. package/dist/defaults/test/README.md +3 -3
  35. package/dist/defaults/test/_init.js +1 -1
  36. package/dist/gulp/tasks/audit.js +5 -8
  37. package/dist/lib/restart-manager/index.js +1 -1
  38. package/dist/lib/restart-manager/install.js +1 -1
  39. package/dist/lib/restart-manager/protocol.js +1 -1
  40. package/dist/main.js +4 -3
  41. package/dist/preload.js +1 -1
  42. package/dist/test/suites/build/audit.test.js +20 -7
  43. package/dist/test/suites/build/build-workflow-jobs.test.js +2 -2
  44. package/dist/test/suites/build/cli.test.js +28 -0
  45. package/dist/test/suites/build/defaults-em-dash.test.js +22 -0
  46. package/dist/test/suites/build/defaults-scaffold.test.js +19 -5
  47. package/dist/test/suites/build/deploy-direct.test.js +7 -5
  48. package/dist/test/suites/build/deploy-dispatch.test.js +2 -1
  49. package/dist/test/suites/build/deploy-hook.test.js +4 -2
  50. package/dist/test/suites/build/dev-verb.test.js +67 -0
  51. package/dist/test/suites/build/ensure-target.test.js +11 -3
  52. package/dist/test/suites/build/merge-line-files.test.js +6 -6
  53. package/dist/test/suites/build/migrate.test.js +29 -0
  54. package/dist/test/suites/build/project-scripts-deps.test.js +6 -10
  55. package/dist/test/suites/build/runner-env-write.test.js +73 -0
  56. package/dist/test/suites/build/runner.test.js +9 -8
  57. package/dist/test/suites/build/setup-scripts.test.js +27 -0
  58. package/dist/test/suites/build/validate-config.test.js +13 -2
  59. package/dist/test/suites/build/verb-logs.test.js +20 -0
  60. package/dist/test/suites/renderer/window-desktop-surface.test.js +1 -1
  61. package/dist/utils/build-pipeline.js +4 -4
  62. package/dist/utils/runner-env.js +13 -28
  63. package/dist/vendor/config/company.js +46 -14
  64. package/dist/vendor/config/defaults.js +30 -7
  65. package/dist/vendor/config/edit.js +25 -3
  66. package/dist/vendor/config/env-delivery.js +1 -1
  67. package/dist/vendor/config/env-schema.js +3 -6
  68. package/dist/vendor/config/env.js +34 -22
  69. package/dist/vendor/config/index.js +13 -17
  70. package/dist/vendor/config/load.js +15 -7
  71. package/dist/vendor/config/repo.js +10 -27
  72. package/dist/vendor/config/schema-client.js +64 -0
  73. package/dist/vendor/config/schema-cloud.js +38 -0
  74. package/dist/vendor/config/schema-manager.js +118 -0
  75. package/dist/vendor/config/schema-overrides.js +68 -0
  76. package/dist/vendor/config/schema.js +99 -152
  77. package/dist/vendor/config/validate.js +97 -77
  78. package/dist/vendor/devkit/agents-md.js +233 -0
  79. package/dist/vendor/devkit/attach-log-file.js +15 -1
  80. package/dist/vendor/devkit/ci-workflows.js +30 -30
  81. package/dist/vendor/devkit/cli-router.js +13 -7
  82. package/dist/vendor/devkit/defaults-engine.js +9 -43
  83. package/dist/vendor/devkit/deploy-snapshot.js +44 -9
  84. package/dist/vendor/devkit/env-lines.js +183 -0
  85. package/dist/vendor/devkit/local.js +62 -10
  86. package/dist/vendor/devkit/lockfile.js +32 -13
  87. package/dist/vendor/devkit/logger.js +7 -2
  88. package/dist/vendor/devkit/merge-line-files.js +219 -176
  89. package/dist/vendor/devkit/omega-bin.js +208 -111
  90. package/dist/vendor/devkit/preludes/docs-sync.js +52 -0
  91. package/dist/vendor/devkit/preludes/index.js +1 -0
  92. package/dist/vendor/devkit/target-picker.js +45 -0
  93. package/dist/vendor/devkit/test/dashed-files.js +37 -0
  94. package/dist/vendor/devkit/test/run-verb-under-tee.js +71 -0
  95. package/dist/vendor/devkit/update.js +15 -15
  96. package/dist/vendor/devkit/verb-scripts.js +40 -0
  97. package/dist/vendor/devkit/verbs.js +170 -0
  98. package/package.json +18 -24
  99. package/dist/commands/install.js +0 -37
  100. package/dist/defaults/AGENTS.md +0 -119
  101. package/dist/defaults/CLAUDE.md +0 -1
  102. package/dist/vendor/config/env-retired.js +0 -137
  103. package/dist/vendor/config/retired-keys.js +0 -635
  104. package/docs/analytics.md +0 -140
  105. package/docs/app-state.md +0 -92
  106. package/docs/audit.md +0 -69
  107. package/docs/auth.md +0 -284
  108. package/docs/auto-updater.md +0 -243
  109. package/docs/boot-sequence.md +0 -44
  110. package/docs/build-system.md +0 -169
  111. package/docs/cdp-debugging.md +0 -169
  112. package/docs/common-mistakes.md +0 -21
  113. package/docs/config-schema.md +0 -120
  114. package/docs/context-menu.md +0 -112
  115. package/docs/context.md +0 -81
  116. package/docs/css.md +0 -84
  117. package/docs/deep-link.md +0 -186
  118. package/docs/environment-detection.md +0 -112
  119. package/docs/fontawesome.md +0 -109
  120. package/docs/hooks.md +0 -89
  121. package/docs/icons.md +0 -79
  122. package/docs/index.md +0 -328
  123. package/docs/installer-options.md +0 -165
  124. package/docs/ipc.md +0 -61
  125. package/docs/lib-modules.md +0 -53
  126. package/docs/logging.md +0 -227
  127. package/docs/menu.md +0 -160
  128. package/docs/releasing.md +0 -239
  129. package/docs/remote-config.md +0 -118
  130. package/docs/remote-scripts.md +0 -144
  131. package/docs/restart-manager.md +0 -144
  132. package/docs/runner.md +0 -290
  133. package/docs/sentry.md +0 -97
  134. package/docs/shared/agent-docs.md +0 -89
  135. package/docs/shared/analytics.md +0 -612
  136. package/docs/shared/brands.md +0 -57
  137. package/docs/shared/breaking-changes.md +0 -917
  138. package/docs/shared/config.md +0 -1948
  139. package/docs/shared/deploys.md +0 -341
  140. package/docs/shared/icons.md +0 -219
  141. package/docs/shared/local-dev.md +0 -167
  142. package/docs/shared/logging.md +0 -205
  143. package/docs/shared/monitoring.md +0 -167
  144. package/docs/shared/publishing.md +0 -187
  145. package/docs/shared/rulings.md +0 -34
  146. package/docs/shared/testing.md +0 -147
  147. package/docs/shared/theming.md +0 -629
  148. package/docs/shared/translation.md +0 -342
  149. package/docs/shared/updates.md +0 -61
  150. package/docs/signing.md +0 -293
  151. package/docs/startup.md +0 -142
  152. package/docs/storage.md +0 -59
  153. package/docs/templating.md +0 -101
  154. package/docs/test-boot-layer.md +0 -157
  155. package/docs/test-framework.md +0 -362
  156. package/docs/themes.md +0 -149
  157. package/docs/tooltips.md +0 -99
  158. package/docs/tray.md +0 -164
  159. package/docs/usage.md +0 -58
  160. package/docs/verts.md +0 -62
  161. package/docs/windows.md +0 -149
@@ -1,13 +1,13 @@
1
- // config/omega.json5 — the single OMEGA config file (JSON5: comments + trailing commas OK).
1
+ // config/omega.json5: the single OMEGA config file (JSON5: comments + trailing commas OK).
2
2
  //
3
3
  // Shape: SHARED sections at the top level (identical spelling in every OMEGA project
4
- // type — website, backend, extension, desktop), then a `targets` object whose KEY
4
+ // type: website, backend, extension, desktop), then a `targets` object whose KEY
5
5
  // PRESENCE says which targets this brand enables and whose values hold target-scoped
6
6
  // settings. Any shared key may also appear inside a target entry to override it for
7
7
  // that surface only (e.g. a desktop-specific monitoring.providers.sentry.dsn
8
8
  // under targets.desktop).
9
9
  //
10
- // Secrets NEVER live here — they live in .env. The validator hard-fails on
10
+ // Secrets NEVER live here: they live in .env. The validator hard-fails on
11
11
  // secret-shaped keys (…Secret, …privateKey).
12
12
  {
13
13
  brand: {
@@ -48,7 +48,7 @@
48
48
  // so the same human gets unified events across desktop + web + backend.
49
49
  analytics: {
50
50
  // Presence-driven: set `providers.google.id` to `G-XXXXXXXXXX` to enable analytics.
51
- // Empty string = analytics disabled (matches @omega.js/backend convention — no redundant enabled flag).
51
+ // Empty string = analytics disabled (matches @omega.js/backend convention, no redundant enabled flag).
52
52
  providers: {
53
53
  google: {
54
54
  id: '', // 'G-XXXXXXXXXX' Measurement ID
@@ -56,7 +56,7 @@
56
56
  },
57
57
  },
58
58
 
59
- // Payment — @omega.js/backend-shaped so the same product catalog can be referenced from backend
59
+ // Payment: @omega.js/backend-shaped so the same product catalog can be referenced from backend
60
60
  // + desktop. The schema enforces publishableKey shape when set; everything else is
61
61
  // freeform so apps can extend per their needs without @omega.js/desktop caring. Leave empty until
62
62
  // you're ready to wire payments.
@@ -69,7 +69,7 @@
69
69
  },
70
70
 
71
71
  // App/cloud platform role (provider-discriminated). `config` is the Firebase web
72
- // SDK config — copy directly from Firebase Console → Project Settings → SDK setup
72
+ // SDK config: copy directly from Firebase Console → Project Settings → SDK setup
73
73
  // (Config option). Same shape every OMEGA target reads.
74
74
  // Empty config {} disables Firebase Auth in the renderer (the auth lib logs a warn).
75
75
  cloud: {
@@ -86,10 +86,10 @@
86
86
  },
87
87
  },
88
88
 
89
- // Appearance — the app's DEFAULT theme. 'system' follows the OS preference live;
89
+ // Appearance: the app's DEFAULT theme. 'system' follows the OS preference live;
90
90
  // 'light'/'dark' are explicit overrides. A user's runtime choice (omega.theme.set
91
91
  // or the [data-omega-theme-set] controls) persists in storage and wins over this on
92
- // every boot. See docs/themes.md.
92
+ // every boot. See @omega.js/manager/docs/desktop/themes.md.
93
93
  theme: {
94
94
  appearance: 'system',
95
95
  },
@@ -102,7 +102,7 @@
102
102
  desktop: {
103
103
  type: 'desktop',
104
104
 
105
- // App-level metadata — universal cross-platform fields. @omega.js/desktop auto-derives sensible
105
+ // App-level metadata: universal cross-platform fields. @omega.js/desktop auto-derives sensible
106
106
  // defaults from the BRAND: `appId` ← `certificates.providers.apple.bundleIdPrefix`
107
107
  // plus `brand.id` with its dashes as dots (`com.example` + `my-app` →
108
108
  // `com.example.my.app`), the same id the certificates service registers.
@@ -111,11 +111,11 @@
111
111
  // `productName` ← `brand.name`, `copyright` ← `© <year>, <brand.name>`.
112
112
  // Override any of these explicitly only if you must.
113
113
  //
114
- // `category` is a generic high-level category — @omega.js/desktop maps it to per-platform values
114
+ // `category` is a generic high-level category. @omega.js/desktop maps it to per-platform values
115
115
  // (mac uses Apple's UTI strings, linux uses freedesktop categories). Allowed values:
116
116
  // productivity (default) | developer-tools | utilities | media | social | network
117
117
  // Override the per-platform mapping in `platforms.<plat>.category` if you need
118
- // something specific. See docs/installer-options.md for the full table.
118
+ // something specific. See @omega.js/manager/docs/desktop/installer-options.md for the full table.
119
119
  //
120
120
  // `copyright` accepts a `{YEAR}` token expanded at build time to the current year.
121
121
  // Default is `© {YEAR}, <brand.name>`. Set explicitly only to change the holder.
@@ -127,12 +127,12 @@
127
127
  languages: ['en'], // applied as mac.electronLanguages
128
128
  darkModeSupport: true, // mac honors via NSRequiresAquaSystemAppearance; win/linux ignore
129
129
  // Icons are convention-only. Drop PNGs at:
130
- // config/icons/global/<slot>.png — universal default for all platforms
130
+ // config/icons/global/<slot>.png : universal default for all platforms
131
131
  // config/icons/mac/<slot>.png : macOS override (beats global)
132
- // config/icons/windows/<slot>.png — Windows override
133
- // config/icons/linux/<slot>.png — Linux override (otherwise falls back to global → windows)
132
+ // config/icons/windows/<slot>.png : Windows override
133
+ // config/icons/linux/<slot>.png : Linux override (otherwise falls back to global → windows)
134
134
  // Slots: icon, tray (mac+win+linux); dmg (mac-only).
135
- // Native size only — @omega.js/desktop downscales @1x variants from your @2x source automatically.
135
+ // Native size only: @omega.js/desktop downscales @1x variants from your @2x source automatically.
136
136
  // macOS tray must be 32×32; @omega.js/desktop renames the dist output to trayTemplate.png for the
137
137
  // OS dark-mode auto-inversion magic.
138
138
  },
@@ -145,7 +145,7 @@
145
145
  // beside `formats` are install knobs that map onto the same
146
146
  // electron-builder concepts (`mac.target`, `win.target`, `linux.target`),
147
147
  // but @omega.js/desktop owns the actual target list so auto-update keeps
148
- // working (see docs/installer-options.md for why). Each block exposes only
148
+ // working (see @omega.js/manager/docs/desktop/installer-options.md for why). Each block exposes only
149
149
  // the knobs that exist for that platform: there is no cross-platform
150
150
  // analog for any of these.
151
151
  platforms: {
@@ -156,7 +156,7 @@
156
156
  formats: {
157
157
  dmg: {},
158
158
  },
159
- arch: ['universal'], // universal binary (x64 + arm64 lipo'd) — one .dmg/.zip for both
159
+ arch: ['universal'], // universal binary (x64 + arm64 lipo'd), one .dmg/.zip for both
160
160
  // Entitlements override map. @omega.js/desktop ships sensible defaults (allow-jit,
161
161
  // allow-unsigned-executable-memory, disable-library-validation, network.client/server,
162
162
  // files.user-selected.read-write, allow-dyld-environment-variables). To override:
@@ -165,7 +165,7 @@
165
165
  // Output: dist/config/entitlements.mac.plist (auto-wired into electron-builder.yml).
166
166
  // Example: { 'com.apple.security.network.server': false, 'com.apple.security.device.audio-input': true }
167
167
  entitlements: {},
168
- // MAS (Mac App Store) — STUBBED. Config is parsed but not yet implemented;
168
+ // MAS (Mac App Store): STUBBED. Config is parsed but not yet implemented;
169
169
  // setting `enabled: true` triggers an audit warning. Real implementation lands
170
170
  // in a future release. Reference plists from a working MAS-published Electron app
171
171
  // are archived at <em>/src/defaults/_mas/ for the eventual implementation.
@@ -189,12 +189,12 @@
189
189
  runAfterFinish: true,
190
190
  perMachine: false, // per-user install (required for oneClick:true)
191
191
  // Code-signing strategy. Picked at workflow time to drive runner selection +
192
- // job gating. See docs/signing.md.
193
- // self-hosted (default) — sign with signtool against an EV USB token (typically
192
+ // job gating. See @omega.js/manager/docs/desktop/signing.md.
193
+ // self-hosted (default): sign with signtool against an EV USB token (typically
194
194
  // on an framework-managed self-hosted GH Actions runner)
195
- // cloud — shell to a cloud signing provider's CLI (Azure /
196
- // SSL.com / DigiCert) — provider configured in cloud.provider
197
- // local — skip CI signing; developer signs manually on their box
195
+ // cloud: shell to a cloud signing provider's CLI (Azure /
196
+ // SSL.com / DigiCert), provider configured in cloud.provider
197
+ // local: skip CI signing; developer signs manually on their box
198
198
  signing: {
199
199
  strategy: 'self-hosted',
200
200
  cloud: { provider: null, options: {} },
@@ -225,9 +225,9 @@
225
225
  enabled: true,
226
226
  autoDownload: true,
227
227
  startupDelayMs: 10000, // 10s after whenReady → first check
228
- feedCheckIntervalMs: 3600000, // 1h between feed polls (HTTP — keep slow)
228
+ feedCheckIntervalMs: 3600000, // 1h between feed polls (HTTP, keep slow)
229
229
  idleEvalIntervalMs: 60000, // 1m idle-install evaluator (cheap, in-process)
230
- maxAgeMs: 2592000000, // 30d — once an update has been pending this long, force install
230
+ maxAgeMs: 2592000000, // 30d: once an update has been pending this long, force install
231
231
  },
232
232
  // Tray, menu, and context-menu are defined in JS files (full power, no DSL).
233
233
  // @omega.js/desktop looks for them at the conventional paths:
@@ -237,11 +237,11 @@
237
237
  // To disable at runtime: call `omega.tray.disable()` / `omega.menu.disable()` /
238
238
  // `omega.contextMenu.disable()` from your main entry. Idempotent.
239
239
 
240
- // Startup behavior — two independent knobs.
240
+ // Startup behavior: two independent knobs.
241
241
  //
242
242
  // `mode` controls how the app launches when THE USER opens it directly:
243
- // normal — main window appears, dock icon visible (typical app).
244
- // hidden — packaged builds bake LSUIElement=true into Info.plist on macOS:
243
+ // normal: main window appears, dock icon visible (typical app).
244
+ // hidden: packaged builds bake LSUIElement=true into Info.plist on macOS:
245
245
  // zero dock bounce, no dock icon, not in Cmd+Tab. Tray + notifications
246
246
  // + networking still work. Your main.js skips windows.create() at boot
247
247
  // and surfaces UI later (typically from a tray click). When you do call
@@ -249,8 +249,8 @@
249
249
  // appears alongside the window.
250
250
  //
251
251
  // `openAtLogin` controls auto-launch on OS login:
252
- // enabled — register the app with the OS to auto-launch (default true).
253
- // mode — `hidden` (default) means at-login launches behave like `mode: 'hidden'`;
252
+ // enabled: register the app with the OS to auto-launch (default true).
253
+ // mode: `hidden` (default) means at-login launches behave like `mode: 'hidden'`;
254
254
  // `normal` means the at-login launch shows UI like a normal launch.
255
255
  // The login-launch mode applies ONLY when the OS launches the app. User-direct
256
256
  // launches always use `startup.mode` above. So a "normal" app can still start
@@ -262,7 +262,7 @@
262
262
  mode: 'hidden',
263
263
  },
264
264
  },
265
- // No `windows` block needed — @omega.js/desktop no longer auto-creates windows. Your main.js
265
+ // No `windows` block needed: @omega.js/desktop no longer auto-creates windows. Your main.js
266
266
  // calls `omega.windows.create('main', { width: 1280, height: 800, ... })` when
267
267
  // you want UI to surface. Defaults baked in:
268
268
  // main → { width: 1024, height: 720, hideOnClose: true, view: 'main' }
@@ -276,7 +276,7 @@
276
276
  // `npx omega deploy`'s precheck auto-creates it if it doesn't exist (uses GH_TOKEN).
277
277
  // Artifact names carry NO version (MyApp-mac-dmg.dmg), so this repo also serves the marketing
278
278
  // site: https://github.com/<org>/<brand.id>-releases/releases/latest/download/<asset> never changes
279
- // across versions, and the website derives its download buttons from it. See docs/releasing.md.
279
+ // across versions, and the website derives its download buttons from it. See @omega.js/manager/docs/desktop/releasing.md.
280
280
  releases: {
281
281
  enabled: true,
282
282
  },
@@ -286,7 +286,7 @@
286
286
  // app/quit → app.quit()
287
287
  // Add custom routes at runtime: omega.deepLink.on('my-route', (ctx) => {...}) in main.
288
288
 
289
- // "Hot config" — JSON document fetched from the brand site so app behavior
289
+ // "Hot config": JSON document fetched from the brand site so app behavior
290
290
  // can be flipped without shipping a new build (e.g. force-update gate, ads
291
291
  // toggle, default user agent strings, etc.). Default URL is derived as
292
292
  // `${brand.url}/data/resources/main.json` (legacy convention). Override the
@@ -296,11 +296,11 @@
296
296
  enabled: true,
297
297
  // url: 'https://brand.example/data/resources/main.json', // default uses brand.url
298
298
  },
299
- // Restart Manager — external guardian app that relaunches this app if it
300
- // crashes. @omega.js/desktop talks to it over a localhost HTTP protocol (docs/restart-manager.md):
299
+ // Restart Manager: external guardian app that relaunches this app if it
300
+ // crashes. @omega.js/desktop talks to it over a localhost HTTP protocol (@omega.js/manager/docs/desktop/restart-manager.md):
301
301
  // auto-registers ~15s after launch, heartbeats every 60s, deregisters on clean
302
302
  // quit, and silently installs RM when missing (mac zip / win silent NSIS /
303
- // linux AppImage — no installer UI, no admin; RM then keeps itself updated via
303
+ // linux AppImage: no installer UI, no admin; RM then keeps itself updated via
304
304
  // its own standard @omega.js/desktop auto-updater). Set false to disable entirely. In dev
305
305
  // mode it's skipped unless OMEGA_RESTART_MANAGER_DEV=1.
306
306
  restartManager: {
@@ -1,10 +1,10 @@
1
1
  # Project docs
2
2
 
3
- Per-subsystem deep references live here. Keep `AGENTS.md` short — it should read as a **table of contents** that points at files in this directory.
3
+ Per-subsystem deep references live here. Keep `AGENTS.md` short: it should read as a **table of contents** that points at files in this directory.
4
4
 
5
5
  ## Pattern
6
6
 
7
- When you find yourself adding more than a paragraph to `AGENTS.md`, create a new `docs/<topic>.md` instead and link to it from `AGENTS.md`. Goal: the project's `AGENTS.md` stays under ~250 lines (`CLAUDE.md` is only the one-line `@AGENTS.md` pointer).
7
+ When you find yourself adding more than a paragraph to `AGENTS.md`, create a new `docs/<topic>.md` instead and link to it from `AGENTS.md`. Goal: the project's `AGENTS.md` stays under ~250 lines.
8
8
 
9
9
  Examples of good `docs/*.md` topics:
10
10
  - Subsystem deep-dives (one per area of the codebase)
@@ -14,4 +14,4 @@ Examples of good `docs/*.md` topics:
14
14
 
15
15
  ## See also
16
16
 
17
- The framework's own docs follow this same pattern — browse `node_modules/@omega.js/desktop/docs/` for the canonical examples.
17
+ The framework's own docs follow this same pattern: browse `node_modules/@omega.js/manager/docs/desktop/` for the canonical examples.
@@ -1,4 +1,4 @@
1
- // Consumer gulpfile — the framework's gulp pipeline, resolved through the
1
+ // Consumer gulpfile: the framework's gulp pipeline, resolved through the
2
2
  // require climb so it works wherever npm hoists the framework (brand-root
3
3
  // node_modules in a monorepo, local node_modules standalone). The old
4
4
  // scripts hardcoded ./node_modules/@omega.js/desktop/... and broke under
@@ -1,4 +1,4 @@
1
- // Optional consumer extension hook — called AFTER the build pipeline finishes, BEFORE
1
+ // Optional consumer extension hook, called AFTER the build pipeline finishes, BEFORE
2
2
  // electron-builder packages anything. No-op by default.
3
3
  //
4
4
  // Use this for: post-build asset processing, additional file copies into dist/, generating
@@ -1,4 +1,4 @@
1
- // Optional consumer extension hook — called BEFORE the build pipeline runs (defaults →
1
+ // Optional consumer extension hook, called BEFORE the build pipeline runs (defaults →
2
2
  // distribute → bundle → sass → html → audit → build-config). No-op by default.
3
3
  //
4
4
  // Use this for: pre-flight checks, generating build-time artifacts, mutating config before
@@ -1,4 +1,4 @@
1
- // Optional consumer extension hook — called AFTER @omega.js/desktop's built-in macOS
1
+ // Optional consumer extension hook, called AFTER @omega.js/desktop's built-in macOS
2
2
  // notarization has already run. No-op by default.
3
3
  //
4
4
  // Use this for: custom stapling, archiving the notarized .app, notifications, uploading the
@@ -8,7 +8,7 @@
8
8
  //
9
9
  // IMPORTANT: This file is NOT the notarization entrypoint. @omega.js/desktop's electron-builder integration
10
10
  // uses its own internal notarize hook as the afterSign entrypoint, then calls into this file
11
- // as a final step. You can never accidentally break notarization by editing this — at worst,
11
+ // as a final step. You can never accidentally break notarization by editing this. At worst,
12
12
  // a thrown error here fails the build loudly.
13
13
 
14
14
  module.exports = async (context) => {
@@ -1,4 +1,4 @@
1
- // Optional consumer extension hook — called AFTER the release publishes successfully (after
1
+ // Optional consumer extension hook, called AFTER the release publishes successfully (after
2
2
  // electron-builder finishes). No-op by default.
3
3
  //
4
4
  // Use this for: posting to Slack/Discord, kicking off downstream workflows, updating a
@@ -1,4 +1,4 @@
1
- // Optional consumer extension hook — called BEFORE electron-builder runs the sign + notarize
1
+ // Optional consumer extension hook, called BEFORE electron-builder runs the sign + notarize
2
2
  // + publish flow. No-op by default.
3
3
  //
4
4
  // Use this for: bumping version files in extra places, last-mile validations, archiving the
@@ -1,3 +1,3 @@
1
- // About window — page-specific styles. Compiled to dist/assets/css/components/about.bundle.css.
1
+ // About window: page-specific styles. Compiled to dist/assets/css/components/about.bundle.css.
2
2
 
3
3
  // Add your page-only styles below.
@@ -1,4 +1,4 @@
1
- // Main window — page-specific styles. Compiled to dist/assets/css/components/main.bundle.css
1
+ // Main window: page-specific styles. Compiled to dist/assets/css/components/main.bundle.css
2
2
  // and loaded only on the main window's HTML page.
3
3
 
4
4
  // Add your page-only styles below.
@@ -1,3 +1,3 @@
1
- // Settings window — page-specific styles. Compiled to dist/assets/css/components/settings.bundle.css.
1
+ // Settings window: page-specific styles. Compiled to dist/assets/css/components/settings.bundle.css.
2
2
 
3
3
  // Add your page-only styles below.
@@ -1,24 +1,24 @@
1
1
  // Context-menu definition. Called by @omega.js/desktop EVERY time the user right-clicks.
2
2
  //
3
3
  // `omega`: the running @omega.js/desktop main-process instance.
4
- // `menu` — per-event builder API + id-path API.
5
- // `params` — Electron's context-menu params (selectionText, isEditable, linkURL,
4
+ // `menu`: per-event builder API + id-path API.
5
+ // `params`: Electron's context-menu params (selectionText, isEditable, linkURL,
6
6
  // srcURL, mediaType, editFlags, x, y, etc.).
7
- // `webContents` — the webContents that fired the event.
7
+ // `webContents`: the webContents that fired the event.
8
8
  //
9
- // This file is OPTIONAL — delete it and @omega.js/desktop still ships a working context menu.
9
+ // This file is OPTIONAL: delete it and @omega.js/desktop still ships a working context menu.
10
10
  //
11
11
  // @omega.js/desktop ships a default template (built per-event from params) with these ids (flat):
12
- // undo, redo — when params.editFlags allow
12
+ // undo, redo: when params.editFlags allow
13
13
  // cut, copy, paste, paste-and-match-style,
14
- // select-all — when params.isEditable
15
- // copy — when params.selectionText (read-only)
16
- // open-link, copy-link — when params.linkURL
17
- // reload — always
18
- // inspect, toggle-devtools — dev mode only
14
+ // select-all: when params.isEditable
15
+ // copy: when params.selectionText (read-only)
16
+ // open-link, copy-link: when params.linkURL
17
+ // reload: always
18
+ // inspect, toggle-devtools: dev mode only
19
19
 
20
20
  module.exports = ({ omega, menu, params, webContents }) => {
21
- // Start from @omega.js/desktop's default template. Don't add anything by default — leave it
21
+ // Start from @omega.js/desktop's default template. Don't add anything by default: leave it
22
22
  // identical to what the framework would do without this file.
23
23
  menu.useDefaults();
24
24
 
@@ -1,10 +1,10 @@
1
1
  // Application menu definition. Called by @omega.js/desktop during boot.
2
2
  //
3
3
  // `omega`: the running @omega.js/desktop main-process instance.
4
- // `menu` — builder API + id-path API (find/update/remove/insertAfter/etc.).
5
- // `defaults` — the platform-aware default template (an array you can mutate manually if needed).
4
+ // `menu`: builder API + id-path API (find/update/remove/insertAfter/etc.).
5
+ // `defaults`: the platform-aware default template (an array you can mutate manually if needed).
6
6
  //
7
- // This file is OPTIONAL — delete it and @omega.js/desktop still ships a working application menu.
7
+ // This file is OPTIONAL: delete it and @omega.js/desktop still ships a working application menu.
8
8
  //
9
9
  // @omega.js/desktop ships a default menu template with stable id paths. Highlights:
10
10
  // main/about, main/check-for-updates, main/preferences (hidden), main/services,
@@ -20,13 +20,13 @@
20
20
 
21
21
  module.exports = ({ omega, menu, defaults }) => {
22
22
  // Start from the platform-appropriate default template. Don't add anything
23
- // by default — leave it identical to what the framework would do without
23
+ // by default: leave it identical to what the framework would do without
24
24
  // this file. Add your own customizations below.
25
25
  menu.useDefaults();
26
26
 
27
27
  // ───────── Examples (uncomment to use) ─────────
28
28
  //
29
- // // Show the Preferences item (hidden by default — flip its visibility once you
29
+ // // Show the Preferences item (hidden by default, flip its visibility once you
30
30
  // // wire up your settings window):
31
31
  // menu.show(process.platform === 'darwin' ? 'main/preferences' : 'file/preferences');
32
32
  //
@@ -1,7 +1,7 @@
1
1
  // Tray definition. Called by @omega.js/desktop during boot.
2
2
  //
3
3
  // `omega`: the running @omega.js/desktop main-process instance.
4
- // `tray` — builder API + id-path API (find/update/remove/insertAfter/etc.).
4
+ // `tray`: builder API + id-path API (find/update/remove/insertAfter/etc.).
5
5
  //
6
6
  // @omega.js/desktop auto-resolves the tray icon by convention (most specific wins):
7
7
  // 1. config/icons/<platform>/tray.png (platform-specific override)
@@ -10,14 +10,14 @@
10
10
  // 4. @omega.js/desktop bundled default
11
11
  // And auto-sets the tooltip to config.app.productName.
12
12
  //
13
- // Default items shipped by @omega.js/desktop (flat ids — no `tray/` prefix needed):
14
- // title — disabled label showing the app name
15
- // open — "Open <app>"
16
- // check-for-updates — wired to autoUpdater (label/enabled auto-updated)
17
- // website — opens brand.url in external browser (only if configured)
18
- // quit — quits the app
13
+ // Default items shipped by @omega.js/desktop (flat ids, no `tray/` prefix needed):
14
+ // title: disabled label showing the app name
15
+ // open: "Open <app>"
16
+ // check-for-updates: wired to autoUpdater (label/enabled auto-updated)
17
+ // website: opens brand.url in external browser (only if configured)
18
+ // quit: quits the app
19
19
  //
20
- // This file is OPTIONAL — delete it and @omega.js/desktop still ships a working tray.
20
+ // This file is OPTIONAL: delete it and @omega.js/desktop still ships a working tray.
21
21
 
22
22
  module.exports = ({ omega, tray }) => {
23
23
  // Use @omega.js/desktop's default template + auto-resolved icon + auto-resolved tooltip.
@@ -51,7 +51,7 @@ module.exports = ({ omega, tray }) => {
51
51
  // // Disable without removing (sets enabled:false):
52
52
  // tray.enable('quit', false);
53
53
  //
54
- // // Add a submenu — items inside addressable as 'account/sign-out' etc.
54
+ // // Add a submenu: items inside addressable as 'account/sign-out' etc.
55
55
  // tray.insertBefore('quit', {
56
56
  // id: 'account', label: 'Account', submenu: [
57
57
  // { id: 'sign-out', label: 'Sign out', click: () => {} },
@@ -8,7 +8,7 @@ omega.initialize()
8
8
  // ─────────────────────────────────────────────────────────────────────────────
9
9
  // 1. Create the main window
10
10
  // ─────────────────────────────────────────────────────────────────────────────
11
- // Always create `main` — @omega.js/desktop uses its presence in the registry to surface UI when
11
+ // Always create `main`: @omega.js/desktop uses its presence in the registry to surface UI when
12
12
  // the user double-clicks the dock icon (macOS) or relaunches the app (win/linux).
13
13
  // In hidden launches (agent / menubar apps with `startup.mode = 'hidden'`, or auto-
14
14
  // launch at login), pass `show: false` so the window is registered but invisible:
@@ -43,7 +43,7 @@ omega.initialize()
43
43
  // },
44
44
  // });
45
45
 
46
- // Secondary windows — built-in defaults (800x600, hideOnClose:false) are good
46
+ // Secondary windows: built-in defaults (800x600, hideOnClose:false) are good
47
47
  // enough for most cases. Examples:
48
48
  //
49
49
  // windows.create('settings'); // baked defaults
@@ -5,7 +5,7 @@ omega.initialize()
5
5
  .then(() => {
6
6
  const { logger } = omega;
7
7
 
8
- // Add any extra contextBridge-exposed APIs here. Be careful — anything you expose runs
8
+ // Add any extra contextBridge-exposed APIs here. Be careful: anything you expose runs
9
9
  // in the renderer's context, so don't pass through privileged Node APIs without care.
10
10
  // ...
11
11
 
@@ -4,7 +4,7 @@ Drop your project test suites here. The framework auto-runs them alongside its o
4
4
 
5
5
  ## Layers
6
6
 
7
- Match the framework's four layers — OMEGA Desktop's test runner discovers files by the directory they sit in:
7
+ Match the framework's four layers. OMEGA Desktop's test runner discovers files by the directory they sit in:
8
8
 
9
9
  | Directory | Runtime | Use for |
10
10
  |---|---|---|
@@ -17,7 +17,7 @@ A renderer suite that declares `view: '<name>'` runs against that view of YOUR a
17
17
 
18
18
  ## Coverage
19
19
 
20
- Every feature ships with tests at every layer it has a surface in — logic (`build`/`main`), UI (`renderer`), end-to-end (`boot`). Skip a layer only when the feature genuinely has no surface there; "the logic test covers it" does not excuse the UI test.
20
+ Every feature ships with tests at every layer it has a surface in: logic (`build`/`main`), UI (`renderer`), end-to-end (`boot`). Skip a layer only when the feature genuinely has no surface there; "the logic test covers it" does not excuse the UI test.
21
21
 
22
22
  ## Quick example
23
23
 
@@ -38,4 +38,4 @@ That is the standalone form: one test per file. Every `run` receives `ctx`, whos
38
38
 
39
39
  ## See also
40
40
 
41
- `node_modules/@omega.js/desktop/docs/test-framework.md` — full reference for the test framework (layers, assert API, fixtures, runner internals).
41
+ `node_modules/@omega.js/manager/docs/desktop/test-framework.md`: full reference for the test framework (layers, assert API, fixtures, runner internals).
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Test lifecycle hook for this project. Runs once before any suite (not a test itself).
3
- * See @omega.js/desktop/docs/test-framework.md → "test/_init.js".
3
+ * See @omega.js/manager/docs/desktop/test-framework.md → "test/_init.js".
4
4
  */
5
5
 
6
6
  module.exports = ({ projectRoot }) => ({
@@ -38,16 +38,13 @@ module.exports = function audit(done) {
38
38
 
39
39
  // 1. Schema-driven config validation. Single source of truth in @omega.js/config
40
40
  // (shared schema + the desktop target refinements).
41
- const { errors: schemaErrors } = validateConfig(config, { target: 'desktop' });
41
+ // build.getConfig() attaches `environment`, a build fact: the config is decorated
42
+ const { errors: schemaErrors } = validateConfig(config, { target: 'desktop', decorated: true });
42
43
  errors.push(...schemaErrors);
43
44
 
44
- // ...and the validator's WARNINGS, which this task used to drop on the floor
45
- // while reporting `0 warnings` ([#911](https://github.com/Omega-JS-Stack/omega/issues/911)).
46
- // A key the schema does not declare is what a typo looks like, and the
47
- // consumer has to see it at build time. They come off the LOAD, the same
48
- // resolution `build.getConfig()` runs: loadConfig judges what the brand
49
- // AUTHORED, before the loader fills its own resolved facts (`company.name`
50
- // and friends) and before the build attaches `environment`.
45
+ // ...and the load's WARNINGS (an undeclared key is an ERROR, above). They
46
+ // come off the LOAD, the resolution `build.getConfig()` runs, which judges
47
+ // what the brand AUTHORED before the build attaches its own facts.
51
48
  const { warnings: configWarnings } = hasOmegaConfig(cwd)
52
49
  ? loadConfig(cwd, 'desktop', { environment: build.getEnvironment() })
53
50
  : { warnings: [] };
@@ -35,7 +35,7 @@
35
35
  // - config.restartManager.enabled === false
36
36
  // - non-production without OMEGA_RESTART_MANAGER_DEV=1 (dev noise guard)
37
37
  //
38
- // Full reference: docs/restart-manager.md.
38
+ // Full reference: docs/desktop/restart-manager.md.
39
39
 
40
40
  const path = require('path');
41
41
  const fs = require('fs');
@@ -19,7 +19,7 @@
19
19
  // the same machine from running installers concurrently; RM itself ignores it.
20
20
  //
21
21
  // Pure helpers (parseFeed, pickArtifact, URL builders) are exported individually
22
- // for build-layer tests. See docs/restart-manager.md.
22
+ // for build-layer tests. See docs/desktop/restart-manager.md.
23
23
 
24
24
  const path = require('path');
25
25
  const fs = require('fs');
@@ -29,7 +29,7 @@
29
29
  // storage-persisted, so they survive the update relaunch). @omega.js/desktop's lib only ever
30
30
  // installs RM when it's missing.
31
31
  //
32
- // Full reference: docs/restart-manager.md.
32
+ // Full reference: docs/desktop/restart-manager.md.
33
33
 
34
34
  const path = require('path');
35
35
 
package/dist/main.js CHANGED
@@ -113,7 +113,7 @@ class Omega {
113
113
  }
114
114
 
115
115
  /**
116
- * Boot the main process in the fixed order (docs/boot-sequence.md), and
116
+ * Boot the main process in the fixed order (docs/desktop/boot-sequence.md), and
117
117
  * settle `ready`.
118
118
  * @param {object|string} [consumerConfig] - a RESOLVED config, a project dir to resolve one from, or nothing.
119
119
  * @param {object} [options] - boot options (the test harness passes `skipWindowCreation`).
@@ -196,7 +196,8 @@ class Omega {
196
196
  // fails loud + early instead of partway through boot with a confusing stack trace.
197
197
  {
198
198
  const { validateConfig, formatErrors } = require('./vendor/config/index.js');
199
- const { errors } = validateConfig(this.config, { target: 'desktop' });
199
+ // A packaged app's config is baked, build facts included: validate it as decorated
200
+ const { errors } = validateConfig(this.config, { target: 'desktop', decorated: true });
200
201
  if (errors.length > 0) {
201
202
  throw new Error(`@omega.js/desktop: config validation failed. Fix the following in config/omega.json5:\n${formatErrors(errors)}`);
202
203
  }
@@ -412,7 +413,7 @@ class Omega {
412
413
  // when missing (mac zip / win silent NSIS / linux AppImage; RM then self-updates
413
414
  // via its own @omega.js/desktop autoUpdater). Skips itself when this app IS restart-manager, in
414
415
  // dev (unless OMEGA_RESTART_MANAGER_DEV=1), or when restartManager.enabled=false.
415
- // See docs/restart-manager.md.
416
+ // See docs/desktop/restart-manager.md.
416
417
  this.restartManager.initialize(this);
417
418
 
418
419
  // 13. Initialize the windows lib: registers app-level handlers (window-all-closed, etc.)
package/dist/preload.js CHANGED
@@ -60,7 +60,7 @@ class Omega {
60
60
  environment: process.env[ENVIRONMENT_VAR] || null,
61
61
  ipc: {
62
62
  invoke: (channel, payload) => ipcRenderer.invoke(channel, payload),
63
- // Returns an unsubscribe fn (docs/ipc.md contract, same shape as the
63
+ // Returns an unsubscribe fn (docs/desktop/ipc.md contract, same shape as the
64
64
  // sibling onChange subscriptions below).
65
65
  on: (channel, handler) => {
66
66
  const wrapped = (_, payload) => handler(payload);
@@ -103,18 +103,31 @@ module.exports = defineCases({
103
103
  },
104
104
  },
105
105
  {
106
- // #911: the task took only `errors` off validateConfig, so a consumer
107
- // read `audit ok (0 warnings)` while the validator's list named real
108
- // findings (a key the schema does not declare, which is what a typo
109
- // looks like). The report is both lists now.
110
- name: 'prints the validator\'s warnings and counts them (#911)',
106
+ // The schema is strict: a key nothing declares is what a typo (or a
107
+ // legacy shape) looks like, and it fails the build naming the fix.
108
+ name: 'an undeclared key fails the audit, naming omega migrate',
111
109
  run: async (ctx) => {
112
110
  const tmp = stageConsumer({ brand: { id: 'testapp', name: 'TestApp' } }, { notAKey: true });
111
+ try {
112
+ const err = await runAudit(tmp);
113
+ ctx.expect(err).toBeDefined();
114
+ ctx.expect(err.message).toMatch(/config\.notAKey is not a key the schema declares/);
115
+ ctx.expect(err.message).toMatch(/npx omega migrate/);
116
+ } finally {
117
+ fs.rmSync(tmp, { recursive: true, force: true });
118
+ }
119
+ },
120
+ },
121
+ {
122
+ // The resolved config carries the company the loader fills and the
123
+ // environment the build attaches: neither is the brand's key.
124
+ name: 'a clean config passes with the loader-filled and build-attached keys on it',
125
+ run: async (ctx) => {
126
+ const tmp = stageConsumer({ brand: { id: 'testapp', name: 'TestApp' } }, { electronBuilder: { mac: { hardenedRuntime: true } } });
113
127
  try {
114
128
  const { err, output } = await runAuditCapturing(tmp);
115
129
  ctx.expect(err).toBeNull();
116
- ctx.expect(output).toMatch(/notAKey/);
117
- ctx.expect(output).toMatch(/audit ok \(1 warning\)/);
130
+ ctx.expect(output).toMatch(/audit ok \(0 warnings\)/);
118
131
  } finally {
119
132
  fs.rmSync(tmp, { recursive: true, force: true });
120
133
  }