@zenbujs/core 0.0.9 → 0.0.12

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 (82) hide show
  1. package/dist/advice-config-BiYhyeTz.d.mts +41 -0
  2. package/dist/advice.d.mts +2 -36
  3. package/dist/advice.mjs +2 -2
  4. package/dist/{base-window-BxBZ2md_.mjs → base-window-4P-fVvC_.mjs} +37 -26
  5. package/dist/{build-config-Dzg2frpk.d.mts → build-config-GF0XzR_Y.d.mts} +42 -18
  6. package/dist/{build-config-pWdmLnrk.mjs → build-config-HMMqpXI1.mjs} +0 -8
  7. package/dist/{build-electron-Dsbb1EMl.mjs → build-electron-Di_FE62r.mjs} +10 -6
  8. package/dist/{build-source-d1J3shV8.mjs → build-source-BIaWpaxE.mjs} +2 -2
  9. package/dist/cli/bin.mjs +7 -7
  10. package/dist/cli/build.d.mts +1 -1
  11. package/dist/cli/build.mjs +1 -1
  12. package/dist/cli/resolve-config.mjs +6 -1
  13. package/dist/{cli-kL6mPgBE.mjs → cli-5jFDJWM4.mjs} +4 -4
  14. package/dist/config.d.mts +3 -3
  15. package/dist/config.mjs +2 -2
  16. package/dist/{db-Bc292RYo.mjs → db-MkOccvBS.mjs} +2 -2
  17. package/dist/db.d.mts +3 -2
  18. package/dist/db.mjs +2 -10
  19. package/dist/{dev-B2emj0HZ.mjs → dev-BSDyzO4j.mjs} +3 -9
  20. package/dist/env-bootstrap.d.mts +1 -1
  21. package/dist/events.d.mts +0 -9
  22. package/dist/{host-version-BIrF8tX7.mjs → host-version-Cog_odmD.mjs} +4 -3
  23. package/dist/{index-CVF768Xs.d.mts → index-C0mXKol5.d.mts} +188 -143
  24. package/dist/{index-DeDxePAa.d.mts → index-FaexRVl_.d.mts} +13 -1
  25. package/dist/index.d.mts +4 -4
  26. package/dist/index.mjs +2 -2
  27. package/dist/launcher.mjs +64 -6
  28. package/dist/link-Bt3LB_NW.mjs +586 -0
  29. package/dist/{load-config-C4Oe2qZO.mjs → load-config-C2XloBaQ.mjs} +68 -5
  30. package/dist/node-loader.mjs +1 -1
  31. package/dist/{publish-source-Dq2c0iOw.mjs → publish-source-v93eB9kA.mjs} +6 -2
  32. package/dist/react.d.mts +6 -6
  33. package/dist/react.mjs +4 -4
  34. package/dist/registry-generated.d.mts +19 -14
  35. package/dist/registry-saQDMUhT.d.mts +13 -0
  36. package/dist/registry.d.mts +1 -1
  37. package/dist/{reloader-B22UiNA2.mjs → reloader-CFzxYa67.mjs} +3 -3
  38. package/dist/{renderer-host-DD16MXhI.mjs → renderer-host-Cw38dSDe.mjs} +35 -24
  39. package/dist/{rpc-C4_NQmpT.mjs → rpc-Dg9zwZ33.mjs} +4 -4
  40. package/dist/rpc.d.mts +1 -1
  41. package/dist/rpc.mjs +1 -1
  42. package/dist/runtime-DYUONc3S.mjs +861 -0
  43. package/dist/{runtime-BQWntcOb.d.mts → runtime-fnPDZFYM.d.mts} +100 -3
  44. package/dist/runtime.d.mts +2 -2
  45. package/dist/runtime.mjs +2 -578
  46. package/dist/{schema-CjrMVk36.d.mts → schema-brYpUjYO.d.mts} +13 -25
  47. package/dist/schema.d.mts +2 -2
  48. package/dist/schema.mjs +9 -2
  49. package/dist/{server-CZLMF8Dj.mjs → server-BJ2ZC2z2.mjs} +2 -2
  50. package/dist/services/default.d.mts +1 -5
  51. package/dist/services/default.mjs +12 -16
  52. package/dist/services/index.d.mts +1 -1
  53. package/dist/services/index.mjs +7 -7
  54. package/dist/setup-gate.d.mts +1 -1
  55. package/dist/setup-gate.mjs +20 -12
  56. package/dist/{transport-F2hv_OEm.mjs → transport-Bqlv9pmJ.mjs} +1 -1
  57. package/dist/updater-Bs1Jtem6.mjs +480 -0
  58. package/dist/{vite-plugins-tt6KAtyE.mjs → vite-plugins-Df-cfldF.mjs} +2 -49
  59. package/dist/vite.d.mts +0 -5
  60. package/dist/vite.mjs +1 -1
  61. package/dist/{window-YFKvAM0l.mjs → window-DgB70qeZ.mjs} +113 -22
  62. package/dist/{write-DgIRjo23.mjs → write-7IfKa_nq.mjs} +1 -1
  63. package/dist/zenbu-bg-parse-CIyPkJOY.mjs +46 -0
  64. package/package.json +19 -18
  65. package/LICENSE +0 -11
  66. package/dist/advice-config-DXSIo0sg.mjs +0 -154
  67. package/dist/link-glX89NV5.mjs +0 -673
  68. package/dist/registry-CMp8FYgS.d.mts +0 -47
  69. package/dist/updater-BtB_Ki1r.mjs +0 -1011
  70. /package/dist/{config-BK78JDRI.mjs → config-DfciRzDu.mjs} +0 -0
  71. /package/dist/{env-bootstrap-rTs8KR3-.d.mts → env-bootstrap-UBug-4Kw.d.mts} +0 -0
  72. /package/dist/{index-C-ALz_SH.d.mts → index-CSMHYi3u.d.mts} +0 -0
  73. /package/dist/{index-ClXLQ1fw.d.mts → index-DJOHDG5e.d.mts} +0 -0
  74. /package/dist/{log-6rzaCV0I.mjs → log-BkRqDwwB.mjs} +0 -0
  75. /package/dist/{mirror-sync-pYU6f3-c.mjs → mirror-sync-snqh9kEp.mjs} +0 -0
  76. /package/dist/{monorepo-Dct-kkbQ.mjs → monorepo-CBzK3l2i.mjs} +0 -0
  77. /package/dist/{node-BhfLKYCi.mjs → node-BuHlEsE4.mjs} +0 -0
  78. /package/dist/{schema-Ca7SxXgS.mjs → schema-C6k0SroY.mjs} +0 -0
  79. /package/dist/{setup-gate-BQq0QgZH.d.mts → setup-gate-DkysEZQO.d.mts} +0 -0
  80. /package/dist/{src-Cven45mq.mjs → src-BpZAt9zL.mjs} +0 -0
  81. /package/dist/{trace-BaVg0rnY.mjs → trace-BVcQSD59.mjs} +0 -0
  82. /package/dist/{transform-BzrwkEdf.mjs → transform-czrcGnVV.mjs} +0 -0
@@ -0,0 +1,41 @@
1
+ //#region src/services/advice-config.d.ts
2
+ interface ViewAdviceEntry {
3
+ moduleId: string;
4
+ name: string;
5
+ type: "replace" | "before" | "after" | "around";
6
+ modulePath: string;
7
+ exportName: string;
8
+ }
9
+ /**
10
+ * Public spec passed to `service.advise({...})`. The plugin root is
11
+ * resolved automatically from the calling service's slot (stamped by
12
+ * `runtime.register` at registration time), so plugin code never has to
13
+ * deal with `import.meta`.
14
+ *
15
+ * `modulePath` is normally relative to the plugin root (the folder
16
+ * containing `zenbu.plugin.json`). Absolute paths are accepted as an
17
+ * escape hatch.
18
+ */
19
+ interface AdviceSpec {
20
+ view: string;
21
+ moduleId: string;
22
+ name: string;
23
+ type: "replace" | "before" | "after" | "around";
24
+ modulePath: string;
25
+ exportName: string;
26
+ }
27
+ /**
28
+ * Public spec passed to `service.contentScript({...})`. Same plugin-root
29
+ * resolution rules as `AdviceSpec`.
30
+ */
31
+ interface ContentScriptSpec {
32
+ view: string;
33
+ modulePath: string;
34
+ }
35
+ declare function getAdvice(type: string): ViewAdviceEntry[];
36
+ declare function getAllAdviceTypes(): string[];
37
+ declare function getContentScripts(type: string): string[];
38
+ declare function getAllContentScriptPaths(): string[];
39
+ declare function getAllTypes(): string[];
40
+ //#endregion
41
+ export { getAllAdviceTypes as a, getContentScripts as c, getAdvice as i, ContentScriptSpec as n, getAllContentScriptPaths as o, ViewAdviceEntry as r, getAllTypes as s, AdviceSpec as t };
package/dist/advice.d.mts CHANGED
@@ -1,36 +1,2 @@
1
- //#region src/services/advice-config.d.ts
2
- interface ViewAdviceEntry {
3
- moduleId: string;
4
- name: string;
5
- type: "replace" | "before" | "after" | "around";
6
- modulePath: string;
7
- exportName: string;
8
- }
9
- /**
10
- * Public-facing advice spec. `modulePath` is normally a path relative to
11
- * the plugin root (the folder containing `zenbu.plugin.json`); pass
12
- * `import.meta` as the second argument so we can resolve it. Absolute
13
- * paths are also accepted as an escape hatch.
14
- */
15
- type AdviceSpec = Omit<ViewAdviceEntry, "modulePath"> & {
16
- modulePath: string;
17
- };
18
- declare function registerAdvice(type: string, entry: AdviceSpec, meta?: ImportMeta): () => void;
19
- declare function getAdvice(type: string): ViewAdviceEntry[];
20
- declare function getAllAdviceTypes(): string[];
21
- /**
22
- * Register a content script for the given view type. `modulePath` is normally
23
- * a path relative to the plugin root (the folder with `zenbu.plugin.json`);
24
- * pass `import.meta` so we can resolve it. Absolute paths are accepted as
25
- * an escape hatch.
26
- *
27
- * this.setup("inject", () =>
28
- * registerContentScript("app", "src/content/clock.tsx", import.meta),
29
- * )
30
- */
31
- declare function registerContentScript(type: string, modulePath: string, meta?: ImportMeta): () => void;
32
- declare function getContentScripts(type: string): string[];
33
- declare function getAllContentScriptPaths(): string[];
34
- declare function getAllTypes(): string[];
35
- //#endregion
36
- export { type AdviceSpec, type ViewAdviceEntry, getAdvice, getAllAdviceTypes, getAllContentScriptPaths, getAllTypes, getContentScripts, registerAdvice, registerContentScript };
1
+ import { a as getAllAdviceTypes, c as getContentScripts, i as getAdvice, n as ContentScriptSpec, o as getAllContentScriptPaths, r as ViewAdviceEntry, s as getAllTypes, t as AdviceSpec } from "./advice-config-BiYhyeTz.mjs";
2
+ export { type AdviceSpec, type ContentScriptSpec, type ViewAdviceEntry, getAdvice, getAllAdviceTypes, getAllContentScriptPaths, getAllTypes, getContentScripts };
package/dist/advice.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { a as getAllTypes, c as registerContentScript, i as getAllContentScriptPaths, n as getAdvice, o as getContentScripts, r as getAllAdviceTypes, s as registerAdvice } from "./advice-config-DXSIo0sg.mjs";
2
- export { getAdvice, getAllAdviceTypes, getAllContentScriptPaths, getAllTypes, getContentScripts, registerAdvice, registerContentScript };
1
+ import { _ as getAllAdviceTypes, b as getContentScripts, g as getAdvice, v as getAllContentScriptPaths, y as getAllTypes } from "./runtime-DYUONc3S.mjs";
2
+ export { getAdvice, getAllAdviceTypes, getAllContentScriptPaths, getAllTypes, getContentScripts };
@@ -1,17 +1,21 @@
1
1
  import { n as __exportAll } from "./chunk-DsiFFCwN.mjs";
2
- import { Service, getAppEntrypoint, runtime } from "./runtime.mjs";
3
- import { t as createLogger } from "./log-6rzaCV0I.mjs";
4
- import { a as DbService } from "./renderer-host-DD16MXhI.mjs";
2
+ import { n as pickZenbuBgEntry, t as parseZenbuBgEntries } from "./zenbu-bg-parse-CIyPkJOY.mjs";
3
+ import { f as runtime, i as getAppEntrypoint, n as Service } from "./runtime-DYUONc3S.mjs";
4
+ import { t as createLogger } from "./log-BkRqDwwB.mjs";
5
+ import { a as DbService } from "./renderer-host-Cw38dSDe.mjs";
5
6
  import fs from "node:fs";
6
7
  import path from "node:path";
7
8
  import { nanoid } from "nanoid";
8
- import { BaseWindow } from "electron";
9
+ import { BaseWindow, nativeTheme } from "electron";
9
10
  //#region src/shared/zenbu-bg.ts
10
- const META_RE = /<meta\s+name=["']zenbu-bg["']\s+content=["']([^"']+)["']/i;
11
11
  /**
12
- * Read the `<meta name="zenbu-bg" content="#xxx">` value from an HTML
13
- * file. Returns the configured value, or `fallback` when the file is
14
- * missing, unreadable, or has no `zenbu-bg` meta tag.
12
+ * Read the `<meta name="zenbu-bg">` color from an HTML file, picking
13
+ * the variant that matches the current system theme
14
+ * (`nativeTheme.shouldUseDarkColors`).
15
+ *
16
+ * Multiple tags with `media="(prefers-color-scheme: light|dark)"` are
17
+ * supported (mirrors the W3C `<meta name="theme-color">` pattern). A
18
+ * tag without `media` is the unconditional fallback.
15
19
  *
16
20
  * This convention exists because Electron paints a `BaseWindow`'s
17
21
  * `backgroundColor` for the brief window between the window appearing
@@ -19,14 +23,13 @@ const META_RE = /<meta\s+name=["']zenbu-bg["']\s+content=["']([^"']+)["']/i;
19
23
  * compositor — and similarly the view itself flashes its
20
24
  * `setBackgroundColor` before any HTML renders. Reading the meta from
21
25
  * the same HTML the renderer will paint keeps both colors in sync with
22
- * whatever theme the renderer is committing to (`#111` for a dark app,
23
- * `#F4F4F4` for a light one), so the user never sees a single white
24
- * frame on window open.
26
+ * whatever theme the renderer is committing to, so the user never sees
27
+ * a single mismatched frame on window open.
25
28
  */
26
29
  function readZenbuBgColor(htmlPath, fallback = "#F4F4F4") {
27
30
  try {
28
- const match = fs.readFileSync(htmlPath, "utf8").match(META_RE);
29
- if (match?.[1]) return match[1];
31
+ const picked = pickZenbuBgEntry(parseZenbuBgEntries(fs.readFileSync(htmlPath, "utf8")), nativeTheme.shouldUseDarkColors);
32
+ if (picked) return picked;
30
33
  } catch {}
31
34
  return fallback;
32
35
  }
@@ -76,21 +79,17 @@ var BaseWindowService = class extends Service.create({
76
79
  }
77
80
  createWindow(opts) {
78
81
  const windowId = opts?.windowId ?? nanoid();
79
- const zenWidth = this.getZenWidth();
80
82
  const win = new BaseWindow({
81
- width: opts?.width ?? zenWidth ?? 1100,
82
- height: opts?.height ?? 750,
83
- ...opts?.x != null && opts?.y != null ? {
84
- x: opts.x,
85
- y: opts.y
86
- } : {},
87
- show: opts?.show ?? true,
83
+ width: this.getZenWidth() ?? 1100,
84
+ height: 750,
85
+ show: true,
88
86
  titleBarStyle: "hidden",
89
87
  trafficLightPosition: {
90
88
  x: 14,
91
89
  y: 10
92
90
  },
93
- backgroundColor: entrypointBgColor()
91
+ backgroundColor: entrypointBgColor(),
92
+ ...opts?.baseWindow
94
93
  });
95
94
  this.windows.set(windowId, win);
96
95
  win.on("closed", () => this.windows.delete(windowId));
@@ -107,12 +106,24 @@ var BaseWindowService = class extends Service.create({
107
106
  }
108
107
  this.bootWindows = [];
109
108
  } else {
110
- const prefs = this.ctx.db.client.readRoot().plugin.core.windowPrefs;
109
+ const prefs = this.ctx.db.client.readRoot().core.windowPrefs;
111
110
  this.createWindow({
112
111
  windowId: MAIN_WINDOW_ID,
113
- ...prefs[MAIN_WINDOW_ID]?.lastKnownBounds
112
+ baseWindow: { ...prefs[MAIN_WINDOW_ID]?.lastKnownBounds }
114
113
  });
115
114
  }
115
+ this.setup("native-theme-sync", () => {
116
+ const onUpdated = () => {
117
+ const color = entrypointBgColor();
118
+ for (const win of this.windows.values()) try {
119
+ win.setBackgroundColor(color);
120
+ } catch {}
121
+ };
122
+ nativeTheme.on("updated", onUpdated);
123
+ return () => {
124
+ nativeTheme.removeListener("updated", onUpdated);
125
+ };
126
+ });
116
127
  this.setup("window-cleanup", () => {
117
128
  return () => {
118
129
  const snapshot = [...this.windows.entries()].map(([windowId, win]) => ({
@@ -120,12 +131,12 @@ var BaseWindowService = class extends Service.create({
120
131
  bounds: win.getBounds()
121
132
  }));
122
133
  this.ctx.db.client.update((root) => {
123
- const next = { ...root.plugin.core.windowPrefs };
134
+ const next = { ...root.core.windowPrefs };
124
135
  for (const { windowId, bounds } of snapshot) next[windowId] = {
125
136
  ...next[windowId],
126
137
  lastKnownBounds: bounds
127
138
  };
128
- root.plugin.core.windowPrefs = next;
139
+ root.core.windowPrefs = next;
129
140
  });
130
141
  for (const win of this.windows.values()) {
131
142
  win.__zenbu_on_close = null;
@@ -76,23 +76,6 @@ type PackageManagerSpec = {
76
76
  version: string;
77
77
  };
78
78
  interface BuildConfig {
79
- /**
80
- * The .app's "host version" — the developer's product version for the
81
- * Electron+core+toolchain bundle as a whole. Required, semver-shaped
82
- * (e.g. `"0.0.6"`).
83
- *
84
- * This is NOT derived from `package.json#version` (which lives in the
85
- * source tree and gets overwritten by `git pull`) or from
86
- * `@zenbujs/core`'s installed version (a transitive dep, not the
87
- * developer's product). Bump it whenever you ship a new .app build.
88
- *
89
- * `zen build:electron` writes this verbatim into `<bundle>/host.json`.
90
- * The launcher and `UpdaterService` read that file to drive
91
- * compatibility checks against each commit's `package.json#zenbu.host`
92
- * range — the predicate is
93
- * `semver.satisfies(hostVersion, commitPackageJson.zenbu.host)`.
94
- */
95
- hostVersion: string;
96
79
  source?: string;
97
80
  out?: string;
98
81
  include: string[];
@@ -130,6 +113,35 @@ interface Plugin {
130
113
  * `view-registry` to decorate registered views. Optional.
131
114
  */
132
115
  icons?: Record<string, string>;
116
+ /**
117
+ * Other plugins whose **own type surface** this plugin needs at compile time.
118
+ *
119
+ * Each entry names an upstream plugin (`name`) and a relative path
120
+ * (`from`) to the file that defines it — either a `zenbu.plugin.ts`
121
+ * (whose default export is a `definePlugin(...)`) or a `zenbu.config.ts`
122
+ * (in which case `name` disambiguates which entry of `plugins:` to use).
123
+ *
124
+ * `zen link` materializes each declared dep as a vendored, committed copy
125
+ * inside `<plugin>/types/deps/<name>/`. The plugin's composite augmentation
126
+ * (`<plugin>/types/zenbu-register.ts`) then wires the vendored own surface
127
+ * into `ZenbuRegister`, so `useDb` / `useRpc` / `useEvents` selectors work
128
+ * even when the plugin is opened in isolation (no host context required).
129
+ *
130
+ * Composites never depend on other composites — only on **own** surfaces —
131
+ * so the dependency graph is a strict DAG and mutual deps are legal.
132
+ */
133
+ dependsOn?: PluginDependency[];
134
+ }
135
+ /**
136
+ * A type-time dependency on another plugin. `from` is the path to the
137
+ * upstream's manifest file; `name` selects which plugin if `from` is a
138
+ * `zenbu.config.ts` with multiple entries. Both fields are required so
139
+ * the resolver never has to guess between same-named plugins in different
140
+ * trees.
141
+ */
142
+ interface PluginDependency {
143
+ name: string;
144
+ from: string;
133
145
  }
134
146
  declare function definePlugin(plugin: Plugin): Plugin;
135
147
  /**
@@ -157,6 +169,18 @@ interface ResolvedPlugin {
157
169
  eventsPath?: string;
158
170
  /** Plugin-author-defined SVG icons. */
159
171
  icons?: Record<string, string>;
172
+ /**
173
+ * Type-time dependencies, with `from` already absolute. The upstream
174
+ * plugin itself is NOT loaded here — `zen link` does that lazily so the
175
+ * runtime path (`getConfig()`, plugin barrel emission) doesn't pay the
176
+ * cost of recursively walking other configs/manifests.
177
+ */
178
+ dependsOn?: ResolvedPluginDependency[];
179
+ }
180
+ interface ResolvedPluginDependency {
181
+ name: string;
182
+ /** Absolute path to the upstream `zenbu.plugin.ts` or `zenbu.config.ts`. */
183
+ fromPath: string;
160
184
  }
161
185
  /**
162
186
  * The whole-app `zenbu.config.ts` shape. Authored by user code; imported
@@ -212,4 +236,4 @@ interface ResolvedConfig {
212
236
  build: ResolvedBuildConfig;
213
237
  }
214
238
  //#endregion
215
- export { Config as a, PackageManagerSpec as c, ResolvedConfig as d, ResolvedPlugin as f, resolveBuildConfig as g, definePlugin as h, BundleConfig as i, Plugin as l, defineConfig as m, BuildContext as n, EmitContext as o, defineBuildConfig as p, BuildPlugin as r, MirrorConfig as s, BuildConfig as t, ResolvedBuildConfig as u };
239
+ export { definePlugin as _, Config as a, PackageManagerSpec as c, ResolvedBuildConfig as d, ResolvedConfig as f, defineConfig as g, defineBuildConfig as h, BundleConfig as i, Plugin as l, ResolvedPluginDependency as m, BuildContext as n, EmitContext as o, ResolvedPlugin as p, BuildPlugin as r, MirrorConfig as s, BuildConfig as t, PluginDependency as u, resolveBuildConfig as v };
@@ -11,13 +11,6 @@ const DEFAULT_PACKAGE_MANAGER = {
11
11
  function defineBuildConfig(config) {
12
12
  return config;
13
13
  }
14
- const SEMVER_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
15
- function validateHostVersion(value) {
16
- if (typeof value !== "string" || value.trim().length === 0) throw new Error("zenbu build.hostVersion: required `string` (e.g. \"0.0.6\"). Set it on `defineBuildConfig({ hostVersion: \"...\" })`.");
17
- const trimmed = value.trim();
18
- if (!SEMVER_RE.test(trimmed)) throw new Error(`zenbu build.hostVersion: "${value}" is not a valid semver string (expected MAJOR.MINOR.PATCH with optional prerelease / build metadata).`);
19
- return trimmed;
20
- }
21
14
  function validatePackageManager(spec) {
22
15
  const allowed = [
23
16
  "pnpm",
@@ -32,7 +25,6 @@ function validatePackageManager(spec) {
32
25
  function resolveBuildConfig(config) {
33
26
  const packageManager = validatePackageManager(config.packageManager ?? DEFAULT_PACKAGE_MANAGER);
34
27
  return {
35
- hostVersion: validateHostVersion(config.hostVersion),
36
28
  source: config.source ?? ".",
37
29
  out: config.out ?? ".zenbu/build/source",
38
30
  include: config.include,
@@ -1,10 +1,11 @@
1
- import { r as writeHostVersion, t as HOST_VERSION_FILENAME } from "./host-version-BIrF8tX7.mjs";
2
- import { t as loadConfig } from "./load-config-C4Oe2qZO.mjs";
1
+ import { r as writeHostVersion, t as HOST_VERSION_FILENAME } from "./host-version-Cog_odmD.mjs";
2
+ import { n as loadConfig } from "./load-config-C2XloBaQ.mjs";
3
3
  import { createRequire } from "node:module";
4
4
  import fs from "node:fs";
5
5
  import os from "node:os";
6
6
  import path from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
+ import semver from "semver";
8
9
  import { execFile, execFileSync, spawn } from "node:child_process";
9
10
  import crypto from "node:crypto";
10
11
  import fsp from "node:fs/promises";
@@ -556,9 +557,13 @@ async function runBuildElectron(argv) {
556
557
  if (!mirrorTarget) throw new Error("zen build:electron: `build.mirror.target` is required in zenbu.config.ts. Set build: defineBuildConfig({ mirror: { target: \"<owner>/<repo>\", branch: \"main\" }, ... }) and run `zen publish:source init` before building.");
557
558
  const mirrorBranch = config.mirror?.branch ?? "main";
558
559
  const mirrorUrl = expandMirrorUrl(mirrorTarget);
559
- const projectPkg = readJson(path.join(projectDir, "package.json"));
560
+ const projectPkgPath = path.join(projectDir, "package.json");
561
+ const projectPkg = readJson(projectPkgPath);
560
562
  const appName = projectPkg.name ?? path.basename(projectDir);
561
- const appVersion = projectPkg.version ?? "0.0.1";
563
+ const rawAppVersion = projectPkg.version;
564
+ if (typeof rawAppVersion !== "string" || rawAppVersion.trim().length === 0) throw new Error(`zen build:electron: ${projectPkgPath} is missing a non-empty \`version\` field. This value is baked into <bundle>/host.json as the .app's host version — bump it whenever you ship a new .app build.`);
565
+ const appVersion = rawAppVersion.trim();
566
+ if (!semver.valid(appVersion)) throw new Error(`zen build:electron: ${projectPkgPath} \`version\` ("${rawAppVersion}") is not a valid semver string (expected MAJOR.MINOR.PATCH with optional prerelease / build metadata).`);
562
567
  const bundleDir = await fsp.mkdtemp(path.join(os.tmpdir(), `zenbu-electron-${appName}-`));
563
568
  const toolchainDir = path.join(bundleDir, "toolchain");
564
569
  const launcherOut = path.join(bundleDir, "launcher.mjs");
@@ -573,7 +578,6 @@ async function runBuildElectron(argv) {
573
578
  console.log(`\n zen build:electron`);
574
579
  console.log(` name: ${appName}`);
575
580
  console.log(` version: ${appVersion}`);
576
- console.log(` host: ${config.hostVersion}`);
577
581
  console.log(` source: ${sourceSha === "uncommitted" ? "uncommitted" : sourceSha.slice(0, 7)}`);
578
582
  console.log(` mirror: ${mirrorTarget} (${mirrorBranch})`);
579
583
  console.log(` pm: ${pmLabel}`);
@@ -616,7 +620,7 @@ async function runBuildElectron(argv) {
616
620
  } : {}
617
621
  };
618
622
  await fsp.writeFile(appConfigOut, JSON.stringify(appConfig, null, 2) + "\n");
619
- writeHostVersion(bundleDir, config.hostVersion);
623
+ writeHostVersion(bundleDir, appVersion);
620
624
  const userConfig = readElectronBuilderConfig(projectDir);
621
625
  const userOutput = userConfig.directories?.output ?? "dist";
622
626
  const resolvedOutput = path.isAbsolute(userOutput) ? userOutput : path.resolve(projectDir, userOutput);
@@ -1,5 +1,5 @@
1
- import { t as loadConfig } from "./load-config-C4Oe2qZO.mjs";
2
- import { t as hashDir } from "./mirror-sync-pYU6f3-c.mjs";
1
+ import { n as loadConfig } from "./load-config-C2XloBaQ.mjs";
2
+ import { t as hashDir } from "./mirror-sync-snqh9kEp.mjs";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import { execFileSync } from "node:child_process";
package/dist/cli/bin.mjs CHANGED
@@ -41,37 +41,37 @@ async function main() {
41
41
  const rest = argv.slice(1);
42
42
  switch (first) {
43
43
  case "dev": {
44
- const { runDev } = await import("../dev-B2emj0HZ.mjs");
44
+ const { runDev } = await import("../dev-BSDyzO4j.mjs");
45
45
  await runDev(rest);
46
46
  return;
47
47
  }
48
48
  case "build:source": {
49
- const { runBuildSource } = await import("../build-source-d1J3shV8.mjs");
49
+ const { runBuildSource } = await import("../build-source-BIaWpaxE.mjs");
50
50
  await runBuildSource(rest);
51
51
  return;
52
52
  }
53
53
  case "build:electron": {
54
- const { runBuildElectron } = await import("../build-electron-Dsbb1EMl.mjs");
54
+ const { runBuildElectron } = await import("../build-electron-Di_FE62r.mjs");
55
55
  await runBuildElectron(rest);
56
56
  return;
57
57
  }
58
58
  case "publish:source": {
59
- const { runPublishSource } = await import("../publish-source-Dq2c0iOw.mjs");
59
+ const { runPublishSource } = await import("../publish-source-v93eB9kA.mjs");
60
60
  await runPublishSource(rest);
61
61
  return;
62
62
  }
63
63
  case "link": {
64
- const { runLink } = await import("../link-glX89NV5.mjs").then((n) => n.n);
64
+ const { runLink } = await import("../link-Bt3LB_NW.mjs").then((n) => n.n);
65
65
  await runLink(rest);
66
66
  return;
67
67
  }
68
68
  case "monorepo": {
69
- const { runMonorepo } = await import("../monorepo-Dct-kkbQ.mjs");
69
+ const { runMonorepo } = await import("../monorepo-CBzK3l2i.mjs");
70
70
  await runMonorepo(rest);
71
71
  return;
72
72
  }
73
73
  case "db": {
74
- const { runDb } = await import("../db-Bc292RYo.mjs");
74
+ const { runDb } = await import("../db-MkOccvBS.mjs");
75
75
  await runDb(rest);
76
76
  return;
77
77
  }
@@ -1,2 +1,2 @@
1
- import { g as resolveBuildConfig, i as BundleConfig, n as BuildContext, o as EmitContext, p as defineBuildConfig, r as BuildPlugin, s as MirrorConfig, t as BuildConfig, u as ResolvedBuildConfig } from "../build-config-Dzg2frpk.mjs";
1
+ import { d as ResolvedBuildConfig, h as defineBuildConfig, i as BundleConfig, n as BuildContext, o as EmitContext, r as BuildPlugin, s as MirrorConfig, t as BuildConfig, v as resolveBuildConfig } from "../build-config-GF0XzR_Y.mjs";
2
2
  export { type BuildConfig, type BuildContext, type BuildPlugin, type BundleConfig, type EmitContext, type MirrorConfig, type ResolvedBuildConfig, defineBuildConfig, resolveBuildConfig };
@@ -1,2 +1,2 @@
1
- import { i as resolveBuildConfig, t as defineBuildConfig } from "../build-config-pWdmLnrk.mjs";
1
+ import { i as resolveBuildConfig, t as defineBuildConfig } from "../build-config-HMMqpXI1.mjs";
2
2
  export { defineBuildConfig, resolveBuildConfig };
@@ -1,7 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { t as loadConfig } from "../load-config-C4Oe2qZO.mjs";
2
+ import { n as loadConfig } from "../load-config-C2XloBaQ.mjs";
3
3
  import { register } from "tsx/esm/api";
4
4
  //#region src/cli/resolve-config.ts
5
+ /**
6
+ * gets ran syncronously in zenbu loader to run ts config to get back obj that can be transformed into js imports
7
+ *
8
+ * takes ~100ms to run
9
+ */
5
10
  async function main() {
6
11
  register();
7
12
  const projectDir = process.argv[2];
@@ -1,6 +1,6 @@
1
- import { o as getZodDefault, t as NO_DEFAULT } from "./schema-Ca7SxXgS.mjs";
2
- import { _ as handleErrnoException, d as readJsonFile, f as readJsonlFile, g as layer$7, l as paths, n as makeRootCache, t as handleWrite, v as FileSystem, y as BadArgument } from "./write-DgIRjo23.mjs";
3
- import { loadSchema } from "./config-BK78JDRI.mjs";
1
+ import { o as getZodDefault, t as NO_DEFAULT } from "./schema-C6k0SroY.mjs";
2
+ import { _ as handleErrnoException, d as readJsonFile, f as readJsonlFile, g as layer$7, l as paths, n as makeRootCache, t as handleWrite, v as FileSystem, y as BadArgument } from "./write-7IfKa_nq.mjs";
3
+ import { loadSchema } from "./config-DfciRzDu.mjs";
4
4
  import fs from "node:fs";
5
5
  import * as NodePath from "node:path";
6
6
  import path from "node:path";
@@ -8030,7 +8030,7 @@ async function run(argv) {
8030
8030
  process.exit(args.help ? 0 : 1);
8031
8031
  }
8032
8032
  if (args.command === "generate") {
8033
- const { findConfigFile, loadConfig } = await import("./config-BK78JDRI.mjs");
8033
+ const { findConfigFile, loadConfig } = await import("./config-DfciRzDu.mjs");
8034
8034
  const resolved = await loadConfig(args.config ?? findConfigFile(process.cwd()));
8035
8035
  await generateMigration({
8036
8036
  schemaPath: resolved.schemaPath,
package/dist/config.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { a as Config, c as PackageManagerSpec, d as ResolvedConfig, f as ResolvedPlugin, h as definePlugin, i as BundleConfig, l as Plugin, m as defineConfig, n as BuildContext, o as EmitContext, p as defineBuildConfig, r as BuildPlugin, s as MirrorConfig, t as BuildConfig, u as ResolvedBuildConfig } from "./build-config-Dzg2frpk.mjs";
2
- import { c as getConfig, d as getSplashPath, g as subscribeConfig, l as getPlugin, n as ConfigSnapshot, r as PluginRecord, s as getAppEntrypoint, u as getPlugins } from "./runtime-BQWntcOb.mjs";
3
- export { type BuildConfig, type BuildContext, type BuildPlugin, type BundleConfig, type Config, type ConfigSnapshot, type EmitContext, type MirrorConfig, type PackageManagerSpec, type Plugin, type PluginRecord, type ResolvedBuildConfig, type ResolvedConfig, type ResolvedPlugin, defineBuildConfig, defineConfig, definePlugin, getAppEntrypoint, getConfig, getPlugin, getPlugins, getSplashPath, subscribeConfig };
1
+ import { _ as definePlugin, a as Config, c as PackageManagerSpec, d as ResolvedBuildConfig, f as ResolvedConfig, g as defineConfig, h as defineBuildConfig, i as BundleConfig, l as Plugin, m as ResolvedPluginDependency, n as BuildContext, o as EmitContext, p as ResolvedPlugin, r as BuildPlugin, s as MirrorConfig, t as BuildConfig, u as PluginDependency } from "./build-config-GF0XzR_Y.mjs";
2
+ import { _ as subscribeConfig, c as getAppEntrypoint, d as getPlugins, f as getSplashPath, i as PluginRecord, l as getConfig, r as ConfigSnapshot, u as getPlugin } from "./runtime-fnPDZFYM.mjs";
3
+ export { type BuildConfig, type BuildContext, type BuildPlugin, type BundleConfig, type Config, type ConfigSnapshot, type EmitContext, type MirrorConfig, type PackageManagerSpec, type Plugin, type PluginDependency, type PluginRecord, type ResolvedBuildConfig, type ResolvedConfig, type ResolvedPlugin, type ResolvedPluginDependency, defineBuildConfig, defineConfig, definePlugin, getAppEntrypoint, getConfig, getPlugin, getPlugins, getSplashPath, subscribeConfig };
package/dist/config.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { getAppEntrypoint, getConfig, getPlugin, getPlugins, getSplashPath, subscribeConfig } from "./runtime.mjs";
2
- import { n as defineConfig, r as definePlugin, t as defineBuildConfig } from "./build-config-pWdmLnrk.mjs";
1
+ import { a as getConfig, c as getSplashPath, i as getAppEntrypoint, o as getPlugin, p as subscribeConfig, s as getPlugins } from "./runtime-DYUONc3S.mjs";
2
+ import { n as defineConfig, r as definePlugin, t as defineBuildConfig } from "./build-config-HMMqpXI1.mjs";
3
3
  export { defineBuildConfig, defineConfig, definePlugin, getAppEntrypoint, getConfig, getPlugin, getPlugins, getSplashPath, subscribeConfig };
@@ -469,7 +469,7 @@ function parseGenerateArgs(argv) {
469
469
  }
470
470
  async function runGenerate(argv) {
471
471
  const flags = parseGenerateArgs(argv);
472
- const { generateMigration } = await import("./cli-kL6mPgBE.mjs");
472
+ const { generateMigration } = await import("./cli-5jFDJWM4.mjs");
473
473
  if (flags.schema || flags.migrationsOut) {
474
474
  if (!flags.schema || !flags.migrationsOut) {
475
475
  console.error("zen db generate: --schema and --migrations must be passed together.");
@@ -495,7 +495,7 @@ async function runGenerate(argv) {
495
495
  console.error(" --schema <path> --migrations <path> directly.");
496
496
  process.exit(1);
497
497
  }
498
- const { loadConfig } = await import("./load-config-C4Oe2qZO.mjs").then((n) => n.n);
498
+ const { loadConfig } = await import("./load-config-C2XloBaQ.mjs").then((n) => n.a);
499
499
  const { resolved } = await loadConfig(projectDir);
500
500
  const cwd = path.resolve(process.cwd());
501
501
  let bestMatch = null;
package/dist/db.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { S as createSchema, _ as InferSchema$1, a as dbStringify, b as blob, f as CollectionRefBrand$1, g as InferRoot$1, i as dbParse, n as connectReplica, o as ClientProxy, p as CollectionRefValue$1, s as CollectionNode$1, v as Schema$1, x as collection, y as SchemaShape$1 } from "./index-DeDxePAa.mjs";
1
+ import { C as createSchema, S as collection, _ as InferSchema$1, a as dbStringify, b as SchemaShape$1, f as CollectionRefBrand$1, g as InferRoot$1, i as dbParse, n as connectReplica, o as ClientProxy, p as CollectionRefValue$1, s as CollectionNode$1, v as InferSchemaRoot$1, x as blob, y as Schema$1 } from "./index-FaexRVl_.mjs";
2
2
  import { z as z$1 } from "zod";
3
3
 
4
4
  //#region src/db.d.ts
@@ -7,10 +7,11 @@ type Schema<TShape extends SchemaShape$1 = SchemaShape$1> = Schema$1<TShape>;
7
7
  type SchemaShape = SchemaShape$1;
8
8
  type InferSchema<S extends Schema$1> = InferSchema$1<S>;
9
9
  type InferRoot<T extends SchemaShape$1> = InferRoot$1<T>;
10
+ type InferSchemaRoot<S> = InferSchemaRoot$1<S>;
10
11
  type CollectionRefBrand<T = unknown> = CollectionRefBrand$1<T>;
11
12
  type CollectionRefValue<T = unknown> = CollectionRefValue$1<T>;
12
13
  type CollectionNode<T = unknown> = CollectionNode$1<T>;
13
14
  type DbClient<T extends SchemaShape$1 = SchemaShape$1> = ClientProxy<T>;
14
15
  declare const connectDb: typeof connectReplica;
15
16
  //#endregion
16
- export { CollectionNode, CollectionRefBrand, CollectionRefValue, DbClient, InferRoot, InferSchema, Schema, SchemaShape, blob, collection, connectDb, createSchema, dbParse, dbStringify, z };
17
+ export { CollectionNode, CollectionRefBrand, CollectionRefValue, DbClient, InferRoot, InferSchema, InferSchemaRoot, Schema, SchemaShape, blob, collection, connectDb, createSchema, dbParse, dbStringify, z };
package/dist/db.mjs CHANGED
@@ -1,15 +1,7 @@
1
- import { i as createSchema, n as blob, r as collection } from "./schema-Ca7SxXgS.mjs";
2
- import { i as dbStringify, r as dbParse, t as connectReplica } from "./transport-F2hv_OEm.mjs";
1
+ import { i as createSchema, n as blob, r as collection } from "./schema-C6k0SroY.mjs";
2
+ import { i as dbStringify, r as dbParse, t as connectReplica } from "./transport-Bqlv9pmJ.mjs";
3
3
  import { z as z$1 } from "zod";
4
4
  //#region src/db.ts
5
- /**
6
- * Public DB surface for plugin authors. The underlying engine (kyju) is an
7
- * internal detail; only the names re-exported here are part of `@zenbujs/core`'s
8
- * stable contract. The user authors schemas with raw zod plus two named
9
- * extensions (`collection`, `blob`); they never import `zod` themselves —
10
- * `z` is re-exported here so there's exactly one zod instance in play and
11
- * type identities never drift across versions.
12
- */
13
5
  const z = z$1;
14
6
  const connectDb = connectReplica;
15
7
  //#endregion
@@ -1,4 +1,4 @@
1
- import { t as linkProject } from "./link-glX89NV5.mjs";
1
+ import { t as linkProject } from "./link-Bt3LB_NW.mjs";
2
2
  import { existsSync, statSync } from "node:fs";
3
3
  import path, { resolve } from "node:path";
4
4
  import { spawn } from "node:child_process";
@@ -42,10 +42,7 @@ async function startLinkWatcher(projectDir, opts = {}) {
42
42
  let lastWatchKey = null;
43
43
  let initial = null;
44
44
  try {
45
- initial = await linkProject(projectDir, {
46
- registryOverride: opts.registryOverride ?? null,
47
- quiet: true
48
- });
45
+ initial = await linkProject(projectDir, { quiet: true });
49
46
  if (opts.verbose) console.error(`[zen dev] initial link ok`);
50
47
  } catch (err) {
51
48
  console.error(`[zen dev] initial link failed (will retry on file change): ${err instanceof Error ? err.message : err}`);
@@ -111,10 +108,7 @@ async function startLinkWatcher(projectDir, opts = {}) {
111
108
  if (closed) return;
112
109
  relinkInFlight = true;
113
110
  try {
114
- const result = await linkProject(projectDir, {
115
- registryOverride: opts.registryOverride ?? null,
116
- quiet: true
117
- });
111
+ const result = await linkProject(projectDir, { quiet: true });
118
112
  if (opts.verbose) console.error(`[zen dev] relinked`);
119
113
  await reconcileSubscriptions(result);
120
114
  } catch {} finally {
@@ -1,2 +1,2 @@
1
- import { t as bootstrapEnv } from "./env-bootstrap-rTs8KR3-.mjs";
1
+ import { t as bootstrapEnv } from "./env-bootstrap-UBug-4Kw.mjs";
2
2
  export { bootstrapEnv };
package/dist/events.d.mts CHANGED
@@ -1,13 +1,4 @@
1
1
  //#region src/events.d.ts
2
- /**
3
- * Core's own events file. Mirrors the contract every plugin follows
4
- * (`events: "./path/to/events.ts"` in zenbu.config / zenbu.plugin),
5
- * exporting a single `Events` type that the link generator scans into
6
- * the registry's `CoreEvents`.
7
- *
8
- * Each top-level key is a namespace; `rpc.emit.<namespace>.<event>(payload)`
9
- * inside a service emits with the matching payload type.
10
- */
11
2
  type Events = {
12
3
  advice: {
13
4
  reload: {
@@ -3,9 +3,10 @@ import path from "node:path";
3
3
  //#region src/shared/host-version.ts
4
4
  /**
5
5
  * Single source of truth for reading the .app's "host version" — the
6
- * concrete semver string the developer authored on
7
- * `defineBuildConfig({ hostVersion: "..." })` and that
8
- * `zen build:electron` baked into `<bundle>/host.json`.
6
+ * concrete semver string `zen build:electron` baked into
7
+ * `<bundle>/host.json` from the developer's `package.json#version` at
8
+ * build time. Frozen into the .app so subsequent `git pull`s of the
9
+ * source can't change it.
9
10
  *
10
11
  * Imported by both:
11
12
  * - `packages/core/src/launcher.ts` (tsdown inlines this into