@omega.js/desktop 0.53.0 → 0.54.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/README.md +38 -38
  2. package/dist/cli-run.js +4 -1
  3. package/dist/cli.js +2 -2
  4. package/dist/commands/cdp/client.js +1 -1
  5. package/dist/commands/cdp.js +1 -1
  6. package/dist/commands/clean.js +2 -3
  7. package/dist/commands/dev.js +25 -0
  8. package/dist/commands/lib/ensure-target.js +12 -17
  9. package/dist/commands/lib/migrate.js +17 -0
  10. package/dist/commands/logs.js +1 -1
  11. package/dist/commands/release.js +1 -1
  12. package/dist/commands/test.js +4 -4
  13. package/dist/commands/update.js +5 -4
  14. package/dist/defaults/.github/workflows/build.yml +18 -18
  15. package/dist/defaults/_.gitignore +0 -2
  16. package/dist/defaults/_mas/README.md +3 -3
  17. package/dist/defaults/config/certs/README.md +1 -1
  18. package/dist/defaults/config/omega.json5 +36 -36
  19. package/dist/defaults/docs/README.md +3 -3
  20. package/dist/defaults/gulpfile.js +1 -1
  21. package/dist/defaults/hooks/build/post.js +1 -1
  22. package/dist/defaults/hooks/build/pre.js +1 -1
  23. package/dist/defaults/hooks/notarize/post.js +2 -2
  24. package/dist/defaults/hooks/release/post.js +1 -1
  25. package/dist/defaults/hooks/release/pre.js +1 -1
  26. package/dist/defaults/src/assets/scss/pages/about.scss +1 -1
  27. package/dist/defaults/src/assets/scss/pages/main.scss +1 -1
  28. package/dist/defaults/src/assets/scss/pages/settings.scss +1 -1
  29. package/dist/defaults/src/integrations/context-menu/index.js +11 -11
  30. package/dist/defaults/src/integrations/menu/index.js +5 -5
  31. package/dist/defaults/src/integrations/tray/index.js +9 -9
  32. package/dist/defaults/src/main.js +2 -2
  33. package/dist/defaults/src/preload.js +1 -1
  34. package/dist/defaults/test/README.md +3 -3
  35. package/dist/defaults/test/_init.js +1 -1
  36. package/dist/gulp/tasks/audit.js +5 -8
  37. package/dist/lib/restart-manager/index.js +1 -1
  38. package/dist/lib/restart-manager/install.js +1 -1
  39. package/dist/lib/restart-manager/protocol.js +1 -1
  40. package/dist/main.js +4 -3
  41. package/dist/preload.js +1 -1
  42. package/dist/test/suites/build/audit.test.js +20 -7
  43. package/dist/test/suites/build/build-workflow-jobs.test.js +2 -2
  44. package/dist/test/suites/build/cli.test.js +28 -0
  45. package/dist/test/suites/build/defaults-em-dash.test.js +22 -0
  46. package/dist/test/suites/build/defaults-scaffold.test.js +19 -5
  47. package/dist/test/suites/build/deploy-direct.test.js +7 -5
  48. package/dist/test/suites/build/deploy-dispatch.test.js +2 -1
  49. package/dist/test/suites/build/deploy-hook.test.js +4 -2
  50. package/dist/test/suites/build/dev-verb.test.js +67 -0
  51. package/dist/test/suites/build/ensure-target.test.js +11 -3
  52. package/dist/test/suites/build/merge-line-files.test.js +6 -6
  53. package/dist/test/suites/build/migrate.test.js +29 -0
  54. package/dist/test/suites/build/project-scripts-deps.test.js +6 -10
  55. package/dist/test/suites/build/runner-env-write.test.js +73 -0
  56. package/dist/test/suites/build/runner.test.js +9 -8
  57. package/dist/test/suites/build/setup-scripts.test.js +27 -0
  58. package/dist/test/suites/build/validate-config.test.js +13 -2
  59. package/dist/test/suites/build/verb-logs.test.js +20 -0
  60. package/dist/test/suites/renderer/window-desktop-surface.test.js +1 -1
  61. package/dist/utils/build-pipeline.js +4 -4
  62. package/dist/utils/runner-env.js +13 -28
  63. package/dist/vendor/config/company.js +46 -14
  64. package/dist/vendor/config/defaults.js +30 -7
  65. package/dist/vendor/config/edit.js +25 -3
  66. package/dist/vendor/config/env-delivery.js +1 -1
  67. package/dist/vendor/config/env-schema.js +3 -6
  68. package/dist/vendor/config/env.js +34 -22
  69. package/dist/vendor/config/index.js +13 -17
  70. package/dist/vendor/config/load.js +15 -7
  71. package/dist/vendor/config/repo.js +10 -27
  72. package/dist/vendor/config/schema-client.js +64 -0
  73. package/dist/vendor/config/schema-cloud.js +38 -0
  74. package/dist/vendor/config/schema-manager.js +118 -0
  75. package/dist/vendor/config/schema-overrides.js +68 -0
  76. package/dist/vendor/config/schema.js +99 -152
  77. package/dist/vendor/config/validate.js +97 -77
  78. package/dist/vendor/devkit/agents-md.js +233 -0
  79. package/dist/vendor/devkit/attach-log-file.js +15 -1
  80. package/dist/vendor/devkit/ci-workflows.js +30 -30
  81. package/dist/vendor/devkit/cli-router.js +13 -7
  82. package/dist/vendor/devkit/defaults-engine.js +9 -43
  83. package/dist/vendor/devkit/deploy-snapshot.js +44 -9
  84. package/dist/vendor/devkit/env-lines.js +183 -0
  85. package/dist/vendor/devkit/local.js +62 -10
  86. package/dist/vendor/devkit/lockfile.js +32 -13
  87. package/dist/vendor/devkit/logger.js +7 -2
  88. package/dist/vendor/devkit/merge-line-files.js +219 -176
  89. package/dist/vendor/devkit/omega-bin.js +208 -111
  90. package/dist/vendor/devkit/preludes/docs-sync.js +52 -0
  91. package/dist/vendor/devkit/preludes/index.js +1 -0
  92. package/dist/vendor/devkit/target-picker.js +45 -0
  93. package/dist/vendor/devkit/test/dashed-files.js +37 -0
  94. package/dist/vendor/devkit/test/run-verb-under-tee.js +71 -0
  95. package/dist/vendor/devkit/update.js +15 -15
  96. package/dist/vendor/devkit/verb-scripts.js +40 -0
  97. package/dist/vendor/devkit/verbs.js +170 -0
  98. package/package.json +18 -24
  99. package/dist/commands/install.js +0 -37
  100. package/dist/defaults/AGENTS.md +0 -119
  101. package/dist/defaults/CLAUDE.md +0 -1
  102. package/dist/vendor/config/env-retired.js +0 -137
  103. package/dist/vendor/config/retired-keys.js +0 -635
  104. package/docs/analytics.md +0 -140
  105. package/docs/app-state.md +0 -92
  106. package/docs/audit.md +0 -69
  107. package/docs/auth.md +0 -284
  108. package/docs/auto-updater.md +0 -243
  109. package/docs/boot-sequence.md +0 -44
  110. package/docs/build-system.md +0 -169
  111. package/docs/cdp-debugging.md +0 -169
  112. package/docs/common-mistakes.md +0 -21
  113. package/docs/config-schema.md +0 -120
  114. package/docs/context-menu.md +0 -112
  115. package/docs/context.md +0 -81
  116. package/docs/css.md +0 -84
  117. package/docs/deep-link.md +0 -186
  118. package/docs/environment-detection.md +0 -112
  119. package/docs/fontawesome.md +0 -109
  120. package/docs/hooks.md +0 -89
  121. package/docs/icons.md +0 -79
  122. package/docs/index.md +0 -328
  123. package/docs/installer-options.md +0 -165
  124. package/docs/ipc.md +0 -61
  125. package/docs/lib-modules.md +0 -53
  126. package/docs/logging.md +0 -227
  127. package/docs/menu.md +0 -160
  128. package/docs/releasing.md +0 -239
  129. package/docs/remote-config.md +0 -118
  130. package/docs/remote-scripts.md +0 -144
  131. package/docs/restart-manager.md +0 -144
  132. package/docs/runner.md +0 -290
  133. package/docs/sentry.md +0 -97
  134. package/docs/shared/agent-docs.md +0 -89
  135. package/docs/shared/analytics.md +0 -612
  136. package/docs/shared/brands.md +0 -57
  137. package/docs/shared/breaking-changes.md +0 -917
  138. package/docs/shared/config.md +0 -1948
  139. package/docs/shared/deploys.md +0 -341
  140. package/docs/shared/icons.md +0 -219
  141. package/docs/shared/local-dev.md +0 -167
  142. package/docs/shared/logging.md +0 -205
  143. package/docs/shared/monitoring.md +0 -167
  144. package/docs/shared/publishing.md +0 -187
  145. package/docs/shared/rulings.md +0 -34
  146. package/docs/shared/testing.md +0 -147
  147. package/docs/shared/theming.md +0 -629
  148. package/docs/shared/translation.md +0 -342
  149. package/docs/shared/updates.md +0 -61
  150. package/docs/signing.md +0 -293
  151. package/docs/startup.md +0 -142
  152. package/docs/storage.md +0 -59
  153. package/docs/templating.md +0 -101
  154. package/docs/test-boot-layer.md +0 -157
  155. package/docs/test-framework.md +0 -362
  156. package/docs/themes.md +0 -149
  157. package/docs/tooltips.md +0 -99
  158. package/docs/tray.md +0 -164
  159. package/docs/usage.md +0 -58
  160. package/docs/verts.md +0 -62
  161. package/docs/windows.md +0 -149
@@ -4,10 +4,10 @@
4
4
  * tool): per dependency report installed vs wanted vs latest, classify the
5
5
  * jump (patch/minor/major), and QUARANTINE releases younger than --min-age
6
6
  * days (default 7 — a brand-new publish may be a compromised one; hold it
7
- * back unless explicitly forced). Report-only by default; --apply installs
8
- * the non-quarantined, non-breaking set (majors need the explicit --major
9
- * opt-in) through `npu install` when npu is on the machine, else plain
10
- * `npm install` with a loud note.
7
+ * back unless explicitly forced). A bare run installs the non-quarantined,
8
+ * non-breaking set (majors need the explicit --major opt-in) through
9
+ * `npu install` when npu is on the machine, else plain `npm install` with a
10
+ * loud note; --dry-run reports and installs nothing.
11
11
  *
12
12
  * `file:`/`link:`/git specs have no registry story (the local era's linked
13
13
  * @omega.js packages) — they're skipped with a dim note, never updated.
@@ -332,7 +332,7 @@ async function buildUpdateReport(options) {
332
332
  }
333
333
 
334
334
  /**
335
- * Pick the updates an --apply run installs. Default tier is MINOR (highest
335
+ * Pick the updates a run installs. Default tier is MINOR (highest
336
336
  * same-major — npu's non-breaking lane); --major unlocks latest. A target
337
337
  * published < minAge days ago is HELD (quarantine) unless already installed.
338
338
  * @param {object[]} rows - buildUpdateReport rows
@@ -469,7 +469,7 @@ function formatReport(report, options = {}) {
469
469
  for (const cells of body) lines.push(render(cells));
470
470
 
471
471
  if (report.rows.some((row) => row.quarantined)) {
472
- lines.push(`QUARANTINED = latest published < ${minAge} days ago (held from --apply; --min-age 0 or --force-fresh overrides)`);
472
+ lines.push(`QUARANTINED = latest published < ${minAge} days ago (held from the install; --min-age 0 or --force-fresh overrides)`);
473
473
  }
474
474
  if (report.rows.some((row) => row.bump === 'major')) {
475
475
  lines.push('major = breaking — never auto-applied (explicit --major opt-in)');
@@ -484,14 +484,14 @@ function formatReport(report, options = {}) {
484
484
  }
485
485
 
486
486
  /**
487
- * The one verb body every wrapper calls: report (default), then apply when
488
- * asked. Flags mirror npu: --apply, --major, --min-age N (default 7, 0
489
- * disables), --force-fresh (alias for --min-age 0).
487
+ * The one verb body every wrapper calls: report, then install (default) or
488
+ * stop at the report (--dry-run). Flags mirror npu: --major, --min-age N
489
+ * (default 7, 0 disables), --force-fresh (alias for --min-age 0).
490
490
  * @param {object} [options]
491
491
  * @param {string} [options.dir] - target directory (default cwd)
492
492
  * @param {string[]} [options.only] - check just these package names (#794)
493
- * @param {boolean} [options.apply] - install the selected set
494
- * @param {boolean} [options.major] - allow breaking jumps (with --apply)
493
+ * @param {boolean} [options.dryRun] - report only, install nothing
494
+ * @param {boolean} [options.major] - allow breaking jumps
495
495
  * @param {number} [options.minAge] - quarantine threshold in days
496
496
  * @param {boolean} [options.forceFresh] - disable the age quarantine
497
497
  * @param {object} [options.logger] - logger with log/warn (default console)
@@ -512,9 +512,9 @@ async function runUpdate(options = {}) {
512
512
  logger.log(`Dependency report for ${report.project}:`);
513
513
  for (const line of formatReport(report, { minAge })) logger.log(line);
514
514
 
515
- if (!options.apply) {
515
+ if (options.dryRun) {
516
516
  if (report.rows.length > 0) {
517
- logger.log('Report only — `omega update --apply` installs the non-quarantined, non-breaking set (--major for breaking).');
517
+ logger.log('Dry run (--dry-run): nothing installed; a bare `omega update` installs the non-quarantined, non-breaking set (--major for breaking).');
518
518
  }
519
519
  return { report, selection: null, commands: [] };
520
520
  }
@@ -529,7 +529,7 @@ async function runUpdate(options = {}) {
529
529
  }
530
530
 
531
531
  if (selection.updates.length === 0) {
532
- logger.log('Nothing to apply.');
532
+ logger.log('Nothing to install.');
533
533
  return { report, selection, commands: [] };
534
534
  }
535
535
 
@@ -545,7 +545,7 @@ async function runUpdate(options = {}) {
545
545
  execFn(entry.command, { cwd: dir, stdio: 'inherit' });
546
546
  }
547
547
 
548
- logger.log(`Applied ${selection.updates.length} update(s).`);
548
+ logger.log(`Installed ${selection.updates.length} update(s).`);
549
549
  return { report, selection, commands };
550
550
  }
551
551
 
@@ -0,0 +1,40 @@
1
+ /**
2
+ * verb-scripts: the package.json scripts a framework scaffolds into its targets,
3
+ * derived from the one verb table (verbs.js). Every fan-out verb a framework owns
4
+ * (fanout `each`) is `"<verb>": "omega <verb>"`, so the brand-root fan-out's
5
+ * `npm run <verb>` reaches the framework in every target, and `dev` is
6
+ * `"start": "omega dev"`. A single-target command (fanout `none`) is no script:
7
+ * the brand root passes it to the framework's CLI. Vendored with the table into
8
+ * every framework dist.
9
+ */
10
+
11
+ const { VERBS } = require('./verbs.js');
12
+
13
+ // npm names the dev script `start` (`npm start`), and the brand-root `omega dev`
14
+ // runs each target's `npm run start`.
15
+ const SCRIPT_KEYS = { dev: 'start' };
16
+
17
+ /**
18
+ * The verb scripts a framework owns.
19
+ *
20
+ * @param {string} framework - The framework package name ('@omega.js/web', ...).
21
+ * @returns {Object<string, string>} Script name to `omega <verb>`, in table order.
22
+ */
23
+ function verbScripts(framework) {
24
+ return Object.fromEntries(VERBS
25
+ .filter((row) => row.owners.includes(framework) && (row.fanout === 'each' || row.name in SCRIPT_KEYS))
26
+ .map((row) => [SCRIPT_KEYS[row.name] || row.name, `omega ${row.name}`]));
27
+ }
28
+
29
+ /**
30
+ * Every script a framework writes into a target: its verb scripts, with the
31
+ * scripts its manifest still declares (`projectScripts`) merged over them.
32
+ *
33
+ * @param {object} manifest - The framework's own package.json.
34
+ * @returns {Object<string, string>} Script name to command.
35
+ */
36
+ function projectScripts(manifest) {
37
+ return { ...verbScripts(manifest.name), ...(manifest.projectScripts || {}) };
38
+ }
39
+
40
+ module.exports = { verbScripts, projectScripts };
@@ -0,0 +1,170 @@
1
+ /**
2
+ * verbs: the ONE verb table. Every verb any OMEGA CLI answers to, declared once
3
+ * with where it runs (`scope`), who answers it (`owners`) and how a root runs it
4
+ * (`fanout`, `order`, `dryRun`). The dispatcher, the brand-root fan-outs and the
5
+ * target-script scaffolds (verb-scripts.js) read it; the field contract lives in
6
+ * docs/devkit/index.md. Pure data: the dispatcher that requires it is vendored
7
+ * into every framework dist.
8
+ */
9
+
10
+ const MANAGER = '@omega.js/manager';
11
+ const WEB = '@omega.js/web';
12
+ const BACKEND = '@omega.js/backend';
13
+ const DESKTOP = '@omega.js/desktop';
14
+ const EXTENSION = '@omega.js/extension';
15
+ const ALL = [MANAGER, WEB, BACKEND, DESKTOP, EXTENSION];
16
+
17
+ // The order every 'each' verb walks: backend's API goes live before the
18
+ // surfaces that call it. A target type with no rank runs after every ranked one.
19
+ const TARGET_ORDER = Object.freeze(['backend', 'web', 'extension', 'desktop', 'mobile']);
20
+
21
+ const SCOPES = Object.freeze(['root', 'contextless', 'box']);
22
+ const FANOUTS = Object.freeze(['each', 'root', 'none']);
23
+
24
+ const VERBS = Object.freeze([
25
+ // ─── contextless: run with no target at all ───────────────────────────────
26
+ { name: 'onboard', aliases: ['-o', '--onboard', 'create', 'new'], scope: 'contextless', owners: [MANAGER],
27
+ fanout: 'root', order: null, dryRun: false },
28
+ { name: 'help', aliases: ['h', '-h', '--help'], scope: 'contextless', owners: ALL,
29
+ fanout: 'root', order: null, dryRun: false },
30
+ { name: 'version', aliases: ['v', '-v', '--version'], scope: 'contextless', owners: ALL,
31
+ fanout: 'root', order: null, dryRun: false },
32
+ // none: prints ONE target's resolved root
33
+ { name: 'cwd', aliases: [], scope: 'contextless', owners: [BACKEND],
34
+ fanout: 'none', order: null, dryRun: false },
35
+ // none: reads one target's logs; interleaved streams would be unreadable
36
+ { name: 'logs', aliases: ['log', '--logs', 'logs:read', 'logs:tail', 'logs:stream'], scope: 'contextless', owners: [DESKTOP, BACKEND],
37
+ fanout: 'none', order: null, dryRun: false },
38
+
39
+ // ─── box: the signing box is a machine, not a project ─────────────────────
40
+ // none: the runner is the box's own service, configured from the runner home
41
+ { name: 'runner', aliases: ['--runner'], scope: 'box', owners: [DESKTOP],
42
+ fanout: 'none', order: null, dryRun: false },
43
+ // none: signs one artifact on the box, from any directory
44
+ { name: 'sign-windows', aliases: ['--sign-windows'], scope: 'box', owners: [DESKTOP],
45
+ fanout: 'none', order: null, dryRun: false },
46
+
47
+ // ─── brand-root fan-outs ──────────────────────────────────────────────────
48
+ { name: 'deploy', aliases: ['-d', '--deploy'], scope: 'root', owners: ALL,
49
+ fanout: 'each', order: TARGET_ORDER, dryRun: false },
50
+ { name: 'build', aliases: ['-b', '--build'], scope: 'root', owners: ALL,
51
+ fanout: 'each', order: TARGET_ORDER, dryRun: true },
52
+ { name: 'clean', aliases: ['-c', '--clean', 'clean:npm'], scope: 'root', owners: ALL,
53
+ fanout: 'each', order: TARGET_ORDER, dryRun: true },
54
+ { name: 'update', aliases: ['-u', '--update'], scope: 'root', owners: ALL,
55
+ fanout: 'each', order: TARGET_ORDER, dryRun: false },
56
+ { name: 'test', aliases: ['-t', '--test'], scope: 'root', owners: ALL,
57
+ fanout: 'each', order: TARGET_ORDER, dryRun: false },
58
+
59
+ // ─── the manager's own, run once at the brand root ────────────────────────
60
+ // root: the link flip walks every target from the brand root, so it runs once, never per target
61
+ { name: 'install', aliases: ['-i', 'i', '--install'], scope: 'root', owners: [MANAGER],
62
+ fanout: 'root', order: null, dryRun: false },
63
+ // root: the brand root boots every target's dev at once; a target runs its own framework's in place
64
+ { name: 'dev', aliases: ['--dev', 'serve', 'start'], scope: 'root', owners: ALL,
65
+ fanout: 'root', order: null, dryRun: false },
66
+ { name: 'manage', aliases: [], scope: 'root', owners: [MANAGER],
67
+ fanout: 'root', order: null, dryRun: false },
68
+ { name: 'bump', aliases: ['--bump'], scope: 'root', owners: [MANAGER],
69
+ fanout: 'root', order: null, dryRun: false },
70
+ { name: 'company', aliases: [], scope: 'root', owners: [MANAGER],
71
+ fanout: 'root', order: null, dryRun: false },
72
+ { name: 'devlog', aliases: [], scope: 'root', owners: [MANAGER],
73
+ fanout: 'root', order: null, dryRun: false },
74
+ { name: 'pipeline', aliases: [], scope: 'root', owners: [MANAGER],
75
+ fanout: 'root', order: null, dryRun: false },
76
+ // root: converts the brand config, then walks every target's migrate entry in-process
77
+ { name: 'migrate', aliases: ['-m', '--migrate', 'migration'], scope: 'root', owners: [MANAGER],
78
+ fanout: 'root', order: null, dryRun: false },
79
+
80
+ // ─── @omega.js/web ────────────────────────────────────────────────────────
81
+ // none: materializes ONE named page or file into one web target
82
+ { name: 'customize', aliases: ['-cz', '--customize'], scope: 'root', owners: [WEB],
83
+ fanout: 'none', order: null, dryRun: false },
84
+ { name: 'translate', aliases: ['--translate', 'translation'], scope: 'root', owners: [WEB],
85
+ fanout: 'each', order: TARGET_ORDER, dryRun: false },
86
+ { name: 'audit', aliases: ['-a', '--audit'], scope: 'root', owners: [WEB],
87
+ fanout: 'each', order: TARGET_ORDER, dryRun: false },
88
+ { name: 'purge', aliases: ['-cf', '--purge', 'cloudflare-purge'], scope: 'root', owners: [WEB],
89
+ fanout: 'each', order: TARGET_ORDER, dryRun: false },
90
+
91
+ // ─── @omega.js/desktop ────────────────────────────────────────────────────
92
+ { name: 'package', aliases: [], scope: 'root', owners: [DESKTOP],
93
+ fanout: 'each', order: TARGET_ORDER, dryRun: false },
94
+ { name: 'validate-certs', aliases: ['certs', '--validate-certs'], scope: 'root', owners: [DESKTOP],
95
+ fanout: 'each', order: TARGET_ORDER, dryRun: false },
96
+ // none: a CI leg's step on the tree that leg just built, one runner at a time
97
+ { name: 'publish', aliases: ['-p', '--publish'], scope: 'root', owners: [DESKTOP],
98
+ fanout: 'none', order: null, dryRun: false },
99
+ // none: cuts one signed release of one app
100
+ { name: 'release', aliases: ['-r', '--release'], scope: 'root', owners: [DESKTOP],
101
+ fanout: 'none', order: null, dryRun: false },
102
+ // none: closes the one release the CI run just built
103
+ { name: 'finalize-release', aliases: ['finalize', '--finalize-release'], scope: 'root', owners: [DESKTOP],
104
+ fanout: 'none', order: null, dryRun: false },
105
+ // none: opens one built app on this machine
106
+ { name: 'launch', aliases: ['open', '--launch'], scope: 'root', owners: [DESKTOP],
107
+ fanout: 'none', order: null, dryRun: false },
108
+ // none: drives one running app over its debugging port
109
+ { name: 'cdp', aliases: [], scope: 'root', owners: [DESKTOP],
110
+ fanout: 'none', order: null, dryRun: false },
111
+
112
+ // ─── @omega.js/backend ────────────────────────────────────────────────────
113
+ // none: clears the terminal; there is nothing per target to repeat
114
+ { name: 'clear', aliases: [], scope: 'root', owners: [BACKEND],
115
+ fanout: 'none', order: null, dryRun: false },
116
+ // none: a long-running emulator suite for one backend; the multi-target boot is `dev`
117
+ { name: 'serve', aliases: [], scope: 'root', owners: [BACKEND],
118
+ fanout: 'none', order: null, dryRun: false },
119
+ { name: 'indexes', aliases: ['indexes:get', 'firestore:indexes', 'firestore:indexes:get'], scope: 'root', owners: [BACKEND],
120
+ fanout: 'each', order: TARGET_ORDER, dryRun: false },
121
+ // none: a long-running emulator keep-alive for one backend
122
+ { name: 'emulator', aliases: ['emulators'], scope: 'root', owners: [BACKEND],
123
+ fanout: 'none', order: null, dryRun: false },
124
+ // none: a long-running source watcher for one backend
125
+ { name: 'watch', aliases: [], scope: 'root', owners: [BACKEND],
126
+ fanout: 'none', order: null, dryRun: false },
127
+ // none: a long-running webhook forwarder into one local backend
128
+ { name: 'stripe', aliases: ['stripe:listen'], scope: 'root', owners: [BACKEND],
129
+ fanout: 'none', order: null, dryRun: false },
130
+ // none: reads or writes named documents in one project
131
+ { name: 'firestore:get', aliases: ['firestore:set', 'firestore:query', 'firestore:delete'], scope: 'root', owners: [BACKEND],
132
+ fanout: 'none', order: null, dryRun: false },
133
+ // none: reads or writes named users in one project
134
+ { name: 'auth:get', aliases: ['auth:list', 'auth:delete', 'auth:set-claims', 'auth:token'], scope: 'root', owners: [BACKEND],
135
+ fanout: 'none', order: null, dryRun: false },
136
+ // none: one stdio MCP server for one backend
137
+ { name: 'mcp', aliases: [], scope: 'root', owners: [BACKEND],
138
+ fanout: 'none', order: null, dryRun: false },
139
+ // none: a one-time conversion that changes what the live project enforces, run alone
140
+ { name: 'migrate:rules', aliases: ['migrate:firestore-rules'], scope: 'root', owners: [BACKEND],
141
+ fanout: 'none', order: null, dryRun: false },
142
+ // none: a one-time conversion of one older tree, run alone
143
+ { name: 'migrate:markers', aliases: [], scope: 'root', owners: [BACKEND],
144
+ fanout: 'none', order: null, dryRun: false },
145
+ ]);
146
+
147
+ /**
148
+ * Every token that selects a verb: its name, then its aliases.
149
+ *
150
+ * @param {object} entry - A VERBS entry.
151
+ * @returns {string[]}
152
+ */
153
+ function tokensOf(entry) {
154
+ return [entry.name, ...entry.aliases];
155
+ }
156
+
157
+ /**
158
+ * The verb a token selects, or null. A name wins over an alias: `serve` is a
159
+ * `dev` alias AND the backend's own verb, and the row that NAMES it answers.
160
+ *
161
+ * @param {string} token - The token as typed.
162
+ * @returns {object|null} The VERBS entry.
163
+ */
164
+ function findVerb(token) {
165
+ return VERBS.find((entry) => entry.name === token)
166
+ || VERBS.find((entry) => entry.aliases.includes(token))
167
+ || null;
168
+ }
169
+
170
+ module.exports = { VERBS, TARGET_ORDER, SCOPES, FANOUTS, tokensOf, findVerb };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omega.js/desktop",
3
- "version": "0.53.0",
3
+ "version": "0.54.1",
4
4
  "description": "OMEGA desktop framework — build, test, and package Electron apps for macOS, Windows, and Linux",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -36,17 +36,17 @@
36
36
  "./lib/window-manager": "./dist/lib/window-manager.js",
37
37
  "./cli": "./dist/cli-run.js",
38
38
  "./ensure-target": "./dist/commands/lib/ensure-target.js",
39
+ "./migrate": "./dist/commands/lib/migrate.js",
39
40
  "./scripts/sync-nvmrc": "./scripts/sync-nvmrc.js"
40
41
  },
41
42
  "bin": {
42
- "omega": "./bin/omega",
43
- "omg": "./bin/omg",
44
- "mgr": "./bin/omega"
43
+ "omega": "bin/omega",
44
+ "omg": "bin/omg",
45
+ "mgr": "bin/omega"
45
46
  },
46
47
  "files": [
47
48
  "bin/",
48
49
  "dist/",
49
- "docs/",
50
50
  "scripts/"
51
51
  ],
52
52
  "preparePackage": {
@@ -101,19 +101,13 @@
101
101
  "start": "npm run prepare:watch",
102
102
  "prepare": "node -e \"require('../devkit/tools/prepare-guard').run()\"",
103
103
  "prepare:watch": "node -e \"require('prepare-package/watch')()\"",
104
- "test": "node ./bin/omega test"
104
+ "test": "node dist/cli-run.js test"
105
105
  },
106
106
  "projectScripts": {
107
- "start": "omega clean && npm run gulp --",
108
107
  "gulp": "gulp",
109
- "build": "omega build",
110
- "package": "omega package",
111
108
  "package:quick": "omega package --quick",
112
- "publish": "omega publish",
113
- "release": "omega release",
114
109
  "release:local": "omega publish --local",
115
110
  "postinstall": "node -e \"try { require('@omega.js/desktop/scripts/sync-nvmrc') } catch (e) {}\"",
116
- "test": "omega test",
117
111
  "electron": "electron ."
118
112
  },
119
113
  "engines": {
@@ -147,39 +141,39 @@
147
141
  "@omega.js/web": "*",
148
142
  "electron": "^42.0.1",
149
143
  "electron-builder": "^26.16.1",
150
- "firebase-admin": "^13.9.0",
151
- "prepare-package": "^2.2.0"
144
+ "firebase-admin": "^13.10.0",
145
+ "prepare-package": "^2.2.1"
152
146
  },
153
147
  "dependencies": {
154
- "@fortawesome/fontawesome-free": "^7.3.0",
155
- "@inquirer/prompts": "^8.5.2",
148
+ "@fortawesome/fontawesome-free": "^7.3.1",
149
+ "@inquirer/prompts": "^8.7.2",
156
150
  "@octokit/rest": "^22.0.1",
157
- "@omega.js/client": "0.53.0",
151
+ "@omega.js/client": "0.54.1",
158
152
  "@popperjs/core": "^2.11.8",
159
153
  "@sentry/electron": "^7.13.0",
160
154
  "chalk": "^5.6.2",
161
155
  "dotenv": "^17.4.2",
162
- "electron-log": "^5.4.3",
156
+ "electron-log": "^5.4.4",
163
157
  "electron-store": "^11.0.2",
164
158
  "electron-updater": "^6.8.3",
165
- "esbuild": "^0.28.1",
159
+ "esbuild": "^0.28.2",
166
160
  "extract-zip": "^2.0.1",
167
161
  "fs-jetpack": "^5.1.0",
168
162
  "glob": "^13.0.6",
169
163
  "gulp-clean-css": "^4.3.0",
170
164
  "gulp-rename": "^2.1.0",
171
- "gulp-responsive-modern": "^1.0.0",
165
+ "gulp-responsive-modern": "^1.0.4",
172
166
  "gulp-sass": "^6.0.1",
173
- "js-yaml": "^4.1.1",
167
+ "js-yaml": "^4.3.2",
174
168
  "json5": "^2.2.3",
175
169
  "lodash": "^4.18.1",
176
- "minimatch": "^10.2.5",
170
+ "minimatch": "^10.2.6",
177
171
  "node-powertools": "^3.0.0",
178
172
  "plist": "^4.0.0",
179
173
  "sass": "^1.99.0",
180
174
  "sharp": "^0.35.3",
181
- "uuid": "^14.0.0",
182
- "wonderful-fetch": "^2.0.5",
175
+ "uuid": "^14.0.2",
176
+ "wonderful-fetch": "^2.0.6",
183
177
  "wonderful-version": "^1.3.2",
184
178
  "ws": "^8.20.0"
185
179
  },
@@ -1,37 +0,0 @@
1
- // Libraries
2
- const build = require('../build.js');
3
- const logger = build.logger('install');
4
- const local = require('../vendor/devkit/local.js');
5
-
6
- const package = build.getPackage('main');
7
-
8
- module.exports = async function (options) {
9
- logger.log(`Installing ${package.name}...`);
10
-
11
- const type = options._[1] || 'prod';
12
-
13
- try {
14
- if (['live', 'prod', 'p', 'production'].includes(type)) {
15
- // The publish-day inverse of `i local`: flip every file: spec in the
16
- // brand tree to the exact <linked version>, then one registry install
17
- logger.log('Installing production (restoring registry specs tree-wide)...');
18
- const actions = await local.restoreRegistrySpecs({ dir: process.cwd(), logger });
19
- const flipped = actions.filter((action) => action.action === 'flip').length;
20
- return logger.log(flipped > 0
21
- ? `Production installation complete (${flipped} spec(s) restored to registry ranges).`
22
- : 'Already on registry specs — nothing to flip.');
23
- }
24
-
25
- if (['dev', 'd', 'development', 'local', 'l'].includes(type)) {
26
- logger.log('Installing development (local Omega monorepo)...');
27
- await local.linkLocalPackages({
28
- dir: process.cwd(),
29
- monorepoRoot: local.resolveMonorepoRoot(),
30
- logger,
31
- });
32
- return logger.log('Development installation complete.');
33
- }
34
- } catch (e) {
35
- logger.error('Error during install:', e);
36
- }
37
- };
@@ -1,119 +0,0 @@
1
- # ========== Default Values ==========
2
- # OMEGA Desktop (@omega.js/desktop) consumer project
3
-
4
- <!-- MAINTAINERS (framework repo): this consumer template is MIRRORED across all OMEGA framework consumer templates (src/defaults/AGENTS.md ×N; web's lives at scaffold/AGENTS.md).
5
- Same sections in the same order: framework-specific extras may be inserted; canonical sections are never reordered/renamed. Edit every framework consumer template together.
6
- The mirroring rule lives in each framework guide's Doc-update parity section (docs/<framework>/index.md) -->
7
-
8
- ## Framework
9
-
10
- This project consumes **OMEGA Desktop** (@omega.js/desktop), a comprehensive framework for building modern Electron desktop apps. @omega.js/desktop provides one-line-import bootstrap per Electron process, a modular feature library with file-based extensibility, a multi-platform build/release pipeline (DMG / NSIS / deb / AppImage), and a built-in four-layer test framework.
11
-
12
- ## 🚨 READ THE FRAMEWORK DOCS FIRST
13
-
14
- **Before doing ANY work on this codebase, the agent MUST read the framework documentation: that is where the architecture, conventions, APIs, and gotchas live. Skipping these will result in solutions that conflict with framework patterns.**
15
-
16
- **Required reading:**
17
- - **`node_modules/@omega.js/AGENTS.md`**: the OMEGA map, the one agent entry into the framework docs; follow it to `docs/desktop/index.md` (the @omega.js/desktop guide: identity, architecture, conventions)
18
- - **`node_modules/@omega.js/desktop/docs/`**: subsystem deep references (read the relevant ones for the task at hand)
19
-
20
- ## 🚨 READ @omega.js/client TOO
21
-
22
- **@omega.js/desktop's renderer instance extends `@omega.js/client`'s base class.**
23
- - It powers auth, Firebase, reactive `data-omega-bind` directives, analytics, error tracking, and utilities (`escapeHTML`, etc.).
24
- - `omega.auth.user` is always a `User`: `authenticated`, `plan`, `active`, `profile.displayName`; `omega.auth.listen()` delivers `{ user, denied }`.
25
- - 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.
26
-
27
- **Required reading:**
28
- - **`node_modules/@omega.js/AGENTS.md`** → `docs/client/index.md`, the @omega.js/client guide: identity, module list, conventions
29
- - **`node_modules/@omega.js/client/docs/`**: module deep references (Auth, Bindings, Firestore, Notifications, etc.)
30
-
31
- ## Quick start
32
-
33
- ```bash
34
- npm start # dev with auto-reload (gulp → esbuild → electron .)
35
- npm run build # local production build (compiles bundles only, no installer)
36
- npm run package # full local production package (DMG/zip/universal-mac, NSIS-win, deb+AppImage-linux)
37
- npm run package:quick # fast packaged build for the host platform/arch only (~20-30s)
38
- npm run release # signed + published release (requires certs)
39
- npx omega test # run YOUR project's test suites (bare runs never include the framework corpus)
40
- npx omega test build/config # run project tests by path (relative to test/; full:<path> for both sources)
41
- npx omega test project: # run ONLY your project tests (all of them)
42
- npx omega test project:custom-test # run only consumer project tests matching a path
43
- npx omega test mgr: # run ONLY framework tests (universal alias; desktop:/framework: are equivalent)
44
- npx omega test desktop:build/config # run only framework tests matching a path
45
- npx omega test --extended # also run tests that hit REAL external services (off by default; TEST_EXTENDED_MODE=true is the env equivalent, a shared name across @omega.js/backend, @omega.js/extension, UJM, and @omega.js/desktop)
46
- # (output is teed to logs/: dev.log on `npm start`, build.log on `npm run build`, test.log on `npx omega test`; cat instead of scrolling scrollback)
47
- npx omega install dev # use LOCAL @omega.js/desktop source (to test framework edits)
48
- npx omega install live # restore the published @omega.js/desktop from npm
49
- ```
50
-
51
- > Editing the @omega.js/desktop framework source while working here? Run `npx omega install dev` so this project picks up your uncommitted framework changes (it otherwise uses its installed `node_modules/@omega.js/desktop`). Run `npx omega install live` to switch back.
52
-
53
- ## Where things live
54
-
55
- - `config/omega.json5`: the single OMEGA config (JSON5), with shared sections (brand, analytics, payment, cloud, monitoring, theme) at the top level; desktop settings (app, platforms, autoUpdate, startup, releases, remoteConfig, restartManager) under `targets.desktop`.
56
- - What the app SHIPS is one declaration: `platforms.<mac|windows|linux>.formats.<dmg|nsis|deb|appimage|snap>`. Presence = enabled, every platform and format is on by default, and `false` drops one (`snap: false`). Per-format settings live inside the format.
57
- - Packaging config: fully generated. @omega.js/desktop produces `dist/electron-builder.yml` from `config/omega.json5` (brand/app/signing) + @omega.js/desktop's opinionated defaults. Consumers never ship an `electron-builder.yml`. Override defaults via the `electronBuilder:` block in `omega.json5` if you genuinely need to.
58
- - `hooks/notarize/post.js`: optional post-notarize extension hook (@omega.js/desktop owns the actual `afterSign` notarize step).
59
- - `src/main.js`: main-process entry. One-line bootstrap of `@omega.js/desktop/main`.
60
- - `src/preload.js`: preload entry. Exposes `window.desktop` via contextBridge.
61
- - `src/integrations/tray/index.js`: tray definition. Edit this; it's yours.
62
- - `src/integrations/menu/index.js`: application menu definition.
63
- - `src/integrations/context-menu/index.js`: right-click menu definition (called per-event with `params`).
64
- - `src/views/<window>/index.html`: per-window HTML.
65
- - `src/assets/js/components/<window>/index.js`: renderer entry per window.
66
- - `src/assets/scss/main.scss`: shared SCSS.
67
- - `config/icons/<platform>/<slot>.png`: optional icon overrides (`mac/icon.png`, `mac/tray.png`, `mac/dmg.png`, `windows/icon.png`, etc.; the platform words are `mac`, `windows`, `linux`).
68
- - Ship ONE file per slot at the native (retina) size; @omega.js/desktop auto-downscales @1x variants.
69
- - macOS tray must be 32×32 (@omega.js/desktop renames to `trayTemplate.png` in dist for the OS dark-mode magic).
70
- - Missing slots fall back to @omega.js/desktop bundled defaults; Linux falls back to Windows resolution.
71
- - `test/**/*.js`: your project test suites (framework auto-runs them alongside its own).
72
-
73
- ## Per-context imports
74
-
75
- Each entry exports ONE ready-made instance, `omega`; a consumer never writes `new`.
76
-
77
- ```js
78
- // src/main.js
79
- const omega = require('@omega.js/desktop/main');
80
- omega.initialize().then(() => { const { logger, windows } = omega; }); // auto-loads JSON5 config
81
-
82
- // src/preload.js
83
- const omega = require('@omega.js/desktop/preload');
84
- omega.initialize();
85
-
86
- // src/assets/js/components/main/index.js
87
- import omega from '@omega.js/desktop/renderer';
88
- omega.initialize().then(() => { const { logger, desktop } = omega; });
89
- ```
90
-
91
- ## Available APIs at runtime
92
-
93
- In main, each a property of `omega`: `windows`, `tray`, `menu`, `contextMenu`, `ipc`, `storage`, `deepLink`, `autoUpdater`, `appState`, `startup`, `protocol`, `authFlow`, `theme`, `fontawesome`, `context`, `usage`, `remoteConfig`, `remoteScripts`, `restartManager`, `analytics`, `sentry`, `logger`.
94
- - `omega.auth` is the signed-in account in main: `.user` (a `User`), `.listen()`, `.signOut()`, `.getIdToken()`, `.handleToken()`.
95
-
96
- In renderer: the @omega.js/client base (`omega.auth`, `omega.firestore`, `omega.bindings`, and `omega.storage`, the page store) plus `omega.desktop`, the preload's bridge to main.
97
- - `omega.desktop.{ipc,storage,theme,fontawesome,autoUpdater,analytics,context,usage,remoteConfig}`; `omega.desktop.storage` is the app store, async over IPC.
98
- - Config: `window.OMEGA_BUILD_JSON.config` (the one `build.js` the view's shell loads).
99
-
100
- ## Dependency resolution
101
-
102
- - **Do NOT install framework dependencies directly** (`firebase`, `fs-jetpack`, `@omega.js/client`, etc.). @omega.js/desktop's bundler resolves them through the framework's own `node_modules/`. If something doesn't resolve, the issue is in @omega.js/desktop's bundle task, not your `package.json`.
103
- - **@omega.js/client owns Firebase.** Never `require('firebase')` or `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).
104
- - **`omega.require(name)`** resolves from @omega.js/desktop's module context at runtime for unbundled code (gulp tasks, test fixtures).
105
-
106
- ## Testing
107
-
108
- Every feature ships with tests at every layer it has a surface in: **logic** (`test/build/`, `test/main/`), **UI** (`test/renderer/`: real events on the real DOM), and **end-to-end** (`test/boot/`).
109
- - Skip a layer only when the feature genuinely has no surface there; "the logic test covers it" does not excuse the UI test.
110
- - Test runs are invisible and never steal keyboard focus (@omega.js/desktop test stealth; set `OMEGA_TEST_SHOW=1` to watch a run live).
111
- - See `test/README.md` and `node_modules/@omega.js/desktop/docs/test-framework.md`.
112
-
113
- <!-- Everything above this marker is owned by the framework and rewritten by every omega verb. Add your project-specific notes below — they are preserved. -->
114
-
115
- # ========== Custom Values ==========
116
-
117
- ## Project-specific notes
118
-
119
- Add anything specific to THIS project here. Edits below this line are preserved across framework re-syncs.
@@ -1 +0,0 @@
1
- @AGENTS.md