@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.
- package/README.md +38 -38
- package/dist/cli-run.js +4 -1
- package/dist/cli.js +2 -2
- package/dist/commands/cdp/client.js +1 -1
- package/dist/commands/cdp.js +1 -1
- package/dist/commands/clean.js +2 -3
- package/dist/commands/dev.js +25 -0
- package/dist/commands/lib/ensure-target.js +12 -17
- package/dist/commands/lib/migrate.js +17 -0
- package/dist/commands/logs.js +1 -1
- package/dist/commands/release.js +1 -1
- package/dist/commands/test.js +4 -4
- package/dist/commands/update.js +5 -4
- package/dist/defaults/.github/workflows/build.yml +18 -18
- package/dist/defaults/_.gitignore +0 -2
- package/dist/defaults/_mas/README.md +3 -3
- package/dist/defaults/config/certs/README.md +1 -1
- package/dist/defaults/config/omega.json5 +36 -36
- package/dist/defaults/docs/README.md +3 -3
- package/dist/defaults/gulpfile.js +1 -1
- package/dist/defaults/hooks/build/post.js +1 -1
- package/dist/defaults/hooks/build/pre.js +1 -1
- package/dist/defaults/hooks/notarize/post.js +2 -2
- package/dist/defaults/hooks/release/post.js +1 -1
- package/dist/defaults/hooks/release/pre.js +1 -1
- package/dist/defaults/src/assets/scss/pages/about.scss +1 -1
- package/dist/defaults/src/assets/scss/pages/main.scss +1 -1
- package/dist/defaults/src/assets/scss/pages/settings.scss +1 -1
- package/dist/defaults/src/integrations/context-menu/index.js +11 -11
- package/dist/defaults/src/integrations/menu/index.js +5 -5
- package/dist/defaults/src/integrations/tray/index.js +9 -9
- package/dist/defaults/src/main.js +2 -2
- package/dist/defaults/src/preload.js +1 -1
- package/dist/defaults/test/README.md +3 -3
- package/dist/defaults/test/_init.js +1 -1
- package/dist/gulp/tasks/audit.js +5 -8
- package/dist/lib/restart-manager/index.js +1 -1
- package/dist/lib/restart-manager/install.js +1 -1
- package/dist/lib/restart-manager/protocol.js +1 -1
- package/dist/main.js +4 -3
- package/dist/preload.js +1 -1
- package/dist/test/suites/build/audit.test.js +20 -7
- package/dist/test/suites/build/build-workflow-jobs.test.js +2 -2
- package/dist/test/suites/build/cli.test.js +28 -0
- package/dist/test/suites/build/defaults-em-dash.test.js +22 -0
- package/dist/test/suites/build/defaults-scaffold.test.js +19 -5
- package/dist/test/suites/build/deploy-direct.test.js +7 -5
- package/dist/test/suites/build/deploy-dispatch.test.js +2 -1
- package/dist/test/suites/build/deploy-hook.test.js +4 -2
- package/dist/test/suites/build/dev-verb.test.js +67 -0
- package/dist/test/suites/build/ensure-target.test.js +11 -3
- package/dist/test/suites/build/merge-line-files.test.js +6 -6
- package/dist/test/suites/build/migrate.test.js +29 -0
- package/dist/test/suites/build/project-scripts-deps.test.js +6 -10
- package/dist/test/suites/build/runner-env-write.test.js +73 -0
- package/dist/test/suites/build/runner.test.js +9 -8
- package/dist/test/suites/build/setup-scripts.test.js +27 -0
- package/dist/test/suites/build/validate-config.test.js +13 -2
- package/dist/test/suites/build/verb-logs.test.js +20 -0
- package/dist/test/suites/renderer/window-desktop-surface.test.js +1 -1
- package/dist/utils/build-pipeline.js +4 -4
- package/dist/utils/runner-env.js +13 -28
- package/dist/vendor/config/company.js +46 -14
- package/dist/vendor/config/defaults.js +30 -7
- package/dist/vendor/config/edit.js +25 -3
- package/dist/vendor/config/env-delivery.js +1 -1
- package/dist/vendor/config/env-schema.js +3 -6
- package/dist/vendor/config/env.js +34 -22
- package/dist/vendor/config/index.js +13 -17
- package/dist/vendor/config/load.js +15 -7
- package/dist/vendor/config/repo.js +10 -27
- package/dist/vendor/config/schema-client.js +64 -0
- package/dist/vendor/config/schema-cloud.js +38 -0
- package/dist/vendor/config/schema-manager.js +118 -0
- package/dist/vendor/config/schema-overrides.js +68 -0
- package/dist/vendor/config/schema.js +99 -152
- package/dist/vendor/config/validate.js +97 -77
- package/dist/vendor/devkit/agents-md.js +233 -0
- package/dist/vendor/devkit/attach-log-file.js +15 -1
- package/dist/vendor/devkit/ci-workflows.js +30 -30
- package/dist/vendor/devkit/cli-router.js +13 -7
- package/dist/vendor/devkit/defaults-engine.js +9 -43
- package/dist/vendor/devkit/deploy-snapshot.js +44 -9
- package/dist/vendor/devkit/env-lines.js +183 -0
- package/dist/vendor/devkit/local.js +62 -10
- package/dist/vendor/devkit/lockfile.js +32 -13
- package/dist/vendor/devkit/logger.js +7 -2
- package/dist/vendor/devkit/merge-line-files.js +219 -176
- package/dist/vendor/devkit/omega-bin.js +208 -111
- package/dist/vendor/devkit/preludes/docs-sync.js +52 -0
- package/dist/vendor/devkit/preludes/index.js +1 -0
- package/dist/vendor/devkit/target-picker.js +45 -0
- package/dist/vendor/devkit/test/dashed-files.js +37 -0
- package/dist/vendor/devkit/test/run-verb-under-tee.js +71 -0
- package/dist/vendor/devkit/update.js +15 -15
- package/dist/vendor/devkit/verb-scripts.js +40 -0
- package/dist/vendor/devkit/verbs.js +170 -0
- package/package.json +18 -24
- package/dist/commands/install.js +0 -37
- package/dist/defaults/AGENTS.md +0 -119
- package/dist/defaults/CLAUDE.md +0 -1
- package/dist/vendor/config/env-retired.js +0 -137
- package/dist/vendor/config/retired-keys.js +0 -635
- package/docs/analytics.md +0 -140
- package/docs/app-state.md +0 -92
- package/docs/audit.md +0 -69
- package/docs/auth.md +0 -284
- package/docs/auto-updater.md +0 -243
- package/docs/boot-sequence.md +0 -44
- package/docs/build-system.md +0 -169
- package/docs/cdp-debugging.md +0 -169
- package/docs/common-mistakes.md +0 -21
- package/docs/config-schema.md +0 -120
- package/docs/context-menu.md +0 -112
- package/docs/context.md +0 -81
- package/docs/css.md +0 -84
- package/docs/deep-link.md +0 -186
- package/docs/environment-detection.md +0 -112
- package/docs/fontawesome.md +0 -109
- package/docs/hooks.md +0 -89
- package/docs/icons.md +0 -79
- package/docs/index.md +0 -328
- package/docs/installer-options.md +0 -165
- package/docs/ipc.md +0 -61
- package/docs/lib-modules.md +0 -53
- package/docs/logging.md +0 -227
- package/docs/menu.md +0 -160
- package/docs/releasing.md +0 -239
- package/docs/remote-config.md +0 -118
- package/docs/remote-scripts.md +0 -144
- package/docs/restart-manager.md +0 -144
- package/docs/runner.md +0 -290
- package/docs/sentry.md +0 -97
- package/docs/shared/agent-docs.md +0 -89
- package/docs/shared/analytics.md +0 -612
- package/docs/shared/brands.md +0 -57
- package/docs/shared/breaking-changes.md +0 -917
- package/docs/shared/config.md +0 -1948
- package/docs/shared/deploys.md +0 -341
- package/docs/shared/icons.md +0 -219
- package/docs/shared/local-dev.md +0 -167
- package/docs/shared/logging.md +0 -205
- package/docs/shared/monitoring.md +0 -167
- package/docs/shared/publishing.md +0 -187
- package/docs/shared/rulings.md +0 -34
- package/docs/shared/testing.md +0 -147
- package/docs/shared/theming.md +0 -629
- package/docs/shared/translation.md +0 -342
- package/docs/shared/updates.md +0 -61
- package/docs/signing.md +0 -293
- package/docs/startup.md +0 -142
- package/docs/storage.md +0 -59
- package/docs/templating.md +0 -101
- package/docs/test-boot-layer.md +0 -157
- package/docs/test-framework.md +0 -362
- package/docs/themes.md +0 -149
- package/docs/tooltips.md +0 -99
- package/docs/tray.md +0 -164
- package/docs/usage.md +0 -58
- package/docs/verts.md +0 -62
- package/docs/windows.md +0 -149
package/docs/ipc.md
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
# IPC
|
|
2
|
-
|
|
3
|
-
Typed channel bus for main ↔ renderer communication. All @omega.js/desktop features register their channels through this single layer rather than calling `ipcMain.handle` directly, so you have one place to look and one place to instrument.
|
|
4
|
-
|
|
5
|
-
## Main-process API
|
|
6
|
-
|
|
7
|
-
```js
|
|
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
|
-
```
|
|
18
|
-
|
|
19
|
-
## Renderer-process API (via preload contextBridge)
|
|
20
|
-
|
|
21
|
-
```js
|
|
22
|
-
await window.desktop.ipc.invoke(channel, payload) // → Promise<result>
|
|
23
|
-
const off = window.desktop.ipc.on(channel, (payload) => { ... });
|
|
24
|
-
window.desktop.ipc.send(channel, payload); // fire-and-forget
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Channel naming
|
|
28
|
-
|
|
29
|
-
framework-internal channels are prefixed `desktop:` (e.g. `desktop:storage:get`, `desktop:storage:change`). Consumers are free to use any namespace.
|
|
30
|
-
|
|
31
|
-
## Validation
|
|
32
|
-
|
|
33
|
-
- `handle()` throws if `channel` is empty/non-string or `handler` is non-function.
|
|
34
|
-
- `handle()` throws on duplicate registration. Call `unhandle()` first if you need to swap.
|
|
35
|
-
- `invoke()` rejects with a clear message if no handler is registered for the channel.
|
|
36
|
-
- Handler errors propagate through `invoke()` (both main-local and renderer-side) — your renderer's `await window.desktop.ipc.invoke(...)` will reject with the original error message.
|
|
37
|
-
|
|
38
|
-
## Zero-trust payloads
|
|
39
|
-
|
|
40
|
-
Registration is validated for you (above) — payload CONTENT is not. Treat every payload reaching a `handle()` / `on()` callback as untrusted input: renderers can be compromised, and apps that embed remote web content (e.g. external pages in `WebContentsView`s) expose the IPC surface to code you don't control.
|
|
41
|
-
|
|
42
|
-
- **Validate shape and values before acting** — types match, IDs are well-formed, enums are from the expected set, paths resolve inside the expected roots.
|
|
43
|
-
- **Gate any URL arriving via IPC** through `sanitize-url.js` before `shell.openExternal` / `loadURL` (the zero-trust URL rule — see [common-mistakes.md](common-mistakes.md)).
|
|
44
|
-
- **Never feed raw payload values** into filesystem paths, shell commands, or `webContents.executeJavaScript`.
|
|
45
|
-
|
|
46
|
-
## Boot order
|
|
47
|
-
|
|
48
|
-
`ipc` initializes **before** `storage` so that storage (and every other feature) can register handlers via `ipc.handle`. This is the canonical pattern: don't touch `ipcMain` directly.
|
|
49
|
-
|
|
50
|
-
## Example
|
|
51
|
-
|
|
52
|
-
```js
|
|
53
|
-
// main
|
|
54
|
-
omega.ipc.handle('user:get-token', async (payload) => {
|
|
55
|
-
const token = await fetchToken(payload.userId);
|
|
56
|
-
return { token };
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// renderer
|
|
60
|
-
const { token } = await window.desktop.ipc.invoke('user:get-token', { userId: 'abc' });
|
|
61
|
-
```
|
package/docs/lib-modules.md
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# Lib Modules
|
|
2
|
-
|
|
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
|
-
|
|
5
|
-
## Lib initialization contract
|
|
6
|
-
|
|
7
|
-
Each lib exposes the same skeleton:
|
|
8
|
-
|
|
9
|
-
```js
|
|
10
|
-
const myLib = {
|
|
11
|
-
_initialized: false,
|
|
12
|
-
_omega: null,
|
|
13
|
-
|
|
14
|
-
initialize(omega) {
|
|
15
|
-
myLib._omega = omega;
|
|
16
|
-
// wire IPC handlers, app event listeners, etc.
|
|
17
|
-
myLib._initialized = true;
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
// Public API
|
|
21
|
-
doThing() { ... },
|
|
22
|
-
|
|
23
|
-
// Disable at runtime (idempotent)
|
|
24
|
-
disable() {
|
|
25
|
-
// tear down listeners; safe to call multiple times
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
module.exports = myLib;
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Don't use `EventEmitter` unless the lib genuinely emits multiple event types. For "fires once when ready" use a promise; for "broadcasts changes" use IPC with renderer subscriptions.
|
|
33
|
-
|
|
34
|
-
## Adding a new lib
|
|
35
|
-
|
|
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
|
-
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
|
-
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
|
-
|
|
42
|
-
## Flat file vs directory split
|
|
43
|
-
|
|
44
|
-
- **Default to flat `src/lib/<name>.js`.**
|
|
45
|
-
- **Split into a directory** (`src/lib/<name>/{index,core,main,renderer,preload}.js`) ONLY when each Electron context has materially different logic that would force ugly runtime branching inside one file. `index.js` becomes a thin context detector that delegates.
|
|
46
|
-
- `lib/sentry/` was that split (the SDK has separate main/renderer/preload entry points) until it moved WHOLE into `@omega.js/monitoring` (#380) — the backend and the client needed the same policy, so the shape it proved now lives in the shared package. `lib/restart-manager/` is split for a different, also-valid reason — a **shared-SSOT split**: its `protocol.js` (the wire contract) must be importable by the Restart Manager app via the `exports` map with zero Electron/@omega.js/desktop baggage, so the contract lives in its own pure-Node file next to the main-only `index.js` + `install.js`. `sign-helpers/` is a helpers directory, not a lib.
|
|
47
|
-
- Don't split prophylactically; convert when the branching gets ugly.
|
|
48
|
-
|
|
49
|
-
## See also
|
|
50
|
-
|
|
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
|
-
- [test-framework.md](test-framework.md) — the four-layer harness new libs must ship tests in
|
package/docs/logging.md
DELETED
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
# Logging
|
|
2
|
-
|
|
3
|
-
@omega.js/desktop ships a runtime logger that writes to **both the console and a file on disk**, so production issues are inspectable without remoting into the user's machine.
|
|
4
|
-
|
|
5
|
-
## What you get
|
|
6
|
-
|
|
7
|
-
- **One log file**, `runtime.log`, populated by all three Electron processes (main / preload / renderer)
|
|
8
|
-
- **Live console output** during development (DevTools console for renderer, terminal stdout for main)
|
|
9
|
-
- **Kept across boots** — never truncated; it rotates by size instead (see the lifetime table below), unlike `dev.log`/`build.log`/`test.log`
|
|
10
|
-
- **Cross-process timestamps** so log lines from main + preload + renderer interleave in arrival order
|
|
11
|
-
|
|
12
|
-
## Where the file lives
|
|
13
|
-
|
|
14
|
-
| Mode | Location |
|
|
15
|
-
|---|---|
|
|
16
|
-
| Dev (`npm start`, `app.isPackaged === false`) | `<projectRoot>/logs/runtime.log` |
|
|
17
|
-
| Prod (installed `.dmg` / `.exe` / `.deb`, `app.isPackaged === true`) | OS log dir: `~/Library/Logs/<ProductName>/runtime.log` (macOS), `%APPDATA%\<ProductName>\logs\runtime.log` (Windows), `~/.config/<ProductName>/logs/runtime.log` (Linux) |
|
|
18
|
-
|
|
19
|
-
`<ProductName>` = `config.app.productName` (falls back to `config.brand.name`). @omega.js/desktop calls `app.setName(productName)` at boot so `app.getPath('logs')` uses the human-readable brand name, not `package.json#name`.
|
|
20
|
-
|
|
21
|
-
## How to write logs
|
|
22
|
-
|
|
23
|
-
In **main process**:
|
|
24
|
-
|
|
25
|
-
```js
|
|
26
|
-
const omega = require('@omega.js/desktop/main');
|
|
27
|
-
await omega.initialize();
|
|
28
|
-
|
|
29
|
-
omega.logger.log('booted');
|
|
30
|
-
omega.logger.warn('connection slow');
|
|
31
|
-
omega.logger.error(new Error('boom'));
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
In **preload**:
|
|
35
|
-
|
|
36
|
-
```js
|
|
37
|
-
const omega = require('@omega.js/desktop/preload');
|
|
38
|
-
await omega.initialize();
|
|
39
|
-
omega.logger.log('preload ready');
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
In **renderer** (use the contextBridge surface, which forwards to main → file):
|
|
43
|
-
|
|
44
|
-
```js
|
|
45
|
-
window.desktop.logger.log('user clicked Save');
|
|
46
|
-
window.desktop.logger.warn('IPC slow');
|
|
47
|
-
window.desktop.logger.error(new Error('ui blew up'));
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
All three end up in the same `runtime.log`, prefixed with their scope (`main`, `preload`, `renderer`):
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
[2026-05-05 14:32:11.045] [info] main omega.initialize
|
|
54
|
-
[2026-05-05 14:32:11.122] [info] main ipc ready
|
|
55
|
-
[2026-05-05 14:32:11.187] [info] preload contextBridge exposed
|
|
56
|
-
[2026-05-05 14:32:11.401] [info] renderer auth.listen attached
|
|
57
|
-
[2026-05-05 14:32:12.998] [warn] main auto-updater check failed: network
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Grep one context with:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
grep ' main ' logs/runtime.log
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## CLI: `npx omega logs`
|
|
67
|
-
|
|
68
|
-
For dev-loop convenience. From the consumer project root:
|
|
69
|
-
|
|
70
|
-
| Command | Effect |
|
|
71
|
-
|---|---|
|
|
72
|
-
| `npx omega logs` | Print path, then `tail -50` of the file |
|
|
73
|
-
| `npx omega logs --tail` (or `-f`) | Follow mode (like `tail -f`). Ctrl+C to stop. Cross-platform. |
|
|
74
|
-
| `npx omega logs --path` (or `-p`) | Print the resolved path only (pipe-friendly) |
|
|
75
|
-
| `npx omega logs --open` | Open the log file in OS default editor |
|
|
76
|
-
| `npx omega logs --lines=100` | Default mode with custom tail length |
|
|
77
|
-
|
|
78
|
-
### The surface argument
|
|
79
|
-
|
|
80
|
-
An optional positional names which of the project's logs to read — `npx omega logs [runtime|dev|build|test]`, resolving `<cwd>/logs/<surface>.log`. It defaults to `runtime`, and every flag above works the same on whichever surface was named:
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
npx omega logs dev --tail # follow the gulp pipeline live
|
|
84
|
-
npx omega logs test --lines=100 # last 100 lines of the previous test run
|
|
85
|
-
npx omega logs build --path # just the path, for piping
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Anything else fails naming the four surfaces. (The four files themselves are described in the lifetime table below; `deploy.log` and `signing.log` are not tail targets.)
|
|
89
|
-
|
|
90
|
-
`mgr logs` only resolves the dev path (`<cwd>/logs/<surface>.log`). To find the production runtime log on a user's machine, use the table above or call `getLogFilePath()` from app code.
|
|
91
|
-
|
|
92
|
-
## How to find the file path from app code
|
|
93
|
-
|
|
94
|
-
```js
|
|
95
|
-
const LoggerLite = require('@omega.js/desktop/lib/logger-lite');
|
|
96
|
-
const filePath = LoggerLite.getLogFilePath();
|
|
97
|
-
// → '/Users/<user>/Library/Logs/MyApp/runtime.log' in production
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Useful for:
|
|
101
|
-
- "Send us your log" buttons in your settings UI
|
|
102
|
-
- Programmatic log shipping (e.g. POSTing the file to your support backend)
|
|
103
|
-
- Crash reporters that want to attach the runtime log
|
|
104
|
-
|
|
105
|
-
## What @omega.js/desktop logs automatically
|
|
106
|
-
|
|
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:
|
|
108
|
-
|
|
109
|
-
**At boot (`omega.initialize()`):**
|
|
110
|
-
|
|
111
|
-
```
|
|
112
|
-
(main) Initializing @omega.js/desktop (main)... pid=12345 platform=darwin arch=arm64 packaged=true argv=["--omega-launched-at-login"]
|
|
113
|
-
(startup) startup boot summary — RAW inputs:
|
|
114
|
-
(startup) process.argv: ["--omega-launched-at-login"]
|
|
115
|
-
(startup) process.platform: darwin
|
|
116
|
-
(startup) process.arch: arm64
|
|
117
|
-
(startup) app.isPackaged: true
|
|
118
|
-
(startup) app.getLoginItemSettings(): {"status":"enabled","openAtLogin":true,"openAsHidden":false,"restoreState":false,"wasOpenedAtLogin":false,"wasOpenedAsHidden":false}
|
|
119
|
-
(startup) boot env: {}
|
|
120
|
-
(startup) startup boot summary — RESOLVED values:
|
|
121
|
-
(startup) config.startup.mode: normal
|
|
122
|
-
(startup) config.startup.openAtLogin: {enabled:true, mode:hidden}
|
|
123
|
-
(startup) isDev: false
|
|
124
|
-
(startup) hasLoginArg: true
|
|
125
|
-
(startup) wasLaunchedAtLogin(): true (via argv-flag)
|
|
126
|
-
(startup) isLaunchHidden(): true
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
The boot summary has two parallel blocks: **RAW inputs** (what the OS / shell gave us) and **RESOLVED values** (what @omega.js/desktop decided to act on). Use it to debug both directions:
|
|
130
|
-
- "Why is @omega.js/desktop behaving like X?" → check resolved values
|
|
131
|
-
- "Why did @omega.js/desktop decide X?" → check raw inputs
|
|
132
|
-
|
|
133
|
-
The `via:` annotation on `wasLaunchedAtLogin()` distinguishes a real login launch (`via:macos-wasOpenedAtLogin`) from a flag-based simulation (`via:argv-flag` — i.e. the user passed `--omega-launched-at-login`).
|
|
134
|
-
|
|
135
|
-
**App lifecycle events** (logged from `main.js`):
|
|
136
|
-
|
|
137
|
-
```
|
|
138
|
-
app event: before-quit (entering quit sequence — close events bypass hide-on-close)
|
|
139
|
-
app event: will-quit
|
|
140
|
-
app event: quit code=0
|
|
141
|
-
app event: window-all-closed
|
|
142
|
-
app event: activate (macOS — dock click or app re-launch)
|
|
143
|
-
app event: open-url url=myapp://auth/token?...
|
|
144
|
-
app event: render-process-gone reason=crashed exitCode=139
|
|
145
|
-
app event: child-process-gone type=GPU reason=killed exitCode=9
|
|
146
|
-
process exit code=0
|
|
147
|
-
uncaughtException: <stack>
|
|
148
|
-
unhandledRejection: <stack>
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
**Window lifecycle events** (per named window, logged from `window-manager`):
|
|
152
|
-
|
|
153
|
-
```
|
|
154
|
-
createNamed: building "main" (show=false, hideOnClose=true)
|
|
155
|
-
createNamed: loaded /path/to/app.asar/dist/views/main/index.html for "main"
|
|
156
|
-
window "main": ready-to-show — staying invisible (show:false at create)
|
|
157
|
-
window "main": ready-to-show — surfacing
|
|
158
|
-
window "main": show event
|
|
159
|
-
window "main": hide event
|
|
160
|
-
window "main": focus event
|
|
161
|
-
window "main": minimize event
|
|
162
|
-
window "main": restore event
|
|
163
|
-
window "main": close intercepted (hide-on-close) — hiding instead
|
|
164
|
-
window "main": close allowed (hideOnClose=true, allowQuit=false, isQuitting=true, force=false)
|
|
165
|
-
window "main": closed (destroyed)
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
**Re-surface handlers**:
|
|
169
|
-
|
|
170
|
-
```
|
|
171
|
-
activate (macOS) — surfacing main (visible=false, minimized=false)
|
|
172
|
-
_ensureDockVisible — calling dock.show()
|
|
173
|
-
_ensureDockVisible — dock already visible
|
|
174
|
-
second-instance argv=["..."] eventArgv=["..."] cwd=/...
|
|
175
|
-
second-instance — surfacing main (visible=false, minimized=false)
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
These cover everything you'd want when debugging "why did the app go invisible / crash / fail to surface" without needing to attach a debugger.
|
|
179
|
-
|
|
180
|
-
## Log levels
|
|
181
|
-
|
|
182
|
-
Standard: `log`, `info`, `warn`, `error`, `debug`. All levels are written to both transports by default.
|
|
183
|
-
|
|
184
|
-
To dial down via env vars (useful in CI to silence verbose framework noise):
|
|
185
|
-
|
|
186
|
-
| Var | Effect |
|
|
187
|
-
|---|---|
|
|
188
|
-
| `OMEGA_LOG_LEVEL_FILE=warn` | Only `warn` + `error` reach the file |
|
|
189
|
-
| `OMEGA_LOG_LEVEL_CONSOLE=error` | Only `error` reaches stdout/stderr |
|
|
190
|
-
|
|
191
|
-
Default is `silly` (everything) on both.
|
|
192
|
-
|
|
193
|
-
## How it works under the hood
|
|
194
|
-
|
|
195
|
-
@omega.js/desktop's runtime logger (`lib/logger-lite.js`) detects which process it's in:
|
|
196
|
-
|
|
197
|
-
- **Main**: writes to `runtime.log` directly via [electron-log](https://github.com/megahertz/electron-log)'s file transport. Sets up an IPC listener on channel `desktop:log:forward` to receive forwarded calls from preload + renderer.
|
|
198
|
-
- **Preload**: writes to console (DevTools) AND forwards each call via `ipcRenderer.send('desktop:log:forward', ...)` to main.
|
|
199
|
-
- **Renderer**: same as preload via `window.desktop.logger` (contextBridge surface).
|
|
200
|
-
- **Outside Electron** (build/CLI tools that happen to require this module): falls back to console-only.
|
|
201
|
-
|
|
202
|
-
File path resolution in main:
|
|
203
|
-
1. Read `app.isPackaged`.
|
|
204
|
-
2. If packaged → `app.getPath('logs')`.
|
|
205
|
-
3. If dev → `<cwd>/logs/`.
|
|
206
|
-
4. `mkdirSync` the dir, point electron-log at `<dir>/runtime.log`.
|
|
207
|
-
|
|
208
|
-
The transport is set up lazily on first `log()` call, so importing `LoggerLite` in build/CLI contexts that have no Electron is harmless.
|
|
209
|
-
|
|
210
|
-
## Coexisting with `dev.log`, `build.log`, `test.log`, and `deploy.log`
|
|
211
|
-
|
|
212
|
-
Five separate logs in `<projectRoot>/logs/`:
|
|
213
|
-
|
|
214
|
-
| File | Source | Lifetime |
|
|
215
|
-
|---|---|---|
|
|
216
|
-
| `runtime.log` | Packaged-app runtime in dev mode | Persistent, rotates at 10 MB to `runtime.old.log` (one archive generation) |
|
|
217
|
-
| `dev.log` | Gulp pipeline + spawned Electron child stdout (`npm start`) | Truncated each `npm start` |
|
|
218
|
-
| `build.log` | Gulp pipeline output for production builds/packages (`npm run build` / `package` / `publish`, i.e. `OMEGA_BUILD_MODE=true`) | Truncated each build |
|
|
219
|
-
| `test.log` | `npx omega test` runner output (suite names, pass/fail states, harness boot lines) | Truncated each test run |
|
|
220
|
-
| `deploy.log` | GH Actions run output, streamed locally by the follower every target's deploy uses (`omega deploy`, `npm run release`) ([#873](https://github.com/Omega-JS-Stack/omega/issues/873); this was `ci.log`) | Truncated each deploy |
|
|
221
|
-
| `signing.log` | JSONL signing events from Windows code-signing (local dev fallback; on CI this writes to the runner home as `omega-signing.log` instead) | Appended (not truncated) |
|
|
222
|
-
|
|
223
|
-
`dev.log` and `build.log` are the same gulp tee — which one it writes is chosen by `OMEGA_BUILD_MODE`, so they never both fill up in one run. (Disable the tee with `OMEGA_LOG_FILE=false`; override its path with `OMEGA_LOG_FILE=<path>`.)
|
|
224
|
-
|
|
225
|
-
They serve different purposes and don't overlap: `dev.log`/`build.log` show you "is the build still running?", `test.log` shows you "which test failed on the last run?", `deploy.log` shows you "did the release workflow pass?", `runtime.log` shows you "is my app's auto-updater finding the right release feed?". All useful.
|
|
226
|
-
|
|
227
|
-
In production: only `runtime.log` exists (no project, no gulp, no GH Actions stream).
|
package/docs/menu.md
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
# Application Menu
|
|
2
|
-
|
|
3
|
-
File-based application menu (the macOS menu bar / Windows + Linux menu). Same builder + id-path API as [tray](tray.md) and [context-menu](context-menu.md).
|
|
4
|
-
|
|
5
|
-
## Config
|
|
6
|
-
|
|
7
|
-
No config block. Path is conventional: `src/integrations/menu/index.js`. To opt out, call `omega.menu.disable()` from your main entry.
|
|
8
|
-
|
|
9
|
-
## Definition file
|
|
10
|
-
|
|
11
|
-
```js
|
|
12
|
-
// src/integrations/menu/index.js
|
|
13
|
-
module.exports = ({ omega, menu, defaults }) => {
|
|
14
|
-
// Easiest: start from the platform-aware default template.
|
|
15
|
-
menu.useDefaults();
|
|
16
|
-
|
|
17
|
-
// Mutate by id-path:
|
|
18
|
-
menu.show('main/preferences'); // @omega.js/desktop ships this hidden by default
|
|
19
|
-
menu.update('main/check-for-updates', { label: 'Get Latest Version' });
|
|
20
|
-
menu.insertAfter('main/check-for-updates', {
|
|
21
|
-
id: 'main/account', label: 'Account...', click: () => omega.windows.show('account'),
|
|
22
|
-
});
|
|
23
|
-
menu.remove('view/reload');
|
|
24
|
-
menu.hide('main/services');
|
|
25
|
-
|
|
26
|
-
// Or add a whole new top-level menu:
|
|
27
|
-
menu.menu('Tools', [{ id: 'tools/sync', label: 'Sync Now', click: () => {} }]);
|
|
28
|
-
};
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Builder API (during definition)
|
|
32
|
-
|
|
33
|
-
```js
|
|
34
|
-
menu.menu(label, items) // add a top-level menu bar entry
|
|
35
|
-
menu.useDefaults() // populate with the platform-appropriate default template
|
|
36
|
-
menu.append(item) // append a top-level descriptor (rare; prefer menu())
|
|
37
|
-
menu.clear() // start over
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Id-path API
|
|
41
|
-
|
|
42
|
-
Same shape across menu / tray / context-menu. Available **during definition** (on the `menu` builder arg) AND **at runtime** on `omega.menu`:
|
|
43
|
-
|
|
44
|
-
```js
|
|
45
|
-
.find(idPath) // live descriptor or null
|
|
46
|
-
.has(idPath) // bool
|
|
47
|
-
.update(idPath, patch) // Object.assign + re-render. returns true if found.
|
|
48
|
-
.remove(idPath) // splice + re-render. returns true if removed.
|
|
49
|
-
.enable(idPath, bool = true) // sugar over update({enabled})
|
|
50
|
-
.show(idPath, bool = true) // sugar over update({visible})
|
|
51
|
-
.hide(idPath) // visible:false
|
|
52
|
-
.insertBefore(idPath, item) // splice in a sibling
|
|
53
|
-
.insertAfter(idPath, item) // splice in a sibling
|
|
54
|
-
.appendTo(idPath, item) // push into a submenu (creates submenu if absent)
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Menu ids are **paths** because menus actually nest (`main/check-for-updates`, `view/developer/toggle-devtools`). @omega.js/desktop matches by full id field first; if that misses it walks the path treating each segment as the last component of an id.
|
|
58
|
-
|
|
59
|
-
## Default template ids
|
|
60
|
-
|
|
61
|
-
Every item in @omega.js/desktop's default template carries a stable id you can target.
|
|
62
|
-
|
|
63
|
-
### macOS App menu (the one labeled with your app name)
|
|
64
|
-
|
|
65
|
-
| ID | Item | Notes |
|
|
66
|
-
|---|---|---|
|
|
67
|
-
| `main/about` | About | |
|
|
68
|
-
| `main/check-for-updates` | Check for Updates… | Auto-updater wired |
|
|
69
|
-
| `main/preferences` | Preferences… | `visible:false` by default — use `menu.show('main/preferences')` |
|
|
70
|
-
| `main/services` | Services submenu | |
|
|
71
|
-
| `main/hide` | Hide | |
|
|
72
|
-
| `main/hide-others` | Hide Others | |
|
|
73
|
-
| `main/show-all` | Show All | |
|
|
74
|
-
| `main/relaunch` | Relaunch | Restarts the app |
|
|
75
|
-
| `main/quit` | Quit | |
|
|
76
|
-
|
|
77
|
-
### File menu (win/linux equivalents of the App menu)
|
|
78
|
-
|
|
79
|
-
| ID | Item | Notes |
|
|
80
|
-
|---|---|---|
|
|
81
|
-
| `file/close` | Close (mac only) | |
|
|
82
|
-
| `file/preferences` | Preferences… (win/linux) | `visible:false` by default |
|
|
83
|
-
| `file/relaunch` | Relaunch (win/linux) | |
|
|
84
|
-
| `file/quit` | Exit | |
|
|
85
|
-
|
|
86
|
-
### Cross-platform
|
|
87
|
-
|
|
88
|
-
| ID | Item |
|
|
89
|
-
|---|---|
|
|
90
|
-
| `edit/undo`, `edit/redo`, `edit/cut`, `edit/copy`, `edit/paste`, `edit/select-all`, `edit/delete` | Edit submenu |
|
|
91
|
-
| `edit/paste-and-match-style` | mac only |
|
|
92
|
-
| `view/reload`, `view/reset-zoom`, `view/zoom-in`, `view/zoom-out`, `view/toggle-fullscreen` | View submenu |
|
|
93
|
-
| `view/developer` | Submenu (dev mode only) |
|
|
94
|
-
| `view/developer/toggle-devtools` | Toggle Developer Tools |
|
|
95
|
-
| `view/developer/inspect-elements` | Inspect Element |
|
|
96
|
-
| `view/developer/force-reload` | Force Reload |
|
|
97
|
-
| `view/developer/simulate-update` | Simulate update submenu (see [docs/auto-updater.md](auto-updater.md)) |
|
|
98
|
-
| `view/developer/simulate-update/available`, `.../unavailable`, `.../error` | Run the update simulator for one scenario |
|
|
99
|
-
| `window/minimize`, `window/zoom`, `window/front` | Window submenu (mac) |
|
|
100
|
-
| `window/minimize`, `window/close` | Window submenu (win/linux) |
|
|
101
|
-
|
|
102
|
-
### Help menu
|
|
103
|
-
|
|
104
|
-
| ID | Item | Notes |
|
|
105
|
-
|---|---|---|
|
|
106
|
-
| `help/check-for-updates` | Check for Updates… (win/linux only) | Auto-updater wired |
|
|
107
|
-
| `help/website` | "`<brandName>` Home" | Only when `brand.url` configured |
|
|
108
|
-
|
|
109
|
-
### Development menu (dev mode only)
|
|
110
|
-
|
|
111
|
-
Top-level, only visible when `omega.isDevelopment()`. Mirrors legacy @omega.js/desktop's developer utilities.
|
|
112
|
-
|
|
113
|
-
| ID | Item | Action |
|
|
114
|
-
|---|---|---|
|
|
115
|
-
| `development/open-exe-folder` | Open exe folder | Reveals `app.getPath('exe')` |
|
|
116
|
-
| `development/open-user-data` | Open user data folder | Reveals `app.getPath('userData')` |
|
|
117
|
-
| `development/open-logs` | Open logs folder | Reveals `app.getPath('logs')` |
|
|
118
|
-
| `development/open-app-config` | Open app config folder | Reveals `app.getPath('appData')` |
|
|
119
|
-
| `development/test-error` | Throw test error | Throws an uncaught error (verifies sentry / error handling) |
|
|
120
|
-
|
|
121
|
-
## Built-in framework items
|
|
122
|
-
|
|
123
|
-
`main/check-for-updates` (mac) and `help/check-for-updates` (win/linux) are **wired to `omega.autoUpdater`**:
|
|
124
|
-
- Label updates dynamically: *Checking…*, *Downloading 42%*, *Restart to Update v1.2.3*, *You're up to date*.
|
|
125
|
-
- Click triggers `autoUpdater.checkNow()` or `autoUpdater.installNow()` depending on state.
|
|
126
|
-
|
|
127
|
-
The same hook also patches the tray's `check-for-updates` item if present, so both UIs stay in lockstep.
|
|
128
|
-
|
|
129
|
-
Patch or remove either as needed — the auto-updater hook is a no-op when the item is missing.
|
|
130
|
-
|
|
131
|
-
## Item descriptors
|
|
132
|
-
|
|
133
|
-
Same dynamic conveniences as tray:
|
|
134
|
-
- `label` / `enabled` / `visible` / `checked` may be functions, evaluated on every `refresh()`
|
|
135
|
-
- `click` wrapped to catch errors
|
|
136
|
-
- `submenu` recursively resolved
|
|
137
|
-
|
|
138
|
-
## Runtime API on `omega.menu`
|
|
139
|
-
|
|
140
|
-
```js
|
|
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
|
-
|
|
146
|
-
// Id-path API — same as listed above.
|
|
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
|
-
|
|
152
|
-
// Inspection
|
|
153
|
-
omega.menu.getItems() // top-level descriptors (shallow copy)
|
|
154
|
-
omega.menu.isRendered() // bool
|
|
155
|
-
omega.menu.getMenu() // the underlying Electron Menu instance
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## Default scaffold
|
|
159
|
-
|
|
160
|
-
The scaffold every verb runs ships `src/integrations/menu/index.js` calling `menu.useDefaults()` plus commented-out examples (show preferences, insertAfter, update, remove, hide, add a Tools menu, appendTo).
|