@omega.js/desktop 0.50.0 → 0.51.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 +1 -1
- package/dist/assets/css/tokens/_index.scss +1 -1
- package/dist/assets/themes/base/_includes/frontend/sections/account-section-header.html +4 -1
- package/dist/assets/themes/base/_includes/frontend/sections/footer.html +13 -6
- package/dist/assets/themes/base/_includes/frontend/sections/nav.html +10 -8
- package/dist/assets/themes/base/_includes/global/sections/account.html +3 -1
- package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +12 -8
- package/dist/assets/themes/base/_includes/global/sections/app-topbar.html +10 -6
- package/dist/assets/themes/base/_includes/global/sections/page-header.html +8 -4
- package/dist/assets/themes/base/_layouts/backend/pages/dashboard/index.html +24 -24
- package/dist/assets/themes/base/_layouts/frontend/pages/about.html +10 -10
- package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +35 -35
- package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +4 -4
- package/dist/assets/themes/base/_layouts/frontend/pages/auth/signin.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/auth/signup.html +4 -4
- package/dist/assets/themes/base/_layouts/frontend/pages/contact.html +3 -3
- package/dist/assets/themes/base/_layouts/frontend/pages/download.html +34 -33
- package/dist/assets/themes/base/_layouts/frontend/pages/extension/index.html +11 -11
- package/dist/assets/themes/base/_layouts/frontend/pages/legal/document.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/status.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/team/index.html +9 -7
- package/dist/assets/themes/base/_layouts/frontend/pages/team/member.html +5 -3
- package/dist/assets/themes/base/_sections/about/letter/section.html +1 -1
- package/dist/assets/themes/base/_sections/about/letter/section.json5 +4 -4
- package/dist/assets/themes/base/_sections/marketing/bento/section.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/bento/section.json5 +15 -15
- package/dist/assets/themes/base/_sections/marketing/cta/section.json5 +1 -1
- package/dist/assets/themes/base/_sections/marketing/hero/section.html +6 -6
- package/dist/assets/themes/base/_sections/marketing/hero/section.json5 +10 -10
- package/dist/assets/themes/base/_sections/marketing/product-demo/section.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/product-demo/section.json5 +2 -2
- package/dist/assets/themes/base/_sections/marketing/stats/section.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/stats/section.json5 +5 -5
- package/dist/assets/themes/base/_sections/marketing/trusted-by/section.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/trusted-by/section.json5 +2 -2
- package/dist/assets/themes/neobrutalism/_layouts/frontend/pages/index.html +10 -10
- package/dist/assets/themes/newsflash/_layouts/frontend/pages/index.html +10 -10
- package/dist/assets/themes/newsflash/_sections/marketing/desks/section.html +2 -2
- package/dist/assets/themes/newsflash/_sections/marketing/desks/section.json5 +4 -4
- package/dist/build.js +69 -28
- package/dist/cli-run.js +20 -13
- package/dist/cli.js +12 -7
- package/dist/commands/build.js +0 -2
- package/dist/commands/deploy.js +116 -44
- package/dist/commands/finalize-release.js +5 -4
- package/dist/commands/launch.js +12 -7
- package/dist/commands/lib/deploy-precheck.js +66 -34
- package/dist/commands/lib/ensure-target.js +71 -11
- package/dist/commands/package.js +0 -1
- package/dist/commands/publish.js +11 -4
- package/dist/commands/release.js +99 -252
- package/dist/commands/runner.js +42 -5
- package/dist/commands/sign-windows.js +46 -15
- package/dist/commands/test.js +4 -3
- package/dist/commands/validate-certs.js +291 -115
- package/dist/config/page-template.html +4 -0
- package/dist/defaults/.github/workflows/build.yml +144 -64
- package/dist/defaults/AGENTS.md +3 -2
- package/dist/defaults/_.gitignore +4 -2
- package/dist/defaults/config/certs/README.md +25 -45
- package/dist/defaults/config/omega.json5 +66 -32
- package/dist/defaults/hooks/deploy/pre.js +10 -0
- package/dist/defaults/src/assets/scss/main.scss +12 -2
- package/dist/defaults/src/integrations/tray/index.js +1 -1
- package/dist/gulp/main.js +13 -25
- package/dist/gulp/tasks/audit.js +18 -6
- package/dist/gulp/tasks/build-config.js +181 -60
- package/dist/gulp/tasks/bundle.js +108 -36
- package/dist/gulp/tasks/release.js +86 -4
- package/dist/gulp/tasks/sass.js +11 -0
- package/dist/hooks/lib/notarize-tools.js +137 -0
- package/dist/hooks/notarize-artifacts.js +57 -0
- package/dist/hooks/notarize.js +59 -8
- package/dist/lib/auth-persistence.js +25 -0
- package/dist/lib/client-bridge.js +11 -8
- package/dist/lib/deep-link.js +15 -8
- package/dist/lib/protocol.js +7 -1
- package/dist/lib/restart-manager/install.js +6 -3
- package/dist/lib/sign-helpers/auto-unlock.js +65 -27
- package/dist/lib/sign-helpers/console-lock.js +34 -0
- package/dist/lib/sign-helpers/exec-with-limit.js +68 -0
- package/dist/lib/sign-helpers/resolve-icons.js +6 -4
- package/dist/lib/tray.js +7 -6
- package/dist/main.js +16 -0
- package/dist/preload.js +8 -0
- package/dist/renderer.js +16 -4
- package/dist/runner/job-started.js +104 -0
- package/dist/test/fixtures/consumer-app/config/omega.json5 +7 -0
- package/dist/test/fixtures/consumer-app/package.json +1 -1
- package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +7 -1
- package/dist/test/harness/main-entry.js +2 -1
- package/dist/test/harness/renderer-preload.js +12 -3
- package/dist/test/runners/boot.js +101 -11
- package/dist/test/runners/electron.js +1 -1
- package/dist/test/suites/boot/consumer-app-boots.test.js +54 -0
- package/dist/test/suites/build/audit.test.js +45 -6
- package/dist/test/suites/build/auth-persistence-resolve.test.js +119 -0
- package/dist/test/suites/build/auto-unlock.test.js +105 -0
- package/dist/test/suites/build/boot-runner-timeout.test.js +253 -0
- package/dist/test/suites/build/brand-scss.test.js +106 -0
- package/dist/test/suites/build/build-config.test.js +146 -36
- package/dist/test/suites/build/build-json-bake.test.js +245 -0
- package/dist/test/suites/build/build-verbs.test.js +48 -15
- package/dist/test/suites/build/build-workflow-jobs.test.js +190 -0
- package/dist/test/suites/build/cli.test.js +32 -10
- package/dist/test/suites/build/config-schema.test.js +4 -4
- package/dist/test/suites/build/console-lock.test.js +51 -0
- package/dist/test/suites/build/defaults-scaffold.test.js +71 -2
- package/dist/test/suites/build/deploy-direct.test.js +241 -0
- package/dist/test/suites/build/deploy-dispatch.test.js +287 -0
- package/dist/test/suites/build/deploy-hook.test.js +169 -0
- package/dist/test/suites/build/ensure-target.test.js +14 -2
- package/dist/test/suites/build/env-delivery.test.js +19 -10
- package/dist/test/suites/build/env-watch.test.js +18 -7
- package/dist/test/suites/build/esm-only-dependency.test.js +127 -0
- package/dist/test/suites/build/exec-with-limit.test.js +53 -0
- package/dist/test/suites/build/finalize-release.test.js +2 -2
- package/dist/test/suites/build/get-config.test.js +120 -8
- package/dist/test/suites/build/github-utils.test.js +12 -6
- package/dist/test/suites/build/license-stamp.test.js +6 -4
- package/dist/test/suites/build/manager.test.js +88 -68
- package/dist/test/suites/build/manifest-deps.test.js +116 -0
- package/dist/test/suites/build/merge-line-files.test.js +27 -4
- package/dist/test/suites/build/notarize-artifacts.test.js +135 -0
- package/dist/test/suites/build/notarize-tools.test.js +38 -0
- package/dist/test/suites/build/notarize.test.js +207 -0
- package/dist/test/suites/build/release-pipeline.test.js +38 -60
- package/dist/test/suites/build/release-skipped-upload.test.js +107 -0
- package/dist/test/suites/build/resolve-icons.test.js +35 -35
- package/dist/test/suites/build/runner-job-guard.test.js +182 -0
- package/dist/test/suites/build/runner.test.js +25 -2
- package/dist/test/suites/build/sentry.test.js +8 -3
- package/dist/test/suites/build/setup-scripts.test.js +3 -0
- package/dist/test/suites/build/sign-windows.test.js +92 -8
- package/dist/test/suites/build/test-stealth.test.js +17 -11
- package/dist/test/suites/build/url-helpers.test.js +37 -17
- package/dist/test/suites/build/validate-certs.test.js +428 -55
- package/dist/test/suites/build/validate-config.test.js +3 -3
- package/dist/test/suites/main/auth-flow.test.js +12 -0
- package/dist/test/suites/main/auth-persistence.test.js +14 -17
- package/dist/test/suites/main/auto-updater.test.js +2 -2
- package/dist/test/suites/main/boot-sequence.test.js +1 -1
- package/dist/test/suites/main/client-bridge.integration.test.js +5 -82
- package/dist/test/suites/main/client-bridge.test.js +19 -6
- package/dist/test/suites/main/deep-link.test.js +54 -0
- package/dist/test/suites/main/startup-paths-and-ua.test.js +1 -1
- package/dist/test/suites/main/url-helpers.test.js +81 -72
- package/dist/test/suites/renderer/cross-context-helpers.test.js +19 -16
- package/dist/utils/build-pipeline.js +10 -10
- package/dist/utils/github.js +12 -51
- package/dist/utils/load-env.js +66 -0
- package/dist/utils/mode-helpers.js +43 -111
- package/dist/utils/platform.js +37 -0
- package/dist/utils/runner-env.js +2 -1
- package/dist/utils/runner-job-guard.js +149 -0
- package/dist/utils/ship-keys.js +52 -0
- package/dist/utils/test-stealth.js +5 -3
- package/dist/utils/url-helpers.js +33 -17
- package/dist/vendor/config/bundle-id.js +53 -0
- package/dist/vendor/config/client-config.js +141 -0
- package/dist/vendor/config/company.js +334 -15
- package/dist/vendor/config/dev-facts.js +48 -0
- package/dist/vendor/config/env-delivery.js +231 -9
- package/dist/vendor/config/env-retired.js +137 -0
- package/dist/vendor/config/env-rules.js +22 -3
- package/dist/vendor/config/env-schema.js +234 -117
- package/dist/vendor/config/env.js +55 -26
- package/dist/vendor/config/environment.js +189 -0
- package/dist/vendor/config/hooks.js +13 -11
- package/dist/vendor/config/index.js +121 -44
- package/dist/vendor/config/load.js +366 -115
- package/dist/vendor/config/merge.js +2 -2
- package/dist/vendor/config/order.js +3 -3
- package/dist/vendor/config/platforms.js +276 -0
- package/dist/vendor/config/repo.js +226 -104
- package/dist/vendor/config/retired-keys.js +232 -27
- package/dist/vendor/config/schema.js +525 -99
- package/dist/vendor/config/site-global.js +63 -53
- package/dist/vendor/config/targets.js +187 -0
- package/dist/vendor/config/validate.js +119 -59
- package/dist/vendor/devkit/argv.js +118 -0
- package/dist/vendor/devkit/attach-log-file.js +21 -13
- package/dist/vendor/devkit/brand-tokens.js +278 -0
- package/dist/vendor/devkit/brand-version.js +264 -0
- package/dist/vendor/devkit/build-json.js +91 -0
- package/dist/vendor/devkit/bundle.js +48 -0
- package/dist/vendor/devkit/certificate-expiry.js +108 -0
- package/dist/vendor/devkit/certs.js +16 -194
- package/dist/vendor/devkit/ci-workflows.js +124 -8
- package/dist/vendor/devkit/cli-router.js +3 -3
- package/dist/vendor/devkit/defaults-engine.js +69 -7
- package/dist/vendor/devkit/deploy-follow.js +297 -0
- package/dist/vendor/devkit/deploy-precheck.js +23 -8
- package/dist/vendor/devkit/deploy-record.js +11 -27
- package/dist/vendor/devkit/deploy-snapshot.js +661 -0
- package/dist/vendor/devkit/deploy.js +445 -75
- package/dist/vendor/devkit/git-auth.js +73 -0
- package/dist/vendor/devkit/git-remote.js +95 -0
- package/dist/vendor/devkit/github-repo.js +290 -0
- package/dist/vendor/devkit/local.js +47 -0
- package/dist/vendor/devkit/merge-line-files.js +23 -16
- package/dist/vendor/devkit/omega-bin.js +18 -3
- package/dist/vendor/devkit/pack-local.js +391 -0
- package/dist/vendor/devkit/preludes/index.js +120 -0
- package/dist/vendor/devkit/preludes/origin-heal.js +156 -0
- package/dist/vendor/devkit/service-account.js +43 -0
- package/dist/vendor/devkit/ship-plan.js +112 -0
- package/dist/vendor/devkit/signing-env.js +180 -0
- package/dist/vendor/devkit/signing-tree.js +92 -0
- package/dist/vendor/devkit/target-seams.js +142 -0
- package/dist/vendor/devkit/target-secrets.js +235 -50
- package/dist/vendor/devkit/test/esm-only-fixture.js +48 -0
- package/dist/vendor/devkit/test/fixtures/esm-only-package/browser.js +19 -0
- package/dist/vendor/devkit/test/fixtures/esm-only-package/index.js +20 -0
- package/dist/vendor/devkit/test/fixtures/esm-only-package/package.json +13 -0
- package/dist/vendor/monitoring/env.js +20 -10
- 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 +1 -1
- package/docs/auto-updater.md +5 -5
- package/docs/boot-sequence.md +1 -1
- package/docs/build-system.md +15 -7
- package/docs/client-bridge.md +9 -7
- package/docs/config-schema.md +4 -4
- package/docs/css.md +8 -2
- package/docs/deep-link.md +12 -4
- package/docs/environment-detection.md +32 -24
- package/docs/hooks.md +3 -1
- package/docs/icons.md +7 -7
- package/docs/index.md +61 -23
- package/docs/installer-options.md +24 -21
- package/docs/logging.md +5 -5
- package/docs/releasing.md +25 -17
- package/docs/runner.md +40 -5
- package/docs/shared/brands.md +12 -6
- package/docs/shared/breaking-changes.md +375 -21
- package/docs/shared/config.md +757 -199
- package/docs/shared/deploys.md +194 -91
- package/docs/shared/icons.md +18 -0
- package/docs/shared/local-dev.md +24 -6
- package/docs/shared/logging.md +9 -6
- package/docs/shared/monitoring.md +27 -13
- package/docs/shared/publishing.md +3 -3
- package/docs/shared/rulings.md +2 -2
- package/docs/shared/testing.md +1 -1
- package/docs/shared/theming.md +26 -1
- package/docs/shared/translation.md +49 -7
- package/docs/shared/updates.md +1 -1
- package/docs/signing.md +59 -33
- package/docs/test-framework.md +10 -5
- package/docs/themes.md +15 -1
- package/package.json +18 -12
- package/bin/omega-desktop +0 -2
- package/dist/commands/push-secrets.js +0 -141
- package/dist/test/suites/build/deliver-certs.test.js +0 -95
- package/dist/test/suites/build/derive-signing-env.test.js +0 -122
- package/dist/test/suites/build/push-secrets.test.js +0 -226
- package/dist/test/suites/build/resolve-signing-cert.test.js +0 -342
- package/dist/utils/deliver-certs.js +0 -69
- package/dist/utils/derive-signing-env.js +0 -56
- package/dist/utils/resolve-signing-cert.js +0 -175
- package/dist/vendor/config/desktop-artifacts.js +0 -110
- package/dist/vendor/config/instances.js +0 -208
- /package/dist/defaults/config/icons/{macos → mac}/dmg.png +0 -0
- /package/dist/defaults/config/icons/{macos → mac}/icon.png +0 -0
- /package/dist/defaults/config/icons/{macos → mac}/tray.png +0 -0
package/docs/runner.md
CHANGED
|
@@ -50,6 +50,7 @@ Then, in a normal (non-elevated) PowerShell:
|
|
|
50
50
|
4. `npx omega sign-windows --smoke` — copies `where.exe` to a temp dir, signs it (the PIN is typed into SafeNet's Token Logon dialog for you), verifies it, cleans up. If this fails, stop and fix it: the runner calls exactly the same `signtool` underneath. Then `npx omega test --extended desktop:build/sign-windows-e2e` from a desktop target: the Windows-gated end-to-end suite, an `--extended` lane because it drives the real token (the bare lane skips its five signing cases everywhere, this box included), which signs, verifies, checks that verify rejects an unsigned file, reads back the event log, and runs one `windows-sign` job's command against the token (it skips itself everywhere but here). That rejection case leans on `where.exe` being catalog-signed rather than embedded-signed, so `signtool verify /pa` reports the unsigned copy as unsigned; if it comes back signed on your box, the sample carries an embedded signature there and the case needs a different one.
|
|
51
51
|
5. `npx omega runner install` again. It tears down any prior install (the electron-manager era's included), downloads the pinned `actions/runner`, registers one runner per org in `OMEGA_RUNNER_ORGS` (every org you administer when it is empty), writes each Startup shortcut, and then brings every registered runner online detached, leaving your terminal free. A scripted install ends online too: nothing about that step needs a terminal.
|
|
52
52
|
6. `npx omega runner status` — confirm the config keys are set, one Startup shortcut and one live listener per org, and that no listener reports `session=0`.
|
|
53
|
+
7. Read the two allow lists the install wrote, and narrow them if you want to ([#875](https://github.com/Omega-JS-Stack/omega/issues/875), § The job guard below): `%LOCALAPPDATA%\omega-runner\allowed-repos.txt` and `allowed-actors.txt`. The install fills them with `<org>/*` for every org it registered and with your `GH_TOKEN` user's login; both are plain text, one entry per line, `#` comments allowed, and nothing rewrites a line you changed.
|
|
53
54
|
|
|
54
55
|
`install` and `config` are ONE walk, so there is nothing to remember about which command changes what. Every key is asked, in the file's order, required or optional, and each question's DEFAULT is that key's current value: what the file saved, else what the shell or a CI job delivered, else the suggestion (the newest SDK `signtool`). Enter keeps what is there — including a secret, which is never echoed back at you ("Enter keeps the current value"). "Current" means current: a key the file does not have yet but your shell delivered is offered as the default, and Enter writes it into the box's file. Every value the walk ends with is written, the kept ones too (which is how an old file's bare `KEY=value` lines come back as `KEY="value"` without a single value moving), and they are written before the orgs question, so backing out of it never costs you the keys you just typed. A required key with nothing saved and an empty answer is refused, naming the key.
|
|
55
56
|
|
|
@@ -84,7 +85,7 @@ Notes worth knowing before you use them:
|
|
|
84
85
|
- **`restart` is `stop` then `start`**, in that order, for the loop you would otherwise run by hand after a config change. It settles two things the two commands typed in sequence do not: the box config walk runs FIRST, so a box missing a required key is refused before anything is killed rather than left stopped, and each org's dir is polled (5 seconds) until no listener stands in it, because `taskkill` returns before the process is gone and a start that raced it would read the dying listener as "already running". A listener still standing after the wait is reported and that org is left alone, exit 1.
|
|
85
86
|
- **`stop` leaves the Startup shortcuts in place**, so a logout/login brings the runner back. For a permanent stop, run `uninstall`.
|
|
86
87
|
- **Every subcommand except `self-update` and `monitor` refuses on non-Windows.** `OMEGA_RUNNER_FORCE=1` overrides it, for framework tests only.
|
|
87
|
-
- **A test process cannot touch a real box.** Every subcommand that changes the machine — `install`, `config`, `register-org`, `start`, `restart`, `stop`, `uninstall`, `self-update` — refuses, before the platform check and naming `OMEGA_TEST_RUNNER`, whenever the run is a test (`omega test` sets that variable; the
|
|
88
|
+
- **A test process cannot touch a real box.** Every subcommand that changes the machine — `install`, `config`, `register-org`, `start`, `restart`, `stop`, `uninstall`, `self-update` — refuses, before the platform check and naming `OMEGA_TEST_RUNNER`, whenever the run is a test (`omega test` sets that variable; `OMEGA_TEST_MODE` counts too, the marker a sibling framework's runner or a consumer's own test script sets) and a home it could act on is not a scratch one, under a `.temp` directory or the OS temp dir. BOTH homes are checked, the passed one and the module-level `RUNNER_HOME`, because the box's `.env` was already read into the process from the latter when the command module was required; the refusal names whichever is real. The marker is read from the process environment only — an injected environment is a fixture for the config walk, never an answer to "am I a test". The Startup folder is the THIRD surface checked, because no home scopes it — `uninstall` sweeps every `omega-runner-*.cmd` in the folder whatever home it was given, and a case whose two homes were both scratch deleted the box's three real shortcuts. It has its own scratch seam, `OMEGA_RUNNER_STARTUP_DIR`, and a test run against the real folder refuses naming both. The surfaces that no path can redirect at all — the watcher service, the legacy logon tasks, the `actions.runner.*` services, and the legacy `em-runner` homes — are simply not swept under a test run; `uninstall` says so on one line instead. A test run also never kills a process whose ExecutablePath it cannot read: that path belongs to another account, and matching it scopes to no home at all, so `stop` and `uninstall` drop the clause instead of `taskkill /F`-ing a stranger's runner. And it never deregisters on its own: `deregisterOrgRunners` mints a real removal token and runs each org directory's `config.cmd`, neither of them home-scoped, so with a roster to remove a test run refuses, naming the seam, unless `exec` is injected and, while `GH_TOKEN` is set, `getRemoveToken` too. A framework suite that wants to drive these points `OMEGA_RUNNER_HOME` and `OMEGA_RUNNER_STARTUP_DIR` at scratches *before* the command module is required, since both are resolved once, at require time. `sign-windows` follows the same rule for its log: from a test run pointed at a real home it tees nowhere rather than write the box's own record. This exists because a suite once ran a real `install` on the box and registered 34 orgs.
|
|
88
89
|
- **`uninstall` deregisters on the GitHub side first, and keeps whatever did not come off.** It walks every `actions-runner-<org>\` directory under the runner home and runs that directory's own `config.cmd remove` before anything is deleted. If a removal exits non-zero — or `GH_TOKEN` is not set, so no removal token can be minted — that runner is still registered, so its directory SURVIVES the uninstall and the summary names the org. Re-running `uninstall` retries it. Belt and braces: `register-org` also deletes every org-side runner starting with this host's prefix before it registers a new one.
|
|
89
90
|
|
|
90
91
|
## Upgrading from the electron-manager runner
|
|
@@ -109,6 +110,34 @@ npx omega runner register-org <org-name>
|
|
|
109
110
|
|
|
110
111
|
`register-org` writes the Startup shortcut but does not launch the runner. Run `npx omega runner start` (it brings up every registered org and skips the ones already alive), or log out and back in.
|
|
111
112
|
|
|
113
|
+
## The job guard
|
|
114
|
+
|
|
115
|
+
The box holds the EV token, so whoever can start a job on it can sign binaries with your cert. The workflows this framework generates fire only on a dispatch, but a workflow is one careless edit away from a `push` trigger, so the box refuses the job itself ([#875](https://github.com/Omega-JS-Stack/omega/issues/875)).
|
|
116
|
+
|
|
117
|
+
`npx omega runner install` (and `start` / `restart`, which heal a box installed before the guard existed) writes three files:
|
|
118
|
+
|
|
119
|
+
| File | What it is |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `%LOCALAPPDATA%\omega-runner\job-started.js` | the hook, a copy of the framework's own, rewritten from the package on every install and start so an update reaches the box |
|
|
122
|
+
| `%LOCALAPPDATA%\omega-runner\allowed-repos.txt` | one `owner/name` per line; `owner/*` means every repo of one owner |
|
|
123
|
+
| `%LOCALAPPDATA%\omega-runner\allowed-actors.txt` | one GitHub login per line |
|
|
124
|
+
|
|
125
|
+
and delivers the hook's path to each registration through that runner's own `<runner dir>\.env` as `ACTIONS_RUNNER_HOOK_JOB_STARTED`: the same file the private HOME travels in, so one write reaches the Startup shortcut and the detached spawn alike. GitHub's runner executes it before a job's first step and FAILS the job on a nonzero exit, with the hook's output in the job's `Set up runner` step. The runner runs it with its own bundled node; nothing on your PATH is involved.
|
|
126
|
+
|
|
127
|
+
Three checks, all of which must pass:
|
|
128
|
+
|
|
129
|
+
| Check | Refused when |
|
|
130
|
+
|---|---|
|
|
131
|
+
| `GITHUB_EVENT_NAME` | it is not `workflow_dispatch`, the ONE trusted event (#923): every publish path (a CMS button, `omega deploy`, a plain HTTP call) dispatches it at the deploy ref |
|
|
132
|
+
| `GITHUB_REPOSITORY` | no line of `allowed-repos.txt` matches it |
|
|
133
|
+
| `GITHUB_ACTOR` | no line of `allowed-actors.txt` matches it. A dispatch carries the deploy token's user, which is the same account |
|
|
134
|
+
|
|
135
|
+
A miss prints ONE line naming the check and the value it saw, and the job dies with nothing run: no checkout, no install, no `signtool`.
|
|
136
|
+
|
|
137
|
+
**Editing the lists is the point.** They start as the scope the registration already has: an `<org>/*` line per registered org, and the `GH_TOKEN` user's login. Narrow `Omega-JS-Stack/*` to `Omega-JS-Stack/my-brand-omega` and the next `install` leaves it alone: an org that already has ANY line is never appended to again. Add a second account by adding a line. An EMPTY list refuses every job rather than passing one, which is what a box whose `GH_TOKEN` could not answer at install time will do until you fill `allowed-actors.txt` in.
|
|
138
|
+
|
|
139
|
+
`uninstall` keeps both lists (they are the box's configuration, like its `.env`) and removes the hook script, which the next install writes back.
|
|
140
|
+
|
|
112
141
|
## Environment variables
|
|
113
142
|
|
|
114
143
|
Split by who sets them.
|
|
@@ -126,6 +155,8 @@ Split by who sets them.
|
|
|
126
155
|
|
|
127
156
|
Shell-only (they decide where the file IS, so they cannot live in it): `OMEGA_RUNNER_HOME` overrides the runner home, `OMEGA_RUNNER_STARTUP_DIR` the Startup folder the shortcuts are written to and swept from (framework tests only — it is the folder's scratch seam), and `OMEGA_SIGN_LOG` the signing event log path.
|
|
128
157
|
|
|
158
|
+
**The runner's own `<runner dir>\.env`** carries two framework-written lines, `HOME` (below) and `ACTIONS_RUNNER_HOOK_JOB_STARTED` (§ The job guard). It is the file GitHub documents for runner env, one `KEY=value` per line, read by the listener at startup and applied to every job it runs; a change to it takes effect at the next `npx omega runner restart`.
|
|
159
|
+
|
|
129
160
|
**The runner's own HOME** ([#807](https://github.com/Omega-JS-Stack/omega/issues/807)) is `%LOCALAPPDATA%\omega-runner\home`, and it holds one file: a real `.gitconfig` carrying `[core] autocrlf = false`. `actions/checkout` copies `$HOME\.gitconfig` into the temporary HOME it runs git under, and its copy helper recreates a SYMLINK source as a Windows junction, which is invalid for a file: a box whose `~/.gitconfig` is a dotfiles symlink (and it stays one) failed every git call in every job with `unknown error occurred while reading the configuration files`. HOME wins over the user's home directory in that lookup. It is delivered through each runner's own `<runner dir>\.env` (`HOME=...`, the file GitHub documents for proxy settings, one `KEY=value` per line, read by the listener at startup and applied to every job it runs), written by `install` and healed by `start` and `restart` for every registered org, so the Startup shortcut and the detached spawn both get it. `runner status` prints the path and whether the `.gitconfig` is there. A `.gitconfig` that is already there with different content is left alone and named in the output: it is yours to edit.
|
|
130
161
|
|
|
131
162
|
The runner belongs to whoever is logged in. There is no service and no scheduled
|
|
@@ -133,17 +164,17 @@ task, so there is no separate account to configure: `WIN_RUNNER_LOGON_ACCOUNT`,
|
|
|
133
164
|
`WIN_RUNNER_LOGON_PASSWORD` and the `set-credentials` subcommand were retired in
|
|
134
165
|
[#337](https://github.com/Omega-JS-Stack/omega/issues/337).
|
|
135
166
|
|
|
136
|
-
**Delivered by CI, optionally
|
|
167
|
+
**Delivered by CI, optionally**: a brand MAY push `WIN_EV_TOKEN_PATH`, `WIN_CSC_KEY_PASSWORD` and `SIGNTOOL_PATH` as GitHub Actions secrets (`omega deploy`'s precheck sends them from its `.env`); the `windows-sign` job's env block carries them and they win over the box file. A self-hosted box normally holds all three itself, so a brand pushes none: the generated env block delivers them empty, and an empty value counts as absent.
|
|
137
168
|
|
|
138
|
-
The signing strategy itself is config, not env: `platforms.
|
|
169
|
+
The signing strategy itself is config, not env: `platforms.windows.signing.strategy` in `config/omega.json5`, `self-hosted` by default.
|
|
139
170
|
|
|
140
171
|
## How a signing job runs
|
|
141
172
|
|
|
142
173
|
1. The mac/linux legs of the brand's `build.yml` package and publish as usual; the Windows leg packages **unsigned** and uploads a `windows-unsigned` artifact.
|
|
143
174
|
2. The `windows-sign` job picks up on your box (labels `self-hosted, windows, ev-token`), downloads that artifact, and runs `npx omega sign-windows --in release --out release/signed`.
|
|
144
175
|
3. For each `.exe` / `.msi`: copy to the output dir, then `signtool sign` with the resolved cert args, `/tr <timestamp url> /td sha256 /fd sha256`.
|
|
145
|
-
4. In thumbprint mode a helper starts alongside the sign call and types the PIN into SafeNet's "Token Logon" dialog if it appears.
|
|
146
|
-
5. **The sign call gets three attempts** with a short backoff. The timestamp server is a third party and a timeout or a 502 from it fixes itself; a failure signtool names as permanent (no matching certificate, wrong password, locked token, malformed file) stops on the first attempt instead of walking the token toward a lockout. Every attempt and every retry lands in the event log.
|
|
176
|
+
4. In thumbprint mode a helper starts alongside the sign call and types the PIN into SafeNet's "Token Logon" dialog if it appears, then watches the dialog for ten seconds: one still open after typing is reported as "the keystrokes did not reach it". Before the first call, a locked console (`LogonUI.exe` running) is refused outright, naming the fix, because the dialog renders behind the lock screen and the PIN lands on the lock screen instead (§ A locked console).
|
|
177
|
+
5. **The sign call gets three attempts** with a short backoff, and **each attempt has a three-minute limit**: a healthy sign takes about twenty seconds, so one still running minutes later is waiting on something that never comes, and its process tree is terminated with a message naming the limit (the attempt reads as transient, so the next one gets a fresh PIN watcher). The `windows-sign` job carries a thirty-minute `timeout-minutes` for the same reason. The timestamp server is a third party and a timeout or a 502 from it fixes itself; a failure signtool names as permanent (no matching certificate, wrong password, locked token, malformed file) stops on the first attempt instead of walking the token toward a lockout. Every attempt and every retry lands in the event log.
|
|
147
178
|
6. `signtool verify /pa` runs once against the signed file. No retry — it is a local check.
|
|
148
179
|
7. `latest.yml` and per-installer `.blockmap` files are written for the signed NSIS `.exe`s, because Windows is split into a post-build sign job and electron-updater has no other way to discover the release.
|
|
149
180
|
8. `npx omega finalize-release --signed-dir release/signed` uploads the signed assets to the release the mac/linux legs created.
|
|
@@ -202,6 +233,10 @@ The Startup folder is the fix: Explorer launches its contents in the interactive
|
|
|
202
233
|
|
|
203
234
|
`npx omega runner status` prints the session id of every live listener and warns loudly on `session=0`, and so does `start` when it meets one. If you see one, it is a leftover from an older install: `npx omega runner restart` replaces it.
|
|
204
235
|
|
|
236
|
+
### A locked console
|
|
237
|
+
|
|
238
|
+
Session 1 is not enough on its own: the desktop has to be UNLOCKED. Behind the lock screen the Token Logon dialog still exists (the watcher enumerates it) but every keystroke lands on the lock screen, so the PIN never arrives and `signtool` waits for it forever ([#864](https://github.com/Omega-JS-Stack/omega/issues/864): a Windows Update restart at the end of active hours auto-signed the box in, locked, and the sign job hung six hours). `sign-windows` now refuses a locked console before the first call, naming `LogonUI.exe` and the fix: unlock the box and re-run. Keeping the box unlocked across an update restart is the box's own setting, not the framework's: a classic auto-logon (Sysinternals Autologon) signs in without locking, where Windows' own "finish setting up after an update" always locks.
|
|
239
|
+
|
|
205
240
|
On a dedicated build box, enable Windows auto-logon so a reboot brings the session (and therefore the runner) back without a human.
|
|
206
241
|
|
|
207
242
|
### Two listeners on one registration
|
package/docs/shared/brands.md
CHANGED
|
@@ -12,25 +12,31 @@ Test-only forever, offline forever: project id `demo-naked-brand` (Firebase's em
|
|
|
12
12
|
|
|
13
13
|
### `brands/sandbox-brand` — the synthetic fixture
|
|
14
14
|
|
|
15
|
-
Fixture for the AUTOMATED corpus/e2e suites: offline, `demo-*` Firebase, deterministic. Both targets are REAL framework consumers, `targets/backend` on `@omega.js/backend` and (since [#775](https://github.com/Omega-JS-Stack/omega/issues/775)) `targets/
|
|
15
|
+
Fixture for the AUTOMATED corpus/e2e suites: offline, `demo-*` Firebase, deterministic. Both targets are REAL framework consumers, `targets/backend` on `@omega.js/backend` and (since [#775](https://github.com/Omega-JS-Stack/omega/issues/775)) `targets/web` on `@omega.js/web`, whose `/e2e` page carries the hooks the brand's own lane drives: the fixture is the brand's content, never a stand-in for the frameworks. Test runs may mangle and reset it. Never touches real cloud. It deliberately carries no agent-docs chain: its files are test output, not a workspace an agent should be guided into.
|
|
16
16
|
|
|
17
|
-
### `brands/omega
|
|
17
|
+
### `brands/playground-omega` — "OMEGA Playground", the standing live test brand
|
|
18
18
|
|
|
19
|
-
Renamed from omega-brand (Ian 2026-07-11
|
|
19
|
+
Renamed from omega-brand (Ian 2026-07-11, zero ambiguity). Born through the real wizard: id `playground` (shortened on 2026-09-10, [#808](https://github.com/Omega-JS-Stack/omega/issues/808), so the `<brand.id>-<role>` rule derives clean repo names off it), url playground.omegajs.dev, a SUBDOMAIN so derived surfaces never claim the real omegajs.dev. Its THREE repos all derive from that id, none of them typed ([#883](https://github.com/Omega-JS-Stack/omega/issues/883), all under the one `repo: { provider: 'github', org: 'Omega-JS-Stack' }` block): `playground-omega` (the PRIVATE source repo, and the folder name here, whose `main` every `omega deploy` snapshots this folder onto, [docs/shared/deploys.md](deploys.md)), `playground-releases` (public: the desktop installers, the extension zips and the autoupdater feed), and `playground-web` (public: the BUILT site alone, one force-orphan commit on `gh-pages`, served by Pages at playground.omegajs.dev, which is what lets the source repo stay private on a free org). The third, the private `playground-rehearsal` snapshot, retired with the rehearsal itself ([#872](https://github.com/Omega-JS-Stack/omega/issues/872)). Points at the real-but-throwaway Firebase project `omegajs-playground` (ITW-org-owned since 2026-07-11; sanctioned for live proofs: Blaze it, break it, delete it; it is TEST INFRASTRUCTURE, never production).
|
|
20
20
|
|
|
21
21
|
REBRANDED **OMEGA Playground** (Ian 2026-08-21, [#433](https://github.com/Omega-JS-Stack/omega/issues/433) — REVERSES the 2026-07-19 fiction ruling, whose invented brand read as a real product in the ad and analytics consoles). The doctrine now: the playground is openly the OMEGA test surface — "we can mess around here, nothing live actually matters" — so drift from the real omegajs.dev site reads as a demo doing its job, never as a broken copy. Infra identity unchanged (id, url, green accent, classy theme); name and voice are the only things that moved, and the catalog's display names stay placeholder demo copy. Cloud-side display names (the Meta pixel, the GA property + streams, the GCP project name) are the manager's follow-up.
|
|
22
22
|
|
|
23
|
+
**The playground converts FIRST, in the same change** (Ian 2026-09-11, [#883](https://github.com/Omega-JS-Stack/omega/issues/883)): "we should ALWAYS be updating playground to our new shapes." Every config, folder, repo, or workflow shape the frameworks adopt lands in `brands/playground-omega` in the commit that adopts it, and the playground deploy is the proof run. A playground on an old shape is a defect, never a pending chore.
|
|
24
|
+
|
|
25
|
+
**Its COMPANY is ITW Creative Works** (`company: { id: "itw-creative-works" }`, [#677](https://github.com/Omega-JS-Stack/omega/issues/677)): one top-level key names the parent, and the parent's name, url and wordmark, its config layer, its `.env`, its hooks and its signing tree all RESOLVE from it. ITW is not an OMEGA brand on this machine yet, so every playground run prints one line saying inheritance is off until it converts (the company layer is simply absent until then). The brand types `company: { webhooks: false }` ([#677](https://github.com/Omega-JS-Stack/omega/issues/677), the successor to the retired `parent: false`), which means only "the SendGrid ACCOUNT is shared with the real ITW brands and its one account-level webhook is theirs": the campaigns and newsletter services are its only readers.
|
|
26
|
+
|
|
23
27
|
Secrets live only in `.env`/`.omega/secrets` (gitignored; the config loader hard-fails secret-shaped keys) — the committed omega.json5 carries public-by-design values only.
|
|
24
28
|
|
|
25
29
|
### `brands/newsflash-brand` — "The Daily Build", the second skin
|
|
26
30
|
|
|
27
31
|
Added with Ian 2026-07-17. Id `daily-build`, url dailybuild.omegajs.dev (same subdomain rule). The standing SECOND-SKIN brand: a fictional dev-news publication wearing the newsflash theme permanently, so both first-party skins stay alive in real consumers (classy = playground, newsflash = here). Born by COPY of the playground — the wizard rehearsal is a separate queued exercise. OFFLINE-only (demo-* Firebase, no real cloud/services, never production); website + backend targets only; website dev port pinned 4100 for side-by-side, backend rides N7 bumps.
|
|
28
32
|
|
|
29
|
-
|
|
33
|
+
It plays the SUB-BRAND in the company-mode ads proof, so its company is the playground (`company: { id: "playground" }`, [#677](https://github.com/Omega-JS-Stack/omega/issues/677)): `advertising.providers.inhouse.source: 'company'` derives `api.<company host>` from the RESOLVED `company.url`, which is the playground's own url once any playground run has written its registry line on this machine (`scripts/e2e-verts-company.js` is the proof).
|
|
34
|
+
|
|
35
|
+
### `../omega-omega` — the REAL brand (sibling repo)
|
|
30
36
|
|
|
31
|
-
BORN 2026-07-18 (cp229), LIVE 2026-07-19 (cp232). Lives outside the monorepo with its own git history; folder + repo
|
|
37
|
+
BORN 2026-07-18 (cp229), LIVE 2026-07-19 (cp232). Lives outside the monorepo with its own git history; folder + repo are `omega-omega` per the `<brand.id>-<role>` rule ([#808](https://github.com/Omega-JS-Stack/omega/issues/808), 2026-09-10; `omega-brand` before that, `omegajs.dev` before 2026-07-19). GitHub: `itw-creative-works/omega-omega`, from `repo: { provider: 'github', org: 'itw-creative-works' }` (the legacy orgWebsite housing) plus the `<brand.id>-<role>` rule; its site publishes to `itw-creative-works/omega-web` ([#883](https://github.com/Omega-JS-Stack/omega/issues/883)).
|
|
32
38
|
|
|
33
|
-
Id `omega`, name "OMEGA", url omegajs.dev (LIVE
|
|
39
|
+
Id `omega`, name "OMEGA", url omegajs.dev (LIVE: GitHub Pages + Cloudflare), classy theme, website port 4200, web + backend + extension targets. The EXTENSION target is the **OMEGA Companion** ([#927](https://github.com/Omega-JS-Stack/omega/issues/927), 2026-09-14): the browser extension that files brand bookmarks and carries the trusted-automation bridge, which used to sit inside `@omega.js/manager` as `extension/` with another product's identity and shipped to no store at all. It is a normal extension target now (Chrome first, the Chrome Web Store lane, no listing created yet), and the router's `omega-extension` upstream holds the MCP half. Born by FORKING the playground's polished content 1:1 (never a promotion of the test project; stale es caches dropped and re-translated fresh). It is the first SUB-BRAND of Ian's eventual company umbrella, which the config `company: { id }` key models ([#677](https://github.com/Omega-JS-Stack/omega/issues/677)).
|
|
34
40
|
|
|
35
41
|
**Backend config is real** (flipped 2026-07-19): project `omegajs`, sdkconfig baked, `.firebaserc` real, Blaze linked to the Main Billing Account. authDomain = the BRAND host per cp268 — `omega build` self-hosts Firebase's `/__/auth/*` helper files (what the 2026-07-19 live 404 was actually missing), and a first-party authDomain keeps sign-in redirects working under browser storage partitioning.
|
|
36
42
|
|