@zenbujs/core 0.0.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 (94) hide show
  1. package/LICENSE +11 -0
  2. package/dist/advice-config-CjgkEf2E.mjs +135 -0
  3. package/dist/advice-config-Cy133IQP.mjs +2 -0
  4. package/dist/advice-runtime.d.mts +35 -0
  5. package/dist/advice-runtime.mjs +131 -0
  6. package/dist/advice.d.mts +36 -0
  7. package/dist/advice.mjs +2 -0
  8. package/dist/base-window-BUt8pwbw.mjs +94 -0
  9. package/dist/base-window-DEIAk618.mjs +2 -0
  10. package/dist/build-config-pbv0w4oN.mjs +17 -0
  11. package/dist/build-electron-B4Gd0Gi4.mjs +516 -0
  12. package/dist/build-source-_q1n1zTV.mjs +162 -0
  13. package/dist/chunk-Dm34NbLt.mjs +6 -0
  14. package/dist/cli/bin.d.mts +1 -0
  15. package/dist/cli/bin.mjs +88 -0
  16. package/dist/cli/build.d.mts +53 -0
  17. package/dist/cli/build.mjs +48 -0
  18. package/dist/cli-BLbQQIVB.mjs +8054 -0
  19. package/dist/config-CdVrW85P.mjs +59 -0
  20. package/dist/config-LK73dJmO.mjs +2 -0
  21. package/dist/db-ByKPbnP6.mjs +2 -0
  22. package/dist/db-DhuAJrye.mjs +531 -0
  23. package/dist/db.d.mts +16 -0
  24. package/dist/db.mjs +16 -0
  25. package/dist/dev-BuqklM0k.mjs +85 -0
  26. package/dist/env-bootstrap-BtVME-CU.d.mts +16 -0
  27. package/dist/env-bootstrap-rj7I-59x.mjs +53 -0
  28. package/dist/env-bootstrap.d.mts +2 -0
  29. package/dist/env-bootstrap.mjs +2 -0
  30. package/dist/http-IBcLzbYu.mjs +2 -0
  31. package/dist/index-Bhlbyrn7.d.mts +63 -0
  32. package/dist/index-CPZ5d6Hl.d.mts +442 -0
  33. package/dist/index-FtE8MXJ_.d.mts +1 -0
  34. package/dist/index.d.mts +6 -0
  35. package/dist/index.mjs +5 -0
  36. package/dist/launcher.mjs +173 -0
  37. package/dist/link-6roQ7Cn6.mjs +580 -0
  38. package/dist/loaders/zenbu.d.mts +22 -0
  39. package/dist/loaders/zenbu.mjs +267 -0
  40. package/dist/log-CyKv8hQg.mjs +20 -0
  41. package/dist/mirror-sync-CodOnwkD.mjs +332 -0
  42. package/dist/monorepo-CmGPHsVm.mjs +119 -0
  43. package/dist/node-D4M19_mV.mjs +5 -0
  44. package/dist/node-loader.d.mts +17 -0
  45. package/dist/node-loader.mjs +33 -0
  46. package/dist/pause-DvAUNmKn.mjs +52 -0
  47. package/dist/publish-source-BVgB62Zj.mjs +131 -0
  48. package/dist/react.d.mts +76 -0
  49. package/dist/react.mjs +291 -0
  50. package/dist/registry-Dh_e7HU1.d.mts +61 -0
  51. package/dist/registry.d.mts +2 -0
  52. package/dist/registry.mjs +1 -0
  53. package/dist/reloader-BCkLjDhS.mjs +2 -0
  54. package/dist/reloader-lLAJ3lqg.mjs +164 -0
  55. package/dist/renderer-host-Bg8QdeeH.mjs +1508 -0
  56. package/dist/renderer-host-DpvBPTHJ.mjs +2 -0
  57. package/dist/rpc-BwwQK6hD.mjs +71 -0
  58. package/dist/rpc-CqitnyR4.mjs +2 -0
  59. package/dist/rpc.d.mts +2 -0
  60. package/dist/rpc.mjs +2 -0
  61. package/dist/runtime-CjqDr8Yf.d.mts +109 -0
  62. package/dist/runtime-DUFKDIe4.mjs +409 -0
  63. package/dist/runtime.d.mts +2 -0
  64. package/dist/runtime.mjs +2 -0
  65. package/dist/schema-CIg4GzHQ.mjs +100 -0
  66. package/dist/schema-DMoSkwUx.d.mts +62 -0
  67. package/dist/schema-dGK6qkfR.mjs +28 -0
  68. package/dist/schema.d.mts +2 -0
  69. package/dist/schema.mjs +2 -0
  70. package/dist/server-BXwZEQ-n.mjs +66 -0
  71. package/dist/server-DjrZUbbu.mjs +2 -0
  72. package/dist/services/default.d.mts +11 -0
  73. package/dist/services/default.mjs +22 -0
  74. package/dist/services/index.d.mts +276 -0
  75. package/dist/services/index.mjs +7 -0
  76. package/dist/setup-gate-BeD6WS6d.mjs +110 -0
  77. package/dist/setup-gate-BqOzm7zp.d.mts +4 -0
  78. package/dist/setup-gate.d.mts +2 -0
  79. package/dist/setup-gate.mjs +2 -0
  80. package/dist/src-pELM4_iH.mjs +376 -0
  81. package/dist/trace-DCB7qFzT.mjs +10 -0
  82. package/dist/transform-DJH3vN4b.mjs +84041 -0
  83. package/dist/transport-BMSzG2-F.mjs +1045 -0
  84. package/dist/view-registry-BualWgAf.mjs +2 -0
  85. package/dist/vite-plugins-Bh3SCOw-.mjs +331 -0
  86. package/dist/vite.d.mts +68 -0
  87. package/dist/vite.mjs +2 -0
  88. package/dist/window-CM2a9Kyc.mjs +2 -0
  89. package/dist/window-CmmpCVX6.mjs +156 -0
  90. package/dist/write-9dRFczGJ.mjs +1248 -0
  91. package/migrations/0000_migration.ts +34 -0
  92. package/migrations/meta/0000_snapshot.json +18 -0
  93. package/migrations/meta/_journal.json +10 -0
  94. package/package.json +124 -0
@@ -0,0 +1,59 @@
1
+ import { createRequire } from "node:module";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+ //#region ../kyju/src/cli/config.ts
6
+ const localRequire = createRequire(import.meta.url);
7
+ const CONFIG_NAMES = [
8
+ "db.config.ts",
9
+ "db.config.js",
10
+ "db.config.mjs"
11
+ ];
12
+ function findConfigFile(cwd) {
13
+ for (const name of CONFIG_NAMES) {
14
+ const p = path.join(cwd, name);
15
+ if (fs.existsSync(p)) return p;
16
+ }
17
+ throw new Error(`No db config found. Expected one of: ${CONFIG_NAMES.join(", ")}`);
18
+ }
19
+ async function loadConfig(configPath) {
20
+ const dir = path.dirname(path.resolve(configPath));
21
+ const mod = await loadModule(path.resolve(configPath));
22
+ const config = mod.default ?? mod;
23
+ if (!config.schema) throw new Error("db config must specify a 'schema' path");
24
+ return {
25
+ schemaPath: path.resolve(dir, config.schema),
26
+ outPath: path.resolve(dir, config.out ?? "./db"),
27
+ alias: config.alias
28
+ };
29
+ }
30
+ async function loadSchema(schemaPath) {
31
+ const mod = await loadModule(schemaPath);
32
+ const schema = mod.schema ?? mod.default;
33
+ if (!schema || !schema.shape) throw new Error(`Schema file must export a 'schema' (via named export or default) created with createSchema(). Got: ${typeof schema}`);
34
+ return schema;
35
+ }
36
+ /**
37
+ * Load a user-authored TS/ESM module (config, schema, migrations entry).
38
+ * Uses tsx's ESM loader (registered once, lazily) so the loaded module can
39
+ * `import` from packages whose `exports` map only declares an ESM `import`
40
+ * condition — like `@zenbujs/core/db`. The legacy CJS path was incompatible
41
+ * with ESM-only deps because `require()` won't resolve `.mjs` files.
42
+ */
43
+ async function loadModule(modulePath) {
44
+ await ensureTsxRegistered();
45
+ return import(pathToFileURL(path.resolve(modulePath)).href);
46
+ }
47
+ let tsxRegistered = null;
48
+ function ensureTsxRegistered() {
49
+ if (tsxRegistered) return tsxRegistered;
50
+ tsxRegistered = (async () => {
51
+ try {
52
+ const tsxApi = localRequire("tsx/esm/api");
53
+ if (typeof tsxApi.register === "function") tsxApi.register();
54
+ } catch {}
55
+ })();
56
+ return tsxRegistered;
57
+ }
58
+ //#endregion
59
+ export { loadSchema as i, loadConfig as n, loadModule as r, findConfigFile as t };
@@ -0,0 +1,2 @@
1
+ import { n as loadConfig, t as findConfigFile } from "./config-CdVrW85P.mjs";
2
+ export { findConfigFile, loadConfig };
@@ -0,0 +1,2 @@
1
+ import "./renderer-host-Bg8QdeeH.mjs";
2
+ export {};
@@ -0,0 +1,531 @@
1
+ import fs, { existsSync, readFileSync } from "node:fs";
2
+ import os, { homedir } from "node:os";
3
+ import path, { join, resolve } from "node:path";
4
+ import fsp from "node:fs/promises";
5
+ //#region src/cli/lib/db-registry.ts
6
+ const INTERNAL_DIR = path.join(os.homedir(), ".zenbu", ".internal");
7
+ const DB_CONFIG_JSON = path.join(INTERNAL_DIR, "db.json");
8
+ const DEFAULT_REGISTRY = {
9
+ defaultDbPath: null,
10
+ dbs: []
11
+ };
12
+ function normalize(p) {
13
+ return path.resolve(p);
14
+ }
15
+ async function ensureDir() {
16
+ await fsp.mkdir(INTERNAL_DIR, { recursive: true });
17
+ }
18
+ async function loadRegistry() {
19
+ let raw;
20
+ try {
21
+ raw = JSON.parse(await fsp.readFile(DB_CONFIG_JSON, "utf8"));
22
+ } catch {
23
+ return { ...DEFAULT_REGISTRY };
24
+ }
25
+ if (!raw || typeof raw !== "object") return { ...DEFAULT_REGISTRY };
26
+ const obj = raw;
27
+ return {
28
+ defaultDbPath: typeof obj.defaultDbPath === "string" ? normalize(obj.defaultDbPath) : null,
29
+ dbs: Array.isArray(obj.dbs) ? obj.dbs.filter((entry) => !!entry && typeof entry === "object" && typeof entry.path === "string").map((entry) => ({
30
+ path: normalize(entry.path),
31
+ lastUsedAt: typeof entry.lastUsedAt === "number" ? entry.lastUsedAt : 0
32
+ })) : []
33
+ };
34
+ }
35
+ async function saveRegistry(registry) {
36
+ await ensureDir();
37
+ await fsp.writeFile(DB_CONFIG_JSON, JSON.stringify(registry, null, 2));
38
+ }
39
+ async function addDb(absPath) {
40
+ const p = normalize(absPath);
41
+ await fsp.mkdir(p, { recursive: true });
42
+ const registry = await loadRegistry();
43
+ const existing = registry.dbs.find((entry) => entry.path === p);
44
+ if (existing) existing.lastUsedAt = Date.now();
45
+ else registry.dbs.push({
46
+ path: p,
47
+ lastUsedAt: Date.now()
48
+ });
49
+ await saveRegistry(registry);
50
+ return registry;
51
+ }
52
+ async function removeDb(absPath) {
53
+ const p = normalize(absPath);
54
+ const registry = await loadRegistry();
55
+ registry.dbs = registry.dbs.filter((entry) => entry.path !== p);
56
+ if (registry.defaultDbPath === p) registry.defaultDbPath = null;
57
+ await saveRegistry(registry);
58
+ return registry;
59
+ }
60
+ async function setDefault(absPath) {
61
+ const p = normalize(absPath);
62
+ await fsp.mkdir(p, { recursive: true });
63
+ const registry = await loadRegistry();
64
+ if (!registry.dbs.some((entry) => entry.path === p)) registry.dbs.push({
65
+ path: p,
66
+ lastUsedAt: Date.now()
67
+ });
68
+ registry.defaultDbPath = p;
69
+ await saveRegistry(registry);
70
+ return registry;
71
+ }
72
+ //#endregion
73
+ //#region src/cli/lib/runtime.ts
74
+ const RUNTIME_JSON = join(homedir(), ".zenbu", ".internal", "runtime.json");
75
+ function readRuntimeConfig() {
76
+ if (!existsSync(RUNTIME_JSON)) return null;
77
+ try {
78
+ const data = JSON.parse(readFileSync(RUNTIME_JSON, "utf-8"));
79
+ if (typeof data.wsPort !== "number" || typeof data.wsToken !== "string" || typeof data.pid !== "number") return null;
80
+ try {
81
+ process.kill(data.pid, 0);
82
+ } catch {
83
+ return null;
84
+ }
85
+ return {
86
+ wsPort: data.wsPort,
87
+ wsToken: data.wsToken,
88
+ dbPath: data.dbPath,
89
+ pid: data.pid
90
+ };
91
+ } catch {
92
+ return null;
93
+ }
94
+ }
95
+ //#endregion
96
+ //#region src/cli/lib/picker.ts
97
+ const ESC = "\x1B[";
98
+ const HIDE_CURSOR = `${ESC}?25l`;
99
+ const SHOW_CURSOR = `${ESC}?25h`;
100
+ const CLEAR_LINE = `${ESC}2K`;
101
+ const UP = (n) => `${ESC}${n}A`;
102
+ const tty = () => process.stdout.isTTY && process.stdin.isTTY;
103
+ const c = {
104
+ reset: () => tty() ? "\x1B[0m" : "",
105
+ dim: (s) => tty() ? `\x1b[2m${s}\x1b[0m` : s,
106
+ bold: (s) => tty() ? `\x1b[1m${s}\x1b[0m` : s,
107
+ green: (s) => tty() ? `\x1b[32m${s}\x1b[0m` : s,
108
+ cyan: (s) => tty() ? `\x1b[36m${s}\x1b[0m` : s,
109
+ yellow: (s) => tty() ? `\x1b[33m${s}\x1b[0m` : s,
110
+ magenta: (s) => tty() ? `\x1b[35m${s}\x1b[0m` : s
111
+ };
112
+ function tildify(p) {
113
+ const home = os.homedir();
114
+ if (p === home) return "~";
115
+ if (p.startsWith(home + "/")) return "~" + p.slice(home.length);
116
+ return p;
117
+ }
118
+ function relTime(ms) {
119
+ if (!ms) return "—";
120
+ const diff = Date.now() - ms;
121
+ if (diff < 0) return "in the future";
122
+ const s = Math.round(diff / 1e3);
123
+ if (s < 45) return "just now";
124
+ const m = Math.round(s / 60);
125
+ if (m < 60) return `${m}m ago`;
126
+ const h = Math.round(m / 60);
127
+ if (h < 24) return `${h}h ago`;
128
+ const d = Math.round(h / 24);
129
+ if (d < 30) return `${d}d ago`;
130
+ const mo = Math.round(d / 30);
131
+ if (mo < 12) return `${mo}mo ago`;
132
+ return `${Math.round(mo / 12)}y ago`;
133
+ }
134
+ /**
135
+ * Arrow-key list picker. Returns the chosen index or null if user aborted
136
+ * (Esc / Ctrl-C). Falls back to a stdin number prompt when stdout isn't a
137
+ * TTY so piping/CI doesn't hang.
138
+ */
139
+ async function pickOne(title, options, initialIndex = 0) {
140
+ if (options.length === 0) return null;
141
+ if (!tty()) return await numberPrompt(title, options, initialIndex);
142
+ const stdin = process.stdin;
143
+ const stdout = process.stdout;
144
+ let idx = Math.max(0, Math.min(initialIndex, options.length - 1));
145
+ const render = (first) => {
146
+ if (!first) stdout.write(UP(options.length + 1));
147
+ stdout.write(`${CLEAR_LINE}${title}\n`);
148
+ for (let i = 0; i < options.length; i++) {
149
+ const opt = options[i];
150
+ const selected = i === idx;
151
+ const arrow = selected ? c.cyan("›") : " ";
152
+ const label = selected ? c.bold(opt.label) : opt.label;
153
+ const detail = opt.detail ? ` ${c.dim(opt.detail)}` : "";
154
+ stdout.write(`${CLEAR_LINE}${arrow} ${label}${detail}\n`);
155
+ }
156
+ };
157
+ stdout.write(HIDE_CURSOR);
158
+ render(true);
159
+ return new Promise((resolve) => {
160
+ const wasRaw = stdin.isRaw;
161
+ stdin.setRawMode?.(true);
162
+ stdin.resume();
163
+ stdin.setEncoding("utf8");
164
+ const cleanup = (result) => {
165
+ stdin.off("data", onData);
166
+ stdin.setRawMode?.(wasRaw ?? false);
167
+ stdin.pause();
168
+ stdout.write(SHOW_CURSOR);
169
+ resolve(result);
170
+ };
171
+ const onData = (data) => {
172
+ if (data === "" || data === "\x1B") return cleanup(null);
173
+ if (data === "\r" || data === "\n") return cleanup(idx);
174
+ if (data === "\x1B[A" || data === "k") {
175
+ idx = (idx - 1 + options.length) % options.length;
176
+ render(false);
177
+ return;
178
+ }
179
+ if (data === "\x1B[B" || data === "j") {
180
+ idx = (idx + 1) % options.length;
181
+ render(false);
182
+ return;
183
+ }
184
+ const n = Number(data);
185
+ if (Number.isInteger(n) && n >= 1 && n <= options.length) {
186
+ idx = n - 1;
187
+ render(false);
188
+ }
189
+ };
190
+ stdin.on("data", onData);
191
+ });
192
+ }
193
+ async function numberPrompt(title, options, initialIndex) {
194
+ process.stdout.write(`${title}\n`);
195
+ for (let i = 0; i < options.length; i++) {
196
+ const opt = options[i];
197
+ const detail = opt.detail ? ` ${opt.detail}` : "";
198
+ process.stdout.write(` ${i + 1}. ${opt.label}${detail}\n`);
199
+ }
200
+ process.stdout.write(`Choose [1-${options.length}] (default ${initialIndex + 1}): `);
201
+ return new Promise((resolve) => {
202
+ let buf = "";
203
+ process.stdin.setEncoding("utf8");
204
+ process.stdin.resume();
205
+ const onData = (data) => {
206
+ buf += data;
207
+ const nl = buf.indexOf("\n");
208
+ if (nl === -1) return;
209
+ process.stdin.off("data", onData);
210
+ process.stdin.pause();
211
+ const trimmed = buf.slice(0, nl).trim();
212
+ if (!trimmed) return resolve(initialIndex);
213
+ const n = Number(trimmed);
214
+ if (!Number.isInteger(n) || n < 1 || n > options.length) return resolve(null);
215
+ resolve(n - 1);
216
+ };
217
+ process.stdin.on("data", onData);
218
+ });
219
+ }
220
+ async function readLine(prompt) {
221
+ process.stdout.write(prompt);
222
+ return new Promise((resolve) => {
223
+ let buf = "";
224
+ process.stdin.setEncoding("utf8");
225
+ process.stdin.resume();
226
+ const onData = (data) => {
227
+ buf += data;
228
+ const nl = buf.indexOf("\n");
229
+ if (nl === -1) return;
230
+ process.stdin.off("data", onData);
231
+ process.stdin.pause();
232
+ resolve(buf.slice(0, nl).trimEnd() || null);
233
+ };
234
+ process.stdin.on("data", onData);
235
+ });
236
+ }
237
+ //#endregion
238
+ //#region src/cli/commands/db.ts
239
+ const ADD_NEW_VALUE = "__add_new__";
240
+ function printUsage(exitCode = 0) {
241
+ console.log(`
242
+ Usage:
243
+ zen db Interactive picker for the default DB
244
+ zen db list List known DB paths
245
+ zen db add <path> Register a path (mkdir -p) without launching
246
+ zen db default [<path>] Set the default DB (interactive when omitted)
247
+ zen db remove [<path>] Drop a path from the registry (interactive when omitted)
248
+ zen db generate [...] Diff a schema against the last snapshot and
249
+ write a new migration. Default: walks up from
250
+ cwd to the nearest zenbu.plugin.json and reads
251
+ "schema" + "migrations" from it. Flags:
252
+ --manifest <path> override manifest path
253
+ --schema <path> schema file (bypasses
254
+ manifest discovery; must
255
+ be paired with --migrations)
256
+ --migrations <path> migrations output dir
257
+ (paired with --schema)
258
+ --name <tag> custom migration name
259
+ --custom generate editable migrate()
260
+ --amend replace the last migration
261
+ `);
262
+ process.exit(exitCode);
263
+ }
264
+ function annotate(e, defaultPath, activePath) {
265
+ const tags = [];
266
+ const rawTags = [];
267
+ if (e.path === defaultPath) {
268
+ tags.push(c.green("default"));
269
+ rawTags.push("default");
270
+ }
271
+ if (activePath && e.path === activePath) {
272
+ tags.push(c.cyan("running"));
273
+ rawTags.push("running");
274
+ }
275
+ return {
276
+ tags,
277
+ rawTags
278
+ };
279
+ }
280
+ async function runList() {
281
+ const reg = await loadRegistry();
282
+ const activePath = readRuntimeConfig()?.dbPath ?? null;
283
+ if (reg.dbs.length === 0) {
284
+ console.log("No DBs registered yet. Run `zen db add <path>` or `zen --db <path>`.");
285
+ return;
286
+ }
287
+ const rows = [...reg.dbs].sort((a, b) => b.lastUsedAt - a.lastUsedAt).map((e) => {
288
+ const { tags } = annotate(e, reg.defaultDbPath, activePath);
289
+ return {
290
+ path: tildify(e.path),
291
+ time: relTime(e.lastUsedAt),
292
+ tags: tags.join(" ")
293
+ };
294
+ });
295
+ const pathW = Math.max(...rows.map((r) => r.path.length), 4);
296
+ const timeW = Math.max(...rows.map((r) => r.time.length), 9);
297
+ console.log("");
298
+ console.log(` ${c.dim("path".padEnd(pathW))} ${c.dim("last used".padEnd(timeW))}`);
299
+ for (const r of rows) console.log(` ${r.path.padEnd(pathW)} ${c.dim(r.time.padEnd(timeW))} ${r.tags}`);
300
+ console.log("");
301
+ }
302
+ async function runAdd(argv) {
303
+ const target = argv[0];
304
+ if (!target) {
305
+ console.error("zen db add: missing <path>");
306
+ process.exit(1);
307
+ }
308
+ const abs = resolve(process.cwd(), target);
309
+ await addDb(abs);
310
+ console.log(`added ${tildify(abs)}`);
311
+ }
312
+ async function pickDefault() {
313
+ const reg = await loadRegistry();
314
+ const activePath = readRuntimeConfig()?.dbPath ?? null;
315
+ const sorted = [...reg.dbs].sort((a, b) => b.lastUsedAt - a.lastUsedAt);
316
+ const options = sorted.map((e) => {
317
+ const { rawTags } = annotate(e, reg.defaultDbPath, activePath);
318
+ return {
319
+ value: e.path,
320
+ label: tildify(e.path),
321
+ detail: [relTime(e.lastUsedAt), ...rawTags].filter(Boolean).join(" · ")
322
+ };
323
+ });
324
+ options.push({
325
+ value: ADD_NEW_VALUE,
326
+ label: c.magenta("+ Add a new path…")
327
+ });
328
+ const idx = await pickOne("Choose default DB:", options, Math.max(0, sorted.findIndex((e) => e.path === reg.defaultDbPath)));
329
+ if (idx === null) {
330
+ console.log("aborted");
331
+ return;
332
+ }
333
+ const chosen = options[idx].value;
334
+ let target;
335
+ if (chosen === ADD_NEW_VALUE) {
336
+ const input = await readLine("New DB path: ");
337
+ if (!input) {
338
+ console.log("aborted");
339
+ return;
340
+ }
341
+ target = resolve(process.cwd(), input.replace(/^~/, process.env.HOME ?? "~"));
342
+ } else target = chosen;
343
+ await setDefault(target);
344
+ console.log(`default = ${tildify(target)}`);
345
+ if (activePath && activePath !== target) console.log(c.yellow(`note: app is currently running on ${tildify(activePath)}; quit and relaunch to pick up the new default.`));
346
+ }
347
+ async function runDefault(argv) {
348
+ if (argv.length === 0) {
349
+ await pickDefault();
350
+ return;
351
+ }
352
+ const abs = resolve(process.cwd(), argv[0]);
353
+ await setDefault(abs);
354
+ console.log(`default = ${tildify(abs)}`);
355
+ const running = readRuntimeConfig();
356
+ if (running?.dbPath && running.dbPath !== abs) console.log(c.yellow(`note: app is currently running on ${tildify(running.dbPath)}; quit and relaunch to pick up the new default.`));
357
+ }
358
+ async function runRemove(argv) {
359
+ let abs = null;
360
+ if (argv.length > 0) abs = resolve(process.cwd(), argv[0]);
361
+ else {
362
+ const reg = await loadRegistry();
363
+ if (reg.dbs.length === 0) {
364
+ console.log("registry is empty");
365
+ return;
366
+ }
367
+ const options = reg.dbs.map((e) => ({
368
+ value: e.path,
369
+ label: tildify(e.path),
370
+ detail: relTime(e.lastUsedAt)
371
+ }));
372
+ const idx = await pickOne("Remove which DB?", options, 0);
373
+ if (idx === null) {
374
+ console.log("aborted");
375
+ return;
376
+ }
377
+ abs = options[idx].value;
378
+ }
379
+ if (!(await loadRegistry()).dbs.some((e) => e.path === abs)) {
380
+ console.error(`zen db remove: ${tildify(abs)} not in registry`);
381
+ process.exit(1);
382
+ }
383
+ await removeDb(abs);
384
+ console.log(`removed ${tildify(abs)}`);
385
+ }
386
+ async function runDb(argv) {
387
+ const [sub, ...rest] = argv;
388
+ if (!sub) {
389
+ await pickDefault();
390
+ return;
391
+ }
392
+ if (sub === "help" || sub === "--help" || sub === "-h") printUsage();
393
+ switch (sub) {
394
+ case "list":
395
+ case "ls":
396
+ await runList();
397
+ return;
398
+ case "add":
399
+ await runAdd(rest);
400
+ return;
401
+ case "default":
402
+ await runDefault(rest);
403
+ return;
404
+ case "remove":
405
+ case "rm":
406
+ await runRemove(rest);
407
+ return;
408
+ case "generate":
409
+ case "gen":
410
+ await runGenerate(rest);
411
+ return;
412
+ default:
413
+ console.error(`zen db: unknown subcommand "${sub}"`);
414
+ printUsage(1);
415
+ }
416
+ }
417
+ /**
418
+ * Drive the embedded migration generator. Two input modes:
419
+ *
420
+ * • Manifest mode (default for plugins). Walks up from cwd to the
421
+ * nearest `zenbu.plugin.json` and reads `schema` + `migrations` from
422
+ * it — same paths `discoverSections` consumes at runtime, so there's
423
+ * one source of truth per plugin.
424
+ *
425
+ * • Direct mode (`--schema <path> --migrations <path>`). Skips manifest
426
+ * discovery entirely. Used for schemas that aren't a zenbu plugin —
427
+ * notably `@zenbujs/core`'s framework schema, which is invoked through
428
+ * a `db:generate` script in `packages/core/package.json`. Composable
429
+ * for any future internal section without growing privileged flags
430
+ * into the CLI.
431
+ *
432
+ * Resolution order: direct mode wins when both paths are given; otherwise
433
+ * `--manifest`; otherwise the walk-up. Mixing direct + manifest is an
434
+ * error (the user almost certainly meant one or the other).
435
+ */
436
+ function findManifest(from) {
437
+ let dir = path.resolve(from);
438
+ while (true) {
439
+ const candidate = path.join(dir, "zenbu.plugin.json");
440
+ if (fs.existsSync(candidate)) return candidate;
441
+ const parent = path.dirname(dir);
442
+ if (parent === dir) return null;
443
+ dir = parent;
444
+ }
445
+ }
446
+ function parseGenerateArgs(argv) {
447
+ const out = {
448
+ manifest: null,
449
+ schema: null,
450
+ migrationsOut: null,
451
+ custom: false,
452
+ amend: false
453
+ };
454
+ for (let i = 0; i < argv.length; i++) {
455
+ const arg = argv[i];
456
+ if (arg === "--manifest" && i + 1 < argv.length) out.manifest = argv[++i];
457
+ else if (arg.startsWith("--manifest=")) out.manifest = arg.slice(11);
458
+ else if (arg === "--schema" && i + 1 < argv.length) out.schema = argv[++i];
459
+ else if (arg.startsWith("--schema=")) out.schema = arg.slice(9);
460
+ else if (arg === "--migrations" && i + 1 < argv.length) out.migrationsOut = argv[++i];
461
+ else if (arg.startsWith("--migrations=")) out.migrationsOut = arg.slice(13);
462
+ else if (arg === "--name" && i + 1 < argv.length) out.name = argv[++i];
463
+ else if (arg.startsWith("--name=")) out.name = arg.slice(7);
464
+ else if (arg === "--custom") out.custom = true;
465
+ else if (arg === "--amend") out.amend = true;
466
+ }
467
+ return out;
468
+ }
469
+ async function runGenerate(argv) {
470
+ const flags = parseGenerateArgs(argv);
471
+ const { generateMigration } = await import("./cli-BLbQQIVB.mjs");
472
+ if (flags.schema || flags.migrationsOut) {
473
+ if (!flags.schema || !flags.migrationsOut) {
474
+ console.error("zen db generate: --schema and --migrations must be passed together.");
475
+ process.exit(1);
476
+ }
477
+ if (flags.manifest) {
478
+ console.error("zen db generate: --manifest is incompatible with --schema/--migrations; pick one input mode.");
479
+ process.exit(1);
480
+ }
481
+ const schemaPath = resolve(process.cwd(), flags.schema);
482
+ const outPath = resolve(process.cwd(), flags.migrationsOut);
483
+ console.log(`Schema: ${schemaPath}`);
484
+ console.log(`Output: ${outPath}`);
485
+ await generateMigration({
486
+ schemaPath,
487
+ outPath,
488
+ name: flags.name,
489
+ custom: flags.custom,
490
+ amend: flags.amend
491
+ });
492
+ return;
493
+ }
494
+ const manifestPath = flags.manifest ? resolve(process.cwd(), flags.manifest) : findManifest(process.cwd());
495
+ if (!manifestPath) {
496
+ console.error("zen db generate: no zenbu.plugin.json found in cwd or any parent.");
497
+ console.error(" Run from inside the plugin, pass --manifest <path>,");
498
+ console.error(" or use --schema <path> --migrations <path> directly.");
499
+ process.exit(1);
500
+ }
501
+ let manifest;
502
+ try {
503
+ manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
504
+ } catch (err) {
505
+ console.error(`zen db generate: failed to parse ${manifestPath}: ${err instanceof Error ? err.message : String(err)}`);
506
+ process.exit(1);
507
+ }
508
+ if (!manifest.schema) {
509
+ console.error(`zen db generate: ${manifestPath} is missing the required "schema" field.`);
510
+ process.exit(1);
511
+ }
512
+ if (!manifest.migrations) {
513
+ console.error(`zen db generate: ${manifestPath} is missing the required "migrations" field`);
514
+ console.error(` (the directory the generator writes migrations into).`);
515
+ process.exit(1);
516
+ }
517
+ const baseDir = path.dirname(manifestPath);
518
+ const schemaPath = path.resolve(baseDir, manifest.schema);
519
+ const outPath = path.resolve(baseDir, manifest.migrations);
520
+ console.log(`Plugin: ${manifest.name ?? path.basename(baseDir)}`);
521
+ console.log(`Manifest: ${manifestPath}`);
522
+ await generateMigration({
523
+ schemaPath,
524
+ outPath,
525
+ name: flags.name,
526
+ custom: flags.custom,
527
+ amend: flags.amend
528
+ });
529
+ }
530
+ //#endregion
531
+ export { runDb };
package/dist/db.d.mts ADDED
@@ -0,0 +1,16 @@
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-CPZ5d6Hl.mjs";
2
+ import { z as z$1 } from "zod";
3
+
4
+ //#region src/db.d.ts
5
+ declare const z: typeof z$1;
6
+ type Schema<TShape extends SchemaShape$1 = SchemaShape$1> = Schema$1<TShape>;
7
+ type SchemaShape = SchemaShape$1;
8
+ type InferSchema<S extends Schema$1> = InferSchema$1<S>;
9
+ type InferRoot<T extends SchemaShape$1> = InferRoot$1<T>;
10
+ type CollectionRefBrand<T = unknown> = CollectionRefBrand$1<T>;
11
+ type CollectionRefValue<T = unknown> = CollectionRefValue$1<T>;
12
+ type CollectionNode<T = unknown> = CollectionNode$1<T>;
13
+ type DbClient<T extends SchemaShape$1 = SchemaShape$1> = ClientProxy<T>;
14
+ declare const connectDb: typeof connectReplica;
15
+ //#endregion
16
+ export { CollectionNode, CollectionRefBrand, CollectionRefValue, DbClient, InferRoot, InferSchema, Schema, SchemaShape, blob, collection, connectDb, createSchema, dbParse, dbStringify, z };
package/dist/db.mjs ADDED
@@ -0,0 +1,16 @@
1
+ import { i as createSchema, n as blob, r as collection } from "./schema-CIg4GzHQ.mjs";
2
+ import { i as dbStringify, r as dbParse, t as connectReplica } from "./transport-BMSzG2-F.mjs";
3
+ import { z as z$1 } from "zod";
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
+ const z = z$1;
14
+ const connectDb = connectReplica;
15
+ //#endregion
16
+ export { blob, collection, connectDb, createSchema, dbParse, dbStringify, z };