@omega.js/desktop 0.51.0 → 0.53.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.
- package/README.md +18 -13
- package/dist/assets/css/core/_initialize.scss +1 -1
- package/dist/assets/js/core/app-shell.js +14 -15
- package/dist/assets/themes/_template/_theme.js +6 -6
- package/dist/assets/themes/base/_includes/global/sections/account.html +4 -4
- package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +5 -5
- package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +3 -3
- package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/tag.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/payment/confirmation.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.js +2 -3
- package/dist/assets/themes/base/_sections/verts/unit/section.html +1 -1
- package/dist/assets/themes/base/_sections/verts/unit/section.js +3 -4
- package/dist/assets/themes/base/_theme.js +4 -3
- package/dist/assets/themes/bootstrap/_theme.js +2 -2
- package/dist/assets/themes/bootstrap/overrides/_links.scss +1 -1
- package/dist/assets/themes/classy/_theme.js +8 -6
- package/dist/assets/themes/classy/css/marketing/_sections.scss +1 -2
- package/dist/assets/themes/classy/js/hero-demo-form.js +3 -2
- package/dist/assets/themes/neobrutalism/_theme.js +5 -5
- package/dist/assets/themes/neobrutalism/js/pages/test/libraries/layers/index.js +1 -1
- package/dist/assets/themes/newsflash/_theme.js +6 -6
- package/dist/assets/themes/newsflash/js/pages/test/libraries/layers/index.js +1 -1
- package/dist/build.js +87 -111
- package/dist/cli.js +1 -1
- package/dist/commands/build.js +2 -2
- package/dist/commands/cdp/capture.js +2 -2
- package/dist/commands/cdp/quit.js +2 -2
- package/dist/commands/cdp/relaunch.js +2 -2
- package/dist/commands/cdp/theme.js +1 -1
- package/dist/commands/clean.js +2 -2
- package/dist/commands/deploy.js +4 -4
- package/dist/commands/finalize-release.js +4 -4
- package/dist/commands/install.js +3 -3
- package/dist/commands/launch.js +2 -2
- package/dist/commands/lib/deploy-precheck.js +3 -3
- package/dist/commands/lib/ensure-target.js +6 -6
- package/dist/commands/package.js +2 -2
- package/dist/commands/publish.js +2 -2
- package/dist/commands/release.js +3 -3
- package/dist/commands/runner.js +145 -48
- package/dist/commands/sign-windows.js +5 -5
- package/dist/commands/test.js +4 -4
- package/dist/commands/update.js +2 -2
- package/dist/commands/validate-certs.js +4 -4
- package/dist/commands/version.js +3 -3
- package/dist/defaults/.github/workflows/build.yml +2 -0
- package/dist/defaults/AGENTS.md +17 -8
- package/dist/defaults/config/omega.json5 +7 -7
- package/dist/defaults/hooks/build/post.js +1 -1
- package/dist/defaults/hooks/build/pre.js +1 -1
- package/dist/defaults/hooks/deploy/pre.js +1 -1
- package/dist/defaults/hooks/release/post.js +1 -1
- package/dist/defaults/hooks/release/pre.js +1 -1
- package/dist/defaults/src/assets/js/components/about/index.js +3 -5
- package/dist/defaults/src/assets/js/components/main/index.js +3 -5
- package/dist/defaults/src/assets/js/components/settings/index.js +3 -5
- package/dist/defaults/src/integrations/context-menu/index.js +2 -2
- package/dist/defaults/src/integrations/menu/index.js +3 -3
- package/dist/defaults/src/integrations/tray/index.js +3 -3
- package/dist/defaults/src/main.js +3 -5
- package/dist/defaults/src/preload.js +3 -5
- package/dist/defaults/test/README.md +2 -2
- package/dist/gulp/main.js +9 -10
- package/dist/gulp/tasks/audit.js +7 -7
- package/dist/gulp/tasks/build-config.js +8 -8
- package/dist/gulp/tasks/bundle.js +16 -16
- package/dist/gulp/tasks/defaults.js +3 -3
- package/dist/gulp/tasks/distribute.js +2 -2
- package/dist/gulp/tasks/html.js +9 -9
- package/dist/gulp/tasks/package-quick.js +3 -3
- package/dist/gulp/tasks/package.js +3 -3
- package/dist/gulp/tasks/release.js +3 -3
- package/dist/gulp/tasks/sass.js +6 -6
- package/dist/gulp/tasks/serve.js +4 -4
- package/dist/hooks/notarize-artifacts.js +1 -1
- package/dist/hooks/notarize.js +1 -1
- package/dist/index.js +5 -8
- package/dist/lib/_environment-mixin.js +50 -0
- package/dist/lib/_lifecycle-mixin.js +45 -0
- package/dist/lib/analytics.js +33 -35
- package/dist/lib/app-state.js +14 -14
- package/dist/lib/auth-flow.js +18 -18
- package/dist/lib/auth-persistence.js +12 -12
- package/dist/lib/auth.js +421 -0
- package/dist/lib/auto-updater.js +49 -49
- package/dist/lib/context-menu.js +13 -13
- package/dist/lib/context.js +19 -19
- package/dist/lib/deep-link.js +34 -34
- package/dist/lib/fontawesome.js +5 -5
- package/dist/lib/ipc.js +4 -4
- package/dist/lib/menu.js +25 -25
- package/dist/lib/protocol.js +5 -5
- package/dist/lib/remote-config.js +22 -22
- package/dist/lib/remote-scripts.js +21 -21
- package/dist/lib/restart-manager/index.js +28 -28
- package/dist/lib/sign-helpers/exec-with-limit.js +1 -1
- package/dist/lib/sign-helpers/sign-events.js +1 -1
- package/dist/lib/startup.js +18 -13
- package/dist/lib/storage.js +10 -10
- package/dist/lib/templating.js +16 -16
- package/dist/lib/theme.js +10 -10
- package/dist/lib/tray.js +27 -27
- package/dist/lib/usage.js +11 -11
- package/dist/lib/window-manager.js +26 -26
- package/dist/main.js +398 -483
- package/dist/preload.js +236 -176
- package/dist/renderer.js +417 -391
- package/dist/runner/job-started.js +1 -1
- package/dist/test/fixtures/consumer-app/config/omega.json5 +1 -1
- package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +8 -11
- package/dist/test/fixtures/consumer-app/src/main.js +5 -7
- package/dist/test/fixtures/consumer-app/src/preload.js +2 -2
- package/dist/test/harness/boot-entry.js +22 -20
- package/dist/test/harness/main-entry.js +31 -30
- package/dist/test/harness/renderer-entry.js +5 -5
- package/dist/test/harness/renderer-preload.js +137 -141
- package/dist/test/index.js +10 -10
- package/dist/test/runner.js +2 -2
- package/dist/test/runners/boot.js +7 -6
- package/dist/test/runners/electron.js +3 -2
- package/dist/test/runners/render-event.js +2 -2
- package/dist/test/suites/boot/consumer-app-boots.test.js +57 -26
- package/dist/test/suites/boot/restart-manager.test.js +2 -2
- package/dist/test/suites/boot/storage-bundled.test.js +5 -5
- package/dist/test/suites/boot/theme.test.js +13 -13
- package/dist/test/suites/build/audit.test.js +1 -1
- package/dist/test/suites/build/auth-persistence-resolve.test.js +6 -6
- package/dist/test/suites/build/boot-fixture.test.js +2 -2
- package/dist/test/suites/build/boot-runner-timeout.test.js +6 -5
- package/dist/test/suites/build/brand-scss.test.js +1 -1
- package/dist/test/suites/build/build-json-bake.test.js +1 -1
- package/dist/test/suites/build/cli.test.js +2 -2
- package/dist/test/suites/build/config-schema.test.js +5 -5
- package/dist/test/suites/build/defaults-scaffold.test.js +2 -2
- package/dist/test/suites/build/deploy-hook.test.js +3 -3
- package/dist/test/suites/build/ensure-target.test.js +2 -2
- package/dist/test/suites/build/env-delivery.test.js +2 -2
- package/dist/test/suites/build/esm-only-dependency.test.js +2 -2
- package/dist/test/suites/build/exports.test.js +9 -8
- package/dist/test/suites/build/get-config.test.js +4 -4
- package/dist/test/suites/build/manifest-deps.test.js +1 -1
- package/dist/test/suites/build/merge-line-files.test.js +1 -1
- package/dist/test/suites/build/omega-shell.test.js +34 -2
- package/dist/test/suites/build/omega.test.js +350 -0
- package/dist/test/suites/build/renderer-auth-bridge.test.js +211 -78
- package/dist/test/suites/build/runner.test.js +612 -5
- package/dist/test/suites/build/sentry.test.js +2 -2
- package/dist/test/suites/build/sign-windows-e2e.test.js +2 -2
- package/dist/test/suites/build/templating.test.js +3 -3
- package/dist/test/suites/build/test-stealth.test.js +7 -9
- package/dist/test/suites/build/url-helpers.test.js +55 -56
- package/dist/test/suites/build/validate-config.test.js +2 -2
- package/dist/test/suites/build/wave5-pins.test.js +2 -2
- package/dist/test/suites/main/analytics.test.js +59 -59
- package/dist/test/suites/main/app-state.test.js +66 -66
- package/dist/test/suites/main/auth-flow.test.js +41 -41
- package/dist/test/suites/main/auth-persistence.test.js +54 -43
- package/dist/test/suites/main/{client-bridge.integration.test.js → auth.integration.test.js} +10 -9
- package/dist/test/suites/main/auth.test.js +336 -0
- package/dist/test/suites/main/auto-updater.test.js +134 -134
- package/dist/test/suites/main/boot-sequence.test.js +37 -49
- package/dist/test/suites/main/context-menu.test.js +51 -50
- package/dist/test/suites/main/context.test.js +25 -25
- package/dist/test/suites/main/deep-link.test.js +74 -74
- package/dist/test/suites/main/fontawesome.test.js +27 -27
- package/dist/test/suites/main/ipc.test.js +35 -35
- package/dist/test/suites/main/menu.test.js +101 -100
- package/dist/test/suites/main/protocol.test.js +19 -19
- package/dist/test/suites/main/remote-config.test.js +63 -63
- package/dist/test/suites/main/remote-scripts.test.js +103 -103
- package/dist/test/suites/main/request.test.js +71 -0
- package/dist/test/suites/main/restart-manager.test.js +33 -33
- package/dist/test/suites/main/startup-paths-and-ua.test.js +4 -4
- package/dist/test/suites/main/startup.test.js +26 -26
- package/dist/test/suites/main/stealth-window.test.js +1 -1
- package/dist/test/suites/main/storage.test.js +25 -25
- package/dist/test/suites/main/theme.test.js +34 -34
- package/dist/test/suites/main/tray.test.js +79 -79
- package/dist/test/suites/main/url-helpers.test.js +133 -133
- package/dist/test/suites/main/usage.test.js +25 -25
- package/dist/test/suites/main/window-bounds.test.js +27 -27
- package/dist/test/suites/main/window-manager.test.js +44 -44
- package/dist/test/suites/renderer/analytics-bridge.test.js +5 -5
- package/dist/test/suites/renderer/cross-context-helpers.test.js +37 -31
- package/dist/test/suites/renderer/round-trip.test.js +3 -3
- package/dist/test/suites/renderer/tooltips.test.js +15 -15
- package/dist/test/suites/renderer/{window-em-surface.test.js → window-desktop-surface.test.js} +27 -7
- package/dist/test/utils/extended-mode-warning.js +1 -1
- package/dist/utils/boot-harness.js +56 -0
- package/dist/utils/mode-helpers.js +2 -15
- package/dist/utils/ship-keys.js +3 -3
- package/dist/utils/signing-status.js +51 -0
- package/dist/utils/test-events.js +7 -0
- package/dist/utils/test-stealth.js +6 -6
- package/dist/utils/url-helpers.js +52 -42
- package/dist/utils/user-agent.js +44 -0
- package/dist/vendor/account/engine.js +3 -3
- package/dist/vendor/account/index.js +14 -45
- package/dist/vendor/account/resolve-account.js +44 -0
- package/dist/vendor/account/schema.js +1 -1
- package/dist/vendor/account/user.js +99 -0
- package/dist/vendor/config/client-config.js +1 -1
- package/dist/vendor/config/environment.js +11 -30
- package/dist/vendor/config/index.js +13 -12
- package/dist/vendor/config/load.js +1 -2
- package/dist/vendor/config/platforms.js +1 -1
- package/dist/vendor/config/repo.js +24 -0
- package/dist/vendor/config/retired-keys.js +2 -2
- package/dist/vendor/config/schema.js +5 -8
- package/dist/vendor/config/site-global.js +2 -3
- package/dist/vendor/config/validate.js +1 -2
- package/dist/vendor/config/winback.js +1 -1
- package/dist/vendor/devkit/actions-secrets.js +1 -1
- package/dist/vendor/devkit/attach-log-file.js +1 -1
- package/dist/vendor/devkit/brand-version.js +162 -1
- package/dist/vendor/devkit/build-json.js +1 -1
- package/dist/vendor/devkit/cli-router.js +3 -4
- package/dist/vendor/devkit/defaults-engine.js +9 -11
- package/dist/vendor/devkit/deploy.js +64 -4
- package/dist/vendor/devkit/git-remote.js +78 -1
- package/dist/vendor/devkit/local.js +53 -3
- package/dist/vendor/devkit/lockfile.js +127 -0
- package/dist/vendor/devkit/merge-line-files.js +2 -3
- package/dist/vendor/devkit/pack-local.js +4 -7
- package/dist/vendor/devkit/preludes/origin-heal.js +35 -49
- package/dist/vendor/devkit/target-secrets.js +34 -45
- package/dist/vendor/devkit/test/runner-core.js +6 -6
- package/dist/vendor/monitoring/env.js +2 -2
- package/dist/vendor/monitoring/index.js +1 -1
- package/dist/vendor/monitoring/main.js +1 -1
- package/dist/vendor/monitoring/preload.js +1 -1
- package/dist/vendor/monitoring/renderer.js +1 -1
- package/docs/analytics.md +8 -8
- package/docs/app-state.md +19 -19
- package/docs/audit.md +4 -4
- package/docs/{client-bridge.md → auth.md} +88 -73
- package/docs/auto-updater.md +8 -8
- package/docs/boot-sequence.md +11 -6
- package/docs/build-system.md +1 -1
- package/docs/cdp-debugging.md +1 -1
- package/docs/common-mistakes.md +7 -7
- package/docs/config-schema.md +1 -1
- package/docs/context-menu.md +13 -13
- package/docs/context.md +11 -11
- package/docs/css.md +3 -9
- package/docs/deep-link.md +25 -25
- package/docs/environment-detection.md +16 -16
- package/docs/fontawesome.md +7 -5
- package/docs/hooks.md +8 -8
- package/docs/index.md +39 -28
- package/docs/ipc.md +10 -10
- package/docs/lib-modules.md +9 -9
- package/docs/logging.md +12 -14
- package/docs/menu.md +18 -18
- package/docs/releasing.md +4 -2
- package/docs/remote-config.md +9 -9
- package/docs/remote-scripts.md +12 -12
- package/docs/restart-manager.md +8 -8
- package/docs/runner.md +12 -10
- package/docs/sentry.md +4 -4
- package/docs/shared/analytics.md +1 -1
- package/docs/shared/brands.md +1 -1
- package/docs/shared/breaking-changes.md +79 -13
- package/docs/shared/config.md +24 -21
- package/docs/shared/deploys.md +30 -7
- package/docs/shared/local-dev.md +5 -3
- package/docs/shared/logging.md +1 -1
- package/docs/shared/monitoring.md +5 -5
- package/docs/shared/testing.md +2 -2
- package/docs/shared/theming.md +1 -1
- package/docs/shared/translation.md +19 -10
- package/docs/signing.md +1 -1
- package/docs/startup.md +16 -16
- package/docs/storage.md +11 -11
- package/docs/templating.md +3 -3
- package/docs/test-boot-layer.md +12 -12
- package/docs/test-framework.md +17 -17
- package/docs/themes.md +7 -7
- package/docs/tooltips.md +2 -2
- package/docs/tray.md +31 -31
- package/docs/usage.md +7 -7
- package/docs/verts.md +1 -1
- package/docs/windows.md +22 -22
- package/package.json +3 -4
- package/dist/lib/client-bridge.js +0 -374
- package/dist/lib/logger.js +0 -4
- package/dist/test/suites/build/manager.test.js +0 -213
- package/dist/test/suites/main/client-bridge.test.js +0 -262
package/docs/index.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
> **Note for contributors and Claude:** This file is the guide for `@omega.js/desktop` — identity, top-level conventions, and a map to the deep references. It lives in the monorepo's `docs/` tree and is loaded on demand (the omega Claude plugin's hooks inject it by context; the repo-root AGENTS.md map is the one agent entry — packages carry no agent docs). The **meat** (per-subsystem APIs, edge cases, behavior tables, defaults lists) lives in the package's own [`docs/<topic>.md`](../docs) files. When extending or adding content, write it in the matching `docs/*.md` file and cross-link from here — do NOT inline it. If a topic doesn't have a doc yet, create one.
|
|
4
4
|
|
|
5
|
-
> **Mirrored structure:** the four framework guides
|
|
5
|
+
> **Mirrored structure:** the four framework guides (`docs/web/index.md`, `docs/backend/index.md`, `docs/extension/index.md`, and `docs/desktop/index.md`) mirror each other: shared sections (Supply-Chain Security, Development Workflow, File Conventions, Doc-update parity, etc.) appear in the **same order at the same position** across all four. When adding a section that applies to multiple frameworks, insert it in the same spot in all of them. Each consumer template (`src/defaults/AGENTS.md`; web's lives at `scaffold/AGENTS.md`, beside its one-line `@AGENTS.md` `CLAUDE.md` pointer) mirrors its guide the same way.
|
|
6
6
|
|
|
7
7
|
## Identity
|
|
8
8
|
|
|
9
|
-
OMEGA Desktop (@omega.js/desktop) is a comprehensive framework for building modern Electron desktop apps
|
|
9
|
+
OMEGA Desktop (@omega.js/desktop) is a comprehensive framework for building modern Electron desktop apps, the desktop of the OMEGA family beside @omega.js/web, @omega.js/extension and @omega.js/backend. Each process module's default export is ONE ready-made instance, `omega`. It provides a one-line-import bootstrap per Electron process, a modular feature library with file-based extensibility, a multi-platform build/release pipeline, and a built-in test framework.
|
|
10
10
|
|
|
11
11
|
## Recommended skills
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ OMEGA Desktop (@omega.js/desktop) is a comprehensive framework for building mode
|
|
|
15
15
|
|
|
16
16
|
## 🚨 READ @omega.js/client TOO
|
|
17
17
|
|
|
18
|
-
**@omega.js/desktop
|
|
18
|
+
**@omega.js/desktop's renderer instance extends `@omega.js/client`'s base class**: `omega.auth`, `omega.storage`, `omega.bindings`, `omega.firestore` and the rest of the client are properties of the renderer's `omega`, beside `omega.desktop`, the preload's bridge to main. The client powers auth, Firebase, reactive `data-omega-bind` directives, analytics, error tracking, and utilities (`escapeHTML`, etc.). Any task that touches auth flows, Firestore reads/writes, subscription resolution, push notifications, or DOM bindings means you are working with @omega.js/client as much as with @omega.js/desktop.
|
|
19
19
|
|
|
20
20
|
**Required reading:**
|
|
21
21
|
- **`docs/client/index.md`** (in the framework monorepo) — the client guide: identity, module list, conventions
|
|
@@ -52,59 +52,70 @@ OMEGA Desktop (@omega.js/desktop) is a comprehensive framework for building mode
|
|
|
52
52
|
|
|
53
53
|
## Architecture
|
|
54
54
|
|
|
55
|
-
###
|
|
55
|
+
### The consumer entry
|
|
56
56
|
|
|
57
|
-
Each Electron process
|
|
57
|
+
Each Electron process's module exports ONE ready-made instance, `omega`; the class is exported by name (`Omega`) for tests only, and a consumer never writes `new`:
|
|
58
58
|
|
|
59
59
|
```js
|
|
60
60
|
// src/main.js
|
|
61
|
-
|
|
61
|
+
const omega = require('@omega.js/desktop/main'); // auto-loads JSON5 config
|
|
62
|
+
omega.initialize().then(() => { const { logger, windows } = omega; });
|
|
62
63
|
|
|
63
64
|
// src/preload.js
|
|
64
|
-
|
|
65
|
+
const omega = require('@omega.js/desktop/preload'); // exposes window.desktop
|
|
66
|
+
omega.initialize();
|
|
65
67
|
|
|
66
68
|
// src/assets/js/components/<view>/index.js
|
|
67
|
-
|
|
69
|
+
import omega from '@omega.js/desktop/renderer';
|
|
70
|
+
omega.initialize().then(() => { const { logger, desktop } = omega; });
|
|
68
71
|
```
|
|
69
72
|
|
|
70
|
-
`
|
|
73
|
+
`initialize()` returns the instance, and `omega.ready` is the same promise, so a module that did not call it can still await it. In main, `omega.initialize()` runs a fixed boot order (startup → ipc → storage → theme → fontawesome → sentry → protocol → deepLink → authFlow → appState → context → usage → whenReady → autoUpdater → tray/menu/contextMenu → startup → auth → remoteConfig → remoteScripts → analytics → restartManager → windows). See [docs/boot-sequence.md](../docs/boot-sequence.md) for the full ordered list + rationale.
|
|
74
|
+
|
|
75
|
+
### The instance (`omega`)
|
|
76
|
+
|
|
77
|
+
- **main**: every lib is a plain property: `omega.windows`, `tray`, `menu`, `contextMenu`, `ipc`, `storage`, `deepLink`, `autoUpdater`, `appState`, `startup`, `protocol`, `authFlow`, `theme`, `fontawesome`, `context`, `usage`, `remoteConfig`, `remoteScripts`, `restartManager`, `analytics`, `sentry`, `logger`, plus `config`, the environment helpers, the URL helpers (`getApiUrl()`, `getWebsiteUrl()`, `getFunctionsUrl()`, `getAuthUrl()`), `quit()`, `relaunch()`, `openAuthFlow()`, `request(url, options)` (the client base's harmonized API fetch, carrying a fresh Bearer token from main's session when signed in) and `require(name)`. `omega.auth` is the signed-in account: `.user` (always a `User`), `.listen()`, `.signOut()`, `.getIdToken()`, `.handleToken()` ([docs/auth.md](../docs/auth.md)).
|
|
78
|
+
- **preload**: exposes `window.desktop` through `contextBridge`; `omega.logger` and the environment helpers.
|
|
79
|
+
- **renderer**: `@omega.js/client`'s base class (`omega.auth`, `omega.storage` the page store, `omega.bindings`, `omega.firestore`, ...) plus `omega.desktop`, the preload's bridge under main's names: `omega.desktop.{ipc,storage,theme,fontawesome,autoUpdater,analytics,context,usage,remoteConfig}`. `omega.desktop.storage` is the app store, async over IPC. The renderer carries the same auth click triggers as the extension's pages: `.omega-signin` runs main's `openAuthFlow()`, `.omega-account` opens the website's `/account` page in the user's browser, and `.omega-signout` (the client's trigger) signs the whole app out through main, whose broadcast then signs every window out ([docs/auth.md](../docs/auth.md)).
|
|
71
80
|
|
|
72
81
|
### Lib modules
|
|
73
82
|
|
|
74
|
-
`src/lib/*.js
|
|
83
|
+
`src/lib/*.js`: every Electron concern its own module. Each exports one object with `initialize(omega)`, and main hangs it on the instance by name. Deep dive per module: see `docs/<lib-name>.md`. Authoring guide (initialization contract, adding a new lib, flat-vs-split): [docs/lib-modules.md](../docs/lib-modules.md).
|
|
75
84
|
|
|
76
85
|
| Module | Description |
|
|
77
86
|
|---|---|
|
|
78
87
|
| `ipc` | typed channel bus, single registration point |
|
|
79
88
|
| `storage` | electron-store wrapper, sync main / async renderer via IPC |
|
|
80
|
-
| `theme` | system-aware appearance
|
|
89
|
+
| `theme` | system-aware appearance: `nativeTheme.themeSource` ('system'/'light'/'dark'), persisted override, live `<html data-bs-theme>` in every renderer via matchMedia |
|
|
81
90
|
| `window-manager` | lazy-creation registry, bounds persistence, Discord-style hide-on-close, inset titlebar, dock-show on first window, re-surface on user re-launch |
|
|
82
91
|
| `tray` / `menu` / `context-menu` | file-based definitions; unified id-path API; default templates with id-tagged items |
|
|
83
92
|
| `startup` | `mode: 'normal' \| 'hidden'`; `'hidden'` bakes `LSUIElement: true` for zero dock bounce |
|
|
84
93
|
| `app-state` | storage-backed launch flags + crash sentinel |
|
|
85
94
|
| `protocol` | single-instance lock + scheme registration |
|
|
95
|
+
| `fontawesome` | serves the bundled icon SVGs to renderers over IPC (`desktop:fontawesome:get`); the renderer auto-renders `fa-*` markup ([docs/fontawesome.md](../docs/fontawesome.md)) |
|
|
86
96
|
| `deep-link` | unified deep-link dispatch (cold + warm start, mac + win + linux), built-in routes, pattern matching |
|
|
87
|
-
| `
|
|
97
|
+
| `auth` | `omega.auth`: main = source-of-truth Firebase Auth, renderers reflect via IPC; session persists via `auth-persistence`; renderers push the account document their client resolved, so main's `omega.auth.user` is the same `User` |
|
|
98
|
+
| `auth-flow` | `omega.authFlow` / `omega.openAuthFlow()`: the sign-in round trip in the user's default browser, returning over the deep link (production) or a one-shot loopback listener (dev/test) |
|
|
88
99
|
| `auth-persistence` | pluggable main-session vault (default: safeStorage OS-keychain encryption; `omega.authPersistence` config) |
|
|
89
100
|
| `auto-updater` | electron-updater wrapper, idle-aware install, 30-day pending gate, dev simulation |
|
|
90
101
|
| `sentry` | `@omega.js/monitoring` — the shared error-reporting contract, auto auth attribution, dev-mode gating |
|
|
91
|
-
| `templating` | `{{ }}` token replacement
|
|
92
|
-
| `context` | runtime info
|
|
102
|
+
| `templating` | `{{ }}` token replacement, used at build time by `gulp/html` |
|
|
103
|
+
| `context` | runtime info: `omega.context.{geolocation,client,session,app}` |
|
|
93
104
|
| `usage` | `opens` / `hoursTotal` / `hoursThisSession`; crash-safe |
|
|
94
105
|
| `remote-config` | "Hot config" fetched from `${brand.url}/data/resources/main.json`, polled hourly |
|
|
95
|
-
| `remote-scripts` | Emergency remote code execution
|
|
106
|
+
| `remote-scripts` | Emergency remote code execution: OPT-IN (`remoteScripts.enabled: true`) + https-only; fetches `${brand.url}/data/scripts/main.js`, content-hash dedup, async `omega` + `require` in scope |
|
|
96
107
|
| `analytics` | GA4 Measurement Protocol; cross-platform `uuidv5` identity; the app's ONE sender — renderer events forward here over IPC ([docs/analytics.md](../docs/analytics.md)) |
|
|
97
108
|
| `restart-manager` | external guardian app for crash relaunches — localhost HTTP protocol v1 (register/heartbeat/deregister), silent install when missing (mac zip / win NSIS `/S` / linux AppImage; RM self-updates via its own @omega.js/desktop autoUpdater); split dir ships the protocol SSOT the RM app imports |
|
|
98
109
|
|
|
99
110
|
### File-based feature definitions
|
|
100
111
|
|
|
101
|
-
Trays, menus, and context-menus are NOT defined in config
|
|
112
|
+
Trays, menus, and context-menus are NOT defined in config: they're defined in JS files the consumer authors at fixed conventional paths (`src/integrations/{tray,menu,context-menu}/index.js`). To opt out, call `omega.{tray,menu,contextMenu}.disable()` at runtime. Each file exports one function of an object: `({ omega, tray })`, `({ omega, menu, defaults })`, and `({ omega, menu, params, webContents })` for the context menu, called per right-click.
|
|
102
113
|
|
|
103
114
|
All three ship sensible default templates and share a unified id-path API (`.find/.has/.update/.remove/.enable/.show/.hide/.insertBefore/.insertAfter/.appendTo`), implemented once in `src/lib/_menu-mixin.js`. See [docs/tray.md](../docs/tray.md), [docs/menu.md](../docs/menu.md), [docs/context-menu.md](../docs/context-menu.md).
|
|
104
115
|
|
|
105
116
|
### Windows
|
|
106
117
|
|
|
107
|
-
@omega.js/desktop does NOT auto-create any windows. Consumers call `
|
|
118
|
+
@omega.js/desktop does NOT auto-create any windows. Consumers call `omega.windows.create('main', { show: !startup.isLaunchHidden() })` from inside `omega.initialize().then(...)`. Inset titlebar by default; Discord-style hide-on-close on `main`; auto re-surface on user re-launch. See [docs/windows.md](../docs/windows.md).
|
|
108
119
|
|
|
109
120
|
### Icons
|
|
110
121
|
|
|
@@ -148,7 +159,7 @@ All three bundles strip `@dev-only` blocks in production builds — code between
|
|
|
148
159
|
|
|
149
160
|
### Config flow
|
|
150
161
|
|
|
151
|
-
`config/omega.json5` (JSON5, in consumer; shared sections top-level + desktop settings under `targets.desktop`) → `
|
|
162
|
+
`config/omega.json5` (JSON5, in consumer; shared sections top-level + desktop settings under `targets.desktop`) → `build.getConfig()` (resolves via `@omega.js/config`: `targets.desktop` overlays the top level, brand-monorepo walk-up included), then applies derived defaults: `app.appId` ← `<certificates.providers.apple.bundleIdPrefix>.<brand.id>` with the brand id's dashes as dots, the very id the certificates service registers ([#909](https://github.com/Omega-JS-Stack/omega/issues/909); no prefix declared, and it falls back to the reverse-domain of `brand.url`, then `app.<brand.id>`), `app.productName` ← `brand.name`) → injected into the NODE bundles (main, preload) at build time as an esbuild `define` of `OMEGA_BUILD_JSON` plus a banner that assigns the same literal to `globalThis`, and written for the RENDERER as the ONE `dist/build.js` every view's shell loads with its first script tag ([#743](https://github.com/Omega-JS-Stack/omega/issues/743), the same file and the same load order web and the extension use). Runtime reads `OMEGA_BUILD_JSON.config` first (authoritative in packaged apps); dev falls back to resolving from disk.
|
|
152
163
|
|
|
153
164
|
The wrapper is the ONE shape every OMEGA browser surface bakes ([#894](https://github.com/Omega-JS-Stack/omega/issues/894)): `{ config, package, mode, license, builtAt }`, with the build's own facts outside `config` and never part of the client contract. What goes INSIDE `config` differs by who reads the bundle:
|
|
154
165
|
|
|
@@ -157,7 +168,7 @@ The wrapper is the ONE shape every OMEGA browser surface bakes ([#894](https://g
|
|
|
157
168
|
| main, preload | the WHOLE resolved config, as a `define` + banner in their own bundles. The main process BOOTS from it (a packaged app's `config/omega.json5` is inside the asar), so `platforms`, `startup`, `autoUpdate`, `releases` and the rest have to be there. Both are Node, neither is a public surface |
|
|
158
169
|
| renderer | the browser subset, `clientConfig(resolved)` from `@omega.js/config` (the config guide's "The browser subset"), written to `dist/build.js` and loaded by the page template as `../../build.js` ahead of the view's own bundle. A renderer is a public surface: its bundle is readable from DevTools, so the GCP account facts, the signing certificates and the account admins are not in it, and the bundle itself carries no copy of the snapshot at all |
|
|
159
170
|
|
|
160
|
-
The build facts include `runtime: 'electron'` ([#896](https://github.com/Omega-JS-Stack/omega/issues/896)): a packaged renderer is a browser with no Electron globals of its own, so @omega.js/client's sniff would answer `'web'` without the baked fact. `mode` is the three keys every surface records, `{ environment, build, publish }`; desktop's own `server` verdict stays inside `
|
|
171
|
+
The build facts include `runtime: 'electron'` ([#896](https://github.com/Omega-JS-Stack/omega/issues/896)): a packaged renderer is a browser with no Electron globals of its own, so @omega.js/client's sniff would answer `'web'` without the baked fact. `mode` is the three keys every surface records, `{ environment, build, publish }`; desktop's own `server` verdict stays inside `build.getMode()`.
|
|
161
172
|
|
|
162
173
|
Both halves carry the same name, so `renderer.js` hands `OMEGA_BUILD_JSON.config` to `@omega.js/client` exactly as an extension page and a web page do.
|
|
163
174
|
|
|
@@ -165,11 +176,11 @@ Required fields: `brand.id` + `brand.name`. Everything else has defaults. See [d
|
|
|
165
176
|
|
|
166
177
|
### Schema validation
|
|
167
178
|
|
|
168
|
-
Every field in `config/omega.json5` is declared in `@omega.js/config`: the shared OMEGA schema plus the desktop refinements (`TARGET_SCHEMAS.desktop`), vendored into `dist/vendor/config/` and exposed to consumers as `require('@omega.js/desktop/config')`. Runs at boot (hard-fails `
|
|
179
|
+
Every field in `config/omega.json5` is declared in `@omega.js/config`: the shared OMEGA schema plus the desktop refinements (`TARGET_SCHEMAS.desktop`), vendored into `dist/vendor/config/` and exposed to consumers as `require('@omega.js/desktop/config')`. Runs at boot (hard-fails `omega.initialize()` if invalid) AND in `gulp/audit` (plus build-pipeline extras). The audit reports the validator's WARNINGS too ([#911](https://github.com/Omega-JS-Stack/omega/issues/911)): `omega build` prints each one and counts it (`audit ok (1 warning)`), so a key the schema does not declare, which is exactly what a typo looks like, is seen at build time instead of dropped. See [docs/config-schema.md](../docs/config-schema.md).
|
|
169
180
|
|
|
170
181
|
### Cross-context helpers
|
|
171
182
|
|
|
172
|
-
|
|
183
|
+
The three process instances (main / preload / renderer) carry the shared helpers as methods, and the build module (`require('@omega.js/desktop/build')`) exports the environment four and `getVersion()` as plain functions: `isDevelopment()`, `isProduction()`, `isTesting()`, `getWebsiteUrl()`, `getEnvironment()`, `getFunctionsUrl()`, `getApiUrl()`, `getAuthUrl()` (the sign-in URL that round-trips an auth token back into the app via the `auth/token` deep link; never link the bare `/signin` page; apps launch it via **`omega.openAuthFlow()`** (main), which opens the user's REAL default browser and, in dev/test where the custom scheme isn't OS-registered, swaps the final hop for a one-shot nonce-checked loopback listener (RFC 8252) feeding the same deep-link pipeline, `lib/auth-flow.js`). Use these instead of grepping `process.env` ad-hoc. `getEnvironment()` returns `'development' | 'testing' | 'production'` (mutually exclusive), and the three `is*()` checks DERIVE from it; gate side effects on the INTENTIONAL check (`isProduction()` for prod-only, `isDevelopment() || isTesting()` for local-or-test); never `!isDevelopment()`.
|
|
173
184
|
|
|
174
185
|
**The environment four are `@omega.js/config`'s ONE module** ([#817](https://github.com/Omega-JS-Stack/omega/issues/817), the contract in full: [docs/shared/config.md](shared/config.md)): `src/utils/mode-helpers.js` re-exports them beside desktop's own `getVersion()`, so all four frameworks hang the identical functions. They read ONE input and never guess: `OMEGA_ENVIRONMENT` in Node, and the baked `OMEGA_BUILD_JSON.config.environment` in a renderer (which has none). Nothing sniffs `app.isPackaged` or `NODE_ENV` any more, and a context with neither input throws by name rather than defaulting; the old default here was `production`, so a plain `npm start` bundled itself as a production artifact while @omega.js/extension's copy of the same function answered `development`. `src/build.js` names the input at load, from the lane (`OMEGA_BUILD_MODE` is production and wins over an inherited value; the test runners name `testing`; a bare dev boot is `development`), and `main.js` names it from the baked config for a packaged app that has no parent lane: a FALLBACK for the context with no input, never an override of a lane that named one ([#925](https://github.com/Omega-JS-Stack/omega/issues/925)). A renderer has no `process` either, so the preload hands it the running word on `window.desktop.environment` and the renderer bootstrap applies it over the bake, which is how a test lane booting a production artifact answers `testing` in every context of that app. See [docs/environment-detection.md](../docs/environment-detection.md).
|
|
175
186
|
|
|
@@ -227,8 +238,8 @@ See [docs/releasing.md](../docs/releasing.md) for the end-to-end flow.
|
|
|
227
238
|
|
|
228
239
|
- **Consumer code can `require()` any @omega.js/desktop dependency** — the bundler re-resolves every name @omega.js/desktop DECLARES from the framework's own installation (`@omega.js/devkit/bundle`'s framework-deps hook). Consumer projects do NOT need to `npm install firebase`, `fs-jetpack`, `@omega.js/client`, or any other @omega.js/desktop dep. If a dep doesn't resolve, the fix is in @omega.js/desktop's `package.json` or its bundle task — not the consumer's `package.json`.
|
|
229
240
|
- **The framework's copy wins ([#87](https://github.com/Omega-JS-Stack/omega/issues/87)).** Every name @omega.js/desktop DECLARES is re-resolved from the framework root by `@omega.js/devkit/bundle`'s resolve hook, so a consumer that declares its own version of a framework dependency still bundles ONE copy — the framework's — the identical hook and guarantee @omega.js/web gives web consumers. npm nests a framework-private copy only when the consumer's declaration conflicts, so this picks the nested copy on a conflict and the shared hoisted copy otherwise. There is no per-dependency override today, so a consumer that genuinely needs its OWN copy of a framework-carried package should raise it upstream ([#87](https://github.com/Omega-JS-Stack/omega/issues/87)) rather than pin and silently lose. Narrower than the webpack `resolve.modules` ordering it replaced ([#737](https://github.com/Omega-JS-Stack/omega/issues/737)): a package the framework only carries TRANSITIVELY is no longer forced to the framework's copy, because the hook reads the declared set. @omega.js/extension is on the same hook since [#738](https://github.com/Omega-JS-Stack/omega/issues/738); pinned by `src/test/suites/build/framework-deps.test.js` in each.
|
|
230
|
-
- **@omega.js/client owns Firebase.** Consumer code NEVER imports Firebase directly (`require('firebase')` / `import('firebase/app')`).
|
|
231
|
-
- **`
|
|
241
|
+
- **@omega.js/client owns Firebase.** Consumer code NEVER imports Firebase directly (`require('firebase')` / `import('firebase/app')`). In renderers use `omega.auth` and `omega.firestore` on the renderer instance. In the main process, use `omega.auth` (the @omega.js/desktop bridge). Same rule on every OMEGA browser surface.
|
|
242
|
+
- **`omega.require(name)`** (main) resolves from @omega.js/desktop's module context at runtime. Use in gulp tasks or unbundled code (e.g. test fixtures). The bundle task's framework-deps hook handles the bundled case.
|
|
232
243
|
|
|
233
244
|
## Development Workflow
|
|
234
245
|
|
|
@@ -272,7 +283,7 @@ Don't ship behavioral changes with stale docs. Validate first, then document —
|
|
|
272
283
|
|
|
273
284
|
API references for each subsystem live in `docs/`. **Whenever you make a behavioral change, update both this overview AND the relevant `docs/*.md` deep reference.** Treat docs as a first-class deliverable, not an afterthought.
|
|
274
285
|
|
|
275
|
-
- [docs/boot-sequence.md](../docs/boot-sequence.md)
|
|
286
|
+
- [docs/boot-sequence.md](../docs/boot-sequence.md): full `omega.initialize()` ordered list + rationale
|
|
276
287
|
- [docs/lib-modules.md](../docs/lib-modules.md) — lib initialization contract, adding a new lib, flat-vs-split convention
|
|
277
288
|
- [docs/storage.md](../docs/storage.md) — main + renderer storage, dot-notation, change broadcasts
|
|
278
289
|
- [docs/ipc.md](../docs/ipc.md) — typed channel bus
|
|
@@ -283,7 +294,7 @@ API references for each subsystem live in `docs/`. **Whenever you make a behavio
|
|
|
283
294
|
- [docs/startup.md](../docs/startup.md) — launch modes, zero-bounce production
|
|
284
295
|
- [docs/app-state.md](../docs/app-state.md) — launch flags, crash sentinel
|
|
285
296
|
- [docs/deep-link.md](../docs/deep-link.md) — cross-platform deep links, single-instance, built-in routes
|
|
286
|
-
- [docs/
|
|
297
|
+
- [docs/auth.md](../docs/auth.md): `omega.auth`, Firebase auth state sync across main + renderers, session persistence (safeStorage vault), the renderer @omega.js/client auth cycle (`data-omega-bind` bindings live in every renderer) + the account push that builds main's `omega.auth.user`
|
|
287
298
|
- [docs/auto-updater.md](../docs/auto-updater.md) — startup + periodic checks, 30-day pending-update gate, idle-aware install
|
|
288
299
|
- [docs/analytics.md](../docs/analytics.md) — GA4 Measurement Protocol, cross-platform `uuidv5` identity
|
|
289
300
|
- [docs/context.md](../docs/context.md) — runtime context block (geolocation, client, session, app)
|
|
@@ -295,17 +306,17 @@ API references for each subsystem live in `docs/`. **Whenever you make a behavio
|
|
|
295
306
|
- [docs/sentry.md](../docs/sentry.md) — the desktop half of `@omega.js/monitoring`, auto auth attribution
|
|
296
307
|
- [docs/templating.md](../docs/templating.md) — `{{ }}` token replacement, page vars, HTML pipeline
|
|
297
308
|
- [docs/logging.md](../docs/logging.md) — runtime logger (main + preload + renderer → one `runtime.log`)
|
|
298
|
-
- [docs/themes.md](../docs/themes.md)
|
|
309
|
+
- [docs/themes.md](../docs/themes.md): vendored classy + bootstrap themes, per-page CSS bundles, system-aware appearance (`omega.theme`)
|
|
299
310
|
- [docs/tooltips.md](../docs/tooltips.md) — Bootstrap JS ships in @omega.js/desktop (prebuilt bundle, Popper inlined): zero-setup auto-initialized tooltips, `window.bootstrap` namespace
|
|
300
311
|
- [docs/css.md](../docs/css.md) — SCSS architecture: main entry, theme `@use` config, per-window bundles, Bootstrap-first
|
|
301
312
|
- [docs/hooks.md](../docs/hooks.md): lifecycle hooks (build/pre, build/post, release/pre, release/post, notarize/post, deploy/pre)
|
|
302
313
|
- [docs/shared/icons.md](../docs/icons.md) — convention-only icon resolution (`global/` + per-platform), retina derivation, macOS Template magic
|
|
303
|
-
- [docs/fontawesome.md](../docs/fontawesome.md)
|
|
314
|
+
- [docs/fontawesome.md](../docs/fontawesome.md): Font Awesome Free served from the npm dep (icon semantics shared with web via @omega.js/client's icon-core): `<i class="fa-solid fa-*">` auto-render, `omega.desktop.fontawesome.get`
|
|
304
315
|
- [docs/verts.md](../docs/verts.md) — `[data-omega-vert]` auto-bind to @omega.js/client's verts module (live via MutationObserver): house/company lane ONLY (type pinned 'house' — no AdSense in desktop surfaces)
|
|
305
316
|
- [docs/installer-options.md](../docs/installer-options.md) — per-target installer config, defaults table
|
|
306
317
|
- [docs/signing.md](../docs/signing.md) — code signing for macOS + Windows
|
|
307
318
|
- [docs/releasing.md](../docs/releasing.md) — end-to-end release walkthrough
|
|
308
|
-
- [docs/runner.md](../docs/runner.md): Windows EV-token signing runner. The listener runs with a private HOME (`%LOCALAPPDATA%\omega-runner\home`, holding a real `.gitconfig`), written at install and healed by `start`/`restart`, so a job's `actions/checkout` never copies the box's symlinked `~/.gitconfig` into a junction it cannot read ([#807](https://github.com/Omega-JS-Stack/omega/issues/807)). The same install writes the box's JOB GUARD ([#875](https://github.com/Omega-JS-Stack/omega/issues/875)): a job-started hook beside the runner, pointed at through each registration's `ACTIONS_RUNNER_HOOK_JOB_STARTED`, that fails any job whose event is not a dispatch or whose repository or actor is not on the box's own allow lists
|
|
319
|
+
- [docs/runner.md](../docs/runner.md): Windows EV-token signing runner. The listener runs with a private HOME (`%LOCALAPPDATA%\omega-runner\home`, holding a real `.gitconfig`), written at install and healed by `start`/`restart`, so a job's `actions/checkout` never copies the box's symlinked `~/.gitconfig` into a junction it cannot read ([#807](https://github.com/Omega-JS-Stack/omega/issues/807)). The same install writes the box's JOB GUARD ([#875](https://github.com/Omega-JS-Stack/omega/issues/875)): a job-started hook beside the runner, pointed at through each registration's `ACTIONS_RUNNER_HOOK_JOB_STARTED`, that fails any job whose event is not a dispatch or whose repository or actor is not on the box's own allow lists. `start` is the one command a box operator runs ([#937](https://github.com/Omega-JS-Stack/omega/issues/937)): it installs a bare box, refreshes a stale actions/runner download in place, and registers any admin org the box does not serve yet before bringing every org online
|
|
309
320
|
- [docs/test-framework.md](../docs/test-framework.md) — writing tests, running them, layers
|
|
310
321
|
- [docs/test-boot-layer.md](../docs/test-boot-layer.md) — the `boot` test layer: consumer end-to-end smoke + @omega.js/desktop's framework self-test from the repo via the bundled fixture (`src/test/fixtures/consumer-app/`) + `OMEGA_TEST_BOOT_PROJECT` (@omega.js/desktop's analog of @omega.js/backend/BXM/UJM `*_TEST_BOOT_PROJECT`)
|
|
311
322
|
- [docs/build-system.md](../docs/build-system.md) — gulp, esbuild, electron-builder pipeline
|
package/docs/ipc.md
CHANGED
|
@@ -5,15 +5,15 @@ Typed channel bus for main ↔ renderer communication. All @omega.js/desktop fea
|
|
|
5
5
|
## Main-process API
|
|
6
6
|
|
|
7
7
|
```js
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
omega.ipc.handle(channel, async (payload, evt) => result) // request/response
|
|
9
|
+
omega.ipc.unhandle(channel)
|
|
10
|
+
omega.ipc.invoke(channel, payload) // call locally (also what renderer triggers)
|
|
11
|
+
omega.ipc.on(channel, (payload, evt) => void) // one-way subscribe (renderer → main)
|
|
12
|
+
omega.ipc.off(channel, fn)
|
|
13
|
+
omega.ipc.broadcast(channel, payload) // → all BrowserWindows
|
|
14
|
+
omega.ipc.send(webContents, channel, payload) // → one renderer
|
|
15
|
+
omega.ipc.hasHandler(channel)
|
|
16
|
+
omega.ipc.listenerCount(channel)
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Renderer-process API (via preload contextBridge)
|
|
@@ -51,7 +51,7 @@ Registration is validated for you (above) — payload CONTENT is not. Treat ever
|
|
|
51
51
|
|
|
52
52
|
```js
|
|
53
53
|
// main
|
|
54
|
-
|
|
54
|
+
omega.ipc.handle('user:get-token', async (payload) => {
|
|
55
55
|
const token = await fetchToken(payload.userId);
|
|
56
56
|
return { token };
|
|
57
57
|
});
|
package/docs/lib-modules.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lib Modules
|
|
2
2
|
|
|
3
|
-
`src/lib/*.js
|
|
3
|
+
`src/lib/*.js`: every Electron concern is its own module. Each exports one object with `initialize(omega)`; the main-process instance hangs each on itself by name and initializes them in a fixed order at boot (see [boot-sequence.md](boot-sequence.md)). Each module's deep reference lives at `docs/<lib-name>.md`; the module list is in the framework guide's Architecture section ([docs/desktop/index.md](../../../docs/desktop/index.md)).
|
|
4
4
|
|
|
5
5
|
## Lib initialization contract
|
|
6
6
|
|
|
@@ -9,10 +9,10 @@ Each lib exposes the same skeleton:
|
|
|
9
9
|
```js
|
|
10
10
|
const myLib = {
|
|
11
11
|
_initialized: false,
|
|
12
|
-
|
|
12
|
+
_omega: null,
|
|
13
13
|
|
|
14
|
-
initialize(
|
|
15
|
-
myLib.
|
|
14
|
+
initialize(omega) {
|
|
15
|
+
myLib._omega = omega;
|
|
16
16
|
// wire IPC handlers, app event listeners, etc.
|
|
17
17
|
myLib._initialized = true;
|
|
18
18
|
},
|
|
@@ -33,9 +33,9 @@ Don't use `EventEmitter` unless the lib genuinely emits multiple event types. Fo
|
|
|
33
33
|
|
|
34
34
|
## Adding a new lib
|
|
35
35
|
|
|
36
|
-
1. Create `src/lib/<name>.js` exporting
|
|
37
|
-
2. Wire it into the boot order in `src/main.js` (or the renderer/preload
|
|
38
|
-
3.
|
|
36
|
+
1. Create `src/lib/<name>.js` exporting one object with `initialize(omega)`.
|
|
37
|
+
2. Wire it into the boot order in `src/main.js` (or the renderer/preload class if it's a per-context lib): check [boot-sequence.md](boot-sequence.md) for where it belongs and what it may depend on.
|
|
38
|
+
3. Set it on the instance in the `Omega` constructor as `this.<camelCaseName>`, so consumers reach it at runtime as `omega.<camelCaseName>`.
|
|
39
39
|
4. Write tests at every layer the lib has a surface in (see [test-framework.md](test-framework.md)) — at minimum `src/test/suites/main/<name>.test.js`.
|
|
40
40
|
5. Add a `docs/<name>.md` deep reference, add the module's row to the Lib modules table in the framework guide (`docs/desktop/index.md`), and link it from the Documentation index.
|
|
41
41
|
|
|
@@ -48,6 +48,6 @@ Don't use `EventEmitter` unless the lib genuinely emits multiple event types. Fo
|
|
|
48
48
|
|
|
49
49
|
## See also
|
|
50
50
|
|
|
51
|
-
- [boot-sequence.md](boot-sequence.md)
|
|
52
|
-
- [environment-detection.md](environment-detection.md)
|
|
51
|
+
- [boot-sequence.md](boot-sequence.md): the fixed `omega.initialize()` order + rationale
|
|
52
|
+
- [environment-detection.md](environment-detection.md): cross-context helpers shared by the three processes and the build module
|
|
53
53
|
- [test-framework.md](test-framework.md) — the four-layer harness new libs must ship tests in
|
package/docs/logging.md
CHANGED
|
@@ -20,25 +20,23 @@
|
|
|
20
20
|
|
|
21
21
|
## How to write logs
|
|
22
22
|
|
|
23
|
-
In **main process
|
|
23
|
+
In **main process**:
|
|
24
24
|
|
|
25
25
|
```js
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
await manager.initialize();
|
|
26
|
+
const omega = require('@omega.js/desktop/main');
|
|
27
|
+
await omega.initialize();
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
omega.logger.log('booted');
|
|
30
|
+
omega.logger.warn('connection slow');
|
|
31
|
+
omega.logger.error(new Error('boom'));
|
|
33
32
|
```
|
|
34
33
|
|
|
35
34
|
In **preload**:
|
|
36
35
|
|
|
37
36
|
```js
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
manager.logger.log('preload ready');
|
|
37
|
+
const omega = require('@omega.js/desktop/preload');
|
|
38
|
+
await omega.initialize();
|
|
39
|
+
omega.logger.log('preload ready');
|
|
42
40
|
```
|
|
43
41
|
|
|
44
42
|
In **renderer** (use the contextBridge surface, which forwards to main → file):
|
|
@@ -52,7 +50,7 @@ window.desktop.logger.error(new Error('ui blew up'));
|
|
|
52
50
|
All three end up in the same `runtime.log`, prefixed with their scope (`main`, `preload`, `renderer`):
|
|
53
51
|
|
|
54
52
|
```
|
|
55
|
-
[2026-05-05 14:32:11.045] [info] main
|
|
53
|
+
[2026-05-05 14:32:11.045] [info] main omega.initialize
|
|
56
54
|
[2026-05-05 14:32:11.122] [info] main ipc ready
|
|
57
55
|
[2026-05-05 14:32:11.187] [info] preload contextBridge exposed
|
|
58
56
|
[2026-05-05 14:32:11.401] [info] renderer auth.listen attached
|
|
@@ -108,7 +106,7 @@ Useful for:
|
|
|
108
106
|
|
|
109
107
|
Beyond what you write yourself, @omega.js/desktop emits a fixed set of high-signal lifecycle lines so post-mortem debugging works without redeploying:
|
|
110
108
|
|
|
111
|
-
**At boot (`
|
|
109
|
+
**At boot (`omega.initialize()`):**
|
|
112
110
|
|
|
113
111
|
```
|
|
114
112
|
(main) Initializing @omega.js/desktop (main)... pid=12345 platform=darwin arch=arm64 packaged=true argv=["--omega-launched-at-login"]
|
|
@@ -118,7 +116,7 @@ Beyond what you write yourself, @omega.js/desktop emits a fixed set of high-sign
|
|
|
118
116
|
(startup) process.arch: arm64
|
|
119
117
|
(startup) app.isPackaged: true
|
|
120
118
|
(startup) app.getLoginItemSettings(): {"status":"enabled","openAtLogin":true,"openAsHidden":false,"restoreState":false,"wasOpenedAtLogin":false,"wasOpenedAsHidden":false}
|
|
121
|
-
(startup)
|
|
119
|
+
(startup) boot env: {}
|
|
122
120
|
(startup) startup boot summary — RESOLVED values:
|
|
123
121
|
(startup) config.startup.mode: normal
|
|
124
122
|
(startup) config.startup.openAtLogin: {enabled:true, mode:hidden}
|
package/docs/menu.md
CHANGED
|
@@ -4,13 +4,13 @@ File-based application menu (the macOS menu bar / Windows + Linux menu). Same bu
|
|
|
4
4
|
|
|
5
5
|
## Config
|
|
6
6
|
|
|
7
|
-
No config block. Path is conventional: `src/integrations/menu/index.js`. To opt out, call `
|
|
7
|
+
No config block. Path is conventional: `src/integrations/menu/index.js`. To opt out, call `omega.menu.disable()` from your main entry.
|
|
8
8
|
|
|
9
9
|
## Definition file
|
|
10
10
|
|
|
11
11
|
```js
|
|
12
12
|
// src/integrations/menu/index.js
|
|
13
|
-
module.exports = ({
|
|
13
|
+
module.exports = ({ omega, menu, defaults }) => {
|
|
14
14
|
// Easiest: start from the platform-aware default template.
|
|
15
15
|
menu.useDefaults();
|
|
16
16
|
|
|
@@ -18,7 +18,7 @@ module.exports = ({ manager, menu, defaults }) => {
|
|
|
18
18
|
menu.show('main/preferences'); // @omega.js/desktop ships this hidden by default
|
|
19
19
|
menu.update('main/check-for-updates', { label: 'Get Latest Version' });
|
|
20
20
|
menu.insertAfter('main/check-for-updates', {
|
|
21
|
-
id: 'main/account', label: 'Account...', click: () =>
|
|
21
|
+
id: 'main/account', label: 'Account...', click: () => omega.windows.show('account'),
|
|
22
22
|
});
|
|
23
23
|
menu.remove('view/reload');
|
|
24
24
|
menu.hide('main/services');
|
|
@@ -39,7 +39,7 @@ menu.clear() // start over
|
|
|
39
39
|
|
|
40
40
|
## Id-path API
|
|
41
41
|
|
|
42
|
-
Same shape across menu / tray / context-menu. Available **during definition** (on the `menu` builder arg) AND **at runtime** on `
|
|
42
|
+
Same shape across menu / tray / context-menu. Available **during definition** (on the `menu` builder arg) AND **at runtime** on `omega.menu`:
|
|
43
43
|
|
|
44
44
|
```js
|
|
45
45
|
.find(idPath) // live descriptor or null
|
|
@@ -108,7 +108,7 @@ Every item in @omega.js/desktop's default template carries a stable id you can t
|
|
|
108
108
|
|
|
109
109
|
### Development menu (dev mode only)
|
|
110
110
|
|
|
111
|
-
Top-level, only visible when `
|
|
111
|
+
Top-level, only visible when `omega.isDevelopment()`. Mirrors legacy @omega.js/desktop's developer utilities.
|
|
112
112
|
|
|
113
113
|
| ID | Item | Action |
|
|
114
114
|
|---|---|---|
|
|
@@ -120,7 +120,7 @@ Top-level, only visible when `manager.isDevelopment()`. Mirrors legacy @omega.js
|
|
|
120
120
|
|
|
121
121
|
## Built-in framework items
|
|
122
122
|
|
|
123
|
-
`main/check-for-updates` (mac) and `help/check-for-updates` (win/linux) are **wired to `
|
|
123
|
+
`main/check-for-updates` (mac) and `help/check-for-updates` (win/linux) are **wired to `omega.autoUpdater`**:
|
|
124
124
|
- Label updates dynamically: *Checking…*, *Downloading 42%*, *Restart to Update v1.2.3*, *You're up to date*.
|
|
125
125
|
- Click triggers `autoUpdater.checkNow()` or `autoUpdater.installNow()` depending on state.
|
|
126
126
|
|
|
@@ -135,24 +135,24 @@ Same dynamic conveniences as tray:
|
|
|
135
135
|
- `click` wrapped to catch errors
|
|
136
136
|
- `submenu` recursively resolved
|
|
137
137
|
|
|
138
|
-
## Runtime API on `
|
|
138
|
+
## Runtime API on `omega.menu`
|
|
139
139
|
|
|
140
140
|
```js
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
omega.menu.refresh() // re-evaluate dynamic state
|
|
142
|
+
omega.menu.define(fn) // replace the whole definition at runtime
|
|
143
|
+
omega.menu.destroy() // tear down (mostly for tests)
|
|
144
|
+
omega.menu.disable() // turn the menu off entirely (idempotent)
|
|
145
145
|
|
|
146
146
|
// Id-path API — same as listed above.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
147
|
+
omega.menu.find('main/check-for-updates')
|
|
148
|
+
omega.menu.update('main/check-for-updates', { label: 'Updates...' })
|
|
149
|
+
omega.menu.remove('view/reload')
|
|
150
|
+
omega.menu.insertAfter('main/check-for-updates', { id: 'main/account', label: 'Account...' })
|
|
151
151
|
|
|
152
152
|
// Inspection
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
omega.menu.getItems() // top-level descriptors (shallow copy)
|
|
154
|
+
omega.menu.isRendered() // bool
|
|
155
|
+
omega.menu.getMenu() // the underlying Electron Menu instance
|
|
156
156
|
```
|
|
157
157
|
|
|
158
158
|
## Default scaffold
|
package/docs/releasing.md
CHANGED
|
@@ -92,7 +92,7 @@ Every verb runs `ensureTarget()` first ([#675](https://github.com/Omega-JS-Stack
|
|
|
92
92
|
`npx omega deploy` adds the network half as a precheck (`--no-secrets` opts out):
|
|
93
93
|
|
|
94
94
|
- Validates signing prereqs (warns if missing — non-fatal).
|
|
95
|
-
- Pushes the composed `.env` → GitHub Actions secrets over the `gh` CLI (`gh auth login`; a CI run, an empty cascade, no remote,
|
|
95
|
+
- Pushes the composed `.env` → GitHub Actions secrets over the `gh` CLI (`gh auth login`; a CI run, an empty cascade, or no GitHub remote skips loudly, and a checkout whose `origin` is not the derived source repo refuses on the one drift line, `origin is <slug> but config derives <derived>: fix repo.org in config/omega.json5 or move the repo`, [#934](https://github.com/Omega-JS-Stack/omega/issues/934)).
|
|
96
96
|
|
|
97
97
|
Now drop your cert files:
|
|
98
98
|
|
|
@@ -174,7 +174,9 @@ build needs setup; matrix over the resolved OSes: npm ci, then
|
|
|
174
174
|
`npm run release:local` on mac and linux (sign, notarize, and
|
|
175
175
|
electron-builder publishes the DRAFT release in the brand's releases
|
|
176
176
|
repo), and `npm run package` on windows, whose unsigned output uploads
|
|
177
|
-
as the `windows-unsigned` artifact
|
|
177
|
+
as the `windows-unsigned` artifact, a one-day intermediate that
|
|
178
|
+
windows-sign consumes in the same run (the releases repo is the
|
|
179
|
+
durable home)
|
|
178
180
|
windows-strategy needs [setup, build]; reads platforms.windows.signing.strategy from config
|
|
179
181
|
(only when windows is in the matrix)
|
|
180
182
|
windows-sign the self-hosted EV-token box, hosted windows-latest for the cloud
|
package/docs/remote-config.md
CHANGED
|
@@ -17,7 +17,7 @@ remoteConfig: {
|
|
|
17
17
|
|
|
18
18
|
## Cadence
|
|
19
19
|
|
|
20
|
-
Polled at the same interval as the auto-updater feed-check (`autoUpdater.feedCheckIntervalMs`, default 1h). Same job category (HTTP, low-frequency, network-dependent), so re-using the cadence keeps both poll-rates aligned. Fetch timeout is 60s; in tests both collapse to 500ms via `
|
|
20
|
+
Polled at the same interval as the auto-updater feed-check (`autoUpdater.feedCheckIntervalMs`, default 1h). Same job category (HTTP, low-frequency, network-dependent), so re-using the cadence keeps both poll-rates aligned. Fetch timeout is 60s; in tests both collapse to 500ms via `omega.isTesting()`.
|
|
21
21
|
|
|
22
22
|
## Defaults — `get()` always returns SOMETHING usable
|
|
23
23
|
|
|
@@ -28,7 +28,7 @@ A key design point: **app boot never blocks on the fetch**. `initialize()` retur
|
|
|
28
28
|
3. **Async, on the first successful background fetch:** server values overlay the defaults.
|
|
29
29
|
4. **Async, on every subsequent successful fetch:** repeats step 3, fires `'update'` event so consumers can re-run gates.
|
|
30
30
|
|
|
31
|
-
Defaults (exported as `
|
|
31
|
+
Defaults (exported as `omega.remoteConfig.DEFAULTS`):
|
|
32
32
|
|
|
33
33
|
```js
|
|
34
34
|
{
|
|
@@ -59,10 +59,10 @@ function checkForceUpdate(cfg) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// Run at boot — works against defaults / cached value / first fetch result, whatever's there.
|
|
62
|
-
checkForceUpdate(
|
|
62
|
+
checkForceUpdate(omega.remoteConfig.get());
|
|
63
63
|
|
|
64
64
|
// Re-run on every fresh fetch so a server-side bump kicks in within an hour.
|
|
65
|
-
|
|
65
|
+
omega.remoteConfig.on('update', checkForceUpdate);
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
## Failure mode
|
|
@@ -74,11 +74,11 @@ Failure warnings are formatted through `src/utils/format-fetch-error.js` — one
|
|
|
74
74
|
## API
|
|
75
75
|
|
|
76
76
|
```js
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const off =
|
|
77
|
+
omega.remoteConfig.get(); // → entire current config (cache-first, never blocks)
|
|
78
|
+
omega.remoteConfig.get('versionRequired'); // → dot-path lookup
|
|
79
|
+
omega.remoteConfig.get('settings.deep.path'); // → nested
|
|
80
|
+
omega.remoteConfig.refreshNow(); // → force a fetch right now (returns Promise<data | null>)
|
|
81
|
+
const off = omega.remoteConfig.on('update', (data) => { ... });
|
|
82
82
|
off(); // unsubscribe
|
|
83
83
|
```
|
|
84
84
|
|
package/docs/remote-scripts.md
CHANGED
|
@@ -31,14 +31,14 @@ Host a plain `.js` file at the source URL. The content is fetched as text and ex
|
|
|
31
31
|
### Example: force all users to update
|
|
32
32
|
|
|
33
33
|
```js
|
|
34
|
-
await
|
|
34
|
+
await omega.autoUpdater.checkNow();
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
### Example: clear corrupted storage
|
|
38
38
|
|
|
39
39
|
```js
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
omega.storage.delete('auth.staleToken');
|
|
41
|
+
omega.storage.set('app.patched', true);
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
### Example: emergency restart with cache wipe
|
|
@@ -52,18 +52,18 @@ if (fs.existsSync(cacheDir)) {
|
|
|
52
52
|
fs.rmSync(cacheDir, { recursive: true });
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
omega.relaunch({ force: true });
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
### Example: redirect updater to a hotfix feed
|
|
59
59
|
|
|
60
60
|
```js
|
|
61
|
-
|
|
61
|
+
omega.autoUpdater._autoUpdater.setFeedURL({
|
|
62
62
|
provider: 'github',
|
|
63
63
|
owner: 'myorg',
|
|
64
64
|
repo: 'myapp-hotfix',
|
|
65
65
|
});
|
|
66
|
-
await
|
|
66
|
+
await omega.autoUpdater.checkNow();
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
### Example: version-gated fix (script handles its own gating)
|
|
@@ -73,7 +73,7 @@ const wv = require('wonderful-version');
|
|
|
73
73
|
const appVersion = require('electron').app.getVersion();
|
|
74
74
|
|
|
75
75
|
if (wv.greaterThanOrEqual(appVersion, '1.4.0') && wv.lessThan(appVersion, '1.6.0')) {
|
|
76
|
-
|
|
76
|
+
omega.storage.delete('corrupted.key');
|
|
77
77
|
}
|
|
78
78
|
```
|
|
79
79
|
|
|
@@ -89,9 +89,9 @@ Or return a 404 — fetch failures are caught and logged, never crash. Failure l
|
|
|
89
89
|
|
|
90
90
|
## Execution context
|
|
91
91
|
|
|
92
|
-
The script runs via `new AsyncFunction('
|
|
92
|
+
The script runs via `new AsyncFunction('omega', 'require', code)`:
|
|
93
93
|
|
|
94
|
-
- **`
|
|
94
|
+
- **`omega`**: the live main-process instance. Full access to all libs: `omega.storage`, `omega.autoUpdater`, `omega.windows`, `omega.ipc`, etc.
|
|
95
95
|
- **`require`** — the real Node.js `require`. Can load `fs`, `path`, `child_process`, `electron`, or any installed package.
|
|
96
96
|
- **`await`** — supported natively.
|
|
97
97
|
|
|
@@ -107,13 +107,13 @@ If the script throws, the error is logged but the hash is still stored (prevents
|
|
|
107
107
|
|
|
108
108
|
```js
|
|
109
109
|
// Force-fetch and execute if the script changed
|
|
110
|
-
await
|
|
110
|
+
await omega.remoteScripts.refreshNow();
|
|
111
111
|
|
|
112
112
|
// See the last execution ({ hash, timestamp } or null)
|
|
113
|
-
|
|
113
|
+
omega.remoteScripts.getLastRun();
|
|
114
114
|
|
|
115
115
|
// Wipe stored hash — next poll will re-run the current script
|
|
116
|
-
|
|
116
|
+
omega.remoteScripts.clearExecuted();
|
|
117
117
|
```
|
|
118
118
|
|
|
119
119
|
## Config
|