@voltro/cli 0.30.2 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/CHANGELOG.md +278 -0
  2. package/dist/{apiBuild-BUS1RfPi.js → apiBuild-C4uEbs3s.js} +2 -2
  3. package/dist/apiBuild-OJEjtwcn.js +2 -0
  4. package/dist/appGraph-CvQCte0z.js +2 -0
  5. package/dist/appGraph-gQ_6GkQQ.js +110 -0
  6. package/dist/bin.js +3 -3
  7. package/dist/checkCommand-CwMrzAgV.js +2 -0
  8. package/dist/{checkCommand-D_wdOFhw.js → checkCommand-dm7OHtPt.js} +401 -505
  9. package/dist/{commands-BgGAUcku.js → commands-C0nEePif.js} +2601 -2498
  10. package/dist/dbCommand-By__Ev0R.js +2 -0
  11. package/dist/{dbCommand-CbPRCD1x.js → dbCommand-ifOMafuG.js} +112 -84
  12. package/dist/{dev-GAOIot9G.js → dev-5ficNnvF.js} +1843 -1832
  13. package/dist/{dev-tPcOmjPJ.js → dev-rc3fwPSZ.js} +1 -1
  14. package/dist/index.js +1 -1
  15. package/dist/{inspectMetrics-BM1vrsga.js → inspectMetrics-BqO4E9G0.js} +1008 -719
  16. package/dist/{sdkgen-BV4fFucu.js → sdkgen-B_5mHQS2.js} +1 -1
  17. package/dist/{serveCommand-ClqXCX1y.js → serveCommand-PxMmn96o.js} +454 -454
  18. package/dist/serveEntry.js +2 -2
  19. package/dist/{start-CTnNvKlk.js → start-D1-8eKrO.js} +204 -199
  20. package/dist/startEntry.js +2 -2
  21. package/package.json +417 -17
  22. package/templates/AGENTS.md +43 -43
  23. package/templates/agent-docs/_index.md +43 -43
  24. package/templates/agent-docs/_manifest.json +84 -42
  25. package/templates/agent-docs/database/migrations.md +14 -1
  26. package/templates/agent-docs/internationalization.md +29 -0
  27. package/templates/agent-docs/plugins/ai-flows.md +148 -0
  28. package/templates/agent-docs/plugins/analytics-postgres.md +90 -0
  29. package/templates/agent-docs/plugins/atlassian.md +378 -0
  30. package/templates/agent-docs/plugins/audit.md +348 -0
  31. package/templates/agent-docs/plugins/auth-auth0.md +92 -0
  32. package/templates/agent-docs/plugins/auth-clerk.md +90 -0
  33. package/templates/agent-docs/plugins/auth-kinde.md +88 -0
  34. package/templates/agent-docs/plugins/auth-oidc.md +95 -0
  35. package/templates/agent-docs/plugins/auth-supabase.md +103 -0
  36. package/templates/agent-docs/plugins/auth-workos.md +105 -0
  37. package/templates/agent-docs/plugins/auth.md +227 -0
  38. package/templates/agent-docs/plugins/billing.md +324 -0
  39. package/templates/agent-docs/plugins/broadcast.md +144 -0
  40. package/templates/agent-docs/plugins/cdc-out.md +116 -0
  41. package/templates/agent-docs/plugins/clickhouse.md +91 -0
  42. package/templates/agent-docs/plugins/datadog.md +105 -0
  43. package/templates/agent-docs/plugins/deactivation.md +114 -0
  44. package/templates/agent-docs/plugins/duckdb.md +82 -0
  45. package/templates/agent-docs/plugins/flags.md +146 -0
  46. package/templates/agent-docs/plugins/governance.md +143 -0
  47. package/templates/agent-docs/plugins/licensing.md +74 -0
  48. package/templates/agent-docs/plugins/logship.md +56 -0
  49. package/templates/agent-docs/plugins/mail.md +334 -0
  50. package/templates/agent-docs/plugins/moderation.md +65 -0
  51. package/templates/agent-docs/plugins/multitenancy.md +99 -0
  52. package/templates/agent-docs/plugins/notifications.md +252 -0
  53. package/templates/agent-docs/plugins/openapi.md +94 -0
  54. package/templates/agent-docs/plugins/postgis.md +140 -0
  55. package/templates/agent-docs/plugins/posthog.md +91 -0
  56. package/templates/agent-docs/plugins/presence.md +115 -0
  57. package/templates/agent-docs/plugins/prometheus.md +124 -0
  58. package/templates/agent-docs/plugins/ratelimit.md +274 -0
  59. package/templates/agent-docs/plugins/rbac.md +270 -0
  60. package/templates/agent-docs/plugins/scim.md +63 -0
  61. package/templates/agent-docs/plugins/search.md +116 -0
  62. package/templates/agent-docs/plugins/sentry.md +192 -0
  63. package/templates/agent-docs/plugins/soft-delete.md +72 -0
  64. package/templates/agent-docs/plugins/sso-saml.md +132 -0
  65. package/templates/agent-docs/plugins/storage.md +709 -0
  66. package/templates/agent-docs/plugins/tinybird.md +92 -0
  67. package/templates/agent-docs/plugins/versioning.md +226 -0
  68. package/templates/agent-docs/plugins/webhooks.md +585 -0
  69. package/templates/agent-docs/security.md +21 -1
  70. package/templates/agent-docs/whats-new.md +137 -22
  71. package/templates/apps/api-ai/package.json +7 -7
  72. package/templates/apps/api-auth/package.json +8 -8
  73. package/templates/apps/api-backend/package.json +7 -7
  74. package/templates/apps/api-backend-deactivation/package.json +7 -7
  75. package/templates/apps/api-backend-mail/package.json +8 -8
  76. package/templates/apps/api-backend-mariadb/package.json +9 -9
  77. package/templates/apps/api-backend-sqlite/package.json +8 -8
  78. package/templates/apps/api-backend-storage/package.json +8 -8
  79. package/templates/apps/api-cms/package.json +10 -10
  80. package/templates/apps/api-collab/package.json +8 -8
  81. package/templates/apps/api-data-advanced/package.json +8 -8
  82. package/templates/apps/api-durable/package.json +8 -8
  83. package/templates/apps/api-feature-flags/package.json +9 -9
  84. package/templates/apps/api-governance/package.json +8 -8
  85. package/templates/apps/api-kv/package.json +8 -8
  86. package/templates/apps/api-moderation/package.json +8 -8
  87. package/templates/apps/api-observability/package.json +8 -8
  88. package/templates/apps/api-ratelimit/package.json +8 -8
  89. package/templates/apps/api-rbac/package.json +8 -8
  90. package/templates/apps/api-rest/package.json +7 -7
  91. package/templates/apps/api-saas/package.json +11 -11
  92. package/templates/apps/api-saas-starter/package.json +10 -10
  93. package/templates/apps/api-search/package.json +8 -8
  94. package/templates/apps/api-status/package.json +8 -8
  95. package/templates/apps/api-versioning/package.json +8 -8
  96. package/templates/apps/api-webhooks/package.json +9 -9
  97. package/templates/apps/changelog/package.json +6 -6
  98. package/templates/apps/edge-functions/package.json +2 -2
  99. package/templates/apps/frontend-admin/package.json +8 -8
  100. package/templates/apps/frontend-app/package.json +8 -8
  101. package/templates/apps/frontend-auth/package.json +8 -8
  102. package/templates/apps/frontend-blank/package.json +7 -7
  103. package/templates/apps/frontend-cms/package.json +9 -9
  104. package/templates/apps/frontend-collab/package.json +9 -9
  105. package/templates/apps/frontend-contact/package.json +7 -7
  106. package/templates/apps/frontend-dashboard/package.json +7 -7
  107. package/templates/apps/frontend-docs/package.json +7 -7
  108. package/templates/apps/frontend-i18n/package.json +6 -6
  109. package/templates/apps/frontend-landing/package.json +7 -7
  110. package/templates/apps/frontend-portal/package.json +8 -8
  111. package/templates/apps/frontend-saas/package.json +8 -8
  112. package/templates/apps/frontend-spa/package.json +7 -7
  113. package/templates/apps/frontend-ssr/package.json +7 -7
  114. package/templates/apps/frontend-ssr-api/package.json +8 -8
  115. package/templates/apps/frontend-static-blog/package.json +6 -6
  116. package/templates/apps/frontend-status/package.json +8 -8
  117. package/templates/apps/mobile-app/package.json +2 -2
  118. package/dist/apiBuild-DMlxvL8h.js +0 -2
  119. package/dist/checkCommand-CARZ36Tr.js +0 -2
  120. package/dist/dbCommand-Ht47LrV-.js +0 -2
@@ -7,11 +7,11 @@ import { FileSystem as v } from "@effect/platform";
7
7
  import { NodeContext as y } from "@effect/platform-node";
8
8
  import { Effect as b } from "effect";
9
9
  import { addSink as x, createLogger as S, printReadyBlock as C } from "@voltro/logger";
10
- import { closeSync as w, existsSync as T, mkdirSync as E, openSync as D, promises as O, readFileSync as ee, readdirSync as k, statSync as A, unlinkSync as j, unwatchFile as te, watchFile as ne, writeSync as M } from "node:fs";
11
- import { currentTraceContext as N, recordSample as re, resolveSecret as P } from "@voltro/runtime";
12
- import { homedir as F } from "node:os";
13
- import { createRequire as I } from "node:module";
14
- import { FRAMEWORK_ENV_CATALOG as ie, appEnvEntries as L, checkEnvNaming as R, formatEnvErrors as z, installEnvSnapshot as ae, isEnvContract as B, pluginEnvEntries as oe, renderDotEnvExample as V, resolveEnv as se } from "@voltro/env";
10
+ import { closeSync as w, existsSync as T, mkdirSync as E, openSync as D, promises as O, readFileSync as k, readdirSync as A, statSync as j, unlinkSync as M, unwatchFile as N, watchFile as ee, writeSync as P } from "node:fs";
11
+ import { currentTraceContext as F, recordSample as I, resolveSecret as te } from "@voltro/runtime";
12
+ import { homedir as L } from "node:os";
13
+ import { createRequire as R } from "node:module";
14
+ import { FRAMEWORK_ENV_CATALOG as ne, appEnvEntries as re, checkEnvNaming as z, formatEnvErrors as ie, installEnvSnapshot as B, isEnvContract as ae, pluginEnvEntries as V, renderDotEnvExample as oe, resolveEnv as se } from "@voltro/env";
15
15
  import { __installPublicEnv as ce } from "@voltro/env/public";
16
16
  import { mkdir as H, readFile as le, writeFile as ue } from "node:fs/promises";
17
17
  import { createHash as de } from "node:crypto";
@@ -19,38 +19,38 @@ import { spawn as fe } from "node:child_process";
19
19
  import { createConnection as pe } from "node:net";
20
20
  import { PassThrough as me } from "node:stream";
21
21
  //#region src/agentsMd.ts
22
- var U = d(g(import.meta.url)), W = [h(U, "..", "templates"), h(U, "..", "..", "templates")], he = (e) => ({
22
+ var he = d(g(import.meta.url)), U = [h(he, "..", "templates"), h(he, "..", "..", "templates")], ge = (e) => ({
23
23
  _tag: "TemplateNotFoundError",
24
24
  searched: e
25
- }), G = ["AGENTS.md", "CLAUDE.md"], ge = "voltro:agents-md:keep", _e = 2048, ve = "<!-- VOLTRO:INDEX -->", K = (e, t) => e.exists(t).pipe(b.orElseSucceed(() => !1)), q = (e, t) => e.readFileString(t).pipe(b.orElseSucceed(() => "")), ye = (e, t) => e.readFileString(t).pipe(b.map((e) => {
25
+ }), W = ["AGENTS.md", "CLAUDE.md"], _e = "voltro:agents-md:keep", ve = 2048, ye = "<!-- VOLTRO:INDEX -->", G = (e, t) => e.exists(t).pipe(b.orElseSucceed(() => !1)), K = (e, t) => e.readFileString(t).pipe(b.orElseSucceed(() => "")), be = (e, t) => e.readFileString(t).pipe(b.map((e) => {
26
26
  try {
27
27
  return JSON.parse(e).workspaces !== void 0;
28
28
  } catch {
29
29
  return !1;
30
30
  }
31
- }), b.orElseSucceed(() => !1)), J = (e) => b.gen(function* () {
31
+ }), b.orElseSucceed(() => !1)), q = (e) => b.gen(function* () {
32
32
  let t = yield* v.FileSystem, n = h(e);
33
33
  for (;;) {
34
- if ((yield* K(t, p(n, ".git"))) || (yield* K(t, p(n, "pnpm-workspace.yaml"))) || (yield* ye(t, p(n, "package.json")))) return n;
34
+ if ((yield* G(t, p(n, ".git"))) || (yield* G(t, p(n, "pnpm-workspace.yaml"))) || (yield* be(t, p(n, "package.json")))) return n;
35
35
  let r = d(n);
36
36
  if (r === n) return h(e);
37
37
  n = r;
38
38
  }
39
- }), be = (e, t, n) => b.gen(function* () {
39
+ }), xe = (e, t, n) => b.gen(function* () {
40
40
  yield* e.makeDirectory(n, { recursive: !0 }).pipe(b.orElseSucceed(() => void 0));
41
41
  let r = yield* e.readDirectory(t).pipe(b.orElseSucceed(() => []));
42
42
  for (let i of r) {
43
43
  let r = p(t, i), a = p(n, i);
44
- (yield* e.stat(r).pipe(b.orElseSucceed(() => null)))?.type === "Directory" ? yield* be(e, r, a) : yield* e.copyFile(r, a).pipe(b.orElseSucceed(() => void 0));
44
+ (yield* e.stat(r).pipe(b.orElseSucceed(() => null)))?.type === "Directory" ? yield* xe(e, r, a) : yield* e.copyFile(r, a).pipe(b.orElseSucceed(() => void 0));
45
45
  }
46
- }), xe = (e) => typeof e?.name == "string" && e.name.length > 0 ? e.name.split("#")[0] : null, Se = (e, t) => b.gen(function* () {
46
+ }), Se = (e) => typeof e?.name == "string" && e.name.length > 0 ? e.name.split("#")[0] : null, Ce = (e, t) => b.gen(function* () {
47
47
  let n = p(t, "app.config.ts");
48
- if (!(yield* K(e, n))) return null;
48
+ if (!(yield* G(e, n))) return null;
49
49
  let r = (yield* b.tryPromise(() => import(_(n).href)).pipe(b.orElseSucceed(() => null)))?.default;
50
- return !r || r.type && r.type !== "api" ? r?.type === "web" ? [] : null : (r.plugins ?? []).map(xe).filter((e) => e !== null);
51
- }), Ce = (e, t) => b.gen(function* () {
50
+ return !r || r.type && r.type !== "api" ? r?.type === "web" ? [] : null : (r.plugins ?? []).map(Se).filter((e) => e !== null);
51
+ }), we = (e, t) => b.gen(function* () {
52
52
  let n = [], r = [], i = p(t, "apps");
53
- if (!(yield* K(e, i))) return {
53
+ if (!(yield* G(e, i))) return {
54
54
  apis: n,
55
55
  webs: r
56
56
  };
@@ -58,8 +58,8 @@ var U = d(g(import.meta.url)), W = [h(U, "..", "templates"), h(U, "..", "..", "t
58
58
  let a = p(i, t);
59
59
  if ((yield* e.stat(a).pipe(b.orElseSucceed(() => null)))?.type === "Directory") for (let t of yield* e.readDirectory(a).pipe(b.orElseSucceed(() => []))) {
60
60
  let i = p(a, t), o = p(i, "app.config.ts");
61
- if (!(yield* K(e, o))) continue;
62
- let s = yield* q(e, o);
61
+ if (!(yield* G(e, o))) continue;
62
+ let s = yield* K(e, o);
63
63
  /type:\s*['"]web['"]/.test(s) ? r.push(i) : n.push(i);
64
64
  }
65
65
  }
@@ -67,7 +67,7 @@ var U = d(g(import.meta.url)), W = [h(U, "..", "templates"), h(U, "..", "..", "t
67
67
  apis: n,
68
68
  webs: r
69
69
  };
70
- }), we = (e) => e.replace(/\|/g, "\\|").replace(/\n/g, " ").trim(), Te = (e, t, n) => {
70
+ }), Te = (e) => e.replace(/\|/g, "\\|").replace(/\n/g, " ").trim(), Ee = (e, t, n) => {
71
71
  let r = [
72
72
  "<!-- voltro agent-docs index — regenerated at seed time -->",
73
73
  "## Deep reference (read on demand)",
@@ -79,17 +79,17 @@ var U = d(g(import.meta.url)), W = [h(U, "..", "templates"), h(U, "..", "..", "t
79
79
  "",
80
80
  "| Topic | Open | Summary |",
81
81
  "|---|---|---|",
82
- ...e.modules.map((e) => `| ${e.title} | \`${n}${e.path}\` | ${we(e.description)} |`),
82
+ ...e.modules.map((e) => `| ${e.title} | \`${n}${e.path}\` | ${Te(e.description)} |`),
83
83
  ""
84
- ], i = new Map(e.plugins.map((e) => [e.pkg, e])), a = t === null ? e.plugins.map((e) => `| ${e.slug} | \`node_modules/${e.pkg}/README.md\` | ${we(e.description)} |`) : t.map((e) => {
84
+ ], i = new Map(e.plugins.map((e) => [e.pkg, e])), a = (e, t) => e.module === void 0 ? `\`node_modules/${t}/README.md\`` : `\`${n}${e.module}\` (or \`node_modules/${t}/README.md\`)`, o = t === null ? e.plugins.map((e) => `| ${e.slug} | ${a(e, e.pkg)} | ${Te(e.description)} |`) : t.map((e) => {
85
85
  let t = i.get(e);
86
- return t ? `| ${t.slug} | \`node_modules/${e}/README.md\` | ${we(t.description)} |` : `| ${e.replace(/^@[^/]+\//, "")} | \`node_modules/${e}/README.md\` | (see plugin README) |`;
86
+ return t ? `| ${t.slug} | ${a(t, e)} | ${Te(t.description)} |` : `| ${e.replace(/^@[^/]+\//, "")} | \`node_modules/${e}/README.md\` | (see plugin README) |`;
87
87
  });
88
- return r.push(`### Plugins${t === null ? "" : " (installed)"}`, "", "| Plugin | Open | Summary |", "|---|---|---|"), r.push(a.length ? a.join("\n") : "| _(none installed)_ | | |", ""), r.join("\n");
89
- }, Ee = (e, t, n) => {
88
+ return r.push(`### Plugins${t === null ? "" : " (installed)"}`, "", "| Plugin | Open | Summary |", "|---|---|---|"), r.push(o.length ? o.join("\n") : "| _(none installed)_ | | |", ""), r.join("\n");
89
+ }, De = (e, t, n) => {
90
90
  let r = t.templates?.[e] ?? t.templates?.[e.replace(/^frontend-/, "")];
91
91
  return `\nScaffolded from the \`${e}\` template — see \`${r ? `${n}${r}` : `${n}agent-docs/templates/overview.md`}\`.\n`;
92
- }, De = {
92
+ }, Oe = {
93
93
  api: (e, t, n = "") => `# api — agent notes
94
94
 
95
95
  You are in a Voltro **api** app. Server primitives live here: \`queries/\`,
@@ -129,7 +129,7 @@ You are in a Voltro **web** app. File-based routing under \`src/pages/**\`.
129
129
  Deep reference (paths from the repo root): \`${e}agent-docs/routing.md\`,
130
130
  \`${e}agent-docs/schema-driven-ui.md\`, \`${e}agent-docs/internationalization.md\`.
131
131
  ${t}`
132
- }, Oe = [
132
+ }, ke = [
133
133
  {
134
134
  name: "voltro-schema",
135
135
  description: "Define or change a Voltro database table/schema (columns, mixins, indexes, relations).",
@@ -160,7 +160,7 @@ ${t}`
160
160
  description: "Export/import + backup/restore Voltro data & assets, and copy prod→dev/stage SAFELY with fail-closed masking/anonymization (.sensitive()/.safe()) + referential subsetting. Use for data takeout, seeding lower envs, backups, or cross-dialect moves.",
161
161
  module: "cli.md"
162
162
  }
163
- ], ke = (e, t) => `---
163
+ ], Ae = (e, t) => `---
164
164
  name: ${e.name}
165
165
  description: ${e.description}
166
166
  ---
@@ -171,10 +171,10 @@ Open the full reference and follow the patterns there:
171
171
 
172
172
  Also read the repo-root \`AGENTS.md\` for the always-true rules (browser/server
173
173
  boundary, naming, anti-patterns) before editing.
174
- `, Ae = (e, t, n, r) => b.gen(function* () {
175
- let i = yield* K(e, t);
174
+ `, je = (e, t, n, r) => b.gen(function* () {
175
+ let i = yield* G(e, t);
176
176
  if (i) {
177
- if ((yield* q(e, t)).slice(0, _e).includes("voltro:agents-md:keep")) return {
177
+ if ((yield* K(e, t)).slice(0, ve).includes("voltro:agents-md:keep")) return {
178
178
  path: t,
179
179
  action: "protected"
180
180
  };
@@ -187,67 +187,67 @@ boundary, naming, anti-patterns) before editing.
187
187
  path: t,
188
188
  action: i ? "overwritten" : "created"
189
189
  };
190
- }), je = (e, t = {}) => b.gen(function* () {
191
- let n = yield* v.FileSystem, r = yield* J(e), i = null;
192
- for (let e of W) if (yield* K(n, p(e, "AGENTS.core.md"))) {
190
+ }), Me = (e, t = {}) => b.gen(function* () {
191
+ let n = yield* v.FileSystem, r = yield* q(e), i = null;
192
+ for (let e of U) if (yield* G(n, p(e, "AGENTS.core.md"))) {
193
193
  i = e;
194
194
  break;
195
195
  }
196
196
  if (i === null) {
197
- for (let e of W) if (yield* K(n, p(e, "AGENTS.md"))) {
198
- let i = yield* q(n, p(e, "AGENTS.md")), a = [];
199
- for (let e of G) a.push(yield* Ae(n, p(r, e), i, t.force ?? !1));
197
+ for (let e of U) if (yield* G(n, p(e, "AGENTS.md"))) {
198
+ let i = yield* K(n, p(e, "AGENTS.md")), a = [];
199
+ for (let e of W) a.push(yield* je(n, p(r, e), i, t.force ?? !1));
200
200
  return { files: a };
201
201
  }
202
- return yield* b.fail(he(W.map((e) => p(e, "AGENTS.core.md"))));
202
+ return yield* b.fail(ge(U.map((e) => p(e, "AGENTS.core.md"))));
203
203
  }
204
- let a = yield* q(n, p(i, "AGENTS.core.md")), o = yield* q(n, p(i, "agent-docs", "_manifest.json")), s = o ? JSON.parse(o) : {
204
+ let a = yield* K(n, p(i, "AGENTS.core.md")), o = yield* K(n, p(i, "agent-docs", "_manifest.json")), s = o ? JSON.parse(o) : {
205
205
  modules: [],
206
206
  plugins: []
207
- }, c = (t.preferPointer ?? !1) || (yield* K(n, p(r, "node_modules/@voltro/cli/templates/agent-docs", "_manifest.json"))), l = c ? "node_modules/@voltro/cli/templates/" : "", u = t.force ?? !1, d = G.map((e) => p(r, e));
208
- if ((yield* b.forEach(d, (e) => q(n, e).pipe(b.map((e) => e.slice(0, _e))))).every((e) => e.includes("voltro:agents-md:keep"))) return { files: d.map((e) => ({
207
+ }, c = (t.preferPointer ?? !1) || (yield* G(n, p(r, "node_modules/@voltro/cli/templates/agent-docs", "_manifest.json"))), l = c ? "node_modules/@voltro/cli/templates/" : "", u = t.force ?? !1, d = W.map((e) => p(r, e));
208
+ if ((yield* b.forEach(d, (e) => K(n, e).pipe(b.map((e) => e.slice(0, ve))))).every((e) => e.includes("voltro:agents-md:keep"))) return { files: d.map((e) => ({
209
209
  path: e,
210
210
  action: "protected"
211
211
  })) };
212
- let { apis: f, webs: m } = yield* Ce(n, r), g = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Set(), y = !1;
212
+ let { apis: f, webs: m } = yield* we(n, r), g = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Set(), y = !1;
213
213
  for (let e of f) {
214
- let t = yield* Se(n, e);
214
+ let t = yield* Ce(n, e);
215
215
  if (g.set(e, t), t !== null) {
216
216
  y = !0;
217
217
  for (let e of t) _.add(e);
218
218
  }
219
219
  }
220
- let x = t.plugins ? t.plugins.map(xe).filter((e) => e !== null) : y ? [..._] : null, S = a.includes(ve) ? a.replace(ve, Te(s, x, l)) : a, C = [];
221
- for (let e of d) C.push(yield* Ae(n, e, S, u));
222
- c || (yield* be(n, p(i, "agent-docs"), p(r, "agent-docs")));
220
+ let x = t.plugins ? t.plugins.map(Se).filter((e) => e !== null) : y ? [..._] : null, S = a.includes(ye) ? a.replace(ye, Ee(s, x, l)) : a, C = [];
221
+ for (let e of d) C.push(yield* je(n, e, S, u));
222
+ c || (yield* xe(n, p(i, "agent-docs"), p(r, "agent-docs")));
223
223
  let w = new Map((t.appTemplates ?? []).map((e) => [h(e.dir), e.template])), T = (e) => {
224
224
  let t = w.get(h(e));
225
- return t ? Ee(t, s, l) : "";
226
- }, E = (e, t) => b.forEach(G, (r) => Ae(n, p(e, r), t, u));
227
- for (let e of f) C.push(...yield* E(e, De.api(l, g.get(e) ?? null, T(e)))), (yield* K(n, p(e, "database"))) && C.push(...yield* E(p(e, "database"), De.database(l)));
228
- for (let e of m) C.push(...yield* E(e, De.web(l, T(e))));
229
- for (let e of Oe) C.push(yield* Ae(n, p(r, ".claude", "skills", e.name, "SKILL.md"), ke(e, l), u));
225
+ return t ? De(t, s, l) : "";
226
+ }, E = (e, t) => b.forEach(W, (r) => je(n, p(e, r), t, u));
227
+ for (let e of f) C.push(...yield* E(e, Oe.api(l, g.get(e) ?? null, T(e)))), (yield* G(n, p(e, "database"))) && C.push(...yield* E(p(e, "database"), Oe.database(l)));
228
+ for (let e of m) C.push(...yield* E(e, Oe.web(l, T(e))));
229
+ for (let e of ke) C.push(yield* je(n, p(r, ".claude", "skills", e.name, "SKILL.md"), Ae(e, l), u));
230
230
  return { files: C };
231
- }), Me = (e, t = {}) => b.runPromise(je(e, t).pipe(b.provide(y.layer))), Ne = async (t) => {
231
+ }), Ne = (e, t = {}) => b.runPromise(Me(e, t).pipe(b.provide(y.layer))), Pe = async (t) => {
232
232
  let n = t.includes("--force"), r = t.find((e) => !e.startsWith("-")) ?? process.cwd();
233
233
  return e(b.gen(function* () {
234
- let e = yield* je(r, { force: n });
234
+ let e = yield* Me(r, { force: n });
235
235
  for (let t of e.files) {
236
- let e = t.action === "created" ? "wrote" : t.action === "overwritten" ? "overwrote" : t.action === "protected" ? `protected (hand-maintained — has "${ge}")` : "present (use --force to overwrite)";
236
+ let e = t.action === "created" ? "wrote" : t.action === "overwritten" ? "overwrote" : t.action === "protected" ? `protected (hand-maintained — has "${_e}")` : "present (use --force to overwrite)";
237
237
  yield* b.logInfo(`${t.path.split("/").slice(-2).join("/")} ${e}`, { action: t.action });
238
238
  }
239
239
  return 0;
240
240
  }).pipe(b.catchTag("TemplateNotFoundError", (e) => b.gen(function* () {
241
241
  return yield* b.logError("AGENTS.md template not found", { searched: e.searched }), 1;
242
242
  }))), { scope: "voltro:agents-md" });
243
- }, Pe = p(F(), ".voltro"), Fe = p(Pe, "runtime-registry.json"), Ie = 3e4, Le = () => {
243
+ }, Fe = p(L(), ".voltro"), Ie = p(Fe, "runtime-registry.json"), Le = 3e4, Re = () => {
244
244
  let e = Math.random().toString(36).slice(2, 10);
245
- return `${Fe}.${process.pid}.${Date.now()}.${e}.tmp`;
246
- }, Re = async () => {
247
- await O.mkdir(Pe, { recursive: !0 });
245
+ return `${Ie}.${process.pid}.${Date.now()}.${e}.tmp`;
248
246
  }, ze = async () => {
247
+ await O.mkdir(Fe, { recursive: !0 });
248
+ }, Be = async () => {
249
249
  try {
250
- let e = await O.readFile(Fe, "utf8"), t = JSON.parse(e);
250
+ let e = await O.readFile(Ie, "utf8"), t = JSON.parse(e);
251
251
  return t.version !== 1 || !Array.isArray(t.apps) ? {
252
252
  version: 1,
253
253
  apps: []
@@ -258,34 +258,34 @@ boundary, naming, anti-patterns) before editing.
258
258
  apps: []
259
259
  };
260
260
  }
261
- }, Be = async (e) => {
262
- await Re();
263
- let t = Le();
261
+ }, Ve = async (e) => {
262
+ await ze();
263
+ let t = Re();
264
264
  try {
265
265
  await O.writeFile(t, JSON.stringify(e, null, 2), {
266
266
  encoding: "utf8",
267
267
  mode: 384
268
- }), await O.rename(t, Fe), await O.chmod(Fe, 384).catch(() => {});
268
+ }), await O.rename(t, Ie), await O.chmod(Ie, 384).catch(() => {});
269
269
  } catch (e) {
270
270
  try {
271
271
  await O.unlink(t);
272
272
  } catch {}
273
273
  throw e;
274
274
  }
275
- }, Ve = (e) => {
275
+ }, He = (e) => {
276
276
  try {
277
277
  return process.kill(e, 0), !0;
278
278
  } catch {
279
279
  return !1;
280
280
  }
281
- }, He = (e) => {
281
+ }, Ue = (e) => {
282
282
  let t = Date.now();
283
- return e.filter((e) => Ve(e.pid) ? t - new Date(e.heartbeatAt).getTime() < Ie : !1);
284
- }, Ue = async () => {
285
- let e = await ze(), t = He(e.apps);
283
+ return e.filter((e) => He(e.pid) ? t - new Date(e.heartbeatAt).getTime() < Le : !1);
284
+ }, We = async () => {
285
+ let e = await Be(), t = Ue(e.apps);
286
286
  if (t.length === e.apps.length) return e;
287
287
  try {
288
- await Be({
288
+ await Ve({
289
289
  version: 1,
290
290
  apps: t
291
291
  });
@@ -294,31 +294,31 @@ boundary, naming, anti-patterns) before editing.
294
294
  version: 1,
295
295
  apps: t
296
296
  };
297
- }, We = async (e) => {
298
- let t = await ze(), n = (/* @__PURE__ */ new Date()).toISOString(), r = t.apps.findIndex((t) => t.id === e.id), i = e.inspectToken ?? process.env.VOLTRO_INSPECT_TOKEN, a = {
297
+ }, Ge = async (e) => {
298
+ let t = await Be(), n = (/* @__PURE__ */ new Date()).toISOString(), r = t.apps.findIndex((t) => t.id === e.id), i = e.inspectToken ?? process.env.VOLTRO_INSPECT_TOKEN, a = {
299
299
  ...e,
300
300
  ...i !== void 0 && i !== "" ? { inspectToken: i } : {},
301
301
  registeredAt: r >= 0 ? t.apps[r].registeredAt : n,
302
302
  heartbeatAt: n
303
303
  };
304
- await Be({
304
+ await Ve({
305
305
  version: 1,
306
306
  apps: r >= 0 ? t.apps.map((e, t) => t === r ? a : e) : [...t.apps, a]
307
307
  });
308
- }, Ge = async (e) => {
308
+ }, Ke = async (e) => {
309
309
  try {
310
- let t = await ze(), n = t.apps.filter((t) => t.id !== e);
310
+ let t = await Be(), n = t.apps.filter((t) => t.id !== e);
311
311
  if (n.length === t.apps.length) return;
312
- await Be({
312
+ await Ve({
313
313
  version: 1,
314
314
  apps: n
315
315
  });
316
316
  } catch {}
317
- }, Ke = (e, t, n) => `${e}:${t}:${n}`, qe = (e) => e.replace(/\\"|"(?:[^"\\]|\\.)*"|(\/\/[^\n]*|\/\*[\s\S]*?\*\/)/g, (e, t) => t ? "" : e), Je = (e) => {
317
+ }, qe = (e, t, n) => `${e}:${t}:${n}`, Je = (e) => e.replace(/\\"|"(?:[^"\\]|\\.)*"|(\/\/[^\n]*|\/\*[\s\S]*?\*\/)/g, (e, t) => t ? "" : e), Ye = (e) => {
318
318
  try {
319
319
  let t = p(e, "tsconfig.json");
320
320
  if (!T(t)) return [];
321
- let n = JSON.parse(qe(ee(t, "utf8"))).compilerOptions ?? {}, r = n.paths ?? {}, i = h(e, n.baseUrl ?? "."), a = [];
321
+ let n = JSON.parse(Je(k(t, "utf8"))).compilerOptions ?? {}, r = n.paths ?? {}, i = h(e, n.baseUrl ?? "."), a = [];
322
322
  for (let [e, t] of Object.entries(r)) {
323
323
  let n = t[0];
324
324
  if (!n) continue;
@@ -338,17 +338,17 @@ boundary, naming, anti-patterns) before editing.
338
338
  } catch {
339
339
  return [];
340
340
  }
341
- }, Ye = (e) => {
341
+ }, Xe = (e) => {
342
342
  let t = e;
343
343
  return t?.code === "ERR_MODULE_NOT_FOUND" || /Cannot find (package|module)/.test(String(t?.message ?? ""));
344
- }, Xe = async (e, t) => {
344
+ }, Ze = async (e, t) => {
345
345
  try {
346
346
  return await t();
347
347
  } catch (t) {
348
- throw Ye(t) ? Error(`voltro: the build tool '${e}' is not installed.\n\nIt's an OPTIONAL dependency of @voltro/cli — needed by 'voltro dev' and 'voltro build', but excluded from a serve-only production install (that's how prod images stay lean). If you are building, reinstall WITHOUT '--no-optional' (e.g. 'pnpm install'). A production SERVE container does not need '${e}' — it boots from the precompiled bundle.`) : t;
348
+ throw Xe(t) ? Error(`voltro: the build tool '${e}' is not installed.\n\nIt's an OPTIONAL dependency of @voltro/cli — needed by 'voltro dev' and 'voltro build', but excluded from a serve-only production install (that's how prod images stay lean). If you are building, reinstall WITHOUT '--no-optional' (e.g. 'pnpm install'). A production SERVE container does not need '${e}' — it boots from the precompiled bundle.`) : t;
349
349
  }
350
- }, Ze = "// AUTO-GENERATED by Voltro — DO NOT EDIT.\n// Source: app.config.ts `env` (defineEnv). Regenerated on every `voltro dev` boot.\n", Qe = (e, t) => t ? `${e} | undefined` : e, $e = (e, t) => Object.entries(e.vars).filter(([, e]) => t(e.access)).map(([e, t]) => `${t.description ? ` /** ${t.description} */\n` : ""} readonly ${e}: ${Qe(t.tsType, t.optional)}`).join("\n"), et = async (e, t) => {
351
- let n = $e(t, () => !0), r = `${Ze}
350
+ }, Qe = "// AUTO-GENERATED by Voltro — DO NOT EDIT.\n// Source: app.config.ts `env` (defineEnv). Regenerated on every `voltro dev` boot.\n", $e = (e, t) => t ? `${e} | undefined` : e, et = (e, t) => Object.entries(e.vars).filter(([, e]) => t(e.access)).map(([e, t]) => `${t.description ? ` /** ${t.description} */\n` : ""} readonly ${e}: ${$e(t.tsType, t.optional)}`).join("\n"), tt = async (e, t) => {
351
+ let n = et(t, () => !0), r = `${Qe}
352
352
  import '@voltro/env/server'
353
353
 
354
354
  declare module '@voltro/env/server' {
@@ -358,8 +358,8 @@ ${n.length > 0 ? n : " // (no variables declared)"}
358
358
  }
359
359
  `;
360
360
  await ue(p(e, "env.generated.d.ts"), r, "utf8");
361
- }, tt = async (e, t) => {
362
- let n = $e(t, (e) => e === "public"), r = `${Ze}
361
+ }, nt = async (e, t) => {
362
+ let n = et(t, (e) => e === "public"), r = `${Qe}
363
363
  import '@voltro/env/public'
364
364
 
365
365
  declare module '@voltro/env/public' {
@@ -369,8 +369,8 @@ ${n.length > 0 ? n : " // (no public variables declared)"}
369
369
  }
370
370
  `, i = p(e, "src");
371
371
  await H(i, { recursive: !0 }), await ue(p(i, "voltro-env.d.ts"), r, "utf8");
372
- }, nt = async (e, t) => {
373
- let n = `${Ze}
372
+ }, rt = async (e, t) => {
373
+ let n = `${Qe}
374
374
  import { __installPublicEnv } from '@voltro/env/public'
375
375
 
376
376
  export const publicEnvValues = ${JSON.stringify(t, null, 2)} as const
@@ -379,13 +379,13 @@ export const publicEnvValues = ${JSON.stringify(t, null, 2)} as const
379
379
  __installPublicEnv(publicEnvValues)
380
380
  `;
381
381
  await H(e, { recursive: !0 }), await ue(p(e, "env.public.ts"), n, "utf8");
382
- }, rt = async (e) => {
383
- let t = B(e.rawEnv) ? e.rawEnv : void 0, n = await se({
382
+ }, it = async (e) => {
383
+ let t = ae(e.rawEnv) ? e.rawEnv : void 0, n = await se({
384
384
  contract: t,
385
- resolveSecret: P
386
- }), r = [...n.errors, ...R(t, e.appType)];
387
- if (r.length > 0) throw Error(z(r));
388
- ae(n.values), e.appType === "web" && ce(n.publicValues);
385
+ resolveSecret: te
386
+ }), r = [...n.errors, ...z(t, e.appType)];
387
+ if (r.length > 0) throw Error(ie(r));
388
+ B(n.values), e.appType === "web" && ce(n.publicValues);
389
389
  let i = t ? Object.keys(t.vars).length : 0;
390
390
  if (i > 0) {
391
391
  let r = Object.keys(n.publicValues).length;
@@ -397,20 +397,20 @@ __installPublicEnv(publicEnvValues)
397
397
  n.length > 0 && e.log.warn(`env: ${n.length} secret var(s) declared on a web app — secrets are reachable only from server-side render code and are NEVER bundled. Prefer declaring secrets on the api.`, { keys: n });
398
398
  }
399
399
  }
400
- return e.generateTypes && t && (e.appType === "api" ? await et(e.root, t) : await tt(e.root, t)), {
400
+ return e.generateTypes && t && (e.appType === "api" ? await tt(e.root, t) : await nt(e.root, t)), {
401
401
  resolved: n,
402
402
  contract: t
403
403
  };
404
- }, it = (e) => {
405
- let t = L(e.contract), n = (e.plugins ?? []).flatMap((e) => oe(e.name, e.declaredEnv)), r = e.includeFramework === !1 ? [] : ie, i = /* @__PURE__ */ new Set(), a = [];
404
+ }, at = (e) => {
405
+ let t = re(e.contract), n = (e.plugins ?? []).flatMap((e) => V(e.name, e.declaredEnv)), r = e.includeFramework === !1 ? [] : ne, i = /* @__PURE__ */ new Set(), a = [];
406
406
  for (let e of [
407
407
  ...t,
408
408
  ...n,
409
409
  ...r
410
410
  ]) i.has(e.key) || (i.add(e.key), a.push(e));
411
411
  return a;
412
- }, at = (e, t, n = (e) => process.env[e]) => {
413
- let r = it(t).map((e) => {
412
+ }, ot = (e, t, n = (e) => process.env[e]) => {
413
+ let r = at(t).map((e) => {
414
414
  let t = n(e.key) !== void 0;
415
415
  return {
416
416
  ...e,
@@ -427,13 +427,13 @@ __installPublicEnv(publicEnvValues)
427
427
  missingRequired: r.filter((e) => e.required && !e.isSet && e.default === void 0).length
428
428
  }
429
429
  };
430
- }, ot = (e, t) => V(it({
430
+ }, st = (e, t) => oe(at({
431
431
  ...e,
432
432
  includeFramework: !1
433
433
  }), {
434
434
  includeFramework: e.includeFramework !== !1,
435
435
  ...t ? { header: t } : {}
436
- }), st = () => {
436
+ }), ct = () => {
437
437
  let e = /* @__PURE__ */ new Map();
438
438
  return {
439
439
  get(t) {
@@ -460,7 +460,7 @@ __installPublicEnv(publicEnvValues)
460
460
  return Array.from(e.entries());
461
461
  }
462
462
  };
463
- }, ct = (e) => {
463
+ }, lt = (e) => {
464
464
  if (typeof e == "number" && Number.isFinite(e) && e > 0) return e * 1e3;
465
465
  if (typeof e != "string") return null;
466
466
  let t = /^\s*(\d+)\s*(s|seconds?|m|minutes?|h|hours?|d|days?)\s*$/i.exec(e);
@@ -469,20 +469,20 @@ __installPublicEnv(publicEnvValues)
469
469
  if (!Number.isFinite(n) || n <= 0) return null;
470
470
  let r = t[2].toLowerCase();
471
471
  return r === "s" || r.startsWith("second") ? n * 1e3 : r === "m" || r.startsWith("minute") ? n * 6e4 : r === "h" || r.startsWith("hour") ? n * 36e5 : r === "d" || r.startsWith("day") ? n * 864e5 : null;
472
- }, lt = (e, t = {}) => {
472
+ }, ut = (e, t = {}) => {
473
473
  let n = [e];
474
474
  return t.tenant !== void 0 && t.tenant !== "" && n.push(`tenant=${t.tenant}`), t.locale !== void 0 && t.locale !== "" && n.push(`lang=${t.locale}`), n.join("|");
475
- }, ut = (e, t) => e.expiresAt > t, dt = (e, t) => e.expiresAt <= t && e.servableUntil > t, ft = S({ scope: "voltro:cli" }), pt = (e, t) => {
475
+ }, dt = (e, t) => e.expiresAt > t, ft = (e, t) => e.expiresAt <= t && e.servableUntil > t, pt = S({ scope: "voltro:cli" }), mt = (e, t) => {
476
476
  if (t?.code !== "EACCES") return "";
477
477
  if (typeof process.getuid != "function") return " — permission denied";
478
478
  try {
479
- let t = A(e);
479
+ let t = j(e);
480
480
  return ` — permission denied: the file is owned by uid ${t.uid} (mode ${(t.mode & 511).toString(8)}) and this process is uid ${process.getuid()}. A container running as root with the workspace bind-mounted writes files the host user cannot read; run it as \`--user <your-uid>:<your-gid>\`, or delete the file and let the owning user recreate it.`;
481
481
  } catch {
482
482
  return " — permission denied (and the file could not be stat-ed either)";
483
483
  }
484
- }, mt = [], ht = (e) => {
485
- mt.length = 0;
484
+ }, ht = [], gt = (e) => {
485
+ ht.length = 0;
486
486
  let t = e[1] && !e[1].startsWith("-") ? e[1] : void 0, n = t ? f(t) ? t : h(process.cwd(), t) : process.cwd(), r = [], i = n;
487
487
  for (;;) {
488
488
  r.push(i);
@@ -493,9 +493,9 @@ __installPublicEnv(publicEnvValues)
493
493
  for (let e of r) for (let t of [".env.local", ".env"]) {
494
494
  let n = h(e, t);
495
495
  if (T(n)) {
496
- mt.push(n);
496
+ ht.push(n);
497
497
  try {
498
- let e = ee(n, "utf8");
498
+ let e = k(n, "utf8");
499
499
  for (let t of e.split(/\r?\n/)) {
500
500
  let e = t.trim();
501
501
  if (e === "" || e.startsWith("#")) continue;
@@ -505,11 +505,11 @@ __installPublicEnv(publicEnvValues)
505
505
  (i.startsWith("\"") && i.endsWith("\"") || i.startsWith("'") && i.endsWith("'")) && (i = i.slice(1, -1)), process.env[r] === void 0 && (process.env[r] = i);
506
506
  }
507
507
  } catch (e) {
508
- ft.warn(`failed to load env file (continuing)${pt(n, e)}`, { path: n }, e);
508
+ pt.warn(`failed to load env file (continuing)${mt(n, e)}`, { path: n }, e);
509
509
  }
510
510
  }
511
511
  }
512
- }, gt = 500, _t = (e, t, n = {}) => {
512
+ }, _t = 500, vt = (e, t, n = {}) => {
513
513
  if (e.length === 0) return () => {};
514
514
  let r = (e) => n.root ? m(n.root, e) : e, i = !1, a = (e) => {
515
515
  i || (i = !0, t.warn(`.env changed (${r(e)}) — hard-restarting: process.env is read once at boot, a reload would keep stale values`, { file: r(e) }), Promise.resolve().then(() => n.onBeforeRestart?.()).catch((e) => t.warn(".env restart: onBeforeRestart failed (continuing)", {}, e)).finally(() => {
@@ -527,62 +527,294 @@ __installPublicEnv(publicEnvValues)
527
527
  });
528
528
  }));
529
529
  };
530
- for (let t of e) ne(t, { interval: gt }, (e, n) => {
530
+ for (let t of e) ee(t, { interval: _t }, (e, n) => {
531
531
  e.mtimeMs !== n.mtimeMs && a(t);
532
532
  });
533
533
  return t.info("watching .env files for changes", {
534
534
  files: e.map(r),
535
- intervalMs: gt
535
+ intervalMs: _t
536
536
  }), () => {
537
- for (let t of e) te(t);
537
+ for (let t of e) N(t);
538
+ };
539
+ }, yt = "VoltroBootRefusal", bt = (e) => {
540
+ let t = Error(e);
541
+ return t.name = yt, t;
542
+ }, xt = [{
543
+ host: "127.0.0.1",
544
+ family: "IPv4"
545
+ }, {
546
+ host: "::1",
547
+ family: "IPv6"
548
+ }], St = (e, t, n) => new Promise((r) => {
549
+ let i = !1, a = (e) => {
550
+ if (!i) {
551
+ i = !0;
552
+ try {
553
+ o.destroy();
554
+ } catch {}
555
+ r(e);
556
+ }
557
+ }, o = pe({
558
+ host: e,
559
+ port: t
560
+ });
561
+ o.once("connect", () => a(!0)), o.once("error", () => a(!1)), o.setTimeout(n, () => a(!1));
562
+ }), Ct = async (e, t = 400) => ({ families: (await Promise.all(xt.map(async (n) => ({
563
+ family: n.family,
564
+ taken: await St(n.host, e, t)
565
+ })))).filter((e) => e.taken).map((e) => e.family) }), wt = (e, t, n) => [
566
+ `${t}: port ${e} is already being served (${n.join(" + ")}).`,
567
+ "",
568
+ " Refusing to start. This is NOT a spurious check — a second listener can",
569
+ " bind the SAME port on the other IP stack, so the boot would report",
570
+ ` "listening on http://localhost:${e}" and "ready", while every request`,
571
+ " went to the process that is already there. Your edits would have no",
572
+ " effect and nothing would say so.",
573
+ "",
574
+ " Find it and stop it:",
575
+ "",
576
+ ` lsof -nP -iTCP:${e} -sTCP:LISTEN`,
577
+ "",
578
+ " Then re-run. To use a different port instead, change `port` in",
579
+ " app.config.ts."
580
+ ].join("\n"), Tt = async (e, t) => {
581
+ let { families: n } = await Ct(e);
582
+ if (n.length !== 0) throw bt(wt(e, t, n));
583
+ }, Et = (e) => e === "effect" || e.startsWith("@effect/") || e.startsWith("@voltro/") || e === "react" || e === "react-dom", Dt = /(^|\/)(\.bin|\.cache|\.pnpm-store|dist|build)(\/|$)/, Ot = (e) => {
584
+ let t = [], n = e;
585
+ for (let e = 0; e < 12; e++) {
586
+ let e = p(n, "node_modules");
587
+ T(e) && t.push(e);
588
+ let r = d(n);
589
+ if (r === n) break;
590
+ n = r;
591
+ }
592
+ return t;
593
+ }, kt = (e) => {
594
+ let t = /* @__PURE__ */ new Set([e]), n = e;
595
+ for (let e = 0; e < 12; e++) {
596
+ for (let e of ["pnpm-workspace.yaml", "pnpm-workspace.yml"]) {
597
+ let r;
598
+ try {
599
+ r = k(p(n, e), "utf8");
600
+ } catch {
601
+ continue;
602
+ }
603
+ for (let e of r.matchAll(/^\s*-\s*['"]?([^'"\n#]+?)['"]?\s*$/gm)) {
604
+ let r = (e[1] ?? "").trim();
605
+ if (r === "" || r.startsWith("!")) continue;
606
+ let i = r.split("/")[0] ?? "";
607
+ if (i === "" || i.includes("*")) continue;
608
+ let a;
609
+ try {
610
+ a = A(p(n, i), { withFileTypes: !0 });
611
+ } catch {
612
+ continue;
613
+ }
614
+ for (let e of a) e.isDirectory() && t.add(p(n, i, e.name));
615
+ }
616
+ }
617
+ for (let e of ["packages", "apps"]) {
618
+ let r;
619
+ try {
620
+ r = A(p(n, e), { withFileTypes: !0 });
621
+ } catch {
622
+ continue;
623
+ }
624
+ for (let i of r) i.isDirectory() && t.add(p(n, e, i.name));
625
+ }
626
+ let e = d(n);
627
+ if (e === n) break;
628
+ n = e;
629
+ }
630
+ return [...t];
631
+ }, At = (e) => {
632
+ let t = [];
633
+ for (let n of kt(e)) {
634
+ let e = p(n, "node_modules", "@voltro"), r;
635
+ try {
636
+ r = A(e);
637
+ } catch {
638
+ continue;
639
+ }
640
+ for (let n of r) {
641
+ let r = p(e, n), i = jt(r);
642
+ i !== void 0 && t.push({
643
+ pkg: `@voltro/${n}`,
644
+ version: i,
645
+ dir: r
646
+ });
647
+ }
648
+ }
649
+ return t;
650
+ }, jt = (e) => {
651
+ try {
652
+ let t = JSON.parse(k(p(e, "package.json"), "utf8"));
653
+ return typeof t.version == "string" ? t.version : void 0;
654
+ } catch {
655
+ return;
656
+ }
657
+ }, Mt = (e) => {
658
+ let t = [], n;
659
+ try {
660
+ n = A(e);
661
+ } catch {
662
+ return t;
663
+ }
664
+ for (let r of n) {
665
+ if (r.startsWith(".") || Dt.test(r)) continue;
666
+ let n = p(e, r);
667
+ if (r.startsWith("@")) {
668
+ let e;
669
+ try {
670
+ e = A(n);
671
+ } catch {
672
+ continue;
673
+ }
674
+ for (let i of e) t.push({
675
+ pkg: `${r}/${i}`,
676
+ dir: p(n, i)
677
+ });
678
+ continue;
679
+ }
680
+ try {
681
+ if (!j(n).isDirectory()) continue;
682
+ } catch {
683
+ continue;
684
+ }
685
+ t.push({
686
+ pkg: r,
687
+ dir: n
688
+ });
689
+ }
690
+ return t;
691
+ }, Nt = (e) => {
692
+ let t = /* @__PURE__ */ new Map(), n = (e, n, r) => {
693
+ if (!Et(e)) return;
694
+ let i = t.get(e) ?? /* @__PURE__ */ new Map();
695
+ i.has(n) || i.set(n, r), t.set(e, i);
538
696
  };
539
- }, vt = S({ scope: "vite" }), yt = /\x1b\[[0-9;]*m/g, bt = /^\s*\[?vite\]?\s*(\([a-z-]+\)\s*)?/, xt = (e) => e.replace(yt, "").replace(bt, "").trim(), St = /proxy error/i, Ct = [
697
+ for (let t of Ot(e)) for (let { pkg: e, dir: r } of Mt(t)) {
698
+ let t = jt(r);
699
+ t !== void 0 && n(e, t, r);
700
+ }
701
+ for (let { pkg: t, version: r, dir: i } of At(e)) n(t, r, i);
702
+ let r = [];
703
+ for (let [n, i] of t) i.size < 2 || r.push({
704
+ pkg: n,
705
+ versions: [...i.keys()].sort(),
706
+ paths: [...i.values()].map((t) => m(e, t)).sort()
707
+ });
708
+ return r.sort((e, t) => e.pkg.localeCompare(t.pkg));
709
+ }, Pt = (e) => {
710
+ if (e.length !== 0) return [
711
+ `• ${e.length} package(s) resolved at more than one version:`,
712
+ ...e.flatMap((e) => [` ${e.pkg} — ${e.versions.join(", ")}`, ...e.paths.map((e) => ` ${e}`)]),
713
+ "",
714
+ " Two copies of `effect` (or `@effect/*`) is the usual cause of type errors",
715
+ " inside the GENERATED rpcGroup.generated.ts that look like framework bugs:",
716
+ " \"Property '[TypeId]' is missing\", \"typeof Never is not assignable to All\",",
717
+ " or an `Rpc<…, Stream<…>, …>` that will not go where `Any` is expected.",
718
+ " Effect types are nominal, so a Schema built by one copy is not the same",
719
+ " type as a Schema expected by the other — and the RUNTIME often still works,",
720
+ " which is why this shows up as a red tsc against a green server.",
721
+ "",
722
+ " Fix it in the install, not the code: align the version across the workspace",
723
+ " (a root `pnpm.overrides` / `resolutions` entry for `effect` is the blunt",
724
+ " instrument), then reinstall. Do not silence the generated file — it is where",
725
+ " a genuine mistake in your own descriptors surfaces."
726
+ ].join("\n");
727
+ }, Ft = (e) => {
728
+ let t = /* @__PURE__ */ new Map();
729
+ for (let n of Ot(e)) for (let { pkg: e, dir: r } of Mt(n)) {
730
+ if (!e.startsWith("@voltro/")) continue;
731
+ let n = jt(r);
732
+ n !== void 0 && !t.has(e) && t.set(e, n);
733
+ }
734
+ if (t.size < 2) return;
735
+ let n = /* @__PURE__ */ new Map();
736
+ for (let e of t.values()) n.set(e, (n.get(e) ?? 0) + 1);
737
+ if (n.size < 2) return;
738
+ let r = [...n.entries()].sort((e, t) => t[1] - e[1] || e[0].localeCompare(t[0]) * -1)[0][0];
739
+ return {
740
+ majority: r,
741
+ behind: [...t.entries()].filter(([, e]) => e !== r).map(([e, t]) => ({
742
+ pkg: e,
743
+ version: t
744
+ })).sort((e, t) => e.pkg.localeCompare(t.pkg))
745
+ };
746
+ }, It = (e) => {
747
+ if (e !== void 0) return [
748
+ `• ${e.behind.length} @voltro/* package(s) are not on ${e.majority}:`,
749
+ ...e.behind.map((e) => ` ${e.pkg} ${e.version}`),
750
+ "",
751
+ " The framework ships in LOCKSTEP — every @voltro/* package carries the",
752
+ " same version at release — so this combination was never built or tested",
753
+ " as a set. It is not a judgement about whether they are compatible.",
754
+ "",
755
+ " Nothing else will tell you. A consumer carried a package two releases",
756
+ " behind through `tsc`, 19 317 tests, `voltro doctor` exit 0 in four apps",
757
+ " and three production builds, all green. None of those checks is ABOUT",
758
+ " version agreement.",
759
+ "",
760
+ " Bump the listed packages and reinstall. If you bump with a script, check",
761
+ " its pattern: the one that produced this report was `@voltro/[a-z-]+`,",
762
+ " which silently skips `@voltro/i18n` because the name contains digits."
763
+ ].join("\n");
764
+ }, Lt = (e, t) => {
765
+ let n = Ft(e);
766
+ n !== void 0 && t.warn?.(`@voltro/* version skew: ${n.behind.length} package(s) are not on ${n.majority}`, {
767
+ majority: n.majority,
768
+ behind: n.behind.map((e) => `${e.pkg}@${e.version}`),
769
+ fix: "the framework ships in lockstep; bump the listed packages and reinstall"
770
+ });
771
+ }, Rt = S({ scope: "vite" }), zt = /\x1b\[[0-9;]*m/g, Bt = /^\s*\[?vite\]?\s*(\([a-z-]+\)\s*)?/, Vt = (e) => e.replace(zt, "").replace(Bt, "").trim(), Ht = /proxy error/i, Ut = [
540
772
  "ECONNREFUSED",
541
773
  "ECONNRESET",
542
774
  "ECONNABORTED",
543
775
  "EPIPE",
544
776
  "ETIMEDOUT"
545
- ], wt = (e, t = 0) => {
777
+ ], Wt = (e, t = 0) => {
546
778
  if (e == null || t > 5) return !1;
547
779
  let n = e;
548
- return typeof n.code == "string" && Ct.includes(n.code) || typeof n.message == "string" && Ct.some((e) => n.message.includes(e)) || Array.isArray(n.errors) && n.errors.some((e) => wt(e, t + 1)) ? !0 : wt(n.cause, t + 1);
549
- }, Tt = 4e3, Et = () => {
780
+ return typeof n.code == "string" && Ut.includes(n.code) || typeof n.message == "string" && Ut.some((e) => n.message.includes(e)) || Array.isArray(n.errors) && n.errors.some((e) => Wt(e, t + 1)) ? !0 : Wt(n.cause, t + 1);
781
+ }, Gt = 4e3, Kt = () => {
550
782
  let e = /* @__PURE__ */ new Set(), t = 0, n = {
551
783
  hasWarned: !1,
552
784
  info: (e) => {
553
- let t = xt(e);
554
- t.length !== 0 && vt.info(t);
785
+ let t = Vt(e);
786
+ t.length !== 0 && Rt.info(t);
555
787
  },
556
788
  warn: (e) => {
557
789
  n.hasWarned = !0;
558
- let t = xt(e);
559
- t.length !== 0 && vt.warn(t);
790
+ let t = Vt(e);
791
+ t.length !== 0 && Rt.warn(t);
560
792
  },
561
793
  warnOnce: (t) => {
562
- let r = xt(t);
563
- e.has(r) || (e.add(r), n.hasWarned = !0, r.length !== 0 && vt.warn(r));
794
+ let r = Vt(t);
795
+ e.has(r) || (e.add(r), n.hasWarned = !0, r.length !== 0 && Rt.warn(r));
564
796
  },
565
797
  error: (e, n) => {
566
- let r = xt(e), i = n?.error;
798
+ let r = Vt(e), i = n?.error;
567
799
  if (r.length !== 0) {
568
- if (St.test(r) && wt(i)) {
800
+ if (Ht.test(r) && Wt(i)) {
569
801
  let e = Date.now();
570
- e - t > Tt && (t = e, vt.info("waiting for api — proxy upstream not accepting connections yet (still starting?)"));
802
+ e - t > Gt && (t = e, Rt.info("waiting for api — proxy upstream not accepting connections yet (still starting?)"));
571
803
  return;
572
804
  }
573
- vt.error(r, {}, i);
805
+ Rt.error(r, {}, i);
574
806
  }
575
807
  },
576
808
  clearScreen: () => {},
577
809
  hasErrorLogged: (e) => !1
578
810
  };
579
811
  return n;
580
- }, Dt = (e = process.env) => {
812
+ }, qt = (e = process.env) => {
581
813
  let t = e.VOLTRO_DEV_SSR_COMPILE_CONCURRENCY;
582
814
  if (t === void 0 || t.trim() === "") return 4;
583
815
  let n = Number(t);
584
816
  return Number.isFinite(n) && n >= 1 ? Math.floor(n) : 4;
585
- }, Ot = (e) => {
817
+ }, Jt = (e) => {
586
818
  let t = Math.max(1, Math.floor(e)), n = 0, r = [], i = () => n < t ? (n++, Promise.resolve()) : new Promise((e) => r.push(e)), a = () => {
587
819
  let e = r.shift();
588
820
  e ? e() : n--;
@@ -600,8 +832,8 @@ __installPublicEnv(publicEnvValues)
600
832
  return n;
601
833
  }
602
834
  };
603
- }, kt = (e) => {
604
- let t = Ot(e.limit), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set();
835
+ }, Yt = (e) => {
836
+ let t = Jt(e.limit), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set();
605
837
  return {
606
838
  load: (i, a) => {
607
839
  if (r.has(i)) return a();
@@ -631,7 +863,7 @@ __installPublicEnv(publicEnvValues)
631
863
  return r.size;
632
864
  }
633
865
  };
634
- }, At = (e) => {
866
+ }, Xt = (e) => {
635
867
  let t = [];
636
868
  for (let n of e.split("/").filter(Boolean)) n.startsWith("[[...") && n.endsWith("]]") ? t.push({
637
869
  name: n.slice(5, -2),
@@ -647,7 +879,7 @@ __installPublicEnv(publicEnvValues)
647
879
  optional: !1
648
880
  });
649
881
  return t;
650
- }, jt = (e) => e.replace(/-([a-z0-9])/g, (e, t) => t.toUpperCase()), Mt = async (e) => {
882
+ }, Zt = (e) => e.replace(/-([a-z0-9])/g, (e, t) => t.toUpperCase()), Qt = async (e) => {
651
883
  let t = h(e);
652
884
  for (let e = 0; e < 4; e++) {
653
885
  let e = p(t, "project.json");
@@ -665,8 +897,8 @@ __installPublicEnv(publicEnvValues)
665
897
  t = n;
666
898
  }
667
899
  return null;
668
- }, Nt = async (e) => {
669
- let t = await Mt(e);
900
+ }, $t = async (e) => {
901
+ let t = await Qt(e);
670
902
  if (!t) return [];
671
903
  let { projectDir: n, manifest: r } = t, i = u(e), a = r.apps ?? {}, o = [];
672
904
  for (let [e, t] of Object.entries(a)) {
@@ -675,23 +907,23 @@ __installPublicEnv(publicEnvValues)
675
907
  if (!T(r)) continue;
676
908
  let a;
677
909
  try {
678
- let { pages: e } = await $(r);
910
+ let { pages: e } = await Q(r);
679
911
  a = e.map((e) => ({
680
912
  pattern: e.pattern,
681
- params: At(e.pattern)
913
+ params: Xt(e.pattern)
682
914
  }));
683
915
  } catch {
684
916
  continue;
685
917
  }
686
918
  o.push({
687
- key: jt(e),
919
+ key: Zt(e),
688
920
  origin: `http://localhost:${t.port}`,
689
921
  ...typeof t.origin == "string" && t.origin.length > 0 ? { prodOrigin: t.origin } : {},
690
922
  routes: a
691
923
  });
692
924
  }
693
925
  return o;
694
- }, Pt = (e) => {
926
+ }, en = (e) => {
695
927
  if (e.params.length === 0) return `'${e.pattern}'`;
696
928
  let t = e.pattern;
697
929
  for (let n of e.params) {
@@ -699,21 +931,21 @@ __installPublicEnv(publicEnvValues)
699
931
  t = t.replace(e, r);
700
932
  }
701
933
  return "`" + t + "`";
702
- }, Ft = (e) => e.params.length === 0 ? "EmptyParams" : `{ ${e.params.map((e) => {
934
+ }, tn = (e) => e.params.length === 0 ? "EmptyParams" : `{ ${e.params.map((e) => {
703
935
  let t = "string";
704
936
  return e.optional ? `readonly ${e.name}?: ${t}` : `readonly ${e.name}: ${t}`;
705
- }).join("; ")} }`, It = (e, t, n) => {
706
- let r = Ft(e), i = Pt(e), a = t ? "VoltroExternalUrl" : "VoltroRouteUrl", o = t && n ? `${n} + ` : "";
937
+ }).join("; ")} }`, nn = (e, t, n) => {
938
+ let r = tn(e), i = en(e), a = t ? "VoltroExternalUrl" : "VoltroRouteUrl", o = t && n ? `${n} + ` : "";
707
939
  return e.params.length === 0 ? `() => (${o}${i}) as ${a}` : `({ ${e.params.map((e) => e.name).join(", ")} }: ${r}) => (${o}${i}) as ${a}`;
708
- }, Lt = (e) => `{\n${[...e].sort((e, t) => e.pattern.localeCompare(t.pattern)).map((e) => ` ${JSON.stringify(e.pattern)}: ${It(e, !1)},`).join("\n")}\n}`, Rt = (e, t) => {
940
+ }, rn = (e) => `{\n${[...e].sort((e, t) => e.pattern.localeCompare(t.pattern)).map((e) => ` ${JSON.stringify(e.pattern)}: ${nn(e, !1)},`).join("\n")}\n}`, an = (e, t) => {
709
941
  if (e.routes.length === 0) return ` ${e.key}: {} as Record<string, never>,`;
710
- let n = [...e.routes].sort((e, t) => e.pattern.localeCompare(t.pattern)), r = t === "prod" && e.prodOrigin ? e.prodOrigin : e.origin, i = JSON.stringify(r), a = n.map((e) => ` ${JSON.stringify(e.pattern)}: ${It(e, !0, i)},`);
942
+ let n = [...e.routes].sort((e, t) => e.pattern.localeCompare(t.pattern)), r = t === "prod" && e.prodOrigin ? e.prodOrigin : e.origin, i = JSON.stringify(r), a = n.map((e) => ` ${JSON.stringify(e.pattern)}: ${nn(e, !0, i)},`);
711
943
  return ` ${e.key}: {\n${a.join("\n")}\n },`;
712
- }, zt = async (e) => {
944
+ }, on = async (e) => {
713
945
  let t = e.pages.map((e) => ({
714
946
  pattern: e.pattern,
715
- params: At(e.pattern)
716
- })), n = await Nt(e.appRoot), r = [
947
+ params: Xt(e.pattern)
948
+ })), n = await $t(e.appRoot), r = [
717
949
  "// THIS FILE IS GENERATED — DO NOT EDIT BY HAND.",
718
950
  "// Re-emitted by `voltro dev` whenever `src/pages/**` changes.",
719
951
  "// Type-safe route builders consumed by <Link to={...}>.",
@@ -722,7 +954,7 @@ __installPublicEnv(publicEnvValues)
722
954
  "",
723
955
  "type EmptyParams = Record<string, never>",
724
956
  ""
725
- ].join("\n"), i = e.mode ?? "dev", a = `${r}\n${`export const routes = ${Lt(t)} as const\n`}\n${n.length === 0 ? "export const siblingApps = {} as Record<string, never>\n" : `export const siblingApps = {\n${n.map((e) => Rt(e, i)).join("\n")}\n} as const\n`}`, o = p(e.appRoot, ".framework", "routes.generated.ts");
957
+ ].join("\n"), i = e.mode ?? "dev", a = `${r}\n${`export const routes = ${rn(t)} as const\n`}\n${n.length === 0 ? "export const siblingApps = {} as Record<string, never>\n" : `export const siblingApps = {\n${n.map((e) => an(e, i)).join("\n")}\n} as const\n`}`, o = p(e.appRoot, ".framework", "routes.generated.ts");
726
958
  await O.mkdir(d(o), { recursive: !0 });
727
959
  let s = null;
728
960
  try {
@@ -735,37 +967,37 @@ __installPublicEnv(publicEnvValues)
735
967
  path: o,
736
968
  wrote: !0
737
969
  });
738
- }, Bt = (e) => {
970
+ }, sn = (e) => {
739
971
  if (e === "" || e === "/") return "/";
740
972
  let t = e.startsWith("/") ? e : `/${e}`;
741
973
  return t.endsWith("/") ? t.slice(0, -1) : t;
742
- }, Vt = (e, t) => {
743
- let n = e.endsWith("/") ? e.slice(0, -1) : e, r = Bt(t);
974
+ }, cn = (e, t) => {
975
+ let n = e.endsWith("/") ? e.slice(0, -1) : e, r = sn(t);
744
976
  return r === "/" ? `${n}/` : `${n}${r}`;
745
- }, Ht = (e, t, n) => {
746
- let r = Bt(e);
977
+ }, ln = (e, t, n) => {
978
+ let r = sn(e);
747
979
  return t === n ? r : r === "/" ? `/${t}` : `/${t}${r}`;
748
- }, Ut = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;"), Wt = (e) => {
980
+ }, un = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;"), dn = (e) => {
749
981
  let { siteUrl: t, entries: n } = e, r = e.locales && e.locales.length > 1 ? e.locales : void 0, i = e.defaultLocale ?? r?.[0] ?? "en", a = r !== void 0, o = /* @__PURE__ */ new Map(), s = (e) => {
750
982
  if (!r) return "";
751
- let n = r.map((n) => ` <xhtml:link rel="alternate" hreflang="${Ut(n)}" href="${Ut(Vt(t, Ht(e, n, i)))}" />`);
752
- return n.push(` <xhtml:link rel="alternate" hreflang="x-default" href="${Ut(Vt(t, Ht(e, i, i)))}" />`), `\n${n.join("\n")}`;
983
+ let n = r.map((n) => ` <xhtml:link rel="alternate" hreflang="${un(n)}" href="${un(cn(t, ln(e, n, i)))}" />`);
984
+ return n.push(` <xhtml:link rel="alternate" hreflang="x-default" href="${un(cn(t, ln(e, i, i)))}" />`), `\n${n.join("\n")}`;
753
985
  };
754
986
  for (let e of n) {
755
987
  let n = r ?? [i];
756
988
  for (let r of n) {
757
- let n = Vt(t, Ht(e.path, r, i)), a = e.lastmod ? `\n <lastmod>${Ut(e.lastmod)}</lastmod>` : "";
758
- o.set(n, ` <url>\n <loc>${Ut(n)}</loc>${a}${s(e.path)}\n </url>`);
989
+ let n = cn(t, ln(e.path, r, i)), a = e.lastmod ? `\n <lastmod>${un(e.lastmod)}</lastmod>` : "";
990
+ o.set(n, ` <url>\n <loc>${un(n)}</loc>${a}${s(e.path)}\n </url>`);
759
991
  }
760
992
  }
761
993
  let c = [...o.keys()].sort().map((e) => o.get(e)).join("\n");
762
994
  return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset${a ? " xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"" : " xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\""}>\n${c}\n</urlset>\n`;
763
- }, Gt = (e) => {
995
+ }, fn = (e) => {
764
996
  if (!e.indexable) return "User-agent: *\nDisallow: /\n";
765
997
  let t = ["User-agent: *", "Allow: /"];
766
- for (let n of e.disallow ?? []) t.push(`Disallow: ${Bt(n)}`);
998
+ for (let n of e.disallow ?? []) t.push(`Disallow: ${sn(n)}`);
767
999
  return e.sitemapUrl && t.push("", `Sitemap: ${e.sitemapUrl}`), `${t.join("\n")}\n`;
768
- }, Kt = 256, qt = (e = Kt) => {
1000
+ }, pn = 256, mn = (e = pn) => {
769
1001
  let t = [], n = /* @__PURE__ */ new Set();
770
1002
  return {
771
1003
  emit(r, i) {
@@ -788,17 +1020,17 @@ __installPublicEnv(publicEnvValues)
788
1020
  return t.slice();
789
1021
  }
790
1022
  };
791
- }, Jt = (e) => `event: ${e.channel}\ndata: ${JSON.stringify(e)}\n\n`, Yt = () => `: keep-alive ${Date.now()}\n\n`, Xt = 8e3, Zt = (e, t = Xt) => {
792
- let n = $t(e);
1023
+ }, hn = (e) => `event: ${e.channel}\ndata: ${JSON.stringify(e)}\n\n`, gn = () => `: keep-alive ${Date.now()}\n\n`, _n = 8e3, vn = (e, t = _n) => {
1024
+ let n = bn(e);
793
1025
  return n.length <= t ? n : `${n.slice(0, t)}\n… [voltro] truncated at ${t} chars (${n.length} total)`;
794
- }, Qt = 4, $t = (e, t = 0, n = /* @__PURE__ */ new Set()) => {
1026
+ }, yn = 4, bn = (e, t = 0, n = /* @__PURE__ */ new Set()) => {
795
1027
  if (e instanceof Error) {
796
1028
  let r = e.stack ?? `${e.name}: ${e.message}`;
797
1029
  if (n.has(e)) return `${r}\n [cycle]`;
798
1030
  n.add(e);
799
1031
  let i = [];
800
- if (t < Qt) if (e instanceof AggregateError && Array.isArray(e.errors)) for (let [r, a] of e.errors.entries()) i.push(`\n [aggregate ${r}] ${en($t(a, t + 1, n))}`);
801
- else e.cause !== void 0 && e.cause !== null && i.push(`\n [cause] ${en($t(e.cause, t + 1, n))}`);
1032
+ if (t < yn) if (e instanceof AggregateError && Array.isArray(e.errors)) for (let [r, a] of e.errors.entries()) i.push(`\n [aggregate ${r}] ${xn(bn(a, t + 1, n))}`);
1033
+ else e.cause !== void 0 && e.cause !== null && i.push(`\n [cause] ${xn(bn(e.cause, t + 1, n))}`);
802
1034
  return r + i.join("");
803
1035
  }
804
1036
  try {
@@ -806,30 +1038,30 @@ __installPublicEnv(publicEnvValues)
806
1038
  } catch {
807
1039
  return "[unstringifiable thrown value]";
808
1040
  }
809
- }, en = (e) => {
1041
+ }, xn = (e) => {
810
1042
  let t = e.split("\n");
811
1043
  return t.length <= 3 ? e : `${t.slice(0, 3).join("\n")}\n …`;
812
- }, tn = {
1044
+ }, Sn = {
813
1045
  trace: 0,
814
1046
  debug: 1,
815
1047
  info: 2,
816
1048
  warn: 3,
817
1049
  error: 4,
818
1050
  fatal: 5
819
- }, nn = 2e3, rn = 200, an = class {
1051
+ }, Cn = 2e3, wn = 200, Tn = class {
820
1052
  capacity;
821
1053
  buffer = [];
822
- constructor(e = nn) {
1054
+ constructor(e = Cn) {
823
1055
  this.capacity = e;
824
1056
  }
825
1057
  append(e) {
826
1058
  this.buffer.push(e), this.buffer.length > this.capacity && this.buffer.shift();
827
1059
  }
828
1060
  query(e = {}) {
829
- let t = e.since ?? 0, n = e.until ?? Date.now(), r = Math.min(e.max ?? rn, this.capacity), i = e.minLevel === void 0 ? tn.trace : tn[e.minLevel], a = e.scope?.toLowerCase(), o = e.source, s = e.filter?.toLowerCase(), c = e.traceId, l = [];
1061
+ let t = e.since ?? 0, n = e.until ?? Date.now(), r = Math.min(e.max ?? wn, this.capacity), i = e.minLevel === void 0 ? Sn.trace : Sn[e.minLevel], a = e.scope?.toLowerCase(), o = e.source, s = e.filter?.toLowerCase(), c = e.traceId, l = [];
830
1062
  for (let e = this.buffer.length - 1; e >= 0 && l.length < r; e--) {
831
1063
  let r = this.buffer[e];
832
- r.ts < t || r.ts > n || tn[r.level] < i || o !== void 0 && r.source !== o || a !== void 0 && (r.scope === void 0 || !r.scope.toLowerCase().includes(a)) || s !== void 0 && !r.message.toLowerCase().includes(s) || c !== void 0 && r.fields.traceId !== c || l.push(r);
1064
+ r.ts < t || r.ts > n || Sn[r.level] < i || o !== void 0 && r.source !== o || a !== void 0 && (r.scope === void 0 || !r.scope.toLowerCase().includes(a)) || s !== void 0 && !r.message.toLowerCase().includes(s) || c !== void 0 && r.fields.traceId !== c || l.push(r);
833
1065
  }
834
1066
  return l.reverse();
835
1067
  }
@@ -842,7 +1074,7 @@ __installPublicEnv(publicEnvValues)
842
1074
  clear() {
843
1075
  this.buffer = [];
844
1076
  }
845
- }, on = null, sn = () => (on === null && (on = new an()), on), cn = (e) => {
1077
+ }, En = null, Dn = () => (En === null && (En = new Tn()), En), On = (e) => {
846
1078
  if (typeof e == "string") return e;
847
1079
  if (e instanceof Error) return e.message;
848
1080
  try {
@@ -850,28 +1082,28 @@ __installPublicEnv(publicEnvValues)
850
1082
  } catch {
851
1083
  return String(e);
852
1084
  }
853
- }, ln = 8e3, un = (e) => typeof e == "string" ? e.length <= ln ? e : `${e.slice(0, ln)}… [voltro: truncated]` : typeof e != "object" || !e ? e : Zt(e, ln), dn = (e, t) => {
1085
+ }, kn = 8e3, An = (e) => typeof e == "string" ? e.length <= kn ? e : `${e.slice(0, kn)}… [voltro: truncated]` : typeof e != "object" || !e ? e : vn(e, kn), jn = (e, t) => {
854
1086
  try {
855
1087
  e(...t);
856
1088
  } catch (n) {
857
1089
  try {
858
- e(...t.map(un)), e(` ↑ [voltro] an argument above was too large for console formatting (${n?.message ?? "inspect failed"}) — printed bounded to ${ln} chars per argument.`);
1090
+ e(...t.map(An)), e(` ↑ [voltro] an argument above was too large for console formatting (${n?.message ?? "inspect failed"}) — printed bounded to ${kn} chars per argument.`);
859
1091
  } catch {
860
1092
  e(`[voltro] a console.error argument could not be formatted at all (${t.length} arg(s)).`);
861
1093
  }
862
1094
  }
863
- }, fn = (e) => {
1095
+ }, Mn = (e) => {
864
1096
  let t = {
865
1097
  log: console.log.bind(console),
866
1098
  info: console.info.bind(console),
867
1099
  warn: console.warn.bind(console),
868
1100
  error: console.error.bind(console),
869
1101
  debug: console.debug.bind(console)
870
- }, n = sn(), r = !1, i = (i) => (...a) => {
871
- if (dn(t[i], a), !r) {
1102
+ }, n = Dn(), r = !1, i = (i) => (...a) => {
1103
+ if (jn(t[i], a), !r) {
872
1104
  r = !0;
873
1105
  try {
874
- let t = a.length > 0 ? cn(a[0]) : "", r = t.length > 500 ? t.slice(0, 500) + "…" : t, o = N();
1106
+ let t = a.length > 0 ? On(a[0]) : "", r = t.length > 500 ? t.slice(0, 500) + "…" : t, o = F();
875
1107
  e.emit("log", {
876
1108
  level: i,
877
1109
  message: r,
@@ -909,7 +1141,7 @@ __installPublicEnv(publicEnvValues)
909
1141
  argsCount: 1,
910
1142
  ...t.scope === void 0 ? {} : { scope: t.scope }
911
1143
  });
912
- let a = N(), o = a !== void 0 && t.fields.traceId === void 0 ? {
1144
+ let a = F(), o = a !== void 0 && t.fields.traceId === void 0 ? {
913
1145
  ...t.fields,
914
1146
  traceId: a.traceId
915
1147
  } : t.fields;
@@ -929,24 +1161,24 @@ __installPublicEnv(publicEnvValues)
929
1161
  return () => {
930
1162
  console.log = t.log, console.info = t.info, console.warn = t.warn, console.error = t.error, console.debug = t.debug, a();
931
1163
  };
932
- }, pn = 2e3, mn = 8, hn = 1e3, gn = 200, Y = (e, t) => e.length > t ? `${e.slice(0, t)}…` : e, _n = (e) => {
1164
+ }, Nn = 2e3, Pn = 8, Fn = 1e3, In = 200, J = (e, t) => e.length > t ? `${e.slice(0, t)}…` : e, Ln = (e) => {
933
1165
  switch (e) {
934
1166
  case "error": return "error";
935
1167
  case "warn": return "warn";
936
1168
  case "debug": return "debug";
937
1169
  default: return "info";
938
1170
  }
939
- }, vn = S({ scope: "client" }), yn = (e, t) => {
1171
+ }, Rn = S({ scope: "client" }), zn = (e, t) => {
940
1172
  let n;
941
1173
  try {
942
1174
  n = JSON.parse(e);
943
1175
  } catch {
944
- return bn(400, { error: "invalid JSON body" });
1176
+ return Bn(400, { error: "invalid JSON body" });
945
1177
  }
946
- if (typeof n != "object" || !n) return bn(400, { error: "body must be a JSON object" });
1178
+ if (typeof n != "object" || !n) return Bn(400, { error: "body must be a JSON object" });
947
1179
  let r = n;
948
- if (!Array.isArray(r.entries)) return bn(400, { error: "entries must be an array" });
949
- let i = typeof r.app == "string" ? Y(r.app, 120) : void 0, a = typeof r.page == "string" ? Y(r.page, 200) : void 0, o = typeof r.ua == "string" ? Y(r.ua, 200) : void 0, s = r.entries.slice(0, gn), c = 0;
1180
+ if (!Array.isArray(r.entries)) return Bn(400, { error: "entries must be an array" });
1181
+ let i = typeof r.app == "string" ? J(r.app, 120) : void 0, a = typeof r.page == "string" ? J(r.page, 200) : void 0, o = typeof r.ua == "string" ? J(r.ua, 200) : void 0, s = r.entries.slice(0, In), c = 0;
950
1182
  for (let e of s) {
951
1183
  if (typeof e != "object" || !e) continue;
952
1184
  let n = e;
@@ -957,7 +1189,7 @@ __installPublicEnv(publicEnvValues)
957
1189
  "warn",
958
1190
  "error",
959
1191
  "debug"
960
- ].includes(n.level) ? n.level : "log", s = typeof n.ts == "number" && Number.isFinite(n.ts) ? n.ts : Date.now(), l = Y(n.message, pn), u = Array.isArray(n.args) ? n.args.slice(0, mn).filter((e) => typeof e == "string").map((e) => Y(e, hn)) : void 0, d = typeof n.stack == "string" ? Y(n.stack, pn) : void 0;
1192
+ ].includes(n.level) ? n.level : "log", s = typeof n.ts == "number" && Number.isFinite(n.ts) ? n.ts : Date.now(), l = J(n.message, Nn), u = Array.isArray(n.args) ? n.args.slice(0, Pn).filter((e) => typeof e == "string").map((e) => J(e, Fn)) : void 0, d = typeof n.stack == "string" ? J(n.stack, Nn) : void 0;
961
1193
  t.emit("clientLog", {
962
1194
  ts: s,
963
1195
  level: r,
@@ -972,35 +1204,35 @@ __installPublicEnv(publicEnvValues)
972
1204
  ...i === void 0 ? {} : { app: i },
973
1205
  ...a === void 0 ? {} : { page: a },
974
1206
  ...u !== void 0 && u.length > 0 ? { args: u } : {}
975
- }, p = _n(r);
976
- (p === "error" || p === "warn") && d !== void 0 ? vn[p](l, f, { stack: d }) : vn[p](l, {
1207
+ }, p = Ln(r);
1208
+ (p === "error" || p === "warn") && d !== void 0 ? Rn[p](l, f, { stack: d }) : Rn[p](l, {
977
1209
  ...f,
978
1210
  ...d === void 0 ? {} : { stack: d }
979
1211
  }), c++;
980
1212
  }
981
- return bn(202, {
1213
+ return Bn(202, {
982
1214
  accepted: c,
983
1215
  dropped: r.entries.length - c
984
1216
  });
985
- }, bn = (e, t) => ({
1217
+ }, Bn = (e, t) => ({
986
1218
  status: e,
987
1219
  contentType: "application/json; charset=utf-8",
988
1220
  body: JSON.stringify(t)
989
- }), xn = "/_voltro/inspect/clientLog", Sn = [
1221
+ }), Vn = "/_voltro/inspect/clientLog", Hn = [
990
1222
  "trace",
991
1223
  "debug",
992
1224
  "info",
993
1225
  "warn",
994
1226
  "error",
995
1227
  "fatal"
996
- ], Cn = {
1228
+ ], Un = {
997
1229
  trace: "TRACE",
998
1230
  debug: "DEBUG",
999
1231
  info: "INFO ",
1000
1232
  warn: "WARN ",
1001
1233
  error: "ERROR",
1002
1234
  fatal: "FATAL"
1003
- }, wn = (e) => Sn.includes(e), Tn = (e, t, n = {}) => {
1235
+ }, Wn = (e) => Hn.includes(e), Gn = (e, t, n = {}) => {
1004
1236
  if (c()) return {
1005
1237
  status: 503,
1006
1238
  contentType: "application/json",
@@ -1031,7 +1263,7 @@ __installPublicEnv(publicEnvValues)
1031
1263
  Number.isFinite(e) && e > 0 && (o.max = Math.floor(e));
1032
1264
  }
1033
1265
  let f = a.get("level");
1034
- f !== null && wn(f) && (o.minLevel = f);
1266
+ f !== null && Wn(f) && (o.minLevel = f);
1035
1267
  let p = a.get("source");
1036
1268
  (p === "server" || p === "client") && (o.source = p);
1037
1269
  let m = a.get("scope");
@@ -1044,7 +1276,7 @@ __installPublicEnv(publicEnvValues)
1044
1276
  if ((a.get("format") ?? "json") === "text") return {
1045
1277
  status: 200,
1046
1278
  contentType: "text/plain; charset=utf-8",
1047
- body: _.map(En).join("\n") + (_.length > 0 ? "\n" : "")
1279
+ body: _.map(Kn).join("\n") + (_.length > 0 ? "\n" : "")
1048
1280
  };
1049
1281
  let v = {
1050
1282
  capturedAt: Date.now(),
@@ -1058,40 +1290,40 @@ __installPublicEnv(publicEnvValues)
1058
1290
  contentType: "application/json; charset=utf-8",
1059
1291
  body: JSON.stringify(v)
1060
1292
  };
1061
- }, En = (e) => {
1062
- let t = new Date(e.ts), n = String(t.getHours()).padStart(2, "0"), r = String(t.getMinutes()).padStart(2, "0"), i = String(t.getSeconds()).padStart(2, "0"), a = String(t.getMilliseconds()).padStart(3, "0"), o = `[${e.scope ?? "?"}/${e.source}]`, s = On(e.fields);
1063
- return `${n}:${r}:${i}.${a} ${Cn[e.level]} ${o} ${e.message}${s}`;
1064
- }, Dn = 80, On = (e) => {
1293
+ }, Kn = (e) => {
1294
+ let t = new Date(e.ts), n = String(t.getHours()).padStart(2, "0"), r = String(t.getMinutes()).padStart(2, "0"), i = String(t.getSeconds()).padStart(2, "0"), a = String(t.getMilliseconds()).padStart(3, "0"), o = `[${e.scope ?? "?"}/${e.source}]`, s = Jn(e.fields);
1295
+ return `${n}:${r}:${i}.${a} ${Un[e.level]} ${o} ${e.message}${s}`;
1296
+ }, qn = 80, Jn = (e) => {
1065
1297
  let t = Object.entries(e);
1066
1298
  if (t.length === 0) return "";
1067
1299
  let n = [];
1068
1300
  for (let [e, r] of t) {
1069
1301
  if (r === void 0) continue;
1070
- let t = kn(r);
1302
+ let t = Yn(r);
1071
1303
  n.push(`${e}=${t}`);
1072
1304
  }
1073
1305
  return n.length > 0 ? " " + n.join(" ") : "";
1074
- }, kn = (e) => {
1306
+ }, Yn = (e) => {
1075
1307
  if (typeof e == "string") {
1076
- let t = e.length > Dn ? e.slice(0, Dn) + "…" : e;
1308
+ let t = e.length > qn ? e.slice(0, qn) + "…" : e;
1077
1309
  return /[\s=]/.test(t) ? `"${t.replace(/"/g, "\\\"")}"` : t;
1078
1310
  }
1079
1311
  if (e === null) return "null";
1080
1312
  if (typeof e == "number" || typeof e == "boolean") return String(e);
1081
1313
  try {
1082
1314
  let t = JSON.stringify(e);
1083
- return t.length > Dn ? t.slice(0, Dn) + "…" : t;
1315
+ return t.length > qn ? t.slice(0, qn) + "…" : t;
1084
1316
  } catch {
1085
1317
  return "[unserialisable]";
1086
1318
  }
1087
- }, An = "/_voltro/inspect/logs", jn = (e, t, n) => {
1319
+ }, Xn = "/_voltro/inspect/logs", Zn = (e, t, n) => {
1088
1320
  if (t.headers.authorization !== void 0) return !1;
1089
1321
  let { token: r } = n;
1090
1322
  if (r === void 0 || r === "" || !n.isLoopback(n.target)) return !1;
1091
1323
  e.setHeader("authorization", `Bearer ${r}`);
1092
1324
  let i = n.writeToken;
1093
1325
  return i !== void 0 && i !== "" && t.headers["x-voltro-inspect-write"] === void 0 && e.setHeader("x-voltro-inspect-write", i), !0;
1094
- }, Mn = [{
1326
+ }, Qn = [{
1095
1327
  match: (e) => typeof e == "string" && e.startsWith("[BABEL] Note: The code generator has deoptimised"),
1096
1328
  handle: (e, t) => {
1097
1329
  let n = e[0], r = n.match(/deoptimised the styling of (.+?) as it exceeds the max of (\d+\w*B)\.?/);
@@ -1103,13 +1335,13 @@ __installPublicEnv(publicEnvValues)
1103
1335
  });
1104
1336
  } else t.info(n);
1105
1337
  }
1106
- }], Nn = () => {
1338
+ }], $n = () => {
1107
1339
  let e = {
1108
1340
  warn: console.warn.bind(console),
1109
1341
  error: console.error.bind(console)
1110
1342
  }, t = S({ scope: "babel" }), n = !1, r = (r) => (...i) => {
1111
1343
  if (!n) {
1112
- for (let e of Mn) if (e.match(i[0])) {
1344
+ for (let e of Qn) if (e.match(i[0])) {
1113
1345
  n = !0;
1114
1346
  try {
1115
1347
  e.handle(i, t);
@@ -1124,7 +1356,7 @@ __installPublicEnv(publicEnvValues)
1124
1356
  return console.warn = r("warn"), console.error = r("error"), () => {
1125
1357
  console.warn = e.warn, console.error = e.error;
1126
1358
  };
1127
- }, Pn = {
1359
+ }, er = {
1128
1360
  loader: "it runs on the server, and the router caches its result per route + params",
1129
1361
  renderMode: "it picks the server render strategy",
1130
1362
  dynamic: "it picks the server render strategy",
@@ -1135,7 +1367,7 @@ __installPublicEnv(publicEnvValues)
1135
1367
  cacheInvalidatesOn: "it wires this page into the ISR cache invalidator",
1136
1368
  interactive: "it decides how much client JS the server ships",
1137
1369
  tenantAware: "it is part of the server-side cache key"
1138
- }, Fn = Object.keys(Pn), In = (e) => t.test(e), Ln = (e) => e.replace(/page\.tsx$/, "page.test.tsx"), Rn = "virtual:voltro-route-refresh", zn = `\0${Rn}`, Bn = /(?:^|&)(raw|url|inline|worker|sharedworker|direct)(?:&|=|$)/, Vn = () => `
1370
+ }, tr = Object.keys(er), nr = (e) => t.test(e), rr = (e) => e.replace(/page\.tsx$/, "page.test.tsx"), ir = "virtual:voltro-route-refresh", ar = `\0${ir}`, or = /(?:^|&)(raw|url|inline|worker|sharedworker|direct)(?:&|=|$)/, sr = () => `
1139
1371
  // GENERATED by @voltro/cli — the \`voltro dev\` route Fast Refresh runtime.
1140
1372
 
1141
1373
  /** Mirrors react-refresh's own \`isLikelyComponentType\` closely enough for the
@@ -1164,11 +1396,11 @@ const stableForm = (value) => {
1164
1396
  * readers (\`build.ts\` prerender, \`webDev.ts\` dev SSR, \`start.ts\`). A change to
1165
1397
  * one of THESE cannot be hot-applied: the server already ran with the old
1166
1398
  * value. Everything else a page exports is plain client-side data. */
1167
- const serverRelevantExports = ${JSON.stringify(Fn)}
1399
+ const serverRelevantExports = ${JSON.stringify(tr)}
1168
1400
 
1169
1401
  /** Name → the server step that already consumed it, so the reload message can
1170
1402
  * say WHY rather than just WHAT. Injected from the same single source. */
1171
- const serverExportEffect = ${JSON.stringify(Pn)}
1403
+ const serverExportEffect = ${JSON.stringify(er)}
1172
1404
 
1173
1405
  /** The reason \`name\` forces a reload, for the console line. */
1174
1406
  export const serverEffectOf = (name) =>
@@ -1211,7 +1443,7 @@ export const routeUpdateNeedsReload = (prevExports, nextExports) => {
1211
1443
  const previousHook = globalThis.__getReactRefreshIgnoredExports
1212
1444
  globalThis.__getReactRefreshIgnoredExports = (args) =>
1213
1445
  ignoredExports.get(args.id) ?? previousHook?.(args) ?? []
1214
- `, Hn = (e) => `
1446
+ `, cr = (e) => `
1215
1447
  if (import.meta.hot) {
1216
1448
  // Self-import to read our OWN exports, the same technique the react plugin
1217
1449
  // uses; the namespace is only complete after evaluation, hence the promise.
@@ -1238,57 +1470,57 @@ import {
1238
1470
  registerRouteModule as __voltro_registerRouteModule,
1239
1471
  routeUpdateNeedsReload as __voltro_routeUpdateNeedsReload,
1240
1472
  serverEffectOf as __voltro_serverEffect,
1241
- } from '${Rn}'
1242
- `, Un = (e) => e.replace(/\\/g, "/"), Wn = (e, t) => {
1243
- let [i = "", a] = Un(e).split("?");
1244
- if (!i.endsWith(".tsx") || a !== void 0 && Bn.test(a)) return !1;
1245
- let o = Un(t).replace(/\/$/, "");
1473
+ } from '${ir}'
1474
+ `, lr = (e) => e.replace(/\\/g, "/"), ur = (e, t) => {
1475
+ let [i = "", a] = lr(e).split("?");
1476
+ if (!i.endsWith(".tsx") || a !== void 0 && or.test(a)) return !1;
1477
+ let o = lr(t).replace(/\/$/, "");
1246
1478
  return i.startsWith(`${o}/`) ? r.test(i) || n.has(i.slice(i.lastIndexOf("/") + 1)) : !1;
1247
- }, Gn = (e, t, n) => Wn(t, n) ? `${e}${Hn(Un(t).split("?")[0] ?? t)}` : null, Kn = (e) => ({
1479
+ }, dr = (e, t, n) => ur(t, n) ? `${e}${cr(lr(t).split("?")[0] ?? t)}` : null, fr = (e) => ({
1248
1480
  name: "voltro:route-fast-refresh",
1249
1481
  enforce: "pre",
1250
- resolveId: (e) => e === "virtual:voltro-route-refresh" ? zn : void 0,
1251
- load: (e) => e === zn ? Vn() : void 0,
1482
+ resolveId: (e) => e === "virtual:voltro-route-refresh" ? ar : void 0,
1483
+ load: (e) => e === ar ? sr() : void 0,
1252
1484
  transform: (t, n, r) => {
1253
1485
  if (r?.ssr === !0) return null;
1254
- let i = Gn(t, n, e);
1486
+ let i = dr(t, n, e);
1255
1487
  return i === null ? null : {
1256
1488
  code: i,
1257
1489
  map: null
1258
1490
  };
1259
1491
  }
1260
- }), qn = [
1492
+ }), pr = [
1261
1493
  "static",
1262
1494
  "spa",
1263
1495
  "ssr",
1264
1496
  "isr"
1265
- ], Jn = (e) => typeof e == "string" && qn.includes(e), Yn = qn.map((e) => `'${e}'`).join(" | "), Xn = (e, t) => `[voltro] ${e}: unknown renderMode '${t}'.\n Valid values: ${Yn}.${t === "client" || t === "csr" || t === "browser" ? "\n A page that renders only in the browser is 'spa': it is skipped by the prerender and mounts on the client. If its route has a layout, that layout still renders server-side as an SSR shell." : t === "server" || t === "dynamic" ? "\n A page rendered per request is 'ssr'." : t === "ssg" || t === "prerender" ? "\n A page rendered once at build time is 'static' (the default)." : ""}`, Zn = class extends Error {
1497
+ ], mr = (e) => typeof e == "string" && pr.includes(e), hr = pr.map((e) => `'${e}'`).join(" | "), gr = (e, t) => `[voltro] ${e}: unknown renderMode '${t}'.\n Valid values: ${hr}.${t === "client" || t === "csr" || t === "browser" ? "\n A page that renders only in the browser is 'spa': it is skipped by the prerender and mounts on the client. If its route has a layout, that layout still renders server-side as an SSR shell." : t === "server" || t === "dynamic" ? "\n A page rendered per request is 'ssr'." : t === "ssg" || t === "prerender" ? "\n A page rendered once at build time is 'static' (the default)." : ""}`, _r = class extends Error {
1266
1498
  page;
1267
1499
  value;
1268
1500
  name = "InvalidRenderModeError";
1269
1501
  constructor(e, t) {
1270
- super(Xn(e, t)), this.page = e, this.value = t;
1502
+ super(gr(e, t)), this.page = e, this.value = t;
1271
1503
  }
1272
- }, Qn = (e, t = "<page>") => {
1504
+ }, vr = (e, t = "<page>") => {
1273
1505
  if (e.renderMode !== void 0 && e.renderMode !== null) {
1274
- if (!Jn(e.renderMode)) throw new Zn(t, String(e.renderMode));
1506
+ if (!mr(e.renderMode)) throw new _r(t, String(e.renderMode));
1275
1507
  return e.renderMode;
1276
1508
  }
1277
1509
  return e.dynamic === "force-dynamic" ? "ssr" : (e.dynamic, "static");
1278
- }, $n = (e, t = "<page>") => ({
1279
- renderMode: Qn(e, t),
1510
+ }, yr = (e, t = "<page>") => ({
1511
+ renderMode: vr(e, t),
1280
1512
  tenantAware: e.tenantAware === !0,
1281
- revalidateMs: ct(e.revalidate),
1282
- staleWhileRevalidateMs: ct(e.staleWhileRevalidate) ?? 0,
1513
+ revalidateMs: lt(e.revalidate),
1514
+ staleWhileRevalidateMs: lt(e.staleWhileRevalidate) ?? 0,
1283
1515
  cacheInvalidatesOn: Array.isArray(e.cacheInvalidatesOn) ? e.cacheInvalidatesOn : [],
1284
1516
  interactive: e.interactive ?? "full",
1285
1517
  hasLoader: typeof e.loader == "function",
1286
1518
  hasMeta: e.meta != null,
1287
1519
  hasGetStaticPaths: typeof e.getStaticPaths == "function"
1288
- }), er = /export\s+const\s+renderMode\s*(?::[^=]+)?=\s*['"]([^'"]*)['"]/, tr = (e) => er.exec(e)?.[1] ?? null, nr = /export\s*\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g, rr = (e) => {
1289
- nr.lastIndex = 0;
1520
+ }), br = /export\s+const\s+renderMode\s*(?::[^=]+)?=\s*['"]([^'"]*)['"]/, xr = (e) => br.exec(e)?.[1] ?? null, Sr = /export\s*\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g, Cr = (e) => {
1521
+ Sr.lastIndex = 0;
1290
1522
  let t;
1291
- for (; (t = nr.exec(e)) !== null;) {
1523
+ for (; (t = Sr.exec(e)) !== null;) {
1292
1524
  let e = t[2];
1293
1525
  if (e.startsWith(".")) for (let n of t[1].split(",")) {
1294
1526
  let t = n.lastIndexOf(" as ");
@@ -1296,16 +1528,16 @@ import {
1296
1528
  }
1297
1529
  }
1298
1530
  return null;
1299
- }, ir = /export\s*\{([^}]*)\}/g, ar = (e) => {
1531
+ }, wr = /export\s*\{([^}]*)\}/g, Tr = (e) => {
1300
1532
  if (/export\s+default\b/.test(e)) return !0;
1301
- ir.lastIndex = 0;
1533
+ wr.lastIndex = 0;
1302
1534
  let t;
1303
- for (; (t = ir.exec(e)) !== null;) for (let e of t[1].split(",")) {
1535
+ for (; (t = wr.exec(e)) !== null;) for (let e of t[1].split(",")) {
1304
1536
  let t = e.lastIndexOf(" as ");
1305
1537
  if ((t === -1 ? e : e.slice(t + 4)).trim() === "default") return !0;
1306
1538
  }
1307
1539
  return !1;
1308
- }, or = async (e, t) => {
1540
+ }, Er = async (e, t) => {
1309
1541
  let n = (await Promise.all(t.map(async (t) => {
1310
1542
  let n;
1311
1543
  try {
@@ -1313,33 +1545,33 @@ import {
1313
1545
  } catch {
1314
1546
  return null;
1315
1547
  }
1316
- let r = tr(n);
1317
- return r !== null && !Jn(r) ? Xn(p("src", "pages", t.file), r) : ar(n) ? null : `${p("src", "pages", t.file)} is a route (a \`page.tsx\` under src/pages/) but exports no default.\n\n A page's default export IS its component — the router has nothing to render without it,\n and the failure would otherwise surface only in \`voltro build\`'s prerender as\n "SSR received a descriptor with no Component", long after the file was written.\n\n Fix: \`export default function Page() { … }\`, or re-export another page's component\n (\`export { default } from '../page'\`). If this file is NOT a route, rename it —\n only the reserved names route, and anything else under src/pages/ is ordinary code\n that may live beside the page that uses it.`;
1548
+ let r = xr(n);
1549
+ return r !== null && !mr(r) ? gr(p("src", "pages", t.file), r) : Tr(n) ? null : `${p("src", "pages", t.file)} is a route (a \`page.tsx\` under src/pages/) but exports no default.\n\n A page's default export IS its component — the router has nothing to render without it,\n and the failure would otherwise surface only in \`voltro build\`'s prerender as\n "SSR received a descriptor with no Component", long after the file was written.\n\n Fix: \`export default function Page() { … }\`, or re-export another page's component\n (\`export { default } from '../page'\`). If this file is NOT a route, rename it —\n only the reserved names route, and anything else under src/pages/ is ordinary code\n that may live beside the page that uses it.`;
1318
1550
  }))).filter((e) => e !== null);
1319
1551
  if (n.length !== 0) throw Error(n.join("\n\n"));
1320
- }, X = p(F(), ".voltro", "logs"), sr = () => {
1552
+ }, Y = p(L(), ".voltro", "logs"), Dr = () => {
1321
1553
  let e = Number(process.env.VOLTRO_LOG_FILE_TTL_MS);
1322
1554
  return Number.isFinite(e) && e > 0 ? e : 3600 * 1e3;
1323
- }, cr = !1, lr = () => {
1324
- if (cr) return;
1325
- cr = !0;
1326
- let e = Date.now() - sr(), t = [];
1555
+ }, Or = !1, kr = () => {
1556
+ if (Or) return;
1557
+ Or = !0;
1558
+ let e = Date.now() - Dr(), t = [];
1327
1559
  try {
1328
- t = k(X);
1560
+ t = A(Y);
1329
1561
  } catch {
1330
1562
  return;
1331
1563
  }
1332
1564
  for (let n of t) {
1333
1565
  if (!n.endsWith(".log")) continue;
1334
- let t = p(X, n);
1566
+ let t = p(Y, n);
1335
1567
  try {
1336
- A(t).mtimeMs < e && j(t);
1568
+ j(t).mtimeMs < e && M(t);
1337
1569
  } catch {}
1338
1570
  }
1339
- }, ur = (e) => e.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80), dr = (e, t) => p(X, `${ur(e)}-${t}.log`), fr = (e) => {
1340
- let t = ur(e), n = [];
1571
+ }, Ar = (e) => e.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80), jr = (e, t) => p(Y, `${Ar(e)}-${t}.log`), Mr = (e) => {
1572
+ let t = Ar(e), n = [];
1341
1573
  try {
1342
- n = k(X);
1574
+ n = A(Y);
1343
1575
  } catch {
1344
1576
  return;
1345
1577
  }
@@ -1347,19 +1579,19 @@ import {
1347
1579
  if (r.length === 0) return;
1348
1580
  let i, a = -1;
1349
1581
  for (let e of r) {
1350
- let t = p(X, e);
1582
+ let t = p(Y, e);
1351
1583
  try {
1352
- let e = A(t);
1584
+ let e = j(t);
1353
1585
  e.mtimeMs > a && (a = e.mtimeMs, i = t);
1354
1586
  } catch {}
1355
1587
  }
1356
1588
  return i;
1357
- }, pr = (e) => {
1589
+ }, Nr = (e) => {
1358
1590
  try {
1359
- E(X, { recursive: !0 });
1591
+ E(Y, { recursive: !0 });
1360
1592
  } catch {}
1361
- lr();
1362
- let t = dr(e, process.pid), n = D(t, "w"), r = (e) => {
1593
+ kr();
1594
+ let t = jr(e, process.pid), n = D(t, "w"), r = (e) => {
1363
1595
  let t = {
1364
1596
  ts: e.ts.getTime(),
1365
1597
  level: e.level,
@@ -1382,7 +1614,7 @@ import {
1382
1614
  }
1383
1615
  }, i = !1, a = x((e) => {
1384
1616
  if (!i) try {
1385
- M(n, r(e));
1617
+ P(n, r(e));
1386
1618
  } catch {}
1387
1619
  }), o = () => {
1388
1620
  if (!i) {
@@ -1400,7 +1632,7 @@ import {
1400
1632
  a(), o(), process.off("exit", o), process.off("uncaughtException", s), process.off("unhandledRejection", s);
1401
1633
  }
1402
1634
  };
1403
- }, mr = async (e, t) => {
1635
+ }, Pr = async (e, t) => {
1404
1636
  let n;
1405
1637
  try {
1406
1638
  n = await O.readFile(e, "utf8");
@@ -1414,11 +1646,11 @@ import {
1414
1646
  i.push(t);
1415
1647
  } catch {}
1416
1648
  return t?.max !== void 0 && i.length > t.max ? i.slice(i.length - t.max) : i;
1417
- }, hr = S({ scope: "voltro:dashboard" }), gr = I(import.meta.url), _r = 5179, vr = (e) => {
1649
+ }, Fr = S({ scope: "voltro:dashboard" }), Ir = R(import.meta.url), Lr = 5179, Rr = (e) => {
1418
1650
  let t = process.env.VOLTRO_DASHBOARD_PATH;
1419
1651
  if (t && T(p(h(t), "app.config.ts"))) return h(t);
1420
1652
  try {
1421
- let e = d(gr.resolve("@voltro/dashboard/package.json"));
1653
+ let e = d(Ir.resolve("@voltro/dashboard/package.json"));
1422
1654
  if (T(p(e, "app.config.ts"))) return e;
1423
1655
  } catch {}
1424
1656
  let n = p("voltro-devtools", "apps", "dashboard"), r = h(e);
@@ -1430,7 +1662,7 @@ import {
1430
1662
  r = t;
1431
1663
  }
1432
1664
  return null;
1433
- }, yr = "VOLTRO_IS_DASHBOARD", br = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1665
+ }, zr = "VOLTRO_IS_DASHBOARD", Br = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1434
1666
  let i = pe({
1435
1667
  port: e,
1436
1668
  host: t
@@ -1438,45 +1670,45 @@ import {
1438
1670
  a || (a = !0, i.destroy(), r(e));
1439
1671
  };
1440
1672
  i.once("connect", () => o(!0)), i.once("error", () => o(!1)), setTimeout(() => o(!1), n);
1441
- }), xr = () => !!(process.env.VOLTRO_DASHBOARD === "off" || process.argv.includes("--disable-dashboard")), Sr = () => process.env[yr] === "1", Cr = () => process.stdout.isTTY === !0, wr = p(F(), ".voltro", "dashboard-launch.lock"), Tr = 1e4, Er = async () => {
1673
+ }), Vr = () => !!(process.env.VOLTRO_DASHBOARD === "off" || process.argv.includes("--disable-dashboard")), Hr = () => process.env[zr] === "1", Ur = () => process.stdout.isTTY === !0, Wr = p(L(), ".voltro", "dashboard-launch.lock"), Gr = 1e4, Kr = async () => {
1442
1674
  try {
1443
- await O.mkdir(d(wr), { recursive: !0 });
1444
- let e = await O.open(wr, "wx");
1675
+ await O.mkdir(d(Wr), { recursive: !0 });
1676
+ let e = await O.open(Wr, "wx");
1445
1677
  return await e.write(`${process.pid}\n${Date.now()}\n`), await e.close(), !0;
1446
1678
  } catch {
1447
1679
  try {
1448
- let e = await O.stat(wr);
1449
- if (Date.now() - e.mtimeMs > Tr) return await O.unlink(wr).catch(() => void 0), Er();
1680
+ let e = await O.stat(Wr);
1681
+ if (Date.now() - e.mtimeMs > Gr) return await O.unlink(Wr).catch(() => void 0), Kr();
1450
1682
  } catch {}
1451
1683
  return !1;
1452
1684
  }
1453
- }, Dr = async () => {
1685
+ }, qr = async () => {
1454
1686
  try {
1455
- await O.unlink(wr);
1687
+ await O.unlink(Wr);
1456
1688
  } catch {}
1457
- }, Or = async (e) => {
1689
+ }, Jr = async (e) => {
1458
1690
  let t = e.port ?? 5179;
1459
- if (xr()) return {
1691
+ if (Vr()) return {
1460
1692
  status: "skipped",
1461
1693
  reason: "disabled by flag/env",
1462
1694
  port: t
1463
1695
  };
1464
- if (Sr()) return {
1696
+ if (Hr()) return {
1465
1697
  status: "skipped",
1466
1698
  reason: "this process IS the dashboard",
1467
1699
  port: t
1468
1700
  };
1469
- if (!Cr()) return {
1701
+ if (!Ur()) return {
1470
1702
  status: "skipped",
1471
1703
  reason: "stdout is not a TTY (CI/smoke)",
1472
1704
  port: t
1473
1705
  };
1474
- if (!await Er()) return {
1706
+ if (!await Kr()) return {
1475
1707
  status: "skipped",
1476
1708
  reason: "another voltro process is currently launching the dashboard",
1477
1709
  port: t
1478
1710
  };
1479
- if (await br(t)) return await Dr(), {
1711
+ if (await Br(t)) return await qr(), {
1480
1712
  status: "already-running",
1481
1713
  port: t
1482
1714
  };
@@ -1493,7 +1725,7 @@ import {
1493
1725
  stdio: "ignore",
1494
1726
  env: {
1495
1727
  ...process.env,
1496
- [yr]: "1",
1728
+ [zr]: "1",
1497
1729
  VOLTRO_DASHBOARD_PORT: String(t)
1498
1730
  }
1499
1731
  });
@@ -1501,22 +1733,22 @@ import {
1501
1733
  if (a.exitCode === null && a.signalCode === null) try {
1502
1734
  a.kill("SIGTERM");
1503
1735
  } catch {}
1504
- }), hr.info(`auto-launching dashboard at http://localhost:${t}`, {
1736
+ }), Fr.info(`auto-launching dashboard at http://localhost:${t}`, {
1505
1737
  port: t,
1506
1738
  mode: i,
1507
1739
  prebuilt: r
1508
- }), r || hr.debug("no pre-built dashboard — running `voltro dev`. Build with `cd voltro-devtools && pnpm build` for a fast prod boot."), hr.debug("disable via --disable-dashboard or VOLTRO_DASHBOARD=off"), setTimeout(() => {
1509
- Dr();
1740
+ }), r || Fr.debug("no pre-built dashboard — running `voltro dev`. Build with `cd voltro-devtools && pnpm build` for a fast prod boot."), Fr.debug("disable via --disable-dashboard or VOLTRO_DASHBOARD=off"), setTimeout(() => {
1741
+ qr();
1510
1742
  }, 4e3).unref(), {
1511
1743
  status: "launched",
1512
1744
  port: t
1513
1745
  };
1514
- }, kr = class extends Error {
1746
+ }, Yr = class extends Error {
1515
1747
  _voltroDeferral = !0;
1516
1748
  constructor(e) {
1517
1749
  super(e), this.name = "DeferralNotSupportedError";
1518
1750
  }
1519
- }, Ar = (e) => typeof e == "object" && !!e && e._voltroDeferral === !0, jr = (e) => {
1751
+ }, Xr = (e) => typeof e == "object" && !!e && e._voltroDeferral === !0, Zr = (e) => {
1520
1752
  if (!(e instanceof Error)) return;
1521
1753
  let t = e._voltroControl;
1522
1754
  if (t === "redirect") {
@@ -1538,7 +1770,7 @@ import {
1538
1770
  },
1539
1771
  body: "not found"
1540
1772
  };
1541
- }, Mr = (e) => {
1773
+ }, Qr = (e) => {
1542
1774
  let { helpers: t } = e, n = t.prepareDeferredLoaderData(e.loaderData, "page"), r = {}, i = {}, a = {};
1543
1775
  for (let [n, o] of Object.entries(e.segmentLoaderData)) {
1544
1776
  let e = Number(n), s = t.prepareDeferredLoaderData(o, e);
@@ -1553,7 +1785,7 @@ import {
1553
1785
  ...e.layoutShell ? { layoutShell: e.layoutShell } : {}
1554
1786
  });
1555
1787
  } catch (e) {
1556
- throw new kr(e instanceof Error ? e.message : String(e));
1788
+ throw new Yr(e instanceof Error ? e.message : String(e));
1557
1789
  }
1558
1790
  return {
1559
1791
  loaderData: n.renderData,
@@ -1569,8 +1801,8 @@ import {
1569
1801
  ...Object.keys(a).length > 0 ? { deferredSegmentIds: a } : {}
1570
1802
  }
1571
1803
  };
1572
- }, Nr = (e) => {
1573
- let { helpers: t, renderInput: n } = e, r = Mr({
1804
+ }, $r = (e) => {
1805
+ let { helpers: t, renderInput: n } = e, r = Qr({
1574
1806
  helpers: t,
1575
1807
  page: e.page,
1576
1808
  pathname: n.pathname,
@@ -1591,19 +1823,19 @@ import {
1591
1823
  stateScript: t.renderRouterStateScript(r.stateInput),
1592
1824
  hasDeferred: r.hasDeferred
1593
1825
  };
1594
- }, Pr = (e) => {
1826
+ }, ei = (e) => {
1595
1827
  let { html: t, meta: n } = e.helpers.renderPageToHtml(e.prepared.renderInput);
1596
1828
  return {
1597
1829
  body: t,
1598
1830
  meta: n
1599
1831
  };
1600
- }, Fr = (e) => [
1832
+ }, ti = (e) => [
1601
1833
  ...e.extra ?? [],
1602
1834
  e.helpers.renderMetaToHtml(e.meta),
1603
1835
  `<meta name="voltro-interactive" content="${e.interactive}" />`,
1604
1836
  ...e.prepared.hasDeferred ? [e.helpers.renderDeferredRegistryScript()] : [],
1605
1837
  e.prepared.stateScript
1606
- ].filter((e) => e.length > 0).join("\n "), Ir = (e) => {
1838
+ ].filter((e) => e.length > 0).join("\n "), ni = (e) => {
1607
1839
  let t = e.indexOf("?");
1608
1840
  return t === -1 ? {
1609
1841
  pathname: e || "/",
@@ -1612,53 +1844,90 @@ import {
1612
1844
  pathname: e.slice(0, t) || "/",
1613
1845
  search: e.slice(t)
1614
1846
  };
1615
- }, Lr = /Could not find required `intl` object/, Rr = (e) => [
1847
+ }, ri = /Could not find required `intl` object/, ii = "__voltro_i18n_instances__", ai = (e = globalThis) => {
1848
+ try {
1849
+ let t = e[ii]?.records;
1850
+ return t === void 0 || t.length === 0 ? void 0 : {
1851
+ instances: t.length,
1852
+ reactIntlCopies: new Set(t.map((e) => e.intlProvider)).size,
1853
+ files: [...new Set(t.map((e) => e.file))]
1854
+ };
1855
+ } catch {
1856
+ return;
1857
+ }
1858
+ }, oi = (e, t) => [
1616
1859
  "",
1617
1860
  "── voltro diagnosis ───────────────────────────────────────────────────",
1618
- `${e} DID wrap this render in <I18nProvider> the framework`,
1619
- "resolved a locale for this request and supplied the provider. You are",
1620
- "seeing this error anyway, which leaves one cause:",
1861
+ `${e} DID wrap this render in <I18nProvider>, and this process`,
1862
+ `holds ${t.instances} live copies of @voltro/i18n bound to`,
1863
+ `${t.reactIntlCopies} distinct react-intl instances.`,
1621
1864
  "",
1622
- " TWO PHYSICAL COPIES OF react-intl (or of @voltro/i18n, which owns it).",
1865
+ " THAT is the cause. A React context is identified by object identity,",
1866
+ " so the provider built from one copy is invisible to a `useT()` from the",
1867
+ " other, and the error is identical to having no provider at all.",
1623
1868
  "",
1624
- "A React context is identified by object identity. The provider built from",
1625
- "one copy is invisible to a `useT()` / `useIntl()` from the other, and the",
1626
- "error is identical to having no provider at all.",
1869
+ " Loaded from:",
1870
+ ...t.files.map((e) => ` - ${e}`),
1627
1871
  "",
1628
- "Check it:",
1872
+ " NOTE: `pnpm ls` will very likely show ONE version. It enumerates",
1873
+ " versions on disk; this counts instances in the running process, and one",
1874
+ " file loaded down two paths is two instances.",
1875
+ "───────────────────────────────────────────────────────────────────────"
1876
+ ].join("\n"), si = (e, t) => [
1877
+ "",
1878
+ "── voltro diagnosis ───────────────────────────────────────────────────",
1879
+ `${e} DID wrap this render in <I18nProvider>, and this process`,
1880
+ `holds exactly ONE @voltro/i18n bound to ONE react-intl (${t.instances}/${t.reactIntlCopies}, from ${t.files[0] ?? "unknown"}).`,
1881
+ "",
1882
+ " So neither of the two known causes applies, and this IS a framework",
1883
+ " bug — report it with this block attached.",
1629
1884
  "",
1630
- " pnpm ls -r --depth 10 @voltro/i18n react-intl",
1885
+ " One thing to check first, because it is the remaining non-framework",
1886
+ " cause and it is in YOUR code: a provider built from react-intl",
1887
+ " DIRECTLY (`import { IntlProvider } from \"react-intl\"`) rather than from",
1888
+ " @voltro/i18n. Vite bundles react-intl for modules it transforms, so a",
1889
+ " direct import can land on a second copy that this count does not see —",
1890
+ " it counts what @voltro/i18n is bound to.",
1891
+ "───────────────────────────────────────────────────────────────────────"
1892
+ ].join("\n"), ci = (e) => [
1893
+ "",
1894
+ "── voltro diagnosis ───────────────────────────────────────────────────",
1895
+ `${e} DID wrap this render in <I18nProvider> — the framework`,
1896
+ "resolved a locale for this request and supplied the provider, so \"no",
1897
+ "provider\" is excluded.",
1631
1898
  "",
1632
- "More than one version of either, anywhere in the workspace, is the cause.",
1633
- "It usually means one package.json was left behind on an upgrade — the app",
1634
- "still builds and every other test still passes.",
1899
+ " The instance count is unavailable (@voltro/i18n did not register), so",
1900
+ " the remaining cause cannot be confirmed from here. It is almost always",
1901
+ " TWO LIVE COPIES of react-intl or @voltro/i18n — a React context is an",
1902
+ " object identity, and a provider from one copy is invisible to a hook",
1903
+ " from the other.",
1635
1904
  "",
1636
- "If both resolve to exactly one version, this diagnosis is wrong and the",
1637
- "framework is at fault. Report it with that output attached.",
1905
+ " Do NOT use `pnpm ls` to rule that out: it lists versions on disk, and",
1906
+ " the duplication here is of module instances in one process.",
1638
1907
  "───────────────────────────────────────────────────────────────────────"
1639
- ].join("\n"), zr = (e, t, n) => {
1908
+ ].join("\n"), li = (e, t, n, r = ai()) => {
1640
1909
  if (!t) return;
1641
- let r = String(e?.message ?? e);
1642
- return Lr.test(r) ? Rr(n) : void 0;
1643
- }, Br = "<div id=\"root\"></div>", Vr = "<div id=\"root\">", Hr = "</div>", Ur = /<script\b[^>]*\btype=["']module["'][^>]*><\/script>[ \t]*\n?/gi, Wr = /\bsrc=["']([^"']+)["']/i, Gr = /<script(?![^>]*\basync\b)([^>]*\btype=["']module["'][^>]*)>/gi, Kr = (e) => {
1644
- let t = e.keepScriptInHead ?? ((e) => e.startsWith("/@")), n = [], r = e.shell.replace(Ur, (e) => {
1645
- let r = Wr.exec(e)?.[1];
1910
+ let i = String(e?.message ?? e);
1911
+ if (ri.test(i)) return r === void 0 ? ci(n) : r.reactIntlCopies > 1 || r.instances > 1 ? oi(n, r) : si(n, r);
1912
+ }, ui = "<div id=\"root\"></div>", di = "<div id=\"root\">", fi = "</div>", pi = /<script\b[^>]*\btype=["']module["'][^>]*><\/script>[ \t]*\n?/gi, mi = /\bsrc=["']([^"']+)["']/i, hi = /<script(?![^>]*\basync\b)([^>]*\btype=["']module["'][^>]*)>/gi, gi = (e) => {
1913
+ let t = e.keepScriptInHead ?? ((e) => e.startsWith("/@")), n = [], r = e.shell.replace(pi, (e) => {
1914
+ let r = mi.exec(e)?.[1];
1646
1915
  return r === void 0 || t(r) ? e : (n.push(r), "");
1647
1916
  });
1648
- e.inlineModuleScriptsAsync && (r = r.replace(Gr, "<script async$1>"));
1649
- let i = r.indexOf(Br);
1650
- if (i === -1) throw Error(`[voltro] the generated shell has no \`${Br}\` element, so a streamed response cannot be split around the page body. This is a framework bug unless the app overrode \`.framework/index.html\` by hand.`);
1917
+ e.inlineModuleScriptsAsync && (r = r.replace(hi, "<script async$1>"));
1918
+ let i = r.indexOf(ui);
1919
+ if (i === -1) throw Error(`[voltro] the generated shell has no \`${ui}\` element, so a streamed response cannot be split around the page body. This is a framework bug unless the app overrode \`.framework/index.html\` by hand.`);
1651
1920
  return {
1652
- head: `${r.slice(0, i)}${Vr}`,
1653
- tail: `${Hr}${r.slice(i + 21)}`,
1921
+ head: `${r.slice(0, i)}${di}`,
1922
+ tail: `${fi}${r.slice(i + 21)}`,
1654
1923
  bootstrapModules: n
1655
1924
  };
1656
- }, qr = (e, t) => (/<title>/i.test(t) ? e.replace(/[^\S\n]*<title>[\s\S]*?<\/title>\n?/i, "") : e).replace("</head>", ` ${t}\n </head>`), Jr = (e) => qr(e.head, e.headInjection).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${e.htmlLang}"`), Yr = (e) => {
1925
+ }, _i = (e, t) => (/<title>/i.test(t) ? e.replace(/[^\S\n]*<title>[\s\S]*?<\/title>\n?/i, "") : e).replace("</head>", ` ${t}\n </head>`), vi = (e) => _i(e.head, e.headInjection).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${e.htmlLang}"`), yi = (e) => {
1657
1926
  let { res: t, shell: n, htmlLang: r, headInjection: i } = e, a = null, o = !1, s = !1, c = () => {
1658
1927
  if (s || !o || a === null) return;
1659
1928
  s = !0, t.statusCode = e.statusCode ?? 200;
1660
1929
  for (let [n, r] of Object.entries(e.headers ?? {})) t.setHeader(n, r);
1661
- t.flushHeaders?.(), t.write(Jr({
1930
+ t.flushHeaders?.(), t.write(vi({
1662
1931
  head: n.head,
1663
1932
  headInjection: i(a.meta),
1664
1933
  htmlLang: r
@@ -1688,16 +1957,16 @@ import {
1688
1957
  return;
1689
1958
  }
1690
1959
  c();
1691
- }, Xr = (e) => Array.isArray(e.preload) && e.preload.length > 0, Zr = (e, t) => typeof e == "string" ? {
1960
+ }, bi = (e) => Array.isArray(e.preload) && e.preload.length > 0, xi = (e, t) => typeof e == "string" ? {
1692
1961
  tag: e,
1693
1962
  input: {}
1694
1963
  } : {
1695
1964
  tag: e.tag,
1696
1965
  input: e.input?.(t) ?? {}
1697
- }, Qr = async (e) => {
1966
+ }, Si = async (e) => {
1698
1967
  let { pageMod: t, params: n, query: r, apiName: i, seed: a, onError: o } = e;
1699
- if (Xr(t) && !(r === void 0 || i === void 0)) for (let e of t.preload) {
1700
- let { tag: t, input: s } = Zr(e, n);
1968
+ if (bi(t) && !(r === void 0 || i === void 0)) for (let e of t.preload) {
1969
+ let { tag: t, input: s } = xi(e, n);
1701
1970
  try {
1702
1971
  a(i, t, s, await r(t, s));
1703
1972
  } catch (e) {
@@ -1707,14 +1976,14 @@ import {
1707
1976
  }, e);
1708
1977
  }
1709
1978
  }
1710
- }, Z = S({ scope: "voltro:dev:web" }), $r = S({ scope: "vite" }), ei = await (async () => {
1979
+ }, X = S({ scope: "voltro:dev:web" }), Ci = S({ scope: "vite" }), wi = await (async () => {
1711
1980
  try {
1712
1981
  let e = p(d(g(import.meta.url)), "..", "package.json"), t = await O.readFile(e, "utf8");
1713
1982
  return JSON.parse(t).version ?? "0.0.0";
1714
1983
  } catch {
1715
1984
  return "0.0.0";
1716
1985
  }
1717
- })(), ti = async () => {
1986
+ })(), Ti = async () => {
1718
1987
  try {
1719
1988
  let e = d(g(import.meta.url)), t = h(e, "..", "..", "devtools");
1720
1989
  if (T(p(t, "package.json"))) return t;
@@ -1723,7 +1992,7 @@ import {
1723
1992
  } catch {
1724
1993
  return null;
1725
1994
  }
1726
- }, ni = (e, t) => e.disableDevtools || !t ? [] : [
1995
+ }, Ei = (e, t) => e.disableDevtools || !t ? [] : [
1727
1996
  "",
1728
1997
  "// Dev-only in-page devtools overlay. The `import.meta.env.DEV` guard is a",
1729
1998
  "// compile-time constant, so prod builds strip this whole `if` block — the",
@@ -1733,12 +2002,12 @@ import {
1733
2002
  " await import('@voltro/devtools/styles.css')",
1734
2003
  " Devtools = (await import('@voltro/devtools')).VoltroDevtools",
1735
2004
  "}"
1736
- ], ri = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], ii = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], ai = (e) => e.sentry ? [
2005
+ ], Di = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], Oi = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], ki = (e) => e.sentry ? [
1737
2006
  "",
1738
2007
  "// Browser-side Sentry (frontend half of the deep integration). Errors +",
1739
2008
  "// browser rpc spans flow to Sentry, sharing the server transactions' trace.",
1740
2009
  `await initSentryBrowser(${JSON.stringify(e.sentry)})`
1741
- ] : [], oi = (e) => e.env ? ["import './env.public'"] : [], si = (e) => {
2010
+ ] : [], Ai = (e) => e.env ? ["import './env.public'"] : [], ji = (e) => {
1742
2011
  let t = [], n = h(e);
1743
2012
  for (;;) {
1744
2013
  T(p(n, "pnpm-workspace.yaml")) && t.push(n);
@@ -1747,14 +2016,14 @@ import {
1747
2016
  n = e;
1748
2017
  }
1749
2018
  return t;
1750
- }, ci = In, li = (e) => {
2019
+ }, Mi = nr, Ni = (e) => {
1751
2020
  if (/\/node_modules\/(?:\.pnpm\/[^/]+\/node_modules\/)?(?:react|react-dom|scheduler)\//.test(e)) return "react";
1752
2021
  let t = /\/([^/]+)\.island\.tsx?$/.exec(e);
1753
2022
  if (t) return `island-${t[1]}`;
1754
- }, ui = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, di = (e) => e.startsWith("(") && e.endsWith(")"), fi = (e) => e.filter((e) => !di(e)), pi = (e) => {
1755
- let t = e.replace(r, "").split("/").filter(Boolean).filter((e) => !di(e));
2023
+ }, Pi = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, Fi = (e) => e.startsWith("(") && e.endsWith(")"), Ii = (e) => e.filter((e) => !Fi(e)), Li = (e) => {
2024
+ let t = e.replace(r, "").split("/").filter(Boolean).filter((e) => !Fi(e));
1756
2025
  return t.length === 0 ? "/" : "/" + t.join("/");
1757
- }, mi = (e) => `${e.replace(r, "").split("/").filter(Boolean).map((e) => e.replace(/[()]/g, "").replace(/\[\.\.\./g, "_rest_").replace(/[[\]]/g, "_")).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_") || "Index"}Page`, Q = (e, t) => e === "" ? `Root${t}` : `${e.split("/").filter(Boolean).map((e) => e.replace(/[()]/g, "").replace(/\[\.\.\./g, "_rest_").replace(/[[\]]/g, "_")).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_") || "Root"}${t}`, $ = async (e) => {
2026
+ }, Ri = (e) => `${e.replace(r, "").split("/").filter(Boolean).map((e) => e.replace(/[()]/g, "").replace(/\[\.\.\./g, "_rest_").replace(/[[\]]/g, "_")).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_") || "Index"}Page`, Z = (e, t) => e === "" ? `Root${t}` : `${e.split("/").filter(Boolean).map((e) => e.replace(/[()]/g, "").replace(/\[\.\.\./g, "_rest_").replace(/[[\]]/g, "_")).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_") || "Root"}${t}`, Q = async (e) => {
1758
2027
  let t = [], i = [], a = async (e, o) => {
1759
2028
  let s = [];
1760
2029
  try {
@@ -1762,17 +2031,17 @@ import {
1762
2031
  } catch {
1763
2032
  return;
1764
2033
  }
1765
- let c = s.filter((e) => e.isDirectory()).map((e) => e.name).sort(), l = s.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !ci(e.name)).map((e) => e.name).sort(), u = new Set(l), d = o.join("/");
2034
+ let c = s.filter((e) => e.isDirectory()).map((e) => e.name).sort(), l = s.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !Mi(e.name)).map((e) => e.name).sort(), u = new Set(l), d = o.join("/");
1766
2035
  if (l.some((e) => n.has(e))) {
1767
2036
  let t = u.has("layout.tsx"), r = !1;
1768
2037
  if (t) try {
1769
2038
  let t = await O.readFile(p(e, "layout.tsx"), "utf8");
1770
- r = ui.test(t);
2039
+ r = Pi.test(t);
1771
2040
  } catch {}
1772
2041
  i.push({
1773
2042
  dir: d,
1774
2043
  chain: o,
1775
- contributesToUrl: o.length === 0 || !di(o[o.length - 1]),
2044
+ contributesToUrl: o.length === 0 || !Fi(o[o.length - 1]),
1776
2045
  hasLayout: t,
1777
2046
  hasLayoutLoader: r,
1778
2047
  hasError: u.has("error.tsx"),
@@ -1786,8 +2055,8 @@ import {
1786
2055
  let n = d ? `${d}/${e}` : e;
1787
2056
  t.push({
1788
2057
  file: n,
1789
- pattern: pi(n),
1790
- ident: mi(n),
2058
+ pattern: Li(n),
2059
+ ident: Ri(n),
1791
2060
  dirChain: o
1792
2061
  });
1793
2062
  }
@@ -1806,14 +2075,14 @@ import {
1806
2075
  dirs: s,
1807
2076
  orphanedSpecials: c
1808
2077
  };
1809
- }, hi = (e, t) => {
2078
+ }, zi = (e, t) => {
1810
2079
  let n = [];
1811
2080
  for (let r = 0; r <= t.length; r++) {
1812
2081
  let i = t.slice(0, r).join("/"), a = e.find((e) => e.dir === i);
1813
2082
  a && n.push(a);
1814
2083
  }
1815
2084
  return n;
1816
- }, gi = async (e) => {
2085
+ }, Bi = async (e) => {
1817
2086
  let { entries: t, loadLayout: n, loadError: r, loadPending: i, ctx: a } = e, o = {};
1818
2087
  return {
1819
2088
  chain: await Promise.all(t.map(async (e, t) => {
@@ -1836,10 +2105,10 @@ import {
1836
2105
  })),
1837
2106
  segmentLoaderData: o
1838
2107
  };
1839
- }, _i = (e) => {
1840
- let t = fi(e);
2108
+ }, Vi = (e) => {
2109
+ let t = Ii(e);
1841
2110
  return t.length === 0 ? "" : "/" + t.join("/");
1842
- }, vi = [
2111
+ }, Hi = [
1843
2112
  "// Hot-reload bridge: keep SSR-injected <link rel=\"stylesheet\"> tags",
1844
2113
  "// in sync with Vite's CSS HMR. Without this, edits to .css files",
1845
2114
  "// only update the JS-injected <style> overlay; the underlying <link>",
@@ -1932,7 +2201,7 @@ import {
1932
2201
  " _vdtErrorStart('Build error')",
1933
2202
  " })",
1934
2203
  "}"
1935
- ].join("\n"), yi = (e) => {
2204
+ ].join("\n"), Ui = (e) => {
1936
2205
  let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
1937
2206
  for (let e of r) e.startsWith("[[...") && e.endsWith("]]") ? (i.push("(.*)"), t.push(e.slice(5, -2)), n += 2) : e.startsWith("[...") && e.endsWith("]") ? (i.push("(.+)"), t.push(e.slice(4, -1)), n += 3) : e.startsWith("[") && e.endsWith("]") ? (i.push("([^/]+)"), t.push(e.slice(1, -1)), n += 1) : i.push(e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
1938
2207
  let a = i.join("/");
@@ -1941,8 +2210,8 @@ import {
1941
2210
  paramNames: t,
1942
2211
  priority: n
1943
2212
  };
1944
- }, bi = (e) => e.map((e) => {
1945
- let { regex: t, paramNames: n, priority: r } = yi(e.pattern);
2213
+ }, Wi = (e) => e.map((e) => {
2214
+ let { regex: t, paramNames: n, priority: r } = Ui(e.pattern);
1946
2215
  return {
1947
2216
  pattern: e.pattern,
1948
2217
  file: e.file,
@@ -1951,7 +2220,7 @@ import {
1951
2220
  paramNames: n,
1952
2221
  priority: r
1953
2222
  };
1954
- }).slice().sort((e, t) => e.priority - t.priority), xi = (e, t) => {
2223
+ }).slice().sort((e, t) => e.priority - t.priority), Gi = (e, t) => {
1955
2224
  for (let n of t) {
1956
2225
  let t = n.regex.exec(e);
1957
2226
  if (!t) continue;
@@ -1963,7 +2232,7 @@ import {
1963
2232
  };
1964
2233
  }
1965
2234
  return null;
1966
- }, Si = async (e, t) => {
2235
+ }, Ki = async (e, t) => {
1967
2236
  let n = e;
1968
2237
  for (;;) {
1969
2238
  let e = p(n, "node_modules", t);
@@ -1977,7 +2246,7 @@ import {
1977
2246
  if (r === n) return null;
1978
2247
  n = r;
1979
2248
  }
1980
- }, Ci = async (e) => {
2249
+ }, qi = async (e) => {
1981
2250
  try {
1982
2251
  let t = await import(_(p(e, "app.config.ts")).href), n = t.default?.port, r = typeof n == "number" ? n : 4e3, i = t.default?.transport?.wsPath, a = typeof i == "string" && i.startsWith("/") ? i : void 0;
1983
2252
  return a ? {
@@ -1986,7 +2255,7 @@ import {
1986
2255
  } : { port: r };
1987
2256
  } catch {}
1988
2257
  return { port: 4e3 };
1989
- }, wi = (e, t) => ({
2258
+ }, Ji = (e, t) => ({
1990
2259
  name: e,
1991
2260
  pkg: t.package,
1992
2261
  browserWsUrl: t.url,
@@ -1994,7 +2263,7 @@ import {
1994
2263
  ...t.serverUrl ? { serverOrigin: t.serverUrl } : {},
1995
2264
  ...t.headers ? { headers: t.headers } : {},
1996
2265
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
1997
- }), Ti = (e, t, n) => {
2266
+ }), Yi = (e, t, n) => {
1998
2267
  let r = t.transport?.wsPath ?? n.wsPath;
1999
2268
  return {
2000
2269
  name: e,
@@ -2006,7 +2275,7 @@ import {
2006
2275
  ...t.headers ? { headers: t.headers } : {},
2007
2276
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
2008
2277
  };
2009
- }, Ei = (e) => {
2278
+ }, Xi = (e) => {
2010
2279
  let t = /* @__PURE__ */ new Map();
2011
2280
  for (let n of e) {
2012
2281
  if (n.proxyTarget === void 0) continue;
@@ -2014,43 +2283,43 @@ import {
2014
2283
  if (e) throw Error(`[voltro] api ${JSON.stringify(n.name)} and ${JSON.stringify(e)} both resolve the same-origin WS path ${JSON.stringify(n.browserWsUrl)}. A custom transport.wsPath must be unique per origin (one api per origin may use a fixed path). Give each a distinct wsPath, or drop the override to use the default /ws/<name>.`);
2015
2284
  t.set(n.browserWsUrl, n.name);
2016
2285
  }
2017
- }, Di = async (e, t) => {
2286
+ }, Zi = async (e, t) => {
2018
2287
  let n = Object.entries(t.apis ?? {}), r = [];
2019
2288
  for (let [t, i] of n) {
2020
2289
  if (i.url) {
2021
- r.push(wi(t, i));
2290
+ r.push(Ji(t, i));
2022
2291
  continue;
2023
2292
  }
2024
- let n = await Si(e, i.package);
2293
+ let n = await Ki(e, i.package);
2025
2294
  if (!n) throw Error(`[voltro dev] api ${JSON.stringify(t)} (package ${JSON.stringify(i.package)}) is not a workspace dep and has no \`url\` set in app.config.ts. External apis need an explicit \`url\` because the framework can't discover their dev port.`);
2026
- r.push(Ti(t, i, await Ci(n)));
2295
+ r.push(Yi(t, i, await qi(n)));
2027
2296
  }
2028
- return Ei(r), r;
2029
- }, Oi = (e) => {
2297
+ return Xi(r), r;
2298
+ }, Qi = (e) => {
2030
2299
  if (!(!/^wss?:\/\//.test(e) && !/^https?:\/\//.test(e))) try {
2031
2300
  let t = new URL(e);
2032
2301
  return t.protocol = t.protocol === "wss:" || t.protocol === "https:" ? "https:" : "http:", `${t.protocol}//${t.host}`;
2033
2302
  } catch {
2034
2303
  return;
2035
2304
  }
2036
- }, ki = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, Ai = (e) => process.env[ki(e)] ?? process.env.VOLTRO_API_ORIGIN, ji = (e, t) => {
2305
+ }, $i = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, ea = (e) => process.env[$i(e)] ?? process.env.VOLTRO_API_ORIGIN, ta = (e, t) => {
2037
2306
  if (!e) return;
2038
- let n = Ai(e.name) ?? e.serverOrigin;
2307
+ let n = ea(e.name) ?? e.serverOrigin;
2039
2308
  if (n) {
2040
- let e = Oi(n);
2309
+ let e = Qi(n);
2041
2310
  if (e) return e;
2042
2311
  }
2043
2312
  if (t?.allowDevProxy && e.proxyTarget) {
2044
- let t = Oi(e.proxyTarget);
2313
+ let t = Qi(e.proxyTarget);
2045
2314
  if (t) return t;
2046
2315
  }
2047
- if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return Oi(e.browserWsUrl);
2048
- }, Mi = (e, t, n) => {
2316
+ if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return Qi(e.browserWsUrl);
2317
+ }, na = (e, t, n) => {
2049
2318
  if (!e) {
2050
2319
  if (n?.apiName === void 0) return;
2051
2320
  let e = n.apiName;
2052
2321
  return async () => {
2053
- throw Error(`[loader.query] api '${e}' has no server-side origin for SSR. In a split web/api deployment the web pod reaches the api by internal DNS, not the browser's relative wsPath — set ${ki(e)} (or VOLTRO_API_ORIGIN, or apis.${e}.serverUrl in app.config.ts) to the api's internal origin, e.g. http://api.<namespace>.svc.cluster.local. The browser transport is unaffected.`);
2322
+ throw Error(`[loader.query] api '${e}' has no server-side origin for SSR. In a split web/api deployment the web pod reaches the api by internal DNS, not the browser's relative wsPath — set ${$i(e)} (or VOLTRO_API_ORIGIN, or apis.${e}.serverUrl in app.config.ts) to the api's internal origin, e.g. http://api.<namespace>.svc.cluster.local. The browser transport is unaffected.`);
2054
2323
  };
2055
2324
  }
2056
2325
  return async (r, i) => {
@@ -2072,7 +2341,7 @@ import {
2072
2341
  });
2073
2342
  } catch (t) {
2074
2343
  let i = t?.cause?.code ?? String(t?.message ?? t);
2075
- throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${ki(n.apiName)} / VOLTRO_API_ORIGIN` : "Set the api server origin"} to the api's SSR-reachable origin (internal cluster DNS in a split deployment).`, { cause: t });
2344
+ throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${$i(n.apiName)} / VOLTRO_API_ORIGIN` : "Set the api server origin"} to the api's SSR-reachable origin (internal cluster DNS in a split deployment).`, { cause: t });
2076
2345
  }
2077
2346
  if (!o.ok) throw Error(`[loader.query] ${r}: HTTP ${o.status} ${await o.text()}`);
2078
2347
  let s = await o.json();
@@ -2090,8 +2359,8 @@ import {
2090
2359
  }
2091
2360
  if (u) return l;
2092
2361
  };
2093
- }, Ni = async (e, t, n, r = {}) => {
2094
- let i = t.title ?? t.name ?? "app", a = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", o = T(p(e, "node_modules", "@voltro", "devtools", "package.json")) || await ti() !== null, s = t.theme === "system" ? [
2362
+ }, $ = async (e, t, n, r = {}) => {
2363
+ let i = t.title ?? t.name ?? "app", a = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", o = T(p(e, "node_modules", "@voltro", "devtools", "package.json")) || await Ti() !== null, s = t.theme === "system" ? [
2095
2364
  " <script>",
2096
2365
  " (function () {",
2097
2366
  " var root = document.documentElement",
@@ -2129,9 +2398,9 @@ import {
2129
2398
  " </body>",
2130
2399
  "</html>",
2131
2400
  ""
2132
- ].join("\n"), l = p(e, "src", "pages"), { pages: u, dirs: d, orphanedSpecials: f } = await $(l);
2133
- await or(l, u);
2134
- for (let e of f) Z.warn(`src/pages/${e.dir || "."}/ contains ${e.files.join(", ")} but no page.tsx at or below it — ${e.files.length > 1 ? "those files are" : "that file is"} inert. A layout/error/loading/not-found file only applies to routes in its own directory tree; if this is an ordinary component, rename it so it does not read as a route boundary.`);
2401
+ ].join("\n"), l = p(e, "src", "pages"), { pages: u, dirs: d, orphanedSpecials: f } = await Q(l);
2402
+ await Er(l, u);
2403
+ for (let e of f) X.warn(`src/pages/${e.dir || "."}/ contains ${e.files.join(", ")} but no page.tsx at or below it — ${e.files.length > 1 ? "those files are" : "that file is"} inert. A layout/error/loading/not-found file only applies to routes in its own directory tree; if this is an ordinary component, rename it so it does not read as a route boundary.`);
2135
2404
  let m = (e) => `${e.replace(/[^a-zA-Z0-9]/g, "_")}AppGroup`, h = (e) => `${e.replace(/[^a-zA-Z0-9]/g, "_")}AppDescriptors`, g = n.map((e) => `import { appGroup as ${m(e.name)}, appDescriptors as ${h(e.name)} } from '${e.pkg}/rpcGroup'`);
2136
2405
  n.some((e) => e.hasAuthHeaders) && (g.push("import __voltroAppConfig from '../app.config'"), g.push("const __voltroAuthHeaders = (__voltroAppConfig as { readonly apis?: Record<string, { readonly authHeaders?: () => Record<string, string> | Promise<Record<string, string>> }> }).apis"));
2137
2406
  let _ = n.map((e) => {
@@ -2142,16 +2411,16 @@ import {
2142
2411
  let n = u.map((e) => ` ${JSON.stringify(e.pattern)}: () => import('../src/pages/${e.file}'),`), r = [];
2143
2412
  for (let e of d) {
2144
2413
  let t = e.dir === "" ? "../src/pages" : `../src/pages/${e.dir}`;
2145
- e.hasLayout && e.hasLayoutLoader ? r.push(`import * as ${Q(e.dir, "Layout")}Mod from '${t}/layout.tsx'`) : e.hasLayout && r.push(`import ${Q(e.dir, "Layout")} from '${t}/layout.tsx'`), e.hasError && r.push(`import ${Q(e.dir, "Error")} from '${t}/error.tsx'`), e.hasPending && r.push(`import ${Q(e.dir, "Pending")} from '${t}/loading.tsx'`), e.hasNotFound && r.push(`import ${Q(e.dir, "NotFound")} from '${t}/not-found.tsx'`);
2414
+ e.hasLayout && e.hasLayoutLoader ? r.push(`import * as ${Z(e.dir, "Layout")}Mod from '${t}/layout.tsx'`) : e.hasLayout && r.push(`import ${Z(e.dir, "Layout")} from '${t}/layout.tsx'`), e.hasError && r.push(`import ${Z(e.dir, "Error")} from '${t}/error.tsx'`), e.hasPending && r.push(`import ${Z(e.dir, "Pending")} from '${t}/loading.tsx'`), e.hasNotFound && r.push(`import ${Z(e.dir, "NotFound")} from '${t}/not-found.tsx'`);
2146
2415
  }
2147
2416
  let i = u.map((e) => {
2148
- let t = hi(d, e.dirChain).map((e) => {
2417
+ let t = zi(d, e.dirChain).map((e) => {
2149
2418
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2150
2419
  return e.hasLayout && t.push(`Layout: refs.layouts[${n}]`), e.hasLayoutLoader && t.push(`loader: refs.layoutLoaders[${n}]`), e.hasError && t.push(`Error: refs.errors[${n}]`), e.hasPending && t.push(`Pending: refs.pendings[${n}]`), ` { ${t.join(", ")} }`;
2151
2420
  }).join(",\n");
2152
2421
  return ` makePageRoute(${JSON.stringify(e.pattern)}, ${t.length > 0 ? `[\n${t},\n ]` : "undefined"}),`;
2153
2422
  }), a = d.filter((e) => e.hasNotFound).map((e) => {
2154
- let t = _i(e.chain), n = hi(d, e.chain).map((e) => {
2423
+ let t = Vi(e.chain), n = zi(d, e.chain).map((e) => {
2155
2424
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2156
2425
  return e.hasLayout && t.push(`Layout: refs.layouts[${n}]`), e.hasError && t.push(`Error: refs.errors[${n}]`), ` { ${t.join(", ")} }`;
2157
2426
  }).join(",\n"), r = n.length > 0 ? `\n chain: [\n${n},\n ],` : "";
@@ -2159,23 +2428,23 @@ import {
2159
2428
  }), s = [], c = [], l = [], f = [], m = [], h = [];
2160
2429
  for (let e of d) {
2161
2430
  let t = e.dir === "" ? "../src/pages/layout.tsx" : `../src/pages/${e.dir}/layout.tsx`, n = e.dir === "" ? "../src/pages/error.tsx" : `../src/pages/${e.dir}/error.tsx`, r = e.dir === "" ? "../src/pages/loading.tsx" : `../src/pages/${e.dir}/loading.tsx`, i = e.dir === "" ? "../src/pages/not-found.tsx" : `../src/pages/${e.dir}/not-found.tsx`, a = JSON.stringify(e.dir);
2162
- e.hasLayout && e.hasLayoutLoader ? (c.push(` ${a}: ${Q(e.dir, "Layout")}Mod.default,`), l.push(` ${a}: ${Q(e.dir, "Layout")}Mod.loader,`), s.push({
2431
+ e.hasLayout && e.hasLayoutLoader ? (c.push(` ${a}: ${Z(e.dir, "Layout")}Mod.default,`), l.push(` ${a}: ${Z(e.dir, "Layout")}Mod.loader,`), s.push({
2163
2432
  relPath: t,
2164
2433
  kind: "layout",
2165
2434
  slotKey: e.dir
2166
- })) : e.hasLayout && (c.push(` ${a}: ${Q(e.dir, "Layout")},`), s.push({
2435
+ })) : e.hasLayout && (c.push(` ${a}: ${Z(e.dir, "Layout")},`), s.push({
2167
2436
  relPath: t,
2168
2437
  kind: "layout",
2169
2438
  slotKey: e.dir
2170
- })), e.hasError && (f.push(` ${a}: ${Q(e.dir, "Error")},`), s.push({
2439
+ })), e.hasError && (f.push(` ${a}: ${Z(e.dir, "Error")},`), s.push({
2171
2440
  relPath: n,
2172
2441
  kind: "error",
2173
2442
  slotKey: e.dir
2174
- })), e.hasPending && (m.push(` ${a}: ${Q(e.dir, "Pending")},`), s.push({
2443
+ })), e.hasPending && (m.push(` ${a}: ${Z(e.dir, "Pending")},`), s.push({
2175
2444
  relPath: r,
2176
2445
  kind: "pending",
2177
2446
  slotKey: e.dir
2178
- })), e.hasNotFound && (h.push(` ${a}: ${Q(e.dir, "NotFound")},`), s.push({
2447
+ })), e.hasNotFound && (h.push(` ${a}: ${Z(e.dir, "NotFound")},`), s.push({
2179
2448
  relPath: i,
2180
2449
  kind: "notFound",
2181
2450
  slotKey: e.dir
@@ -2190,7 +2459,7 @@ import {
2190
2459
  let n = JSON.stringify(e.slotKey);
2191
2460
  return e.kind === "page" ? ` if (newMods[${t}] && refs.pages[${n}] !== undefined) { refs.pages[${n}] = newMods[${t}]; changed = true }` : ` if (newMods[${t}]?.default) { refs.${e.kind === "layout" ? "layouts" : e.kind === "error" ? "errors" : e.kind === "pending" ? "pendings" : "notFounds"}[${n}] = newMods[${t}].default;${e.kind === "layout" ? ` refs.layoutLoaders[${n}] = newMods[${t}].loader;` : ""} changed = true }`;
2192
2461
  }), C = t.locales ?? [], w = C.length > 0 && C.every((t) => T(p(e, "src", "locales", `${t}.ts`)) || T(p(e, "src", "locales", `${t}.tsx`))), E = w, D = t.defaultLocale ?? C[0] ?? "en";
2193
- if (C.length > 0 && !w && Z.info(`i18n: locales [${C.join(", ")}] declared with no src/locales/<code>.ts — using them for <html lang> and the resolved locale only. Add the catalogs to get <I18nProvider> wired, or keep your own i18n stack.`), C.length > 0 && !C.includes(D)) throw Error(`[voltro dev] app.config.ts: defaultLocale '${D}' must be one of locales [${C.join(", ")}]`);
2462
+ if (C.length > 0 && !w && X.info(`i18n: locales [${C.join(", ")}] declared with no src/locales/<code>.ts — using them for <html lang> and the resolved locale only. Add the catalogs to get <I18nProvider> wired, or keep your own i18n stack.`), C.length > 0 && !C.includes(D)) throw Error(`[voltro dev] app.config.ts: defaultLocale '${D}' must be one of locales [${C.join(", ")}]`);
2194
2463
  let O = E ? [
2195
2464
  "import { I18nProvider } from '@voltro/i18n'",
2196
2465
  "import { resolveLocale } from '@voltro/i18n/server'",
@@ -2407,14 +2676,14 @@ import {
2407
2676
  "// resolved apis map. Side-effect only — no local component definitions —",
2408
2677
  "// so downstream invalidations (user page edits) terminate at app.tsx.",
2409
2678
  "",
2410
- ...oi(t),
2679
+ ...Ai(t),
2411
2680
  "import { mount } from '@voltro/web'",
2412
2681
  ...g,
2413
2682
  "import { App } from './app'",
2414
2683
  "import { preloadCurrentRoute } from './routeTable'",
2415
- ...ii(t),
2416
- ...ni(t, o),
2417
- ...ai(t),
2684
+ ...Oi(t),
2685
+ ...Ei(t, o),
2686
+ ...ki(t),
2418
2687
  "",
2419
2688
  "// Preload the current route's page chunk BEFORE hydration so the first",
2420
2689
  "// client render matches the SSG/SSR-prerendered HTML. Without it, a lazy",
@@ -2431,10 +2700,10 @@ import {
2431
2700
  " apis: {",
2432
2701
  ..._,
2433
2702
  " },",
2434
- ...ri(t, o),
2703
+ ...Di(t, o),
2435
2704
  "})",
2436
2705
  "",
2437
- vi
2706
+ Hi
2438
2707
  ].join("\n");
2439
2708
  } else v = "", y = "", b = [
2440
2709
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
@@ -2442,25 +2711,25 @@ import {
2442
2711
  "// and calls mount(). Side-effect only, no component definitions, so the",
2443
2712
  "// user's component file remains the Fast Refresh boundary.",
2444
2713
  "",
2445
- ...oi(t),
2714
+ ...Ai(t),
2446
2715
  "import { mount } from '@voltro/web'",
2447
2716
  ...g,
2448
2717
  "import App from '../src/App'",
2449
- ...ii(t),
2450
- ...ni(t, o),
2451
- ...ai(t),
2718
+ ...Oi(t),
2719
+ ...Ei(t, o),
2720
+ ...ki(t),
2452
2721
  "",
2453
2722
  "mount(App, {",
2454
2723
  " apis: {",
2455
2724
  ..._,
2456
2725
  " },",
2457
- ...ri(t, o),
2726
+ ...Di(t, o),
2458
2727
  "})",
2459
2728
  "",
2460
- vi
2729
+ Hi
2461
2730
  ].join("\n");
2462
2731
  let x = p(e, ".framework");
2463
- await O.mkdir(x, { recursive: !0 }), t.env ? await nt(x, r) : await O.rm(p(x, "env.public.ts"), { force: !0 }), await O.writeFile(p(x, "index.html"), c, "utf8"), await O.writeFile(p(x, "main.tsx"), b, "utf8"), v ? (await O.writeFile(p(x, "app.tsx"), v, "utf8"), await O.writeFile(p(x, "routeTable.ts"), y, "utf8")) : (await O.rm(p(x, "app.tsx"), { force: !0 }), await O.rm(p(x, "routeTable.ts"), { force: !0 }));
2732
+ await O.mkdir(x, { recursive: !0 }), t.env ? await rt(x, r) : await O.rm(p(x, "env.public.ts"), { force: !0 }), await O.writeFile(p(x, "index.html"), c, "utf8"), await O.writeFile(p(x, "main.tsx"), b, "utf8"), v ? (await O.writeFile(p(x, "app.tsx"), v, "utf8"), await O.writeFile(p(x, "routeTable.ts"), y, "utf8")) : (await O.rm(p(x, "app.tsx"), { force: !0 }), await O.rm(p(x, "routeTable.ts"), { force: !0 }));
2464
2733
  let S = p(e, ".gitignore"), C = "";
2465
2734
  try {
2466
2735
  C = await O.readFile(S, "utf8");
@@ -2471,65 +2740,65 @@ import {
2471
2740
  try {
2472
2741
  await O.appendFile(S, `${e}${D.join("\n")}\n`, "utf8");
2473
2742
  } catch (e) {
2474
- Z.warn(`could not add ${D.join(", ")} to ${S} — add it by hand so the generated directory stays out of git. The build is unaffected.`, { reason: e?.message ?? String(e) });
2743
+ X.warn(`could not add ${D.join(", ")} to ${S} — add it by hand so the generated directory stays out of git. The build is unaffected.`, { reason: e?.message ?? String(e) });
2475
2744
  }
2476
2745
  }
2477
- }, Pi = async (e, t) => {
2746
+ }, ra = async (e, t) => {
2478
2747
  try {
2479
2748
  let n = p(d(e), "project.json");
2480
2749
  if (!T(n)) return;
2481
2750
  let r = await O.readFile(n, "utf8"), i = JSON.parse(r).apps ?? {}, a = e.split("/").filter(Boolean).pop() ?? "", o = [];
2482
2751
  for (let [e, n] of Object.entries(i)) e !== a && n.port === t && o.push(e);
2483
2752
  if (o.length === 0) return;
2484
- Z.warn("sibling app(s) claim the same port — only one boots", {
2753
+ X.warn("sibling app(s) claim the same port — only one boots", {
2485
2754
  port: t,
2486
2755
  conflicts: o,
2487
2756
  projectJson: n
2488
2757
  });
2489
2758
  } catch {}
2490
- }, Fi = (e) => p(e, ".framework", "dist", "server", "appConfig.js"), Ii = async (e) => {
2491
- let t = Fi(e), n = T(t) ? t : p(e, "app.config.ts");
2759
+ }, ia = (e) => p(e, ".framework", "dist", "server", "appConfig.js"), aa = async (e, t = {}) => {
2760
+ let n = ia(e), r = t.preferSource !== !0 && T(n) ? n : p(e, "app.config.ts");
2492
2761
  try {
2493
- let e = (await import(_(n).href)).default;
2762
+ let e = (await import(_(r).href)).default;
2494
2763
  return typeof e == "object" && e && "type" in e && e.type === "web" ? e : null;
2495
2764
  } catch {
2496
2765
  return null;
2497
2766
  }
2498
- }, Li = async (e) => {
2499
- let t = await Ii(e);
2767
+ }, oa = async (e) => {
2768
+ let t = await aa(e, { preferSource: !0 });
2500
2769
  if (!t) return {
2501
2770
  ran: !1,
2502
2771
  exitCode: 0
2503
2772
  };
2504
- Nn();
2505
- let n = qt();
2506
- fn(n), Z.info("booting voltro dev (web)", { app: t.name ?? "(unnamed)" });
2507
- let r = await Di(e, t);
2508
- for (let e of r) Z.info("api wired", {
2773
+ $n();
2774
+ let n = mn();
2775
+ Mn(n), X.info("booting voltro dev (web)", { app: t.name ?? "(unnamed)" }), Lt(e, X);
2776
+ let r = await Zi(e, t);
2777
+ for (let e of r) X.info("api wired", {
2509
2778
  name: e.name,
2510
2779
  pkg: e.pkg,
2511
2780
  ...e.proxyTarget ? { proxyTo: e.proxyTarget } : { directWs: e.browserWsUrl }
2512
2781
  });
2513
- Me(e).then((e) => {
2782
+ Ne(e).then((e) => {
2514
2783
  for (let t of e.files) if (t.action === "created") {
2515
2784
  let e = t.path.split("/").pop() ?? t.path;
2516
- Z.info(`${e} seeded`, { path: t.path });
2785
+ X.info(`${e} seeded`, { path: t.path });
2517
2786
  }
2518
2787
  }).catch(() => {});
2519
- let { resolved: d } = await rt({
2788
+ let { resolved: d } = await it({
2520
2789
  rawEnv: t.env,
2521
2790
  appType: "web",
2522
2791
  root: e,
2523
- log: Z,
2792
+ log: X,
2524
2793
  generateTypes: !0
2525
2794
  }), f = d.publicValues;
2526
- await Ni(e, t, r, f), Z.debug("generated framework entry files", { files: [
2795
+ await $(e, t, r, f), X.debug("generated framework entry files", { files: [
2527
2796
  "index.html",
2528
2797
  ".framework/main.tsx",
2529
2798
  ...t.env ? [".framework/env.public.ts"] : []
2530
2799
  ] });
2531
- let g = process.env.VOLTRO_IS_DASHBOARD === "1" && process.env.VOLTRO_DASHBOARD_PORT ? Number(process.env.VOLTRO_DASHBOARD_PORT) : t.port ?? 5173, _ = t.name ?? "unnamed", v = Ke("web", _, g), y = pr(_);
2532
- await We({
2800
+ let g = process.env.VOLTRO_IS_DASHBOARD === "1" && process.env.VOLTRO_DASHBOARD_PORT ? Number(process.env.VOLTRO_DASHBOARD_PORT) : t.port ?? 5173, _ = t.name ?? "unnamed", v = qe("web", _, g), y = Nr(_);
2801
+ await Ge({
2533
2802
  id: v,
2534
2803
  name: _,
2535
2804
  kind: "web",
@@ -2537,22 +2806,22 @@ import {
2537
2806
  pid: process.pid,
2538
2807
  status: "booting",
2539
2808
  logFile: y.path
2540
- }).catch(() => {}), await Pi(e, g);
2541
- let { pages: b, dirs: x } = await $(p(e, "src", "pages")), S = {
2809
+ }).catch(() => {}), await ra(e, g);
2810
+ let { pages: b, dirs: x } = await Q(p(e, "src", "pages")), S = {
2542
2811
  dirs: x,
2543
- ssrRoutes: bi(b)
2812
+ ssrRoutes: Wi(b)
2544
2813
  }, w = x.map((e) => ({
2545
2814
  dir: e.dir,
2546
2815
  hasLayout: e.hasLayout,
2547
2816
  hasError: e.hasError,
2548
2817
  hasPending: e.hasPending,
2549
2818
  hasNotFound: e.hasNotFound
2550
- })), E = await zt({
2819
+ })), E = await on({
2551
2820
  appRoot: e,
2552
2821
  pages: b
2553
2822
  });
2554
- E.wrote && Z.debug("routes codegen wrote", { path: m(e, E.path) });
2555
- let D = await Xe("vite", () => import("vite")), ee = (await import("@vitejs/plugin-react")).default, k = (await import("@tailwindcss/vite")).default, A = p(e, ".framework"), j = p(e, "src"), te = /* @__PURE__ */ new Set([
2823
+ E.wrote && X.debug("routes codegen wrote", { path: m(e, E.path) });
2824
+ let D = await Ze("vite", () => import("vite")), k = (await import("@vitejs/plugin-react")).default, A = (await import("@tailwindcss/vite")).default, j = p(e, ".framework"), M = p(e, "src"), N = /* @__PURE__ */ new Set([
2556
2825
  ".framework",
2557
2826
  "node_modules",
2558
2827
  "dist",
@@ -2560,15 +2829,15 @@ import {
2560
2829
  ".vite",
2561
2830
  ".turbo",
2562
2831
  ".cache"
2563
- ]), ne = {
2832
+ ]), ee = {
2564
2833
  name: "framework:watch-app-sources",
2565
2834
  async configureServer(t) {
2566
2835
  try {
2567
- let n = (await O.readdir(e, { withFileTypes: !0 })).filter((e) => e.isDirectory() && !te.has(e.name));
2836
+ let n = (await O.readdir(e, { withFileTypes: !0 })).filter((e) => e.isDirectory() && !N.has(e.name));
2568
2837
  for (let r of n) t.watcher.add(p(e, r.name));
2569
- n.length === 0 && t.watcher.add(j);
2838
+ n.length === 0 && t.watcher.add(M);
2570
2839
  } catch {
2571
- t.watcher.add(j);
2840
+ t.watcher.add(M);
2572
2841
  }
2573
2842
  try {
2574
2843
  let n = await O.readFile(p(e, "package.json"), "utf8"), r = JSON.parse(n), i = Object.keys({
@@ -2576,7 +2845,7 @@ import {
2576
2845
  ...r.devDependencies
2577
2846
  });
2578
2847
  await Promise.all(i.map(async (n) => {
2579
- let r = await Si(e, n);
2848
+ let r = await Ki(e, n);
2580
2849
  if (!r) return;
2581
2850
  let i = p(r, "src");
2582
2851
  try {
@@ -2585,63 +2854,63 @@ import {
2585
2854
  }));
2586
2855
  } catch {}
2587
2856
  }
2588
- }, M = p(e, "src", "pages"), N = (e) => e.endsWith(".tsx") && (e === M || e.startsWith(M + "/")), re = (e) => e === M || e.startsWith(M + "/"), P = async (n) => {
2857
+ }, P = p(e, "src", "pages"), F = (e) => e.endsWith(".tsx") && (e === P || e.startsWith(P + "/")), I = (e) => e === P || e.startsWith(P + "/"), te = async (n) => {
2589
2858
  try {
2590
2859
  let i = Date.now();
2591
- await Ni(e, t, r, f);
2592
- let { pages: a, dirs: o } = await $(M);
2593
- await zt({
2860
+ await $(e, t, r, f);
2861
+ let { pages: a, dirs: o } = await Q(P);
2862
+ await on({
2594
2863
  appRoot: e,
2595
2864
  pages: a
2596
- }), S.dirs = o, S.ssrRoutes = bi(a), Z.info("page tree regenerated", {
2865
+ }), S.dirs = o, S.ssrRoutes = Wi(a), X.info("page tree regenerated", {
2597
2866
  reason: n,
2598
2867
  ms: Date.now() - i,
2599
2868
  routes: S.ssrRoutes.length
2600
2869
  });
2601
2870
  } catch (e) {
2602
- Z.error("page tree regen failed", { reason: n }, e);
2871
+ X.error("page tree regen failed", { reason: n }, e);
2603
2872
  }
2604
- }, F = {
2873
+ }, L = {
2605
2874
  name: "framework:regenerate-on-page-tree-change",
2606
2875
  configureServer(t) {
2607
2876
  let n = null, r = [], i = (e) => {
2608
2877
  r.push(e), n && clearTimeout(n), n = setTimeout(() => {
2609
2878
  n = null;
2610
2879
  let e = r.length === 1 ? r[0] : `${r.length} events (${r[0]}, …)`;
2611
- r.length = 0, P(e);
2880
+ r.length = 0, te(e);
2612
2881
  }, 50);
2613
2882
  };
2614
2883
  t.watcher.on("add", (t) => {
2615
- N(t) && i(`add ${m(e, t)}`);
2884
+ F(t) && i(`add ${m(e, t)}`);
2616
2885
  }), t.watcher.on("unlink", (t) => {
2617
- N(t) && i(`unlink ${m(e, t)}`);
2886
+ F(t) && i(`unlink ${m(e, t)}`);
2618
2887
  }), t.watcher.on("addDir", (t) => {
2619
- re(t) && i(`addDir ${m(e, t)}`);
2888
+ I(t) && i(`addDir ${m(e, t)}`);
2620
2889
  }), t.watcher.on("unlinkDir", (t) => {
2621
- re(t) && i(`unlinkDir ${m(e, t)}`);
2890
+ I(t) && i(`unlinkDir ${m(e, t)}`);
2622
2891
  });
2623
2892
  }
2624
- }, I = p(e, "app.config.ts"), ie = (e) => {
2625
- if (!B(e.env)) return "";
2893
+ }, R = p(e, "app.config.ts"), ne = (e) => {
2894
+ if (!ae(e.env)) return "";
2626
2895
  let t = Object.entries(e.env.vars).map(([e, t]) => `${e}:${t.access}`).sort();
2627
2896
  return `${String(e.env.publicPrefix)}|${t.join(",")}`;
2628
- }, L = (e, t) => {
2897
+ }, re = (e, t) => {
2629
2898
  let n = [];
2630
- return e.port !== t.port && n.push(`port ${e.port ?? "(default)"} → ${t.port ?? "(default)"}`), JSON.stringify(e.proxies) !== JSON.stringify(t.proxies) && n.push("proxies"), JSON.stringify(e.allowedHosts) !== JSON.stringify(t.allowedHosts) && n.push("allowedHosts"), JSON.stringify(e.apis) !== JSON.stringify(t.apis) && n.push("apis"), ie(e) !== ie(t) && n.push("env"), n;
2631
- }, R = t, z = h(I), ae = {
2899
+ return e.port !== t.port && n.push(`port ${e.port ?? "(default)"} → ${t.port ?? "(default)"}`), JSON.stringify(e.proxies) !== JSON.stringify(t.proxies) && n.push("proxies"), JSON.stringify(e.allowedHosts) !== JSON.stringify(t.allowedHosts) && n.push("allowedHosts"), JSON.stringify(e.apis) !== JSON.stringify(t.apis) && n.push("apis"), ne(e) !== ne(t) && n.push("env"), n;
2900
+ }, z = t, ie = h(R), B = {
2632
2901
  name: "framework:watch-app-config",
2633
2902
  async configureServer(t) {
2634
- t.watcher.add(I), Z.info("watching app.config.ts for changes", { path: m(e, I) });
2903
+ t.watcher.add(R), X.info("watching app.config.ts for changes", { path: m(e, R) });
2635
2904
  let n = async () => {
2636
2905
  try {
2637
2906
  try {
2638
- let e = t.moduleGraph.getModuleById(I);
2907
+ let e = t.moduleGraph.getModuleById(R);
2639
2908
  e && t.moduleGraph.invalidateModule(e);
2640
2909
  } catch {}
2641
- let e = (await t.ssrLoadModule(I, { fixStacktrace: !0 })).default;
2642
- return typeof e == "object" && e && "type" in e && e.type === "web" ? e : (Z.warn("app.config.ts re-load returned wrong shape", { hasDefault: e !== void 0 }), null);
2910
+ let e = (await t.ssrLoadModule(R, { fixStacktrace: !0 })).default;
2911
+ return typeof e == "object" && e && "type" in e && e.type === "web" ? e : (X.warn("app.config.ts re-load returned wrong shape", { hasDefault: e !== void 0 }), null);
2643
2912
  } catch (e) {
2644
- return Z.warn("app.config.ts re-load failed — ignoring this change", {}, e), null;
2913
+ return X.warn("app.config.ts re-load failed — ignoring this change", {}, e), null;
2645
2914
  }
2646
2915
  }, r = null, i = () => {
2647
2916
  r && clearTimeout(r), r = setTimeout(() => {
@@ -2650,20 +2919,20 @@ import {
2650
2919
  }, a = async () => {
2651
2920
  let r = await n();
2652
2921
  if (!r) {
2653
- Z.info("app.config.ts onConfigChange: load returned null — skipping");
2922
+ X.info("app.config.ts onConfigChange: load returned null — skipping");
2654
2923
  return;
2655
2924
  }
2656
- if (Z.info("app.config.ts onConfigChange: loaded", {
2925
+ if (X.info("app.config.ts onConfigChange: loaded", {
2657
2926
  theme: r.theme,
2658
2927
  port: r.port,
2659
2928
  name: r.name
2660
- }), JSON.stringify(r) === JSON.stringify(R)) {
2661
- Z.info("app.config.ts onConfigChange: parsed config unchanged — skipping (no-op edit?)");
2929
+ }), JSON.stringify(r) === JSON.stringify(z)) {
2930
+ X.info("app.config.ts onConfigChange: parsed config unchanged — skipping (no-op edit?)");
2662
2931
  return;
2663
2932
  }
2664
- let i = L(R, r);
2933
+ let i = re(z, r);
2665
2934
  if (i.length > 0) {
2666
- Z.warn("app.config.ts changed — hard restart required", { fields: i });
2935
+ X.warn("app.config.ts changed — hard restart required", { fields: i });
2667
2936
  try {
2668
2937
  await t.close();
2669
2938
  } catch {}
@@ -2677,45 +2946,45 @@ import {
2677
2946
  process.on("SIGINT", r), process.on("SIGTERM", a), e.on("exit", (e, t) => {
2678
2947
  process.off("SIGINT", r), process.off("SIGTERM", a), t ? process.kill(process.pid, t) : process.exit(e ?? 0);
2679
2948
  }), e.on("error", (e) => {
2680
- Z.error("restart spawn failed", {}, e), process.exit(1);
2949
+ X.error("restart spawn failed", {}, e), process.exit(1);
2681
2950
  });
2682
2951
  return;
2683
2952
  }
2684
2953
  try {
2685
2954
  let n = Date.now();
2686
- await Ni(e, r, await Di(e, r)), R = r, t.ws && t.ws.send({
2955
+ await $(e, r, await Zi(e, r)), z = r, t.ws && t.ws.send({
2687
2956
  type: "full-reload",
2688
2957
  path: "*"
2689
- }), Z.info("app.config.ts soft-regen", {
2958
+ }), X.info("app.config.ts soft-regen", {
2690
2959
  ms: Date.now() - n,
2691
2960
  reload: "full"
2692
2961
  });
2693
2962
  } catch (e) {
2694
- Z.error("app.config.ts soft-regen failed", {}, e);
2963
+ X.error("app.config.ts soft-regen failed", {}, e);
2695
2964
  }
2696
- }, o = (e) => u(e) === "app.config.ts" ? e === I || h(e) === z : !1;
2965
+ }, o = (e) => u(e) === "app.config.ts" ? e === R || h(e) === ie : !1;
2697
2966
  t.watcher.on("change", (e) => {
2698
- o(e) && (Z.info("app.config.ts change event (chokidar)", { file: e }), i());
2967
+ o(e) && (X.info("app.config.ts change event (chokidar)", { file: e }), i());
2699
2968
  }), t.watcher.on("add", (e) => {
2700
- o(e) && (Z.info("app.config.ts add event (chokidar)", { file: e }), i());
2969
+ o(e) && (X.info("app.config.ts add event (chokidar)", { file: e }), i());
2701
2970
  });
2702
2971
  try {
2703
2972
  let { watchFile: e } = await import("node:fs");
2704
- e(I, { interval: 500 }, (e, t) => {
2705
- e.mtimeMs !== t.mtimeMs && (Z.info("app.config.ts change event (poll)", { mtime: e.mtimeMs }), i());
2706
- }), Z.info("app.config.ts polling watcher attached", { intervalMs: 500 });
2973
+ e(R, { interval: 500 }, (e, t) => {
2974
+ e.mtimeMs !== t.mtimeMs && (X.info("app.config.ts change event (poll)", { mtime: e.mtimeMs }), i());
2975
+ }), X.info("app.config.ts polling watcher attached", { intervalMs: 500 });
2707
2976
  } catch (e) {
2708
- Z.warn("app.config.ts polling watcher could not attach", {}, e);
2977
+ X.warn("app.config.ts polling watcher could not attach", {}, e);
2709
2978
  }
2710
- _t(mt, Z, {
2979
+ vt(ht, X, {
2711
2980
  root: e,
2712
2981
  onBeforeRestart: () => t.close()
2713
2982
  });
2714
2983
  }
2715
- }, oe = /\/apps\/[^/]+\/.*\.(route|mutation|workflow|schema)\.tsx?$/, V = 0, se = {
2984
+ }, V = /\/apps\/[^/]+\/.*\.(route|mutation|workflow|schema)\.tsx?$/, oe = 0, se = {
2716
2985
  name: "framework:suppress-api-hmr",
2717
2986
  handleHotUpdate(e) {
2718
- if (V += 1, oe.test(e.file)) return [];
2987
+ if (oe += 1, V.test(e.file)) return [];
2719
2988
  }
2720
2989
  }, ce = {
2721
2990
  name: "framework:reoptimize-on-rpcgroup-change",
@@ -2723,7 +2992,7 @@ import {
2723
2992
  let n = /* @__PURE__ */ new Map();
2724
2993
  for (let i of r) {
2725
2994
  if (!i.proxyTarget) continue;
2726
- let r = await Si(e, i.pkg);
2995
+ let r = await Ki(e, i.pkg);
2727
2996
  if (!r) continue;
2728
2997
  let a = p(r, "rpcGroup.generated.ts");
2729
2998
  try {
@@ -2749,14 +3018,14 @@ import {
2749
3018
  i !== t && (n.set(e, i), r = e);
2750
3019
  }
2751
3020
  if (r !== null) {
2752
- a = !0, Z.info(`rpcGroup changed (${m(e, r)}) — re-bundling the api client + reloading (descriptor edits propagate automatically; no manual restart needed)`);
3021
+ a = !0, X.info(`rpcGroup changed (${m(e, r)}) — re-bundling the api client + reloading (descriptor edits propagate automatically; no manual restart needed)`);
2753
3022
  try {
2754
- await O.rm(p(A, ".vite", "deps"), {
3023
+ await O.rm(p(j, ".vite", "deps"), {
2755
3024
  recursive: !0,
2756
3025
  force: !0
2757
3026
  }), await t.restart(!0);
2758
3027
  } catch (e) {
2759
- a = !1, Z.error("rpcGroup re-optimize failed", {}, e);
3028
+ a = !1, X.error("rpcGroup re-optimize failed", {}, e);
2760
3029
  }
2761
3030
  }
2762
3031
  }, s = (e) => {
@@ -2768,7 +3037,7 @@ import {
2768
3037
  }
2769
3038
  }, H = {}, le = (e) => (t) => {
2770
3039
  t.on("proxyReq", (t, n) => {
2771
- jn(t, n, {
3040
+ Zn(t, n, {
2772
3041
  target: e,
2773
3042
  token: process.env.VOLTRO_INSPECT_TOKEN,
2774
3043
  writeToken: process.env.VOLTRO_INSPECT_WRITE_TOKEN,
@@ -2794,14 +3063,14 @@ import {
2794
3063
  }
2795
3064
  for (let [e, n] of Object.entries(t.proxies ?? {})) {
2796
3065
  if (H[e]) {
2797
- Z.warn("user proxy ignored — prefix already claimed by an api ws proxy", { prefix: e });
3066
+ X.warn("user proxy ignored — prefix already claimed by an api ws proxy", { prefix: e });
2798
3067
  continue;
2799
3068
  }
2800
3069
  H[e] = {
2801
3070
  target: n.target,
2802
3071
  changeOrigin: n.changeOrigin ?? !0,
2803
3072
  ...n.rewrite === void 0 ? {} : { rewrite: (t) => t.replace(RegExp(`^${e}`), n.rewrite) }
2804
- }, Z.info(`proxy ${e} → ${n.target}`, {
3073
+ }, X.info(`proxy ${e} → ${n.target}`, {
2805
3074
  prefix: e,
2806
3075
  target: n.target,
2807
3076
  ...n.rewrite === void 0 ? {} : { rewrite: n.rewrite }
@@ -2819,18 +3088,18 @@ import {
2819
3088
  pattern: n.pattern,
2820
3089
  file: n.file,
2821
3090
  dirChain: n.dirChain,
2822
- renderMode: Qn(i, p("src", "pages", n.file)),
3091
+ renderMode: vr(i, p("src", "pages", n.file)),
2823
3092
  interactive: i.interactive ?? "full",
2824
3093
  tenantAware: i.tenantAware === !0,
2825
- revalidateMs: ct(i.revalidate),
2826
- staleWhileRevalidateMs: ct(i.staleWhileRevalidate) ?? 0,
3094
+ revalidateMs: lt(i.revalidate),
3095
+ staleWhileRevalidateMs: lt(i.staleWhileRevalidate) ?? 0,
2827
3096
  cacheInvalidatesOn: Array.isArray(i.cacheInvalidatesOn) ? i.cacheInvalidatesOn : [],
2828
3097
  hasLoader: typeof i.loader == "function",
2829
3098
  hasMeta: i.meta != null,
2830
3099
  hasGetStaticPaths: typeof i.getStaticPaths == "function"
2831
3100
  });
2832
3101
  } catch (e) {
2833
- Z.warn("inspect: failed to load page metadata", { pattern: n.pattern }, e);
3102
+ X.warn("inspect: failed to load page metadata", { pattern: n.pattern }, e);
2834
3103
  }
2835
3104
  return u = t, t;
2836
3105
  };
@@ -2850,9 +3119,9 @@ import {
2850
3119
  }), r();
2851
3120
  }), r.middlewares.use((t, n, r) => {
2852
3121
  if (t.method !== "GET" && t.method !== "HEAD") return r();
2853
- let { pathname: i } = Ir(t.url ?? "/");
3122
+ let { pathname: i } = ni(t.url ?? "/");
2854
3123
  if (i !== "/robots.txt" || T(p(e, "public", "robots.txt"))) return r();
2855
- n.statusCode = 200, n.setHeader("Content-Type", "text/plain; charset=utf-8"), n.end(Gt({ indexable: !1 }));
3124
+ n.statusCode = 200, n.setHeader("Content-Type", "text/plain; charset=utf-8"), n.end(fn({ indexable: !1 }));
2856
3125
  }), t.name === "voltroDashboard" && r.middlewares.use(async (e, t, n) => {
2857
3126
  let r = e.url ?? "", a = r.split("?")[0];
2858
3127
  if (a === "/api/dashboard/proxy") {
@@ -2943,7 +3212,7 @@ import {
2943
3212
  for (let [t, n] of Object.entries(e.headers ?? {})) n !== void 0 && (u[String(t).toLowerCase()] = Array.isArray(n) ? n.join(", ") : String(n));
2944
3213
  let f = o.split("?")[0];
2945
3214
  if (e.method === "GET" && (f === "/_voltro/inspect/logs" || o.startsWith("/_voltro/inspect/logs?"))) {
2946
- let e = a(u.origin), t = Tn(o, sn(), u);
3215
+ let e = a(u.origin), t = Gn(o, Dn(), u);
2947
3216
  r.statusCode = t.status, r.setHeader("content-type", t.contentType);
2948
3217
  for (let [t, n] of Object.entries(e)) r.setHeader(t, n);
2949
3218
  r.end(t.body);
@@ -2961,7 +3230,7 @@ import {
2961
3230
  e.setEncoding("utf-8"), e.on("data", (e) => {
2962
3231
  i += e;
2963
3232
  }), e.on("end", () => {
2964
- let e = yn(i, n);
3233
+ let e = zn(i, n);
2965
3234
  r.statusCode = e.status, r.setHeader("content-type", e.contentType);
2966
3235
  for (let [e, n] of Object.entries(t)) r.setHeader(e, n);
2967
3236
  r.end(e.body);
@@ -2992,14 +3261,14 @@ import {
2992
3261
  for (let [e, n] of Object.entries(t)) r.setHeader(e, n);
2993
3262
  r.flushHeaders?.(), r.write("retry: 5000\n\n");
2994
3263
  let l = o.indexOf("?");
2995
- if (!(l !== -1 && new URLSearchParams(o.slice(l + 1)).get("live") === "1")) for (let e of n.buffered()) r.write(Jt(e));
3264
+ if (!(l !== -1 && new URLSearchParams(o.slice(l + 1)).get("live") === "1")) for (let e of n.buffered()) r.write(hn(e));
2996
3265
  let d = n.subscribe((e) => {
2997
3266
  try {
2998
- r.write(Jt(e));
3267
+ r.write(hn(e));
2999
3268
  } catch {}
3000
3269
  }), f = setInterval(() => {
3001
3270
  try {
3002
- r.write(Yt());
3271
+ r.write(gn());
3003
3272
  } catch {}
3004
3273
  }, 15e3), p = () => {
3005
3274
  clearInterval(f), d();
@@ -3012,7 +3281,7 @@ import {
3012
3281
  kind: "web",
3013
3282
  meta: {
3014
3283
  name: t.name ?? "(unnamed)",
3015
- voltroVersion: ei,
3284
+ voltroVersion: wi,
3016
3285
  port: g,
3017
3286
  mode: "dev",
3018
3287
  apis: Object.entries(t.apis ?? {}).map(([e, t]) => {
@@ -3030,7 +3299,7 @@ import {
3030
3299
  size: 0,
3031
3300
  entries: []
3032
3301
  }),
3033
- env: () => at(t.name ?? "app", { contract: B(t.env) ? t.env : void 0 })
3302
+ env: () => ot(t.name ?? "app", { contract: ae(t.env) ? t.env : void 0 })
3034
3303
  }, u, { method: e.method ?? "GET" });
3035
3304
  if (n === null) return i();
3036
3305
  r.statusCode = n.status, r.setHeader("content-type", n.contentType);
@@ -3047,19 +3316,19 @@ import {
3047
3316
  e.middlewares.use(async (e, t, n) => {
3048
3317
  if (!(e.url ?? "").startsWith("/api/dashboard/registry")) return n();
3049
3318
  try {
3050
- let e = await Ue();
3319
+ let e = await We();
3051
3320
  t.statusCode = 200, t.setHeader("content-type", "application/json; charset=utf-8"), t.end(JSON.stringify(e));
3052
3321
  } catch (e) {
3053
3322
  t.statusCode = 500, t.setHeader("content-type", "text/plain"), t.end(`registry read error: ${e.message}`);
3054
3323
  }
3055
3324
  });
3056
3325
  }
3057
- } : null, me = /* @__PURE__ */ new Set(), U = (e, t, n, r, i, a = !1) => {
3058
- let o = zr(i, a, t) ?? "";
3059
- if (Z.error(`${t} render failed`, {
3326
+ } : null, me = /* @__PURE__ */ new Set(), he = (e, t, n, r, i, a = !1) => {
3327
+ let o = li(i, a, t) ?? "";
3328
+ if (X.error(`${t} render failed`, {
3060
3329
  pathname: n,
3061
3330
  pattern: r,
3062
- cause: Zt(i) + o
3331
+ cause: vn(i) + o
3063
3332
  }), e.headersSent) {
3064
3333
  e.end();
3065
3334
  return;
@@ -3067,58 +3336,70 @@ import {
3067
3336
  e.writeHead(500, {
3068
3337
  "content-type": "text/plain; charset=utf-8",
3069
3338
  "x-voltro-rendered-by": `${t}-failed`,
3070
- "x-voltro-ssr-generation": String(V)
3339
+ "x-voltro-ssr-generation": String(oe)
3071
3340
  });
3072
- let s = V === 0 ? "" : `\n[voltro] this process has absorbed ${V} hot update(s) since boot, so its SSR\nmodule graph may not match the files on disk. Before reporting this — to us or to\nyourself — restart \`voltro dev\` and measure once from a fresh boot.\n`;
3073
- e.end(`${t} render failed for ${n}\n\n${Zt(i)}\n${o}\n${s}`);
3074
- }, W = Dt(), he = kt({
3075
- limit: W,
3076
- onColdStart: (e) => Z.debug("ssr cold-compile start", { id: e }),
3077
- onColdEnd: (e, { durationMs: t, failed: n }) => Z.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
3341
+ let s = oe === 0 ? "" : `\n[voltro] this process has absorbed ${oe} hot update(s) since boot, so its SSR\nmodule graph may not match the files on disk. Before reporting this — to us or to\nyourself — restart \`voltro dev\` and measure once from a fresh boot.\n`;
3342
+ e.end(`${t} render failed for ${n}\n\n${vn(i)}\n${o}\n${s}`);
3343
+ }, U = qt(), ge = Yt({
3344
+ limit: U,
3345
+ onColdStart: (e) => X.debug("ssr cold-compile start", { id: e }),
3346
+ onColdEnd: (e, { durationMs: t, failed: n }) => X.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
3078
3347
  id: e,
3079
3348
  ms: t,
3080
3349
  ...n ? { failed: !0 } : {}
3081
3350
  })
3082
3351
  });
3083
- Z.debug(`ssr cold-compile concurrency ${W}`, { concurrency: W });
3084
- let G = null, ge = async () => (G === null && (G = await O.readFile(p(e, ".framework", "index.html"), "utf8")), G), _e = {
3352
+ X.debug(`ssr cold-compile concurrency ${U}`, { concurrency: U });
3353
+ let W = null, _e = async () => (W === null && (W = await O.readFile(p(e, ".framework", "index.html"), "utf8")), W), ve = {
3085
3354
  name: "framework:ssr",
3086
3355
  configureServer(n) {
3087
- let i = (e) => he.load(e, async () => await n.ssrLoadModule(e)), a, o = () => {
3356
+ let i = (e) => ge.load(e, async () => await n.ssrLoadModule(e)), a, o = !1, s = () => {
3088
3357
  if (a !== void 0) return a;
3089
3358
  let n = t.locales ?? [], r = t.defaultLocale ?? n[0] ?? "en";
3090
3359
  return n.length === 0 ? (a = Promise.resolve(() => void 0), a) : (a = (async () => {
3091
- let [{ makeSsgWrap: t }, { makeSsrI18nResolver: a }] = await Promise.all([i("@voltro/i18n"), i("@voltro/i18n/server")]), o = {};
3360
+ let [{ makeSsgWrap: t }, { makeSsrI18nResolver: a }] = await Promise.all([i("@voltro/i18n"), i("@voltro/i18n/server")]), s = {};
3092
3361
  for (let a of n) if (T(p(e, "src", "locales", `${a}.ts`))) try {
3093
3362
  let n = (await i(p(e, "src", "locales", `${a}.ts`))).default;
3094
- n !== void 0 && (o[a] = t(a, n, r));
3363
+ n !== void 0 && (s[a] = t(a, n, r));
3095
3364
  } catch (e) {
3096
- Z.warn("locale catalog failed to load for SSR", { locale: a }, e);
3365
+ X.warn("locale catalog failed to load for SSR", { locale: a }, e);
3366
+ }
3367
+ if (o = Object.keys(s).length > 0, Object.keys(s).length === 0) {
3368
+ let { resolveLocale: e } = await i("@voltro/i18n/server");
3369
+ return (t, i) => ({
3370
+ locale: e({
3371
+ cookieHeader: t ?? null,
3372
+ acceptLanguageHeader: i ?? null,
3373
+ supported: n,
3374
+ defaultLocale: r
3375
+ }),
3376
+ outerWrap: (e) => e
3377
+ });
3097
3378
  }
3098
3379
  return a({
3099
- wraps: o,
3380
+ wraps: s,
3100
3381
  supported: n,
3101
3382
  defaultLocale: r
3102
3383
  });
3103
3384
  })(), a);
3104
3385
  };
3105
- n.middlewares.use(async (a, s, c) => {
3106
- if (a.method !== "GET" && a.method !== "HEAD") return c();
3107
- let l = a.url ?? "/";
3108
- l.indexOf("?");
3109
- let { pathname: u, search: d } = Ir(l);
3110
- if (u.startsWith("/@") || u.startsWith("/node_modules/") || u.startsWith("/.framework/") || u.startsWith("/_voltro/") || u === "/main.tsx" || u === "/index.html" || u === "/sw.js" || u === "/favicon.ico" || u === "/robots.txt" || /\.[a-z0-9]+$/i.test(u)) return c();
3111
- let f = xi(u, S.ssrRoutes);
3112
- if (!f) return c();
3113
- let m = !me.has(f.route.pattern), h = Date.now();
3114
- m && Z.info(`ssr compiling ${f.route.pattern}`, {
3115
- pattern: f.route.pattern,
3116
- pathname: u
3386
+ n.middlewares.use(async (a, c, l) => {
3387
+ if (a.method !== "GET" && a.method !== "HEAD") return l();
3388
+ let u = a.url ?? "/";
3389
+ u.indexOf("?");
3390
+ let { pathname: d, search: f } = ni(u);
3391
+ if (d.startsWith("/@") || d.startsWith("/node_modules/") || d.startsWith("/.framework/") || d.startsWith("/_voltro/") || d === "/main.tsx" || d === "/index.html" || d === "/sw.js" || d === "/favicon.ico" || d === "/robots.txt" || /\.[a-z0-9]+$/i.test(d)) return l();
3392
+ let m = Gi(d, S.ssrRoutes);
3393
+ if (!m) return l();
3394
+ let h = !me.has(m.route.pattern), g = Date.now();
3395
+ h && X.info(`ssr compiling ${m.route.pattern}`, {
3396
+ pattern: m.route.pattern,
3397
+ pathname: d
3117
3398
  });
3118
- let g = {}, _ = async (e, t) => {
3399
+ let _ = {}, v = async (e, t) => {
3119
3400
  let n = Date.now(), r = await t();
3120
- return g[e] = (g[e] ?? 0) + (Date.now() - n), r;
3121
- }, v = async (e, t, r) => {
3401
+ return _[e] = (_[e] ?? 0) + (Date.now() - n), r;
3402
+ }, y = async (e, t, r) => {
3122
3403
  let i = await n.moduleGraph.getModuleById(e);
3123
3404
  if (!(!i || t.has(e))) {
3124
3405
  if (t.add(e), i.id && /\.(css|sass|scss|less|stylus|pcss|postcss)(\?|$)/.test(i.id)) {
@@ -3126,234 +3407,234 @@ import {
3126
3407
  r.includes(e) || r.push(e);
3127
3408
  return;
3128
3409
  }
3129
- for (let e of i.importedModules ?? []) e.id && await v(e.id, t, r);
3410
+ for (let e of i.importedModules ?? []) e.id && await y(e.id, t, r);
3130
3411
  }
3131
- }, y = !1;
3412
+ }, b = !1;
3132
3413
  try {
3133
- let b = await _("loadPage", async () => await i(p(e, "src", "pages", f.route.file))), x = Qn(b, p("src", "pages", f.route.file)), C = hi(S.dirs, f.route.dirChain), w = x === "spa" && C.some((e) => e.hasLayout);
3134
- if (x !== "ssr" && x !== "isr" && !w) return c();
3135
- let T = {};
3136
- for (let [e, t] of Object.entries(a.headers ?? {})) typeof t == "string" ? T[e] = t : Array.isArray(t) && (T[e] = t.join(", "));
3137
- let E = Mi(ji(r[0], { allowDevProxy: !0 }), T.cookie, { apiName: r[0]?.name }), D = new AbortController(), O = () => D.abort();
3138
- s.once("close", O);
3139
- let ee = null, k = [], A = {};
3414
+ let x = await v("loadPage", async () => await i(p(e, "src", "pages", m.route.file))), C = vr(x, p("src", "pages", m.route.file)), w = zi(S.dirs, m.route.dirChain), T = C === "spa" && w.some((e) => e.hasLayout);
3415
+ if (C !== "ssr" && C !== "isr" && !T) return l();
3416
+ let E = {};
3417
+ for (let [e, t] of Object.entries(a.headers ?? {})) typeof t == "string" ? E[e] = t : Array.isArray(t) && (E[e] = t.join(", "));
3418
+ let D = na(ta(r[0], { allowDevProxy: !0 }), E.cookie, { apiName: r[0]?.name }), O = new AbortController(), k = () => O.abort();
3419
+ c.once("close", k);
3420
+ let A = null, j = [], M = {};
3140
3421
  try {
3141
- (await i("@voltro/web/ssr")).beginStoreSeeds(), {chain: k, segmentLoaderData: A} = await _("loadChain", () => gi({
3142
- entries: C,
3422
+ (await i("@voltro/web/ssr")).beginStoreSeeds(), {chain: j, segmentLoaderData: M} = await v("loadChain", () => Bi({
3423
+ entries: w,
3143
3424
  loadLayout: (t) => i(p(e, "src", "pages", t.dir, "layout.tsx")),
3144
3425
  loadError: (t) => i(p(e, "src", "pages", t.dir, "error.tsx")),
3145
3426
  loadPending: (t) => i(p(e, "src", "pages", t.dir, "loading.tsx")),
3146
3427
  ctx: {
3147
- params: f.params,
3148
- pathname: u,
3149
- search: d,
3150
- signal: D.signal,
3151
- headers: T,
3152
- query: E
3428
+ params: m.params,
3429
+ pathname: d,
3430
+ search: f,
3431
+ signal: O.signal,
3432
+ headers: E,
3433
+ query: D
3153
3434
  }
3154
3435
  }));
3155
- let t = b.loader;
3156
- typeof t == "function" && !w && (ee = await _("loader", () => t({
3157
- params: f.params,
3158
- pathname: u,
3159
- search: d,
3160
- signal: D.signal,
3161
- headers: T,
3162
- query: E
3436
+ let t = x.loader;
3437
+ typeof t == "function" && !T && (A = await v("loader", () => t({
3438
+ params: m.params,
3439
+ pathname: d,
3440
+ search: f,
3441
+ signal: O.signal,
3442
+ headers: E,
3443
+ query: D
3163
3444
  })));
3164
3445
  } finally {
3165
- s.off("close", O);
3446
+ c.off("close", k);
3166
3447
  }
3167
- let j = await _("loadSsrHelpers", async () => await i("@voltro/web/ssr"));
3168
- w || await Qr({
3169
- pageMod: b,
3170
- params: f.params,
3171
- query: E,
3448
+ let N = await v("loadSsrHelpers", async () => await i("@voltro/web/ssr"));
3449
+ T || await Si({
3450
+ pageMod: x,
3451
+ params: m.params,
3452
+ query: D,
3172
3453
  apiName: r[0]?.name,
3173
- seed: j.seedPreloadedSubscription,
3174
- onError: ({ tag: e, apiName: t }, n) => Z.warn("preload seed failed", {
3454
+ seed: N.seedPreloadedSubscription,
3455
+ onError: ({ tag: e, apiName: t }, n) => X.warn("preload seed failed", {
3175
3456
  tag: e,
3176
3457
  apiName: t,
3177
- pathname: u
3458
+ pathname: d
3178
3459
  }, n)
3179
3460
  });
3180
- let te = {
3181
- pattern: f.route.pattern,
3182
- Component: b.default,
3183
- meta: b.meta,
3184
- loader: b.loader,
3185
- ErrorBoundary: b.ErrorBoundary,
3186
- Pending: b.Pending,
3187
- renderMode: x,
3188
- chain: k
3189
- }, ne = {
3190
- cookies: j.parseCookieHeader(T.cookie),
3191
- headers: T,
3192
- url: l
3193
- }, M = b.interactive ?? "full", N = (await o())(T.cookie, T["accept-language"]);
3194
- y = N !== void 0;
3195
- let re = N ? {
3196
- outerWrap: N.outerWrap,
3197
- locale: N.locale
3198
- } : {}, P = w ? Nr({
3199
- helpers: j,
3200
- page: `src/pages/${f.route.file}`,
3201
- interactive: M,
3461
+ let ee = {
3462
+ pattern: m.route.pattern,
3463
+ Component: x.default,
3464
+ meta: x.meta,
3465
+ loader: x.loader,
3466
+ ErrorBoundary: x.ErrorBoundary,
3467
+ Pending: x.Pending,
3468
+ renderMode: C,
3469
+ chain: j
3470
+ }, P = {
3471
+ cookies: N.parseCookieHeader(E.cookie),
3472
+ headers: E,
3473
+ url: u
3474
+ }, F = x.interactive ?? "full", I = (await s())(E.cookie, E["accept-language"]);
3475
+ b = I !== void 0 && o;
3476
+ let te = I ? {
3477
+ outerWrap: I.outerWrap,
3478
+ locale: I.locale
3479
+ } : {}, L = T ? $r({
3480
+ helpers: N,
3481
+ page: `src/pages/${m.route.file}`,
3482
+ interactive: F,
3202
3483
  delivery: "stream",
3203
3484
  renderInput: {
3204
- descriptor: te,
3205
- params: f.params,
3206
- pathname: u,
3207
- search: d,
3208
- segmentLoaderData: A,
3209
- requestContext: ne,
3210
- ...re
3485
+ descriptor: ee,
3486
+ params: m.params,
3487
+ pathname: d,
3488
+ search: f,
3489
+ segmentLoaderData: M,
3490
+ requestContext: P,
3491
+ ...te
3211
3492
  }
3212
- }) : null, F = w ? null : Mr({
3213
- helpers: j,
3214
- page: `src/pages/${f.route.file}`,
3215
- pathname: u,
3216
- renderMode: x,
3217
- interactive: M,
3218
- loaderData: ee,
3219
- segmentLoaderData: A,
3220
- pageLoaderRan: typeof b.loader == "function"
3221
- }), I = [];
3222
- await _("collectCss", async () => {
3493
+ }) : null, R = T ? null : Qr({
3494
+ helpers: N,
3495
+ page: `src/pages/${m.route.file}`,
3496
+ pathname: d,
3497
+ renderMode: C,
3498
+ interactive: F,
3499
+ loaderData: A,
3500
+ segmentLoaderData: M,
3501
+ pageLoaderRan: typeof x.loader == "function"
3502
+ }), ne = [];
3503
+ await v("collectCss", async () => {
3223
3504
  let t = /* @__PURE__ */ new Set(), n = [
3224
- p(e, "src", "pages", f.route.file),
3225
- ...C.flatMap((t) => [
3505
+ p(e, "src", "pages", m.route.file),
3506
+ ...w.flatMap((t) => [
3226
3507
  ...t.hasLayout ? [p(e, "src", "pages", t.dir, "layout.tsx")] : [],
3227
3508
  ...t.hasError ? [p(e, "src", "pages", t.dir, "error.tsx")] : [],
3228
3509
  ...t.hasPending ? [p(e, "src", "pages", t.dir, "loading.tsx")] : []
3229
3510
  ]),
3230
3511
  p(e, ".framework", "main.tsx")
3231
3512
  ];
3232
- for (let e of n) await v(e, t, I);
3513
+ for (let e of n) await y(e, t, ne);
3233
3514
  });
3234
- let ie = await _("readShell", ge), L = await _("transformShell", () => n.transformIndexHtml(l, ie)), R = I.map((e) => `<link rel="stylesheet" href="${e}?direct" />`).join("\n "), z = N?.locale ?? ne.cookies["voltro:locale"] ?? t.defaultLocale ?? (t.locales ?? [])[0] ?? "en", ae = Date.now();
3235
- if (P) {
3236
- let e = (e) => Fr({
3237
- helpers: j,
3238
- prepared: P,
3515
+ let re = await v("readShell", _e), z = await v("transformShell", () => n.transformIndexHtml(u, re)), ie = ne.map((e) => `<link rel="stylesheet" href="${e}?direct" />`).join("\n "), B = I?.locale ?? P.cookies["voltro:locale"] ?? t.defaultLocale ?? (t.locales ?? [])[0] ?? "en", ae = Date.now();
3516
+ if (L) {
3517
+ let e = (e) => ti({
3518
+ helpers: N,
3519
+ prepared: L,
3239
3520
  meta: e,
3240
- interactive: M,
3241
- extra: [R]
3521
+ interactive: F,
3522
+ extra: [ie]
3242
3523
  });
3243
- if (P.hasDeferred) Yr({
3244
- res: s,
3245
- shell: Kr({
3246
- shell: L,
3524
+ if (L.hasDeferred) yi({
3525
+ res: c,
3526
+ shell: gi({
3527
+ shell: z,
3247
3528
  inlineModuleScriptsAsync: !0
3248
3529
  }),
3249
- htmlLang: z,
3530
+ htmlLang: B,
3250
3531
  headers: {
3251
3532
  "content-type": "text/html; charset=utf-8",
3252
3533
  "x-voltro-rendered-by": "spa-shell-dev"
3253
3534
  },
3254
3535
  headInjection: e,
3255
- render: (e) => j.renderPageToStream({
3256
- ...P.renderInput,
3536
+ render: (e) => N.renderPageToStream({
3537
+ ...L.renderInput,
3257
3538
  ...e
3258
3539
  }),
3259
3540
  onShellError: (e) => {
3260
- U(s, "spa-shell-dev", u, f.route.pattern, e, y);
3541
+ he(c, "spa-shell-dev", d, m.route.pattern, e, b);
3261
3542
  }
3262
3543
  });
3263
3544
  else {
3264
- let t = Pr({
3265
- helpers: j,
3266
- prepared: P
3267
- }), n = L.replace("<div id=\"root\"></div>", `<div id="root">${t.body}</div>`).replace("</head>", ` ${e(t.meta)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${z}"`);
3268
- s.statusCode = 200, s.setHeader("content-type", "text/html; charset=utf-8"), s.setHeader("x-voltro-rendered-by", "spa-shell-dev"), s.end(n);
3545
+ let t = ei({
3546
+ helpers: N,
3547
+ prepared: L
3548
+ }), n = z.replace("<div id=\"root\"></div>", `<div id="root">${t.body}</div>`).replace("</head>", ` ${e(t.meta)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${B}"`);
3549
+ c.statusCode = 200, c.setHeader("content-type", "text/html; charset=utf-8"), c.setHeader("x-voltro-rendered-by", "spa-shell-dev"), c.end(n);
3269
3550
  }
3270
- } else if (F) {
3551
+ } else if (R) {
3271
3552
  let e = (e) => [
3272
- R,
3273
- j.renderMetaToHtml(e),
3274
- `<meta name="voltro-interactive" content="${M}" />`,
3275
- ...F.hasDeferred ? [j.renderDeferredRegistryScript()] : [],
3276
- j.renderRouterStateScript(F.stateInput)
3553
+ ie,
3554
+ N.renderMetaToHtml(e),
3555
+ `<meta name="voltro-interactive" content="${F}" />`,
3556
+ ...R.hasDeferred ? [N.renderDeferredRegistryScript()] : [],
3557
+ N.renderRouterStateScript(R.stateInput)
3277
3558
  ].filter((e) => e.length > 0).join("\n "), t = {
3278
- descriptor: te,
3279
- params: f.params,
3280
- pathname: u,
3281
- search: d,
3282
- loaderData: F.loaderData,
3283
- segmentLoaderData: F.segmentLoaderData,
3284
- requestContext: ne,
3285
- ...re
3559
+ descriptor: ee,
3560
+ params: m.params,
3561
+ pathname: d,
3562
+ search: f,
3563
+ loaderData: R.loaderData,
3564
+ segmentLoaderData: R.segmentLoaderData,
3565
+ requestContext: P,
3566
+ ...te
3286
3567
  };
3287
- if (x === "ssr" && M === "full") Yr({
3288
- res: s,
3289
- shell: Kr({
3290
- shell: L,
3568
+ if (C === "ssr" && F === "full") yi({
3569
+ res: c,
3570
+ shell: gi({
3571
+ shell: z,
3291
3572
  inlineModuleScriptsAsync: !0
3292
3573
  }),
3293
- htmlLang: z,
3574
+ htmlLang: B,
3294
3575
  headers: {
3295
3576
  "content-type": "text/html; charset=utf-8",
3296
3577
  "x-voltro-rendered-by": "ssr-dev"
3297
3578
  },
3298
3579
  headInjection: e,
3299
- render: (e) => j.renderPageToStream({
3580
+ render: (e) => N.renderPageToStream({
3300
3581
  ...t,
3301
3582
  ...e
3302
3583
  }),
3303
3584
  onShellError: (e) => {
3304
- U(s, "ssr-dev", u, f.route.pattern, e, y);
3585
+ he(c, "ssr-dev", d, m.route.pattern, e, b);
3305
3586
  }
3306
3587
  });
3307
3588
  else {
3308
- let { html: n, meta: r } = j.renderPageToHtml(t), i = L.replace("<div id=\"root\"></div>", `<div id="root">${n}</div>`).replace("</head>", ` ${e(r)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${z}"`);
3309
- s.statusCode = 200, s.setHeader("content-type", "text/html; charset=utf-8"), s.setHeader("x-voltro-rendered-by", "ssr-dev"), s.end(i);
3589
+ let { html: n, meta: r } = N.renderPageToHtml(t), i = z.replace("<div id=\"root\"></div>", `<div id="root">${n}</div>`).replace("</head>", ` ${e(r)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${B}"`);
3590
+ c.statusCode = 200, c.setHeader("content-type", "text/html; charset=utf-8"), c.setHeader("x-voltro-rendered-by", "ssr-dev"), c.end(i);
3310
3591
  }
3311
3592
  }
3312
- g.render = Date.now() - ae;
3313
- let B = Date.now() - h;
3314
- m ? (me.add(f.route.pattern), Z.info(`ssr compiled ${f.route.pattern} in ${B}ms`, {
3315
- pattern: f.route.pattern,
3316
- pathname: u,
3317
- elapsedMs: B,
3593
+ _.render = Date.now() - ae;
3594
+ let V = Date.now() - g;
3595
+ h ? (me.add(m.route.pattern), X.info(`ssr compiled ${m.route.pattern} in ${V}ms`, {
3596
+ pattern: m.route.pattern,
3597
+ pathname: d,
3598
+ elapsedMs: V,
3318
3599
  cold: !0,
3319
- phases: g
3320
- })) : B > 200 && Z.info(`ssr rendered ${u} in ${B}ms`, {
3321
- pattern: f.route.pattern,
3322
- pathname: u,
3323
- elapsedMs: B,
3600
+ phases: _
3601
+ })) : V > 200 && X.info(`ssr rendered ${d} in ${V}ms`, {
3602
+ pattern: m.route.pattern,
3603
+ pathname: d,
3604
+ elapsedMs: V,
3324
3605
  cold: !1,
3325
- phases: g
3606
+ phases: _
3326
3607
  });
3327
3608
  } catch (e) {
3328
- if (Ar(e)) {
3329
- Z.error("ssr-dev render refused", {
3330
- pathname: u,
3331
- pattern: f.route.pattern
3332
- }, e), s.statusCode = 500, s.setHeader("content-type", "text/plain; charset=utf-8"), s.end(e.message);
3609
+ if (Xr(e)) {
3610
+ X.error("ssr-dev render refused", {
3611
+ pathname: d,
3612
+ pattern: m.route.pattern
3613
+ }, e), c.statusCode = 500, c.setHeader("content-type", "text/plain; charset=utf-8"), c.end(e.message);
3333
3614
  return;
3334
3615
  }
3335
- let t = jr(e);
3616
+ let t = Zr(e);
3336
3617
  if (t) {
3337
- s.statusCode = t.status;
3338
- for (let [e, n] of Object.entries(t.headers)) s.setHeader(e, String(n));
3339
- s.end(t.body);
3618
+ c.statusCode = t.status;
3619
+ for (let [e, n] of Object.entries(t.headers)) c.setHeader(e, String(n));
3620
+ c.end(t.body);
3340
3621
  return;
3341
3622
  }
3342
- U(s, "ssr-dev", u, f.route.pattern, e, y);
3623
+ he(c, "ssr-dev", d, m.route.pattern, e, b);
3343
3624
  }
3344
3625
  });
3345
3626
  }
3346
- }, ve = Date.now(), K = D.version ?? "?", q = await ti(), ye = p(e, "node_modules", "@voltro", "ui-shadcn"), J = T(p(ye, "package.json")) ? ye : null, be = [], xe = await (async () => {
3627
+ }, ye = Date.now(), G = D.version ?? "?", K = await Ti(), be = p(e, "node_modules", "@voltro", "ui-shadcn"), q = T(p(be, "package.json")) ? be : null, xe = [], Se = await (async () => {
3347
3628
  let t = [];
3348
3629
  for (let n of r) {
3349
3630
  if (!n.proxyTarget) continue;
3350
- let r = await Si(e, n.pkg);
3631
+ let r = await Ki(e, n.pkg);
3351
3632
  if (r) try {
3352
3633
  t.push(await O.readFile(p(r, "rpcGroup.generated.ts"), "utf8"));
3353
3634
  } catch {}
3354
3635
  }
3355
3636
  if (t.length === 0) return !1;
3356
- let n = de("sha1").update(t.join("\0")).digest("hex"), i = p(A, ".voltro-rpcgroup-optimize"), a = "";
3637
+ let n = de("sha1").update(t.join("\0")).digest("hex"), i = p(j, ".voltro-rpcgroup-optimize"), a = "";
3357
3638
  try {
3358
3639
  a = (await O.readFile(i, "utf8")).trim();
3359
3640
  } catch {}
@@ -3363,61 +3644,68 @@ import {
3363
3644
  } catch {}
3364
3645
  return !0;
3365
3646
  })();
3366
- xe && Z.info("rpcGroup changed since last boot — forcing a dep re-optimize so the browser loads the current api client"), await (await D.createServer({
3367
- root: A,
3647
+ Se && X.info("rpcGroup changed since last boot — forcing a dep re-optimize so the browser loads the current api client");
3648
+ try {
3649
+ await Tt(g, "voltro dev (web)");
3650
+ } catch (e) {
3651
+ X.error(String(e.message ?? e)), process.exit(1);
3652
+ }
3653
+ await (await D.createServer({
3654
+ root: j,
3368
3655
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
3369
- ssr: { noExternal: ["react-intl"] },
3656
+ ssr: { noExternal: ["react-intl", "@voltro/i18n"] },
3370
3657
  resolve: {
3371
3658
  dedupe: [
3372
3659
  "react",
3373
3660
  "react-dom",
3374
- "react-intl"
3661
+ "react-intl",
3662
+ "@voltro/i18n"
3375
3663
  ],
3376
3664
  alias: [
3377
- ...q ? [{
3665
+ ...K ? [{
3378
3666
  find: "@voltro/devtools/styles.css",
3379
- replacement: p(q, "src/styles.css")
3667
+ replacement: p(K, "src/styles.css")
3380
3668
  }, {
3381
3669
  find: "@voltro/devtools",
3382
- replacement: p(q, "src/index.ts")
3670
+ replacement: p(K, "src/index.ts")
3383
3671
  }] : [],
3384
- ...J ? [
3672
+ ...q ? [
3385
3673
  {
3386
3674
  find: "@voltro/ui-shadcn/tokens.css",
3387
- replacement: p(J, "src/tokens.css")
3675
+ replacement: p(q, "src/tokens.css")
3388
3676
  },
3389
3677
  {
3390
3678
  find: "@voltro/ui-shadcn/cn",
3391
- replacement: p(J, "src/cn.ts")
3679
+ replacement: p(q, "src/cn.ts")
3392
3680
  },
3393
3681
  {
3394
3682
  find: "@voltro/ui-shadcn/brand",
3395
- replacement: p(J, "src/brand/voltroLogo.tsx")
3683
+ replacement: p(q, "src/brand/voltroLogo.tsx")
3396
3684
  },
3397
3685
  {
3398
3686
  find: "@voltro/ui-shadcn",
3399
- replacement: p(J, "src/index.ts")
3687
+ replacement: p(q, "src/index.ts")
3400
3688
  }
3401
3689
  ] : [],
3402
- ...Je(e)
3690
+ ...Ye(e)
3403
3691
  ]
3404
3692
  },
3405
3693
  optimizeDeps: {
3406
- include: [...r.map((e) => `${e.pkg}/rpcGroup`), ...be],
3407
- force: xe
3694
+ include: [...r.map((e) => `${e.pkg}/rpcGroup`), ...xe],
3695
+ force: Se
3408
3696
  },
3409
- customLogger: Et(),
3697
+ customLogger: Kt(),
3410
3698
  plugins: [
3411
- Kn(p(e, "src", "pages")),
3412
- ee(),
3699
+ fr(p(e, "src", "pages")),
3413
3700
  k(),
3414
- ne,
3415
- F,
3416
- ae,
3701
+ A(),
3702
+ ee,
3703
+ L,
3704
+ B,
3417
3705
  se,
3418
3706
  ce,
3419
3707
  ue,
3420
- _e,
3708
+ ve,
3421
3709
  ...pe ? [pe] : []
3422
3710
  ],
3423
3711
  server: {
@@ -3426,24 +3714,24 @@ import {
3426
3714
  host: !0,
3427
3715
  allowedHosts: t.allowedHosts === !0 || [...t.allowedHosts ?? []],
3428
3716
  proxy: H,
3429
- fs: { allow: [e, ...si(e)] }
3717
+ fs: { allow: [e, ...ji(e)] }
3430
3718
  },
3431
3719
  appType: "spa",
3432
- cacheDir: p(A, ".vite"),
3720
+ cacheDir: p(j, ".vite"),
3433
3721
  publicDir: p(e, "public")
3434
- })).listen(), $r.info(`v${K} ready in ${Date.now() - ve}ms`, {
3435
- version: K,
3436
- bootMs: Date.now() - ve
3437
- }), Z.info(`listening on http://localhost:${g}`, {
3722
+ })).listen(), Ci.info(`v${G} ready in ${Date.now() - ye}ms`, {
3723
+ version: G,
3724
+ bootMs: Date.now() - ye
3725
+ }), X.info(`listening on http://localhost:${g}`, {
3438
3726
  port: g,
3439
3727
  app: t.name ?? "(unnamed)"
3440
3728
  });
3441
- for (let e of r) e.proxyTarget && (Z.info(`proxy /ws/${e.name} → ${e.proxyTarget}`, {
3729
+ for (let e of r) e.proxyTarget && (X.info(`proxy /ws/${e.name} → ${e.proxyTarget}`, {
3442
3730
  api: e.name,
3443
3731
  target: e.proxyTarget
3444
- }), Z.info(`proxy /_voltro/api/${e.name} → ${e.proxyTarget.replace(/^ws/, "http")}/_voltro/inspect`, { api: e.name }));
3732
+ }), X.info(`proxy /_voltro/api/${e.name} → ${e.proxyTarget.replace(/^ws/, "http")}/_voltro/inspect`, { api: e.name }));
3445
3733
  try {
3446
- await We({
3734
+ await Ge({
3447
3735
  id: v,
3448
3736
  name: _,
3449
3737
  kind: "web",
@@ -3452,13 +3740,13 @@ import {
3452
3740
  status: "live",
3453
3741
  logFile: y.path
3454
3742
  });
3455
- let t = vr(e);
3743
+ let t = Rr(e);
3456
3744
  if (t) {
3457
- let e = await Or({ dashboardAppPath: t });
3458
- e.status === "launched" ? Z.info(`dashboard launched at http://localhost:${e.port}`, { port: e.port }) : e.status === "already-running" && Z.debug(`dashboard already running on :${e.port}`, { port: e.port });
3745
+ let e = await Jr({ dashboardAppPath: t });
3746
+ e.status === "launched" ? X.info(`dashboard launched at http://localhost:${e.port}`, { port: e.port }) : e.status === "already-running" && X.debug(`dashboard already running on :${e.port}`, { port: e.port });
3459
3747
  }
3460
3748
  setInterval(() => {
3461
- We({
3749
+ Ge({
3462
3750
  id: v,
3463
3751
  name: _,
3464
3752
  kind: "web",
@@ -3469,54 +3757,55 @@ import {
3469
3757
  }).catch(() => {});
3470
3758
  }, 1e4).unref();
3471
3759
  let n = () => {
3472
- Ge(v), y.dispose();
3760
+ Ke(v), y.dispose();
3473
3761
  };
3474
3762
  process.on("SIGINT", n), process.on("SIGTERM", n);
3475
3763
  } catch (e) {
3476
- Z.warn("runtime-registry write failed", {}, e);
3764
+ X.warn("runtime-registry write failed", {}, e);
3477
3765
  }
3478
3766
  return C({
3479
3767
  app: t.name ?? "unnamed",
3480
3768
  kind: "web",
3481
3769
  url: `http://localhost:${g}`,
3482
- bootMs: Date.now() - ve
3770
+ bootMs: Date.now() - ye
3483
3771
  }), new Promise(() => {});
3484
- }, Ri = async (e) => {
3772
+ }, sa = async (e) => {
3485
3773
  process.env.NODE_ENV || (process.env.NODE_ENV = "production");
3486
- let t = await Ii(e);
3774
+ let t = await aa(e);
3487
3775
  if (!t) return {
3488
3776
  ran: !1,
3489
3777
  exitCode: 0
3490
3778
  };
3491
- let n = Date.now(), r = Z.child("serve");
3779
+ let n = Date.now(), r = X.child("serve");
3492
3780
  r.info("booting voltro serve (preview)", { app: t.name ?? "(unnamed)" });
3493
- let i = await Di(e, t);
3781
+ let i = await Zi(e, t);
3494
3782
  for (let e of i) r.info("api wired", {
3495
3783
  name: e.name,
3496
3784
  pkg: e.pkg
3497
3785
  });
3498
- await Ni(e, t, i);
3786
+ await $(e, t, i);
3499
3787
  {
3500
- let { pages: t } = await $(p(e, "src", "pages"));
3501
- await zt({
3788
+ let { pages: t } = await Q(p(e, "src", "pages"));
3789
+ await on({
3502
3790
  appRoot: e,
3503
3791
  pages: t
3504
3792
  });
3505
3793
  }
3506
- let a = t.port ?? 5173, o = await Xe("vite", () => import("vite")), s = (await import("@vitejs/plugin-react")).default, c = p(e, ".framework");
3507
- Z.info("running production build"), await o.build({
3794
+ let a = t.port ?? 5173, o = await Ze("vite", () => import("vite")), s = (await import("@vitejs/plugin-react")).default, c = p(e, ".framework");
3795
+ X.info("running production build"), await o.build({
3508
3796
  root: c,
3509
3797
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
3510
3798
  plugins: [s()],
3511
- customLogger: Et(),
3799
+ customLogger: Kt(),
3512
3800
  resolve: { dedupe: [
3513
3801
  "react",
3514
3802
  "react-dom",
3515
- "react-intl"
3803
+ "react-intl",
3804
+ "@voltro/i18n"
3516
3805
  ] },
3517
3806
  build: {
3518
3807
  outDir: "dist",
3519
- rollupOptions: { output: { manualChunks: li } }
3808
+ rollupOptions: { output: { manualChunks: Ni } }
3520
3809
  },
3521
3810
  publicDir: p(e, "public")
3522
3811
  });
@@ -3536,14 +3825,14 @@ import {
3536
3825
  extras: d,
3537
3826
  bootMs: Date.now() - n
3538
3827
  }), new Promise(() => {});
3539
- }, zi = 5e3, Bi = 6e4, Vi = (e, t) => {
3828
+ }, ca = 5e3, la = 6e4, ua = (e, t) => {
3540
3829
  if (e.length === 0) return 0;
3541
3830
  if (e.length === 1) return e[0];
3542
3831
  let n = t * (e.length - 1), r = Math.floor(n), i = Math.ceil(n);
3543
3832
  if (r === i) return e[r];
3544
3833
  let a = n - r;
3545
3834
  return e[r] * (1 - a) + e[i] * a;
3546
- }, Hi = (e) => {
3835
+ }, da = (e) => {
3547
3836
  if (e.length === 0) return {
3548
3837
  p50: 0,
3549
3838
  p95: 0,
@@ -3555,18 +3844,18 @@ import {
3555
3844
  let t = e.slice().sort((e, t) => e - t), n = 0;
3556
3845
  for (let e of t) n += e;
3557
3846
  return {
3558
- p50: Vi(t, .5),
3559
- p95: Vi(t, .95),
3560
- p99: Vi(t, .99),
3847
+ p50: ua(t, .5),
3848
+ p95: ua(t, .95),
3849
+ p99: ua(t, .99),
3561
3850
  mean: n / t.length,
3562
3851
  min: t[0],
3563
3852
  max: t[t.length - 1]
3564
3853
  };
3565
- }, Ui = (e = {}) => {
3566
- let t = e.maxSamples ?? zi, n = e.defaultWindowMs ?? Bi, r = [];
3854
+ }, fa = (e = {}) => {
3855
+ let t = e.maxSamples ?? ca, n = e.defaultWindowMs ?? la, r = [];
3567
3856
  return {
3568
3857
  record(e) {
3569
- re(e), r.push({
3858
+ I(e), r.push({
3570
3859
  ...e,
3571
3860
  ts: Date.now()
3572
3861
  }), r.length > t && r.shift();
@@ -3592,7 +3881,7 @@ import {
3592
3881
  tag: e.tag,
3593
3882
  count: e.samples.length,
3594
3883
  errorCount: n,
3595
- latencyMs: Hi(t)
3884
+ latencyMs: da(t)
3596
3885
  });
3597
3886
  }
3598
3887
  return c.sort((e, t) => t.count - e.count), {
@@ -3605,4 +3894,4 @@ import {
3605
3894
  };
3606
3895
  };
3607
3896
  //#endregion
3608
- export { Dt as $, mr as A, An as B, Ir as C, vr as D, Or as E, Jn as F, sn as G, xn as H, Xn as I, Yt as J, Jt as K, Qn as L, rr as M, qn as N, fr as O, $n as P, kt as Q, In as R, Fr as S, _r as T, yn as U, Tn as V, fn as W, Wt as X, Gt as Y, zt as Z, Yr as _, Ge as _t, gi as a, dt as at, Nr as b, Ne as bt, Di as c, at as ct, li as d, tt as dt, _t as et, $ as f, et as ft, Kr as g, Ue as gt, qr as h, Ke as ht, Mi as i, ut as it, tr as j, pr as k, Li as l, ot as lt, Qr as m, Je as mt, ui as n, mt as nt, hi as o, st as ot, Ni as p, Xe as pt, qt as q, ji as r, lt as rt, Ii as s, ct as st, Ui as t, ht as tt, Ri as u, rt as ut, Ar as v, We as vt, yr as w, Pr as x, Mr as y, Me as yt, Ln as z };
3897
+ export { qt as $, Pr as A, Xn as B, ni as C, We as Ct, Rr as D, Pe as Dt, Jr as E, Ne as Et, mr as F, Dn as G, Vn as H, gr as I, gn as J, hn as K, vr as L, Cr as M, pr as N, Mr as O, yr as P, Yt as Q, nr as R, ti as S, qe as St, Lr as T, Ge as Tt, zn as U, Gn as V, Mn as W, dn as X, fn as Y, on as Z, yi as _, it as _t, Bi as a, Tt as at, $r as b, Ze as bt, Zi as c, gt as ct, Ni as d, dt, Nt as et, Q as f, ft, gi as g, st as gt, _i as h, ot as ht, na as i, Lt as it, xr as j, Nr as k, oa as l, ht as lt, Si as m, lt as mt, Pi as n, Pt as nt, zi as o, bt as ot, $ as p, ct as pt, mn as q, ta as r, It as rt, aa as s, vt as st, fa as t, Ft as tt, sa as u, ut, Xr as v, nt as vt, zr as w, Ke as wt, ei as x, Ye as xt, Qr as y, tt as yt, rr as z };