@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
package/README.md CHANGED
@@ -21,11 +21,11 @@
21
21
  - **Lazy windows + Discord-style hide-on-close.** @omega.js/desktop doesn't auto-create any windows — your `main.js` calls `windows.create('main', { show: !startup.isLaunchHidden() })`. The `main` window's X button hides instead of quitting on every platform; real quit only via Cmd+Q / menu Quit / tray Quit / auto-update install. Inset titlebar by default (mac `hiddenInset` traffic lights / win native overlay buttons / linux native frame) with a draggable topbar in the page template.
22
22
  - **Zero-bounce hidden-launch on macOS.** `startup.mode = 'hidden'` bakes `LSUIElement: true` into Info.plist at build time → app launches completely invisible (no dock icon, no Cmd+Tab, no taskbar). Tray + notifications + networking still work. When the user double-clicks the running app's icon, @omega.js/desktop's `app.on('activate')` (macOS) / `app.on('second-instance')` (win/linux) handler surfaces the `main` window and the dock icon appears alongside it. CleanMyMac-style "tray-only at login, full window when manually opened" is the default.
23
23
  - **Auto-update background install.** When a download finishes from a background poll (not user-initiated), @omega.js/desktop auto-relaunches into the new version after 5s — apps update overnight without bothering the user. User-initiated checks skip this so your UI can prompt instead.
24
- - **Vert (ad) units with zero JS.** Drop `<div data-omega-vert></div>` into any view — the renderer auto-binds it (live, MutationObserver) to the shared OMEGA verts module: house/company inventory only (no AdSense in desktop surfaces), lazy near-viewport loading, sandboxed iframe, no-fill collapse. See [verts](docs/verts.md).
24
+ - **Vert (ad) units with zero JS.** Drop `<div data-omega-vert></div>` into any view — the renderer auto-binds it (live, MutationObserver) to the shared OMEGA verts module: house/company inventory only (no AdSense in desktop surfaces), lazy near-viewport loading, sandboxed iframe, no-fill collapse. See [verts](../../docs/desktop/verts.md).
25
25
  - **esbuild-bundled** main / preload / renderer for source protection.
26
26
  - **Built-in test framework**: Jest-like syntax, four layers: `build` (plain Node), `main` (spawned Electron), `renderer` (hidden BrowserWindow), and `boot` (spawns the consumer's actual built `dist/main.bundle.js` for end-to-end smoke tests against the live `omega`, no `npm start && sleep && kill` shell hacks). Boot layer always rebuilds the bundle first so tests never see stale code.
27
- - **Schema-validated config.** One `config/omega.json5` (the OMEGA-wide format: shared brand/analytics/payment/firebase sections + desktop settings under `targets.desktop`), validated against the canonical schema in the bundled `@omega.js/config`. Validation runs at app boot AND during `gulp audit` — a misconfigured app never reaches the "white window of confusion" stage; it tells you exactly which field is broken with a numbered list. Simple flag model — `required: true | false | (config) => bool` — and `match` / `enum` / `type` only fire on field presence so consumers never see a flood of redundant errors for the same field. Pure-JS validator, no Ajv/Joi/Zod dep. See [config-schema](docs/config-schema.md).
28
- - **Multi-platform build/release** via GitHub Actions — macOS sign + notarize, Linux (deb + AppImage + optional Snap), Windows EV-token signing (self-hosted runner now, cloud-signing pluggable). Sensible installer defaults out of the box: NSIS one-click install on Windows (desktop + start menu shortcut, launch on finish), universal mac binary (one .dmg for Intel + Apple Silicon), `app.category` automatically mapped to per-platform values, copyright `{YEAR}` token always current. Snap Store publishing is on by default in the scaffold and auto-skipped at build time when `SNAPCRAFT_STORE_CREDENTIALS` isn't set — drop the credential blob into `.env`, run `mgr push-secrets`, and the next release ships to the Snap Store. See [installer-options](docs/installer-options.md).
27
+ - **Schema-validated config.** One `config/omega.json5` (the OMEGA-wide format: shared brand/analytics/payment/firebase sections + desktop settings under `targets.desktop`), validated against the canonical schema in the bundled `@omega.js/config`. Validation runs at app boot AND during `gulp audit` — a misconfigured app never reaches the "white window of confusion" stage; it tells you exactly which field is broken with a numbered list. Simple flag model — `required: true | false | (config) => bool` — and `match` / `enum` / `type` only fire on field presence so consumers never see a flood of redundant errors for the same field. Pure-JS validator, no Ajv/Joi/Zod dep. See [config-schema](../../docs/desktop/config-schema.md).
28
+ - **Multi-platform build/release** via GitHub Actions — macOS sign + notarize, Linux (deb + AppImage + optional Snap), Windows EV-token signing (self-hosted runner now, cloud-signing pluggable). Sensible installer defaults out of the box: NSIS one-click install on Windows (desktop + start menu shortcut, launch on finish), universal mac binary (one .dmg for Intel + Apple Silicon), `app.category` automatically mapped to per-platform values, copyright `{YEAR}` token always current. Snap Store publishing is on by default in the scaffold and auto-skipped at build time when `SNAPCRAFT_STORE_CREDENTIALS` isn't set — drop the credential blob into `.env`, run `mgr push-secrets`, and the next release ships to the Snap Store. See [installer-options](../../docs/desktop/installer-options.md).
29
29
 
30
30
  ## Quick start (consumer)
31
31
 
@@ -36,11 +36,11 @@ npm install @omega.js/desktop --save-dev
36
36
  nvm use # switch to the Node version Electron uses (one-time per shell)
37
37
  npm start # dev: gulp → esbuild → electron .
38
38
  OMEGA_CDP_PORT=9222 npm start # dev + expose Chrome DevTools Protocol for Claude/MCP debugging
39
- npx omega cdp status # drive the running dev app over CDP: status|eval|shot|capture|theme|relaunch|quit (docs/cdp-debugging.md)
39
+ npx omega cdp status # drive the running dev app over CDP: status|eval|shot|capture|theme|relaunch|quit (docs/desktop/cdp-debugging.md)
40
40
  npm run build # local production build (bundles only, no installer)
41
41
  npm run package:quick # fast packaged build for host platform/arch (.app/.exe-folder/linux-unpacked, ~20-30s) — for smoke-testing packaged behavior
42
42
  npm run package # full local production package (DMG/zip/universal-mac, NSIS-win, deb+AppImage-linux)
43
- npm run release # signed + published release via GitHub Actions
43
+ npx omega release # signed + published release via GitHub Actions
44
44
  npx omega test # YOUR project tests only (C5 scoping — docs/shared/testing.md)
45
45
  npx omega test framework: # the framework's own suite (aliases: omega:, mgr:, desktop:, em:; add a path to narrow)
46
46
  npx omega test full: # both sources
@@ -82,7 +82,7 @@ Five logs in `<projectRoot>/logs/`, each with its own purpose:
82
82
  | `dev.log` | Gulp pipeline output — sass, bundle, html, electron child stdout from `npm start` | Truncated each `npm start` |
83
83
  | `build.log` | Gulp pipeline output for production builds/packages (`npm run build` / `package` / `publish`, i.e. `OMEGA_BUILD_MODE=true`) | Truncated each build |
84
84
  | `test.log` | `npx omega test` runner output (suite names, pass/fail, harness boot lines) | Truncated each test run |
85
- | `deploy.log` | `omega deploy` and `npm run release`, the whole deploy: the scaffold, the precheck, the dispatch, then the streamed GH Actions run | Truncated each deploy |
85
+ | `deploy.log` | `omega deploy` and `omega release`, the whole deploy: the scaffold, the precheck, the dispatch, then the streamed GH Actions run | Truncated each deploy |
86
86
 
87
87
  ```bash
88
88
  npx omega logs # tail last 50 of runtime.log
@@ -96,7 +96,7 @@ In production, `runtime.log` lives at `app.getPath('logs')`:
96
96
  - Windows: `%APPDATA%\<AppName>\logs\runtime.log`
97
97
  - Linux: `~/.config/<AppName>/logs/runtime.log`
98
98
 
99
- See [docs/logging.md](docs/logging.md) for the full picture (renderer forwarding, log levels, programmatic path access).
99
+ See [docs/desktop/logging.md](../../docs/desktop/logging.md) for the full picture (renderer forwarding, log levels, programmatic path access).
100
100
 
101
101
  Override gulp's `dev.log` path via `OMEGA_LOG_FILE=<path>`; disable entirely via `OMEGA_LOG_FILE=false`. The default `.gitignore` includes `logs/`.
102
102
 
@@ -131,40 +131,40 @@ omega.initialize().then(() => { const { logger, desktop } = omega; });
131
131
 
132
132
  ## Documentation
133
133
 
134
- Each subsystem has its own API reference under [`docs/`](docs/):
135
-
136
- - [storage](docs/storage.md) — KV store, sync in main, async (via IPC) in renderer, dot-notation paths, change broadcasts
137
- - [ipc](docs/ipc.md) — typed channel bus, `handle` / `invoke` / `broadcast`
138
- - [windows](docs/windows.md) — lazy named-window registry (no auto-create), bounds persistence, inset titlebar, hide-on-close
139
- - [tray](docs/tray.md) — file-based tray definition, dynamic items, runtime mutators
140
- - [menu](docs/menu.md) — file-based application menu, platform-aware default template
141
- - [context-menu](docs/context-menu.md) — file-based right-click menus, called per-event with `params`
142
- - [startup](docs/startup.md) — launch modes (`normal` / `hidden`), LSUIElement on macOS, login-item handling
143
- - [app-state](docs/app-state.md) — first-launch / launch-count / crash-sentinel flags
144
- - [deep-link](docs/deep-link.md) — cross-platform deep links, single-instance, pattern routing, built-in routes
145
- - [auth](docs/auth.md): `omega.auth`, Firebase auth state synchronized across main + every renderer
146
- - [auto-updater](docs/auto-updater.md) — startup + periodic checks, 30-day max-age gate, dev simulation
147
- - [analytics](docs/analytics.md) — GA4 Measurement Protocol with cross-platform `uuidv5` identity (same human → same `user_id` across desktop/web/backend)
148
- - [context](docs/context.md) — runtime info block (geolocation, client, session, app) — @omega.js/backend-shaped
149
- - [usage](docs/usage.md) — opens / hoursTotal / hoursThisSession; clean-exit accumulation
150
- - [remote-config](docs/remote-config.md) — "hot config" fetched from brand site for runtime flag flips without re-releases
151
- - [restart-manager](docs/restart-manager.md) — auxiliary helper app for relaunches; auto-installs via signed mac.zip / NSIS exe / browser-opened .deb
152
- - [config-schema](docs/config-schema.md) — canonical schema + validator for `config/omega.json5`. Hard-fails boot AND `gulp audit` on missing required fields, regex mismatches, enum violations, type mismatches. Single source of truth in the bundled `@omega.js/config`
153
- - [templating](docs/templating.md) — `{{ var }}` token replacement, page template, body-only views
154
- - [themes](docs/themes.md): classy + bootstrap themes, `@use 'omega-desktop' as * with (...)` overrides, per-page CSS bundles, system-aware appearance (`omega.theme`)
155
- - [sentry](docs/sentry.md) — error/crash reporting, dev-mode gating, auto auth attribution, release tagging
156
- - [hooks](docs/hooks.md) — lifecycle hooks (build/pre, build/post, release/pre, release/post, notarize)
157
- - [installer-options](docs/installer-options.md) — installer/distribution config: NSIS one-click defaults, ia32 inclusion, app.category mapping, `{YEAR}` copyright token, snap publishing (default-on with cred-gated auto-skip), MAS roadmap
158
- - [signing](docs/signing.md) — macOS + Windows code signing reference, cert files, env vars
159
- - [releasing](docs/releasing.md) — end-to-end release walkthrough (`.env` → GitHub Release)
160
- - [runner](docs/runner.md) — Windows EV-token signing runner — `npx omega runner start`, which onboards new GH orgs, `npx omega runner monitor` for a live signing event tail
161
- - [test-framework](docs/test-framework.md) — writing tests, running them, layers
162
- - [test-boot-layer](docs/test-boot-layer.md) — boot test layer (spawns the consumer's actual built bundle for end-to-end smoke tests)
163
- - [build-system](docs/build-system.md) — gulp, esbuild, electron-builder pipeline
134
+ Each subsystem has its own API reference under [`docs/desktop/`](../../docs/desktop):
135
+
136
+ - [storage](../../docs/desktop/storage.md) — KV store, sync in main, async (via IPC) in renderer, dot-notation paths, change broadcasts
137
+ - [ipc](../../docs/desktop/ipc.md) — typed channel bus, `handle` / `invoke` / `broadcast`
138
+ - [windows](../../docs/desktop/windows.md) — lazy named-window registry (no auto-create), bounds persistence, inset titlebar, hide-on-close
139
+ - [tray](../../docs/desktop/tray.md) — file-based tray definition, dynamic items, runtime mutators
140
+ - [menu](../../docs/desktop/menu.md) — file-based application menu, platform-aware default template
141
+ - [context-menu](../../docs/desktop/context-menu.md) — file-based right-click menus, called per-event with `params`
142
+ - [startup](../../docs/desktop/startup.md) — launch modes (`normal` / `hidden`), LSUIElement on macOS, login-item handling
143
+ - [app-state](../../docs/desktop/app-state.md) — first-launch / launch-count / crash-sentinel flags
144
+ - [deep-link](../../docs/desktop/deep-link.md) — cross-platform deep links, single-instance, pattern routing, built-in routes
145
+ - [auth](../../docs/desktop/auth.md): `omega.auth`, Firebase auth state synchronized across main + every renderer
146
+ - [auto-updater](../../docs/desktop/auto-updater.md) — startup + periodic checks, 30-day max-age gate, dev simulation
147
+ - [analytics](../../docs/desktop/analytics.md) — GA4 Measurement Protocol with cross-platform `uuidv5` identity (same human → same `user_id` across desktop/web/backend)
148
+ - [context](../../docs/desktop/context.md) — runtime info block (geolocation, client, session, app) — @omega.js/backend-shaped
149
+ - [usage](../../docs/desktop/usage.md) — opens / hoursTotal / hoursThisSession; clean-exit accumulation
150
+ - [remote-config](../../docs/desktop/remote-config.md) — "hot config" fetched from brand site for runtime flag flips without re-releases
151
+ - [restart-manager](../../docs/desktop/restart-manager.md) — auxiliary helper app for relaunches; auto-installs via signed mac.zip / NSIS exe / browser-opened .deb
152
+ - [config-schema](../../docs/desktop/config-schema.md) — canonical schema + validator for `config/omega.json5`. Hard-fails boot AND `gulp audit` on missing required fields, regex mismatches, enum violations, type mismatches. Single source of truth in the bundled `@omega.js/config`
153
+ - [templating](../../docs/desktop/templating.md) — `{{ var }}` token replacement, page template, body-only views
154
+ - [themes](../../docs/desktop/themes.md): classy + bootstrap themes, `@use 'omega-desktop' as * with (...)` overrides, per-page CSS bundles, system-aware appearance (`omega.theme`)
155
+ - [sentry](../../docs/desktop/sentry.md) — error/crash reporting, dev-mode gating, auto auth attribution, release tagging
156
+ - [hooks](../../docs/desktop/hooks.md) — lifecycle hooks (build/pre, build/post, release/pre, release/post, notarize)
157
+ - [installer-options](../../docs/desktop/installer-options.md) — installer/distribution config: NSIS one-click defaults, ia32 inclusion, app.category mapping, `{YEAR}` copyright token, snap publishing (default-on with cred-gated auto-skip), MAS roadmap
158
+ - [signing](../../docs/desktop/signing.md) — macOS + Windows code signing reference, cert files, env vars
159
+ - [releasing](../../docs/desktop/releasing.md) — end-to-end release walkthrough (`.env` → GitHub Release)
160
+ - [runner](../../docs/desktop/runner.md) — Windows EV-token signing runner — `npx omega runner start`, which onboards new GH orgs, `npx omega runner monitor` for a live signing event tail
161
+ - [test-framework](../../docs/desktop/test-framework.md) — writing tests, running them, layers
162
+ - [test-boot-layer](../../docs/desktop/test-boot-layer.md) — boot test layer (spawns the consumer's actual built bundle for end-to-end smoke tests)
163
+ - [build-system](../../docs/desktop/build-system.md) — gulp, esbuild, electron-builder pipeline
164
164
 
165
165
  ## Status
166
166
 
167
- Active development on `v1`. See [`PROGRESS.md`](PROGRESS.md) for pass-by-pass progress.
167
+ Active development on `v1`.
168
168
 
169
169
  ## License
170
170
 
package/dist/cli-run.js CHANGED
@@ -9,7 +9,7 @@
9
9
  const BOOLEAN_FLAGS = [
10
10
  'extended', 'local', 'quick', 'q', 'direct', 'dry-run', 'secrets',
11
11
  'smoke', 'verify-only', 'find-window-id', 'publish', 'open', 'tail', 'f', 'strict',
12
- 'apply', 'major', 'force-fresh',
12
+ 'major', 'force-fresh',
13
13
  ];
14
14
 
15
15
  async function run() {
@@ -39,3 +39,6 @@ async function run() {
39
39
  }
40
40
 
41
41
  module.exports = { run, BOOLEAN_FLAGS };
42
+
43
+ // Runnable as a file: the package's own `npm test` calls it directly, never through the dispatcher
44
+ if (require.main === module) run();
package/dist/cli.js CHANGED
@@ -36,14 +36,14 @@ module.exports = createCliRouter({
36
36
  defaultCommand: 'help',
37
37
  aliases: {
38
38
  clean: ['-c', '--clean'],
39
- install: ['-i', 'i', '--install'],
39
+ dev: ['serve', 'start', '--dev'],
40
40
  version: ['-v', '--version'],
41
41
  build: ['-b', '--build'],
42
42
  deploy: ['-d', '--deploy'],
43
43
  publish: ['-p', '--publish'],
44
44
  release: ['-r', '--release'],
45
45
  test: ['-t', '--test'],
46
- update: ['-u', '--update', 'outdated', 'out'],
46
+ update: ['-u', '--update'],
47
47
  logs: ['--logs', 'log'],
48
48
  'validate-certs': ['certs', '--validate-certs'],
49
49
  'sign-windows': ['--sign-windows'],
@@ -7,7 +7,7 @@
7
7
  // matcher instead of a "selected page"; the main window's document is always
8
8
  // at `dist/views/main/` (the MAIN_VIEW default matcher).
9
9
  //
10
- // See docs/cdp-debugging.md for the full toolkit reference.
10
+ // See docs/desktop/cdp-debugging.md for the full toolkit reference.
11
11
 
12
12
  // The main window's view path — @omega.js/desktop's templating convention, so it holds for
13
13
  // every consumer. Subcommands that need "the app's main renderer" (status,
@@ -16,7 +16,7 @@
16
16
  // MANGLES quoted eval expressions (cross-env strips inner quotes), so a
17
17
  // pinned-port script must pass the port as a flag instead. Targets are
18
18
  // matched by URL substring (the main window is always `/views/main/`).
19
- // Full reference: docs/cdp-debugging.md.
19
+ // Full reference: docs/desktop/cdp-debugging.md.
20
20
 
21
21
  const path = require('path');
22
22
 
@@ -13,9 +13,8 @@ const dirs = [
13
13
  ];
14
14
 
15
15
  module.exports = async function (options) {
16
- // The local scaffold (#675): the consumer `start` script is
17
- // `omega clean && npm run gulp --`, and gulp itself is one of the peer
18
- // deps the ensure installs — clean is the only verb that runs before it.
16
+ // The local scaffold: dev, build and package clean before gulp runs,
17
+ // and gulp itself is one of the peer deps the ensure installs.
19
18
  await ensureTarget({ log: (line) => logger.log(line), warn: (line) => logger.warn(line) });
20
19
 
21
20
  // Quick mode used to keep `dist/` so "the next gulp run is incremental" —
@@ -0,0 +1,25 @@
1
+ // Libraries
2
+ const build = require('../build.js');
3
+ const logger = build.logger('dev');
4
+ const { runPipeline } = require('../utils/build-pipeline.js');
5
+
6
+ // The local dev loop the target's `start` script runs: clean (which runs the
7
+ // local scaffold), then the gulp default task, build then launch electron. The
8
+ // `--` flags it was given ride to the gulp lane (`--debug`, `--remote-debugging-port=<n>`).
9
+ function plan(options, argv = process.argv.slice(2)) {
10
+ return {
11
+ env: {},
12
+ steps: [
13
+ { type: 'clean' },
14
+ { type: 'gulp', task: 'default', args: argv.filter((arg) => arg.startsWith('--')) },
15
+ ],
16
+ };
17
+ }
18
+
19
+ module.exports = async function (options) {
20
+ logger.log('Starting the dev loop...');
21
+
22
+ await runPipeline(plan(options), options);
23
+ };
24
+
25
+ module.exports.plan = plan;
@@ -20,7 +20,8 @@
20
20
  * peer dependencies installed when missing or behind (a satisfied target
21
21
  * installs nothing)
22
22
  * defaults tree src/defaults/** — copy-if-missing, marker merges for
23
- * .env/.gitignore/AGENTS.md, workflows re-rendered
23
+ * .env/.gitignore, workflows re-rendered
24
+ * AGENTS.md standalone only, through devkit's one builder
24
25
  * locality a WARNING when the framework is a `file:` link
25
26
  *
26
27
  * Everything here is copy-if-missing, marker-merge or write-if-changed. What
@@ -36,6 +37,8 @@ const { ensurePeerDependencies, readProject } = require('./dependencies.js');
36
37
  const { renderSecretsBlock } = require('../../vendor/config/env-delivery.js');
37
38
  const { composeTargetWorkflows, renderInstallFirewall, renderInstallWorkspace } = require('../../vendor/devkit/ci-workflows.js');
38
39
  const { assertScaffoldable } = require('../../vendor/devkit/scaffold-guard.js');
40
+ const { scaffoldAgentsMd } = require('../../vendor/devkit/agents-md.js');
41
+ const { projectScripts } = require('../../vendor/devkit/verb-scripts.js');
39
42
 
40
43
  const logger = build.logger('ensure-target');
41
44
  const package = build.getPackage('main');
@@ -52,11 +55,8 @@ function setupScripts(projectDir, result) {
52
55
 
53
56
  const project = readProject(projectDir);
54
57
 
55
- project.scripts = project.scripts || {};
56
-
57
- Object.keys(package.projectScripts || {}).forEach((key) => {
58
- project.scripts[key] = package.projectScripts[key];
59
- });
58
+ // The verb table's scripts for this framework, the manifest's declarations over them
59
+ project.scripts = { ...project.scripts, ...projectScripts(package) };
60
60
 
61
61
  // Electron consumer projects should not be published to npm
62
62
  project.private = true;
@@ -195,18 +195,10 @@ async function copyDefaults(projectDir, engineLogger) {
195
195
  // material really lives, so a target keeps the explanation that matches
196
196
  // the ignore rules the scaffold just wrote, never an older one.
197
197
  'config/certs/README.md': { overwrite: true },
198
- // The agent-docs chain (#63): AGENTS.md carries the content (marker-merged
199
- // like .gitignore), CLAUDE.md is the one-line `@AGENTS.md` pointer — copied
200
- // when missing by the `**/*` rule above, never clobbered.
201
- 'AGENTS.md': { mergeLines: true, template: templateContext },
202
- // Brand doc unification (Ian 2026-07-20): inside a brand monorepo the
203
- // BRAND ROOT is the one doc home — per-target AGENTS.md/CLAUDE.md/CHANGELOG.md/docs/
204
- // never scaffold, and existing framework-owned-only copies are swept
205
- // (retire rules; consumer content is never destroyed). Standalone projects
206
- // keep them. Last-match-wins: these override the rules above.
198
+ // In a brand the BRAND ROOT is the one doc home: per-target CHANGELOG.md
199
+ // and docs/ never scaffold, and framework-owned copies are swept (consumer
200
+ // content is kept). Last-match-wins over the rules above.
207
201
  ...(isBrandTarget ? {
208
- 'AGENTS.md': { retire: true, template: templateContext },
209
- 'CLAUDE.md': { retire: true, template: templateContext },
210
202
  'CHANGELOG.md': { retire: true },
211
203
  'docs/**/*': { retire: true },
212
204
  } : {}),
@@ -235,6 +227,9 @@ async function copyDefaults(projectDir, engineLogger) {
235
227
  logger: engineLogger,
236
228
  });
237
229
 
230
+ // The project-root AGENTS.md, through devkit's one builder.
231
+ scaffoldAgentsMd({ outputDir: projectDir, standalone: seed.standalone, result: applied, logger: engineLogger });
232
+
238
233
  if (isBrandTarget) {
239
234
  // The same templateContext the yml rule uses, so the composed copy carries
240
235
  // the generated `githubSecrets` block — a composed workflow with the raw
@@ -0,0 +1,17 @@
1
+ /**
2
+ * migrateTarget: the desktop leg of the brand root's `omega migrate`. No
3
+ * legacy electron-manager shape converts mechanically yet (the register's
4
+ * by-hand steps cover them), so it answers the shared shape with nothing due.
5
+ * Every framework exposes this entry, so the manager's walk never special-cases
6
+ * a framework name.
7
+ *
8
+ * @param {string} targetDir - the desktop target's root
9
+ * @param {object} [options]
10
+ * @param {boolean} [options.execute] - convert (default: report only)
11
+ * @returns {{ due: string[], changed: string[], errors: string[] }}
12
+ */
13
+ function migrateTarget(targetDir, options = {}) {
14
+ return { due: [], changed: [], errors: [] };
15
+ }
16
+
17
+ module.exports = { migrateTarget };
@@ -3,7 +3,7 @@
3
3
  //
4
4
  // The optional positional names the surface (default `runtime`) and resolves to
5
5
  // <projectRoot>/logs/<surface>.log — the same four files documented in
6
- // docs/logging.md. Every flag below works on whichever surface was named.
6
+ // docs/desktop/logging.md. Every flag below works on whichever surface was named.
7
7
  //
8
8
  // `runtime` resolves to the file the runtime logger writes to:
9
9
  // - Dev (running from a project directory): <projectRoot>/logs/runtime.log
@@ -2,7 +2,7 @@
2
2
  // run it started.
3
3
  //
4
4
  // Replaces the old "do it from my laptop" release flow with "let CI do it, but make it
5
- // feel local." User runs `npm run release` (or `npx omega release`) and gets:
5
+ // feel local." User runs `npx omega release` and gets:
6
6
  // 1. The ONE deploy lane every target takes (`@omega.js/devkit/deploy`'s
7
7
  // deployViaDispatch, #872, #915): the composed workflow files reach the
8
8
  // default branch when they differ there (GitHub registers a workflow from
@@ -21,7 +21,7 @@ module.exports = async function (options) {
21
21
 
22
22
  // Tee all test output to <projectRoot>/logs/test.log (ANSI-stripped) — mirrors
23
23
  // @omega.js/backend's test.log and @omega.js/desktop's own dev.log pattern.
24
- attachLogFile(path.join(process.cwd(), 'logs', 'test.log'));
24
+ const detachLog = attachLogFile(path.join(process.cwd(), 'logs', 'test.log'));
25
25
 
26
26
  // The local half of the retired `omega setup` (#675) — idempotent, offline,
27
27
  // and quiet on a converged target. The gulp verbs get it from the `defaults`
@@ -104,19 +104,19 @@ module.exports = async function (options) {
104
104
  // ONE target to every target, so a distinct code lets it count this as a
105
105
  // miss rather than a failure (#814).
106
106
  process.exitCode = noMatchExitCode();
107
- await attachLogFile.detach();
107
+ detachLog();
108
108
  return;
109
109
  }
110
110
 
111
111
  if (result.failed > 0) {
112
112
  process.exitCode = 1;
113
- await attachLogFile.detach();
113
+ detachLog();
114
114
  throw new Error(`${result.failed} test(s) failed`);
115
115
  }
116
116
 
117
117
  // Close test.log before exiting. Nothing to flush: every write already went
118
118
  // to the fd synchronously (#197), so the Results block survives the exit
119
119
  // below whatever happens — detach() just closes the handle.
120
- await attachLogFile.detach();
120
+ detachLog();
121
121
  process.exit(0);
122
122
  };
@@ -1,9 +1,10 @@
1
1
  /**
2
- * `omega update` — dependency freshness report (npu-outdated semantics):
2
+ * `omega update` — dependency freshness (npu-outdated semantics):
3
3
  * installed/wanted/latest + patch/minor/major per dep, releases younger than
4
- * --min-age days (default 7) QUARANTINED. `--apply` installs the
4
+ * --min-age days (default 7) QUARANTINED. A bare run installs the
5
5
  * non-quarantined, non-breaking set (`--major` opts into breaking) through
6
- * npu when present. The whole verb is the shared devkit implementation.
6
+ * npu when present; `--dry-run` reports and installs nothing. The whole verb
7
+ * is the shared devkit implementation.
7
8
  */
8
9
  const build = require('../build.js');
9
10
  const logger = build.logger('update');
@@ -12,7 +13,7 @@ const { runUpdate } = require('../vendor/devkit/update.js');
12
13
  module.exports = async function (options) {
13
14
  await runUpdate({
14
15
  dir: process.cwd(),
15
- apply: options.apply,
16
+ dryRun: options.dryRun || options['dry-run'],
16
17
  major: options.major,
17
18
  minAge: options.minAge ?? options['min-age'],
18
19
  forceFresh: options.forceFresh || options['force-fresh'],
@@ -27,7 +27,7 @@ env:
27
27
  # `KEY: ${{ secrets.KEY }}` line per `delivery: { desktop: 'ci' | 'bake' }`
28
28
  # entry (@omega.js/config's env-delivery.js), re-rendered by every verb's
29
29
  # ensureTarget. Signing, notarization, store and analytics credentials all
30
- # arrive here, workflow-wide — the jobs and steps below consume them without
30
+ # arrive here, workflow-wide: the jobs and steps below consume them without
31
31
  # restating one. Add a key to the schema, not to this file.
32
32
  {{ githubSecrets }}
33
33
 
@@ -103,7 +103,7 @@ jobs:
103
103
 
104
104
  {{ installFirewall }}
105
105
 
106
- # On Windows, force cmd for every shell step in this job — the runner's default
106
+ # On Windows, force cmd for every shell step in this job: the runner's default
107
107
  # is PowerShell 7 which has its own ExecutionPolicy/wrapping quirks that cause
108
108
  # `npm ci` and similar to exit silently with no captured output. cmd has none
109
109
  # of that. mac/linux use their default bash regardless of this flag (per
@@ -135,7 +135,7 @@ jobs:
135
135
  echo "NPM: $(npm -v)"
136
136
  echo "Omega: $(node "${{ github.workspace }}/node_modules/@omega.js/desktop/bin/omega" version)"
137
137
 
138
- # macOS — decode signing assets from secrets, then sign + notarize + publish.
138
+ # macOS: decode signing assets from secrets, then sign + notarize + publish.
139
139
  # `npx omega deploy`'s precheck uploads .p12 / .p8 files as base64-encoded secrets;
140
140
  # the workflow decodes them back to disk for electron-builder + notarytool to read.
141
141
  # Each decode is gated on its secret EXISTING (#872): `base64 --decode` of an
@@ -150,13 +150,13 @@ jobs:
150
150
  if [ -n "${{ secrets.CSC_LINK }}" ]; then
151
151
  echo "${{ secrets.CSC_LINK }}" | base64 --decode > config/certs/dev-id.p12
152
152
  else
153
- echo "No CSC_LINK secret: run omega deploy from targets/desktop (its precheck pushes them). A mac build must be signed."
153
+ echo "No CSC_LINK secret: run omega deploy at the brand root (its precheck pushes them). A mac build must be signed."
154
154
  exit 1
155
155
  fi
156
156
  if [ -n "${{ secrets.APPLE_API_KEY }}" ]; then
157
157
  echo "${{ secrets.APPLE_API_KEY }}" | base64 --decode > config/certs/AuthKey.p8
158
158
  else
159
- echo "No APPLE_API_KEY secret: run omega deploy from targets/desktop (its precheck pushes them). A mac build must be notarized."
159
+ echo "No APPLE_API_KEY secret: run omega deploy at the brand root (its precheck pushes them). A mac build must be notarized."
160
160
  exit 1
161
161
  fi
162
162
  # The two file-path OVERRIDES of the workflow env: electron-builder and
@@ -176,7 +176,7 @@ jobs:
176
176
  # Linux: install snapcraft when (a) the brand still SHIPS the snap format
177
177
  # (`platforms.linux.formats.snap`, on unless dropped with `false`) AND
178
178
  # (b) SNAPCRAFT_STORE_CREDENTIALS is set as a repo secret. Without the secret we
179
- # skip snapcraft install entirely — build-config.js auto-skips the snap target on
179
+ # skip snapcraft install entirely: build-config.js auto-skips the snap target on
180
180
  # the same condition, so the build still produces .deb + .AppImage cleanly with
181
181
  # no snap publish attempt and no failure.
182
182
  - name: Install Snapcraft (Linux, when snap enabled + creds present)
@@ -192,7 +192,7 @@ jobs:
192
192
  CONFIG_OK=0
193
193
  echo "platforms.linux.formats.snap is dropped, skipping snapcraft install."
194
194
  fi
195
- # (b) Credentials check — empty secret means no publish creds available.
195
+ # (b) Credentials check: empty secret means no publish creds available.
196
196
  if [ -n "$SNAPCRAFT_STORE_CREDENTIALS" ]; then
197
197
  CREDS_OK=1
198
198
  else
@@ -204,7 +204,7 @@ jobs:
204
204
  echo "Snapcraft installed."
205
205
  fi
206
206
 
207
- # Linux — no signing. The workflow env carries the mac credentials as the
207
+ # Linux: no signing. The workflow env carries the mac credentials as the
208
208
  # base64 secrets themselves (only the mac job decodes them to disk), and a
209
209
  # leg that never signs for mac has no business holding them: empty reads as
210
210
  # UNSET after the build's sanitize pass (#872).
@@ -215,18 +215,18 @@ jobs:
215
215
  APPLE_API_KEY: ''
216
216
  run: npm run release:local
217
217
 
218
- # Windows — package (build + electron-builder package) unsigned. We do NOT publish
218
+ # Windows: package (build + electron-builder package) unsigned. We do NOT publish
219
219
  # here. Mac/linux's `npm run release:local` step already created the GH Release via
220
220
  # electron-builder publish; windows-sign uploads signed .exe to that same release.
221
- # shell: cmd as above — PowerShell 7's wrapping breaks long-running npm scripts.
221
+ # shell: cmd as above. PowerShell 7's wrapping breaks long-running npm scripts.
222
222
  - if: matrix.os == 'windows-latest'
223
223
  shell: cmd
224
224
  env:
225
225
  OMEGA_SKIP_WIN_SIGN: 'true'
226
226
  # The workflow env carries the mac signing cert (CSC_LINK is the
227
227
  # base64 .p12 the mac job decodes); electron-builder would otherwise
228
- # try to sign the Windows build with it. Empty reads as UNSET — the
229
- # build's sanitize pass drops it — so this step packages unsigned, as
228
+ # try to sign the Windows build with it. Empty reads as UNSET (the
229
+ # build's sanitize pass drops it), so this step packages unsigned, as
230
230
  # it always did. windows-sign signs separately.
231
231
  CSC_LINK: ''
232
232
  CSC_KEY_PASSWORD: ''
@@ -276,9 +276,9 @@ jobs:
276
276
  name: Sign Windows
277
277
  needs: [setup, build, windows-strategy]
278
278
  # Strategy comes from config platforms.windows.signing.strategy (read by windows-strategy job).
279
- # self-hosted (default) — runs on a self-hosted runner with EV USB token attached
280
- # cloud — runs on hosted windows-latest, calls cloud signing provider
281
- # local — skip this job; sign locally via `npx omega sign-windows`
279
+ # self-hosted (default): runs on a self-hosted runner with EV USB token attached
280
+ # cloud: runs on hosted windows-latest, calls cloud signing provider
281
+ # local: skip this job; sign locally via `npx omega sign-windows`
282
282
  # The trigger half of the signer guard (#875): only a DISPATCH may reach the
283
283
  # box that holds the EV token, so a `pull_request` or `push` trigger added to
284
284
  # this file later skips the sign job instead of signing a stray build. A skip,
@@ -298,7 +298,7 @@ jobs:
298
298
  defaults:
299
299
  run:
300
300
  shell: cmd
301
- # Signing credentials — self-hosted EV USB token (WIN_EV_TOKEN_PATH,
301
+ # Signing credentials: self-hosted EV USB token (WIN_EV_TOKEN_PATH,
302
302
  # WIN_CSC_KEY_PASSWORD, SIGNTOOL_PATH) and the cloud providers (only the set
303
303
  # `platforms.windows.signing.cloud.provider` names is consumed), all arrive
304
304
  # through the workflow's generated env block. Set them in the brand .env and
@@ -348,11 +348,11 @@ jobs:
348
348
  {{ installFirewall }}
349
349
  - run: sfw npm ci {{ installWorkspace }}
350
350
  # Flip the releases-repo release from Draft to Published so electron-updater
351
- # can read it. Idempotent — safe to run even if already published. ONLY runs
351
+ # can read it. Idempotent: safe to run even if already published. ONLY runs
352
352
  # on all-platforms builds: a partial run (e.g. `--platforms windows`) leaves
353
353
  # the release as a draft, so subsequent runs can fill in the missing platform
354
354
  # assets before electron-updater starts seeing the version.
355
355
  - if: needs.setup.outputs.mac == 'true' && needs.setup.outputs.linux == 'true' && needs.setup.outputs.windows == 'true'
356
356
  run: node "${{ github.workspace }}/node_modules/@omega.js/desktop/bin/omega" finalize-release --publish
357
357
  - if: needs.setup.outputs.mac != 'true' || needs.setup.outputs.linux != 'true' || needs.setup.outputs.windows != 'true'
358
- run: echo "Partial-platform run (mac=${{ needs.setup.outputs.mac }} linux=${{ needs.setup.outputs.linux }} windows=${{ needs.setup.outputs.windows }}) — leaving release as draft. Run with --platforms all to publish."
358
+ run: echo "Partial-platform run (mac=${{ needs.setup.outputs.mac }} linux=${{ needs.setup.outputs.linux }} windows=${{ needs.setup.outputs.windows }}), leaving release as draft. Run with --platforms all to publish."
@@ -22,5 +22,3 @@ config/certs/*
22
22
  *.pem
23
23
 
24
24
  # ========== Custom Values ==========
25
-
26
- # Add your own ignores below. This section is preserved across framework re-syncs.
@@ -1,4 +1,4 @@
1
- # MAS (Mac App Store) Reference Plists — ARCHIVED
1
+ # MAS (Mac App Store) Reference Plists (ARCHIVED)
2
2
 
3
3
  These entitlement plists are reference material for a future Mac App Store
4
4
  distribution implementation. They are **NOT** part of the active scaffold copied
@@ -24,7 +24,7 @@ Team ID + appId at build time.
24
24
  ## Roadmap
25
25
 
26
26
  When MAS support is implemented (currently stubbed in
27
- `config.targets.mac.mas` — see `docs/installer-options.md`), this folder will be
27
+ `config.targets.mac.mas`, see `node_modules/@omega.js/manager/docs/desktop/installer-options.md`), this folder will be
28
28
  the starting point for the entitlements @omega.js/desktop auto-generates into `dist/config/`
29
29
  when `mac.mas.enabled === true`. The structure should be similar to the existing
30
30
  `writeMacEntitlements` flow but with separate output files for `mas`, `mas.inherit`,
@@ -42,7 +42,7 @@ The other MAS-specific concerns:
42
42
  MAS distribution adds significant non-trivial complexity (sandboxed app, App Store
43
43
  review cycle, separate provisioning profile per app, manual submission to App
44
44
  Store Connect via Transporter or Xcode). It's the right move only for apps that
45
- genuinely benefit from App Store distribution — most consumer apps ship via DMG
45
+ genuinely benefit from App Store distribution: most consumer apps ship via DMG
46
46
  download from a website, not the Mac App Store.
47
47
 
48
48
  If you need MAS now, the legacy @omega.js/desktop (pre-v1) had support that you
@@ -37,4 +37,4 @@ These are values, not files, and live in the brand `.env` (never here):
37
37
 
38
38
  Windows keeps no file here at all: the self-hosted EV USB token is addressed by `WIN_EV_TOKEN_PATH` / `WIN_CSC_KEY_PASSWORD`, and each cloud provider by its own env set.
39
39
 
40
- For the whole picture see [`docs/signing.md`](../../docs/signing.md).
40
+ For the whole picture see `node_modules/@omega.js/manager/docs/desktop/signing.md`.