@voltro/cli 0.44.1 → 0.45.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 (101) hide show
  1. package/CHANGELOG.md +104 -1
  2. package/dist/{apiBuild-DvWreIQP.js → apiBuild-CDQBNRDx.js} +1 -1
  3. package/dist/apiBuild-yJCqJYQ8.js +2 -0
  4. package/dist/bin.d.ts +16 -0
  5. package/dist/bin.js +46 -11
  6. package/dist/{build-Ckc-FA7d.js → build-yvsLG77U.js} +7 -7
  7. package/dist/{checkCommand-BNfEs4KG.js → checkCommand-Boxov8lr.js} +11 -11
  8. package/dist/{checkCommand-AlbawIal.js → checkCommand-lrzwOzV1.js} +1 -1
  9. package/dist/codegen-DcE2li1i.js +2 -0
  10. package/dist/{codegen-CbpGCWLG.js → codegen-sbN1Y8PB.js} +37 -37
  11. package/dist/codegenCommand-CQOLytL-.js +144 -0
  12. package/dist/{codemodRunner-BKTnaGOz.js → codemodRunner-5ZhDH3rB.js} +41 -0
  13. package/dist/{commands-CYkHTox2.js → commands-CEkVoFM5.js} +19 -19
  14. package/dist/{dashboardCommand-DHDmlo9A.js → dashboardCommand-0ahyp-zA.js} +1 -1
  15. package/dist/{dataCommand-WFn8CM11.js → dataCommand-D4IlZcih.js} +275 -211
  16. package/dist/{dev-D-JZ6CGQ.js → dev-DAM5CnAa.js} +1856 -1801
  17. package/dist/{dev-BZO5aLdr.js → dev-P4HyeY9W.js} +1 -1
  18. package/dist/devActivity.d.ts +16 -0
  19. package/dist/doctorCommand-2K1dIzYk.js +2 -0
  20. package/dist/{doctorCommand-BlUyESpD.js → doctorCommand-DW2cwAvC.js} +244 -223
  21. package/dist/doctorSourceRelations-CPjSwYuZ.js +83 -0
  22. package/dist/{dormancyCommand-lQxdrU8C.js → dormancyCommand-BqQz7lbM.js} +1 -1
  23. package/dist/{embeddingsCommand-ByBTju6X.js → embeddingsCommand-DJyArpU4.js} +1 -1
  24. package/dist/{envCommand-CpCbYAgR.js → envCommand-CviRZx1L.js} +1 -1
  25. package/dist/{evolveCommand-CBV3-TtK.js → evolveCommand-qdlP-R9G.js} +2 -2
  26. package/dist/index.d.ts +16 -0
  27. package/dist/index.js +1 -1
  28. package/dist/{infoCommand-DJoA9cKD.js → infoCommand-CNWPSUcW.js} +1 -1
  29. package/dist/inspectState.d.ts +16 -0
  30. package/dist/{runtimeTrace-DJ9tPhrc.js → runtimeTrace-BDZSt9W_.js} +1 -1
  31. package/dist/{sdkgen-7dr8-Onw.js → sdkgen-sNaD3oZB.js} +1 -1
  32. package/dist/{serveCommand-BlnAlNQg.js → serveCommand-BBhT2U94.js} +731 -737
  33. package/dist/serveCommand-DY2jLy0o.js +2 -0
  34. package/dist/serveEntry.d.ts +16 -0
  35. package/dist/serveEntry.js +1 -1
  36. package/dist/startEntry.d.ts +16 -0
  37. package/dist/startup.d.ts +16 -0
  38. package/dist/{test-CLYXrZ2F.js → test-CHb7UwvE.js} +1 -1
  39. package/dist/updateCommand-BH6EGuCc.js +2 -0
  40. package/dist/{updateCommand-BvRidHp6.js → updateCommand-rCnhaj84.js} +1 -1
  41. package/dist/{webhooksCommand-BfO_JF2b.js → webhooksCommand-C0iZZfaI.js} +1 -1
  42. package/package.json +23 -17
  43. package/templates/AGENTS.md +1 -1
  44. package/templates/agent-docs/_index.md +1 -1
  45. package/templates/agent-docs/cli.md +41 -1
  46. package/templates/agent-docs/data.md +33 -3
  47. package/templates/agent-docs/plugins/versioning.md +2 -0
  48. package/templates/agent-docs/whats-new.md +93 -6
  49. package/templates/apps/api-ai/package.json +7 -7
  50. package/templates/apps/api-auth/package.json +8 -8
  51. package/templates/apps/api-backend/package.json +7 -7
  52. package/templates/apps/api-backend-deactivation/package.json +7 -7
  53. package/templates/apps/api-backend-mail/package.json +8 -8
  54. package/templates/apps/api-backend-mariadb/package.json +9 -9
  55. package/templates/apps/api-backend-sqlite/package.json +8 -8
  56. package/templates/apps/api-backend-storage/package.json +8 -8
  57. package/templates/apps/api-cms/package.json +10 -10
  58. package/templates/apps/api-collab/package.json +8 -8
  59. package/templates/apps/api-data-advanced/package.json +8 -8
  60. package/templates/apps/api-durable/package.json +8 -8
  61. package/templates/apps/api-feature-flags/package.json +9 -9
  62. package/templates/apps/api-governance/package.json +8 -8
  63. package/templates/apps/api-kv/package.json +8 -8
  64. package/templates/apps/api-moderation/package.json +8 -8
  65. package/templates/apps/api-observability/package.json +8 -8
  66. package/templates/apps/api-ratelimit/package.json +8 -8
  67. package/templates/apps/api-rbac/package.json +8 -8
  68. package/templates/apps/api-rest/package.json +7 -7
  69. package/templates/apps/api-saas/package.json +11 -11
  70. package/templates/apps/api-saas-starter/package.json +10 -10
  71. package/templates/apps/api-search/package.json +8 -8
  72. package/templates/apps/api-status/package.json +8 -8
  73. package/templates/apps/api-versioning/package.json +8 -8
  74. package/templates/apps/api-webhooks/package.json +9 -9
  75. package/templates/apps/changelog/package.json +6 -6
  76. package/templates/apps/edge-functions/package.json +2 -2
  77. package/templates/apps/frontend-admin/package.json +8 -8
  78. package/templates/apps/frontend-app/package.json +9 -9
  79. package/templates/apps/frontend-auth/package.json +8 -8
  80. package/templates/apps/frontend-blank/package.json +7 -7
  81. package/templates/apps/frontend-cms/package.json +9 -9
  82. package/templates/apps/frontend-collab/package.json +10 -10
  83. package/templates/apps/frontend-contact/package.json +7 -7
  84. package/templates/apps/frontend-dashboard/package.json +7 -7
  85. package/templates/apps/frontend-docs/package.json +7 -7
  86. package/templates/apps/frontend-i18n/package.json +6 -6
  87. package/templates/apps/frontend-landing/package.json +7 -7
  88. package/templates/apps/frontend-portal/package.json +8 -8
  89. package/templates/apps/frontend-saas/package.json +8 -8
  90. package/templates/apps/frontend-spa/package.json +7 -7
  91. package/templates/apps/frontend-ssr/package.json +7 -7
  92. package/templates/apps/frontend-ssr-api/package.json +8 -8
  93. package/templates/apps/frontend-static-blog/package.json +6 -6
  94. package/templates/apps/frontend-status/package.json +8 -8
  95. package/templates/apps/mobile-app/package.json +4 -4
  96. package/dist/apiBuild-XaW40W8x.js +0 -2
  97. package/dist/codegen-i8QGcHsi.js +0 -2
  98. package/dist/codegenCommand-iClXoRCW.js +0 -129
  99. package/dist/doctorCommand-BeLOwq7S.js +0 -2
  100. package/dist/serveCommand-Dg_E1ev4.js +0 -2
  101. package/dist/updateCommand-DcKVmLVN.js +0 -2
@@ -1,8 +1,8 @@
1
- import { Bt as e, Ht as t, Vt as n } from "./dev-D-JZ6CGQ.js";
1
+ import { Bt as e, Ht as t, Vt as n } from "./dev-DAM5CnAa.js";
2
2
  import { at as r, it as i, ot as a, s as o, st as s, t as c, w as l, y as u } from "./webDev-101csg6Q.js";
3
3
  import { w as d } from "./frameworkTableAssembly-oMPBKqlE.js";
4
4
  import { n as f } from "./pageConvention-cEiRxdab.js";
5
- import { r as p, u as m } from "./apiBuild-DvWreIQP.js";
5
+ import { r as p, u as m } from "./apiBuild-CDQBNRDx.js";
6
6
  import { n as h, r as g, t as ee } from "./cliOutput-D1tSBoRM.js";
7
7
  import { n as _, t as te } from "./tsconfigPaths-BWXBWgcl.js";
8
8
  import { n as ne, r as re } from "./fileTaxonomy-CJfgOllU.js";
@@ -477,33 +477,33 @@ var le = /* @__PURE__ */ new Set([
477
477
  for (let n of e.problems) t.push(` • ${n}`);
478
478
  }
479
479
  return e.unreadable.length > 0 && t.push(`… ${e.file}: ${e.unreadable.length} matcher(s) not statically readable (${e.unreadable.join(", ")}) — doctor did NOT check them. The boot still does.`), e.seen === 0 && t.push(`… ${e.file}: no \`defineMiddleware(...)\` found — doctor checked nothing here. A middleware assigned through a variable or re-exported from another module is invisible to this rule.`), t.length === 0 && e.seen > 0 && t.push(`✓ ${e.file}: ${e.seen} middleware(s), matchers resolve and do not overlap`), t;
480
- }, j = (e) => e.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/[^\n]*/g, "$1"), ze = /* @__PURE__ */ new Set([
480
+ }, ze = (e) => e.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/[^\n]*/g, "$1"), Be = /* @__PURE__ */ new Set([
481
481
  "requireScope",
482
482
  "requireAnyScope",
483
483
  "requireAuth",
484
484
  "assertScope",
485
485
  "assertCan",
486
486
  "can"
487
- ]), Be = (e) => {
487
+ ]), Ve = (e) => {
488
488
  let t = /* @__PURE__ */ new Set();
489
- for (let n of e) for (let e of j(n).matchAll(/\bexport\s+(?:const|function|async\s+function)\s+((?:require|assert)[A-Z]\w*)/g)) t.add(e[1]);
489
+ for (let n of e) for (let e of ze(n).matchAll(/\bexport\s+(?:const|function|async\s+function)\s+((?:require|assert)[A-Z]\w*)/g)) t.add(e[1]);
490
490
  return t;
491
- }, Ve = (e, t) => {
491
+ }, He = (e, t) => {
492
492
  for (let n of t) if (RegExp(`\\b${n}\\s*\\(`).test(e)) return n;
493
- }, He = (e) => {
493
+ }, Ue = (e) => {
494
494
  let t = /\bsubject\s*\.\s*id\b[^\n]*?(?:!==|===|!=|==)|(?:!==|===|!=|==)[^\n]*?\bsubject\s*\.\s*id\b/.test(e), n = /(?:Error|Denied|Forbidden|Unauthorized)\b|\b(?:fail|die|throw)\b/.test(e);
495
495
  return t && n;
496
- }, Ue = (e, t, n) => {
496
+ }, We = (e, t, n) => {
497
497
  if (e.hasDeclaredGuards) return { kind: "declared-guard" };
498
- let r = j(e.src), i = Ve(r, t);
499
- return i === void 0 ? He(r) ? { kind: "inline-ownership" } : n.has(e.tag) ? { kind: "allowlisted" } : { kind: "unchecked" } : {
498
+ let r = ze(e.src), i = He(r, t);
499
+ return i === void 0 ? Ue(r) ? { kind: "inline-ownership" } : n.has(e.tag) ? { kind: "allowlisted" } : { kind: "unchecked" } : {
500
500
  kind: "vocabulary-guard",
501
501
  name: i
502
502
  };
503
- }, We = (e, t, n) => {
503
+ }, Ge = (e, t, n) => {
504
504
  let r = e.op === "delete" ? 3 : e.op === "update" ? 2 : 1;
505
505
  return e.table !== void 0 && (t.has(e.table) && (r += 2), n.has(e.table) && e.op === "delete" && (r += 2)), r;
506
- }, Ge = (e, t, n) => {
506
+ }, Ke = (e, t, n) => {
507
507
  switch (t.kind) {
508
508
  case "declared-guard": return "guards: on the descriptor";
509
509
  case "vocabulary-guard": return `calls ${t.name}()`;
@@ -511,15 +511,15 @@ var le = /* @__PURE__ */ new Set([
511
511
  case "allowlisted": return "accepted by a previous run";
512
512
  case "unchecked": return n ? e.op === "read" ? "no check in this file — this app registers a row filter; VERIFY it covers this table, then record it as reviewed= rather than debt" : `${e.op}s${e.table ? ` ${e.table}` : ""} with no check in this file — this app registers a row filter; VERIFY it covers this table, then record it as reviewed= rather than debt` : e.op === "read" ? "returns a row the client selected, with nothing compared to the caller" : `${e.op}s${e.table ? ` ${e.table}` : ""} with nothing constraining WHICH row`;
513
513
  }
514
- }, Ke = (e) => {
514
+ }, qe = (e) => {
515
515
  let t = e.executors.map((t) => {
516
- let n = Ue(t, e.guardVocabulary, e.allowlist);
516
+ let n = We(t, e.guardVocabulary, e.allowlist);
517
517
  return {
518
518
  tag: t.tag,
519
519
  path: t.path,
520
520
  verdict: n,
521
- severity: We(t, e.tenantScopedTables, e.referencedTables),
522
- why: Ge(t, n, e.rowFilterRegistered === !0)
521
+ severity: Ge(t, e.tenantScopedTables, e.referencedTables),
522
+ why: Ke(t, n, e.rowFilterRegistered === !0)
523
523
  };
524
524
  }), n = (e) => t.filter((t) => t.verdict.kind === e).length;
525
525
  return {
@@ -533,7 +533,7 @@ var le = /* @__PURE__ */ new Set([
533
533
  },
534
534
  unchecked: t.filter((e) => e.verdict.kind === "unchecked").sort((e, t) => t.severity - e.severity || e.tag.localeCompare(t.tag))
535
535
  };
536
- }, qe = [
536
+ }, Je = [
537
537
  "# voltro doctor — authz allowlist",
538
538
  "#",
539
539
  "# Two KINDS of line, and the difference is the point:",
@@ -558,19 +558,19 @@ var le = /* @__PURE__ */ new Set([
558
558
  "# `--write-authz-allowlist` PRESERVES reviewed= lines. It only ever adds debt",
559
559
  "# lines for executors that are newly unchecked.",
560
560
  ""
561
- ], Je = (e) => {
561
+ ], Ye = (e) => {
562
562
  let t = [...e].map((e) => typeof e == "string" ? { tag: e } : e), n = t.filter((e) => e.reviewed === void 0).map((e) => e.tag).sort(), r = t.filter((e) => e.reviewed !== void 0).sort((e, t) => e.tag.localeCompare(t.tag));
563
563
  return [
564
- ...qe,
564
+ ...Je,
565
565
  ...n,
566
566
  ...r.length > 0 ? ["", "# reviewed — read by a human, open on purpose"] : [],
567
567
  ...r.map((e) => `${e.tag} reviewed=${e.reviewed}`),
568
568
  ""
569
569
  ].join("\n");
570
- }, Ye = (e, t) => {
570
+ }, Xe = (e, t) => {
571
571
  let n = [...new Set(t)].sort();
572
- if (e === void 0) return Je(n.map((e) => ({ tag: e })));
573
- let r = M(e).tags, i = n.filter((e) => !r.has(e));
572
+ if (e === void 0) return Ye(n.map((e) => ({ tag: e })));
573
+ let r = j(e).tags, i = n.filter((e) => !r.has(e));
574
574
  return i.length === 0 ? e : [
575
575
  e.replace(/\n+$/, ""),
576
576
  "",
@@ -579,25 +579,25 @@ var le = /* @__PURE__ */ new Set([
579
579
  ...i,
580
580
  ""
581
581
  ].join("\n");
582
- }, Xe = (e, t) => {
582
+ }, Ze = (e, t) => {
583
583
  let n = [...new Set(t)];
584
584
  if (e === void 0) return {
585
585
  added: n.length,
586
586
  kept: 0,
587
587
  removed: 0
588
588
  };
589
- let r = M(e).tags;
589
+ let r = j(e).tags;
590
590
  return {
591
591
  added: n.filter((e) => !r.has(e)).length,
592
592
  kept: r.size,
593
593
  removed: 0
594
594
  };
595
- }, Ze = class extends Error {
595
+ }, Qe = class extends Error {
596
596
  tag;
597
597
  constructor(e) {
598
598
  super(`authz allowlist: '${e}' is marked reviewed with no reason. Write \`${e} reviewed=<why it is genuinely open>\`. A bare tag is the other, honest option — it records the executor as DEBT, which is what an unexplained exemption is.`), this.tag = e, this.name = "AllowlistReasonMissingError";
599
599
  }
600
- }, M = (e) => {
600
+ }, j = (e) => {
601
601
  let t = [];
602
602
  for (let n of e.split("\n")) {
603
603
  let e = n.trim();
@@ -610,7 +610,7 @@ var le = /* @__PURE__ */ new Set([
610
610
  continue;
611
611
  }
612
612
  let a = r[2].trim();
613
- if (a.length === 0) throw new Ze(i);
613
+ if (a.length === 0) throw new Qe(i);
614
614
  t.push({
615
615
  tag: i,
616
616
  reviewed: a
@@ -620,13 +620,13 @@ var le = /* @__PURE__ */ new Set([
620
620
  tags: new Set(t.map((e) => e.tag)),
621
621
  entries: t
622
622
  };
623
- }, Qe = (e) => {
623
+ }, $e = (e) => {
624
624
  let t = e.indexOf(".");
625
625
  return t <= 0 ? void 0 : e.slice(0, t);
626
- }, $e = (e, t) => {
626
+ }, et = (e, t) => {
627
627
  let n = new Set(t.tables), r = new Set(t.rpcTags), i = /* @__PURE__ */ new Map();
628
628
  for (let e of t.rpcTags) {
629
- let t = Qe(e);
629
+ let t = $e(e);
630
630
  if (t === void 0) continue;
631
631
  let n = i.get(t);
632
632
  n ? n.push(e) : i.set(t, [e]);
@@ -655,7 +655,7 @@ var le = /* @__PURE__ */ new Set([
655
655
  });
656
656
  continue;
657
657
  }
658
- let s = new Set(o.rpcTags.map(Qe).filter((e) => e !== void 0));
658
+ let s = new Set(o.rpcTags.map($e).filter((e) => e !== void 0));
659
659
  for (let e of s) {
660
660
  let t = i.get(e);
661
661
  t !== void 0 && a.push({
@@ -668,12 +668,12 @@ var le = /* @__PURE__ */ new Set([
668
668
  }
669
669
  }
670
670
  return a;
671
- }, et = (e, t) => {
671
+ }, tt = (e, t) => {
672
672
  let n = e.reduce((e, t) => e + t.tables.length, 0), r = [`plugin surface · ${e.length} plugin(s) contribute ${n} table(s)`];
673
673
  if (t.length === 0) return r.push(" ✓ no overlap with your own tables or rpc namespaces"), r;
674
674
  for (let e of t) r.push(` ${e.fatal ? "✗" : "⚠"} ${e.plugin} — ${e.detail}`), r.push(` ${e.fix}`);
675
675
  return r;
676
- }, tt = async (e) => {
676
+ }, nt = async (e) => {
677
677
  if (!await e.hasWorkflows().catch(() => !1)) return { kind: "not-applicable" };
678
678
  let t;
679
679
  try {
@@ -697,12 +697,12 @@ var le = /* @__PURE__ */ new Set([
697
697
  } finally {
698
698
  await t.close().catch(() => {});
699
699
  }
700
- }, nt = (e) => {
700
+ }, rt = (e) => {
701
701
  let t = Math.round(e / 6e4);
702
702
  if (t < 90) return `${t}m`;
703
703
  let n = Math.round(t / 60);
704
704
  return n < 48 ? `${n}h` : `${Math.round(n / 24)}d`;
705
- }, rt = (e) => {
705
+ }, it = (e) => {
706
706
  if (e.kind === "not-applicable") return null;
707
707
  if (e.kind === "skipped") return `• stuck runs: NOT CHECKED — ${e.reason}\n This is the one doctor rule that reads the database rather than your source.
708
708
  Run it where the app's DB env vars are set, or ignore this line locally.`;
@@ -710,13 +710,13 @@ var le = /* @__PURE__ */ new Set([
710
710
  if (t.stalled.length === 0) n.push(`✓ stuck runs: none (${t.examined} live run(s) old enough to examine${t.waitingOnTimer > 0 ? `, ${t.waitingOnTimer} waiting on a durable timer` : ""}${t.alreadyReported > 0 ? `, ${t.alreadyReported} already reported` : ""})`);
711
711
  else {
712
712
  n.push(`✗ stuck runs: ${t.stalled.length} run(s) have made no progress`);
713
- for (let e of t.stalled.slice(0, 20)) n.push(` ${e.tag} ${e.runId} idle ${nt(e.idleMs)} ${e.reason}`);
713
+ for (let e of t.stalled.slice(0, 20)) n.push(` ${e.tag} ${e.runId} idle ${rt(e.idleMs)} ${e.reason}`);
714
714
  t.stalled.length > 20 && n.push(` … and ${t.stalled.length - 20} more`), n.push(" Nothing was changed — this is a SUSPICION, not a verdict. `awaiting-signal` usually means the sender never came.");
715
715
  }
716
716
  t.sawFullRunPage && n.push(" (the examined page filled up — more old runs exist than were read this pass)");
717
717
  for (let e of t.failures) n.push(` ! could not examine ${e.subject}: ${e.detail}`);
718
718
  return n.join("\n");
719
- }, it = (e) => S(b(e, "app.config.ts")) || S(b(e, "app.config.js")), at = (e) => {
719
+ }, at = (e) => S(b(e, "app.config.ts")) || S(b(e, "app.config.js")), ot = (e) => {
720
720
  let t = m(e), n = p(e);
721
721
  return {
722
722
  root: e,
@@ -725,22 +725,22 @@ var le = /* @__PURE__ */ new Set([
725
725
  apiBundle: n,
726
726
  apiBundlePresent: S(n)
727
727
  };
728
- }, ot = [
728
+ }, st = [
729
729
  "Production `voltro serve` requires a precompiled serve bundle and never transpiles on demand.",
730
730
  "Add a `voltro build .` step BEFORE `voltro serve .` in your Dockerfile / start script.",
731
731
  "(Generated Dockerfiles from `voltro create-project` already do this.)"
732
- ].join("\n "), st = (e, t = !1) => {
733
- let n = at(e);
734
- if (console.log(`voltro doctor — serve preflight for ${n.root}`), !it(e)) return console.log("• no app.config found here — nothing to check (run against an app root)."), 0;
732
+ ].join("\n "), ct = (e, t = !1) => {
733
+ let n = ot(e);
734
+ if (console.log(`voltro doctor — serve preflight for ${n.root}`), !at(e)) return console.log("• no app.config found here — nothing to check (run against an app root)."), 0;
735
735
  console.log(`${n.serveBundlePresent ? "✓" : "✗"} serve bundle: ${n.serveBundlePresent ? "present" : "MISSING"} (${n.serveBundle})`), console.log(`${n.apiBundlePresent ? "✓" : "•"} api bundle: ${n.apiBundlePresent ? "present" : "absent"} (${n.apiBundle})`);
736
736
  let r = process.env.NODE_ENV === "production";
737
737
  if (n.serveBundlePresent) return console.log("✓ serve preflight: ready for `voltro serve`."), 0;
738
738
  let i = t || r;
739
- return console.error(`${i ? "✗" : "•"} serve bundle missing — ${i ? "production `voltro serve` will FAIL." : "a non-production `voltro serve` still runs via tsx."}`), console.error(` ${ot}`), +!!i;
740
- }, ct = (e) => {
739
+ return console.error(`${i ? "✗" : "•"} serve bundle missing — ${i ? "production `voltro serve` will FAIL." : "a non-production `voltro serve` still runs via tsx."}`), console.error(` ${st}`), +!!i;
740
+ }, lt = (e) => {
741
741
  let t = e.absPath.replace(/\.server\.(tsx?)$/, ".$1");
742
742
  if (t !== e.absPath) return e.sources.get(t) ?? e.sources.get(t.replace(/\.ts$/, ".tsx"));
743
- }, lt = (e, t, n) => {
743
+ }, ut = (e, t, n) => {
744
744
  let r = new Set(e), i = _(n), a = (e) => (/\.(tsx?|jsx?)$/.test(e) ? [e] : [
745
745
  `${e}.ts`,
746
746
  `${e}.tsx`,
@@ -766,7 +766,7 @@ var le = /* @__PURE__ */ new Set([
766
766
  r !== void 0 && o.push(r);
767
767
  }
768
768
  return o;
769
- }, s = /* @__PURE__ */ new Set(), c = e.filter((e) => mt.test(y(n, e))), l = new Set(c);
769
+ }, s = /* @__PURE__ */ new Set(), c = e.filter((e) => ht.test(y(n, e))), l = new Set(c);
770
770
  for (; c.length > 0;) {
771
771
  let e = c.shift();
772
772
  if (!s.has(e)) {
@@ -779,11 +779,11 @@ var le = /* @__PURE__ */ new Set([
779
779
  let d = /* @__PURE__ */ new Set();
780
780
  for (let e of s) l.has(e) || u.has(e) || d.add(e);
781
781
  return d;
782
- }, N = (e) => e.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/(^|[^:])\/\/[^\n]*/g, "$1").replace(/'(?:[^'\\\n]|\\.)*'/g, "''").replace(/"(?:[^"\\\n]|\\.)*"/g, "\"\""), ut = (e, t) => (e.match(t) ?? []).length, P = (e, t) => e.getDescendantsOfKind(O.CallExpression).filter((e) => t.test(e.getExpression().getText())).length, dt = (e, t) => {
782
+ }, M = (e) => e.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/(^|[^:])\/\/[^\n]*/g, "$1").replace(/'(?:[^'\\\n]|\\.)*'/g, "''").replace(/"(?:[^"\\\n]|\\.)*"/g, "\"\""), dt = (e, t) => (e.match(t) ?? []).length, N = (e, t) => e.getDescendantsOfKind(O.CallExpression).filter((e) => t.test(e.getExpression().getText())).length, ft = (e, t) => {
783
783
  if (e.src.includes(t)) return !0;
784
784
  let n = t.replace(/^@voltro\/plugin-/, "");
785
- return n !== t && P(e.file, RegExp(`^${n}Plugin$`)) > 0;
786
- }, ft = (e, t) => {
785
+ return n !== t && N(e.file, RegExp(`^${n}Plugin$`)) > 0;
786
+ }, pt = (e, t) => {
787
787
  let n = [], r = RegExp(`\\b${t}\\s*(?:<[^()]*>)?\\s*\\(`, "g"), i;
788
788
  for (; (i = r.exec(e)) !== null;) {
789
789
  let t = i.index + i[0].length, r = 1, a = t;
@@ -791,10 +791,10 @@ var le = /* @__PURE__ */ new Set([
791
791
  n.push(e.slice(t, a - 1));
792
792
  }
793
793
  return n;
794
- }, pt = (e, t) => {
794
+ }, mt = (e, t) => {
795
795
  let n = t.getSymbol()?.getDeclarations()?.[0];
796
796
  return n === void 0 ? [] : e.getDescendantsOfKind(O.Identifier).filter((e) => e.getSymbol()?.getDeclarations()?.[0] === n);
797
- }, mt = /\.(server|cron|workflow\.server|subscribe|reaction|outbox|startup|trigger|webhook|migration|seed)\.tsx?$/, ht = /\.(query|mutation|action|stream)\.server\.tsx?$/, gt = [
797
+ }, ht = /\.(server|cron|workflow\.server|subscribe|reaction|outbox|startup|trigger|webhook|migration|seed)\.tsx?$/, gt = /\.(query|mutation|action|stream)\.server\.tsx?$/, _t = [
798
798
  "Id",
799
799
  "ID",
800
800
  "Hash",
@@ -820,7 +820,7 @@ var le = /* @__PURE__ */ new Set([
820
820
  "Comment",
821
821
  "Provider",
822
822
  "Format"
823
- ], _t = RegExp(`(?:${gt.join("|")})$|_(?:${gt.map((e) => e.toLowerCase()).join("|")})$`), vt = [
823
+ ], vt = RegExp(`(?:${_t.join("|")})$|_(?:${_t.map((e) => e.toLowerCase()).join("|")})$`), yt = [
824
824
  {
825
825
  id: "hardcoded-framework-cookie",
826
826
  scope: "client",
@@ -833,7 +833,7 @@ var le = /* @__PURE__ */ new Set([
833
833
  scope: "server",
834
834
  smell: "an executor that never names its own descriptor — its input type is hand-written, so it can drift from the contract it implements",
835
835
  use: "import the descriptor and type the input as `ExecutorInput<typeof descriptor>`, so the wire contract and the handler cannot disagree",
836
- match: ({ src: e, path: t }) => ht.test(t) && !/\bimport\s[^;]*\bfrom\s*['"][^'"]*['"]/.test((e.match(/^\s*import\s[^;]*from\s*['"]\.[^'"]*['"]/gm) ?? []).join("\n"))
836
+ match: ({ src: e, path: t }) => gt.test(t) && !/\bimport\s[^;]*\bfrom\s*['"][^'"]*['"]/.test((e.match(/^\s*import\s[^;]*from\s*['"]\.[^'"]*['"]/gm) ?? []).join("\n"))
837
837
  },
838
838
  {
839
839
  id: "subject-write-no-guard",
@@ -842,12 +842,12 @@ var le = /* @__PURE__ */ new Set([
842
842
  use: "declare `guards:` on the descriptor, or — if the procedure really is open — compare the loaded row's owner against `ctx.request.subject.id` and fail with a typed error",
843
843
  match: (e) => {
844
844
  let { src: t, path: n } = e;
845
- if (!ht.test(n)) return !1;
846
- let r = N(t);
845
+ if (!gt.test(n)) return !1;
846
+ let r = M(t);
847
847
  if (!(/\bsubject\s*\.\s*id\b/.test(r) && /\b(?:insert|update|upsert|insertMany|updateMany|insertRow|upsertRow|updateManyRow)\s*\(/.test(r)) || /\b(?:guard|guards|requireScope|requireAnyScope|assertCan|assertScope|requireAuth|Unauthenticated)\b/.test(r) || /[=!]==?\s*[^;\n]*\bsubject\s*\.\s*id\b|\bsubject\s*\.\s*id\b\s*[=!]==/.test(r)) return !1;
848
- let i = ct(e);
848
+ let i = lt(e);
849
849
  if (i === void 0) return !1;
850
- let a = N(i);
850
+ let a = M(i);
851
851
  return /\binternal\s*:\s*true\b/.test(a) || /\bguards\s*:\s*\[/.test(a) || /\.guard\s*\(/.test(a) ? !1 : /\bopenAccess\s*:/.test(a);
852
852
  }
853
853
  },
@@ -856,14 +856,14 @@ var le = /* @__PURE__ */ new Set([
856
856
  scope: "server",
857
857
  smell: "raw fetch() for outbound HTTP on the server (no traceparent, no retry, and no SSRF guard where the URL is not a constant)",
858
858
  use: "yield* HttpClient — the framework client. It injects traceparent, retries, and honours `http.allowHosts`. Where the URL is built from anything a caller supplied it ALSO blocks loopback / RFC-1918 / link-local targets (incl. 169.254.169.254) on the initial request AND every redirect hop — for a hard-coded host that half is redundant, and the first three are still the reason to switch",
859
- match: ({ file: e, path: t, serverOnly: n }) => (mt.test(t) || n) && P(e, /^(?:globalThis\.|window\.|self\.)?fetch$/) > 0
859
+ match: ({ file: e, path: t, serverOnly: n }) => (ht.test(t) || n) && N(e, /^(?:globalThis\.|window\.|self\.)?fetch$/) > 0
860
860
  },
861
861
  {
862
862
  id: "form",
863
863
  scope: "client",
864
864
  smell: "per-field useState + a submit flag (hand-rolled form)",
865
865
  use: "useFormBinding — fields + validation from the mutation input Schema; server ValidationError({ field }) routes to the field",
866
- match: ({ src: e, file: t }) => P(t, /^useState$/) >= 4 && /onSubmit|handleSubmit|isSubmitting/.test(e)
866
+ match: ({ src: e, file: t }) => N(t, /^useState$/) >= 4 && /onSubmit|handleSubmit|isSubmitting/.test(e)
867
867
  },
868
868
  {
869
869
  id: "table",
@@ -891,7 +891,7 @@ var le = /* @__PURE__ */ new Set([
891
891
  scope: "client",
892
892
  smell: "useMemo fanning in multiple subscriptions (hand-maintained dep array)",
893
893
  use: "useDerived — dependency-tracked, referentially stable",
894
- match: ({ src: e }) => ut(e, /\buseSubscription\s*[(<]/g) >= 3 && ut(e, /\buseMemo\s*\(/g) >= 3
894
+ match: ({ src: e }) => dt(e, /\buseSubscription\s*[(<]/g) >= 3 && dt(e, /\buseMemo\s*\(/g) >= 3
895
895
  },
896
896
  {
897
897
  id: "next-shim",
@@ -916,7 +916,7 @@ var le = /* @__PURE__ */ new Set([
916
916
  match: ({ file: e }) => e.getDescendantsOfKind(O.CallExpression).filter((e) => /(^|\.)useSubscription$/.test(e.getExpression().getText())).flatMap((e) => {
917
917
  let t = e.getFirstAncestorByKind(O.VariableDeclaration)?.getNameNode();
918
918
  return t === void 0 ? [] : E.isObjectBindingPattern(t) ? t.getElements().filter((e) => (e.getPropertyNameNode() ?? e.getNameNode()).getText() === "data").map((e) => e.getNameNode()) : [];
919
- }).some((t) => pt(e, t).some((e) => {
919
+ }).some((t) => mt(e, t).some((e) => {
920
920
  let t = e.getParent();
921
921
  if (E.isBinaryExpression(t)) {
922
922
  let n = t.getOperatorToken().getText(), r = t.getLeft() === e ? t.getRight() : t.getLeft();
@@ -944,7 +944,7 @@ var le = /* @__PURE__ */ new Set([
944
944
  scope: "server",
945
945
  smell: "several sequential store reads assembling related data (an N+1 you are writing by hand)",
946
946
  use: "reads are a parent→child walk on ONE key → relations() in a *.relations.ts + .with({ … }) (ONE JSON-aggregate query, every dialect); reads collect ids from SEVERAL sources → keep the assembly and run the independent leading reads under Effect.all (same queries, same results, only concurrent — zero parity risk)",
947
- match: (e) => P(e.file, /\bstore\.query$/) >= 3 || P(e.file, /\bstore\.query$/) >= 2 && /\bnew Map\s*\(/.test(e.src)
947
+ match: (e) => N(e.file, /\bstore\.query$/) >= 3 || N(e.file, /\bstore\.query$/) >= 2 && /\bnew Map\s*\(/.test(e.src)
948
948
  },
949
949
  {
950
950
  id: "store-effect-lift",
@@ -967,7 +967,7 @@ var le = /* @__PURE__ */ new Set([
967
967
  use: ".encrypted() on the column — boot fails loudly if no cipher is configured, so it can never silently persist plaintext (a *Hash column and a vault* handle are NOT plaintext secrets: the hash IS the protection — often a unique lookup key — and the handle only names a secret held elsewhere, so both are skipped)",
968
968
  match: ({ src: e }) => e.split("\n").some((e) => [...e.matchAll(/\b([A-Za-z_$][\w$]*)\s*:\s*(?:text|varchar|string|longtext)\s*\(/g)].some((t) => {
969
969
  let n = t[1];
970
- return !/token|secret|credential|password|apikey|accesskey/i.test(n) || _t.test(n) || /^vault/i.test(n) || /\.unique\s*\(/.test(e) ? !1 : !/\.encrypted\s*\(/.test(e);
970
+ return !/token|secret|credential|password|apikey|accesskey/i.test(n) || vt.test(n) || /^vault/i.test(n) || /\.unique\s*\(/.test(e) ? !1 : !/\.encrypted\s*\(/.test(e);
971
971
  }))
972
972
  },
973
973
  {
@@ -977,7 +977,7 @@ var le = /* @__PURE__ */ new Set([
977
977
  use: "you cannot look a value up by equality AND encrypt it non-deterministically — `.encrypted()` would make this column unfindable. Store the HASH as the unique lookup key and keep the secret itself either `.encrypted()` in a second column or nowhere (the framework's own `_voltro_api_keys.hashedKey` is the shape: the presented value is hashed and compared, never read back). A deterministic cipher is the other option and buys equality lookup at the cost of leaking which rows share a value",
978
978
  match: ({ src: e }) => e.split("\n").some((e) => [...e.matchAll(/\b([A-Za-z_$][\w$]*)\s*:\s*(?:text|varchar|string|longtext)\s*\(/g)].some((t) => {
979
979
  let n = t[1];
980
- return !/token|secret|credential|password|apikey|accesskey/i.test(n) || _t.test(n) || /^vault/i.test(n) ? !1 : /\.unique\s*\(/.test(e) && !/\.encrypted\s*\(/.test(e);
980
+ return !/token|secret|credential|password|apikey|accesskey/i.test(n) || vt.test(n) || /^vault/i.test(n) ? !1 : /\.unique\s*\(/.test(e) && !/\.encrypted\s*\(/.test(e);
981
981
  }))
982
982
  },
983
983
  {
@@ -1041,9 +1041,9 @@ var le = /* @__PURE__ */ new Set([
1041
1041
  scope: "server",
1042
1042
  smell: "setRowFilter is registered, but no test passes `rowFilter:` to makeTestContext",
1043
1043
  use: "wire the filter into at least one test (`makeTestContext({ subject, store, rowFilter })`) and sabotage the predicate once to watch it go red — an untested row filter is a visibility rule nothing verifies",
1044
- match: ({ file: e, testSources: t }) => P(e, /^setRowFilter$/) > 0 && ![...t.values()].some((e) => {
1045
- let t = N(e);
1046
- return ft(t, "makeTestContext").length > 0 && /\browFilter\b/.test(t);
1044
+ match: ({ file: e, testSources: t }) => N(e, /^setRowFilter$/) > 0 && ![...t.values()].some((e) => {
1045
+ let t = M(e);
1046
+ return pt(t, "makeTestContext").length > 0 && /\browFilter\b/.test(t);
1047
1047
  })
1048
1048
  },
1049
1049
  {
@@ -1053,15 +1053,15 @@ var le = /* @__PURE__ */ new Set([
1053
1053
  use: "timestampMs / timestampMsOrNull from @voltro/database/wire in the descriptor's output struct — `output` IS the serializer (it is the rpc success schema), so a Date field declared as timestampMs crosses as epoch ms on its own; declaring Schema.Number describes the WIRE type and leaves nothing to convert",
1054
1054
  match: ({ src: e }) => /\.(getTime|toISOString)\s*\(\s*\)/.test(e) && /\.map\s*\(|=>\s*\(\{/.test(e) && /\bexport\s+default\b/.test(e)
1055
1055
  }
1056
- ], yt = (e) => I(e), bt = (e, t) => {
1056
+ ], bt = (e) => F(e), xt = (e, t) => {
1057
1057
  let n = /* @__PURE__ */ new Set();
1058
1058
  for (let r of t) {
1059
1059
  let t = y(e, r), i = t.split(/[\\/]/)[0];
1060
1060
  n.add(i !== void 0 && i !== t ? i : ".");
1061
1061
  }
1062
1062
  return [...n].sort();
1063
- }, xt = /\.(tsx?|jsx?)$/, F = /(^|\/)(node_modules|dist|build|\.framework|\.next|coverage)(\/|$)/, St = /(^|[\\/])[^\\/]*\.generated\.[cm]?[jt]sx?$|\.d\.[cm]?ts$/, Ct = (e, t = [], n = 0) => {
1064
- if (n > 12 || F.test(e)) return t;
1063
+ }, St = /\.(tsx?|jsx?)$/, P = /(^|\/)(node_modules|dist|build|\.framework|\.next|coverage)(\/|$)/, Ct = /(^|[\\/])[^\\/]*\.generated\.[cm]?[jt]sx?$|\.d\.[cm]?ts$/, wt = (e, t = [], n = 0) => {
1064
+ if (n > 12 || P.test(e)) return t;
1065
1065
  let r;
1066
1066
  try {
1067
1067
  r = w(e, { withFileTypes: !0 });
@@ -1072,12 +1072,12 @@ var le = /* @__PURE__ */ new Set([
1072
1072
  let r = v(e, i.name);
1073
1073
  if (i.isDirectory()) {
1074
1074
  if (i.name.startsWith(".")) continue;
1075
- Ct(r, t, n + 1);
1075
+ wt(r, t, n + 1);
1076
1076
  } else je.test(i.name) && t.push(r);
1077
1077
  }
1078
1078
  return t;
1079
- }, I = (e, t = [], n = 0) => {
1080
- if (n > 12 || F.test(e)) return t;
1079
+ }, F = (e, t = [], n = 0) => {
1080
+ if (n > 12 || P.test(e)) return t;
1081
1081
  let r;
1082
1082
  try {
1083
1083
  r = w(e);
@@ -1091,11 +1091,11 @@ var le = /* @__PURE__ */ new Set([
1091
1091
  } catch {
1092
1092
  continue;
1093
1093
  }
1094
- a.isDirectory() ? I(r, t, n + 1) : xt.test(i) && !/\.(test|spec)\./.test(i) && !St.test(i) && t.push(r);
1094
+ a.isDirectory() ? F(r, t, n + 1) : St.test(i) && !/\.(test|spec)\./.test(i) && !Ct.test(i) && t.push(r);
1095
1095
  }
1096
1096
  return t;
1097
- }, wt = (e, t = [], n = 0) => {
1098
- if (n > 12 || F.test(e)) return t;
1097
+ }, I = (e, t = [], n = 0) => {
1098
+ if (n > 12 || P.test(e)) return t;
1099
1099
  let r;
1100
1100
  try {
1101
1101
  r = w(e);
@@ -1109,17 +1109,17 @@ var le = /* @__PURE__ */ new Set([
1109
1109
  } catch {
1110
1110
  continue;
1111
1111
  }
1112
- a.isDirectory() ? wt(r, t, n + 1) : xt.test(i) && /\.(test|spec)\./.test(i) && t.push(r);
1112
+ a.isDirectory() ? I(r, t, n + 1) : St.test(i) && /\.(test|spec)\./.test(i) && t.push(r);
1113
1113
  }
1114
1114
  return t;
1115
- }, Tt = (e) => {
1116
- let t = yt(e);
1115
+ }, L = (e) => {
1116
+ let t = bt(e);
1117
1117
  return {
1118
- dirs: bt(e, t),
1118
+ dirs: xt(e, t),
1119
1119
  fileCount: t.length
1120
1120
  };
1121
- }, Et = (e) => {
1122
- let t = yt(e);
1121
+ }, Tt = (e) => {
1122
+ let t = bt(e);
1123
1123
  if (t.length === 0) return [];
1124
1124
  let n = new D({
1125
1125
  useInMemoryFileSystem: !0,
@@ -1128,8 +1128,8 @@ var le = /* @__PURE__ */ new Set([
1128
1128
  for (let e of t) try {
1129
1129
  i.set(e, C(e, "utf8"));
1130
1130
  } catch {}
1131
- let a = lt([...i.keys()], i, e), o = /* @__PURE__ */ new Map();
1132
- for (let t of wt(e)) try {
1131
+ let a = ut([...i.keys()], i, e), o = /* @__PURE__ */ new Map();
1132
+ for (let t of I(e)) try {
1133
1133
  o.set(t, C(t, "utf8"));
1134
1134
  } catch {}
1135
1135
  for (let s of t) {
@@ -1149,23 +1149,23 @@ var le = /* @__PURE__ */ new Set([
1149
1149
  } catch {
1150
1150
  continue;
1151
1151
  }
1152
- for (let t of vt) {
1153
- if (t.plugin !== void 0 && dt(c, t.plugin) || !t.match(c)) continue;
1152
+ for (let t of yt) {
1153
+ if (t.plugin !== void 0 && ft(c, t.plugin) || !t.match(c)) continue;
1154
1154
  let n = r.get(t.id) ?? [];
1155
1155
  n.push(y(e, s)), r.set(t.id, n);
1156
1156
  }
1157
1157
  }
1158
- return vt.filter((e) => r.has(e.id)).map((e) => ({
1158
+ return yt.filter((e) => r.has(e.id)).map((e) => ({
1159
1159
  rule: e,
1160
1160
  files: r.get(e.id)
1161
1161
  })).sort((e, t) => t.files.length - e.files.length || e.rule.id.localeCompare(t.rule.id));
1162
- }, L = (e) => {
1163
- let t = Tt(e);
1162
+ }, R = (e) => {
1163
+ let t = L(e);
1164
1164
  return {
1165
1165
  root: e,
1166
1166
  scannedFiles: t.fileCount,
1167
1167
  scannedDirs: t.dirs,
1168
- findings: Et(e).map(({ rule: e, files: t }) => ({
1168
+ findings: Tt(e).map(({ rule: e, files: t }) => ({
1169
1169
  id: e.id,
1170
1170
  scope: e.scope,
1171
1171
  smell: e.smell,
@@ -1173,13 +1173,13 @@ var le = /* @__PURE__ */ new Set([
1173
1173
  files: t
1174
1174
  }))
1175
1175
  };
1176
- }, Dt = 3, Ot = .2, kt = 50, At = (e, t) => e >= kt && t > 0 && e / t >= Ot, jt = (e) => {
1176
+ }, Et = 3, Dt = .2, Ot = 50, kt = (e, t) => e >= Ot && t > 0 && e / t >= Dt, At = (e) => {
1177
1177
  let t = /* @__PURE__ */ new Map();
1178
- for (let n of I(e)) try {
1178
+ for (let n of F(e)) try {
1179
1179
  t.set(y(e, n), C(n, "utf8"));
1180
1180
  } catch {}
1181
1181
  let n = /* @__PURE__ */ new Map();
1182
- for (let t of Ct(e)) try {
1182
+ for (let t of wt(e)) try {
1183
1183
  n.set(y(e, t), C(t, "utf8"));
1184
1184
  } catch {}
1185
1185
  let r = Me({
@@ -1187,8 +1187,8 @@ var le = /* @__PURE__ */ new Set([
1187
1187
  envFiles: n
1188
1188
  });
1189
1189
  r !== void 0 && (console.log(""), console.log(Ne(r)));
1190
- }, Mt = (e) => {
1191
- let t = L(e);
1190
+ }, z = (e) => {
1191
+ let t = R(e);
1192
1192
  if (console.log(""), t.scannedFiles === 0) return console.log(`\u2022 hand-roll scan: no source directories found under ${e}.`), console.log(" Walked the app root recursively (node_modules / dist / .framework pruned). Run `voltro doctor <app>` against an app root."), 0;
1193
1193
  if (t.findings.length === 0) return console.log(`\u2713 hand-roll scan: ${t.scannedFiles} file${t.scannedFiles === 1 ? "" : "s"} across ${t.scannedDirs.join(", ")} \u2014 no hand-rolled primitives found.`), 0;
1194
1194
  console.log(`\u2022 Shipped primitives you may be hand-rolling (scanned ${t.scannedFiles} files across ${t.scannedDirs.join(", ")}):`);
@@ -1199,24 +1199,24 @@ var le = /* @__PURE__ */ new Set([
1199
1199
  console.log(` [${e}]`);
1200
1200
  let i = [...r].sort((e, t) => e.files.length - t.files.length);
1201
1201
  for (let e of i) {
1202
- if (At(e.files.length, t.scannedFiles)) {
1202
+ if (kt(e.files.length, t.scannedFiles)) {
1203
1203
  let n = Math.round(e.files.length / t.scannedFiles * 100);
1204
1204
  console.log(` ${e.smell} \u2014 ${e.files.length} file(s), ${n}% of those scanned: a codebase-wide pattern rather than a work list`), console.log(` \u2192 ${e.use}`), console.log(" (paths omitted on purpose at this scale — `voltro doctor --json` has every one.)");
1205
1205
  continue;
1206
1206
  }
1207
- let r = e.files.slice(0, Dt).join(", "), i = e.files.length - Dt;
1207
+ let r = e.files.slice(0, Et).join(", "), i = e.files.length - Et;
1208
1208
  i > 0 && (n += i);
1209
1209
  let a = i > 0 ? `, +${i} more` : "";
1210
1210
  console.log(` ${e.smell} \u2014 ${e.files.length} file(s): ${r}${a}`), console.log(` \u2192 ${e.use}`);
1211
1211
  }
1212
1212
  }
1213
1213
  return n > 0 && console.log(` (${n} more file path${n === 1 ? "" : "s"} not shown \u2014 \`voltro doctor --json\` prints every one.)`), console.log(" (See the \"Pick the SERVER primitive\" / \"Pick the CLIENT primitive\" rubrics in AGENTS.md / CLAUDE.md.)"), t.findings.length;
1214
- }, Nt = "renderMode:'spa' skips this page's SSR compile while its layout shell still renders server-side — adopt it if the page BODY does not need SSR (internal/authenticated pages); keep 'ssr' if the page content needs SEO or server first-paint.", Pt = /export\s+const\s+renderMode\s*(?::[^=]+)?=\s*['"]([^'"]*)['"]/, Ft = /export\s+const\s+dynamic\s*=\s*['"]force-(dynamic|static)['"]/, It = (e) => {
1215
- let t = Pt.exec(e)?.[1];
1214
+ }, jt = "renderMode:'spa' skips this page's SSR compile while its layout shell still renders server-side — adopt it if the page BODY does not need SSR (internal/authenticated pages); keep 'ssr' if the page content needs SEO or server first-paint.", Mt = /export\s+const\s+renderMode\s*(?::[^=]+)?=\s*['"]([^'"]*)['"]/, Nt = /export\s+const\s+dynamic\s*=\s*['"]force-(dynamic|static)['"]/, Pt = (e) => {
1215
+ let t = Mt.exec(e)?.[1];
1216
1216
  if (t !== void 0) return t === "ssr" ? "ssr" : null;
1217
- let n = Ft.exec(e)?.[1];
1217
+ let n = Nt.exec(e)?.[1];
1218
1218
  return n === "dynamic" ? "ssr" : n === "static" ? null : "default";
1219
- }, R = async (e) => {
1219
+ }, B = async (e) => {
1220
1220
  let t = v(e, "src", "pages");
1221
1221
  if (!S(t)) return [];
1222
1222
  let { pages: n, dirs: r } = await u(t), i = [];
@@ -1229,7 +1229,7 @@ var le = /* @__PURE__ */ new Set([
1229
1229
  continue;
1230
1230
  }
1231
1231
  if (c.test(n)) continue;
1232
- let s = It(n);
1232
+ let s = Pt(n);
1233
1233
  s !== null && i.push({
1234
1234
  file: y(e, v(t, a.file)),
1235
1235
  pattern: a.pattern,
@@ -1237,20 +1237,20 @@ var le = /* @__PURE__ */ new Set([
1237
1237
  });
1238
1238
  }
1239
1239
  return i;
1240
- }, Lt = 10, Rt = async (e) => {
1240
+ }, Ft = 10, It = async (e) => {
1241
1241
  console.log("");
1242
1242
  let t = v(e, "src", "pages");
1243
1243
  if (!S(t)) return console.log("• spa-candidate scan: no src/pages here — nothing to check (web apps only)."), 0;
1244
- let n = await R(e);
1244
+ let n = await B(e);
1245
1245
  if (n.length === 0) return console.log("✓ spa-candidate scan: no loader-free, layout-backed pages to flag."), 0;
1246
1246
  console.log(`• renderMode:'spa' candidates (${n.length} page${n.length === 1 ? "" : "s"} — loader-free, under a layout, currently ssr/default):`);
1247
- for (let e of n.slice(0, Lt)) {
1247
+ for (let e of n.slice(0, Ft)) {
1248
1248
  let t = e.currentMode === "ssr" ? "renderMode:'ssr'" : "default renderMode";
1249
1249
  console.log(` ${e.file} (${e.pattern}) — ${t}`);
1250
1250
  }
1251
- let r = n.length - Lt;
1252
- return r > 0 && console.log(` (+${r} more page${r === 1 ? "" : "s"} not shown — \`voltro doctor --json\` prints every one.)`), console.log(` → ${Nt}`), n.length;
1253
- }, zt = /* @__PURE__ */ new Set([
1251
+ let r = n.length - Ft;
1252
+ return r > 0 && console.log(` (+${r} more page${r === 1 ? "" : "s"} not shown — \`voltro doctor --json\` prints every one.)`), console.log(` → ${jt}`), n.length;
1253
+ }, Lt = /* @__PURE__ */ new Set([
1254
1254
  "node_modules",
1255
1255
  "dist",
1256
1256
  "build",
@@ -1258,7 +1258,7 @@ var le = /* @__PURE__ */ new Set([
1258
1258
  ".vite",
1259
1259
  ".framework",
1260
1260
  ".git"
1261
- ]), Bt = (e, t, n) => {
1261
+ ]), Rt = (e, t, n) => {
1262
1262
  let r;
1263
1263
  try {
1264
1264
  r = w(e, { withFileTypes: !0 });
@@ -1266,11 +1266,11 @@ var le = /* @__PURE__ */ new Set([
1266
1266
  return;
1267
1267
  }
1268
1268
  for (let i of r) {
1269
- if (zt.has(i.name)) continue;
1269
+ if (Lt.has(i.name)) continue;
1270
1270
  let r = v(e, i.name);
1271
- i.isDirectory() ? Bt(r, t, n) : i.isFile() && i.name.endsWith(".tsx") && n.push(y(t, r));
1271
+ i.isDirectory() ? Rt(r, t, n) : i.isFile() && i.name.endsWith(".tsx") && n.push(y(t, r));
1272
1272
  }
1273
- }, Vt = (e, t) => {
1273
+ }, zt = (e, t) => {
1274
1274
  let n = /* @__PURE__ */ new Set(), r = /(?:from|import)\s*\(?\s*['"](\.[^'"]*)['"]/g;
1275
1275
  for (let i of t) {
1276
1276
  let t;
@@ -1295,16 +1295,16 @@ var le = /* @__PURE__ */ new Set([
1295
1295
  }
1296
1296
  }
1297
1297
  return n;
1298
- }, Ht = (e, t) => {
1298
+ }, Bt = (e, t) => {
1299
1299
  let n = e.slice(t.length).split(x).slice(0, -1)[0];
1300
1300
  return n !== void 0 && n.startsWith("[");
1301
- }, z = (e) => {
1301
+ }, V = (e) => {
1302
1302
  let t = [], n = v(e, "src", "pages"), r = v(e, "src");
1303
1303
  if (!S(r)) return t;
1304
1304
  let i = [];
1305
- Bt(r, e, i), i.sort();
1305
+ Rt(r, e, i), i.sort();
1306
1306
  let a = `${y(e, n)}${x}`;
1307
- Vt(e, i);
1307
+ zt(e, i);
1308
1308
  for (let n of i) {
1309
1309
  let r = n.slice(n.lastIndexOf(x) + 1);
1310
1310
  if (n.startsWith(a)) {
@@ -1320,7 +1320,7 @@ var le = /* @__PURE__ */ new Set([
1320
1320
  file: n
1321
1321
  });
1322
1322
  } catch {}
1323
- Ht(n, a) && t.push({
1323
+ Bt(n, a) && t.push({
1324
1324
  kind: "top-level-dynamic-route",
1325
1325
  file: n
1326
1326
  });
@@ -1332,35 +1332,35 @@ var le = /* @__PURE__ */ new Set([
1332
1332
  });
1333
1333
  }
1334
1334
  return t;
1335
- }, Ut = 10, B = (e, t, n) => {
1335
+ }, Vt = 10, H = (e, t, n) => {
1336
1336
  if (t.length === 0) return;
1337
1337
  console.log(`• ${e} (${t.length}):`);
1338
- for (let e of t.slice(0, Ut)) console.log(` ${e}`);
1339
- let r = t.length - Ut;
1338
+ for (let e of t.slice(0, Vt)) console.log(` ${e}`);
1339
+ let r = t.length - Vt;
1340
1340
  r > 0 && console.log(` (+${r} more not shown — \`voltro doctor --json\` prints every one.)`), console.log(` → ${n}`);
1341
- }, Wt = (e) => {
1341
+ }, Ht = (e) => {
1342
1342
  console.log("");
1343
1343
  let t = v(e, "src", "pages");
1344
1344
  if (!S(t)) return console.log("• page-convention scan: no src/pages here — nothing to check (web apps only)."), 0;
1345
- let n = z(e);
1345
+ let n = V(e);
1346
1346
  if (n.length === 0) return console.log("✓ page-convention scan: every route is a page.tsx in its own directory, with a test beside it."), 0;
1347
1347
  let r = (e) => n.filter((t) => t.kind === e).map((e) => e.file);
1348
- return B("will NEVER route — page.tsx outside src/pages/", r("suffixed-outside-pages"), "the name says \"route\", the location says otherwise, and the location wins: the URL comes from the directory chain under src/pages/. Move it into the directory whose route it serves, or rename it."), B("pages with no test beside them", r("page-without-test"), "a page and its test belong together — `users/[id].page.tsx` → `users/[id].page.test.tsx`. Advisory only; a missing test is a gap, not a defect."), B("routes whose FIRST segment is dynamic — they claim every URL of that depth", r("top-level-dynamic-route"), "a route like `[id]/[code]` answers `/api/health`, `/internal/readiness` and anything else with that many segments on this origin. That is what the pattern means, so it is not a bug — but it is invisible until something requests such a URL, and then the page renders, its loader runs, and the failure reads as an application error rather than as a route claiming a path nobody meant it to. Give the route a literal first segment (`scan/[id]/[code]`) if you did not intend to own the whole origin at that depth. Advisory."), B("pages with no `meta` export — they serve the APP name as their title", r("page-without-meta"), "a page with no `meta` sets no title, so the response carries `<title>{your app.config name}</title>` — the same string on every such page, to every reader that does not run JavaScript: link previews, crawlers, a bookmark taken before hydration, a screen reader announcing the document. The client router fixes the tab after hydration, which is exactly why this is easy to miss. Add `export const meta = { title: \"…\" }` (or a function of params/loaderData). If such a page also has no real body — it redirects from an effect, say — the missing title is the symptom rather than the bug: on an `ssr` route the server answers 200 with an empty document and the redirect happens only once JavaScript runs. Move it into the loader (`redirect(...)`, a real 303). Advisory."), n.length;
1349
- }, Gt = "voltro doctor [app] [flags]\n\nPreflight an app root: verify it can boot under production `voltro serve`,\nreport shipped primitives the source looks to be hand-rolling, and flag pages\nthat are safe `renderMode:'spa'` candidates.\n\nArguments:\n [app] App directory to check (default: the current directory).\n\nFlags:\n --strict Treat a missing serve bundle as blocking regardless of NODE_ENV\n (the `voltro serve --preflight` behavior). Without it, a missing\n bundle only fails when NODE_ENV=production.\n --json Print the complete scan as JSON — hand-roll findings AND spa\n candidates, every file path, nothing elided. Skips the preflight output.\n --write-authz-allowlist\n Record today's executors that reference NO access check into\n voltro-authz-allowlist.txt, so every later run fails only on\n ADDITIONS. The list is DEBT, not approval — an entry stops\n mattering as soon as its executor gains a guard.\n -h, --help Print this help.", Kt = /* @__PURE__ */ new Map(), V = (e) => {
1350
- let t = Kt.get(e);
1348
+ return H("will NEVER route — page.tsx outside src/pages/", r("suffixed-outside-pages"), "the name says \"route\", the location says otherwise, and the location wins: the URL comes from the directory chain under src/pages/. Move it into the directory whose route it serves, or rename it."), H("pages with no test beside them", r("page-without-test"), "a page and its test belong together — `users/[id].page.tsx` → `users/[id].page.test.tsx`. Advisory only; a missing test is a gap, not a defect."), H("routes whose FIRST segment is dynamic — they claim every URL of that depth", r("top-level-dynamic-route"), "a route like `[id]/[code]` answers `/api/health`, `/internal/readiness` and anything else with that many segments on this origin. That is what the pattern means, so it is not a bug — but it is invisible until something requests such a URL, and then the page renders, its loader runs, and the failure reads as an application error rather than as a route claiming a path nobody meant it to. Give the route a literal first segment (`scan/[id]/[code]`) if you did not intend to own the whole origin at that depth. Advisory."), H("pages with no `meta` export — they serve the APP name as their title", r("page-without-meta"), "a page with no `meta` sets no title, so the response carries `<title>{your app.config name}</title>` — the same string on every such page, to every reader that does not run JavaScript: link previews, crawlers, a bookmark taken before hydration, a screen reader announcing the document. The client router fixes the tab after hydration, which is exactly why this is easy to miss. Add `export const meta = { title: \"…\" }` (or a function of params/loaderData). If such a page also has no real body — it redirects from an effect, say — the missing title is the symptom rather than the bug: on an `ssr` route the server answers 200 with an empty document and the redirect happens only once JavaScript runs. Move it into the loader (`redirect(...)`, a real 303). Advisory."), n.length;
1349
+ }, Ut = "voltro doctor [app] [flags]\n\nPreflight an app root: verify it can boot under production `voltro serve`,\nreport shipped primitives the source looks to be hand-rolling, and flag pages\nthat are safe `renderMode:'spa'` candidates.\n\nArguments:\n [app] App directory to check (default: the current directory).\n\nFlags:\n --strict Treat a missing serve bundle as blocking regardless of NODE_ENV\n (the `voltro serve --preflight` behavior). Without it, a missing\n bundle only fails when NODE_ENV=production.\n --json Print the complete scan as JSON — hand-roll findings AND spa\n candidates, every file path, nothing elided. Skips the preflight output.\n --write-authz-allowlist\n Record today's executors that reference NO access check into\n voltro-authz-allowlist.txt, so every later run fails only on\n ADDITIONS. The list is DEBT, not approval — an entry stops\n mattering as soon as its executor gains a guard.\n -h, --help Print this help.", Wt = /* @__PURE__ */ new Map(), U = (e) => {
1350
+ let t = Wt.get(e);
1351
1351
  if (t !== void 0) return t;
1352
1352
  let n = (async () => {
1353
- let { walk: t, loadDiscovered: n } = await import("./dev-BZO5aLdr.js"), r = await t(e);
1353
+ let { walk: t, loadDiscovered: n } = await import("./dev-P4HyeY9W.js"), r = await t(e);
1354
1354
  return {
1355
1355
  files: r,
1356
1356
  discovered: await n(r)
1357
1357
  };
1358
1358
  })();
1359
- return Kt.set(e, n), n;
1360
- }, qt = async (e) => {
1359
+ return Wt.set(e, n), n;
1360
+ }, Gt = async (e) => {
1361
1361
  let t;
1362
1362
  try {
1363
- let { files: n, discovered: r } = await V(e), i = r.tables.map((e) => {
1363
+ let { files: n, discovered: r } = await U(e), i = r.tables.map((e) => {
1364
1364
  let t = e;
1365
1365
  return {
1366
1366
  name: t.tableName,
@@ -1373,7 +1373,7 @@ var le = /* @__PURE__ */ new Set([
1373
1373
  return;
1374
1374
  }
1375
1375
  t !== null && (console.log(""), console.log(`${t.includes("does not exist") ? "✗" : "✓"} ${t}`));
1376
- }, Jt = (e) => e.map((e) => {
1376
+ }, Kt = (e) => e.map((e) => {
1377
1377
  let t = e, n = Object.entries(t.fields ?? {}).map(([e, t]) => ({
1378
1378
  name: e,
1379
1379
  type: typeof t?.type == "string" ? t.type : ""
@@ -1383,21 +1383,42 @@ var le = /* @__PURE__ */ new Set([
1383
1383
  columns: n,
1384
1384
  primaryKey: t.appliedPrimaryKey ?? []
1385
1385
  };
1386
- }), H = async (e) => {
1386
+ }), qt = async (e) => {
1387
1387
  try {
1388
- let { discovered: t } = await V(e);
1389
- return ve(Jt(t.tables));
1388
+ let { missingRelationSources: t } = await import("./doctorSourceRelations-CPjSwYuZ.js"), { sourceKeys: n } = await import("@voltro/protocol"), { readFile: r } = await import("node:fs/promises"), { discovered: i } = await U(e), a = [];
1389
+ for (let e of i.queries) {
1390
+ let i = n(e.descriptor.source);
1391
+ if (i.length === 0) continue;
1392
+ let o = Jt(e.file);
1393
+ if (o === void 0) continue;
1394
+ let s = await r(o, "utf8").catch(() => null);
1395
+ s !== null && a.push(...t(e.descriptor.name, i, s));
1396
+ }
1397
+ return a;
1390
1398
  } catch {
1391
1399
  return null;
1392
1400
  }
1393
- }, Yt = async (e) => {
1394
- let t = await H(e);
1401
+ }, Jt = (e) => e.endsWith(".ts") && !e.endsWith(".server.ts") ? `${e.slice(0, -3)}.server.ts` : void 0, Yt = async (e) => {
1402
+ let t = await qt(e);
1403
+ if (t === null || t.length === 0) return;
1404
+ let { describeMissingRelationSource: n } = await import("./doctorSourceRelations-CPjSwYuZ.js");
1405
+ console.log(""), console.log(`\u2717 ${t.length} quer${t.length === 1 ? "y" : "ies"} load a relation they do not declare:`);
1406
+ for (let e of t) console.log(` ${n(e)}`);
1407
+ }, W = async (e) => {
1408
+ try {
1409
+ let { discovered: t } = await U(e);
1410
+ return ve(Kt(t.tables));
1411
+ } catch {
1412
+ return null;
1413
+ }
1414
+ }, Xt = async (e) => {
1415
+ let t = await W(e);
1395
1416
  if (t === null || t.tablesChecked === 0) return;
1396
1417
  let n = be(t);
1397
1418
  n !== null && (console.log(""), console.log(`${t.issues.length > 0 ? "✗" : "✓"} ${n}`));
1398
- }, U = async (e) => {
1419
+ }, G = async (e) => {
1399
1420
  try {
1400
- let { payloadPropertyNames: t } = await import("@voltro/runtime"), { discovered: n } = await V(e);
1421
+ let { payloadPropertyNames: t } = await import("@voltro/runtime"), { discovered: n } = await U(e);
1401
1422
  return we(n.events.map((e) => {
1402
1423
  let n = e.descriptor, r = t(n.key);
1403
1424
  return {
@@ -1410,19 +1431,19 @@ var le = /* @__PURE__ */ new Set([
1410
1431
  } catch {
1411
1432
  return null;
1412
1433
  }
1413
- }, Xt = async (e) => {
1414
- let t = await U(e);
1434
+ }, Zt = async (e) => {
1435
+ let t = await G(e);
1415
1436
  if (t === null || t.eventsChecked === 0) return;
1416
1437
  let n = Te(t);
1417
1438
  n !== null && (console.log(""), console.log(`• ${n}`));
1418
1439
  let r = Ee(t);
1419
1440
  r !== null && (console.log(""), console.log(`⚠️ ${r}`));
1420
- }, W = (e) => {
1441
+ }, K = (e) => {
1421
1442
  let t = e, n = typeof t?.message == "string" && t.message !== "" ? t.message : String(e), r = typeof t?.code == "string" ? t.code : void 0;
1422
1443
  return r === void 0 ? n : `${r}: ${n}`;
1423
- }, G = async (e) => {
1444
+ }, q = async (e) => {
1424
1445
  try {
1425
- let { formatServerOnlyLeaks: t } = await import("@voltro/runtime"), n = (await V(e)).discovered.serverOnlyLeaks, r = t(n);
1446
+ let { formatServerOnlyLeaks: t } = await import("@voltro/runtime"), n = (await U(e)).discovered.serverOnlyLeaks, r = t(n);
1426
1447
  return {
1427
1448
  status: {
1428
1449
  checked: !0,
@@ -1433,12 +1454,12 @@ var le = /* @__PURE__ */ new Set([
1433
1454
  } catch (e) {
1434
1455
  return { status: {
1435
1456
  checked: !1,
1436
- reason: W(e)
1457
+ reason: K(e)
1437
1458
  } };
1438
1459
  }
1439
- }, K = async (r) => {
1460
+ }, J = async (r) => {
1440
1461
  try {
1441
- let { loadApiConfig: i } = await import("./dev-BZO5aLdr.js"), { discovered: a } = await V(r), o = n(await i(r)), s = {
1462
+ let { loadApiConfig: i } = await import("./dev-P4HyeY9W.js"), { discovered: a } = await U(r), o = n(await i(r)), s = {
1442
1463
  queries: a.queries,
1443
1464
  mutations: a.mutations,
1444
1465
  actions: a.actions,
@@ -1454,26 +1475,26 @@ var le = /* @__PURE__ */ new Set([
1454
1475
  } catch (e) {
1455
1476
  return {
1456
1477
  checked: !1,
1457
- reason: W(e),
1478
+ reason: K(e),
1458
1479
  defaultDeny: !0,
1459
1480
  undecided: [],
1460
1481
  openAccess: []
1461
1482
  };
1462
1483
  }
1463
- }, Zt = async (e) => {
1464
- let t = await K(e);
1484
+ }, Qt = async (e) => {
1485
+ let t = await J(e);
1465
1486
  if (!t.checked) return console.log(""), console.log("• access decisions: NOT CHECKED — the app's descriptors could not be loaded (not a pass)"), console.log(` reason: ${t.reason ?? "unknown"}`), !1;
1466
1487
  console.log(""), console.log(`access decisions · security.defaultDeny ${t.defaultDeny ? "ON" : "OFF"}`), console.log(` ✗ no access decision ${String(t.undecided.length).padStart(4)}`), console.log(` ✓ openAccess, declared on purpose ${String(t.openAccess.length).padStart(4)}`);
1467
1488
  for (let e of t.openAccess) console.log(` ${e.tag} — ${e.openAccess ?? ""}`);
1468
1489
  if (t.undecided.length === 0) return !1;
1469
1490
  console.log("");
1470
1491
  for (let e of t.undecided) console.log(` ✗ ${e.tag} (${e.kind})${e.file === void 0 ? "" : `\n ${e.file}`}`);
1471
- return console.log(""), t.defaultDeny ? (console.log(" `voltro dev` and `voltro serve` REFUSE to boot on these. Give each a decision:"), Qt(), !0) : (console.log(" This app sets `security: { defaultDeny: false }`, so these BOOT — and each one is"), console.log(" callable by any authenticated session. Advisory here for that reason only."), Qt(), !1);
1472
- }, Qt = () => {
1492
+ return console.log(""), t.defaultDeny ? (console.log(" `voltro dev` and `voltro serve` REFUSE to boot on these. Give each a decision:"), $t(), !0) : (console.log(" This app sets `security: { defaultDeny: false }`, so these BOOT — and each one is"), console.log(" callable by any authenticated session. Advisory here for that reason only."), $t(), !1);
1493
+ }, $t = () => {
1473
1494
  console.log(" `guards: [{ scope: '…' }]` authority the SUBJECT holds globally"), console.log(" `guards: [{ action, resourceType, resource }]` authority per ROW / per resource"), console.log(" — backed by `defineResourcePolicy` + a tuple source you register. If your"), console.log(" relationships already live in your own tables (a `teamMembers` row), register"), console.log(" a tuple source over them; nothing is copied. Fail-closed without a resolver."), console.log(" Docs: Authentication → Authorization."), console.log(" `openAccess: '<why anyone may call it>'` deliberately unauthenticated");
1474
- }, q = async (e) => {
1495
+ }, Y = async (e) => {
1475
1496
  try {
1476
- let { files: t } = await V(e), { WEBHOOK_PATTERN: n, loadWebhookFiles: r } = await import("./webhookDiscovery-il9ti-HE.js"), { incomingWebhookVerification: i } = await import("@voltro/plugin-webhooks"), a = t.filter((e) => n.test(ie(e)));
1497
+ let { files: t } = await U(e), { WEBHOOK_PATTERN: n, loadWebhookFiles: r } = await import("./webhookDiscovery-il9ti-HE.js"), { incomingWebhookVerification: i } = await import("@voltro/plugin-webhooks"), a = t.filter((e) => n.test(ie(e)));
1477
1498
  if (a.length === 0) return {
1478
1499
  checked: !0,
1479
1500
  unverified: [],
@@ -1500,14 +1521,14 @@ var le = /* @__PURE__ */ new Set([
1500
1521
  } catch (e) {
1501
1522
  return {
1502
1523
  checked: !1,
1503
- reason: W(e),
1524
+ reason: K(e),
1504
1525
  unverified: [],
1505
1526
  open: [],
1506
1527
  verified: 0
1507
1528
  };
1508
1529
  }
1509
- }, $t = async (e) => {
1510
- let t = await q(e);
1530
+ }, en = async (e) => {
1531
+ let t = await Y(e);
1511
1532
  if (!t.checked) return console.log(""), console.log("• webhook verification: NOT CHECKED — the app's webhooks could not be loaded (not a pass)"), console.log(` reason: ${t.reason ?? "unknown"}`), !1;
1512
1533
  if (t.verified + t.open.length + t.unverified.length === 0) return !1;
1513
1534
  console.log(""), console.log("incoming webhook verification"), console.log(` ✓ signature / provider verified ${String(t.verified).padStart(4)}`), console.log(` ! deliberately public (none) ${String(t.open.length).padStart(4)}`), console.log(` ✗ nothing verifies the caller ${String(t.unverified.length).padStart(4)}`);
@@ -1516,13 +1537,13 @@ var le = /* @__PURE__ */ new Set([
1516
1537
  console.log("");
1517
1538
  for (let e of t.unverified) console.log(` ✗ ${e.id}\n ${e.file}`);
1518
1539
  return console.log(""), console.log(" These are public POSTs that run your application code, and `voltro dev` /"), console.log(" `voltro serve` REFUSE to mount them. Declare one of: `provider:` (a preset),"), console.log(" `signature:` (your own HMAC scheme), `verification: 'provider'` (your handler"), console.log(" verifies), or `verification: 'none'` (deliberately public)."), !0;
1519
- }, en = async (e) => {
1520
- let { status: t, message: n } = await G(e);
1540
+ }, tn = async (e) => {
1541
+ let { status: t, message: n } = await q(e);
1521
1542
  return t.checked ? n !== void 0 && (console.log(""), console.log(`✗ [serverOnly] ${n}`), !0) : (console.log(""), console.log("• serverOnly: NOT CHECKED — the app's descriptors could not be loaded (not a pass)"), console.log(` reason: ${t.reason ?? "unknown"}`), console.log(" This audit is the automated check that a hash or a token cannot reach the wire, so"), console.log(" an app that leans on `.serverOnly()` should treat a persistent skip as a failure."), console.log(" `voltro doctor --json` reports it as `serverOnly.checked: false` for a CI gate."), !1);
1522
- }, tn = async (e) => tt({
1523
- hasWorkflows: async () => (await V(e)).discovered.workflows.length > 0,
1543
+ }, nn = async (e) => nt({
1544
+ hasWorkflows: async () => (await U(e)).discovered.workflows.length > 0,
1524
1545
  openStore: async () => {
1525
- let { loadApiConfig: t, buildStore: n } = await import("./dev-BZO5aLdr.js"), r = await t(e);
1546
+ let { loadApiConfig: t, buildStore: n } = await import("./dev-P4HyeY9W.js"), r = await t(e);
1526
1547
  if (r === null) throw Error("no app.config.ts in this directory");
1527
1548
  let i = await n(r, void 0);
1528
1549
  return {
@@ -1536,13 +1557,13 @@ var le = /* @__PURE__ */ new Set([
1536
1557
  let { sweepStalledRuns: t } = await import("@voltro/workflow");
1537
1558
  return t({ store: e });
1538
1559
  }
1539
- }), nn = async (e) => {
1540
- let t = rt(await tn(e));
1560
+ }), rn = async (e) => {
1561
+ let t = it(await nn(e));
1541
1562
  t !== null && (console.log(""), console.log(t));
1542
- }, rn = async (e) => {
1563
+ }, an = async (e) => {
1543
1564
  let t;
1544
1565
  try {
1545
- let { payloadPropertyNames: n } = await import("@voltro/runtime"), { files: r, discovered: i } = await V(e);
1566
+ let { payloadPropertyNames: n } = await import("@voltro/runtime"), { files: r, discovered: i } = await U(e);
1546
1567
  t = ke(r, i.workflows.map((e) => {
1547
1568
  let t = e.definition, r = t.payloadSchema === void 0 ? {
1548
1569
  required: [],
@@ -1562,18 +1583,18 @@ var le = /* @__PURE__ */ new Set([
1562
1583
  console.log("");
1563
1584
  let r = t.issues.length > 0 ? "✗" : t.unchecked.length > 0 ? "•" : "✓";
1564
1585
  console.log(`${r} ${n}`);
1565
- }, J = "voltro-authz-allowlist.txt", an = (e, t = (e) => {
1586
+ }, X = "voltro-authz-allowlist.txt", on = (e, t = (e) => {
1566
1587
  try {
1567
1588
  return C(e, "utf8");
1568
1589
  } catch {
1569
1590
  return "";
1570
1591
  }
1571
- }) => /* @__PURE__ */ new Set([...ze, ...Be(I(e).map(t))]), Y = (e, t) => {
1592
+ }) => /* @__PURE__ */ new Set([...Be, ...Ve(F(e).map(t))]), sn = (e, t) => {
1572
1593
  let n = t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1573
1594
  return new RegExp(String.raw`(?:export\s+)?const\s+([A-Za-z_$][\w$]*)\s*=\s*define[A-Za-z]*Event\s*\(\s*\{[^}]*?name\s*:\s*['"\`]${n}['"\`]`, "s").exec(e)?.[1];
1574
- }, X = async (e) => {
1595
+ }, Z = async (e) => {
1575
1596
  try {
1576
- let { discovered: t } = await V(e), n = t.events.map((e) => ({
1597
+ let { discovered: t } = await U(e), n = t.events.map((e) => ({
1577
1598
  name: e.descriptor.name,
1578
1599
  file: e.file
1579
1600
  })).filter((e) => typeof e.name == "string");
@@ -1584,25 +1605,25 @@ var le = /* @__PURE__ */ new Set([
1584
1605
  } catch {
1585
1606
  return "";
1586
1607
  }
1587
- }, a = I(e).filter((e) => !r.has(e)).map(i).join("\n");
1608
+ }, a = F(e).filter((e) => !r.has(e)).map(i).join("\n");
1588
1609
  return n.filter(({ name: e, file: t }) => {
1589
1610
  if (a.includes(e)) return !1;
1590
- let n = Y(i(t), e);
1611
+ let n = sn(i(t), e);
1591
1612
  return n === void 0 || !new RegExp(String.raw`\b${n}\b`).test(a);
1592
1613
  }).map((e) => e.name).sort();
1593
1614
  } catch {
1594
1615
  return [];
1595
1616
  }
1596
- }, on = async (e) => {
1597
- let t = await X(e);
1617
+ }, cn = async (e) => {
1618
+ let t = await Z(e);
1598
1619
  if (t.length !== 0) {
1599
1620
  console.log(""), console.log(`• ${t.length} declared event(s) with no emit call site found:`);
1600
1621
  for (let e of t) console.log(` ${e}`);
1601
1622
  console.log(""), console.log(" An event you declare is an event partners can subscribe to. One that"), console.log(" never fires is indistinguishable, from their side, from a broken"), console.log(" endpoint of their own — so they debug your contract instead of"), console.log(" reading it."), console.log(" ADVISORY: this looks for the event name AND the identifier its"), console.log(" declaration binds it to, so `emit(ctx, apiKeyCreated, …)` counts. An"), console.log(" emit through an ASSEMBLED name still reads as missing here.");
1602
1623
  }
1603
- }, sn = async (e) => {
1624
+ }, ln = async (e) => {
1604
1625
  try {
1605
- let { loadApiConfig: t } = await import("./dev-BZO5aLdr.js"), n = (await t(e))?.doctor?.scopeVocabulary;
1626
+ let { loadApiConfig: t } = await import("./dev-P4HyeY9W.js"), n = (await t(e))?.doctor?.scopeVocabulary;
1606
1627
  if (typeof n != "string") return [];
1607
1628
  let [r, i] = n.split("#");
1608
1629
  if (r === void 0 || i === void 0) return [];
@@ -1611,7 +1632,7 @@ var le = /* @__PURE__ */ new Set([
1611
1632
  } catch {
1612
1633
  return [];
1613
1634
  }
1614
- }, Z = async (e) => {
1635
+ }, Q = async (e) => {
1615
1636
  let t = (e) => ({
1616
1637
  evaluated: !1,
1617
1638
  notEvaluated: e,
@@ -1619,7 +1640,7 @@ var le = /* @__PURE__ */ new Set([
1619
1640
  findings: []
1620
1641
  });
1621
1642
  try {
1622
- let { offlineManifest: n, toInput: r } = await import("./checkCommand-AlbawIal.js"), { buildAppGraph: i, checkAppGraph: a } = await import("./appGraph-zuMGKVYX.js"), o = await n(e), s = r(o.manifest, o.tables), c = await sn(e), l = [.../* @__PURE__ */ new Set([...s.scopes ?? [], ...c])];
1643
+ let { offlineManifest: n, toInput: r } = await import("./checkCommand-lrzwOzV1.js"), { buildAppGraph: i, checkAppGraph: a } = await import("./appGraph-zuMGKVYX.js"), o = await n(e), s = r(o.manifest, o.tables), c = await ln(e), l = [.../* @__PURE__ */ new Set([...s.scopes ?? [], ...c])];
1623
1644
  if (l.length === 0) {
1624
1645
  try {
1625
1646
  let { loadAppSchemaInputs: t } = await import("./frameworkTableAssembly-DgylYh9_.js");
@@ -1646,8 +1667,8 @@ var le = /* @__PURE__ */ new Set([
1646
1667
  } catch {
1647
1668
  return t("app-not-importable");
1648
1669
  }
1649
- }, cn = async (e) => {
1650
- let { findings: t, evaluated: n, notEvaluated: r } = await Z(e);
1670
+ }, un = async (e) => {
1671
+ let { findings: t, evaluated: n, notEvaluated: r } = await Q(e);
1651
1672
  if (!n) {
1652
1673
  if (console.log(""), r === "app-not-importable") {
1653
1674
  console.log("• scope vocabulary: NOT EVALUATED — `app.config.ts` could not be imported."), console.log(" This is not a statement about your scopes: the rule never got to read"), console.log(" them. The commonest cause is a config that demands its environment while"), console.log(" it is evaluated — an auth strategy reading a secret, say — so it imports"), console.log(" inside the container and not on a workstation."), console.log(""), console.log(" Run doctor where that environment exists, or make the config importable"), console.log(" without it. The same import failure is reported above for plugin tables;"), console.log(" both sections have this one cause.");
@@ -1661,7 +1682,7 @@ var le = /* @__PURE__ */ new Set([
1661
1682
  for (let e of t) console.log(` ${e.node}${e.file === void 0 ? "" : ` ${e.file}`}`), console.log(` ${e.detail}`);
1662
1683
  console.log(""), console.log(" Each of these is uncallable by every user in every role — not"), console.log(" misconfigured, DEAD — and nothing fails at boot to say so. The"), console.log(" usual cause is a typo or a rename that moved one side only."), console.log(` ${t[0].fix}`);
1663
1684
  }
1664
- }, ln = async (e) => {
1685
+ }, dn = async (e) => {
1665
1686
  let t = ["src/locales", "locales"], n, r = [];
1666
1687
  for (let i of t) {
1667
1688
  let t = v(e, i);
@@ -1673,7 +1694,7 @@ var le = /* @__PURE__ */ new Set([
1673
1694
  if (n === void 0 || r.length === 0) return;
1674
1695
  let i = [];
1675
1696
  try {
1676
- let { loadApiConfig: t } = await import("./dev-BZO5aLdr.js");
1697
+ let { loadApiConfig: t } = await import("./dev-P4HyeY9W.js");
1677
1698
  i = (await t(e))?.locales ?? [];
1678
1699
  } catch {
1679
1700
  return;
@@ -1686,7 +1707,7 @@ var le = /* @__PURE__ */ new Set([
1686
1707
  console.log("");
1687
1708
  for (let e of Fe(a, n)) console.log(e);
1688
1709
  }
1689
- }, un = async (e) => {
1710
+ }, fn = async (e) => {
1690
1711
  let t = v(e, "src", "pages");
1691
1712
  if (!S(t)) return !1;
1692
1713
  let n = [];
@@ -1701,10 +1722,10 @@ var le = /* @__PURE__ */ new Set([
1701
1722
  console.log("");
1702
1723
  for (let e of Re(r)) console.log(e);
1703
1724
  return r.problems.length > 0;
1704
- }, dn = async (e) => {
1705
- let { discovered: t } = await V(e), n = [];
1725
+ }, pn = async (e) => {
1726
+ let { discovered: t } = await U(e), n = [];
1706
1727
  try {
1707
- let { loadApiConfig: t } = await import("./dev-BZO5aLdr.js");
1728
+ let { loadApiConfig: t } = await import("./dev-P4HyeY9W.js");
1708
1729
  n = ((await t(e))?.plugins ?? []).map((e) => {
1709
1730
  let t = (e.extendSchema?.tables ?? []).map((e) => {
1710
1731
  let t = e;
@@ -1717,8 +1738,8 @@ var le = /* @__PURE__ */ new Set([
1717
1738
  plugin: e.name,
1718
1739
  tables: t,
1719
1740
  rpcTags: n,
1720
- canDisableTables: fn.has(r),
1721
- canAlias: pn.has(r)
1741
+ canDisableTables: mn.has(r),
1742
+ canAlias: hn.has(r)
1722
1743
  };
1723
1744
  });
1724
1745
  } catch {
@@ -1730,18 +1751,18 @@ var le = /* @__PURE__ */ new Set([
1730
1751
  ...t.mutations,
1731
1752
  ...t.actions,
1732
1753
  ...t.streams ?? []
1733
- ].map((e) => String(e.descriptor.name)), i = $e(n, {
1754
+ ].map((e) => String(e.descriptor.name)), i = et(n, {
1734
1755
  tables: t.tables.map((e) => e.tableName),
1735
1756
  rpcTags: r
1736
1757
  });
1737
1758
  console.log();
1738
- for (let e of et(n, i)) console.log(e);
1739
- }, fn = /* @__PURE__ */ new Set([
1759
+ for (let e of tt(n, i)) console.log(e);
1760
+ }, mn = /* @__PURE__ */ new Set([
1740
1761
  "@voltro/plugin-rbac",
1741
1762
  "@voltro/plugin-audit",
1742
1763
  "@voltro/plugin-notifications",
1743
1764
  "aiFlows"
1744
- ]), pn = /* @__PURE__ */ new Set([
1765
+ ]), hn = /* @__PURE__ */ new Set([
1745
1766
  "aiFlows",
1746
1767
  "@voltro/plugin-audit",
1747
1768
  "@voltro/plugin-billing",
@@ -1758,8 +1779,8 @@ var le = /* @__PURE__ */ new Set([
1758
1779
  "@voltro/plugin-sso-saml",
1759
1780
  "@voltro/plugin-storage",
1760
1781
  "@voltro/plugin-versioning"
1761
- ]), Q = 20, mn = async (e) => {
1762
- let t = await $(e), n = new Set(t.reviewed.map((e) => e.tag)), r = t.result.findings.filter((e) => e.verdict.kind === "allowlisted" && !n.has(e.tag)).length;
1782
+ ]), $ = 20, gn = async (e) => {
1783
+ let t = await _n(e), n = new Set(t.reviewed.map((e) => e.tag)), r = t.result.findings.filter((e) => e.verdict.kind === "allowlisted" && !n.has(e.tag)).length;
1763
1784
  return {
1764
1785
  executors: t.executorCount,
1765
1786
  guardVocabulary: [...t.vocabulary].sort(),
@@ -1771,15 +1792,15 @@ var le = /* @__PURE__ */ new Set([
1771
1792
  },
1772
1793
  unchecked: t.result.unchecked
1773
1794
  };
1774
- }, $ = async (e) => {
1775
- let { discovered: t } = await V(e), n = /* @__PURE__ */ new Map(), r = (e) => {
1795
+ }, _n = async (e) => {
1796
+ let { discovered: t } = await U(e), n = /* @__PURE__ */ new Map(), r = (e) => {
1776
1797
  if (!n.has(e)) try {
1777
1798
  n.set(e, C(e, "utf8"));
1778
1799
  } catch {
1779
1800
  n.set(e, "");
1780
1801
  }
1781
1802
  return n.get(e);
1782
- }, i = an(e, r), a = /* @__PURE__ */ new Set();
1803
+ }, i = on(e, r), a = /* @__PURE__ */ new Set();
1783
1804
  for (let e of t.tables) for (let t of Object.values(e.fields ?? {})) try {
1784
1805
  let e = t.references?.();
1785
1806
  e && a.add(e.tableName);
@@ -1811,12 +1832,12 @@ var le = /* @__PURE__ */ new Set([
1811
1832
  op: a?.op === "delete" || a?.op === "insert" ? a.op : t,
1812
1833
  ...a?.table === void 0 ? {} : { table: a.table }
1813
1834
  };
1814
- })), s = v(e, J), c = S(s) ? M(C(s, "utf8")) : void 0, l = !1;
1815
- for (let t of I(e)) if (/\bsetRowFilter\s*[<(]/.test(r(t))) {
1835
+ })), s = v(e, X), c = S(s) ? j(C(s, "utf8")) : void 0, l = !1;
1836
+ for (let t of F(e)) if (/\bsetRowFilter\s*[<(]/.test(r(t))) {
1816
1837
  l = !0;
1817
1838
  break;
1818
1839
  }
1819
- let u = Ke({
1840
+ let u = qe({
1820
1841
  executors: o,
1821
1842
  guardVocabulary: i,
1822
1843
  tenantScopedTables: t.tenantScopedTables,
@@ -1833,46 +1854,46 @@ var le = /* @__PURE__ */ new Set([
1833
1854
  executorCount: o.length,
1834
1855
  allowPath: s
1835
1856
  };
1836
- }, hn = async (e, t) => {
1837
- let { result: n, vocabulary: r, existing: i, reviewed: a, executorCount: o, allowPath: s, rowFilterRegistered: c } = await $(e), l = n.counts;
1857
+ }, vn = async (e, t) => {
1858
+ let { result: n, vocabulary: r, existing: i, reviewed: a, executorCount: o, allowPath: s, rowFilterRegistered: c } = await _n(e), l = n.counts;
1838
1859
  console.log(`\nauthz scan · ${o} executor(s)`);
1839
- let u = [...r].filter((e) => !ze.has(e)).sort();
1860
+ let u = [...r].filter((e) => !Be.has(e)).sort();
1840
1861
  console.log(u.length === 0 ? " guard vocabulary: framework names only — no exported require*/assert* found in this app" : ` guard vocabulary: ${u.length} from your source (${u.slice(0, 6).join(", ")}${u.length > 6 ? ", …" : ""})`), console.log(` ✗ no access check ${String(l.unchecked).padStart(4)}`), console.log(` ⚠ inline ownership check, no named guard${String(l.inlineOwnership).padStart(4)} (informational)`), console.log(` ✓ guards: on the descriptor ${String(l.declaredGuard).padStart(4)}`), console.log(` ✓ calls a guard from the vocabulary ${String(l.vocabularyGuard).padStart(4)}`);
1841
1862
  let d = new Set(a.map((e) => e.tag)), f = n.findings.filter((e) => e.verdict.kind === "allowlisted" && !d.has(e.tag)).length, p = l.allowlisted - f;
1842
- if (console.log(` – accepted as recorded debt ${String(f).padStart(4)} (${J})`), console.log(` ✓ reviewed, open on purpose ${String(p).padStart(4)} (\`reviewed=<why>\` in that file)`), c && console.log(" ⓘ this app registers setRowFilter — the scan CANNOT see through it. A finding below may\n already be constrained; verify the filter covers that table and record it as `reviewed=`."), t) {
1843
- let e = S(s) ? C(s, "utf8") : void 0, t = n.unchecked.map((e) => e.tag), r = Xe(e, t);
1844
- return oe(s, Ye(e, t), "utf8"), console.log(`\n${J}: +${r.added} new, ${r.kept} kept, ${r.removed} removed. Doctor now fails on ADDITIONS only.`), r.added === 0 && console.log(" (nothing new was unchecked — the file is unchanged.)"), !1;
1863
+ if (console.log(` – accepted as recorded debt ${String(f).padStart(4)} (${X})`), console.log(` ✓ reviewed, open on purpose ${String(p).padStart(4)} (\`reviewed=<why>\` in that file)`), c && console.log(" ⓘ this app registers setRowFilter — the scan CANNOT see through it. A finding below may\n already be constrained; verify the filter covers that table and record it as `reviewed=`."), t) {
1864
+ let e = S(s) ? C(s, "utf8") : void 0, t = n.unchecked.map((e) => e.tag), r = Ze(e, t);
1865
+ return oe(s, Xe(e, t), "utf8"), console.log(`\n${X}: +${r.added} new, ${r.kept} kept, ${r.removed} removed. Doctor now fails on ADDITIONS only.`), r.added === 0 && console.log(" (nothing new was unchecked — the file is unchanged.)"), !1;
1845
1866
  }
1846
1867
  if (n.unchecked.length === 0) return !1;
1847
1868
  console.log("");
1848
- for (let e of n.unchecked.slice(0, Q)) console.log(` ✗ ${e.tag} — ${e.why}\n ${e.path}`);
1849
- return n.unchecked.length > Q && console.log(` … and ${n.unchecked.length - Q} more — \`voltro doctor --json\` prints every one (\`authz.unchecked\`).`), i === void 0 ? (console.log(`\nNo ${J} yet, so this run is advisory. To start the ratchet:`), console.log("\n voltro doctor --write-authz-allowlist\n"), console.log("That records today's unchecked handlers as DEBT and fails every run after on"), console.log("anything NEW. Fix a handler and its line stops mattering — the scan reports it as"), console.log("guarded whether or not the line is still there."), !1) : (console.log(`\n${n.unchecked.length} executor(s) with no access check are not in ${J}.`), console.log("Add a guard, or add the tag to that file if it is genuinely open."), console.log("\nBefore hand-rolling another check: `guards: [{ action, resourceType, resource }]`"), console.log("answers \"may this subject act on THIS row\" declaratively, and an app whose"), console.log("relationships live in its own tables registers its own tuple source rather than"), console.log("copying data into a framework table. See the authorization docs."), !0);
1850
- }, gn = async (e) => {
1851
- if (e.includes("--help") || e.includes("-h")) return console.log(Gt), 0;
1869
+ for (let e of n.unchecked.slice(0, $)) console.log(` ✗ ${e.tag} — ${e.why}\n ${e.path}`);
1870
+ return n.unchecked.length > $ && console.log(` … and ${n.unchecked.length - $} more — \`voltro doctor --json\` prints every one (\`authz.unchecked\`).`), i === void 0 ? (console.log(`\nNo ${X} yet, so this run is advisory. To start the ratchet:`), console.log("\n voltro doctor --write-authz-allowlist\n"), console.log("That records today's unchecked handlers as DEBT and fails every run after on"), console.log("anything NEW. Fix a handler and its line stops mattering — the scan reports it as"), console.log("guarded whether or not the line is still there."), !1) : (console.log(`\n${n.unchecked.length} executor(s) with no access check are not in ${X}.`), console.log("Add a guard, or add the tag to that file if it is genuinely open."), console.log("\nBefore hand-rolling another check: `guards: [{ action, resourceType, resource }]`"), console.log("answers \"may this subject act on THIS row\" declaratively, and an app whose"), console.log("relationships live in its own tables registers its own tuple source rather than"), console.log("copying data into a framework table. See the authorization docs."), !0);
1871
+ }, yn = async (e) => {
1872
+ if (e.includes("--help") || e.includes("-h")) return console.log(Ut), 0;
1852
1873
  let t = e.includes("--strict"), n = e.find((e) => !e.startsWith("-")), o = b(n ?? process.cwd());
1853
1874
  if (g(e)) return ee(), h({
1854
- ...L(o),
1855
- spaCandidates: await R(o),
1856
- pageConvention: z(o),
1875
+ ...R(o),
1876
+ spaCandidates: await B(o),
1877
+ pageConvention: V(o),
1857
1878
  fileTaxonomy: re(o).findings,
1858
- junctionFks: (await H(o))?.issues ?? [],
1859
- eventDelivery: await U(o),
1879
+ junctionFks: (await W(o))?.issues ?? [],
1880
+ eventDelivery: await G(o),
1860
1881
  duplicateInstances: i(o),
1861
1882
  versionSkew: r(o) ?? null,
1862
- serverOnly: (await G(o)).status,
1863
- accessDecisions: await K(o),
1864
- webhookVerification: await q(o),
1865
- authz: await mn(o),
1866
- ungrantedScopes: await Z(o),
1867
- neverEmittedEvents: await X(o),
1868
- stalledRuns: await tn(o)
1883
+ serverOnly: (await q(o)).status,
1884
+ accessDecisions: await J(o),
1885
+ webhookVerification: await Y(o),
1886
+ authz: await gn(o),
1887
+ ungrantedScopes: await Q(o),
1888
+ neverEmittedEvents: await Z(o),
1889
+ stalledRuns: await nn(o)
1869
1890
  }), 0;
1870
- let c = st(o, t);
1871
- Mt(o), jt(o), Wt(o), ne(o), await Rt(o), await rn(o), await nn(o), await qt(o), await Yt(o), await Xt(o), await dn(o), await cn(o), await on(o), await ln(o);
1872
- let l = await en(o), u = await hn(o, e.includes("--write-authz-allowlist")), d = await Zt(o), f = await $t(o), p = await un(o), m = s(r(o));
1891
+ let c = ct(o, t);
1892
+ z(o), At(o), Ht(o), ne(o), await It(o), await an(o), await rn(o), await Gt(o), await Xt(o), await Yt(o), await Zt(o), await pn(o), await un(o), await cn(o), await dn(o);
1893
+ let l = await tn(o), u = await vn(o, e.includes("--write-authz-allowlist")), d = await Qt(o), f = await en(o), p = await fn(o), m = s(r(o));
1873
1894
  m !== void 0 && (console.log(""), console.log(m));
1874
1895
  let _ = a(i(o));
1875
1896
  return _ !== void 0 && console.log(`\n${_}`), l || u || d || p || f ? Math.max(c, 1) : c;
1876
1897
  };
1877
1898
  //#endregion
1878
- export { G as C, R as S, q as T, Rt as _, mn as a, Et as b, U as c, Tt as d, at as f, Wt as g, Mt as h, K as i, an as l, jt as m, ot as n, X as o, H as p, Nt as r, Y as s, Gt as t, L as u, gn as v, Z as w, z as x, st as y };
1899
+ export { B as C, Y as E, V as S, Q as T, Ht as _, gn as a, ct as b, G as c, L as d, ot as f, z as g, At as h, J as i, on as l, qt as m, st as n, Z as o, W as p, jt as r, sn as s, Ut as t, R as u, It as v, q as w, Tt as x, yn as y };