@dereekb/dbx-components-mcp 13.10.3 → 13.10.4

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.
@@ -5,7 +5,7 @@ const require = __createRequire(import.meta.url);
5
5
  // packages/dbx-components-mcp/package.json
6
6
  var package_default = {
7
7
  name: "@dereekb/dbx-components-mcp",
8
- version: "13.10.3",
8
+ version: "13.10.4",
9
9
  type: "module",
10
10
  bin: {
11
11
  "dbx-components-mcp": "dbx-components-mcp.js"
@@ -836,10 +836,10 @@ var defaultGlobber = async (input) => {
836
836
  }
837
837
  return matches;
838
838
  };
839
- async function loadPackageName(packagePath, readFile13) {
839
+ async function loadPackageName(packagePath, readFile15) {
840
840
  let raw = null;
841
841
  try {
842
- raw = await readFile13(packagePath);
842
+ raw = await readFile15(packagePath);
843
843
  } catch {
844
844
  raw = null;
845
845
  }
@@ -899,15 +899,15 @@ function globToRegex(pattern) {
899
899
  var DEFAULT_READ_FILE = defaultReadFile;
900
900
  var DEFAULT_GLOBBER = defaultGlobber;
901
901
  async function buildForgeFieldsManifest(input) {
902
- const { projectRoot, generator, readFile: readFile13 = DEFAULT_READ_FILE, globber = DEFAULT_GLOBBER, now = () => /* @__PURE__ */ new Date() } = input;
902
+ const { projectRoot, generator, readFile: readFile15 = DEFAULT_READ_FILE, globber = DEFAULT_GLOBBER, now = () => /* @__PURE__ */ new Date() } = input;
903
903
  const configPath = resolve(projectRoot, FORGE_FIELDS_SCAN_CONFIG_FILENAME);
904
904
  const packagePath = resolve(projectRoot, "package.json");
905
- const configOutcome = await loadScanConfig(configPath, readFile13);
905
+ const configOutcome = await loadScanConfig(configPath, readFile15);
906
906
  if (configOutcome.kind !== "ok") {
907
907
  return configOutcome.outcome;
908
908
  }
909
909
  const scanSection = configOutcome.section;
910
- const packageOutcome = await loadPackageName(packagePath, readFile13);
910
+ const packageOutcome = await loadPackageName(packagePath, readFile15);
911
911
  if (packageOutcome.kind !== "ok") {
912
912
  return packageOutcome.outcome;
913
913
  }
@@ -920,7 +920,7 @@ async function buildForgeFieldsManifest(input) {
920
920
  const project = new Project({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
921
921
  for (const relPath of filePaths) {
922
922
  const absolute = resolve(projectRoot, relPath);
923
- const text = await readFile13(absolute);
923
+ const text = await readFile15(absolute);
924
924
  project.createSourceFile(absolute, text, { overwrite: true });
925
925
  }
926
926
  const extractResult = extractForgeFieldEntries({ project });
@@ -951,10 +951,10 @@ async function buildForgeFieldsManifest(input) {
951
951
  }
952
952
  return outcome;
953
953
  }
954
- async function loadScanConfig(configPath, readFile13) {
954
+ async function loadScanConfig(configPath, readFile15) {
955
955
  let raw = null;
956
956
  try {
957
- raw = await readFile13(configPath);
957
+ raw = await readFile15(configPath);
958
958
  } catch {
959
959
  raw = null;
960
960
  }
@@ -1020,7 +1020,7 @@ import { resolve as resolve2 } from "node:path";
1020
1020
  var DEFAULT_READ_FILE2 = (path) => nodeReadFile2(path, "utf-8");
1021
1021
  var DEFAULT_WRITE_FILE = (path, data) => nodeWriteFile(path, data, "utf-8");
1022
1022
  async function runScanCliBase(input, config) {
1023
- const { argv, cwd, generator, readFile: readFile13 = DEFAULT_READ_FILE2, writeFile: writeFile2 = DEFAULT_WRITE_FILE, globber, now, log = console.log, errorLog = console.error } = input;
1023
+ const { argv, cwd, generator, readFile: readFile15 = DEFAULT_READ_FILE2, writeFile: writeFile2 = DEFAULT_WRITE_FILE, globber, now, log = console.log, errorLog = console.error } = input;
1024
1024
  let result;
1025
1025
  const args = parseScanArgs(argv);
1026
1026
  if (args.kind === "parse-error") {
@@ -1036,8 +1036,8 @@ async function runScanCliBase(input, config) {
1036
1036
  result = { exitCode: 2 };
1037
1037
  } else {
1038
1038
  const projectRoot = resolve2(cwd, args.project);
1039
- const outcome = await config.buildManifest({ projectRoot, generator, readFile: readFile13, globber, now });
1040
- result = await handleOutcome({ outcome, args, projectArg: args.project, readFile: readFile13, writeFile: writeFile2, log, errorLog, config });
1039
+ const outcome = await config.buildManifest({ projectRoot, generator, readFile: readFile15, globber, now });
1040
+ result = await handleOutcome({ outcome, args, projectArg: args.project, readFile: readFile15, writeFile: writeFile2, log, errorLog, config });
1041
1041
  }
1042
1042
  return result;
1043
1043
  }
@@ -1091,7 +1091,7 @@ function parseScanArgs(argv) {
1091
1091
  return result;
1092
1092
  }
1093
1093
  async function handleOutcome(input) {
1094
- const { outcome, args, projectArg, readFile: readFile13, writeFile: writeFile2, log, errorLog, config } = input;
1094
+ const { outcome, args, projectArg, readFile: readFile15, writeFile: writeFile2, log, errorLog, config } = input;
1095
1095
  let result;
1096
1096
  if (outcome.kind === "success") {
1097
1097
  const finalOutPath = args.out === void 0 ? outcome.outPath : resolve2(outcome.outPath, "..", args.out);
@@ -1099,7 +1099,7 @@ async function handleOutcome(input) {
1099
1099
  if (args.check) {
1100
1100
  let existing = null;
1101
1101
  try {
1102
- existing = await readFile13(finalOutPath);
1102
+ existing = await readFile15(finalOutPath);
1103
1103
  } catch {
1104
1104
  existing = null;
1105
1105
  }
@@ -1579,15 +1579,15 @@ var SCAN_CONFIG_FILENAME = "dbx-mcp.scan.json";
1579
1579
  var DEFAULT_READ_FILE3 = defaultReadFile;
1580
1580
  var DEFAULT_GLOBBER2 = defaultGlobber;
1581
1581
  async function buildManifest(input) {
1582
- const { projectRoot, generator, readFile: readFile13 = DEFAULT_READ_FILE3, globber = DEFAULT_GLOBBER2, now = () => /* @__PURE__ */ new Date() } = input;
1582
+ const { projectRoot, generator, readFile: readFile15 = DEFAULT_READ_FILE3, globber = DEFAULT_GLOBBER2, now = () => /* @__PURE__ */ new Date() } = input;
1583
1583
  const configPath = resolve3(projectRoot, SCAN_CONFIG_FILENAME);
1584
1584
  const packagePath = resolve3(projectRoot, "package.json");
1585
- const configOutcome = await loadScanConfig2(configPath, readFile13);
1585
+ const configOutcome = await loadScanConfig2(configPath, readFile15);
1586
1586
  if (configOutcome.kind !== "ok") {
1587
1587
  return configOutcome.outcome;
1588
1588
  }
1589
1589
  const scanConfig = configOutcome.config;
1590
- const packageOutcome = await loadPackageName(packagePath, readFile13);
1590
+ const packageOutcome = await loadPackageName(packagePath, readFile15);
1591
1591
  if (packageOutcome.kind !== "ok") {
1592
1592
  return packageOutcome.outcome;
1593
1593
  }
@@ -1600,7 +1600,7 @@ async function buildManifest(input) {
1600
1600
  const project = new Project2({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
1601
1601
  for (const relPath of filePaths) {
1602
1602
  const absolute = resolve3(projectRoot, relPath);
1603
- const text = await readFile13(absolute);
1603
+ const text = await readFile15(absolute);
1604
1604
  project.createSourceFile(absolute, text, { overwrite: true });
1605
1605
  }
1606
1606
  const extracted = extractEntries({ project });
@@ -1629,10 +1629,10 @@ async function buildManifest(input) {
1629
1629
  }
1630
1630
  return outcome;
1631
1631
  }
1632
- async function loadScanConfig2(configPath, readFile13) {
1632
+ async function loadScanConfig2(configPath, readFile15) {
1633
1633
  let raw = null;
1634
1634
  try {
1635
- raw = await readFile13(configPath);
1635
+ raw = await readFile15(configPath);
1636
1636
  } catch {
1637
1637
  raw = null;
1638
1638
  }
@@ -1704,7 +1704,7 @@ var USAGE2 = [
1704
1704
  var DEFAULT_READ_FILE4 = (path) => nodeReadFile3(path, "utf-8");
1705
1705
  var DEFAULT_WRITE_FILE2 = (path, data) => nodeWriteFile2(path, data, "utf-8");
1706
1706
  async function runScanCli(input) {
1707
- const { argv, cwd, generator, readFile: readFile13 = DEFAULT_READ_FILE4, writeFile: writeFile2 = DEFAULT_WRITE_FILE2, globber, now, log = console.log, errorLog = console.error } = input;
1707
+ const { argv, cwd, generator, readFile: readFile15 = DEFAULT_READ_FILE4, writeFile: writeFile2 = DEFAULT_WRITE_FILE2, globber, now, log = console.log, errorLog = console.error } = input;
1708
1708
  let result;
1709
1709
  const args = parseArgs(argv);
1710
1710
  if (args.kind === "parse-error") {
@@ -1720,8 +1720,8 @@ async function runScanCli(input) {
1720
1720
  result = { exitCode: 2 };
1721
1721
  } else {
1722
1722
  const projectRoot = resolve4(cwd, args.project);
1723
- const outcome = await buildManifest({ projectRoot, generator, readFile: readFile13, globber, now });
1724
- result = await handleOutcome2({ outcome, args, projectArg: args.project, readFile: readFile13, writeFile: writeFile2, log, errorLog });
1723
+ const outcome = await buildManifest({ projectRoot, generator, readFile: readFile15, globber, now });
1724
+ result = await handleOutcome2({ outcome, args, projectArg: args.project, readFile: readFile15, writeFile: writeFile2, log, errorLog });
1725
1725
  }
1726
1726
  return result;
1727
1727
  }
@@ -1775,12 +1775,12 @@ function parseArgs(argv) {
1775
1775
  return result;
1776
1776
  }
1777
1777
  async function handleSuccessOutcome(input) {
1778
- const { outcome, args, projectArg, readFile: readFile13, writeFile: writeFile2, log, errorLog } = input;
1778
+ const { outcome, args, projectArg, readFile: readFile15, writeFile: writeFile2, log, errorLog } = input;
1779
1779
  const finalOutPath = args.out === void 0 ? outcome.outPath : resolve4(outcome.outPath, "..", args.out);
1780
1780
  const serialized = serializeManifest(outcome.manifest);
1781
1781
  let result;
1782
1782
  if (args.check) {
1783
- result = await checkManifest({ finalOutPath, serialized, outcome, projectArg, readFile: readFile13, log, errorLog });
1783
+ result = await checkManifest({ finalOutPath, serialized, outcome, projectArg, readFile: readFile15, log, errorLog });
1784
1784
  } else {
1785
1785
  await writeFile2(finalOutPath, serialized);
1786
1786
  log(`Wrote manifest: ${finalOutPath} (${outcome.manifest.entries.length} entries, ${outcome.scannedFileCount} files scanned)`);
@@ -1789,10 +1789,10 @@ async function handleSuccessOutcome(input) {
1789
1789
  return result;
1790
1790
  }
1791
1791
  async function checkManifest(input) {
1792
- const { finalOutPath, serialized, outcome, projectArg, readFile: readFile13, log, errorLog } = input;
1792
+ const { finalOutPath, serialized, outcome, projectArg, readFile: readFile15, log, errorLog } = input;
1793
1793
  let existing;
1794
1794
  try {
1795
- existing = await readFile13(finalOutPath);
1795
+ existing = await readFile15(finalOutPath);
1796
1796
  } catch {
1797
1797
  existing = null;
1798
1798
  }
@@ -1987,13 +1987,13 @@ function parseDecoratorInput(property) {
1987
1987
  }
1988
1988
  }
1989
1989
  const required = requiredFromDecorator ?? !property.hasQuestionToken();
1990
- const type60 = property.getTypeNode()?.getText() ?? "unknown";
1990
+ const type62 = property.getTypeNode()?.getText() ?? "unknown";
1991
1991
  const initializer = property.getInitializer();
1992
1992
  const defaultValue = initializer === void 0 ? void 0 : initializer.getText();
1993
1993
  return {
1994
1994
  propertyName,
1995
1995
  alias: alias ?? propertyName,
1996
- type: type60,
1996
+ type: type62,
1997
1997
  required,
1998
1998
  description: readPropertyDescription(property),
1999
1999
  ...defaultValue === void 0 ? {} : { defaultValue }
@@ -2059,22 +2059,22 @@ function parseDecoratorOutput(property) {
2059
2059
  alias = decoratorArg.getLiteralText();
2060
2060
  }
2061
2061
  const initializer = property.getInitializer();
2062
- let type60 = "unknown";
2062
+ let type62 = "unknown";
2063
2063
  if (initializer !== void 0 && Node4.isNewExpression(initializer)) {
2064
2064
  const typeArgs = initializer.getTypeArguments();
2065
2065
  if (typeArgs.length > 0) {
2066
- type60 = typeArgs[0].getText();
2066
+ type62 = typeArgs[0].getText();
2067
2067
  }
2068
2068
  } else {
2069
2069
  const explicit = property.getTypeNode()?.getText();
2070
2070
  if (explicit !== void 0) {
2071
- type60 = explicit;
2071
+ type62 = explicit;
2072
2072
  }
2073
2073
  }
2074
2074
  return {
2075
2075
  propertyName,
2076
2076
  name: alias ?? propertyName,
2077
- type: type60,
2077
+ type: type62,
2078
2078
  description: readPropertyDescription(property)
2079
2079
  };
2080
2080
  }
@@ -2089,7 +2089,7 @@ function parseSignalOutput(property) {
2089
2089
  }
2090
2090
  const propertyName = property.getName();
2091
2091
  const typeArgs = initializer.getTypeArguments();
2092
- const type60 = typeArgs.length > 0 ? typeArgs[0].getText() : "void";
2092
+ const type62 = typeArgs.length > 0 ? typeArgs[0].getText() : "void";
2093
2093
  const args = initializer.getArguments();
2094
2094
  let alias;
2095
2095
  if (args.length > 0 && Node4.isObjectLiteralExpression(args[0])) {
@@ -2098,7 +2098,7 @@ function parseSignalOutput(property) {
2098
2098
  return {
2099
2099
  propertyName,
2100
2100
  name: alias ?? propertyName,
2101
- type: type60,
2101
+ type: type62,
2102
2102
  description: readPropertyDescription(property)
2103
2103
  };
2104
2104
  }
@@ -2485,15 +2485,15 @@ var UI_COMPONENTS_SCAN_CONFIG_FILENAME = "dbx-mcp.scan.json";
2485
2485
  var DEFAULT_READ_FILE5 = defaultReadFile;
2486
2486
  var DEFAULT_GLOBBER3 = defaultGlobber;
2487
2487
  async function buildUiComponentsManifest(input) {
2488
- const { projectRoot, generator, readFile: readFile13 = DEFAULT_READ_FILE5, globber = DEFAULT_GLOBBER3, now = () => /* @__PURE__ */ new Date() } = input;
2488
+ const { projectRoot, generator, readFile: readFile15 = DEFAULT_READ_FILE5, globber = DEFAULT_GLOBBER3, now = () => /* @__PURE__ */ new Date() } = input;
2489
2489
  const configPath = resolve5(projectRoot, UI_COMPONENTS_SCAN_CONFIG_FILENAME);
2490
2490
  const packagePath = resolve5(projectRoot, "package.json");
2491
- const configOutcome = await loadScanConfig3(configPath, readFile13);
2491
+ const configOutcome = await loadScanConfig3(configPath, readFile15);
2492
2492
  if (configOutcome.kind !== "ok") {
2493
2493
  return configOutcome.outcome;
2494
2494
  }
2495
2495
  const scanSection = configOutcome.section;
2496
- const packageOutcome = await loadPackageName(packagePath, readFile13);
2496
+ const packageOutcome = await loadPackageName(packagePath, readFile15);
2497
2497
  if (packageOutcome.kind !== "ok") {
2498
2498
  return packageOutcome.outcome;
2499
2499
  }
@@ -2506,7 +2506,7 @@ async function buildUiComponentsManifest(input) {
2506
2506
  const project = new Project3({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
2507
2507
  for (const relPath of filePaths) {
2508
2508
  const absolute = resolve5(projectRoot, relPath);
2509
- const text = await readFile13(absolute);
2509
+ const text = await readFile15(absolute);
2510
2510
  project.createSourceFile(absolute, text, { overwrite: true });
2511
2511
  }
2512
2512
  const extractResult = extractUiEntries({ project });
@@ -2537,10 +2537,10 @@ async function buildUiComponentsManifest(input) {
2537
2537
  }
2538
2538
  return outcome;
2539
2539
  }
2540
- async function loadScanConfig3(configPath, readFile13) {
2540
+ async function loadScanConfig3(configPath, readFile15) {
2541
2541
  let raw = null;
2542
2542
  try {
2543
- raw = await readFile13(configPath);
2543
+ raw = await readFile15(configPath);
2544
2544
  } catch {
2545
2545
  raw = null;
2546
2546
  }
@@ -2679,11 +2679,11 @@ var DbxMcpConfig = type13({
2679
2679
  var CONFIG_FILENAME = "dbx-mcp.config.json";
2680
2680
  var DEFAULT_READ_FILE6 = (path) => nodeReadFile4(path, "utf-8");
2681
2681
  async function findAndLoadConfig(input) {
2682
- const { cwd, readFile: readFile13 = DEFAULT_READ_FILE6 } = input;
2682
+ const { cwd, readFile: readFile15 = DEFAULT_READ_FILE6 } = input;
2683
2683
  const configPath = resolve6(cwd, CONFIG_FILENAME);
2684
2684
  let raw = null;
2685
2685
  try {
2686
- raw = await readFile13(configPath);
2686
+ raw = await readFile15(configPath);
2687
2687
  } catch {
2688
2688
  raw = null;
2689
2689
  }
@@ -2948,10 +2948,10 @@ import { readFile as nodeReadFile5 } from "node:fs/promises";
2948
2948
  import { type as type16 } from "arktype";
2949
2949
  var DEFAULT_READ_FILE7 = (path) => nodeReadFile5(path, "utf-8");
2950
2950
  var SUPPORTED_VERSION = 1;
2951
- async function loadFromSource(source, readFile13, schema) {
2951
+ async function loadFromSource(source, readFile15, schema) {
2952
2952
  let raw = null;
2953
2953
  try {
2954
- raw = await readFile13(source.path);
2954
+ raw = await readFile15(source.path);
2955
2955
  } catch {
2956
2956
  raw = null;
2957
2957
  }
@@ -3008,12 +3008,12 @@ function warningSortKey(warning) {
3008
3008
  return key;
3009
3009
  }
3010
3010
  async function loadManifestsBase(input, config) {
3011
- const { sources, readFile: readFile13 = DEFAULT_READ_FILE7 } = input;
3011
+ const { sources, readFile: readFile15 = DEFAULT_READ_FILE7 } = input;
3012
3012
  const { name, schema, extractIndexValue, buildEntryKey } = config;
3013
3013
  const successes = [];
3014
3014
  const warnings = [];
3015
3015
  for (const source of sources) {
3016
- const outcome = await loadFromSource(source, readFile13, schema);
3016
+ const outcome = await loadFromSource(source, readFile15, schema);
3017
3017
  if (outcome.kind === "success") {
3018
3018
  successes.push({ source, manifest: outcome.manifest });
3019
3019
  } else if (isStrictSource(source)) {
@@ -3117,9 +3117,9 @@ var DEFAULT_BUNDLED_PATHS = () => {
3117
3117
  return DEFAULT_BUNDLED_FILENAMES.map((name) => resolve7(packageRoot, "generated", name));
3118
3118
  };
3119
3119
  async function loadActionRegistry(input) {
3120
- const { cwd, bundledManifestPaths = DEFAULT_BUNDLED_PATHS, readFile: readFile13 } = input;
3120
+ const { cwd, bundledManifestPaths = DEFAULT_BUNDLED_PATHS, readFile: readFile15 } = input;
3121
3121
  const bundledSources = bundledManifestPaths().map((path) => ({ origin: "bundled", path }));
3122
- const configResult = await findAndLoadConfig({ cwd, readFile: readFile13 });
3122
+ const configResult = await findAndLoadConfig({ cwd, readFile: readFile15 });
3123
3123
  const externalSources = [];
3124
3124
  if (configResult.config !== null && configResult.configPath !== null) {
3125
3125
  const baseDir = dirname(configResult.configPath);
@@ -3133,7 +3133,7 @@ async function loadActionRegistry(input) {
3133
3133
  let loaderWarnings = [];
3134
3134
  const sources = [...bundledSources, ...externalSources];
3135
3135
  if (sources.length > 0) {
3136
- const loaded = await loadActionManifests({ sources, readFile: readFile13 });
3136
+ const loaded = await loadActionManifests({ sources, readFile: readFile15 });
3137
3137
  registry = createActionRegistry(loaded);
3138
3138
  loaderWarnings = loaded.warnings;
3139
3139
  }
@@ -3333,9 +3333,9 @@ var DEFAULT_BUNDLED_PATHS2 = () => {
3333
3333
  return DEFAULT_BUNDLED_FILENAMES2.map((name) => resolve8(packageRoot, "generated", name));
3334
3334
  };
3335
3335
  async function loadFilterRegistry(input) {
3336
- const { cwd, bundledManifestPaths = DEFAULT_BUNDLED_PATHS2, readFile: readFile13 } = input;
3336
+ const { cwd, bundledManifestPaths = DEFAULT_BUNDLED_PATHS2, readFile: readFile15 } = input;
3337
3337
  const bundledSources = bundledManifestPaths().map((path) => ({ origin: "bundled", path }));
3338
- const configResult = await findAndLoadConfig({ cwd, readFile: readFile13 });
3338
+ const configResult = await findAndLoadConfig({ cwd, readFile: readFile15 });
3339
3339
  const externalSources = [];
3340
3340
  if (configResult.config !== null && configResult.configPath !== null) {
3341
3341
  const baseDir = dirname2(configResult.configPath);
@@ -3349,7 +3349,7 @@ async function loadFilterRegistry(input) {
3349
3349
  let loaderWarnings = [];
3350
3350
  const sources = [...bundledSources, ...externalSources];
3351
3351
  if (sources.length > 0) {
3352
- const loaded = await loadFilterManifests({ sources, readFile: readFile13 });
3352
+ const loaded = await loadFilterManifests({ sources, readFile: readFile15 });
3353
3353
  registry = createFilterRegistry(loaded);
3354
3354
  loaderWarnings = loaded.warnings;
3355
3355
  }
@@ -3580,9 +3580,9 @@ var DEFAULT_BUNDLED_PATHS3 = () => {
3580
3580
  return DEFAULT_BUNDLED_FILENAMES3.map((name) => resolve9(packageRoot, "generated", name));
3581
3581
  };
3582
3582
  async function loadForgeFieldRegistry(input) {
3583
- const { cwd, bundledManifestPaths = DEFAULT_BUNDLED_PATHS3, readFile: readFile13 } = input;
3583
+ const { cwd, bundledManifestPaths = DEFAULT_BUNDLED_PATHS3, readFile: readFile15 } = input;
3584
3584
  const bundledSources = bundledManifestPaths().map((path) => ({ origin: "bundled", path }));
3585
- const configResult = await findAndLoadConfig({ cwd, readFile: readFile13 });
3585
+ const configResult = await findAndLoadConfig({ cwd, readFile: readFile15 });
3586
3586
  const externalSources = [];
3587
3587
  if (configResult.config !== null && configResult.configPath !== null) {
3588
3588
  const baseDir = dirname3(configResult.configPath);
@@ -3596,7 +3596,7 @@ async function loadForgeFieldRegistry(input) {
3596
3596
  let loaderWarnings = [];
3597
3597
  const sources = [...bundledSources, ...externalSources];
3598
3598
  if (sources.length > 0) {
3599
- const loaded = await loadForgeFieldManifests({ sources, readFile: readFile13 });
3599
+ const loaded = await loadForgeFieldManifests({ sources, readFile: readFile15 });
3600
3600
  registry = createForgeFieldRegistry(loaded);
3601
3601
  loaderWarnings = loaded.warnings;
3602
3602
  }
@@ -3762,9 +3762,9 @@ var DEFAULT_BUNDLED_PATHS4 = () => {
3762
3762
  return DEFAULT_BUNDLED_FILENAMES4.map((name) => resolve10(packageRoot, "generated", name));
3763
3763
  };
3764
3764
  async function loadPipeRegistry(input) {
3765
- const { cwd, bundledManifestPaths = DEFAULT_BUNDLED_PATHS4, readFile: readFile13 } = input;
3765
+ const { cwd, bundledManifestPaths = DEFAULT_BUNDLED_PATHS4, readFile: readFile15 } = input;
3766
3766
  const bundledSources = bundledManifestPaths().map((path) => ({ origin: "bundled", path }));
3767
- const configResult = await findAndLoadConfig({ cwd, readFile: readFile13 });
3767
+ const configResult = await findAndLoadConfig({ cwd, readFile: readFile15 });
3768
3768
  const externalSources = [];
3769
3769
  if (configResult.config !== null && configResult.configPath !== null) {
3770
3770
  const baseDir = dirname4(configResult.configPath);
@@ -3778,7 +3778,7 @@ async function loadPipeRegistry(input) {
3778
3778
  let loaderWarnings = [];
3779
3779
  const sources = [...bundledSources, ...externalSources];
3780
3780
  if (sources.length > 0) {
3781
- const loaded = await loadPipeManifests({ sources, readFile: readFile13 });
3781
+ const loaded = await loadPipeManifests({ sources, readFile: readFile15 });
3782
3782
  registry = createPipeRegistry(loaded);
3783
3783
  loaderWarnings = loaded.warnings;
3784
3784
  }
@@ -3882,10 +3882,10 @@ function isCoreTopic(topic) {
3882
3882
  // packages/dbx-components-mcp/src/manifest/loader.ts
3883
3883
  var DEFAULT_READ_FILE8 = (path) => nodeReadFile6(path, "utf-8");
3884
3884
  var SUPPORTED_VERSION2 = 1;
3885
- async function loadFromSource2(source, readFile13) {
3885
+ async function loadFromSource2(source, readFile15) {
3886
3886
  let raw = null;
3887
3887
  try {
3888
- raw = await readFile13(source.path);
3888
+ raw = await readFile15(source.path);
3889
3889
  } catch {
3890
3890
  }
3891
3891
  let result;
@@ -3972,11 +3972,11 @@ function warningSortKey2(warning) {
3972
3972
  return key;
3973
3973
  }
3974
3974
  async function loadSemanticTypeManifests(input) {
3975
- const { sources, readFile: readFile13 = DEFAULT_READ_FILE8 } = input;
3975
+ const { sources, readFile: readFile15 = DEFAULT_READ_FILE8 } = input;
3976
3976
  const successes = [];
3977
3977
  const warnings = [];
3978
3978
  for (const source of sources) {
3979
- const outcome = await loadFromSource2(source, readFile13);
3979
+ const outcome = await loadFromSource2(source, readFile15);
3980
3980
  if (outcome.kind === "success") {
3981
3981
  successes.push({ source, manifest: outcome.manifest });
3982
3982
  } else if (isStrictSource2(source)) {
@@ -4073,9 +4073,9 @@ var DEFAULT_BUNDLED_PATHS5 = () => {
4073
4073
  return DEFAULT_BUNDLED_FILENAMES5.map((name) => resolve11(packageRoot, "generated", name));
4074
4074
  };
4075
4075
  async function loadSemanticTypeRegistry(input) {
4076
- const { cwd, bundledManifestPaths = DEFAULT_BUNDLED_PATHS5, readFile: readFile13 } = input;
4076
+ const { cwd, bundledManifestPaths = DEFAULT_BUNDLED_PATHS5, readFile: readFile15 } = input;
4077
4077
  const bundledSources = bundledManifestPaths().map((path) => ({ origin: "bundled", path }));
4078
- const configResult = await findAndLoadConfig({ cwd, readFile: readFile13 });
4078
+ const configResult = await findAndLoadConfig({ cwd, readFile: readFile15 });
4079
4079
  const externalSources = [];
4080
4080
  if (configResult.config !== null && configResult.configPath !== null) {
4081
4081
  const baseDir = dirname5(configResult.configPath);
@@ -4089,7 +4089,7 @@ async function loadSemanticTypeRegistry(input) {
4089
4089
  let loaderWarnings = [];
4090
4090
  const sources = [...bundledSources, ...externalSources];
4091
4091
  if (sources.length > 0) {
4092
- const loaded = await loadSemanticTypeManifests({ sources, readFile: readFile13 });
4092
+ const loaded = await loadSemanticTypeManifests({ sources, readFile: readFile15 });
4093
4093
  registry = createSemanticTypeRegistry(loaded);
4094
4094
  loaderWarnings = loaded.warnings;
4095
4095
  }
@@ -4234,9 +4234,9 @@ var DEFAULT_BUNDLED_PATHS6 = () => {
4234
4234
  return DEFAULT_BUNDLED_FILENAMES6.map((name) => resolve12(packageRoot, "generated", name));
4235
4235
  };
4236
4236
  async function loadUiComponentRegistry(input) {
4237
- const { cwd, bundledManifestPaths = DEFAULT_BUNDLED_PATHS6, readFile: readFile13 } = input;
4237
+ const { cwd, bundledManifestPaths = DEFAULT_BUNDLED_PATHS6, readFile: readFile15 } = input;
4238
4238
  const bundledSources = bundledManifestPaths().map((path) => ({ origin: "bundled", path }));
4239
- const configResult = await findAndLoadConfig({ cwd, readFile: readFile13 });
4239
+ const configResult = await findAndLoadConfig({ cwd, readFile: readFile15 });
4240
4240
  const externalSources = [];
4241
4241
  if (configResult.config !== null && configResult.configPath !== null) {
4242
4242
  const baseDir = dirname6(configResult.configPath);
@@ -4250,7 +4250,7 @@ async function loadUiComponentRegistry(input) {
4250
4250
  let loaderWarnings = [];
4251
4251
  const sources = [...bundledSources, ...externalSources];
4252
4252
  if (sources.length > 0) {
4253
- const loaded = await loadUiComponentManifests({ sources, readFile: readFile13 });
4253
+ const loaded = await loadUiComponentManifests({ sources, readFile: readFile15 });
4254
4254
  registry = createUiComponentRegistry(loaded);
4255
4255
  loaderWarnings = loaded.warnings;
4256
4256
  }
@@ -7262,7 +7262,7 @@ function createLookupFormTool(config) {
7262
7262
  }
7263
7263
  return lines.join("\n").trimEnd();
7264
7264
  }
7265
- function run10(rawArgs) {
7265
+ function run12(rawArgs) {
7266
7266
  let args;
7267
7267
  try {
7268
7268
  args = parseLookupFormArgs(rawArgs);
@@ -7291,7 +7291,7 @@ function createLookupFormTool(config) {
7291
7291
  }
7292
7292
  const tool = {
7293
7293
  definition: DBX_FORM_LOOKUP_TOOL,
7294
- run: run10
7294
+ run: run12
7295
7295
  };
7296
7296
  return tool;
7297
7297
  }
@@ -7480,7 +7480,7 @@ function formatSearchResults(input) {
7480
7480
  }
7481
7481
  function createSearchFormTool(config) {
7482
7482
  const { registry } = config;
7483
- function run10(rawArgs) {
7483
+ function run12(rawArgs) {
7484
7484
  return runSearchTool(
7485
7485
  {
7486
7486
  entries: registry.all,
@@ -7496,7 +7496,7 @@ function createSearchFormTool(config) {
7496
7496
  }
7497
7497
  const tool = {
7498
7498
  definition: DBX_FORM_SEARCH_TOOL,
7499
- run: run10
7499
+ run: run12
7500
7500
  };
7501
7501
  return tool;
7502
7502
  }
@@ -8019,7 +8019,7 @@ function renderScaffold(specs, valueTypeName, wrapInSection) {
8019
8019
  }
8020
8020
  function createFormScaffoldTool(config) {
8021
8021
  const { registry } = config;
8022
- function run10(rawArgs) {
8022
+ function run12(rawArgs) {
8023
8023
  let args;
8024
8024
  try {
8025
8025
  args = parseScaffoldArgs(rawArgs);
@@ -8053,7 +8053,7 @@ ${code11}
8053
8053
  }
8054
8054
  const tool = {
8055
8055
  definition: DBX_FORM_SCAFFOLD_TOOL,
8056
- run: run10
8056
+ run: run12
8057
8057
  };
8058
8058
  return tool;
8059
8059
  }
@@ -8314,7 +8314,7 @@ function formatNotFound3(normalized, candidates) {
8314
8314
  }
8315
8315
  function createLookupUiTool(input) {
8316
8316
  const { registry } = input;
8317
- const run10 = (rawArgs) => {
8317
+ const run12 = (rawArgs) => {
8318
8318
  let args;
8319
8319
  try {
8320
8320
  args = parseLookupUiArgs(rawArgs);
@@ -8341,7 +8341,7 @@ function createLookupUiTool(input) {
8341
8341
  const result = { content: [{ type: "text", text }] };
8342
8342
  return result;
8343
8343
  };
8344
- return { definition: DBX_UI_LOOKUP_TOOL, run: run10 };
8344
+ return { definition: DBX_UI_LOOKUP_TOOL, run: run12 };
8345
8345
  }
8346
8346
 
8347
8347
  // packages/dbx-components-mcp/src/tools/search-ui.tool.ts
@@ -8523,7 +8523,7 @@ function formatSearchResults2(options) {
8523
8523
  }
8524
8524
  function createSearchUiTool(input) {
8525
8525
  const { registry } = input;
8526
- const run10 = (rawArgs) => {
8526
+ const run12 = (rawArgs) => {
8527
8527
  let args;
8528
8528
  try {
8529
8529
  args = parseSearchUiArgs(rawArgs);
@@ -8538,7 +8538,7 @@ function createSearchUiTool(input) {
8538
8538
  const result = { content: [{ type: "text", text }] };
8539
8539
  return result;
8540
8540
  };
8541
- return { definition: DBX_UI_SEARCH_TOOL, run: run10 };
8541
+ return { definition: DBX_UI_SEARCH_TOOL, run: run12 };
8542
8542
  }
8543
8543
 
8544
8544
  // packages/dbx-components-mcp/src/tools/ui-examples.tool.ts
@@ -9934,7 +9934,7 @@ var FolderValidateArgsType = type30({
9934
9934
  });
9935
9935
  function createFolderValidateTool(config) {
9936
9936
  const { definition, inspectFolder: inspectFolder3, validate, format } = config;
9937
- async function run10(rawArgs) {
9937
+ async function run12(rawArgs) {
9938
9938
  const parsed = FolderValidateArgsType(rawArgs);
9939
9939
  if (parsed instanceof type30.errors) {
9940
9940
  return toolError(`Invalid arguments: ${parsed.summary}`);
@@ -9974,7 +9974,7 @@ function createFolderValidateTool(config) {
9974
9974
  };
9975
9975
  return toolResult;
9976
9976
  }
9977
- const tool = { definition, run: run10 };
9977
+ const tool = { definition, run: run12 };
9978
9978
  return tool;
9979
9979
  }
9980
9980
  var SourceValidateArgsType = type30({
@@ -9984,7 +9984,7 @@ var SourceValidateArgsType = type30({
9984
9984
  });
9985
9985
  function createSourceValidateTool(config) {
9986
9986
  const { definition, validate, format } = config;
9987
- async function run10(rawArgs) {
9987
+ async function run12(rawArgs) {
9988
9988
  const parsed = SourceValidateArgsType(rawArgs);
9989
9989
  if (parsed instanceof type30.errors) {
9990
9990
  return toolError(`Invalid arguments: ${parsed.summary}`);
@@ -10011,7 +10011,7 @@ function createSourceValidateTool(config) {
10011
10011
  };
10012
10012
  return toolResult;
10013
10013
  }
10014
- const tool = { definition, run: run10 };
10014
+ const tool = { definition, run: run12 };
10015
10015
  return tool;
10016
10016
  }
10017
10017
  var TwoSideValidateArgsType = type30({
@@ -10038,7 +10038,7 @@ function resolveTwoSideInput(parsed) {
10038
10038
  }
10039
10039
  function createTwoSideValidateTool(config) {
10040
10040
  const { definition, inspectAndValidate, format } = config;
10041
- async function run10(rawArgs) {
10041
+ async function run12(rawArgs) {
10042
10042
  const parsed = TwoSideValidateArgsType(rawArgs);
10043
10043
  if (parsed instanceof type30.errors) {
10044
10044
  return toolError(`Invalid arguments: ${parsed.summary}`);
@@ -10055,7 +10055,7 @@ function createTwoSideValidateTool(config) {
10055
10055
  };
10056
10056
  return toolResult;
10057
10057
  }
10058
- const tool = { definition, run: run10 };
10058
+ const tool = { definition, run: run12 };
10059
10059
  return tool;
10060
10060
  }
10061
10061
  var ListAppArgsType = type30({
@@ -10065,7 +10065,7 @@ var ListAppArgsType = type30({
10065
10065
  });
10066
10066
  function createListAppTool(config) {
10067
10067
  const { definition, inspectAndList, formatMarkdown: formatMarkdown2, formatJson: formatJson2 } = config;
10068
- async function run10(rawArgs) {
10068
+ async function run12(rawArgs) {
10069
10069
  const parsed = ListAppArgsType(rawArgs);
10070
10070
  if (parsed instanceof type30.errors) {
10071
10071
  return toolError(`Invalid arguments: ${parsed.summary}`);
@@ -10079,7 +10079,7 @@ function createListAppTool(config) {
10079
10079
  const toolResult = { content: [{ type: "text", text }] };
10080
10080
  return toolResult;
10081
10081
  }
10082
- const tool = { definition, run: run10 };
10082
+ const tool = { definition, run: run12 };
10083
10083
  return tool;
10084
10084
  }
10085
10085
 
@@ -10113,15 +10113,18 @@ function findDataInterfaces(sourceFile, groupInterface) {
10113
10113
  continue;
10114
10114
  }
10115
10115
  const fields = extractInterfaceFields(iface);
10116
- out.push({ name, fields });
10116
+ const dbxModelTag = readDbxModelTag(iface.getJsDocs());
10117
+ out.push({ name, line: iface.getStartLineNumber(), dbxModelTag, fields });
10117
10118
  }
10118
10119
  return out;
10119
10120
  }
10120
10121
  function extractInterfaceFields(iface) {
10121
10122
  const fields = [];
10122
10123
  for (const prop of iface.getProperties()) {
10123
- const jsDocFirstLine = firstJsDocLine(prop.getJsDocs());
10124
- const field = { name: prop.getName(), line: prop.getStartLineNumber(), jsDocFirstLine };
10124
+ const jsDocs = prop.getJsDocs();
10125
+ const jsDocFirstLine = firstJsDocLine(jsDocs);
10126
+ const dbxModelVariableTag = readDbxModelVariableTag(jsDocs);
10127
+ const field = { name: prop.getName(), line: prop.getStartLineNumber(), jsDocFirstLine, dbxModelVariableTag };
10125
10128
  fields.push(field);
10126
10129
  }
10127
10130
  return fields;
@@ -10154,10 +10157,46 @@ function findGroupInterface(sourceFile) {
10154
10157
  name: iface.getName(),
10155
10158
  exported: iface.isExported(),
10156
10159
  properties,
10157
- line: iface.getStartLineNumber()
10160
+ line: iface.getStartLineNumber(),
10161
+ dbxModelGroupTag: readDbxModelGroupTag2(iface.getJsDocs())
10158
10162
  };
10159
10163
  return result;
10160
10164
  }
10165
+ function readDbxModelGroupTag2(jsDocs) {
10166
+ let result;
10167
+ for (const jsDoc of jsDocs) {
10168
+ for (const tag of jsDoc.getTags()) {
10169
+ if (tag.getTagName() !== "dbxModelGroup") continue;
10170
+ const text = tag.getCommentText()?.trim() ?? "";
10171
+ result = text.length > 0 ? text : true;
10172
+ }
10173
+ }
10174
+ return result;
10175
+ }
10176
+ function readDbxModelTag(jsDocs) {
10177
+ let result = false;
10178
+ for (const jsDoc of jsDocs) {
10179
+ for (const tag of jsDoc.getTags()) {
10180
+ if (tag.getTagName() === "dbxModel") {
10181
+ result = true;
10182
+ }
10183
+ }
10184
+ }
10185
+ return result;
10186
+ }
10187
+ function readDbxModelVariableTag(jsDocs) {
10188
+ let result;
10189
+ for (const jsDoc of jsDocs) {
10190
+ for (const tag of jsDoc.getTags()) {
10191
+ if (tag.getTagName() !== "dbxModelVariable") continue;
10192
+ const text = tag.getCommentText()?.trim();
10193
+ if (text !== void 0 && text.length > 0 && result === void 0) {
10194
+ result = text;
10195
+ }
10196
+ }
10197
+ }
10198
+ return result;
10199
+ }
10161
10200
  function findGroupTypes(sourceFile) {
10162
10201
  const candidate = sourceFile.getTypeAliases().find((t) => {
10163
10202
  const name = t.getName();
@@ -10737,6 +10776,16 @@ var RULE_CATALOG = [
10737
10776
  whenItDoesNotApply: "Fields whose name is unambiguously self-describing (rare with 1-4 char abbreviations).",
10738
10777
  canonicalFix: "Add `/** <fullName> -- <description> *\\/` above the field declaration."
10739
10778
  },
10779
+ {
10780
+ code: "MODEL_FIELD_MISSING_VARIABLE_TAG",
10781
+ source: "dbx_model_validate",
10782
+ severity: "warning",
10783
+ title: "A persisted field is missing its `@dbxModelVariable <name>` JSDoc tag",
10784
+ whatItFlags: "A persisted field is missing its `@dbxModelVariable <name>` JSDoc tag.",
10785
+ whenItApplies: "Every field on a `@dbxModel` interface \u2014 the tag carries the human-readable long name the catalog and decoder use when surfacing the field to operators.",
10786
+ whenItDoesNotApply: "Fields on embedded sub-object interfaces (no `@dbxModel` parent) and fields the project deliberately leaves untagged (rare).",
10787
+ canonicalFix: "Append `@dbxModelVariable <longName>` to the field's JSDoc block."
10788
+ },
10740
10789
  {
10741
10790
  code: "MODEL_FIELD_NAME_TOO_LONG",
10742
10791
  source: "dbx_model_validate",
@@ -10747,6 +10796,22 @@ var RULE_CATALOG = [
10747
10796
  whenItDoesNotApply: "Fields that compose well-known multi-character abbreviations the project intentionally allows.",
10748
10797
  canonicalFix: "Rename the field to a 1\u20134 character abbreviation (e.g. `name` \u2192 `n`, `userId` \u2192 `uid`)."
10749
10798
  },
10799
+ {
10800
+ code: "MODEL_GROUP_INTERFACE_MISSING_TAG",
10801
+ source: "dbx_model_validate",
10802
+ severity: "error",
10803
+ title: "The `<Group>FirestoreCollections` interface is missing its `@dbxModelGroup` JSDoc tag",
10804
+ whatItFlags: "The `<Group>FirestoreCollections` interface is missing its `@dbxModelGroup` JSDoc tag.",
10805
+ whenItApplies: "Every group container \u2014 the rich catalog extractor (`scan/extract-models`) requires the tag to register the group, and downstream traversal/referencing depends on that registration.",
10806
+ whenItDoesNotApply: "Files in `@dereekb/firebase` itself (upstream-owned sources).",
10807
+ canonicalFix: "Add `@dbxModelGroup <Group>` to the JSDoc above the `<Group>FirestoreCollections` declaration.",
10808
+ seeAlso: [
10809
+ {
10810
+ kind: "artifact",
10811
+ target: "firestore-model"
10812
+ }
10813
+ ]
10814
+ },
10750
10815
  {
10751
10816
  code: "MODEL_IDENTITY_BAD_ARGS",
10752
10817
  source: "dbx_model_validate",
@@ -10767,6 +10832,38 @@ var RULE_CATALOG = [
10767
10832
  whenItDoesNotApply: "When intentionally module-private (rare).",
10768
10833
  canonicalFix: "Add `export` to the identity constant declaration."
10769
10834
  },
10835
+ {
10836
+ code: "MODEL_IDENTITY_NOT_TAGGED",
10837
+ source: "dbx_model_validate",
10838
+ severity: "error",
10839
+ title: "`firestoreModelIdentity(...)` was found but its corresponding model interface lacks the `@dbxModel` JSDoc tag, leaving the model invisible to the catalog and to downstream traversal/referencing code",
10840
+ whatItFlags: "`firestoreModelIdentity(...)` was found but its corresponding model interface lacks the `@dbxModel` JSDoc tag, leaving the model invisible to the catalog and to downstream traversal/referencing code.",
10841
+ whenItApplies: "Every `firestoreModelIdentity(...)` call whose `<PascalName>` interface is missing `@dbxModel`. Anchored at the identity line so the fix points at both the interface and the identity.",
10842
+ whenItDoesNotApply: "Files in `@dereekb/firebase` itself.",
10843
+ canonicalFix: "Add `@dbxModel` to the JSDoc on the `<PascalName>` interface so the catalog and decoder recognise it as a model.",
10844
+ seeAlso: [
10845
+ {
10846
+ kind: "artifact",
10847
+ target: "firestore-model"
10848
+ }
10849
+ ]
10850
+ },
10851
+ {
10852
+ code: "MODEL_INTERFACE_MISSING_TAG",
10853
+ source: "dbx_model_validate",
10854
+ severity: "error",
10855
+ title: "The model's data interface is missing its `@dbxModel` JSDoc tag",
10856
+ whatItFlags: "The model's data interface is missing its `@dbxModel` JSDoc tag.",
10857
+ whenItApplies: "Every `<PascalName>` interface that anchors a `firestoreModelIdentity(...)` model \u2014 the rich catalog extractor (`scan/extract-models`) requires the tag to register the model.",
10858
+ whenItDoesNotApply: "Embedded sub-object interfaces (no matching identity) and files in `@dereekb/firebase` itself.",
10859
+ canonicalFix: "Add `@dbxModel` to the JSDoc above the `<PascalName>` interface declaration.",
10860
+ seeAlso: [
10861
+ {
10862
+ kind: "artifact",
10863
+ target: "firestore-model"
10864
+ }
10865
+ ]
10866
+ },
10770
10867
  {
10771
10868
  code: "MODEL_INTERFACE_NOT_EXPORTED",
10772
10869
  source: "dbx_model_validate",
@@ -12562,9 +12659,7 @@ function checkFieldJsDocs(file, violations) {
12562
12659
  line: field.line,
12563
12660
  model: iface.name
12564
12661
  });
12565
- continue;
12566
- }
12567
- if (!FULL_NAME_FIRST_LINE.test(field.jsDocFirstLine)) {
12662
+ } else if (!FULL_NAME_FIRST_LINE.test(field.jsDocFirstLine)) {
12568
12663
  pushViolation(violations, {
12569
12664
  code: "MODEL_FIELD_JSDOC_NO_FULL_NAME",
12570
12665
  severity: "warning",
@@ -12574,6 +12669,16 @@ function checkFieldJsDocs(file, violations) {
12574
12669
  model: iface.name
12575
12670
  });
12576
12671
  }
12672
+ if (iface.dbxModelTag && field.dbxModelVariableTag === void 0) {
12673
+ pushViolation(violations, {
12674
+ code: "MODEL_FIELD_MISSING_VARIABLE_TAG",
12675
+ severity: "warning",
12676
+ message: `Field \`${field.name}\` in interface \`${iface.name}\` is missing its \`@dbxModelVariable <name>\` JSDoc tag. The catalog uses the tag for the field's long name.`,
12677
+ file: file.name,
12678
+ line: field.line,
12679
+ model: iface.name
12680
+ });
12681
+ }
12577
12682
  }
12578
12683
  }
12579
12684
  }
@@ -12598,6 +12703,15 @@ function checkFileLevel(file, violations) {
12598
12703
  model: void 0
12599
12704
  });
12600
12705
  }
12706
+ if (groupInterface.dbxModelGroupTag === void 0) {
12707
+ pushViolation(violations, {
12708
+ code: "MODEL_GROUP_INTERFACE_MISSING_TAG",
12709
+ message: `Interface \`${groupInterface.name}\` is missing its \`@dbxModelGroup\` JSDoc tag. Add \`@dbxModelGroup <Group>\` so the catalog and downstream traversal can register the group.`,
12710
+ file: name,
12711
+ line: groupInterface.line,
12712
+ model: void 0
12713
+ });
12714
+ }
12601
12715
  checkGroupInterfaceCoverage(file, violations);
12602
12716
  } else {
12603
12717
  pushViolation(violations, {
@@ -12747,6 +12861,23 @@ function checkInterface(file, model, violations) {
12747
12861
  model: model.name
12748
12862
  });
12749
12863
  }
12864
+ const dataInterface = file.dataInterfaces.find((d) => d.name === model.name);
12865
+ if (dataInterface && !dataInterface.dbxModelTag) {
12866
+ pushViolation(violations, {
12867
+ code: "MODEL_INTERFACE_MISSING_TAG",
12868
+ message: `Interface \`${model.name}\` is missing its \`@dbxModel\` JSDoc tag. The catalog skips untagged interfaces, so downstream traversal/referencing of \`${model.name}\` is broken.`,
12869
+ file: file.name,
12870
+ line: dataInterface.line,
12871
+ model: model.name
12872
+ });
12873
+ pushViolation(violations, {
12874
+ code: "MODEL_IDENTITY_NOT_TAGGED",
12875
+ message: `\`firestoreModelIdentity\` was found for \`${model.identity.constName}\` but its \`${model.name}\` interface is not tagged with \`@dbxModel\`. Tag the interface so the catalog registers the model.`,
12876
+ file: file.name,
12877
+ line: model.identity.line,
12878
+ model: model.name
12879
+ });
12880
+ }
12750
12881
  }
12751
12882
  function checkRoles(file, model, violations) {
12752
12883
  if (!model.rolesType) {
@@ -13279,7 +13410,7 @@ function validateFirebaseModelSources(sources) {
13279
13410
  var DBX_MODEL_VALIDATE_TOOL = {
13280
13411
  name: "dbx_model_validate",
13281
13412
  description: [
13282
- "Validate a @dereekb/firebase model file against the workspace model-group convention. Checks that the file exports a `<Group>FirestoreCollections` interface and `<Group>Types` union, and that every `firestoreModelIdentity(...)` has the canonical declarations in order (interface, roles, document class, converter, collection reference fn, collection type, collection fn) \u2014 plus the factory-type + collection-group triple for subcollections. All reported issues are hard errors.",
13413
+ "Validate a @dereekb/firebase model file against the workspace model-group convention. Checks that the file exports a `<Group>FirestoreCollections` interface and `<Group>Types` union, and that every `firestoreModelIdentity(...)` has the canonical declarations in order (interface, roles, document class, converter, collection reference fn, collection type, collection fn) \u2014 plus the factory-type + collection-group triple for subcollections. Also enforces JSDoc tagging required for catalog discovery and downstream traversal: `@dbxModelGroup <Group>` on the group container, `@dbxModel` on every model interface (with a per-identity `MODEL_IDENTITY_NOT_TAGGED` error anchored at the `firestoreModelIdentity(...)` line), and `@dbxModelVariable <name>` on every persisted field (warning).",
13283
13414
  "",
13284
13415
  "Provide at least one of:",
13285
13416
  "- `sources`: array of `{ name, text }` \u2014 file contents supplied directly.",
@@ -14496,12 +14627,14 @@ function formatResult3(result) {
14496
14627
  }
14497
14628
 
14498
14629
  // packages/dbx-components-mcp/src/tools/model-validate-folder/inspect.ts
14499
- import { readdir as readdir2, stat as stat4 } from "node:fs/promises";
14500
- import { basename as basename4 } from "node:path";
14630
+ import { readdir as readdir2, readFile as readFile4, stat as stat4 } from "node:fs/promises";
14631
+ import { basename as basename4, join as join3 } from "node:path";
14632
+ var CONTENT_VALIDATION_SKIP_SUFFIXES = [".spec.ts", ".id.ts", ".query.ts", ".action.ts", ".api.ts"];
14501
14633
  async function inspectFolder(path) {
14502
14634
  const name = basename4(path);
14503
14635
  let status;
14504
14636
  let files = [];
14637
+ let sources = [];
14505
14638
  try {
14506
14639
  const stats = await stat4(path);
14507
14640
  if (stats.isDirectory()) {
@@ -14514,6 +14647,7 @@ async function inspectFolder(path) {
14514
14647
  collected.push(entry.name);
14515
14648
  }
14516
14649
  files = collected;
14650
+ sources = await readModelSources(path, collected);
14517
14651
  } else {
14518
14652
  status = "not-directory";
14519
14653
  }
@@ -14525,9 +14659,19 @@ async function inspectFolder(path) {
14525
14659
  throw err;
14526
14660
  }
14527
14661
  }
14528
- const result = { name, path, status, files };
14662
+ const result = { name, path, status, files, sources };
14529
14663
  return result;
14530
14664
  }
14665
+ async function readModelSources(folderPath, files) {
14666
+ const out = [];
14667
+ for (const filename of files) {
14668
+ if (filename === "index.ts") continue;
14669
+ if (CONTENT_VALIDATION_SKIP_SUFFIXES.some((suffix) => filename.endsWith(suffix))) continue;
14670
+ const text = await readFile4(join3(folderPath, filename), "utf8");
14671
+ out.push({ filename, text });
14672
+ }
14673
+ return out;
14674
+ }
14531
14675
 
14532
14676
  // packages/dbx-components-mcp/src/tools/model-validate-folder/rules.ts
14533
14677
  function runRules3(inspection) {
@@ -14563,8 +14707,26 @@ function runRules3(inspection) {
14563
14707
  }
14564
14708
  checkRequiredFiles(inspection, violations);
14565
14709
  checkStrayFiles(inspection, violations);
14710
+ checkSourceContents(inspection, violations);
14566
14711
  return violations;
14567
14712
  }
14713
+ function checkSourceContents(inspection, violations) {
14714
+ const sources = inspection.sources;
14715
+ if (!sources || sources.length === 0) {
14716
+ return;
14717
+ }
14718
+ const validatorSources = sources.map((s) => ({ name: s.filename, text: s.text }));
14719
+ const result = validateFirebaseModelSources(validatorSources);
14720
+ for (const v of result.violations) {
14721
+ pushViolation3(violations, {
14722
+ code: v.code,
14723
+ severity: v.severity,
14724
+ message: v.message,
14725
+ folder: inspection.path,
14726
+ file: v.file
14727
+ });
14728
+ }
14729
+ }
14568
14730
  function checkRequiredFiles(inspection, violations) {
14569
14731
  const presentFiles = new Set(inspection.files);
14570
14732
  for (const required of buildRequiredFiles(inspection.name)) {
@@ -14625,6 +14787,8 @@ var DBX_MODEL_VALIDATE_FOLDER_TOOL = {
14625
14787
  description: [
14626
14788
  "Validate that one or more model folders follow the canonical layout. Each folder named `<name>/` must contain `<name>.ts`, `<name>.id.ts`, `<name>.query.ts`, `<name>.action.ts`, `<name>.api.ts`, and `index.ts`. Missing files are hard errors.",
14627
14789
  "",
14790
+ "Also runs every `dbx_model_validate` rule against the contents of each model `.ts` file, so untagged models surface here too \u2014 e.g. `MODEL_IDENTITY_NOT_TAGGED` when `firestoreModelIdentity(...)` is declared without a matching `@dbxModel` interface. Sub-files (`<name>.id.ts`, `.query.ts`, `.action.ts`, `.api.ts`, `*.spec.ts`, `index.ts`) are skipped \u2014 they never declare `firestoreModelIdentity` calls.",
14791
+ "",
14628
14792
  "Warnings cover: stray `.ts` files at the folder root that do not start with `<name>.` (they should be grouped under the model prefix), and reserved folder names (`system/`, `notification/`, `storagefile/`) that have dedicated validators and are skipped here.",
14629
14793
  "",
14630
14794
  "Provide at least one of:",
@@ -15611,13 +15775,13 @@ function collectIdentityImports(sourceFile) {
15611
15775
  }
15612
15776
 
15613
15777
  // packages/dbx-components-mcp/src/tools/model-fixture-shared/inspect.ts
15614
- import { readFile as readFile4 } from "node:fs/promises";
15615
- import { join as join3 } from "node:path";
15778
+ import { readFile as readFile5 } from "node:fs/promises";
15779
+ import { join as join4 } from "node:path";
15616
15780
  var FIXTURE_RELATIVE_PATH = "src/test/fixture.ts";
15617
15781
  async function inspectAppFixtures(apiAbs, apiRel) {
15618
- const absolutePath = join3(apiAbs, FIXTURE_RELATIVE_PATH);
15782
+ const absolutePath = join4(apiAbs, FIXTURE_RELATIVE_PATH);
15619
15783
  const relativePath = `${apiRel}/${FIXTURE_RELATIVE_PATH}`;
15620
- const text = await readFile4(absolutePath, "utf8");
15784
+ const text = await readFile5(absolutePath, "utf8");
15621
15785
  return extractAppFixturesFromText({ text, fixturePath: relativePath });
15622
15786
  }
15623
15787
 
@@ -16464,7 +16628,7 @@ var TOOL3 = {
16464
16628
  }
16465
16629
  };
16466
16630
  function createModelFixtureValidateAppTool(config = {}) {
16467
- async function run10(rawArgs) {
16631
+ async function run12(rawArgs) {
16468
16632
  const parsed = ValidateArgsType(rawArgs);
16469
16633
  if (parsed instanceof type34.errors) {
16470
16634
  return toolError(`Invalid arguments: ${parsed.summary}`);
@@ -16491,12 +16655,12 @@ function createModelFixtureValidateAppTool(config = {}) {
16491
16655
  };
16492
16656
  return toolResult;
16493
16657
  }
16494
- return { definition: TOOL3, run: run10 };
16658
+ return { definition: TOOL3, run: run12 };
16495
16659
  }
16496
16660
 
16497
16661
  // packages/dbx-components-mcp/src/tools/model-fixture-scaffold.tool.ts
16498
- import { readFile as readFile5, writeFile } from "node:fs/promises";
16499
- import { join as join4, resolve as resolve20 } from "node:path";
16662
+ import { readFile as readFile6, writeFile } from "node:fs/promises";
16663
+ import { join as join5, resolve as resolve20 } from "node:path";
16500
16664
  import { type as type35 } from "arktype";
16501
16665
  var ScaffoldArgsType3 = type35({
16502
16666
  apiDir: "string",
@@ -16614,10 +16778,10 @@ async function run3(rawArgs) {
16614
16778
  if (conflicts.length > 0) {
16615
16779
  return toolError(["Refusing to scaffold \u2014 the following names already exist in `" + extraction.fixturePath + "`:", "", ...conflicts.map((c) => "- `" + c + "`"), "", "Rename, delete, or pick a different model name and retry."].join("\n"));
16616
16780
  }
16617
- const absolutePath = join4(apiAbs, FIXTURE_RELATIVE_PATH);
16781
+ const absolutePath = join5(apiAbs, FIXTURE_RELATIVE_PATH);
16618
16782
  let original;
16619
16783
  try {
16620
- original = await readFile5(absolutePath, "utf8");
16784
+ original = await readFile6(absolutePath, "utf8");
16621
16785
  } catch (err) {
16622
16786
  return toolError(`Failed to read fixture file: ${err instanceof Error ? err.message : String(err)}`);
16623
16787
  }
@@ -16666,7 +16830,7 @@ function collectConflicts(extraction, rendered) {
16666
16830
  var modelFixtureScaffoldTool = { definition: TOOL4, run: run3 };
16667
16831
 
16668
16832
  // packages/dbx-components-mcp/src/tools/model-fixture-forward.tool.ts
16669
- import { join as join5, resolve as resolve21 } from "node:path";
16833
+ import { join as join6, resolve as resolve21 } from "node:path";
16670
16834
  import { type as type36 } from "arktype";
16671
16835
  import { Project as Project8 } from "ts-morph";
16672
16836
  var ForwardArgsType = type36({
@@ -16680,110 +16844,1007 @@ var TOOL5 = {
16680
16844
  inputSchema: {
16681
16845
  type: "object",
16682
16846
  properties: {
16683
- apiDir: { type: "string", description: "Relative path to the API app." },
16684
- model: { type: "string", description: "Bare model name (e.g. `StorageFile`)." },
16685
- methods: {
16686
- type: "array",
16687
- items: { type: "string" },
16688
- description: "Optional whitelist of instance method names to forward."
16689
- }
16847
+ apiDir: { type: "string", description: "Relative path to the API app." },
16848
+ model: { type: "string", description: "Bare model name (e.g. `StorageFile`)." },
16849
+ methods: {
16850
+ type: "array",
16851
+ items: { type: "string" },
16852
+ description: "Optional whitelist of instance method names to forward."
16853
+ }
16854
+ },
16855
+ required: ["apiDir", "model"]
16856
+ }
16857
+ };
16858
+ async function run4(rawArgs) {
16859
+ const parsed = ForwardArgsType(rawArgs);
16860
+ if (parsed instanceof type36.errors) {
16861
+ return toolError(`Invalid arguments: ${parsed.summary}`);
16862
+ }
16863
+ const cwd = process.cwd();
16864
+ try {
16865
+ ensurePathInsideCwd(parsed.apiDir, cwd);
16866
+ } catch (err) {
16867
+ return toolError(toErrorMessage(err));
16868
+ }
16869
+ const apiAbs = resolve21(cwd, parsed.apiDir);
16870
+ let extraction;
16871
+ try {
16872
+ extraction = await inspectAppFixtures(apiAbs, parsed.apiDir);
16873
+ } catch (err) {
16874
+ return toolError(`Failed to read fixture file: ${toErrorMessage(err)}`);
16875
+ }
16876
+ const entry = extraction.entries.find((e) => e.model === parsed.model);
16877
+ if (!entry) {
16878
+ const known = extraction.entries.map((e) => e.model).join(", ") || "(none)";
16879
+ return toolError(`Model \`${parsed.model}\` not found in \`${extraction.fixturePath}\`. Known: ${known}.`);
16880
+ }
16881
+ const rendered = renderForwarders({ entry, methods: parsed.methods });
16882
+ if (rendered.added.length === 0) {
16883
+ return { content: [{ type: "text", text: renderNoOpReport(extraction.fixturePath, entry.fixtureClassName, rendered) }] };
16884
+ }
16885
+ const absolutePath = join6(apiAbs, FIXTURE_RELATIVE_PATH);
16886
+ const writeError = await applyForwardersToFile(absolutePath, entry.fixtureClassName, rendered);
16887
+ if (writeError) {
16888
+ return toolError(writeError);
16889
+ }
16890
+ return { content: [{ type: "text", text: renderSuccessReport(extraction.fixturePath, entry.fixtureClassName, rendered) }] };
16891
+ }
16892
+ function toErrorMessage(err) {
16893
+ return err instanceof Error ? err.message : String(err);
16894
+ }
16895
+ async function applyForwardersToFile(absolutePath, fixtureClassName, rendered) {
16896
+ const project = new Project8({ skipAddingFilesFromTsConfig: true });
16897
+ let sourceFile;
16898
+ try {
16899
+ sourceFile = project.addSourceFileAtPath(absolutePath);
16900
+ } catch (err) {
16901
+ return `Failed to load fixture file: ${toErrorMessage(err)}`;
16902
+ }
16903
+ const fixtureClass = sourceFile.getClass(fixtureClassName);
16904
+ if (!fixtureClass) {
16905
+ return `Could not locate class \`${fixtureClassName}\` for in-place edit. The fixture file may have been modified since parsing.`;
16906
+ }
16907
+ for (const forwarder of rendered.added) {
16908
+ fixtureClass.insertText(fixtureClass.getEnd() - 1, "\n" + forwarder.source + "\n");
16909
+ }
16910
+ sourceFile.formatText({ ensureNewLineAtEndOfFile: true });
16911
+ try {
16912
+ await sourceFile.save();
16913
+ } catch (err) {
16914
+ return `Failed to write fixture file: ${toErrorMessage(err)}`;
16915
+ }
16916
+ return void 0;
16917
+ }
16918
+ function renderNoOpReport(fixturePath, fixtureClassName, rendered) {
16919
+ const lines = [`# No forwarders to add for \`${fixtureClassName}\``, "", `File: \`${fixturePath}\``];
16920
+ appendListSection(lines, "## Already forwarded", rendered.skippedAlreadyForwarded);
16921
+ appendListSection(lines, "## Whitelisted methods missing from Instance", rendered.missingFromInstance);
16922
+ return lines.join("\n");
16923
+ }
16924
+ function renderSuccessReport(fixturePath, fixtureClassName, rendered) {
16925
+ const lines = [`# Forwarded ${rendered.added.length} method${rendered.added.length === 1 ? "" : "s"} to \`${fixtureClassName}\``, "", `File: \`${fixturePath}\``, "", "## Added"];
16926
+ for (const f of rendered.added) {
16927
+ lines.push(`- \`${f.method}\``);
16928
+ }
16929
+ appendListSection(lines, "## Skipped (already forwarded)", rendered.skippedAlreadyForwarded);
16930
+ appendListSection(lines, "## Whitelisted methods missing from Instance", rendered.missingFromInstance);
16931
+ return lines.join("\n");
16932
+ }
16933
+ function appendListSection(lines, heading, names) {
16934
+ if (names.length === 0) return;
16935
+ lines.push("", heading);
16936
+ for (const name of names) {
16937
+ lines.push(`- \`${name}\``);
16938
+ }
16939
+ }
16940
+ var modelFixtureForwardTool = { definition: TOOL5, run: run4 };
16941
+
16942
+ // packages/dbx-components-mcp/src/tools/model-test-tree.tool.ts
16943
+ import { resolve as resolve22 } from "node:path";
16944
+ import { type as type37 } from "arktype";
16945
+
16946
+ // packages/dbx-components-mcp/src/tools/model-test-shared/extract.ts
16947
+ import { Node as Node12, Project as Project9, SyntaxKind as SyntaxKind7 } from "ts-morph";
16948
+ var SPEC_FILE_VIRTUAL_PATH = "__spec__/spec.ts";
16949
+ var FIXTURE_CONTEXT_SUFFIX = "Context";
16950
+ var FIXTURE_FACTORY_SUFFIX = "ContextFactory";
16951
+ var HOOK_NAMES = /* @__PURE__ */ new Set(["beforeEach", "beforeAll", "afterEach", "afterAll"]);
16952
+ var DESCRIBE_NAMES = /* @__PURE__ */ new Set(["describe", "xdescribe", "fdescribe"]);
16953
+ var IT_NAMES = /* @__PURE__ */ new Set(["it", "xit", "fit", "test"]);
16954
+ function extractSpecTreeFromText(input) {
16955
+ const { text, specPath } = input;
16956
+ const project = new Project9({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
16957
+ const sourceFile = project.createSourceFile(SPEC_FILE_VIRTUAL_PATH, text, { overwrite: true });
16958
+ const { prefix, prefixSource, knownFixtureNames } = resolvePrefixAndFixtures(sourceFile, input);
16959
+ const helpers = collectHelpers(sourceFile);
16960
+ const helperNames = new Set(helpers.map((h) => h.name));
16961
+ const counts = { describe: 0, it: 0, fixture: 0 };
16962
+ const rootChildren = [];
16963
+ for (const stmt of sourceFile.getStatements()) {
16964
+ if (!Node12.isExpressionStatement(stmt)) continue;
16965
+ const expr = stmt.getExpression();
16966
+ if (!Node12.isCallExpression(expr)) continue;
16967
+ const node = walkCall(expr, { prefix, knownFixtureNames, helperNames, counts });
16968
+ if (node !== void 0) {
16969
+ rootChildren.push(node);
16970
+ }
16971
+ }
16972
+ const lastLine = sourceFile.getEndLineNumber();
16973
+ const root = {
16974
+ kind: "wrapper",
16975
+ callee: specPath,
16976
+ line: 1,
16977
+ endLine: lastLine,
16978
+ children: rootChildren
16979
+ };
16980
+ const result = {
16981
+ specPath,
16982
+ prefix,
16983
+ prefixSource,
16984
+ knownFixtureNames,
16985
+ root,
16986
+ helpers,
16987
+ fixtureCallsCount: counts.fixture,
16988
+ itCount: counts.it,
16989
+ describeCount: counts.describe
16990
+ };
16991
+ return result;
16992
+ }
16993
+ function resolvePrefixAndFixtures(sourceFile, input) {
16994
+ const supplied = input.knownFixtureNames ?? [];
16995
+ if (input.prefix !== void 0 && input.prefix !== "" && supplied.length > 0) {
16996
+ const result2 = {
16997
+ prefix: input.prefix,
16998
+ prefixSource: "apiDir",
16999
+ knownFixtureNames: dedupedSorted(supplied)
17000
+ };
17001
+ return result2;
17002
+ }
17003
+ const imported = collectFixtureImports(sourceFile);
17004
+ if (imported.length > 0) {
17005
+ const detectedPrefix = detectPrefixFromImports(imported);
17006
+ const result2 = {
17007
+ prefix: detectedPrefix,
17008
+ prefixSource: "imports",
17009
+ knownFixtureNames: dedupedSorted(imported)
17010
+ };
17011
+ return result2;
17012
+ }
17013
+ const result = { prefix: void 0, prefixSource: "unknown", knownFixtureNames: [] };
17014
+ return result;
17015
+ }
17016
+ function collectFixtureImports(sourceFile) {
17017
+ const seen = /* @__PURE__ */ new Set();
17018
+ for (const decl of sourceFile.getImportDeclarations()) {
17019
+ const spec = decl.getModuleSpecifierValue();
17020
+ if (!matchesFixtureModulePath(spec)) continue;
17021
+ for (const named of decl.getNamedImports()) {
17022
+ const name = named.getName();
17023
+ if (!name.endsWith(FIXTURE_CONTEXT_SUFFIX)) continue;
17024
+ if (name.endsWith(FIXTURE_FACTORY_SUFFIX)) continue;
17025
+ if (!/^[a-z]/.test(name)) continue;
17026
+ seen.add(name);
17027
+ }
17028
+ }
17029
+ return [...seen];
17030
+ }
17031
+ function matchesFixtureModulePath(spec) {
17032
+ return /(^|\/)test\/fixture(\.[a-z]+)?$/.test(spec);
17033
+ }
17034
+ function detectPrefixFromImports(names) {
17035
+ if (names.length === 0) return void 0;
17036
+ const stems = names.map((n) => n.slice(0, n.length - FIXTURE_CONTEXT_SUFFIX.length));
17037
+ let common = stems[0];
17038
+ for (let i = 1; i < stems.length; i++) {
17039
+ common = sharedPrefix(common, stems[i]);
17040
+ if (common.length === 0) return void 0;
17041
+ }
17042
+ const camelEnd = trimToCamelBoundary(common);
17043
+ if (camelEnd.length === 0) return void 0;
17044
+ return camelEnd.charAt(0).toUpperCase() + camelEnd.slice(1);
17045
+ }
17046
+ function sharedPrefix(a, b) {
17047
+ const max = Math.min(a.length, b.length);
17048
+ let i = 0;
17049
+ while (i < max && a.charAt(i) === b.charAt(i)) i++;
17050
+ return a.slice(0, i);
17051
+ }
17052
+ function trimToCamelBoundary(s) {
17053
+ for (let i = s.length - 1; i >= 0; i--) {
17054
+ if (/[A-Z]/.test(s.charAt(i))) {
17055
+ return s.slice(0, i);
17056
+ }
17057
+ }
17058
+ return s;
17059
+ }
17060
+ function dedupedSorted(names) {
17061
+ return [...new Set(names)].sort();
17062
+ }
17063
+ function walkCall(call, ctx) {
17064
+ const calleeName = getCalleeName(call);
17065
+ if (calleeName === void 0) return void 0;
17066
+ const line = call.getStartLineNumber();
17067
+ const endLine = call.getEndLineNumber();
17068
+ if (DESCRIBE_NAMES.has(calleeName)) {
17069
+ ctx.counts.describe += 1;
17070
+ return describeOrItNode("describe", call, calleeName, line, endLine, ctx);
17071
+ }
17072
+ if (IT_NAMES.has(calleeName)) {
17073
+ ctx.counts.it += 1;
17074
+ return describeOrItNode("it", call, calleeName, line, endLine, ctx);
17075
+ }
17076
+ if (HOOK_NAMES.has(calleeName)) {
17077
+ return hookNode(call, calleeName, line, endLine);
17078
+ }
17079
+ if (isKnownFixtureName(calleeName, ctx)) {
17080
+ ctx.counts.fixture += 1;
17081
+ return fixtureNode(call, calleeName, ctx, line, endLine);
17082
+ }
17083
+ if (ctx.helperNames.has(calleeName)) {
17084
+ return helperCallNode(call, calleeName, ctx, line, endLine);
17085
+ }
17086
+ const callback = findCallback(call);
17087
+ if (callback === void 0) return void 0;
17088
+ const wrapperChildren = walkCallbackBody(callback, ctx);
17089
+ const wrapper = { kind: "wrapper", callee: calleeName, line, endLine, children: wrapperChildren };
17090
+ return wrapper;
17091
+ }
17092
+ function isKnownFixtureName(name, ctx) {
17093
+ if (ctx.knownFixtureNames.length > 0) {
17094
+ return ctx.knownFixtureNames.includes(name);
17095
+ }
17096
+ if (!name.endsWith(FIXTURE_CONTEXT_SUFFIX)) return false;
17097
+ if (name.endsWith(FIXTURE_FACTORY_SUFFIX)) return false;
17098
+ if (!/^[a-z]/.test(name)) return false;
17099
+ if (ctx.prefix !== void 0) {
17100
+ const lowerPrefix = ctx.prefix.charAt(0).toLowerCase() + ctx.prefix.slice(1);
17101
+ if (!name.startsWith(lowerPrefix)) return false;
17102
+ }
17103
+ return true;
17104
+ }
17105
+ function describeOrItNode(kind, call, calleeName, line, endLine, ctx) {
17106
+ const args = call.getArguments();
17107
+ const titleArg = args[0];
17108
+ const titleInfo = readTitle(titleArg);
17109
+ const callback = findCallback(call);
17110
+ const children = kind === "describe" && callback !== void 0 ? walkCallbackBody(callback, ctx) : [];
17111
+ const node = {
17112
+ kind,
17113
+ title: titleInfo.title,
17114
+ titleIsTemplate: titleInfo.titleIsTemplate || void 0,
17115
+ callee: calleeName === kind ? void 0 : calleeName,
17116
+ line,
17117
+ endLine,
17118
+ children
17119
+ };
17120
+ return node;
17121
+ }
17122
+ function hookNode(_call, calleeName, line, endLine) {
17123
+ const node = { kind: "hook", title: calleeName, line, endLine, children: [] };
17124
+ return node;
17125
+ }
17126
+ function fixtureNode(call, calleeName, ctx, line, endLine) {
17127
+ const args = call.getArguments();
17128
+ const argsObject = args[0];
17129
+ const parentVars = Node12.isObjectLiteralExpression(argsObject) ? readParentVars(argsObject) : [];
17130
+ const callback = findCallback(call);
17131
+ const varName = callback !== void 0 ? readCallbackVarName(callback) : void 0;
17132
+ const model = stripFixturePrefix(calleeName, ctx.prefix);
17133
+ const children = callback !== void 0 ? walkCallbackBody(callback, ctx) : [];
17134
+ const node = {
17135
+ kind: "fixture",
17136
+ callee: calleeName,
17137
+ model,
17138
+ varName,
17139
+ parentVars: parentVars.length > 0 ? parentVars : void 0,
17140
+ line,
17141
+ endLine,
17142
+ children
17143
+ };
17144
+ return node;
17145
+ }
17146
+ function helperCallNode(call, calleeName, ctx, line, endLine) {
17147
+ const callback = findCallback(call);
17148
+ const children = callback !== void 0 ? walkCallbackBody(callback, ctx) : [];
17149
+ const node = { kind: "helperCall", callee: calleeName, line, endLine, children };
17150
+ return node;
17151
+ }
17152
+ function stripFixturePrefix(name, prefix) {
17153
+ if (!name.endsWith(FIXTURE_CONTEXT_SUFFIX)) return void 0;
17154
+ const stem = name.slice(0, name.length - FIXTURE_CONTEXT_SUFFIX.length);
17155
+ if (prefix === void 0 || prefix === "") {
17156
+ if (stem.length === 0) return void 0;
17157
+ return stem.charAt(0).toUpperCase() + stem.slice(1);
17158
+ }
17159
+ const lower = prefix.charAt(0).toLowerCase() + prefix.slice(1);
17160
+ if (!stem.startsWith(lower)) return void 0;
17161
+ const model = stem.slice(lower.length);
17162
+ return model.length > 0 ? model : void 0;
17163
+ }
17164
+ function readTitle(arg) {
17165
+ if (arg === void 0) return { title: void 0, titleIsTemplate: false };
17166
+ if (Node12.isStringLiteral(arg) || Node12.isNoSubstitutionTemplateLiteral(arg)) {
17167
+ const result2 = { title: arg.getLiteralText(), titleIsTemplate: false };
17168
+ return result2;
17169
+ }
17170
+ if (Node12.isTemplateExpression(arg)) {
17171
+ const result2 = { title: arg.getText(), titleIsTemplate: true };
17172
+ return result2;
17173
+ }
17174
+ const result = { title: arg.getText(), titleIsTemplate: true };
17175
+ return result;
17176
+ }
17177
+ function findCallback(call) {
17178
+ const args = call.getArguments();
17179
+ for (let i = args.length - 1; i >= 0; i--) {
17180
+ const a = args[i];
17181
+ if (Node12.isArrowFunction(a) || Node12.isFunctionExpression(a)) {
17182
+ return a;
17183
+ }
17184
+ }
17185
+ return void 0;
17186
+ }
17187
+ function readCallbackVarName(callback) {
17188
+ const params = callback.getParameters();
17189
+ if (params.length === 0) return void 0;
17190
+ const first = params[0];
17191
+ const nameNode = first.getNameNode();
17192
+ if (Node12.isIdentifier(nameNode)) {
17193
+ return nameNode.getText();
17194
+ }
17195
+ return void 0;
17196
+ }
17197
+ function readParentVars(obj) {
17198
+ const out = [];
17199
+ for (const prop of obj.getProperties()) {
17200
+ if (Node12.isShorthandPropertyAssignment(prop)) {
17201
+ out.push(prop.getName());
17202
+ continue;
17203
+ }
17204
+ if (Node12.isPropertyAssignment(prop)) {
17205
+ const init = prop.getInitializer();
17206
+ if (init !== void 0 && Node12.isIdentifier(init)) {
17207
+ out.push(init.getText());
17208
+ }
17209
+ }
17210
+ }
17211
+ return out;
17212
+ }
17213
+ function walkCallbackBody(callback, ctx) {
17214
+ const body = callback.getBody();
17215
+ if (Node12.isBlock(body)) {
17216
+ return walkBlock(body, ctx);
17217
+ }
17218
+ if (Node12.isCallExpression(body)) {
17219
+ const child = walkCall(body, ctx);
17220
+ return child === void 0 ? [] : [child];
17221
+ }
17222
+ return [];
17223
+ }
17224
+ function walkBlock(block, ctx) {
17225
+ const children = [];
17226
+ for (const stmt of block.getStatements()) {
17227
+ if (!Node12.isExpressionStatement(stmt)) continue;
17228
+ const expr = stmt.getExpression();
17229
+ if (!Node12.isCallExpression(expr)) continue;
17230
+ const child = walkCall(expr, ctx);
17231
+ if (child !== void 0) {
17232
+ children.push(child);
17233
+ }
17234
+ }
17235
+ return children;
17236
+ }
17237
+ function getCalleeName(call) {
17238
+ const expr = call.getExpression();
17239
+ if (Node12.isIdentifier(expr)) return expr.getText();
17240
+ return void 0;
17241
+ }
17242
+ function collectHelpers(sourceFile) {
17243
+ const out = [];
17244
+ for (const fn of sourceFile.getFunctions()) {
17245
+ const name = fn.getName();
17246
+ if (name === void 0) continue;
17247
+ const usage = scanForDescribeOrIt(fn);
17248
+ if (!usage.emitsDescribe && !usage.emitsIt) continue;
17249
+ out.push({ name, line: fn.getStartLineNumber(), endLine: fn.getEndLineNumber(), emitsDescribe: usage.emitsDescribe, emitsIt: usage.emitsIt });
17250
+ }
17251
+ for (const v of sourceFile.getVariableStatements()) {
17252
+ for (const decl of v.getDeclarations()) {
17253
+ const init = decl.getInitializer();
17254
+ if (init === void 0) continue;
17255
+ if (!Node12.isArrowFunction(init) && !Node12.isFunctionExpression(init)) continue;
17256
+ const usage = scanForDescribeOrIt(init);
17257
+ if (!usage.emitsDescribe && !usage.emitsIt) continue;
17258
+ out.push({ name: decl.getName(), line: decl.getStartLineNumber(), endLine: decl.getEndLineNumber(), emitsDescribe: usage.emitsDescribe, emitsIt: usage.emitsIt });
17259
+ }
17260
+ }
17261
+ return out;
17262
+ }
17263
+ function scanForDescribeOrIt(node) {
17264
+ const usage = { emitsDescribe: false, emitsIt: false };
17265
+ node.forEachDescendant((descendant) => {
17266
+ if (descendant.getKind() !== SyntaxKind7.CallExpression) return;
17267
+ const call = descendant;
17268
+ const expr = call.getExpression();
17269
+ if (!Node12.isIdentifier(expr)) return;
17270
+ const name = expr.getText();
17271
+ if (DESCRIBE_NAMES.has(name)) usage.emitsDescribe = true;
17272
+ if (IT_NAMES.has(name)) usage.emitsIt = true;
17273
+ });
17274
+ return usage;
17275
+ }
17276
+
17277
+ // packages/dbx-components-mcp/src/tools/model-test-shared/inspect.ts
17278
+ import { readFile as readFile7 } from "node:fs/promises";
17279
+ async function inspectSpecFile(config) {
17280
+ const { specAbs, specRel, apiAbs, apiRel } = config;
17281
+ const text = await readFile7(specAbs, "utf8");
17282
+ let prefix;
17283
+ let knownFixtureNames;
17284
+ if (apiAbs !== void 0 && apiRel !== void 0) {
17285
+ try {
17286
+ const fixtures = await inspectAppFixtures(apiAbs, apiRel);
17287
+ prefix = fixtures.prefix;
17288
+ const lowerPrefix = prefix !== void 0 ? prefix.charAt(0).toLowerCase() + prefix.slice(1) : "";
17289
+ knownFixtureNames = fixtures.entries.map((entry) => `${lowerPrefix}${entry.model}Context`);
17290
+ } catch {
17291
+ }
17292
+ }
17293
+ return extractSpecTreeFromText({ text, specPath: specRel, prefix, knownFixtureNames });
17294
+ }
17295
+
17296
+ // packages/dbx-components-mcp/src/tools/model-test-shared/search.ts
17297
+ function searchSpecTree(tree, query) {
17298
+ const hits = [];
17299
+ const describeStack = [];
17300
+ const fixtureStack = [];
17301
+ const visit = (node) => {
17302
+ matchNode(node, query, describeStack, fixtureStack, hits);
17303
+ let pushedDescribe = false;
17304
+ let pushedFixture = false;
17305
+ if (node.kind === "describe" && node.title !== void 0) {
17306
+ describeStack.push(node.title);
17307
+ pushedDescribe = true;
17308
+ }
17309
+ if (node.kind === "fixture" && node.model !== void 0) {
17310
+ fixtureStack.push(node.model);
17311
+ pushedFixture = true;
17312
+ }
17313
+ for (const child of node.children) {
17314
+ visit(child);
17315
+ }
17316
+ if (pushedDescribe) describeStack.pop();
17317
+ if (pushedFixture) fixtureStack.pop();
17318
+ };
17319
+ for (const child of tree.root.children) {
17320
+ visit(child);
17321
+ }
17322
+ const result = { query, hits };
17323
+ return result;
17324
+ }
17325
+ function matchNode(node, query, describeStack, fixtureStack, hits) {
17326
+ let matched = false;
17327
+ switch (query.mode) {
17328
+ case "model":
17329
+ matched = node.kind === "fixture" && node.model?.toLowerCase() === query.value.toLowerCase();
17330
+ break;
17331
+ case "chain":
17332
+ matched = node.kind === "fixture" && chainContainsSequence([...fixtureStack, node.model ?? ""], parseChainQuery(query.value));
17333
+ break;
17334
+ case "describe":
17335
+ matched = node.kind === "describe" && node.title !== void 0 && node.title.toLowerCase().includes(query.value.toLowerCase());
17336
+ break;
17337
+ case "it":
17338
+ matched = node.kind === "it" && node.title !== void 0 && node.title.toLowerCase().includes(query.value.toLowerCase());
17339
+ break;
17340
+ default: {
17341
+ const exhaustive = query;
17342
+ void exhaustive;
17343
+ }
17344
+ }
17345
+ if (!matched) return;
17346
+ const hit = {
17347
+ kind: node.kind,
17348
+ title: node.title,
17349
+ model: node.model,
17350
+ callee: node.callee,
17351
+ line: node.line,
17352
+ endLine: node.endLine,
17353
+ describePath: [...describeStack],
17354
+ fixtureChain: [...fixtureStack]
17355
+ };
17356
+ hits.push(hit);
17357
+ }
17358
+ function parseChainQuery(value) {
17359
+ return value.split(">").map((s) => s.trim()).filter((s) => s.length > 0).map((s) => s.toLowerCase());
17360
+ }
17361
+ function chainContainsSequence(chain, sequence) {
17362
+ if (sequence.length === 0) return true;
17363
+ if (sequence.length > chain.length) return false;
17364
+ const lowerChain = chain.map((s) => s.toLowerCase());
17365
+ outer: for (let i = 0; i <= lowerChain.length - sequence.length; i++) {
17366
+ for (const [j, element] of sequence.entries()) {
17367
+ if (lowerChain[i + j] !== element) continue outer;
17368
+ }
17369
+ return true;
17370
+ }
17371
+ return false;
17372
+ }
17373
+
17374
+ // packages/dbx-components-mcp/src/tools/model-test-shared/format.json.ts
17375
+ function formatTreeAsJson(tree, view = "all", filters = {}) {
17376
+ if (view === "helpers") {
17377
+ const result2 = { specPath: tree.specPath, prefix: tree.prefix, prefixSource: tree.prefixSource, helpers: tree.helpers };
17378
+ return JSON.stringify(result2, null, 2);
17379
+ }
17380
+ if (view === "its") {
17381
+ const its = collectIts(tree);
17382
+ const result2 = { specPath: tree.specPath, prefix: tree.prefix, prefixSource: tree.prefixSource, its };
17383
+ return JSON.stringify(result2, null, 2);
17384
+ }
17385
+ const filteredRoot = applyFilters(tree.root, view, filters);
17386
+ const result = { specPath: tree.specPath, prefix: tree.prefix, prefixSource: tree.prefixSource, knownFixtureNames: tree.knownFixtureNames, view, filters, counts: { describes: tree.describeCount, its: tree.itCount, fixtures: tree.fixtureCallsCount, helpers: tree.helpers.length }, root: filteredRoot };
17387
+ return JSON.stringify(result, null, 2);
17388
+ }
17389
+ function formatSearchAsJson(tree, result) {
17390
+ const payload = { specPath: tree.specPath, prefix: tree.prefix, prefixSource: tree.prefixSource, query: result.query, hits: result.hits };
17391
+ return JSON.stringify(payload, null, 2);
17392
+ }
17393
+ function collectIts(tree) {
17394
+ const out = [];
17395
+ const stack = [];
17396
+ const visit = (node) => {
17397
+ if (node.kind === "it") {
17398
+ const entry = { describePath: [...stack], title: node.title, titleIsTemplate: node.titleIsTemplate, line: node.line, endLine: node.endLine };
17399
+ out.push(entry);
17400
+ }
17401
+ let pushed = false;
17402
+ if (node.kind === "describe" && node.title !== void 0) {
17403
+ stack.push(node.title);
17404
+ pushed = true;
17405
+ }
17406
+ for (const child of node.children) visit(child);
17407
+ if (pushed) stack.pop();
17408
+ };
17409
+ for (const c of tree.root.children) visit(c);
17410
+ return out;
17411
+ }
17412
+ function applyFilters(root, view, filters) {
17413
+ let next = view === "describes" ? collapseTo(root, ["describe", "it", "hook", "helperCall"]) : view === "fixtures" ? collapseTo(root, ["fixture"]) : root;
17414
+ if (filters.filterByModel !== void 0 && filters.filterByModel !== "") {
17415
+ next = pruneByModel(next, filters.filterByModel.toLowerCase()) ?? { ...next, children: [] };
17416
+ }
17417
+ if (filters.filterByDescribePath !== void 0 && filters.filterByDescribePath !== "") {
17418
+ next = pruneByDescribePath(next, parseDescribePath(filters.filterByDescribePath)) ?? { ...next, children: [] };
17419
+ }
17420
+ return next;
17421
+ }
17422
+ function collapseTo(node, keep) {
17423
+ const collapsedChildren = [];
17424
+ for (const child of node.children) {
17425
+ const transformed = collapseTo(child, keep);
17426
+ if (keep.includes(child.kind)) {
17427
+ collapsedChildren.push(transformed);
17428
+ } else {
17429
+ collapsedChildren.push(...transformed.children);
17430
+ }
17431
+ }
17432
+ return { ...node, children: collapsedChildren };
17433
+ }
17434
+ function pruneByModel(node, model) {
17435
+ const matchedSelf = node.kind === "fixture" && node.model?.toLowerCase() === model;
17436
+ const prunedChildren = [];
17437
+ for (const child of node.children) {
17438
+ const result = pruneByModel(child, model);
17439
+ if (result !== void 0) prunedChildren.push(result);
17440
+ }
17441
+ if (matchedSelf || prunedChildren.length > 0) {
17442
+ return { ...node, children: prunedChildren };
17443
+ }
17444
+ return void 0;
17445
+ }
17446
+ function pruneByDescribePath(node, path) {
17447
+ if (path.length === 0) return node;
17448
+ const matched = [];
17449
+ collectDescribesMatching(node, path, [], matched);
17450
+ if (matched.length === 0) return void 0;
17451
+ return { ...node, children: matched };
17452
+ }
17453
+ function collectDescribesMatching(node, target, stack, out) {
17454
+ if (node.kind === "describe" && node.title !== void 0) {
17455
+ stack.push(node.title.toLowerCase());
17456
+ if (pathStartsWith(stack, target)) {
17457
+ out.push(node);
17458
+ stack.pop();
17459
+ return;
17460
+ }
17461
+ }
17462
+ for (const child of node.children) collectDescribesMatching(child, target, stack, out);
17463
+ if (node.kind === "describe" && node.title !== void 0) stack.pop();
17464
+ }
17465
+ function pathStartsWith(actual, expected) {
17466
+ if (expected.length > actual.length) return false;
17467
+ for (const [i, element] of expected.entries()) {
17468
+ if (!actual[i].includes(element)) return false;
17469
+ }
17470
+ return true;
17471
+ }
17472
+ function parseDescribePath(value) {
17473
+ return value.split(">").map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0);
17474
+ }
17475
+
17476
+ // packages/dbx-components-mcp/src/tools/model-test-shared/format.markdown.ts
17477
+ var INDENT = " ";
17478
+ function formatTreeAsMarkdown(tree, view = "all", filters = {}) {
17479
+ const lines = [];
17480
+ appendHeader(lines, tree, view, filters);
17481
+ if (view === "helpers") {
17482
+ appendHelpersSection(lines, tree.helpers);
17483
+ return lines.join("\n");
17484
+ }
17485
+ if (view === "its") {
17486
+ appendItIndex(lines, tree);
17487
+ return lines.join("\n");
17488
+ }
17489
+ const filteredRoot = applyFilters2(tree.root, view, filters);
17490
+ if (filteredRoot.children.length === 0) {
17491
+ lines.push("", "_No matching nodes._");
17492
+ return lines.join("\n");
17493
+ }
17494
+ lines.push("", `## Tree (view: ${view})`);
17495
+ if (filters.filterByModel) lines.push(`Filter \u2014 model: \`${filters.filterByModel}\``);
17496
+ if (filters.filterByDescribePath) lines.push(`Filter \u2014 describePath: \`${filters.filterByDescribePath}\``);
17497
+ lines.push("");
17498
+ for (const child of filteredRoot.children) {
17499
+ appendNode(lines, child, 0);
17500
+ }
17501
+ return lines.join("\n");
17502
+ }
17503
+ function formatSearchAsMarkdown(tree, result) {
17504
+ const lines = [];
17505
+ lines.push(`# Spec search \u2014 ${tree.specPath}`);
17506
+ lines.push("");
17507
+ lines.push(`Query: \`${result.query.mode}\` = \`${result.query.value}\``);
17508
+ lines.push(`Matches: ${result.hits.length}`);
17509
+ if (result.hits.length === 0) {
17510
+ lines.push("", "_No matches._");
17511
+ return lines.join("\n");
17512
+ }
17513
+ lines.push("");
17514
+ for (const hit of result.hits) {
17515
+ appendHit(lines, hit);
17516
+ }
17517
+ return lines.join("\n");
17518
+ }
17519
+ function appendHeader(lines, tree, view, filters) {
17520
+ lines.push(`# Spec tree \u2014 ${tree.specPath}`);
17521
+ lines.push("");
17522
+ lines.push(`Detected workspace prefix: \`${tree.prefix ?? "(none)"}\` (source: ${tree.prefixSource})`);
17523
+ lines.push(`Counts: ${tree.describeCount} describes, ${tree.itCount} its, ${tree.fixtureCallsCount} fixture calls, ${tree.helpers.length} helper-describes`);
17524
+ if (view !== "helpers" && view !== "its" && (filters.filterByModel || filters.filterByDescribePath)) {
17525
+ lines.push(`Active filters: ${[filters.filterByModel ? `model=\`${filters.filterByModel}\`` : "", filters.filterByDescribePath ? `describePath=\`${filters.filterByDescribePath}\`` : ""].filter(Boolean).join(", ")}`);
17526
+ }
17527
+ }
17528
+ function appendHelpersSection(lines, helpers) {
17529
+ lines.push("", `## Helpers (${helpers.length})`);
17530
+ if (helpers.length === 0) {
17531
+ lines.push("", "_No helper-describes detected._");
17532
+ return;
17533
+ }
17534
+ lines.push("");
17535
+ lines.push("| Name | Emits | Lines |");
17536
+ lines.push("|---|---|---|");
17537
+ for (const h of helpers) {
17538
+ const emits = [];
17539
+ if (h.emitsDescribe) emits.push("describe");
17540
+ if (h.emitsIt) emits.push("it");
17541
+ lines.push(`| \`${h.name}\` | ${emits.join(", ")} | ${h.line}\u2013${h.endLine} |`);
17542
+ }
17543
+ }
17544
+ function appendItIndex(lines, tree) {
17545
+ const its = [];
17546
+ const stack = [];
17547
+ const collect = (node) => {
17548
+ if (node.kind === "it") {
17549
+ its.push({ describePath: [...stack], node });
17550
+ }
17551
+ let pushed = false;
17552
+ if (node.kind === "describe" && node.title !== void 0) {
17553
+ stack.push(node.title);
17554
+ pushed = true;
17555
+ }
17556
+ for (const child of node.children) collect(child);
17557
+ if (pushed) stack.pop();
17558
+ };
17559
+ for (const c of tree.root.children) collect(c);
17560
+ lines.push("", `## Tests (${its.length})`);
17561
+ if (its.length === 0) {
17562
+ lines.push("", "_No `it` calls detected._");
17563
+ return;
17564
+ }
17565
+ lines.push("");
17566
+ for (const { describePath, node } of its) {
17567
+ const path = describePath.length > 0 ? `${describePath.join(" > ")} > ` : "";
17568
+ const title = node.title !== void 0 ? node.titleIsTemplate ? `\`${node.title}\` _(template)_` : `\`${node.title}\`` : "_(no title)_";
17569
+ lines.push(`- ${path}${title} [L${node.line}]`);
17570
+ }
17571
+ }
17572
+ function appendHit(lines, hit) {
17573
+ const label = hitLabel(hit);
17574
+ lines.push(`- ${label} [L${hit.line}\u2013${hit.endLine}]`);
17575
+ if (hit.describePath.length > 0) {
17576
+ lines.push(`${INDENT}describes: ${hit.describePath.map((s) => `\`${s}\``).join(" > ")}`);
17577
+ }
17578
+ if (hit.fixtureChain.length > 0) {
17579
+ lines.push(`${INDENT}fixtures: ${hit.fixtureChain.map((s) => `\`${s}\``).join(" > ")}`);
17580
+ }
17581
+ }
17582
+ function hitLabel(hit) {
17583
+ switch (hit.kind) {
17584
+ case "fixture":
17585
+ return `**fixture** \`${hit.callee ?? "?"}\` \u2192 \`${hit.model ?? "?"}\``;
17586
+ case "describe":
17587
+ return `**describe** \`${hit.title ?? "?"}\``;
17588
+ case "it":
17589
+ return `**it** \`${hit.title ?? "?"}\``;
17590
+ case "helperCall":
17591
+ return `**helperCall** \`${hit.callee ?? "?"}\``;
17592
+ case "wrapper":
17593
+ return `**wrapper** \`${hit.callee ?? "?"}\``;
17594
+ case "hook":
17595
+ return `**${hit.title ?? "hook"}**`;
17596
+ default:
17597
+ return "**?**";
17598
+ }
17599
+ }
17600
+ function appendNode(lines, node, depth) {
17601
+ const indent = INDENT.repeat(depth);
17602
+ lines.push(`${indent}- ${nodeLabel(node)} [L${node.line}\u2013${node.endLine}]`);
17603
+ for (const child of node.children) {
17604
+ appendNode(lines, child, depth + 1);
17605
+ }
17606
+ }
17607
+ function nodeLabel(node) {
17608
+ switch (node.kind) {
17609
+ case "describe":
17610
+ return `**describe** ${node.title === void 0 ? "_(no title)_" : node.titleIsTemplate ? `\`${node.title}\` _(template)_` : `\`${node.title}\``}`;
17611
+ case "it":
17612
+ return `**it** ${node.title === void 0 ? "_(no title)_" : node.titleIsTemplate ? `\`${node.title}\` _(template)_` : `\`${node.title}\``}`;
17613
+ case "hook":
17614
+ return `**${node.title ?? "hook"}**`;
17615
+ case "fixture": {
17616
+ const var_ = node.varName !== void 0 ? ` _(as \`${node.varName}\`)_` : "";
17617
+ const parents = node.parentVars && node.parentVars.length > 0 ? ` deps: \`${node.parentVars.join(", ")}\`` : "";
17618
+ return `**fixture** \`${node.callee ?? "?"}\` \u2192 \`${node.model ?? "?"}\`${var_}${parents}`;
17619
+ }
17620
+ case "wrapper":
17621
+ return `**wrapper** \`${node.callee ?? "?"}\``;
17622
+ case "helperCall":
17623
+ return `**helperCall** \`${node.callee ?? "?"}\``;
17624
+ default:
17625
+ return "**?**";
17626
+ }
17627
+ }
17628
+ function applyFilters2(root, view, filters) {
17629
+ let next = view === "describes" ? collapseTo2(root, ["describe", "it", "hook", "helperCall"]) : view === "fixtures" ? collapseTo2(root, ["fixture"]) : root;
17630
+ if (filters.filterByModel !== void 0 && filters.filterByModel !== "") {
17631
+ next = pruneByModel2(next, filters.filterByModel.toLowerCase()) ?? { ...next, children: [] };
17632
+ }
17633
+ if (filters.filterByDescribePath !== void 0 && filters.filterByDescribePath !== "") {
17634
+ next = pruneByDescribePath2(next, parseDescribePath2(filters.filterByDescribePath)) ?? { ...next, children: [] };
17635
+ }
17636
+ return next;
17637
+ }
17638
+ function collapseTo2(node, keep) {
17639
+ const collapsedChildren = [];
17640
+ for (const child of node.children) {
17641
+ const transformed = collapseTo2(child, keep);
17642
+ if (keep.includes(child.kind)) {
17643
+ collapsedChildren.push(transformed);
17644
+ } else {
17645
+ collapsedChildren.push(...transformed.children);
17646
+ }
17647
+ }
17648
+ return { ...node, children: collapsedChildren };
17649
+ }
17650
+ function pruneByModel2(node, model) {
17651
+ const matchedSelf = node.kind === "fixture" && node.model?.toLowerCase() === model;
17652
+ const prunedChildren = [];
17653
+ for (const child of node.children) {
17654
+ const result = pruneByModel2(child, model);
17655
+ if (result !== void 0) prunedChildren.push(result);
17656
+ }
17657
+ if (matchedSelf || prunedChildren.length > 0) {
17658
+ return { ...node, children: prunedChildren };
17659
+ }
17660
+ return void 0;
17661
+ }
17662
+ function pruneByDescribePath2(node, path) {
17663
+ if (path.length === 0) return node;
17664
+ const matched = [];
17665
+ collectDescribesMatching2(node, path, [], matched);
17666
+ if (matched.length === 0) return void 0;
17667
+ return { ...node, children: matched };
17668
+ }
17669
+ function collectDescribesMatching2(node, target, stack, out) {
17670
+ if (node.kind === "describe" && node.title !== void 0) {
17671
+ stack.push(node.title.toLowerCase());
17672
+ if (pathStartsWith2(stack, target)) {
17673
+ out.push(node);
17674
+ stack.pop();
17675
+ return;
17676
+ }
17677
+ }
17678
+ for (const child of node.children) collectDescribesMatching2(child, target, stack, out);
17679
+ if (node.kind === "describe" && node.title !== void 0) stack.pop();
17680
+ }
17681
+ function pathStartsWith2(actual, expected) {
17682
+ if (expected.length > actual.length) return false;
17683
+ for (const [i, element] of expected.entries()) {
17684
+ if (!actual[i].includes(element)) return false;
17685
+ }
17686
+ return true;
17687
+ }
17688
+ function parseDescribePath2(value) {
17689
+ return value.split(">").map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0);
17690
+ }
17691
+
17692
+ // packages/dbx-components-mcp/src/tools/model-test-tree.tool.ts
17693
+ var TreeArgsType = type37({
17694
+ specFile: "string",
17695
+ "apiDir?": "string",
17696
+ "view?": "'all' | 'describes' | 'fixtures' | 'its' | 'helpers'",
17697
+ "filterByModel?": "string",
17698
+ "filterByDescribePath?": "string",
17699
+ "format?": "'markdown' | 'json'"
17700
+ });
17701
+ var TOOL6 = {
17702
+ name: "dbx_model_test_tree",
17703
+ description: [
17704
+ "Parse one API `.spec.ts` file and return its structural skeleton \u2014 nested `describe`/`it` calls, `<prefix><Model>Context(...)` fixture chains, locally-defined helper-describe functions, and the wrapper calls between them. Each node carries its 1-based line range so callers can navigate by line offset instead of grepping.",
17705
+ "",
17706
+ "Provide:",
17707
+ "- `specFile`: relative path to the `.spec.ts` file (e.g. `apps/hellosubs-api/src/app/function/job/job.crud.instruction.spec.ts`).",
17708
+ "- `apiDir` (optional but recommended): relative path to the API app (e.g. `apps/hellosubs-api`). When supplied the tool reuses `inspectAppFixtures()` for the authoritative workspace prefix and the full set of `<prefix><Model>Context` names. When omitted the prefix is detected from the spec's own imports off `**/test/fixture`.",
17709
+ "- `view` (optional): `all` (default), `describes` (drop fixtures + wrappers), `fixtures` (only fixture chains, e.g. `Country > CountryState > Region > District > ...`), `its` (flat index of every `it()` with full describe path), or `helpers` (locally-defined helper-describe functions).",
17710
+ "- `filterByModel` (optional): keep only subtrees that contain a fixture call resolving to this model (e.g. `Job`).",
17711
+ "- `filterByDescribePath` (optional): keep only subtrees rooted at a describe whose `>`-separated path matches (e.g. `admin > job published`).",
17712
+ "- `format` (optional): `markdown` (default) or `json`.",
17713
+ "",
17714
+ "Paths escaping the server cwd are rejected."
17715
+ ].join("\n"),
17716
+ inputSchema: {
17717
+ type: "object",
17718
+ properties: {
17719
+ specFile: { type: "string", description: "Relative path to the `.spec.ts` file." },
17720
+ apiDir: { type: "string", description: "Optional relative path to the API app. Enables authoritative prefix + fixture-name detection via `inspectAppFixtures()`." },
17721
+ view: { type: "string", enum: ["all", "describes", "fixtures", "its", "helpers"], description: "View mode. Defaults to `all`." },
17722
+ filterByModel: { type: "string", description: "Keep only subtrees that contain a fixture call resolving to this model (case-insensitive)." },
17723
+ filterByDescribePath: { type: "string", description: "`>`-separated describe path; keep only subtrees rooted there (case-insensitive substring per segment)." },
17724
+ format: { type: "string", enum: ["markdown", "json"], description: "Output format. Defaults to markdown." }
17725
+ },
17726
+ required: ["specFile"]
17727
+ }
17728
+ };
17729
+ async function run5(rawArgs) {
17730
+ const parsed = TreeArgsType(rawArgs);
17731
+ if (parsed instanceof type37.errors) {
17732
+ return toolError(`Invalid arguments: ${parsed.summary}`);
17733
+ }
17734
+ const cwd = process.cwd();
17735
+ try {
17736
+ ensurePathInsideCwd(parsed.specFile, cwd);
17737
+ if (parsed.apiDir !== void 0) ensurePathInsideCwd(parsed.apiDir, cwd);
17738
+ } catch (err) {
17739
+ return toolError(err instanceof Error ? err.message : String(err));
17740
+ }
17741
+ const specAbs = resolve22(cwd, parsed.specFile);
17742
+ const apiAbs = parsed.apiDir !== void 0 ? resolve22(cwd, parsed.apiDir) : void 0;
17743
+ let tree;
17744
+ try {
17745
+ tree = await inspectSpecFile({ specAbs, specRel: parsed.specFile, apiAbs, apiRel: parsed.apiDir });
17746
+ } catch (err) {
17747
+ return toolError(`Failed to read spec file: ${err instanceof Error ? err.message : String(err)}`);
17748
+ }
17749
+ const view = parsed.view ?? "all";
17750
+ const filters = { filterByModel: parsed.filterByModel, filterByDescribePath: parsed.filterByDescribePath };
17751
+ const text = parsed.format === "json" ? formatTreeAsJson(tree, view, filters) : formatTreeAsMarkdown(tree, view, filters);
17752
+ const result = { content: [{ type: "text", text }] };
17753
+ return result;
17754
+ }
17755
+ var modelTestTreeTool = { definition: TOOL6, run: run5 };
17756
+
17757
+ // packages/dbx-components-mcp/src/tools/model-test-search.tool.ts
17758
+ import { resolve as resolve23 } from "node:path";
17759
+ import { type as type38 } from "arktype";
17760
+ var SearchArgsType2 = type38({
17761
+ specFile: "string",
17762
+ "apiDir?": "string",
17763
+ "model?": "string",
17764
+ "chain?": "string",
17765
+ "describe?": "string",
17766
+ "it?": "string",
17767
+ "format?": "'markdown' | 'json'"
17768
+ });
17769
+ var TOOL7 = {
17770
+ name: "dbx_model_test_search",
17771
+ description: [
17772
+ "Search one API `.spec.ts` file for `describe`s, `it`s, or `<prefix><Model>Context(...)` fixture calls matching a single criterion. Each hit is returned with the full describe path and fixture chain leading to it, plus its line range, so callers can jump straight to the right block.",
17773
+ "",
17774
+ "Provide exactly one of:",
17775
+ "- `model`: bare PascalCase model name (e.g. `Job`) \u2014 matches every `<prefix>JobContext(...)` site.",
17776
+ "- `chain`: `>`-separated model sequence (e.g. `Country > CountryState`) \u2014 matches every fixture chain containing the consecutive subsequence.",
17777
+ "- `describe`: case-insensitive substring against `describe(...)` titles.",
17778
+ "- `it`: case-insensitive substring against `it(...)` / `test(...)` titles.",
17779
+ "",
17780
+ "Plus:",
17781
+ "- `specFile`: relative path to the `.spec.ts` file.",
17782
+ "- `apiDir` (optional but recommended): enables authoritative prefix + fixture-name detection via `inspectAppFixtures()`.",
17783
+ "- `format` (optional): `markdown` (default) or `json`."
17784
+ ].join("\n"),
17785
+ inputSchema: {
17786
+ type: "object",
17787
+ properties: {
17788
+ specFile: { type: "string", description: "Relative path to the `.spec.ts` file." },
17789
+ apiDir: { type: "string", description: "Optional relative path to the API app." },
17790
+ model: { type: "string", description: "Bare PascalCase model name (e.g. `Job`)." },
17791
+ chain: { type: "string", description: "`>`-separated chain (e.g. `Country > CountryState`)." },
17792
+ describe: { type: "string", description: "Substring match against describe titles." },
17793
+ it: { type: "string", description: "Substring match against it/test titles." },
17794
+ format: { type: "string", enum: ["markdown", "json"], description: "Output format. Defaults to markdown." }
16690
17795
  },
16691
- required: ["apiDir", "model"]
17796
+ required: ["specFile"]
16692
17797
  }
16693
17798
  };
16694
- async function run4(rawArgs) {
16695
- const parsed = ForwardArgsType(rawArgs);
16696
- if (parsed instanceof type36.errors) {
17799
+ async function run6(rawArgs) {
17800
+ const parsed = SearchArgsType2(rawArgs);
17801
+ if (parsed instanceof type38.errors) {
16697
17802
  return toolError(`Invalid arguments: ${parsed.summary}`);
16698
17803
  }
16699
- const cwd = process.cwd();
16700
- try {
16701
- ensurePathInsideCwd(parsed.apiDir, cwd);
16702
- } catch (err) {
16703
- return toolError(toErrorMessage(err));
16704
- }
16705
- const apiAbs = resolve21(cwd, parsed.apiDir);
16706
- let extraction;
16707
- try {
16708
- extraction = await inspectAppFixtures(apiAbs, parsed.apiDir);
16709
- } catch (err) {
16710
- return toolError(`Failed to read fixture file: ${toErrorMessage(err)}`);
16711
- }
16712
- const entry = extraction.entries.find((e) => e.model === parsed.model);
16713
- if (!entry) {
16714
- const known = extraction.entries.map((e) => e.model).join(", ") || "(none)";
16715
- return toolError(`Model \`${parsed.model}\` not found in \`${extraction.fixturePath}\`. Known: ${known}.`);
16716
- }
16717
- const rendered = renderForwarders({ entry, methods: parsed.methods });
16718
- if (rendered.added.length === 0) {
16719
- return { content: [{ type: "text", text: renderNoOpReport(extraction.fixturePath, entry.fixtureClassName, rendered) }] };
17804
+ const queryFields = [
17805
+ { mode: "model", value: parsed.model },
17806
+ { mode: "chain", value: parsed.chain },
17807
+ { mode: "describe", value: parsed.describe },
17808
+ { mode: "it", value: parsed.it }
17809
+ ].filter((q) => q.value !== void 0 && q.value !== "");
17810
+ if (queryFields.length === 0) {
17811
+ return toolError("Provide exactly one of `model`, `chain`, `describe`, or `it`.");
16720
17812
  }
16721
- const absolutePath = join5(apiAbs, FIXTURE_RELATIVE_PATH);
16722
- const writeError = await applyForwardersToFile(absolutePath, entry.fixtureClassName, rendered);
16723
- if (writeError) {
16724
- return toolError(writeError);
17813
+ if (queryFields.length > 1) {
17814
+ return toolError(`Provide exactly one query field. Received: ${queryFields.map((q) => q.mode).join(", ")}.`);
16725
17815
  }
16726
- return { content: [{ type: "text", text: renderSuccessReport(extraction.fixturePath, entry.fixtureClassName, rendered) }] };
16727
- }
16728
- function toErrorMessage(err) {
16729
- return err instanceof Error ? err.message : String(err);
16730
- }
16731
- async function applyForwardersToFile(absolutePath, fixtureClassName, rendered) {
16732
- const project = new Project8({ skipAddingFilesFromTsConfig: true });
16733
- let sourceFile;
17816
+ const query = { mode: queryFields[0].mode, value: queryFields[0].value };
17817
+ const cwd = process.cwd();
16734
17818
  try {
16735
- sourceFile = project.addSourceFileAtPath(absolutePath);
17819
+ ensurePathInsideCwd(parsed.specFile, cwd);
17820
+ if (parsed.apiDir !== void 0) ensurePathInsideCwd(parsed.apiDir, cwd);
16736
17821
  } catch (err) {
16737
- return `Failed to load fixture file: ${toErrorMessage(err)}`;
16738
- }
16739
- const fixtureClass = sourceFile.getClass(fixtureClassName);
16740
- if (!fixtureClass) {
16741
- return `Could not locate class \`${fixtureClassName}\` for in-place edit. The fixture file may have been modified since parsing.`;
16742
- }
16743
- for (const forwarder of rendered.added) {
16744
- fixtureClass.insertText(fixtureClass.getEnd() - 1, "\n" + forwarder.source + "\n");
17822
+ return toolError(err instanceof Error ? err.message : String(err));
16745
17823
  }
16746
- sourceFile.formatText({ ensureNewLineAtEndOfFile: true });
17824
+ const specAbs = resolve23(cwd, parsed.specFile);
17825
+ const apiAbs = parsed.apiDir !== void 0 ? resolve23(cwd, parsed.apiDir) : void 0;
17826
+ let tree;
16747
17827
  try {
16748
- await sourceFile.save();
17828
+ tree = await inspectSpecFile({ specAbs, specRel: parsed.specFile, apiAbs, apiRel: parsed.apiDir });
16749
17829
  } catch (err) {
16750
- return `Failed to write fixture file: ${toErrorMessage(err)}`;
16751
- }
16752
- return void 0;
16753
- }
16754
- function renderNoOpReport(fixturePath, fixtureClassName, rendered) {
16755
- const lines = [`# No forwarders to add for \`${fixtureClassName}\``, "", `File: \`${fixturePath}\``];
16756
- appendListSection(lines, "## Already forwarded", rendered.skippedAlreadyForwarded);
16757
- appendListSection(lines, "## Whitelisted methods missing from Instance", rendered.missingFromInstance);
16758
- return lines.join("\n");
16759
- }
16760
- function renderSuccessReport(fixturePath, fixtureClassName, rendered) {
16761
- const lines = [`# Forwarded ${rendered.added.length} method${rendered.added.length === 1 ? "" : "s"} to \`${fixtureClassName}\``, "", `File: \`${fixturePath}\``, "", "## Added"];
16762
- for (const f of rendered.added) {
16763
- lines.push(`- \`${f.method}\``);
16764
- }
16765
- appendListSection(lines, "## Skipped (already forwarded)", rendered.skippedAlreadyForwarded);
16766
- appendListSection(lines, "## Whitelisted methods missing from Instance", rendered.missingFromInstance);
16767
- return lines.join("\n");
16768
- }
16769
- function appendListSection(lines, heading, names) {
16770
- if (names.length === 0) return;
16771
- lines.push("", heading);
16772
- for (const name of names) {
16773
- lines.push(`- \`${name}\``);
17830
+ return toolError(`Failed to read spec file: ${err instanceof Error ? err.message : String(err)}`);
16774
17831
  }
17832
+ const result = searchSpecTree(tree, query);
17833
+ const text = parsed.format === "json" ? formatSearchAsJson(tree, result) : formatSearchAsMarkdown(tree, result);
17834
+ const out = { content: [{ type: "text", text }] };
17835
+ return out;
16775
17836
  }
16776
- var modelFixtureForwardTool = { definition: TOOL5, run: run4 };
17837
+ var modelTestSearchTool = { definition: TOOL7, run: run6 };
16777
17838
 
16778
17839
  // packages/dbx-components-mcp/src/tools/storagefile-m-validate-app/extract.ts
16779
- import { Node as Node13, SyntaxKind as SyntaxKind8 } from "ts-morph";
17840
+ import { Node as Node14, SyntaxKind as SyntaxKind9 } from "ts-morph";
16780
17841
 
16781
17842
  // packages/dbx-components-mcp/src/tools/_validate/ast.ts
16782
- import { Node as Node12, Project as Project9, SyntaxKind as SyntaxKind7 } from "ts-morph";
17843
+ import { Node as Node13, Project as Project10, SyntaxKind as SyntaxKind8 } from "ts-morph";
16783
17844
  var COMPONENT_VIRTUAL_PREFIX = "__component__/";
16784
17845
  var API_VIRTUAL_PREFIX = "__api__/";
16785
17846
  function buildInMemoryProject(input) {
16786
- const project = new Project9({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
17847
+ const project = new Project10({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
16787
17848
  const componentSources = [];
16788
17849
  const apiSources = [];
16789
17850
  for (const file of input.component.files) {
@@ -16803,28 +17864,28 @@ function componentRelPath(sourceFile) {
16803
17864
  }
16804
17865
  function unwrapAsExpressions(node) {
16805
17866
  let current = node;
16806
- while (current && Node12.isAsExpression(current)) {
17867
+ while (current && Node13.isAsExpression(current)) {
16807
17868
  current = current.getExpression();
16808
17869
  }
16809
17870
  return current;
16810
17871
  }
16811
17872
  function asObjectLiteral(node) {
16812
17873
  const inner = unwrapAsExpressions(node);
16813
- if (inner && Node12.isObjectLiteralExpression(inner)) {
17874
+ if (inner && Node13.isObjectLiteralExpression(inner)) {
16814
17875
  return inner;
16815
17876
  }
16816
17877
  return void 0;
16817
17878
  }
16818
17879
  function asArrayLiteral(node) {
16819
17880
  const inner = unwrapAsExpressions(node);
16820
- if (inner && Node12.isArrayLiteralExpression(inner)) {
17881
+ if (inner && Node13.isArrayLiteralExpression(inner)) {
16821
17882
  return inner;
16822
17883
  }
16823
17884
  return void 0;
16824
17885
  }
16825
17886
  function readStringLiteralInitializer(decl) {
16826
17887
  const initializer = unwrapAsExpressions(decl.getInitializer());
16827
- if (initializer && Node12.isStringLiteral(initializer)) {
17888
+ if (initializer && Node13.isStringLiteral(initializer)) {
16828
17889
  return initializer.getLiteralText();
16829
17890
  }
16830
17891
  return void 0;
@@ -16836,37 +17897,37 @@ function typeAnnotationText(node) {
16836
17897
  function getPropertyInitializer(obj, name) {
16837
17898
  const prop = obj.getProperty(name);
16838
17899
  if (!prop) return void 0;
16839
- if (Node12.isPropertyAssignment(prop)) {
17900
+ if (Node13.isPropertyAssignment(prop)) {
16840
17901
  return prop.getInitializer();
16841
17902
  }
16842
- if (Node12.isShorthandPropertyAssignment(prop)) {
17903
+ if (Node13.isShorthandPropertyAssignment(prop)) {
16843
17904
  return prop.getNameNode();
16844
17905
  }
16845
17906
  return void 0;
16846
17907
  }
16847
17908
  function readStringProperty2(obj, name) {
16848
17909
  const init = unwrapAsExpressions(getPropertyInitializer(obj, name));
16849
- if (init && Node12.isStringLiteral(init)) {
17910
+ if (init && Node13.isStringLiteral(init)) {
16850
17911
  return init.getLiteralText();
16851
17912
  }
16852
17913
  return void 0;
16853
17914
  }
16854
17915
  function readIdentifierProperty(obj, name) {
16855
17916
  const init = unwrapAsExpressions(getPropertyInitializer(obj, name));
16856
- if (init && Node12.isIdentifier(init)) {
17917
+ if (init && Node13.isIdentifier(init)) {
16857
17918
  return init.getText();
16858
17919
  }
16859
17920
  return void 0;
16860
17921
  }
16861
17922
  function findReturnExpression(fn) {
16862
- if (!Node12.isArrowFunction(fn) && !Node12.isFunctionDeclaration(fn) && !Node12.isFunctionExpression(fn)) {
17923
+ if (!Node13.isArrowFunction(fn) && !Node13.isFunctionDeclaration(fn) && !Node13.isFunctionExpression(fn)) {
16863
17924
  return void 0;
16864
17925
  }
16865
17926
  const body = fn.getBody();
16866
17927
  if (!body) return void 0;
16867
- if (Node12.isBlock(body)) {
17928
+ if (Node13.isBlock(body)) {
16868
17929
  for (const stmt of body.getStatements()) {
16869
- if (Node12.isReturnStatement(stmt)) {
17930
+ if (Node13.isReturnStatement(stmt)) {
16870
17931
  return stmt.getExpression();
16871
17932
  }
16872
17933
  }
@@ -16880,17 +17941,17 @@ function findLocalVariable(sf, name) {
16880
17941
  if (decl.getName() === name) return decl;
16881
17942
  }
16882
17943
  }
16883
- for (const decl of sf.getDescendantsOfKind(SyntaxKind7.VariableDeclaration)) {
17944
+ for (const decl of sf.getDescendantsOfKind(SyntaxKind8.VariableDeclaration)) {
16884
17945
  if (decl.getName() === name) return decl;
16885
17946
  }
16886
17947
  return void 0;
16887
17948
  }
16888
17949
  function collectTypeofReferences(node, out) {
16889
- if (Node12.isTypeQuery(node)) {
17950
+ if (Node13.isTypeQuery(node)) {
16890
17951
  out.push(node.getExprName().getText());
16891
17952
  return;
16892
17953
  }
16893
- for (const tq of node.getDescendantsOfKind(SyntaxKind7.TypeQuery)) {
17954
+ for (const tq of node.getDescendantsOfKind(SyntaxKind8.TypeQuery)) {
16894
17955
  out.push(tq.getExprName().getText());
16895
17956
  }
16896
17957
  }
@@ -17188,8 +18249,8 @@ function getFunctionType(x) {
17188
18249
  return typeof x === "function" ? x.prototype ? Object.getOwnPropertyDescriptor(x, "prototype")?.writable ? "function" : "class" : x.constructor.name === "AsyncFunction" ? "function" : "arrow" : null;
17189
18250
  }
17190
18251
  function isNonClassFunction(x) {
17191
- const type60 = getFunctionType(x);
17192
- return type60 != null && type60 !== "class";
18252
+ const type62 = getFunctionType(x);
18253
+ return type62 != null && type62 !== "class";
17193
18254
  }
17194
18255
 
17195
18256
  // packages/util/src/lib/getter/getter.ts
@@ -17266,9 +18327,9 @@ function asNumber(input) {
17266
18327
  }
17267
18328
 
17268
18329
  // packages/util/src/lib/number/round.ts
17269
- function roundingFunction(type60) {
18330
+ function roundingFunction(type62) {
17270
18331
  let fn;
17271
- switch (type60) {
18332
+ switch (type62) {
17272
18333
  case "floor":
17273
18334
  fn = Math.floor;
17274
18335
  break;
@@ -17521,9 +18582,9 @@ function filterKeyValueTuplesInputToFilter(input) {
17521
18582
  }
17522
18583
  function filterKeyValueTupleFunction(inputFilter) {
17523
18584
  const filter = filterKeyValueTuplesInputToFilter(inputFilter);
17524
- const { valueFilter: type60 = 1 /* UNDEFINED */, invertFilter: inverseFilter = false, keysFilter } = filter;
18585
+ const { valueFilter: type62 = 1 /* UNDEFINED */, invertFilter: inverseFilter = false, keysFilter } = filter;
17525
18586
  let filterFn;
17526
- switch (type60) {
18587
+ switch (type62) {
17527
18588
  case 1 /* UNDEFINED */:
17528
18589
  filterFn = ([, x]) => x !== void 0;
17529
18590
  break;
@@ -17782,7 +18843,7 @@ var NUMBER_STRING_DENCODER_64_DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcd
17782
18843
  var NUMBER_STRING_DENCODER_64_DEFAULT_NEGATIVE_PREFIX = "!";
17783
18844
  function numberStringDencoder(config) {
17784
18845
  const { negativePrefix, digits } = config;
17785
- const type60 = negativePrefix ? "integer" : "positive_integer";
18846
+ const type62 = negativePrefix ? "integer" : "positive_integer";
17786
18847
  const log2OfDigits = Math.min(6, Math.floor(Math.log2(digits.length)));
17787
18848
  const bitDepth = Math.pow(2, log2OfDigits);
17788
18849
  const bitMask = bitDepth - 1;
@@ -17819,7 +18880,7 @@ function numberStringDencoder(config) {
17819
18880
  return result;
17820
18881
  }
17821
18882
  return {
17822
- type: type60,
18883
+ type: type62,
17823
18884
  digits,
17824
18885
  bitDepth,
17825
18886
  negativePrefix,
@@ -17890,9 +18951,9 @@ function readableStreamToStringFunction(encoding) {
17890
18951
  var readableStreamToBase64 = readableStreamToStringFunction("base64");
17891
18952
  function readableStreamToBuffer(stream) {
17892
18953
  const chunks = [];
17893
- return new Promise((resolve34, reject) => {
18954
+ return new Promise((resolve36, reject) => {
17894
18955
  stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
17895
- stream.on("end", () => resolve34(Buffer.concat(chunks)));
18956
+ stream.on("end", () => resolve36(Buffer.concat(chunks)));
17896
18957
  stream.on("error", reject);
17897
18958
  });
17898
18959
  }
@@ -18315,7 +19376,7 @@ function extractUploadInitializerEntries(sources) {
18315
19376
  const out = [];
18316
19377
  for (const sf of sources) {
18317
19378
  const rel = apiRelPath(sf);
18318
- for (const decl of sf.getDescendantsOfKind(SyntaxKind8.VariableDeclaration)) {
19379
+ for (const decl of sf.getDescendantsOfKind(SyntaxKind9.VariableDeclaration)) {
18319
19380
  const typeText = typeAnnotationText(decl);
18320
19381
  if (typeText !== UPLOAD_SERVICE_INITIALIZER_TYPE) continue;
18321
19382
  const obj = asObjectLiteral(decl.getInitializer());
@@ -18345,7 +19406,7 @@ function buildApiFunctionIndex(sources) {
18345
19406
  for (const decl of stmt.getDeclarations()) {
18346
19407
  const initializer = unwrapAsExpressions(decl.getInitializer());
18347
19408
  if (!initializer) continue;
18348
- if (Node13.isArrowFunction(initializer) || Node13.isFunctionExpression(initializer)) {
19409
+ if (Node14.isArrowFunction(initializer) || Node14.isFunctionExpression(initializer)) {
18349
19410
  map.set(decl.getName(), { node: initializer, sourceFile: sf });
18350
19411
  }
18351
19412
  }
@@ -18358,34 +19419,34 @@ function collectInitializerBindingsFromValue(options) {
18358
19419
  const { node, sf, index, resolved, unresolved, visited } = options;
18359
19420
  const inner = unwrapAsExpressions(node);
18360
19421
  if (!inner) return false;
18361
- if (Node13.isArrayLiteralExpression(inner)) {
19422
+ if (Node14.isArrayLiteralExpression(inner)) {
18362
19423
  for (const el of inner.getElements()) {
18363
- if (Node13.isSpreadElement(el)) {
19424
+ if (Node14.isSpreadElement(el)) {
18364
19425
  const spreadInner = el.getExpression();
18365
- if (Node13.isIdentifier(spreadInner)) {
19426
+ if (Node14.isIdentifier(spreadInner)) {
18366
19427
  collectInitializerBindingsFromIdentifier({ name: spreadInner.getText(), sf, index, resolved, unresolved, visited });
18367
- } else if (Node13.isCallExpression(spreadInner)) {
19428
+ } else if (Node14.isCallExpression(spreadInner)) {
18368
19429
  const callee = spreadInner.getExpression();
18369
- if (Node13.isIdentifier(callee)) {
19430
+ if (Node14.isIdentifier(callee)) {
18370
19431
  collectInitializerBindingsFromIdentifier({ name: callee.getText(), sf, index, resolved, unresolved, visited });
18371
19432
  }
18372
19433
  }
18373
19434
  continue;
18374
19435
  }
18375
19436
  const elementInner = unwrapAsExpressions(el);
18376
- if (elementInner && Node13.isIdentifier(elementInner)) {
19437
+ if (elementInner && Node14.isIdentifier(elementInner)) {
18377
19438
  resolved.push(elementInner.getText());
18378
19439
  }
18379
19440
  }
18380
19441
  return true;
18381
19442
  }
18382
- if (Node13.isCallExpression(inner)) {
19443
+ if (Node14.isCallExpression(inner)) {
18383
19444
  const callee = inner.getExpression();
18384
- if (Node13.isIdentifier(callee)) {
19445
+ if (Node14.isIdentifier(callee)) {
18385
19446
  return collectInitializerBindingsFromIdentifier({ name: callee.getText(), sf, index, resolved, unresolved, visited });
18386
19447
  }
18387
19448
  }
18388
- if (Node13.isIdentifier(inner)) {
19449
+ if (Node14.isIdentifier(inner)) {
18389
19450
  return collectInitializerBindingsFromIdentifier({ name: inner.getText(), sf, index, resolved, unresolved, visited });
18390
19451
  }
18391
19452
  return false;
@@ -18424,15 +19485,15 @@ function collectUploadInitializerArray(options) {
18424
19485
  const { initializerArr, sf, index, direct, spreads, resolved, unresolved } = options;
18425
19486
  const visited = /* @__PURE__ */ new Set();
18426
19487
  for (const el of initializerArr.getElements()) {
18427
- if (Node13.isSpreadElement(el)) {
19488
+ if (Node14.isSpreadElement(el)) {
18428
19489
  const inner2 = el.getExpression();
18429
- if (Node13.isIdentifier(inner2)) {
19490
+ if (Node14.isIdentifier(inner2)) {
18430
19491
  const name = inner2.getText();
18431
19492
  spreads.push(name);
18432
19493
  collectInitializerBindingsFromIdentifier({ name, sf, index, resolved, unresolved, visited });
18433
- } else if (Node13.isCallExpression(inner2)) {
19494
+ } else if (Node14.isCallExpression(inner2)) {
18434
19495
  const callee = inner2.getExpression();
18435
- if (Node13.isIdentifier(callee)) {
19496
+ if (Node14.isIdentifier(callee)) {
18436
19497
  const name = callee.getText();
18437
19498
  spreads.push(name);
18438
19499
  collectInitializerBindingsFromIdentifier({ name, sf, index, resolved, unresolved, visited });
@@ -18441,7 +19502,7 @@ function collectUploadInitializerArray(options) {
18441
19502
  continue;
18442
19503
  }
18443
19504
  const inner = unwrapAsExpressions(el);
18444
- if (inner && Node13.isIdentifier(inner)) {
19505
+ if (inner && Node14.isIdentifier(inner)) {
18445
19506
  const name = inner.getText();
18446
19507
  direct.push(name);
18447
19508
  resolved.push(name);
@@ -18452,9 +19513,9 @@ function extractUploadServiceCalls(sources, index) {
18452
19513
  const out = [];
18453
19514
  for (const sf of sources) {
18454
19515
  const rel = apiRelPath(sf);
18455
- for (const call of sf.getDescendantsOfKind(SyntaxKind8.CallExpression)) {
19516
+ for (const call of sf.getDescendantsOfKind(SyntaxKind9.CallExpression)) {
18456
19517
  const expr = call.getExpression();
18457
- if (!Node13.isIdentifier(expr) || expr.getText() !== UPLOAD_SERVICE_FACTORY) continue;
19518
+ if (!Node14.isIdentifier(expr) || expr.getText() !== UPLOAD_SERVICE_FACTORY) continue;
18458
19519
  const args = call.getArguments();
18459
19520
  const first = args[0] ? resolveObjectArg(args[0], sf) : void 0;
18460
19521
  if (!first) continue;
@@ -18482,12 +19543,12 @@ function extractUploadServiceCalls(sources, index) {
18482
19543
  function resolveObjectArg(node, sf) {
18483
19544
  const inner = unwrapAsExpressions(node);
18484
19545
  if (!inner) return void 0;
18485
- if (Node13.isObjectLiteralExpression(inner)) return inner;
18486
- if (Node13.isIdentifier(inner)) {
19546
+ if (Node14.isObjectLiteralExpression(inner)) return inner;
19547
+ if (Node14.isIdentifier(inner)) {
18487
19548
  const declNode = findLocalVariable(sf, inner.getText());
18488
19549
  if (declNode) {
18489
19550
  const declInit = unwrapAsExpressions(declNode.getInitializer());
18490
- if (declInit && Node13.isObjectLiteralExpression(declInit)) {
19551
+ if (declInit && Node14.isObjectLiteralExpression(declInit)) {
18491
19552
  return declInit;
18492
19553
  }
18493
19554
  }
@@ -18497,12 +19558,12 @@ function resolveObjectArg(node, sf) {
18497
19558
  function resolveArrayFromProperty(obj, name, sf) {
18498
19559
  const init = unwrapAsExpressions(getPropertyInitializer(obj, name));
18499
19560
  if (!init) return void 0;
18500
- if (Node13.isArrayLiteralExpression(init)) return init;
18501
- if (Node13.isIdentifier(init)) {
19561
+ if (Node14.isArrayLiteralExpression(init)) return init;
19562
+ if (Node14.isIdentifier(init)) {
18502
19563
  const declNode = findLocalVariable(sf, init.getText());
18503
19564
  if (declNode) {
18504
19565
  const declInit = unwrapAsExpressions(declNode.getInitializer());
18505
- if (declInit && Node13.isArrayLiteralExpression(declInit)) {
19566
+ if (declInit && Node14.isArrayLiteralExpression(declInit)) {
18506
19567
  return declInit;
18507
19568
  }
18508
19569
  }
@@ -18513,11 +19574,11 @@ function enclosingFactoryName(node) {
18513
19574
  let current = node.getParent();
18514
19575
  let result;
18515
19576
  while (current) {
18516
- if (Node13.isFunctionDeclaration(current)) {
19577
+ if (Node14.isFunctionDeclaration(current)) {
18517
19578
  result = current.getName() ?? void 0;
18518
19579
  break;
18519
19580
  }
18520
- if (Node13.isVariableDeclaration(current)) {
19581
+ if (Node14.isVariableDeclaration(current)) {
18521
19582
  result = current.getName();
18522
19583
  break;
18523
19584
  }
@@ -18529,7 +19590,7 @@ function extractUploadServiceWirings(sources) {
18529
19590
  const out = [];
18530
19591
  for (const sf of sources) {
18531
19592
  const rel = apiRelPath(sf);
18532
- for (const obj of sf.getDescendantsOfKind(SyntaxKind8.ObjectLiteralExpression)) {
19593
+ for (const obj of sf.getDescendantsOfKind(SyntaxKind9.ObjectLiteralExpression)) {
18533
19594
  const provideIdent = readIdentifierProperty(obj, "provide");
18534
19595
  if (provideIdent !== UPLOAD_SERVICE_PROVIDE_TOKEN) continue;
18535
19596
  const useFactory = readIdentifierProperty(obj, "useFactory");
@@ -18542,7 +19603,7 @@ function extractProcessingConfigs(sources) {
18542
19603
  const out = [];
18543
19604
  for (const sf of sources) {
18544
19605
  const rel = apiRelPath(sf);
18545
- for (const decl of sf.getDescendantsOfKind(SyntaxKind8.VariableDeclaration)) {
19606
+ for (const decl of sf.getDescendantsOfKind(SyntaxKind9.VariableDeclaration)) {
18546
19607
  const config = extractProcessingConfigFromDecl(decl, rel);
18547
19608
  if (config) {
18548
19609
  out.push(config);
@@ -18571,10 +19632,10 @@ function extractProcessingConfigFromDecl(decl, rel) {
18571
19632
  function readFlowSubtasks(obj) {
18572
19633
  const flowInit = unwrapAsExpressions(getPropertyInitializer(obj, "flow"));
18573
19634
  const subtasks = [];
18574
- if (flowInit && Node13.isArrayLiteralExpression(flowInit)) {
19635
+ if (flowInit && Node14.isArrayLiteralExpression(flowInit)) {
18575
19636
  for (const el of flowInit.getElements()) {
18576
19637
  const inner = unwrapAsExpressions(el);
18577
- if (inner && Node13.isObjectLiteralExpression(inner)) {
19638
+ if (inner && Node14.isObjectLiteralExpression(inner)) {
18578
19639
  const subtask = readIdentifierProperty(inner, "subtask");
18579
19640
  if (subtask) subtasks.push(subtask);
18580
19641
  }
@@ -18586,9 +19647,9 @@ function extractProcessingHandlerCalls(sources) {
18586
19647
  const out = [];
18587
19648
  for (const sf of sources) {
18588
19649
  const rel = apiRelPath(sf);
18589
- for (const call of sf.getDescendantsOfKind(SyntaxKind8.CallExpression)) {
19650
+ for (const call of sf.getDescendantsOfKind(SyntaxKind9.CallExpression)) {
18590
19651
  const expr = call.getExpression();
18591
- if (!Node13.isIdentifier(expr) || expr.getText() !== PROCESSING_HANDLER_FACTORY) continue;
19652
+ if (!Node14.isIdentifier(expr) || expr.getText() !== PROCESSING_HANDLER_FACTORY) continue;
18592
19653
  const args = call.getArguments();
18593
19654
  const first = args[0] ? resolveObjectArg(args[0], sf) : void 0;
18594
19655
  if (!first) continue;
@@ -18609,7 +19670,7 @@ function extractProcessingHandlerCalls(sources) {
18609
19670
  }
18610
19671
  function collectProcessorArrayElements(processorsArr, direct, spreads) {
18611
19672
  for (const el of processorsArr.getElements()) {
18612
- if (Node13.isSpreadElement(el)) {
19673
+ if (Node14.isSpreadElement(el)) {
18613
19674
  addProcessorIdentifierName(el.getExpression(), spreads);
18614
19675
  continue;
18615
19676
  }
@@ -18621,13 +19682,13 @@ function collectProcessorArrayElements(processorsArr, direct, spreads) {
18621
19682
  }
18622
19683
  function addProcessorIdentifierName(node, bucket) {
18623
19684
  if (!node) return;
18624
- if (Node13.isIdentifier(node)) {
19685
+ if (Node14.isIdentifier(node)) {
18625
19686
  bucket.push(node.getText());
18626
19687
  return;
18627
19688
  }
18628
- if (Node13.isCallExpression(node)) {
19689
+ if (Node14.isCallExpression(node)) {
18629
19690
  const callee = node.getExpression();
18630
- if (Node13.isIdentifier(callee)) {
19691
+ if (Node14.isIdentifier(callee)) {
18631
19692
  bucket.push(callee.getText());
18632
19693
  }
18633
19694
  }
@@ -18982,8 +20043,8 @@ function formatResult4(result) {
18982
20043
  }
18983
20044
 
18984
20045
  // packages/dbx-components-mcp/src/tools/_validate/inspect.ts
18985
- import { readdir as readdir3, readFile as readFile6, stat as stat5 } from "node:fs/promises";
18986
- import { join as join6, relative as relative5, sep as sep4 } from "node:path";
20046
+ import { readdir as readdir3, readFile as readFile8, stat as stat5 } from "node:fs/promises";
20047
+ import { join as join7, relative as relative5, sep as sep4 } from "node:path";
18987
20048
  async function inspectSide(rootDir, subpaths) {
18988
20049
  const rootStatus = await readRootStatus(rootDir);
18989
20050
  if (rootStatus !== void 0) {
@@ -18993,7 +20054,7 @@ async function inspectSide(rootDir, subpaths) {
18993
20054
  const presentFolders = [];
18994
20055
  const collectedFiles = [];
18995
20056
  for (const sub of subpaths) {
18996
- const absFolder = join6(rootDir, sub);
20057
+ const absFolder = join7(rootDir, sub);
18997
20058
  const folderPresent = await isDirectory(absFolder);
18998
20059
  if (!folderPresent) continue;
18999
20060
  presentFolders.push(sub);
@@ -19039,7 +20100,7 @@ async function collectTsFiles(absFolder, rootDir) {
19039
20100
  continue;
19040
20101
  }
19041
20102
  for (const entry of entries) {
19042
- const full = join6(current, entry.name);
20103
+ const full = join7(current, entry.name);
19043
20104
  if (entry.isDirectory()) {
19044
20105
  stack.push(full);
19045
20106
  continue;
@@ -19048,7 +20109,7 @@ async function collectTsFiles(absFolder, rootDir) {
19048
20109
  if (!entry.name.endsWith(".ts")) continue;
19049
20110
  if (entry.name.endsWith(".spec.ts")) continue;
19050
20111
  if (entry.name.endsWith(".d.ts")) continue;
19051
- const text = await readFile6(full, "utf8");
20112
+ const text = await readFile8(full, "utf8");
19052
20113
  const rel = relative5(rootDir, full).split(sep4).join("/");
19053
20114
  out.push({ relPath: rel, text });
19054
20115
  }
@@ -19301,8 +20362,8 @@ var storageFileMListAppTool = createListAppTool({
19301
20362
  });
19302
20363
 
19303
20364
  // packages/dbx-components-mcp/src/tools/validate-two-side-folder.ts
19304
- import { readdir as readdir4, readFile as readFile7, stat as stat6 } from "node:fs/promises";
19305
- import { join as join7 } from "node:path";
20365
+ import { readdir as readdir4, readFile as readFile9, stat as stat6 } from "node:fs/promises";
20366
+ import { join as join8 } from "node:path";
19306
20367
  var REEXPORT_PATTERN = /^\s*export\s+\*\s+from\s+['"]\.\/([^'"\n]+)['"]\s*;?\s*$/gm;
19307
20368
  function createTwoSideFolderValidator(config) {
19308
20369
  async function inspect(input) {
@@ -19346,7 +20407,7 @@ async function inspectSide2(input) {
19346
20407
  let indexSource;
19347
20408
  const rootStatOk = await isExistingDirectory(rootDir);
19348
20409
  if (rootStatOk) {
19349
- const absFolder = join7(rootDir, subPath);
20410
+ const absFolder = join8(rootDir, subPath);
19350
20411
  const folderStatOk = await isExistingDirectory(absFolder);
19351
20412
  if (folderStatOk) {
19352
20413
  const folder = await readFolder(absFolder, indexFile);
@@ -19398,7 +20459,7 @@ async function readFolder(absFolder, indexFile) {
19398
20459
  let indexSource;
19399
20460
  if (collectedFiles.includes(indexFile)) {
19400
20461
  try {
19401
- indexSource = await readFile7(join7(absFolder, indexFile), "utf8");
20462
+ indexSource = await readFile9(join8(absFolder, indexFile), "utf8");
19402
20463
  } catch {
19403
20464
  indexSource = void 0;
19404
20465
  }
@@ -19618,7 +20679,7 @@ var storageFileMValidateFolderTool = createTwoSideValidateTool({
19618
20679
  });
19619
20680
 
19620
20681
  // packages/dbx-components-mcp/src/tools/notification-m-validate-app/extract.ts
19621
- import { Node as Node14, SyntaxKind as SyntaxKind9 } from "ts-morph";
20682
+ import { Node as Node15, SyntaxKind as SyntaxKind10 } from "ts-morph";
19622
20683
  var NOTIF_TEMPLATE_TYPE = "NotificationTemplateType";
19623
20684
  var NOTIF_TEMPLATE_TYPE_INFO = "NotificationTemplateTypeInfo";
19624
20685
  var NOTIF_TEMPLATE_TYPE_INFO_ARRAY = "NotificationTemplateTypeInfo[]";
@@ -19739,7 +20800,7 @@ function extractTemplateInfoAggregates(sources) {
19739
20800
  const ids = [];
19740
20801
  for (const el of arr.getElements()) {
19741
20802
  const inner = unwrapAsExpressions(el);
19742
- if (inner && Node14.isIdentifier(inner)) {
20803
+ if (inner && Node15.isIdentifier(inner)) {
19743
20804
  ids.push(inner.getText());
19744
20805
  }
19745
20806
  }
@@ -19785,7 +20846,7 @@ function extractTaskAllTypesAggregates(sources) {
19785
20846
  const ids = [];
19786
20847
  for (const el of arr.getElements()) {
19787
20848
  const inner = unwrapAsExpressions(el);
19788
- if (inner && Node14.isIdentifier(inner)) {
20849
+ if (inner && Node15.isIdentifier(inner)) {
19789
20850
  ids.push(inner.getText());
19790
20851
  }
19791
20852
  }
@@ -19813,14 +20874,14 @@ function extractTaskCheckpointAliases(sources) {
19813
20874
  return out;
19814
20875
  }
19815
20876
  function collectStringLiterals(node, out) {
19816
- if (Node14.isLiteralTypeNode(node)) {
20877
+ if (Node15.isLiteralTypeNode(node)) {
19817
20878
  const lit = node.getLiteral();
19818
- if (Node14.isStringLiteral(lit)) {
20879
+ if (Node15.isStringLiteral(lit)) {
19819
20880
  out.push(lit.getLiteralText());
19820
20881
  }
19821
20882
  return;
19822
20883
  }
19823
- if (Node14.isUnionTypeNode(node)) {
20884
+ if (Node15.isUnionTypeNode(node)) {
19824
20885
  for (const child of node.getTypeNodes()) {
19825
20886
  collectStringLiterals(child, out);
19826
20887
  }
@@ -19874,7 +20935,7 @@ function extractTemplateInfoRecord(sources, index) {
19874
20935
  }
19875
20936
  function tryReadTemplateInfoRecord(decl, rel, index) {
19876
20937
  const initializer = unwrapAsExpressions(decl.getInitializer());
19877
- if (!initializer || !Node14.isCallExpression(initializer)) return void 0;
20938
+ if (!initializer || !Node15.isCallExpression(initializer)) return void 0;
19878
20939
  if (initializer.getExpression().getText() !== TEMPLATE_INFO_RECORD_FACTORY) return void 0;
19879
20940
  const args = initializer.getArguments();
19880
20941
  const arr = args[0] ? asArrayLiteral(args[0]) : void 0;
@@ -19895,15 +20956,15 @@ function tryReadTemplateInfoRecord(decl, rel, index) {
19895
20956
  }
19896
20957
  function classifyInfoRecordArrayElements(arr, direct, spreads) {
19897
20958
  for (const el of arr.getElements()) {
19898
- if (Node14.isSpreadElement(el)) {
20959
+ if (Node15.isSpreadElement(el)) {
19899
20960
  const inner2 = el.getExpression();
19900
- if (Node14.isIdentifier(inner2)) {
20961
+ if (Node15.isIdentifier(inner2)) {
19901
20962
  spreads.push(inner2.getText());
19902
20963
  }
19903
20964
  continue;
19904
20965
  }
19905
20966
  const inner = unwrapAsExpressions(el);
19906
- if (inner && Node14.isIdentifier(inner)) {
20967
+ if (inner && Node15.isIdentifier(inner)) {
19907
20968
  direct.push(inner.getText());
19908
20969
  }
19909
20970
  }
@@ -19924,13 +20985,13 @@ function resolveTemplateInfoSpreads(direct, spreads, index) {
19924
20985
  function extractTemplateInfoRecordWiring(sources) {
19925
20986
  for (const sf of sources) {
19926
20987
  const rel = apiRelPath(sf);
19927
- for (const call of sf.getDescendantsOfKind(SyntaxKind9.CallExpression)) {
20988
+ for (const call of sf.getDescendantsOfKind(SyntaxKind10.CallExpression)) {
19928
20989
  if (call.getExpression().getText() !== TEMPLATE_INFO_RECORD_SERVICE) continue;
19929
20990
  const args = call.getArguments();
19930
20991
  const first = args[0];
19931
20992
  if (!first) continue;
19932
20993
  const inner = unwrapAsExpressions(first);
19933
- if (!inner || !Node14.isIdentifier(inner)) continue;
20994
+ if (!inner || !Node15.isIdentifier(inner)) continue;
19934
20995
  const result = {
19935
20996
  recordIdentifier: inner.getText(),
19936
20997
  sourceFile: rel
@@ -19943,7 +21004,7 @@ function extractTemplateInfoRecordWiring(sources) {
19943
21004
  function extractTemplateConfigsArrayWiring(sources) {
19944
21005
  for (const sf of sources) {
19945
21006
  const rel = apiRelPath(sf);
19946
- for (const obj of sf.getDescendantsOfKind(SyntaxKind9.ObjectLiteralExpression)) {
21007
+ for (const obj of sf.getDescendantsOfKind(SyntaxKind10.ObjectLiteralExpression)) {
19947
21008
  const provideIdent = readIdentifierProperty(obj, "provide");
19948
21009
  if (provideIdent !== TEMPLATE_CONFIGS_ARRAY_TOKEN) continue;
19949
21010
  const useFactoryIdent = readIdentifierProperty(obj, "useFactory");
@@ -19968,7 +21029,7 @@ function buildApiFunctionIndex2(sources) {
19968
21029
  for (const decl of stmt.getDeclarations()) {
19969
21030
  const initializer = unwrapAsExpressions(decl.getInitializer());
19970
21031
  if (!initializer) continue;
19971
- if (Node14.isArrowFunction(initializer) || Node14.isFunctionExpression(initializer)) {
21032
+ if (Node15.isArrowFunction(initializer) || Node15.isFunctionExpression(initializer)) {
19972
21033
  map.set(decl.getName(), { node: initializer, sourceFile: sf, relPath: rel });
19973
21034
  }
19974
21035
  }
@@ -20004,11 +21065,11 @@ function extractTemplateConfigsArrayFactory(sources, index) {
20004
21065
  const arr = returnExpr ? asArrayLiteral(returnExpr) : void 0;
20005
21066
  if (arr) {
20006
21067
  for (const el of arr.getElements()) {
20007
- if (Node14.isSpreadElement(el)) {
21068
+ if (Node15.isSpreadElement(el)) {
20008
21069
  const inner2 = el.getExpression();
20009
- if (Node14.isCallExpression(inner2)) {
21070
+ if (Node15.isCallExpression(inner2)) {
20010
21071
  const callee = inner2.getExpression();
20011
- if (Node14.isIdentifier(callee)) {
21072
+ if (Node15.isIdentifier(callee)) {
20012
21073
  const callName = callee.getText();
20013
21074
  spreadCalls.push(callName);
20014
21075
  if (!index.functionsByName.has(callName)) {
@@ -20019,9 +21080,9 @@ function extractTemplateConfigsArrayFactory(sources, index) {
20019
21080
  continue;
20020
21081
  }
20021
21082
  const inner = unwrapAsExpressions(el);
20022
- if (inner && Node14.isCallExpression(inner)) {
21083
+ if (inner && Node15.isCallExpression(inner)) {
20023
21084
  const callee = inner.getExpression();
20024
- if (Node14.isIdentifier(callee)) {
21085
+ if (Node15.isIdentifier(callee)) {
20025
21086
  directCalls.push(callee.getText());
20026
21087
  }
20027
21088
  }
@@ -20070,11 +21131,11 @@ function collectFromArrayEntryFactory(name, out, index) {
20070
21131
  const arr = asArrayLiteral(returnExpr);
20071
21132
  if (!arr) return;
20072
21133
  for (const el of arr.getElements()) {
20073
- if (Node14.isSpreadElement(el)) {
21134
+ if (Node15.isSpreadElement(el)) {
20074
21135
  const inner2 = el.getExpression();
20075
- if (Node14.isCallExpression(inner2)) {
21136
+ if (Node15.isCallExpression(inner2)) {
20076
21137
  const callee = inner2.getExpression();
20077
- if (Node14.isIdentifier(callee)) {
21138
+ if (Node15.isIdentifier(callee)) {
20078
21139
  collectFromArrayEntryFactory(callee.getText(), out, index);
20079
21140
  }
20080
21141
  }
@@ -20082,9 +21143,9 @@ function collectFromArrayEntryFactory(name, out, index) {
20082
21143
  }
20083
21144
  const inner = unwrapAsExpressions(el);
20084
21145
  if (!inner) continue;
20085
- if (Node14.isCallExpression(inner)) {
21146
+ if (Node15.isCallExpression(inner)) {
20086
21147
  const callee = inner.getExpression();
20087
- if (Node14.isIdentifier(callee)) {
21148
+ if (Node15.isIdentifier(callee)) {
20088
21149
  collectFromSingleEntryFactory(callee.getText(), out, index);
20089
21150
  }
20090
21151
  continue;
@@ -20102,9 +21163,9 @@ function extractTaskServiceCalls(sources, index, trustedExternal) {
20102
21163
  const out = [];
20103
21164
  for (const sf of sources) {
20104
21165
  const rel = apiRelPath(sf);
20105
- for (const call of sf.getDescendantsOfKind(SyntaxKind9.CallExpression)) {
21166
+ for (const call of sf.getDescendantsOfKind(SyntaxKind10.CallExpression)) {
20106
21167
  const expr = call.getExpression();
20107
- if (!Node14.isIdentifier(expr) || expr.getText() !== TASK_SERVICE_FACTORY) continue;
21168
+ if (!Node15.isIdentifier(expr) || expr.getText() !== TASK_SERVICE_FACTORY) continue;
20108
21169
  const args = call.getArguments();
20109
21170
  const first = args[0] ? asObjectLiteral(args[0]) : void 0;
20110
21171
  if (!first) continue;
@@ -20130,13 +21191,13 @@ function collectValidateArrayElements(validateArr) {
20130
21191
  const spreads = [];
20131
21192
  if (!validateArr) return { ids, spreads };
20132
21193
  for (const el of validateArr.getElements()) {
20133
- if (Node14.isSpreadElement(el)) {
21194
+ if (Node15.isSpreadElement(el)) {
20134
21195
  const inner2 = el.getExpression();
20135
- if (Node14.isIdentifier(inner2)) spreads.push(inner2.getText());
21196
+ if (Node15.isIdentifier(inner2)) spreads.push(inner2.getText());
20136
21197
  continue;
20137
21198
  }
20138
21199
  const inner = unwrapAsExpressions(el);
20139
- if (inner && Node14.isIdentifier(inner)) ids.push(inner.getText());
21200
+ if (inner && Node15.isIdentifier(inner)) ids.push(inner.getText());
20140
21201
  }
20141
21202
  return { ids, spreads };
20142
21203
  }
@@ -20149,17 +21210,17 @@ function collectHandlersArrayElements(options) {
20149
21210
  if (!handlersArr) return { handlerTypes, unresolvedSpreads, resolvedBindings, unresolvedBindings };
20150
21211
  const visited = /* @__PURE__ */ new Set();
20151
21212
  for (const el of handlersArr.getElements()) {
20152
- if (Node14.isSpreadElement(el)) {
21213
+ if (Node15.isSpreadElement(el)) {
20153
21214
  consumeHandlersSpreadElement({ inner: el.getExpression(), sf, index, trustedExternal, unresolvedSpreads, resolvedBindings, unresolvedBindings, visited });
20154
21215
  continue;
20155
21216
  }
20156
21217
  const inner = unwrapAsExpressions(el);
20157
21218
  if (!inner) continue;
20158
- if (Node14.isIdentifier(inner)) {
21219
+ if (Node15.isIdentifier(inner)) {
20159
21220
  collectHandlerBindingsFromIdentifier({ name: inner.getText(), sf, index, trustedExternal, resolved: resolvedBindings, unresolved: unresolvedBindings, visited });
20160
- } else if (Node14.isCallExpression(inner)) {
21221
+ } else if (Node15.isCallExpression(inner)) {
20161
21222
  const callee = inner.getExpression();
20162
- if (Node14.isIdentifier(callee)) {
21223
+ if (Node15.isIdentifier(callee)) {
20163
21224
  collectHandlerBindingsFromIdentifier({ name: callee.getText(), sf, index, trustedExternal, resolved: resolvedBindings, unresolved: unresolvedBindings, visited });
20164
21225
  }
20165
21226
  }
@@ -20168,16 +21229,16 @@ function collectHandlersArrayElements(options) {
20168
21229
  }
20169
21230
  function consumeHandlersSpreadElement(options) {
20170
21231
  const { inner, sf, index, trustedExternal, unresolvedSpreads, resolvedBindings, unresolvedBindings, visited } = options;
20171
- if (Node14.isCallExpression(inner)) {
21232
+ if (Node15.isCallExpression(inner)) {
20172
21233
  const callee = inner.getExpression();
20173
- if (Node14.isIdentifier(callee)) {
21234
+ if (Node15.isIdentifier(callee)) {
20174
21235
  const name = callee.getText();
20175
21236
  unresolvedSpreads.push(name);
20176
21237
  collectHandlerBindingsFromIdentifier({ name, sf, index, trustedExternal, resolved: resolvedBindings, unresolved: unresolvedBindings, visited });
20177
21238
  }
20178
21239
  return;
20179
21240
  }
20180
- if (Node14.isIdentifier(inner)) {
21241
+ if (Node15.isIdentifier(inner)) {
20181
21242
  const name = inner.getText();
20182
21243
  unresolvedSpreads.push(name);
20183
21244
  collectHandlerBindingsFromIdentifier({ name, sf, index, trustedExternal, resolved: resolvedBindings, unresolved: unresolvedBindings, visited });
@@ -20187,13 +21248,13 @@ function collectHandlerBindingsFromValue(options) {
20187
21248
  const { node, sf, index, trustedExternal, resolved, unresolved, visited } = options;
20188
21249
  const inner = unwrapAsExpressions(node);
20189
21250
  if (!inner) return false;
20190
- if (Node14.isCallExpression(inner)) {
21251
+ if (Node15.isCallExpression(inner)) {
20191
21252
  const callee = inner.getExpression();
20192
- if (Node14.isIdentifier(callee)) {
21253
+ if (Node15.isIdentifier(callee)) {
20193
21254
  return collectHandlerBindingsFromIdentifier({ name: callee.getText(), sf, index, trustedExternal, resolved, unresolved, visited });
20194
21255
  }
20195
21256
  }
20196
- if (Node14.isIdentifier(inner)) {
21257
+ if (Node15.isIdentifier(inner)) {
20197
21258
  return collectHandlerBindingsFromIdentifier({ name: inner.getText(), sf, index, trustedExternal, resolved, unresolved, visited });
20198
21259
  }
20199
21260
  return false;
@@ -20210,7 +21271,7 @@ function collectHandlerBindingsFromIdentifier(options) {
20210
21271
  const typeText = typeNode ? typeNode.getText() : void 0;
20211
21272
  const isHandlerConfigTyped = typeText !== void 0 && (typeText === NOTIF_TASK_SERVICE_HANDLER_CONFIG || typeText.startsWith(`${NOTIF_TASK_SERVICE_HANDLER_CONFIG}<`));
20212
21273
  const declInit = unwrapAsExpressions(localDecl.getInitializer());
20213
- const isObjectLit = declInit !== void 0 && Node14.isObjectLiteralExpression(declInit);
21274
+ const isObjectLit = declInit !== void 0 && Node15.isObjectLiteralExpression(declInit);
20214
21275
  if (isHandlerConfigTyped && isObjectLit) {
20215
21276
  resolved.push(localDecl.getName());
20216
21277
  resolvedAny = true;
@@ -20241,12 +21302,12 @@ function collectHandlerBindingsFromIdentifier(options) {
20241
21302
  function resolveArrayFromProperty2(obj, name, sf) {
20242
21303
  const init = unwrapAsExpressions(getPropertyInitializer(obj, name));
20243
21304
  if (!init) return void 0;
20244
- if (Node14.isArrayLiteralExpression(init)) return init;
20245
- if (Node14.isIdentifier(init)) {
21305
+ if (Node15.isArrayLiteralExpression(init)) return init;
21306
+ if (Node15.isIdentifier(init)) {
20246
21307
  const declNode = findLocalVariable(sf, init.getText());
20247
21308
  if (declNode) {
20248
21309
  const declInit = unwrapAsExpressions(declNode.getInitializer());
20249
- if (declInit && Node14.isArrayLiteralExpression(declInit)) {
21310
+ if (declInit && Node15.isArrayLiteralExpression(declInit)) {
20250
21311
  return declInit;
20251
21312
  }
20252
21313
  }
@@ -20267,12 +21328,12 @@ function extractTaskHandlerEntries(sources) {
20267
21328
  if (!typeIdent) return;
20268
21329
  const flowInit = unwrapAsExpressions(getPropertyInitializer(obj, "flow"));
20269
21330
  let flowCount;
20270
- if (flowInit && Node14.isArrayLiteralExpression(flowInit)) {
21331
+ if (flowInit && Node15.isArrayLiteralExpression(flowInit)) {
20271
21332
  flowCount = flowInit.getElements().length;
20272
21333
  }
20273
21334
  let dataArg;
20274
21335
  let checkpointArg;
20275
- if (Node14.isTypeReference(typeNode)) {
21336
+ if (Node15.isTypeReference(typeNode)) {
20276
21337
  const tArgs = typeNode.getTypeArguments();
20277
21338
  if (tArgs.length >= 1) dataArg = tArgs[0].getText();
20278
21339
  if (tArgs.length >= 2) checkpointArg = tArgs[1].getText();
@@ -20292,7 +21353,7 @@ function extractTaskHandlerEntries(sources) {
20292
21353
  };
20293
21354
  for (const sf of sources) {
20294
21355
  const rel = apiRelPath(sf);
20295
- for (const decl of sf.getDescendantsOfKind(SyntaxKind9.VariableDeclaration)) {
21356
+ for (const decl of sf.getDescendantsOfKind(SyntaxKind10.VariableDeclaration)) {
20296
21357
  collectFromVariable(decl, rel);
20297
21358
  }
20298
21359
  }
@@ -21123,8 +22184,8 @@ function formatResult8(result) {
21123
22184
  }
21124
22185
 
21125
22186
  // packages/dbx-components-mcp/src/tools/system-m-validate-folder/inspect.ts
21126
- import { readdir as readdir5, readFile as readFile8, stat as stat7 } from "node:fs/promises";
21127
- import { basename as basename5, join as join8 } from "node:path";
22187
+ import { readdir as readdir5, readFile as readFile10, stat as stat7 } from "node:fs/promises";
22188
+ import { basename as basename5, join as join9 } from "node:path";
21128
22189
  async function inspectFolder2(path) {
21129
22190
  const name = basename5(path);
21130
22191
  let status;
@@ -21144,7 +22205,7 @@ async function inspectFolder2(path) {
21144
22205
  files = collected;
21145
22206
  if (collected.includes("system.ts")) {
21146
22207
  try {
21147
- systemSource = await readFile8(join8(path, "system.ts"), "utf8");
22208
+ systemSource = await readFile10(join9(path, "system.ts"), "utf8");
21148
22209
  } catch {
21149
22210
  systemSource = void 0;
21150
22211
  }
@@ -21165,14 +22226,14 @@ async function inspectFolder2(path) {
21165
22226
  }
21166
22227
 
21167
22228
  // packages/dbx-components-mcp/src/tools/system-m-validate-folder/extract.ts
21168
- import { Node as Node15, Project as Project10 } from "ts-morph";
22229
+ import { Node as Node16, Project as Project11 } from "ts-morph";
21169
22230
  var TYPE_CONSTANT_SUFFIX = "_SYSTEM_STATE_TYPE";
21170
22231
  var DATA_INTERFACE_SUFFIX = "SystemData";
21171
22232
  var CONVERTER_CONFIG_TYPE = "SystemStateStoredDataFieldConverterConfig";
21172
22233
  var CONVERTER_MAP_TYPE = "SystemStateStoredDataConverterMap";
21173
22234
  var SYSTEM_STATE_STORED_DATA = "SystemStateStoredData";
21174
22235
  function extractSystemFile(name, text) {
21175
- const project = new Project10({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
22236
+ const project = new Project11({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
21176
22237
  const sourceFile = project.createSourceFile(name, text, { overwrite: true });
21177
22238
  const typeConstants = findTypeConstants(sourceFile);
21178
22239
  const dataInterfaces = findDataInterfaces2(sourceFile);
@@ -21229,7 +22290,7 @@ function findDataInterfaces2(sourceFile) {
21229
22290
  return out;
21230
22291
  }
21231
22292
  function extendsSystemStateStoredData(iface) {
21232
- if (!Node15.isInterfaceDeclaration(iface)) return false;
22293
+ if (!Node16.isInterfaceDeclaration(iface)) return false;
21233
22294
  for (const clause of iface.getExtends()) {
21234
22295
  const text = clause.getText();
21235
22296
  if (text === SYSTEM_STATE_STORED_DATA || text.startsWith(`${SYSTEM_STATE_STORED_DATA}<`) || text === `${SYSTEM_STATE_STORED_DATA}, ${SYSTEM_STATE_STORED_DATA}`) {
@@ -21249,14 +22310,14 @@ function findConverters2(sourceFile) {
21249
22310
  for (const decl of stmt.getDeclarations()) {
21250
22311
  const typeNode = decl.getTypeNode();
21251
22312
  if (!typeNode) continue;
21252
- if (!Node15.isTypeReference(typeNode)) continue;
22313
+ if (!Node16.isTypeReference(typeNode)) continue;
21253
22314
  const typeName = typeNode.getTypeName().getText();
21254
22315
  if (typeName !== CONVERTER_CONFIG_TYPE) continue;
21255
22316
  const typeArgs = typeNode.getTypeArguments();
21256
22317
  let dataTypeArgument;
21257
22318
  if (typeArgs.length >= 1) {
21258
22319
  const arg = typeArgs[0];
21259
- if (Node15.isTypeReference(arg)) {
22320
+ if (Node16.isTypeReference(arg)) {
21260
22321
  dataTypeArgument = arg.getTypeName().getText();
21261
22322
  } else {
21262
22323
  dataTypeArgument = arg.getText();
@@ -21303,19 +22364,19 @@ function collectConverterMapKeys(decl) {
21303
22364
  if (!obj) return [];
21304
22365
  const out = [];
21305
22366
  for (const prop of obj.getProperties()) {
21306
- if (!Node15.isPropertyAssignment(prop)) continue;
22367
+ if (!Node16.isPropertyAssignment(prop)) continue;
21307
22368
  const nameNode = prop.getNameNode();
21308
22369
  const line = prop.getStartLineNumber();
21309
- if (Node15.isComputedPropertyName(nameNode)) {
22370
+ if (Node16.isComputedPropertyName(nameNode)) {
21310
22371
  const inner = nameNode.getExpression();
21311
22372
  out.push({ raw: inner.getText(), kind: "identifier", line });
21312
22373
  continue;
21313
22374
  }
21314
- if (Node15.isStringLiteral(nameNode)) {
22375
+ if (Node16.isStringLiteral(nameNode)) {
21315
22376
  out.push({ raw: nameNode.getLiteralText(), kind: "string", line });
21316
22377
  continue;
21317
22378
  }
21318
- if (Node15.isIdentifier(nameNode)) {
22379
+ if (Node16.isIdentifier(nameNode)) {
21319
22380
  out.push({ raw: nameNode.getText(), kind: "string", line });
21320
22381
  continue;
21321
22382
  }
@@ -21325,10 +22386,10 @@ function collectConverterMapKeys(decl) {
21325
22386
  }
21326
22387
  function unwrapObjectLiteral(node) {
21327
22388
  let current = node;
21328
- while (current && Node15.isAsExpression(current)) {
22389
+ while (current && Node16.isAsExpression(current)) {
21329
22390
  current = current.getExpression();
21330
22391
  }
21331
- if (current && Node15.isObjectLiteralExpression(current)) {
22392
+ if (current && Node16.isObjectLiteralExpression(current)) {
21332
22393
  return current;
21333
22394
  }
21334
22395
  return void 0;
@@ -21362,10 +22423,10 @@ function findLastTopLevelExportLine(sourceFile) {
21362
22423
  return last;
21363
22424
  }
21364
22425
  function isExportedTopLevel(stmt) {
21365
- if (Node15.isVariableStatement(stmt) || Node15.isFunctionDeclaration(stmt) || Node15.isClassDeclaration(stmt) || Node15.isInterfaceDeclaration(stmt) || Node15.isTypeAliasDeclaration(stmt) || Node15.isEnumDeclaration(stmt)) {
22426
+ if (Node16.isVariableStatement(stmt) || Node16.isFunctionDeclaration(stmt) || Node16.isClassDeclaration(stmt) || Node16.isInterfaceDeclaration(stmt) || Node16.isTypeAliasDeclaration(stmt) || Node16.isEnumDeclaration(stmt)) {
21366
22427
  return stmt.isExported();
21367
22428
  }
21368
- if (Node15.isExportDeclaration(stmt) || Node15.isExportAssignment(stmt)) {
22429
+ if (Node16.isExportDeclaration(stmt) || Node16.isExportAssignment(stmt)) {
21369
22430
  return true;
21370
22431
  }
21371
22432
  return false;
@@ -21676,7 +22737,7 @@ var systemMValidateFolderTool = createFolderValidateTool({
21676
22737
  });
21677
22738
 
21678
22739
  // packages/dbx-components-mcp/src/tools/lookup-action.tool.ts
21679
- import { type as type37 } from "arktype";
22740
+ import { type as type39 } from "arktype";
21680
22741
  var DBX_ACTION_LOOKUP_TOOL = {
21681
22742
  name: "dbx_action_lookup",
21682
22743
  description: [
@@ -21709,13 +22770,13 @@ var DBX_ACTION_LOOKUP_TOOL = {
21709
22770
  required: ["topic"]
21710
22771
  }
21711
22772
  };
21712
- var LookupActionArgsType = type37({
22773
+ var LookupActionArgsType = type39({
21713
22774
  topic: "string",
21714
22775
  "depth?": "'brief' | 'full'"
21715
22776
  });
21716
22777
  function parseLookupActionArgs(raw) {
21717
22778
  const parsed = LookupActionArgsType(raw);
21718
- if (parsed instanceof type37.errors) {
22779
+ if (parsed instanceof type39.errors) {
21719
22780
  throw new TypeError(`Invalid arguments: ${parsed.summary}`);
21720
22781
  }
21721
22782
  const result = {
@@ -21982,7 +23043,7 @@ function code6(value) {
21982
23043
  }
21983
23044
  function createLookupActionTool(input) {
21984
23045
  const { registry } = input;
21985
- const run10 = (rawArgs) => {
23046
+ const run12 = (rawArgs) => {
21986
23047
  let args;
21987
23048
  try {
21988
23049
  args = parseLookupActionArgs(rawArgs);
@@ -22009,11 +23070,11 @@ function createLookupActionTool(input) {
22009
23070
  const result = { content: [{ type: "text", text }] };
22010
23071
  return result;
22011
23072
  };
22012
- return { definition: DBX_ACTION_LOOKUP_TOOL, run: run10 };
23073
+ return { definition: DBX_ACTION_LOOKUP_TOOL, run: run12 };
22013
23074
  }
22014
23075
 
22015
23076
  // packages/dbx-components-mcp/src/tools/action-examples.tool.ts
22016
- import { type as type38 } from "arktype";
23077
+ import { type as type40 } from "arktype";
22017
23078
 
22018
23079
  // packages/dbx-components-mcp/src/tools/data/patterns/actions/action.auto-trigger-on-modify.pattern.ts
22019
23080
  var ACTION_PATTERN_AUTO_TRIGGER_ON_MODIFY = {
@@ -22373,13 +23434,13 @@ var DBX_ACTION_EXAMPLES_TOOL = {
22373
23434
  required: ["pattern"]
22374
23435
  }
22375
23436
  };
22376
- var ActionExamplesArgsType = type38({
23437
+ var ActionExamplesArgsType = type40({
22377
23438
  pattern: "string",
22378
23439
  "depth?": "'minimal' | 'brief' | 'full'"
22379
23440
  });
22380
23441
  function parseActionExamplesArgs(raw) {
22381
23442
  const parsed = ActionExamplesArgsType(raw);
22382
- if (parsed instanceof type38.errors) {
23443
+ if (parsed instanceof type40.errors) {
22383
23444
  throw new TypeError(`Invalid arguments: ${parsed.summary}`);
22384
23445
  }
22385
23446
  const result = {
@@ -22441,7 +23502,7 @@ var actionExamplesTool = {
22441
23502
  };
22442
23503
 
22443
23504
  // packages/dbx-components-mcp/src/tools/action-scaffold.tool.ts
22444
- import { type as type39 } from "arktype";
23505
+ import { type as type41 } from "arktype";
22445
23506
  var TRIGGER_VALUES = ["button", "form", "auto-modify"];
22446
23507
  var SUCCESS_FEEDBACK_VALUES = ["snackbar", "redirect", "none"];
22447
23508
  var CONTEXT_PROVIDER_VALUES = ["inline", "parent", "host-component"];
@@ -22475,7 +23536,7 @@ var DBX_ACTION_SCAFFOLD_TOOL = {
22475
23536
  required: ["use_case", "trigger", "value_type"]
22476
23537
  }
22477
23538
  };
22478
- var ScaffoldArgsType4 = type39({
23539
+ var ScaffoldArgsType4 = type41({
22479
23540
  use_case: "string",
22480
23541
  trigger: "'button' | 'form' | 'auto-modify'",
22481
23542
  "confirm?": "boolean",
@@ -22486,7 +23547,7 @@ var ScaffoldArgsType4 = type39({
22486
23547
  });
22487
23548
  function parseScaffoldArgs2(raw) {
22488
23549
  const parsed = ScaffoldArgsType4(raw);
22489
- if (parsed instanceof type39.errors) {
23550
+ if (parsed instanceof type41.errors) {
22490
23551
  throw new TypeError(`Invalid arguments: ${parsed.summary}`);
22491
23552
  }
22492
23553
  const useCase = parsed.use_case.trim();
@@ -22692,16 +23753,16 @@ var actionScaffoldTool = {
22692
23753
  };
22693
23754
 
22694
23755
  // packages/dbx-components-mcp/src/tools/route-tree.tool.ts
22695
- import { type as type40 } from "arktype";
23756
+ import { type as type42 } from "arktype";
22696
23757
 
22697
23758
  // packages/dbx-components-mcp/src/tools/route/load-sources.ts
22698
- import { glob as fsGlob4, readFile as readFile9, stat as stat8 } from "node:fs/promises";
22699
- import { dirname as dirname7, isAbsolute as isAbsolute7, resolve as resolve22, sep as sep5 } from "node:path";
23759
+ import { glob as fsGlob4, readFile as readFile11, stat as stat8 } from "node:fs/promises";
23760
+ import { dirname as dirname7, isAbsolute as isAbsolute7, resolve as resolve24, sep as sep5 } from "node:path";
22700
23761
 
22701
23762
  // packages/dbx-components-mcp/src/tools/route/extract.ts
22702
- import { Node as Node16, Project as Project11, SyntaxKind as SyntaxKind10 } from "ts-morph";
23763
+ import { Node as Node17, Project as Project12, SyntaxKind as SyntaxKind11 } from "ts-morph";
22703
23764
  function extractFile3(source) {
22704
- const project = new Project11({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
23765
+ const project = new Project12({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
22705
23766
  const sourceFile = project.createSourceFile(source.name, source.text, { overwrite: true });
22706
23767
  const issues = [];
22707
23768
  const objectLiteralsByName = collectStateConsts(sourceFile);
@@ -22714,9 +23775,9 @@ function extractFile3(source) {
22714
23775
  }
22715
23776
  for (const arrayLit of findStateArrayLiterals(sourceFile)) {
22716
23777
  for (const element of arrayLit.getElements()) {
22717
- if (Node16.isObjectLiteralExpression(element)) {
23778
+ if (Node17.isObjectLiteralExpression(element)) {
22718
23779
  addNode({ file: source.name, literal: element, fallbackConstName: void 0, into: collected, issues });
22719
- } else if (Node16.isIdentifier(element)) {
23780
+ } else if (Node17.isIdentifier(element)) {
22720
23781
  const ref = objectLiteralsByName.get(element.getText());
22721
23782
  if (ref) {
22722
23783
  addNode({ file: source.name, literal: ref.literal, fallbackConstName: element.getText(), into: collected, issues });
@@ -22737,7 +23798,7 @@ function collectStateConsts(sourceFile) {
22737
23798
  for (const stmt of sourceFile.getVariableStatements()) {
22738
23799
  for (const decl of stmt.getDeclarations()) {
22739
23800
  const initializer = decl.getInitializer();
22740
- if (!initializer || !Node16.isObjectLiteralExpression(initializer)) {
23801
+ if (!initializer || !Node17.isObjectLiteralExpression(initializer)) {
22741
23802
  continue;
22742
23803
  }
22743
23804
  const typeNode = decl.getTypeNode();
@@ -22752,12 +23813,12 @@ function findStateArrayLiterals(sourceFile) {
22752
23813
  for (const stmt of sourceFile.getVariableStatements()) {
22753
23814
  for (const decl of stmt.getDeclarations()) {
22754
23815
  const initializer = decl.getInitializer();
22755
- if (initializer && Node16.isArrayLiteralExpression(initializer) && declarationIsStateArray(stmt, decl.getName(), initializer)) {
23816
+ if (initializer && Node17.isArrayLiteralExpression(initializer) && declarationIsStateArray(stmt, decl.getName(), initializer)) {
22756
23817
  arrays.push(initializer);
22757
23818
  }
22758
23819
  }
22759
23820
  }
22760
- for (const call of sourceFile.getDescendantsOfKind(SyntaxKind10.CallExpression)) {
23821
+ for (const call of sourceFile.getDescendantsOfKind(SyntaxKind11.CallExpression)) {
22761
23822
  const expr = call.getExpression();
22762
23823
  const exprText = expr.getText();
22763
23824
  const isProvide = exprText === "provideStates";
@@ -22766,17 +23827,17 @@ function findStateArrayLiterals(sourceFile) {
22766
23827
  continue;
22767
23828
  }
22768
23829
  for (const arg of call.getArguments()) {
22769
- if (!Node16.isObjectLiteralExpression(arg)) {
23830
+ if (!Node17.isObjectLiteralExpression(arg)) {
22770
23831
  continue;
22771
23832
  }
22772
23833
  const statesProp = arg.getProperty("states");
22773
- if (!statesProp || !Node16.isPropertyAssignment(statesProp)) {
23834
+ if (!statesProp || !Node17.isPropertyAssignment(statesProp)) {
22774
23835
  continue;
22775
23836
  }
22776
23837
  const initializer = statesProp.getInitializer();
22777
- if (initializer && Node16.isArrayLiteralExpression(initializer)) {
23838
+ if (initializer && Node17.isArrayLiteralExpression(initializer)) {
22778
23839
  arrays.push(initializer);
22779
- } else if (initializer && Node16.isIdentifier(initializer)) {
23840
+ } else if (initializer && Node17.isIdentifier(initializer)) {
22780
23841
  const referenced = findArrayLiteralForIdentifier(sourceFile, initializer);
22781
23842
  if (referenced) {
22782
23843
  arrays.push(referenced);
@@ -22793,10 +23854,10 @@ function declarationIsStateArray(stmt, name, literal) {
22793
23854
  return true;
22794
23855
  }
22795
23856
  for (const element of literal.getElements()) {
22796
- if (Node16.isObjectLiteralExpression(element) && hasStringNameProperty(element)) {
23857
+ if (Node17.isObjectLiteralExpression(element) && hasStringNameProperty(element)) {
22797
23858
  return true;
22798
23859
  }
22799
- if (Node16.isIdentifier(element)) {
23860
+ if (Node17.isIdentifier(element)) {
22800
23861
  return true;
22801
23862
  }
22802
23863
  }
@@ -22804,11 +23865,11 @@ function declarationIsStateArray(stmt, name, literal) {
22804
23865
  }
22805
23866
  function hasStringNameProperty(literal) {
22806
23867
  const nameProp = literal.getProperty("name");
22807
- if (!nameProp || !Node16.isPropertyAssignment(nameProp)) {
23868
+ if (!nameProp || !Node17.isPropertyAssignment(nameProp)) {
22808
23869
  return false;
22809
23870
  }
22810
23871
  const initializer = nameProp.getInitializer();
22811
- return initializer !== void 0 && (Node16.isStringLiteral(initializer) || Node16.isNoSubstitutionTemplateLiteral(initializer));
23872
+ return initializer !== void 0 && (Node17.isStringLiteral(initializer) || Node17.isNoSubstitutionTemplateLiteral(initializer));
22812
23873
  }
22813
23874
  function findArrayLiteralForIdentifier(sourceFile, identifier) {
22814
23875
  const name = identifier.getText();
@@ -22818,7 +23879,7 @@ function findArrayLiteralForIdentifier(sourceFile, identifier) {
22818
23879
  continue;
22819
23880
  }
22820
23881
  const initializer = decl.getInitializer();
22821
- if (initializer && Node16.isArrayLiteralExpression(initializer)) {
23882
+ if (initializer && Node17.isArrayLiteralExpression(initializer)) {
22822
23883
  return initializer;
22823
23884
  }
22824
23885
  }
@@ -22868,64 +23929,64 @@ function addNode(options) {
22868
23929
  }
22869
23930
  function stringPropertyValue(literal, key) {
22870
23931
  const prop = literal.getProperty(key);
22871
- if (!prop || !Node16.isPropertyAssignment(prop)) {
23932
+ if (!prop || !Node17.isPropertyAssignment(prop)) {
22872
23933
  return void 0;
22873
23934
  }
22874
23935
  const initializer = prop.getInitializer();
22875
23936
  if (!initializer) {
22876
23937
  return void 0;
22877
23938
  }
22878
- if (Node16.isStringLiteral(initializer) || Node16.isNoSubstitutionTemplateLiteral(initializer)) {
23939
+ if (Node17.isStringLiteral(initializer) || Node17.isNoSubstitutionTemplateLiteral(initializer)) {
22879
23940
  return initializer.getLiteralText();
22880
23941
  }
22881
23942
  return void 0;
22882
23943
  }
22883
23944
  function booleanPropertyValue(literal, key) {
22884
23945
  const prop = literal.getProperty(key);
22885
- if (!prop || !Node16.isPropertyAssignment(prop)) {
23946
+ if (!prop || !Node17.isPropertyAssignment(prop)) {
22886
23947
  return void 0;
22887
23948
  }
22888
23949
  const initializer = prop.getInitializer();
22889
23950
  if (!initializer) {
22890
23951
  return void 0;
22891
23952
  }
22892
- if (initializer.getKind() === SyntaxKind10.TrueKeyword) {
23953
+ if (initializer.getKind() === SyntaxKind11.TrueKeyword) {
22893
23954
  return true;
22894
23955
  }
22895
- if (initializer.getKind() === SyntaxKind10.FalseKeyword) {
23956
+ if (initializer.getKind() === SyntaxKind11.FalseKeyword) {
22896
23957
  return false;
22897
23958
  }
22898
23959
  return void 0;
22899
23960
  }
22900
23961
  function identifierPropertyValue(literal, key) {
22901
23962
  const prop = literal.getProperty(key);
22902
- if (!prop || !Node16.isPropertyAssignment(prop)) {
23963
+ if (!prop || !Node17.isPropertyAssignment(prop)) {
22903
23964
  return void 0;
22904
23965
  }
22905
23966
  const initializer = prop.getInitializer();
22906
23967
  if (!initializer) {
22907
23968
  return void 0;
22908
23969
  }
22909
- if (Node16.isIdentifier(initializer)) {
23970
+ if (Node17.isIdentifier(initializer)) {
22910
23971
  return initializer.getText();
22911
23972
  }
22912
- if (Node16.isPropertyAccessExpression(initializer)) {
23973
+ if (Node17.isPropertyAccessExpression(initializer)) {
22913
23974
  return initializer.getText();
22914
23975
  }
22915
23976
  return void 0;
22916
23977
  }
22917
23978
  function objectPropertyKeys(literal, key) {
22918
23979
  const prop = literal.getProperty(key);
22919
- if (!prop || !Node16.isPropertyAssignment(prop)) {
23980
+ if (!prop || !Node17.isPropertyAssignment(prop)) {
22920
23981
  return [];
22921
23982
  }
22922
23983
  const initializer = prop.getInitializer();
22923
- if (!initializer || !Node16.isObjectLiteralExpression(initializer)) {
23984
+ if (!initializer || !Node17.isObjectLiteralExpression(initializer)) {
22924
23985
  return [];
22925
23986
  }
22926
23987
  const out = [];
22927
23988
  for (const member of initializer.getProperties()) {
22928
- if (Node16.isPropertyAssignment(member) || Node16.isShorthandPropertyAssignment(member) || Node16.isMethodDeclaration(member)) {
23989
+ if (Node17.isPropertyAssignment(member) || Node17.isShorthandPropertyAssignment(member) || Node17.isMethodDeclaration(member)) {
22929
23990
  const nameNode = member.getNameNode();
22930
23991
  if (nameNode) {
22931
23992
  out.push(nameNode.getText());
@@ -22936,7 +23997,7 @@ function objectPropertyKeys(literal, key) {
22936
23997
  }
22937
23998
  function collectResolveKeys(literal) {
22938
23999
  const prop = literal.getProperty("resolve");
22939
- if (!prop || !Node16.isPropertyAssignment(prop)) {
24000
+ if (!prop || !Node17.isPropertyAssignment(prop)) {
22940
24001
  return [];
22941
24002
  }
22942
24003
  const initializer = prop.getInitializer();
@@ -22944,22 +24005,22 @@ function collectResolveKeys(literal) {
22944
24005
  return [];
22945
24006
  }
22946
24007
  const keys = [];
22947
- if (Node16.isObjectLiteralExpression(initializer)) {
24008
+ if (Node17.isObjectLiteralExpression(initializer)) {
22948
24009
  for (const member of initializer.getProperties()) {
22949
- if (Node16.isPropertyAssignment(member) || Node16.isShorthandPropertyAssignment(member) || Node16.isMethodDeclaration(member)) {
24010
+ if (Node17.isPropertyAssignment(member) || Node17.isShorthandPropertyAssignment(member) || Node17.isMethodDeclaration(member)) {
22950
24011
  const nameNode = member.getNameNode();
22951
24012
  if (nameNode) {
22952
24013
  keys.push(nameNode.getText());
22953
24014
  }
22954
24015
  }
22955
24016
  }
22956
- } else if (Node16.isArrayLiteralExpression(initializer)) {
24017
+ } else if (Node17.isArrayLiteralExpression(initializer)) {
22957
24018
  for (const element of initializer.getElements()) {
22958
- if (Node16.isObjectLiteralExpression(element)) {
24019
+ if (Node17.isObjectLiteralExpression(element)) {
22959
24020
  const tokenProp = element.getProperty("token");
22960
- if (tokenProp && Node16.isPropertyAssignment(tokenProp)) {
24021
+ if (tokenProp && Node17.isPropertyAssignment(tokenProp)) {
22961
24022
  const tokenInit = tokenProp.getInitializer();
22962
- if (tokenInit && (Node16.isStringLiteral(tokenInit) || Node16.isIdentifier(tokenInit))) {
24023
+ if (tokenInit && (Node17.isStringLiteral(tokenInit) || Node17.isIdentifier(tokenInit))) {
22963
24024
  keys.push(tokenInit.getText().replaceAll(/^['"]|['"]$/g, ""));
22964
24025
  }
22965
24026
  }
@@ -23011,7 +24072,7 @@ function computeRelativeSpecifiers(source) {
23011
24072
  // packages/dbx-components-mcp/src/tools/route/load-sources.ts
23012
24073
  var TRY_EXTENSIONS = [".ts", ".tsx", "/index.ts", "/index.tsx"];
23013
24074
  async function loadRouteSources(args) {
23014
- const cwdResolved = args.cwd ? resolve22(process.cwd(), args.cwd) : process.cwd();
24075
+ const cwdResolved = args.cwd ? resolve24(process.cwd(), args.cwd) : process.cwd();
23015
24076
  guardCwdInsideServer(args.cwd, cwdResolved);
23016
24077
  const collected = /* @__PURE__ */ new Map();
23017
24078
  if (args.sources) {
@@ -23083,21 +24144,21 @@ async function loadOne(relative13, cwd, into) {
23083
24144
  if (into.has(relative13)) {
23084
24145
  return;
23085
24146
  }
23086
- const absolute = resolve22(cwd, relative13);
24147
+ const absolute = resolve24(cwd, relative13);
23087
24148
  const cwdPrefix = cwd.endsWith(sep5) ? cwd : cwd + sep5;
23088
24149
  if (!absolute.startsWith(cwdPrefix) && absolute !== cwd) {
23089
24150
  throw new Error(`Path \`${relative13}\` resolves outside the server cwd and is not allowed.`);
23090
24151
  }
23091
- const text = await readFile9(absolute, "utf8");
24152
+ const text = await readFile11(absolute, "utf8");
23092
24153
  into.set(relative13, { name: relative13, text });
23093
24154
  }
23094
24155
  async function resolveRelativeImport(fromFile, specifier, cwd) {
23095
24156
  if (!specifier.startsWith(".")) {
23096
24157
  return void 0;
23097
24158
  }
23098
- const fromAbsolute = isAbsolute7(fromFile) ? fromFile : resolve22(cwd, fromFile);
24159
+ const fromAbsolute = isAbsolute7(fromFile) ? fromFile : resolve24(cwd, fromFile);
23099
24160
  const fromDir = dirname7(fromAbsolute);
23100
- const baseAbsolute = resolve22(fromDir, specifier);
24161
+ const baseAbsolute = resolve24(fromDir, specifier);
23101
24162
  const cwdPrefix = cwd.endsWith(sep5) ? cwd : cwd + sep5;
23102
24163
  for (const ext of TRY_EXTENSIONS) {
23103
24164
  const candidateAbsolute = baseAbsolute + ext;
@@ -23108,7 +24169,7 @@ async function resolveRelativeImport(fromFile, specifier, cwd) {
23108
24169
  if (!exists) {
23109
24170
  continue;
23110
24171
  }
23111
- const text = await readFile9(candidateAbsolute, "utf8");
24172
+ const text = await readFile11(candidateAbsolute, "utf8");
23112
24173
  const relativeName = candidateAbsolute.startsWith(cwdPrefix) ? candidateAbsolute.slice(cwdPrefix.length) : candidateAbsolute;
23113
24174
  const result = { name: relativeName, text };
23114
24175
  return result;
@@ -23476,8 +24537,8 @@ var DBX_ROUTE_TREE_TOOL = {
23476
24537
  }
23477
24538
  }
23478
24539
  };
23479
- var TreeArgsType = type40({
23480
- "sources?": type40({ name: "string", text: "string" }).array(),
24540
+ var TreeArgsType2 = type42({
24541
+ "sources?": type42({ name: "string", text: "string" }).array(),
23481
24542
  "paths?": "string[]",
23482
24543
  "glob?": "string",
23483
24544
  "format?": "'markdown' | 'json' | 'flat'",
@@ -23485,8 +24546,8 @@ var TreeArgsType = type40({
23485
24546
  "cwd?": "string"
23486
24547
  });
23487
24548
  function parseArgs4(raw) {
23488
- const parsed = TreeArgsType(raw);
23489
- if (parsed instanceof type40.errors) {
24549
+ const parsed = TreeArgsType2(raw);
24550
+ if (parsed instanceof type42.errors) {
23490
24551
  throw new TypeError(`Invalid arguments: ${parsed.summary}`);
23491
24552
  }
23492
24553
  const result = {
@@ -23536,7 +24597,7 @@ var routeTreeTool = {
23536
24597
  };
23537
24598
 
23538
24599
  // packages/dbx-components-mcp/src/tools/route-lookup.tool.ts
23539
- import { type as type41 } from "arktype";
24600
+ import { type as type43 } from "arktype";
23540
24601
  var DBX_ROUTE_LOOKUP_TOOL = {
23541
24602
  name: "dbx_route_lookup",
23542
24603
  description: ["Look up a single UIRouter state by name, full URL, or component class name. Returns the state's URL, component, parent chain, params, resolves, siblings, and children.", "", "Provide at least one of `sources` / `paths` / `glob` to point the tool at the source set, plus a `topic`.", "", "Resolution order: exact state name \u2192 URL path \u2192 component class name \u2192 fuzzy substring (returns up to 5 candidates)."].join("\n"),
@@ -23561,9 +24622,9 @@ var DBX_ROUTE_LOOKUP_TOOL = {
23561
24622
  required: ["topic"]
23562
24623
  }
23563
24624
  };
23564
- var LookupArgsType2 = type41({
24625
+ var LookupArgsType2 = type43({
23565
24626
  topic: "string",
23566
- "sources?": type41({ name: "string", text: "string" }).array(),
24627
+ "sources?": type43({ name: "string", text: "string" }).array(),
23567
24628
  "paths?": "string[]",
23568
24629
  "glob?": "string",
23569
24630
  "depth?": "'brief' | 'full'",
@@ -23571,7 +24632,7 @@ var LookupArgsType2 = type41({
23571
24632
  });
23572
24633
  function parseArgs5(raw) {
23573
24634
  const parsed = LookupArgsType2(raw);
23574
- if (parsed instanceof type41.errors) {
24635
+ if (parsed instanceof type43.errors) {
23575
24636
  throw new TypeError(`Invalid arguments: ${parsed.summary}`);
23576
24637
  }
23577
24638
  const result = {
@@ -23764,7 +24825,7 @@ var routeLookupTool = {
23764
24825
  };
23765
24826
 
23766
24827
  // packages/dbx-components-mcp/src/tools/route-search.tool.ts
23767
- import { type as type42 } from "arktype";
24828
+ import { type as type44 } from "arktype";
23768
24829
  var DBX_ROUTE_SEARCH_TOOL = {
23769
24830
  name: "dbx_route_search",
23770
24831
  description: ["Search the UIRouter state tree of a dbx-components app. Matches against state names, full URLs, component class names, resolve keys, and source-file paths. Returns the top 10 results with state name, URL, component, and source location.", "", "Provide at least one of `sources` / `paths` / `glob` plus a `query`. `scope` narrows to a single axis (`name`, `url`, `component`, `resolve`)."].join("\n"),
@@ -23788,17 +24849,17 @@ var DBX_ROUTE_SEARCH_TOOL = {
23788
24849
  required: ["query"]
23789
24850
  }
23790
24851
  };
23791
- var SearchArgsType2 = type42({
24852
+ var SearchArgsType3 = type44({
23792
24853
  query: "string",
23793
- "sources?": type42({ name: "string", text: "string" }).array(),
24854
+ "sources?": type44({ name: "string", text: "string" }).array(),
23794
24855
  "paths?": "string[]",
23795
24856
  "glob?": "string",
23796
24857
  "scope?": "'name' | 'url' | 'component' | 'resolve' | 'all'",
23797
24858
  "cwd?": "string"
23798
24859
  });
23799
24860
  function parseArgs6(raw) {
23800
- const parsed = SearchArgsType2(raw);
23801
- if (parsed instanceof type42.errors) {
24861
+ const parsed = SearchArgsType3(raw);
24862
+ if (parsed instanceof type44.errors) {
23802
24863
  throw new TypeError(`Invalid arguments: ${parsed.summary}`);
23803
24864
  }
23804
24865
  const result = {
@@ -23891,14 +24952,14 @@ var routeSearchTool = {
23891
24952
  };
23892
24953
 
23893
24954
  // packages/dbx-components-mcp/src/tools/_lookup.factory.ts
23894
- import { type as type43 } from "arktype";
23895
- var LOOKUP_ARGS_TYPE = type43({
24955
+ import { type as type45 } from "arktype";
24956
+ var LOOKUP_ARGS_TYPE = type45({
23896
24957
  topic: "string",
23897
24958
  "depth?": "'brief' | 'full'"
23898
24959
  });
23899
24960
  function parseLookupArgs(raw) {
23900
24961
  const parsed = LOOKUP_ARGS_TYPE(raw);
23901
- if (parsed instanceof type43.errors) {
24962
+ if (parsed instanceof type45.errors) {
23902
24963
  throw new TypeError(`Invalid arguments: ${parsed.summary}`);
23903
24964
  }
23904
24965
  const result = {
@@ -24100,7 +25161,7 @@ function createLookupFilterTool(input) {
24100
25161
  }
24101
25162
 
24102
25163
  // packages/dbx-components-mcp/src/tools/filter-scaffold.tool.ts
24103
- import { type as type44 } from "arktype";
25164
+ import { type as type46 } from "arktype";
24104
25165
  var DBX_FILTER_SCAFFOLD_TOOL = {
24105
25166
  name: "dbx_filter_scaffold",
24106
25167
  description: [
@@ -24125,7 +25186,7 @@ var DBX_FILTER_SCAFFOLD_TOOL = {
24125
25186
  required: ["model_name", "filter_type"]
24126
25187
  }
24127
25188
  };
24128
- var ScaffoldArgsType5 = type44({
25189
+ var ScaffoldArgsType5 = type46({
24129
25190
  model_name: "string",
24130
25191
  filter_type: "string",
24131
25192
  "preset_keys?": "string[]",
@@ -24133,7 +25194,7 @@ var ScaffoldArgsType5 = type44({
24133
25194
  });
24134
25195
  function parseArgs7(raw) {
24135
25196
  const parsed = ScaffoldArgsType5(raw);
24136
- if (parsed instanceof type44.errors) {
25197
+ if (parsed instanceof type46.errors) {
24137
25198
  throw new TypeError(`Invalid arguments: ${parsed.summary}`);
24138
25199
  }
24139
25200
  const modelName = parsed.model_name.trim();
@@ -24373,8 +25434,8 @@ function createLookupPipeTool(input) {
24373
25434
 
24374
25435
  // packages/dbx-components-mcp/src/tools/artifact-scaffold.tool.ts
24375
25436
  import { access } from "node:fs/promises";
24376
- import { resolve as resolve23, sep as sep6 } from "node:path";
24377
- import { type as type45 } from "arktype";
25437
+ import { resolve as resolve25, sep as sep6 } from "node:path";
25438
+ import { type as type47 } from "arktype";
24378
25439
 
24379
25440
  // packages/dbx-components-mcp/src/tools/artifact-scaffold/templates.ts
24380
25441
  function splitWords(input) {
@@ -24922,7 +25983,7 @@ var DBX_ARTIFACT_SCAFFOLD_TOOL = {
24922
25983
  required: ["artifact", "name", "componentDir", "apiDir"]
24923
25984
  }
24924
25985
  };
24925
- var ScaffoldArtifactArgsType = type45({
25986
+ var ScaffoldArtifactArgsType = type47({
24926
25987
  artifact: ARTIFACT_KIND_LITERAL_UNION,
24927
25988
  name: "string",
24928
25989
  componentDir: "string",
@@ -24935,7 +25996,7 @@ var ScaffoldArtifactArgsType = type45({
24935
25996
  });
24936
25997
  function parseArgs8(raw) {
24937
25998
  const parsed = ScaffoldArtifactArgsType(raw);
24938
- if (parsed instanceof type45.errors) {
25999
+ if (parsed instanceof type47.errors) {
24939
26000
  throw new TypeError(`Invalid arguments: ${parsed.summary}`);
24940
26001
  }
24941
26002
  const result = {
@@ -24948,7 +26009,7 @@ function parseArgs8(raw) {
24948
26009
  return result;
24949
26010
  }
24950
26011
  function ensureInsideCwd(relativePath, cwd) {
24951
- const absolute = resolve23(cwd, relativePath);
26012
+ const absolute = resolve25(cwd, relativePath);
24952
26013
  const cwdPrefix = cwd.endsWith(sep6) ? cwd : cwd + sep6;
24953
26014
  if (!absolute.startsWith(cwdPrefix) && absolute !== cwd) {
24954
26015
  throw new Error(`Path \`${relativePath}\` resolves outside the server cwd and is not allowed.`);
@@ -24988,7 +26049,7 @@ async function runArtifactScaffold(rawArgs) {
24988
26049
  const message = err instanceof Error ? err.message : String(err);
24989
26050
  return toolError(`Scaffold failed: ${message}`);
24990
26051
  }
24991
- const checked = await applyIdempotency(raw, (relativePath) => fileExists2(resolve23(cwd, relativePath)));
26052
+ const checked = await applyIdempotency(raw, (relativePath) => fileExists2(resolve25(cwd, relativePath)));
24992
26053
  const text = formatResult9(checked);
24993
26054
  const result = {
24994
26055
  content: [{ type: "text", text }]
@@ -25001,7 +26062,7 @@ var artifactScaffoldTool = {
25001
26062
  };
25002
26063
 
25003
26064
  // packages/dbx-components-mcp/src/tools/artifact-file-convention.tool.ts
25004
- import { type as type46 } from "arktype";
26065
+ import { type as type48 } from "arktype";
25005
26066
 
25006
26067
  // packages/dbx-components-mcp/src/tools/artifact-file-convention/spec.ts
25007
26068
  var FIRESTORE_MODEL = {
@@ -25437,7 +26498,7 @@ var DBX_ARTIFACT_FILE_CONVENTION_TOOL = {
25437
26498
  required: ["artifact"]
25438
26499
  }
25439
26500
  };
25440
- var FileConventionArgsType = type46({
26501
+ var FileConventionArgsType = type48({
25441
26502
  artifact: ARTIFACT_KIND_LITERAL_UNION2,
25442
26503
  "componentDir?": "string",
25443
26504
  "apiDir?": "string",
@@ -25445,7 +26506,7 @@ var FileConventionArgsType = type46({
25445
26506
  });
25446
26507
  function parseArgs9(raw) {
25447
26508
  const parsed = FileConventionArgsType(raw);
25448
- if (parsed instanceof type46.errors) {
26509
+ if (parsed instanceof type48.errors) {
25449
26510
  throw new TypeError(`Invalid arguments: ${parsed.summary}`);
25450
26511
  }
25451
26512
  const result = {
@@ -25478,12 +26539,12 @@ var artifactFileConventionTool = {
25478
26539
  };
25479
26540
 
25480
26541
  // packages/dbx-components-mcp/src/tools/explain-rule.tool.ts
25481
- import { type as type47 } from "arktype";
25482
- var ExplainRuleArgsType = type47({
26542
+ import { type as type49 } from "arktype";
26543
+ var ExplainRuleArgsType = type49({
25483
26544
  code: "string",
25484
26545
  "format?": "'markdown' | 'json'"
25485
26546
  });
25486
- var TOOL6 = {
26547
+ var TOOL8 = {
25487
26548
  name: "dbx_explain_rule",
25488
26549
  description: [
25489
26550
  "Explain one validation rule by code. Returns the title, severity, source tool, what it flags, when it applies, when it does NOT apply, canonical fix, optional fix template, and any see-also references.",
@@ -25506,9 +26567,9 @@ var TOOL6 = {
25506
26567
  required: ["code"]
25507
26568
  }
25508
26569
  };
25509
- async function run5(rawArgs) {
26570
+ async function run7(rawArgs) {
25510
26571
  const parsed = ExplainRuleArgsType(rawArgs);
25511
- if (parsed instanceof type47.errors) {
26572
+ if (parsed instanceof type49.errors) {
25512
26573
  return toolError(`Invalid arguments: ${parsed.summary}`);
25513
26574
  }
25514
26575
  const exact = findRule(parsed.code);
@@ -25530,24 +26591,26 @@ async function run5(rawArgs) {
25530
26591
  const result = { content: [{ type: "text", text }], isError: true };
25531
26592
  return result;
25532
26593
  }
25533
- var explainRuleTool = { definition: TOOL6, run: run5 };
26594
+ var explainRuleTool = { definition: TOOL8, run: run7 };
25534
26595
 
25535
26596
  // packages/dbx-components-mcp/src/tools/app-validate.tool.ts
25536
- import { resolve as resolve24, join as join9 } from "node:path";
26597
+ import { resolve as resolve26, join as join10 } from "node:path";
25537
26598
  import { readdir as readdir6, stat as stat9 } from "node:fs/promises";
25538
- import { type as type48 } from "arktype";
26599
+ import { type as type50 } from "arktype";
25539
26600
  var Cluster = "'storagefile_m' | 'notification_m' | 'model_folder' | 'system_m' | 'fixture'";
25540
- var AppValidateArgsType = type48({
26601
+ var AppValidateArgsType = type50({
25541
26602
  componentDir: "string",
25542
26603
  apiDir: "string",
25543
26604
  "format?": "'markdown' | 'json'",
25544
26605
  "skip?": `(${Cluster})[]`
25545
26606
  });
25546
- var TOOL7 = {
26607
+ var TOOL9 = {
25547
26608
  name: "dbx_app_validate",
25548
26609
  description: [
25549
26610
  "Aggregate validator for a downstream `-firebase` component + API app pair. Runs every per-domain validator (`storagefile_m`, `notification_m`, model-folder, `system_m`, fixture) and returns one severity-grouped report.",
25550
26611
  "",
26612
+ "The `model_folder` cluster includes both folder-structure findings (canonical 5-file layout) and per-file content findings forwarded from `dbx_model_validate` \u2014 including the JSDoc-tag rules (`MODEL_IDENTITY_NOT_TAGGED`, `MODEL_GROUP_INTERFACE_MISSING_TAG`, `MODEL_INTERFACE_MISSING_TAG`) that flag downstream apps where `firestoreModelIdentity(...)` calls lack catalog tagging.",
26613
+ "",
25551
26614
  "Replaces the six-tool dance an agent runs to validate one app end-to-end. Each finding is tagged with its source cluster, code, file/line, and canonical-fix line (when the rule catalog has an entry).",
25552
26615
  "",
25553
26616
  "Inputs:",
@@ -25573,9 +26636,9 @@ var TOOL7 = {
25573
26636
  required: ["componentDir", "apiDir"]
25574
26637
  }
25575
26638
  };
25576
- async function run6(rawArgs) {
26639
+ async function run8(rawArgs) {
25577
26640
  const parsed = AppValidateArgsType(rawArgs);
25578
- if (parsed instanceof type48.errors) {
26641
+ if (parsed instanceof type50.errors) {
25579
26642
  return toolError(`Invalid arguments: ${parsed.summary}`);
25580
26643
  }
25581
26644
  const cwd = process.cwd();
@@ -25585,8 +26648,8 @@ async function run6(rawArgs) {
25585
26648
  } catch (err) {
25586
26649
  return toolError(err instanceof Error ? err.message : String(err));
25587
26650
  }
25588
- const componentAbs = resolve24(cwd, parsed.componentDir);
25589
- const apiAbs = resolve24(cwd, parsed.apiDir);
26651
+ const componentAbs = resolve26(cwd, parsed.componentDir);
26652
+ const apiAbs = resolve26(cwd, parsed.apiDir);
25590
26653
  const skip = new Set(parsed.skip ?? []);
25591
26654
  const findings = [];
25592
26655
  const skipped = [];
@@ -25658,7 +26721,7 @@ async function runModelFolders(ctx) {
25658
26721
  return;
25659
26722
  }
25660
26723
  try {
25661
- const modelRoot = join9(ctx.componentAbs, "src/lib/model");
26724
+ const modelRoot = join10(ctx.componentAbs, "src/lib/model");
25662
26725
  const reservedNames = new Set(RESERVED_MODEL_FOLDERS.map((r) => r.name));
25663
26726
  let entries;
25664
26727
  try {
@@ -25675,7 +26738,7 @@ async function runModelFolders(ctx) {
25675
26738
  for (const entry of entries) {
25676
26739
  if (!entry.isDirectory()) continue;
25677
26740
  if (reservedNames.has(entry.name)) continue;
25678
- const inspection = await inspectFolder(join9(modelRoot, entry.name));
26741
+ const inspection = await inspectFolder(join10(modelRoot, entry.name));
25679
26742
  inspections.push(inspection);
25680
26743
  }
25681
26744
  if (inspections.length === 0) {
@@ -25695,7 +26758,7 @@ async function runSystemFolder(ctx) {
25695
26758
  ctx.skipped.push("system_m");
25696
26759
  return;
25697
26760
  }
25698
- const systemPath = join9(ctx.componentAbs, "src/lib/model/system");
26761
+ const systemPath = join10(ctx.componentAbs, "src/lib/model/system");
25699
26762
  try {
25700
26763
  let exists = true;
25701
26764
  try {
@@ -25781,21 +26844,21 @@ function renderFinding(finding) {
25781
26844
  function formatJson(report) {
25782
26845
  return JSON.stringify(report, null, 2);
25783
26846
  }
25784
- var appValidateTool = { definition: TOOL7, run: run6 };
26847
+ var appValidateTool = { definition: TOOL9, run: run8 };
25785
26848
 
25786
26849
  // packages/dbx-components-mcp/src/tools/model-list-component.tool.ts
25787
- import { resolve as resolve25 } from "node:path";
25788
- import { type as type49 } from "arktype";
26850
+ import { resolve as resolve27 } from "node:path";
26851
+ import { type as type51 } from "arktype";
25789
26852
 
25790
26853
  // packages/dbx-components-mcp/src/tools/model-list-component/extract.ts
25791
- import { readdir as readdir7, readFile as readFile10, stat as stat10 } from "node:fs/promises";
25792
- import { basename as basename6, join as join10, relative as relative6, sep as sep7 } from "node:path";
25793
- import { Node as Node17, Project as Project12 } from "ts-morph";
26854
+ import { readdir as readdir7, readFile as readFile12, stat as stat10 } from "node:fs/promises";
26855
+ import { basename as basename6, join as join11, relative as relative6, sep as sep7 } from "node:path";
26856
+ import { Node as Node18, Project as Project13 } from "ts-morph";
25794
26857
  var MODEL_SUBPATH2 = "src/lib/model";
25795
26858
  var MODEL_SUBPATH_PREFIX = `${MODEL_SUBPATH2}/`;
25796
26859
  var RESERVED_NAMES = RESERVED_MODEL_FOLDERS.map((r) => r.name);
25797
26860
  async function extractComponentModels(componentAbs) {
25798
- const modelRoot = join10(componentAbs, MODEL_SUBPATH2);
26861
+ const modelRoot = join11(componentAbs, MODEL_SUBPATH2);
25799
26862
  const folders = await listFolders(modelRoot);
25800
26863
  if (folders === void 0) {
25801
26864
  const result2 = { modelRoot, models: [], skipped: [], unidentifiedFolders: [] };
@@ -25819,7 +26882,7 @@ async function extractComponentModels(componentAbs) {
25819
26882
  skipReservedFolders: RESERVED_NAMES
25820
26883
  });
25821
26884
  const richByFolder = groupRichByFolder(richResult.models);
25822
- const fallbackProject = new Project12({ useInMemoryFileSystem: true });
26885
+ const fallbackProject = new Project13({ useInMemoryFileSystem: true });
25823
26886
  const models = [];
25824
26887
  const unidentified = [];
25825
26888
  for (const folder of targetFolders) {
@@ -25885,7 +26948,7 @@ function projectRich(model, folder) {
25885
26948
  }
25886
26949
  async function fallbackForFolder(input) {
25887
26950
  const { modelRoot, componentAbs, folder, project } = input;
25888
- const folderAbs = join10(modelRoot, folder);
26951
+ const folderAbs = join11(modelRoot, folder);
25889
26952
  const mainFile = await readMainFile(folderAbs, folder);
25890
26953
  if (mainFile === void 0) return void 0;
25891
26954
  const sourceFile = project.createSourceFile(mainFile.fileName, mainFile.text, { overwrite: true });
@@ -25919,9 +26982,9 @@ async function listFolders(modelRoot) {
25919
26982
  return out;
25920
26983
  }
25921
26984
  async function readMainFile(folderAbs, folder) {
25922
- const candidate = join10(folderAbs, `${folder}.ts`);
26985
+ const candidate = join11(folderAbs, `${folder}.ts`);
25923
26986
  try {
25924
- const text = await readFile10(candidate, "utf8");
26987
+ const text = await readFile12(candidate, "utf8");
25925
26988
  return { absPath: candidate, fileName: basename6(candidate), text };
25926
26989
  } catch {
25927
26990
  return void 0;
@@ -25931,7 +26994,7 @@ function findIdentityIn(sourceFile) {
25931
26994
  for (const statement of sourceFile.getVariableStatements()) {
25932
26995
  for (const decl of statement.getDeclarations()) {
25933
26996
  const initializer = decl.getInitializer();
25934
- if (!initializer || !Node17.isCallExpression(initializer)) continue;
26997
+ if (!initializer || !Node18.isCallExpression(initializer)) continue;
25935
26998
  if (initializer.getExpression().getText() !== "firestoreModelIdentity") continue;
25936
26999
  const args = initializer.getArguments();
25937
27000
  const parsed = parseIdentityArgs2(args);
@@ -25951,13 +27014,13 @@ function parseIdentityArgs2(args) {
25951
27014
  return { parentIdentityRef: void 0, collectionName: stringLiteralValue3(args[0]), collectionPrefix: stringLiteralValue3(args[1]) };
25952
27015
  }
25953
27016
  if (args.length === 3) {
25954
- const parent = Node17.isIdentifier(args[0]) ? args[0].getText() : void 0;
27017
+ const parent = Node18.isIdentifier(args[0]) ? args[0].getText() : void 0;
25955
27018
  return { parentIdentityRef: parent, collectionName: stringLiteralValue3(args[1]), collectionPrefix: stringLiteralValue3(args[2]) };
25956
27019
  }
25957
27020
  return { parentIdentityRef: void 0, collectionName: void 0, collectionPrefix: void 0 };
25958
27021
  }
25959
27022
  function stringLiteralValue3(node) {
25960
- if (Node17.isStringLiteral(node) || Node17.isNoSubstitutionTemplateLiteral(node)) {
27023
+ if (Node18.isStringLiteral(node) || Node18.isNoSubstitutionTemplateLiteral(node)) {
25961
27024
  return node.getLiteralText();
25962
27025
  }
25963
27026
  return void 0;
@@ -26060,12 +27123,12 @@ function stripCoverage(model) {
26060
27123
  }
26061
27124
 
26062
27125
  // packages/dbx-components-mcp/src/tools/model-list-component.tool.ts
26063
- var ListArgsType2 = type49({
27126
+ var ListArgsType2 = type51({
26064
27127
  componentDir: "string",
26065
27128
  "apiDir?": "string",
26066
27129
  "format?": "'markdown' | 'json'"
26067
27130
  });
26068
- var TOOL8 = {
27131
+ var TOOL10 = {
26069
27132
  name: "dbx_model_list_component",
26070
27133
  description: [
26071
27134
  "List every Firestore model declared in a downstream `-firebase` component package, with optional fixture-coverage annotation when an API app is also supplied.",
@@ -26089,9 +27152,9 @@ var TOOL8 = {
26089
27152
  required: ["componentDir"]
26090
27153
  }
26091
27154
  };
26092
- async function run7(rawArgs) {
27155
+ async function run9(rawArgs) {
26093
27156
  const parsed = ListArgsType2(rawArgs);
26094
- if (parsed instanceof type49.errors) {
27157
+ if (parsed instanceof type51.errors) {
26095
27158
  return toolError(`Invalid arguments: ${parsed.summary}`);
26096
27159
  }
26097
27160
  const cwd = process.cwd();
@@ -26101,8 +27164,8 @@ async function run7(rawArgs) {
26101
27164
  } catch (err) {
26102
27165
  return toolError(err instanceof Error ? err.message : String(err));
26103
27166
  }
26104
- const componentAbs = resolve25(cwd, parsed.componentDir);
26105
- const apiAbs = parsed.apiDir ? resolve25(cwd, parsed.apiDir) : void 0;
27167
+ const componentAbs = resolve27(cwd, parsed.componentDir);
27168
+ const apiAbs = parsed.apiDir ? resolve27(cwd, parsed.apiDir) : void 0;
26106
27169
  let report;
26107
27170
  try {
26108
27171
  report = await listComponentModels(componentAbs, { componentDir: parsed.componentDir, apiDir: parsed.apiDir, apiAbs });
@@ -26113,26 +27176,26 @@ async function run7(rawArgs) {
26113
27176
  const result = { content: [{ type: "text", text }] };
26114
27177
  return result;
26115
27178
  }
26116
- var modelListComponentTool = { definition: TOOL8, run: run7 };
27179
+ var modelListComponentTool = { definition: TOOL10, run: run9 };
26117
27180
 
26118
27181
  // packages/dbx-components-mcp/src/tools/server-actions-list-app.tool.ts
26119
- import { resolve as resolve26 } from "node:path";
26120
- import { type as type50 } from "arktype";
27182
+ import { resolve as resolve28 } from "node:path";
27183
+ import { type as type52 } from "arktype";
26121
27184
 
26122
27185
  // packages/dbx-components-mcp/src/tools/server-actions-list-app/extract.ts
26123
- import { readdir as readdir8, readFile as readFile11, stat as stat11 } from "node:fs/promises";
26124
- import { dirname as dirname8, join as join11, relative as relative7, sep as sep8 } from "node:path";
26125
- import { Node as Node18, Project as Project13 } from "ts-morph";
27186
+ import { readdir as readdir8, readFile as readFile13, stat as stat11 } from "node:fs/promises";
27187
+ import { dirname as dirname8, join as join12, relative as relative7, sep as sep8 } from "node:path";
27188
+ import { Node as Node19, Project as Project14 } from "ts-morph";
26126
27189
  var ACTION_SERVER_SUFFIX = ".action.server.ts";
26127
27190
  var COMMON_MODEL_SUBPATH = "src/app/common/model";
26128
27191
  var COMMON_BARREL_REL = "src/app/common/index.ts";
26129
27192
  async function extractServerActions(apiAbs, apiRel) {
26130
- const modelRoot = join11(apiAbs, COMMON_MODEL_SUBPATH);
27193
+ const modelRoot = join12(apiAbs, COMMON_MODEL_SUBPATH);
26131
27194
  const actionFiles = await collectActionFiles(modelRoot);
26132
27195
  if (actionFiles.length === 0) {
26133
27196
  return { modelRoot, entries: [], fixtureStatus: "ok" };
26134
27197
  }
26135
- const project = new Project13({ useInMemoryFileSystem: true });
27198
+ const project = new Project14({ useInMemoryFileSystem: true });
26136
27199
  const commonBarrelExports = await readCommonBarrelExports(apiAbs);
26137
27200
  const fixtureCoverageMap = /* @__PURE__ */ new Map();
26138
27201
  let fixtureStatus = "ok";
@@ -26147,7 +27210,7 @@ async function extractServerActions(apiAbs, apiRel) {
26147
27210
  }
26148
27211
  const entries = [];
26149
27212
  for (const filePath of actionFiles) {
26150
- const text = await readFile11(filePath, "utf8");
27213
+ const text = await readFile13(filePath, "utf8");
26151
27214
  const sourceFile = project.createSourceFile(filePath, text, { overwrite: true });
26152
27215
  const classes = findServerActionClasses(sourceFile);
26153
27216
  for (const className of classes) {
@@ -26187,7 +27250,7 @@ async function collectActionFiles(root) {
26187
27250
  continue;
26188
27251
  }
26189
27252
  for (const entry of entries) {
26190
- const full = join11(current, entry.name);
27253
+ const full = join12(current, entry.name);
26191
27254
  if (entry.isDirectory()) {
26192
27255
  stack.push(full);
26193
27256
  continue;
@@ -26236,7 +27299,7 @@ async function findModuleCandidates(actionFilePath) {
26236
27299
  for (const entry of entries) {
26237
27300
  if (!entry.isFile()) continue;
26238
27301
  if (!entry.name.endsWith(".module.ts")) continue;
26239
- out.push(join11(dir, entry.name));
27302
+ out.push(join12(dir, entry.name));
26240
27303
  }
26241
27304
  } catch {
26242
27305
  }
@@ -26245,13 +27308,13 @@ async function findModuleCandidates(actionFilePath) {
26245
27308
  }
26246
27309
  async function safeRead(path) {
26247
27310
  try {
26248
- return await readFile11(path, "utf8");
27311
+ return await readFile13(path, "utf8");
26249
27312
  } catch {
26250
27313
  return void 0;
26251
27314
  }
26252
27315
  }
26253
27316
  function inspectModuleText(input) {
26254
- const project = new Project13({ useInMemoryFileSystem: true });
27317
+ const project = new Project14({ useInMemoryFileSystem: true });
26255
27318
  const sourceFile = project.createSourceFile("module.ts", input.text, { overwrite: true });
26256
27319
  let providedByModule = false;
26257
27320
  let exportedByModule = false;
@@ -26259,7 +27322,7 @@ function inspectModuleText(input) {
26259
27322
  for (const decorator of cls.getDecorators()) {
26260
27323
  if (decorator.getName() !== "Module") continue;
26261
27324
  const args = decorator.getArguments();
26262
- if (args.length === 0 || !Node18.isObjectLiteralExpression(args[0])) continue;
27325
+ if (args.length === 0 || !Node19.isObjectLiteralExpression(args[0])) continue;
26263
27326
  const obj = args[0];
26264
27327
  providedByModule ||= moduleArrayContains(obj, "providers", input.className);
26265
27328
  exportedByModule ||= moduleArrayContains(obj, "exports", input.className);
@@ -26269,26 +27332,26 @@ function inspectModuleText(input) {
26269
27332
  }
26270
27333
  function moduleArrayContains(decoratorArg, propertyName, className) {
26271
27334
  const property = decoratorArg.getProperty(propertyName);
26272
- if (!property || !Node18.isPropertyAssignment(property)) return false;
27335
+ if (!property || !Node19.isPropertyAssignment(property)) return false;
26273
27336
  const initializer = property.getInitializer();
26274
- if (!initializer || !Node18.isArrayLiteralExpression(initializer)) return false;
27337
+ if (!initializer || !Node19.isArrayLiteralExpression(initializer)) return false;
26275
27338
  for (const element of initializer.getElements()) {
26276
- if (Node18.isIdentifier(element) && element.getText() === className) return true;
26277
- if (Node18.isObjectLiteralExpression(element)) {
27339
+ if (Node19.isIdentifier(element) && element.getText() === className) return true;
27340
+ if (Node19.isObjectLiteralExpression(element)) {
26278
27341
  const provideProp = element.getProperty("provide");
26279
- if (provideProp && Node18.isPropertyAssignment(provideProp)) {
27342
+ if (provideProp && Node19.isPropertyAssignment(provideProp)) {
26280
27343
  const provideInit = provideProp.getInitializer();
26281
- if (provideInit && Node18.isIdentifier(provideInit) && provideInit.getText() === className) return true;
27344
+ if (provideInit && Node19.isIdentifier(provideInit) && provideInit.getText() === className) return true;
26282
27345
  }
26283
27346
  }
26284
27347
  }
26285
27348
  return false;
26286
27349
  }
26287
27350
  async function readCommonBarrelExports(apiAbs) {
26288
- const path = join11(apiAbs, COMMON_BARREL_REL);
27351
+ const path = join12(apiAbs, COMMON_BARREL_REL);
26289
27352
  const text = await safeRead(path);
26290
27353
  if (text === void 0) return /* @__PURE__ */ new Set();
26291
- const project = new Project13({ useInMemoryFileSystem: true });
27354
+ const project = new Project14({ useInMemoryFileSystem: true });
26292
27355
  const sourceFile = project.createSourceFile(path, text, { overwrite: true });
26293
27356
  const exported = /* @__PURE__ */ new Set();
26294
27357
  for (const decl of sourceFile.getExportDeclarations()) {
@@ -26332,11 +27395,11 @@ function collectInterfaceGetters(sourceFile) {
26332
27395
  const out = /* @__PURE__ */ new Map();
26333
27396
  for (const iface of sourceFile.getInterfaces()) {
26334
27397
  for (const member of iface.getMembers()) {
26335
- if (Node18.isGetAccessorDeclaration(member)) {
27398
+ if (Node19.isGetAccessorDeclaration(member)) {
26336
27399
  out.set(member.getName(), iface.getName());
26337
27400
  continue;
26338
27401
  }
26339
- if (Node18.isPropertySignature(member)) {
27402
+ if (Node19.isPropertySignature(member)) {
26340
27403
  out.set(member.getName(), iface.getName());
26341
27404
  }
26342
27405
  }
@@ -26348,7 +27411,7 @@ function collectClassGetters(sourceFile) {
26348
27411
  for (const cls of sourceFile.getClasses()) {
26349
27412
  const set = /* @__PURE__ */ new Set();
26350
27413
  for (const member of cls.getMembers()) {
26351
- if (Node18.isGetAccessorDeclaration(member)) set.add(member.getName());
27414
+ if (Node19.isGetAccessorDeclaration(member)) set.add(member.getName());
26352
27415
  }
26353
27416
  if (set.size > 0) out.set(cls.getName() ?? "<anon>", set);
26354
27417
  }
@@ -26427,11 +27490,11 @@ async function listAppServerActions(apiAbs, options) {
26427
27490
  }
26428
27491
 
26429
27492
  // packages/dbx-components-mcp/src/tools/server-actions-list-app.tool.ts
26430
- var ListArgsType3 = type50({
27493
+ var ListArgsType3 = type52({
26431
27494
  apiDir: "string",
26432
27495
  "format?": "'markdown' | 'json'"
26433
27496
  });
26434
- var TOOL9 = {
27497
+ var TOOL11 = {
26435
27498
  name: "dbx_server_actions_list_app",
26436
27499
  description: [
26437
27500
  "List every `*ServerActions` abstract class declared in an API app, with NestJS module wiring, common-barrel export status, and test-fixture coverage.",
@@ -26454,9 +27517,9 @@ var TOOL9 = {
26454
27517
  required: ["apiDir"]
26455
27518
  }
26456
27519
  };
26457
- async function run8(rawArgs) {
27520
+ async function run10(rawArgs) {
26458
27521
  const parsed = ListArgsType3(rawArgs);
26459
- if (parsed instanceof type50.errors) {
27522
+ if (parsed instanceof type52.errors) {
26460
27523
  return toolError(`Invalid arguments: ${parsed.summary}`);
26461
27524
  }
26462
27525
  const cwd = process.cwd();
@@ -26465,7 +27528,7 @@ async function run8(rawArgs) {
26465
27528
  } catch (err) {
26466
27529
  return toolError(err instanceof Error ? err.message : String(err));
26467
27530
  }
26468
- const apiAbs = resolve26(cwd, parsed.apiDir);
27531
+ const apiAbs = resolve28(cwd, parsed.apiDir);
26469
27532
  let report;
26470
27533
  try {
26471
27534
  report = await listAppServerActions(apiAbs, { apiDir: parsed.apiDir });
@@ -26476,19 +27539,19 @@ async function run8(rawArgs) {
26476
27539
  const result = { content: [{ type: "text", text }] };
26477
27540
  return result;
26478
27541
  }
26479
- var serverActionsListAppTool = { definition: TOOL9, run: run8 };
27542
+ var serverActionsListAppTool = { definition: TOOL11, run: run10 };
26480
27543
 
26481
27544
  // packages/dbx-components-mcp/src/tools/mcp-config.tool.ts
26482
- import { type as type57 } from "arktype";
26483
- import { resolve as resolve33 } from "node:path";
27545
+ import { type as type59 } from "arktype";
27546
+ import { resolve as resolve35 } from "node:path";
26484
27547
 
26485
27548
  // packages/dbx-components-mcp/src/tools/mcp-config/snapshot.ts
26486
- import { dirname as dirname9, isAbsolute as isAbsolute8, relative as relative8, resolve as resolve28 } from "node:path";
27549
+ import { dirname as dirname9, isAbsolute as isAbsolute8, relative as relative8, resolve as resolve30 } from "node:path";
26487
27550
  import { stat as stat13 } from "node:fs/promises";
26488
27551
 
26489
27552
  // packages/dbx-components-mcp/src/scan/discover-downstream-packages.ts
26490
- import { glob as fsGlob5, readFile as readFile12, stat as stat12 } from "node:fs/promises";
26491
- import { basename as basename7, join as join12, resolve as resolve27, sep as sep9 } from "node:path";
27553
+ import { glob as fsGlob5, readFile as readFile14, stat as stat12 } from "node:fs/promises";
27554
+ import { basename as basename7, join as join13, resolve as resolve29, sep as sep9 } from "node:path";
26492
27555
  var COMPONENT_GLOBS = ["components/*-firebase", "components/*-shared", "components/*-web", "components/*-core"];
26493
27556
  var APPS_GLOB = "apps/*";
26494
27557
  var SCAN_CONFIG_FILENAME2 = "dbx-mcp.scan.json";
@@ -26518,7 +27581,7 @@ async function discoverConventionalDirs(workspaceRoot) {
26518
27581
  }
26519
27582
  for await (const match of fsGlob5(APPS_GLOB, { cwd: workspaceRoot })) {
26520
27583
  const rel = match.split(sep9).join("/");
26521
- if (await fileExists3(join12(workspaceRoot, rel, SCAN_CONFIG_FILENAME2))) {
27584
+ if (await fileExists3(join13(workspaceRoot, rel, SCAN_CONFIG_FILENAME2))) {
26522
27585
  found.add(rel);
26523
27586
  }
26524
27587
  }
@@ -26533,13 +27596,13 @@ function normaliseExplicitDirs(dirs) {
26533
27596
  return result;
26534
27597
  }
26535
27598
  async function inspectPackage2(workspaceRoot, relDir) {
26536
- const absDir = resolve27(workspaceRoot, relDir);
27599
+ const absDir = resolve29(workspaceRoot, relDir);
26537
27600
  const isDir = await isDirectory2(absDir);
26538
27601
  if (!isDir) return void 0;
26539
27602
  const packageName = await readPackageName2(absDir, relDir);
26540
27603
  const slug = packageNameToSlug(packageName);
26541
- const hasScanConfig = await fileExists3(join12(absDir, SCAN_CONFIG_FILENAME2));
26542
- const declaredScanClusters = hasScanConfig ? await readDeclaredClusters(join12(absDir, SCAN_CONFIG_FILENAME2)) : [];
27604
+ const hasScanConfig = await fileExists3(join13(absDir, SCAN_CONFIG_FILENAME2));
27605
+ const declaredScanClusters = hasScanConfig ? await readDeclaredClusters(join13(absDir, SCAN_CONFIG_FILENAME2)) : [];
26543
27606
  const heuristicClusters = await detectCandidateClusters(absDir);
26544
27607
  const candidateClusters = mergeClusters(heuristicClusters, declaredScanClusters);
26545
27608
  return {
@@ -26572,7 +27635,7 @@ async function readPackageName2(absDir, relDir) {
26572
27635
  const fallback = basename7(relDir);
26573
27636
  let result = fallback;
26574
27637
  try {
26575
- const text = await readFile12(join12(absDir, PACKAGE_JSON2), "utf8");
27638
+ const text = await readFile14(join13(absDir, PACKAGE_JSON2), "utf8");
26576
27639
  const parsed = JSON.parse(text);
26577
27640
  if (typeof parsed.name === "string" && parsed.name.length > 0) {
26578
27641
  result = parsed.name;
@@ -26587,7 +27650,7 @@ function packageNameToSlug(packageName) {
26587
27650
  async function readDeclaredClusters(scanConfigPath) {
26588
27651
  let parsed = null;
26589
27652
  try {
26590
- const text = await readFile12(scanConfigPath, "utf8");
27653
+ const text = await readFile14(scanConfigPath, "utf8");
26591
27654
  parsed = JSON.parse(text);
26592
27655
  } catch {
26593
27656
  parsed = null;
@@ -26664,7 +27727,7 @@ async function collectRegisteredSources(config, configBaseDir, workspaceRoot) {
26664
27727
  for (const cluster of DOWNSTREAM_CLUSTERS) {
26665
27728
  const declared = config[cluster]?.sources ?? [];
26666
27729
  for (const declaredPath of declared) {
26667
- const absolutePath = isAbsolute8(declaredPath) ? declaredPath : resolve28(configBaseDir, declaredPath);
27730
+ const absolutePath = isAbsolute8(declaredPath) ? declaredPath : resolve30(configBaseDir, declaredPath);
26668
27731
  const exists = await fileExists4(absolutePath);
26669
27732
  const relativePath = relativeOrAbsolute(workspaceRoot, absolutePath);
26670
27733
  out.push({ cluster, declaredPath, absolutePath, relativePath, exists });
@@ -26702,21 +27765,21 @@ function relativeOrAbsolute(from, target) {
26702
27765
 
26703
27766
  // packages/dbx-components-mcp/src/tools/mcp-config/init.ts
26704
27767
  import { writeFile as nodeWriteFile3, mkdir as nodeMkdir, readFile as nodeReadFile7 } from "node:fs/promises";
26705
- import { dirname as dirname10, relative as relative9, resolve as resolve29 } from "node:path";
27768
+ import { dirname as dirname10, relative as relative9, resolve as resolve31 } from "node:path";
26706
27769
  var HEURISTIC_CLUSTERS = ["uiComponents", "forgeFields", "pipes", "actions", "filters"];
26707
27770
  var DEFAULT_INCLUDE = ["src/**/*.ts"];
26708
27771
  var DEFAULT_EXCLUDE = ["**/*.spec.ts", "**/*.test.ts", "**/*.stories.ts"];
26709
27772
  async function buildInitPlan(input) {
26710
27773
  const { snapshot } = input;
26711
- const readFile13 = input.readFile ?? defaultReadFile2;
27774
+ const readFile15 = input.readFile ?? defaultReadFile2;
26712
27775
  const changes = [];
26713
27776
  const sourcesToRegister = [];
26714
27777
  for (const ps of snapshot.packages) {
26715
- const planResult = await planPackageScanConfig({ snapshot, packageSnapshot: ps, readFile: readFile13 });
27778
+ const planResult = await planPackageScanConfig({ snapshot, packageSnapshot: ps, readFile: readFile15 });
26716
27779
  if (planResult.change !== void 0) changes.push(planResult.change);
26717
27780
  for (const reg of planResult.sourcesToRegister) sourcesToRegister.push(reg);
26718
27781
  }
26719
- const configChange = await planRootConfig({ snapshot, sourcesToRegister, readFile: readFile13 });
27782
+ const configChange = await planRootConfig({ snapshot, sourcesToRegister, readFile: readFile15 });
26720
27783
  if (configChange !== void 0) changes.push(configChange);
26721
27784
  return { workspaceRoot: snapshot.workspaceRoot, changes };
26722
27785
  }
@@ -26730,10 +27793,10 @@ async function applyInitPlan(plan, opts) {
26730
27793
  }
26731
27794
  }
26732
27795
  async function planPackageScanConfig(input) {
26733
- const { snapshot, packageSnapshot, readFile: readFile13 } = input;
27796
+ const { snapshot, packageSnapshot, readFile: readFile15 } = input;
26734
27797
  const { pkg } = packageSnapshot;
26735
- const scanConfigPath = resolve29(pkg.absDir, "dbx-mcp.scan.json");
26736
- const before = await tryRead(scanConfigPath, readFile13);
27798
+ const scanConfigPath = resolve31(pkg.absDir, "dbx-mcp.scan.json");
27799
+ const before = await tryRead(scanConfigPath, readFile15);
26737
27800
  const parsed = parseExisting(before);
26738
27801
  const targetClusters = HEURISTIC_CLUSTERS.filter((c) => pkg.candidateClusters.includes(c));
26739
27802
  if (targetClusters.length === 0 && parsed === null) {
@@ -26775,9 +27838,9 @@ async function planPackageScanConfig(input) {
26775
27838
  return { change, sourcesToRegister };
26776
27839
  }
26777
27840
  async function planRootConfig(input) {
26778
- const { snapshot, sourcesToRegister, readFile: readFile13 } = input;
26779
- const configPath = snapshot.configPath ?? resolve29(snapshot.workspaceRoot, "dbx-mcp.config.json");
26780
- const before = snapshot.configPath !== null ? await tryRead(configPath, readFile13) : null;
27841
+ const { snapshot, sourcesToRegister, readFile: readFile15 } = input;
27842
+ const configPath = snapshot.configPath ?? resolve31(snapshot.workspaceRoot, "dbx-mcp.config.json");
27843
+ const before = snapshot.configPath !== null ? await tryRead(configPath, readFile15) : null;
26781
27844
  const baseConfig = snapshot.config !== null ? cloneConfig(snapshot.config) : { version: 1 };
26782
27845
  if (baseConfig.version !== 1) baseConfig.version = 1;
26783
27846
  let mutated = false;
@@ -26805,11 +27868,11 @@ async function planRootConfig(input) {
26805
27868
  };
26806
27869
  }
26807
27870
  function defaultOutFor(input) {
26808
- const targetAbs = resolve29(input.snapshot.workspaceRoot, ".tmp/dbx-mcp", `${input.slug}.${input.cluster}.json`);
27871
+ const targetAbs = resolve31(input.snapshot.workspaceRoot, ".tmp/dbx-mcp", `${input.slug}.${input.cluster}.json`);
26809
27872
  return relative9(dirname10(input.scanConfigPath), targetAbs).split("\\").join("/");
26810
27873
  }
26811
27874
  function resolveScanOut(scanConfigPath, out) {
26812
- return resolve29(dirname10(scanConfigPath), out);
27875
+ return resolve31(dirname10(scanConfigPath), out);
26813
27876
  }
26814
27877
  function relativeFromConfig(snapshot, absolute) {
26815
27878
  const configDir = snapshot.configPath !== null ? dirname10(snapshot.configPath) : snapshot.workspaceRoot;
@@ -26842,9 +27905,9 @@ function cloneConfig(config) {
26842
27905
  }
26843
27906
  return out;
26844
27907
  }
26845
- async function tryRead(path, readFile13) {
27908
+ async function tryRead(path, readFile15) {
26846
27909
  try {
26847
- return await readFile13(path);
27910
+ return await readFile15(path);
26848
27911
  } catch {
26849
27912
  return null;
26850
27913
  }
@@ -26856,12 +27919,12 @@ var defaultMkdir = async (dir) => {
26856
27919
  };
26857
27920
 
26858
27921
  // packages/dbx-components-mcp/src/scan/actions-build-manifest.ts
26859
- import { relative as relative10, resolve as resolve30 } from "node:path";
26860
- import { type as type52 } from "arktype";
26861
- import { Project as Project14 } from "ts-morph";
27922
+ import { relative as relative10, resolve as resolve32 } from "node:path";
27923
+ import { type as type54 } from "arktype";
27924
+ import { Project as Project15 } from "ts-morph";
26862
27925
 
26863
27926
  // packages/dbx-components-mcp/src/scan/actions-extract.ts
26864
- import { Node as Node19, SyntaxKind as SyntaxKind11 } from "ts-morph";
27927
+ import { Node as Node20, SyntaxKind as SyntaxKind12 } from "ts-morph";
26865
27928
  var ACTION_MARKER = "dbxAction";
26866
27929
  var ACTION_SLUG_TAG = "dbxActionSlug";
26867
27930
  var ACTION_ROLE_TAG = "dbxActionRole";
@@ -27069,7 +28132,7 @@ function filterStates(values) {
27069
28132
  }
27070
28133
  function readEnumMemberLiteral(member) {
27071
28134
  const initializer = member.getInitializer();
27072
- if (initializer !== void 0 && (Node19.isStringLiteral(initializer) || Node19.isNoSubstitutionTemplateLiteral(initializer))) {
28135
+ if (initializer !== void 0 && (Node20.isStringLiteral(initializer) || Node20.isNoSubstitutionTemplateLiteral(initializer))) {
27073
28136
  return initializer.getLiteralText();
27074
28137
  }
27075
28138
  return member.getName();
@@ -27141,7 +28204,7 @@ function extractStoreObservables(decl) {
27141
28204
  return out;
27142
28205
  }
27143
28206
  function isVisibleMethod(method) {
27144
- if (method.hasModifier(SyntaxKind11.PrivateKeyword) || method.hasModifier(SyntaxKind11.ProtectedKeyword)) {
28207
+ if (method.hasModifier(SyntaxKind12.PrivateKeyword) || method.hasModifier(SyntaxKind12.ProtectedKeyword)) {
27145
28208
  return false;
27146
28209
  }
27147
28210
  const name = method.getName();
@@ -27160,15 +28223,15 @@ function readMethodDescription(method) {
27160
28223
  }
27161
28224
 
27162
28225
  // packages/dbx-components-mcp/src/scan/actions-scan-config-schema.ts
27163
- import { type as type51 } from "arktype";
27164
- var ActionsScanSection = type51({
28226
+ import { type as type53 } from "arktype";
28227
+ var ActionsScanSection = type53({
27165
28228
  "source?": "string",
27166
28229
  "module?": "string",
27167
28230
  include: "string[] >= 1",
27168
28231
  "exclude?": "string[]",
27169
28232
  "out?": "string"
27170
28233
  });
27171
- var ActionsScanConfig = type51({
28234
+ var ActionsScanConfig = type53({
27172
28235
  version: "1",
27173
28236
  actions: ActionsScanSection
27174
28237
  });
@@ -27179,20 +28242,20 @@ var ACTIONS_SCAN_CONFIG_FILENAME = "dbx-mcp.scan.json";
27179
28242
  var DEFAULT_READ_FILE9 = defaultReadFile;
27180
28243
  var DEFAULT_GLOBBER4 = defaultGlobber;
27181
28244
  async function buildActionsManifest(input) {
27182
- const { projectRoot, generator, readFile: readFile13 = DEFAULT_READ_FILE9, globber = DEFAULT_GLOBBER4, now = () => /* @__PURE__ */ new Date() } = input;
27183
- const configPath = resolve30(projectRoot, ACTIONS_SCAN_CONFIG_FILENAME);
27184
- const packagePath = resolve30(projectRoot, "package.json");
27185
- const configOutcome = await loadScanConfig4(configPath, readFile13);
28245
+ const { projectRoot, generator, readFile: readFile15 = DEFAULT_READ_FILE9, globber = DEFAULT_GLOBBER4, now = () => /* @__PURE__ */ new Date() } = input;
28246
+ const configPath = resolve32(projectRoot, ACTIONS_SCAN_CONFIG_FILENAME);
28247
+ const packagePath = resolve32(projectRoot, "package.json");
28248
+ const configOutcome = await loadScanConfig4(configPath, readFile15);
27186
28249
  if (configOutcome.kind !== "ok") return configOutcome.outcome;
27187
28250
  const scanSection = configOutcome.section;
27188
- const packageOutcome = await loadPackageName(packagePath, readFile13);
28251
+ const packageOutcome = await loadPackageName(packagePath, readFile15);
27189
28252
  if (packageOutcome.kind !== "ok") return packageOutcome.outcome;
27190
28253
  const packageName = packageOutcome.packageName;
27191
28254
  const filePaths = await globber({ projectRoot, include: scanSection.include, exclude: scanSection.exclude ?? [] });
27192
- const project = new Project14({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
28255
+ const project = new Project15({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
27193
28256
  for (const relPath of filePaths) {
27194
- const absolute = resolve30(projectRoot, relPath);
27195
- const text = await readFile13(absolute);
28257
+ const absolute = resolve32(projectRoot, relPath);
28258
+ const text = await readFile15(absolute);
27196
28259
  project.createSourceFile(absolute, text, { overwrite: true });
27197
28260
  }
27198
28261
  const extractResult = extractActionEntries({ project });
@@ -27209,10 +28272,10 @@ async function buildActionsManifest(input) {
27209
28272
  };
27210
28273
  const validated = ActionManifest(manifest);
27211
28274
  let outcome;
27212
- if (validated instanceof type52.errors) {
28275
+ if (validated instanceof type54.errors) {
27213
28276
  outcome = { kind: "invalid-manifest", error: validated.summary };
27214
28277
  } else {
27215
- const outPath = resolve30(projectRoot, scanSection.out ?? DEFAULT_ACTIONS_SCAN_OUT_PATH);
28278
+ const outPath = resolve32(projectRoot, scanSection.out ?? DEFAULT_ACTIONS_SCAN_OUT_PATH);
27216
28279
  outcome = {
27217
28280
  kind: "success",
27218
28281
  manifest: validated,
@@ -27223,10 +28286,10 @@ async function buildActionsManifest(input) {
27223
28286
  }
27224
28287
  return outcome;
27225
28288
  }
27226
- async function loadScanConfig4(configPath, readFile13) {
28289
+ async function loadScanConfig4(configPath, readFile15) {
27227
28290
  let raw = null;
27228
28291
  try {
27229
- raw = await readFile13(configPath);
28292
+ raw = await readFile15(configPath);
27230
28293
  } catch {
27231
28294
  raw = null;
27232
28295
  }
@@ -27243,7 +28306,7 @@ async function loadScanConfig4(configPath, readFile13) {
27243
28306
  }
27244
28307
  if (parseError === null) {
27245
28308
  const validated = ActionsScanConfig(parsed);
27246
- if (validated instanceof type52.errors) {
28309
+ if (validated instanceof type54.errors) {
27247
28310
  result = { kind: "fail", outcome: { kind: "invalid-scan-config", configPath, error: validated.summary } };
27248
28311
  } else {
27249
28312
  result = { kind: "ok", section: validated.actions };
@@ -27374,9 +28437,9 @@ function formatExtractWarning3(warning) {
27374
28437
  }
27375
28438
 
27376
28439
  // packages/dbx-components-mcp/src/scan/filters-build-manifest.ts
27377
- import { relative as relative11, resolve as resolve31 } from "node:path";
27378
- import { type as type54 } from "arktype";
27379
- import { Project as Project15 } from "ts-morph";
28440
+ import { relative as relative11, resolve as resolve33 } from "node:path";
28441
+ import { type as type56 } from "arktype";
28442
+ import { Project as Project16 } from "ts-morph";
27380
28443
 
27381
28444
  // packages/dbx-components-mcp/src/scan/filters-extract.ts
27382
28445
  var FILTER_MARKER = "dbxFilter";
@@ -27568,15 +28631,15 @@ function extractOutputs3(decl) {
27568
28631
  }
27569
28632
 
27570
28633
  // packages/dbx-components-mcp/src/scan/filters-scan-config-schema.ts
27571
- import { type as type53 } from "arktype";
27572
- var FiltersScanSection = type53({
28634
+ import { type as type55 } from "arktype";
28635
+ var FiltersScanSection = type55({
27573
28636
  "source?": "string",
27574
28637
  "module?": "string",
27575
28638
  include: "string[] >= 1",
27576
28639
  "exclude?": "string[]",
27577
28640
  "out?": "string"
27578
28641
  });
27579
- var FiltersScanConfig = type53({
28642
+ var FiltersScanConfig = type55({
27580
28643
  version: "1",
27581
28644
  filters: FiltersScanSection
27582
28645
  });
@@ -27587,15 +28650,15 @@ var FILTERS_SCAN_CONFIG_FILENAME = "dbx-mcp.scan.json";
27587
28650
  var DEFAULT_READ_FILE10 = defaultReadFile;
27588
28651
  var DEFAULT_GLOBBER5 = defaultGlobber;
27589
28652
  async function buildFiltersManifest(input) {
27590
- const { projectRoot, generator, readFile: readFile13 = DEFAULT_READ_FILE10, globber = DEFAULT_GLOBBER5, now = () => /* @__PURE__ */ new Date() } = input;
27591
- const configPath = resolve31(projectRoot, FILTERS_SCAN_CONFIG_FILENAME);
27592
- const packagePath = resolve31(projectRoot, "package.json");
27593
- const configOutcome = await loadScanConfig5(configPath, readFile13);
28653
+ const { projectRoot, generator, readFile: readFile15 = DEFAULT_READ_FILE10, globber = DEFAULT_GLOBBER5, now = () => /* @__PURE__ */ new Date() } = input;
28654
+ const configPath = resolve33(projectRoot, FILTERS_SCAN_CONFIG_FILENAME);
28655
+ const packagePath = resolve33(projectRoot, "package.json");
28656
+ const configOutcome = await loadScanConfig5(configPath, readFile15);
27594
28657
  if (configOutcome.kind !== "ok") {
27595
28658
  return configOutcome.outcome;
27596
28659
  }
27597
28660
  const scanSection = configOutcome.section;
27598
- const packageOutcome = await loadPackageName(packagePath, readFile13);
28661
+ const packageOutcome = await loadPackageName(packagePath, readFile15);
27599
28662
  if (packageOutcome.kind !== "ok") {
27600
28663
  return packageOutcome.outcome;
27601
28664
  }
@@ -27605,10 +28668,10 @@ async function buildFiltersManifest(input) {
27605
28668
  include: scanSection.include,
27606
28669
  exclude: scanSection.exclude ?? []
27607
28670
  });
27608
- const project = new Project15({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
28671
+ const project = new Project16({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
27609
28672
  for (const relPath of filePaths) {
27610
- const absolute = resolve31(projectRoot, relPath);
27611
- const text = await readFile13(absolute);
28673
+ const absolute = resolve33(projectRoot, relPath);
28674
+ const text = await readFile15(absolute);
27612
28675
  project.createSourceFile(absolute, text, { overwrite: true });
27613
28676
  }
27614
28677
  const extractResult = extractFilterEntries({ project });
@@ -27625,10 +28688,10 @@ async function buildFiltersManifest(input) {
27625
28688
  };
27626
28689
  const validated = FilterManifest(manifest);
27627
28690
  let outcome;
27628
- if (validated instanceof type54.errors) {
28691
+ if (validated instanceof type56.errors) {
27629
28692
  outcome = { kind: "invalid-manifest", error: validated.summary };
27630
28693
  } else {
27631
- const outPath = resolve31(projectRoot, scanSection.out ?? DEFAULT_FILTERS_SCAN_OUT_PATH);
28694
+ const outPath = resolve33(projectRoot, scanSection.out ?? DEFAULT_FILTERS_SCAN_OUT_PATH);
27632
28695
  outcome = {
27633
28696
  kind: "success",
27634
28697
  manifest: validated,
@@ -27639,10 +28702,10 @@ async function buildFiltersManifest(input) {
27639
28702
  }
27640
28703
  return outcome;
27641
28704
  }
27642
- async function loadScanConfig5(configPath, readFile13) {
28705
+ async function loadScanConfig5(configPath, readFile15) {
27643
28706
  let raw = null;
27644
28707
  try {
27645
- raw = await readFile13(configPath);
28708
+ raw = await readFile15(configPath);
27646
28709
  } catch {
27647
28710
  raw = null;
27648
28711
  }
@@ -27659,7 +28722,7 @@ async function loadScanConfig5(configPath, readFile13) {
27659
28722
  }
27660
28723
  if (parseError === null) {
27661
28724
  const validated = FiltersScanConfig(parsed);
27662
- if (validated instanceof type54.errors) {
28725
+ if (validated instanceof type56.errors) {
27663
28726
  result = { kind: "fail", outcome: { kind: "invalid-scan-config", configPath, error: validated.summary } };
27664
28727
  } else {
27665
28728
  result = { kind: "ok", section: validated.filters };
@@ -27752,12 +28815,12 @@ function formatExtractWarning4(warning) {
27752
28815
  }
27753
28816
 
27754
28817
  // packages/dbx-components-mcp/src/scan/pipes-build-manifest.ts
27755
- import { relative as relative12, resolve as resolve32 } from "node:path";
27756
- import { type as type56 } from "arktype";
27757
- import { Project as Project16 } from "ts-morph";
28818
+ import { relative as relative12, resolve as resolve34 } from "node:path";
28819
+ import { type as type58 } from "arktype";
28820
+ import { Project as Project17 } from "ts-morph";
27758
28821
 
27759
28822
  // packages/dbx-components-mcp/src/scan/pipes-extract.ts
27760
- import { Node as Node20 } from "ts-morph";
28823
+ import { Node as Node21 } from "ts-morph";
27761
28824
  var PIPE_MARKER = "dbxPipe";
27762
28825
  var PIPE_SLUG_TAG = "dbxPipeSlug";
27763
28826
  var PIPE_CATEGORY_TAG = "dbxPipeCategory";
@@ -27950,7 +29013,7 @@ function readPipeDecoratorConfig(decorator) {
27950
29013
  return void 0;
27951
29014
  }
27952
29015
  const firstArg = args[0];
27953
- if (!Node20.isObjectLiteralExpression(firstArg)) {
29016
+ if (!Node21.isObjectLiteralExpression(firstArg)) {
27954
29017
  return void 0;
27955
29018
  }
27956
29019
  const name = readStringProperty(firstArg, "name");
@@ -27963,7 +29026,7 @@ function readPipeDecoratorConfig(decorator) {
27963
29026
  }
27964
29027
  function readBooleanProperty(obj, propName) {
27965
29028
  const prop = obj.getProperty(propName);
27966
- if (prop === void 0 || !Node20.isPropertyAssignment(prop)) {
29029
+ if (prop === void 0 || !Node21.isPropertyAssignment(prop)) {
27967
29030
  return void 0;
27968
29031
  }
27969
29032
  const initializer = prop.getInitializer();
@@ -27989,10 +29052,10 @@ function readTransformSignature(method, fallbackParamDescriptions) {
27989
29052
  for (let i = 1; i < params.length; i += 1) {
27990
29053
  const param = params[i];
27991
29054
  const name = param.getName();
27992
- const type60 = readParamType(param);
29055
+ const type62 = readParamType(param);
27993
29056
  const description = methodParamDescriptions.get(name) ?? fallbackParamDescriptions.get(name) ?? "";
27994
29057
  const required = !param.isOptional() && !param.hasInitializer();
27995
- args.push({ name, type: type60, description, required });
29058
+ args.push({ name, type: type62, description, required });
27996
29059
  }
27997
29060
  return { inputType, outputType, args };
27998
29061
  }
@@ -28029,15 +29092,15 @@ function extractParamName(rawTag) {
28029
29092
  }
28030
29093
 
28031
29094
  // packages/dbx-components-mcp/src/scan/pipes-scan-config-schema.ts
28032
- import { type as type55 } from "arktype";
28033
- var PipesScanSection = type55({
29095
+ import { type as type57 } from "arktype";
29096
+ var PipesScanSection = type57({
28034
29097
  "source?": "string",
28035
29098
  "module?": "string",
28036
29099
  include: "string[] >= 1",
28037
29100
  "exclude?": "string[]",
28038
29101
  "out?": "string"
28039
29102
  });
28040
- var PipesScanConfig = type55({
29103
+ var PipesScanConfig = type57({
28041
29104
  version: "1",
28042
29105
  pipes: PipesScanSection
28043
29106
  });
@@ -28048,15 +29111,15 @@ var PIPES_SCAN_CONFIG_FILENAME = "dbx-mcp.scan.json";
28048
29111
  var DEFAULT_READ_FILE11 = defaultReadFile;
28049
29112
  var DEFAULT_GLOBBER6 = defaultGlobber;
28050
29113
  async function buildPipesManifest(input) {
28051
- const { projectRoot, generator, readFile: readFile13 = DEFAULT_READ_FILE11, globber = DEFAULT_GLOBBER6, now = () => /* @__PURE__ */ new Date() } = input;
28052
- const configPath = resolve32(projectRoot, PIPES_SCAN_CONFIG_FILENAME);
28053
- const packagePath = resolve32(projectRoot, "package.json");
28054
- const configOutcome = await loadScanConfig6(configPath, readFile13);
29114
+ const { projectRoot, generator, readFile: readFile15 = DEFAULT_READ_FILE11, globber = DEFAULT_GLOBBER6, now = () => /* @__PURE__ */ new Date() } = input;
29115
+ const configPath = resolve34(projectRoot, PIPES_SCAN_CONFIG_FILENAME);
29116
+ const packagePath = resolve34(projectRoot, "package.json");
29117
+ const configOutcome = await loadScanConfig6(configPath, readFile15);
28055
29118
  if (configOutcome.kind !== "ok") {
28056
29119
  return configOutcome.outcome;
28057
29120
  }
28058
29121
  const scanSection = configOutcome.section;
28059
- const packageOutcome = await loadPackageName(packagePath, readFile13);
29122
+ const packageOutcome = await loadPackageName(packagePath, readFile15);
28060
29123
  if (packageOutcome.kind !== "ok") {
28061
29124
  return packageOutcome.outcome;
28062
29125
  }
@@ -28066,10 +29129,10 @@ async function buildPipesManifest(input) {
28066
29129
  include: scanSection.include,
28067
29130
  exclude: scanSection.exclude ?? []
28068
29131
  });
28069
- const project = new Project16({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
29132
+ const project = new Project17({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
28070
29133
  for (const relPath of filePaths) {
28071
- const absolute = resolve32(projectRoot, relPath);
28072
- const text = await readFile13(absolute);
29134
+ const absolute = resolve34(projectRoot, relPath);
29135
+ const text = await readFile15(absolute);
28073
29136
  project.createSourceFile(absolute, text, { overwrite: true });
28074
29137
  }
28075
29138
  const extractResult = extractPipeEntries({ project });
@@ -28086,10 +29149,10 @@ async function buildPipesManifest(input) {
28086
29149
  };
28087
29150
  const validated = PipeManifest(manifest);
28088
29151
  let outcome;
28089
- if (validated instanceof type56.errors) {
29152
+ if (validated instanceof type58.errors) {
28090
29153
  outcome = { kind: "invalid-manifest", error: validated.summary };
28091
29154
  } else {
28092
- const outPath = resolve32(projectRoot, scanSection.out ?? DEFAULT_PIPES_SCAN_OUT_PATH);
29155
+ const outPath = resolve34(projectRoot, scanSection.out ?? DEFAULT_PIPES_SCAN_OUT_PATH);
28093
29156
  outcome = {
28094
29157
  kind: "success",
28095
29158
  manifest: validated,
@@ -28100,10 +29163,10 @@ async function buildPipesManifest(input) {
28100
29163
  }
28101
29164
  return outcome;
28102
29165
  }
28103
- async function loadScanConfig6(configPath, readFile13) {
29166
+ async function loadScanConfig6(configPath, readFile15) {
28104
29167
  let raw = null;
28105
29168
  try {
28106
- raw = await readFile13(configPath);
29169
+ raw = await readFile15(configPath);
28107
29170
  } catch {
28108
29171
  raw = null;
28109
29172
  }
@@ -28120,7 +29183,7 @@ async function loadScanConfig6(configPath, readFile13) {
28120
29183
  }
28121
29184
  if (parseError === null) {
28122
29185
  const validated = PipesScanConfig(parsed);
28123
- if (validated instanceof type56.errors) {
29186
+ if (validated instanceof type58.errors) {
28124
29187
  result = { kind: "fail", outcome: { kind: "invalid-scan-config", configPath, error: validated.summary } };
28125
29188
  } else {
28126
29189
  result = { kind: "ok", section: validated.pipes };
@@ -28468,7 +29531,7 @@ function hasUnregisteredCandidates(snapshot) {
28468
29531
  }
28469
29532
 
28470
29533
  // packages/dbx-components-mcp/src/tools/mcp-config.tool.ts
28471
- var TOOL10 = {
29534
+ var TOOL12 = {
28472
29535
  name: "dbx_mcp_config",
28473
29536
  description: [
28474
29537
  "Inspect, validate, and configure the dbx-mcp downstream-manifest pipeline for a workspace.",
@@ -28512,7 +29575,7 @@ var TOOL10 = {
28512
29575
  required: ["op"]
28513
29576
  }
28514
29577
  };
28515
- var McpConfigArgsType = type57({
29578
+ var McpConfigArgsType = type59({
28516
29579
  op: "'status' | 'validate' | 'init' | 'refresh'",
28517
29580
  "cwd?": "string",
28518
29581
  "dryRun?": "boolean",
@@ -28520,12 +29583,12 @@ var McpConfigArgsType = type57({
28520
29583
  });
28521
29584
  function parseArgs10(rawArgs, defaultCwd) {
28522
29585
  const parsed = McpConfigArgsType(rawArgs);
28523
- if (parsed instanceof type57.errors) {
29586
+ if (parsed instanceof type59.errors) {
28524
29587
  return `Invalid arguments: ${parsed.summary}`;
28525
29588
  }
28526
29589
  let workspaceRoot = defaultCwd;
28527
29590
  if (parsed.cwd !== void 0 && parsed.cwd.length > 0) {
28528
- workspaceRoot = resolve33(defaultCwd, parsed.cwd);
29591
+ workspaceRoot = resolve35(defaultCwd, parsed.cwd);
28529
29592
  }
28530
29593
  if (parsed.explicitDirs !== void 0) {
28531
29594
  for (const dir of parsed.explicitDirs) {
@@ -28543,7 +29606,7 @@ function parseArgs10(rawArgs, defaultCwd) {
28543
29606
  explicitDirs: parsed.explicitDirs
28544
29607
  };
28545
29608
  }
28546
- async function run9(rawArgs) {
29609
+ async function run11(rawArgs) {
28547
29610
  const parsed = parseArgs10(rawArgs, process.cwd());
28548
29611
  if (typeof parsed === "string") return toolError(parsed);
28549
29612
  const snapshot = await buildSnapshot({ workspaceRoot: parsed.workspaceRoot, explicitDirs: parsed.explicitDirs });
@@ -28572,12 +29635,12 @@ async function run9(rawArgs) {
28572
29635
  }
28573
29636
  }
28574
29637
  var mcpConfigTool = {
28575
- definition: TOOL10,
28576
- run: run9
29638
+ definition: TOOL12,
29639
+ run: run11
28577
29640
  };
28578
29641
 
28579
29642
  // packages/dbx-components-mcp/src/tools/lookup-semantic-type.tool.ts
28580
- import { type as type58 } from "arktype";
29643
+ import { type as type60 } from "arktype";
28581
29644
 
28582
29645
  // packages/dbx-components-mcp/src/tools/semantic-type-lookup.formatter.ts
28583
29646
  function formatSemanticTypeEntry(entry, depth) {
@@ -28758,13 +29821,13 @@ var DBX_SEMANTIC_TYPE_LOOKUP_TOOL = {
28758
29821
  required: ["name"]
28759
29822
  }
28760
29823
  };
28761
- var LookupSemanticTypeArgsType = type58({
29824
+ var LookupSemanticTypeArgsType = type60({
28762
29825
  name: "string",
28763
29826
  "depth?": "'brief' | 'full'"
28764
29827
  });
28765
29828
  function parseLookupArgs2(raw) {
28766
29829
  const parsed = LookupSemanticTypeArgsType(raw);
28767
- if (parsed instanceof type58.errors) {
29830
+ if (parsed instanceof type60.errors) {
28768
29831
  throw new TypeError(`Invalid arguments: ${parsed.summary}`);
28769
29832
  }
28770
29833
  const result = {
@@ -28775,7 +29838,7 @@ function parseLookupArgs2(raw) {
28775
29838
  }
28776
29839
  function createSemanticTypeLookupTool(config) {
28777
29840
  const { registry } = config;
28778
- function run10(rawArgs) {
29841
+ function run12(rawArgs) {
28779
29842
  let args;
28780
29843
  let result;
28781
29844
  try {
@@ -28811,7 +29874,7 @@ function createSemanticTypeLookupTool(config) {
28811
29874
  }
28812
29875
  const tool = {
28813
29876
  definition: DBX_SEMANTIC_TYPE_LOOKUP_TOOL,
28814
- run: run10
29877
+ run: run12
28815
29878
  };
28816
29879
  return tool;
28817
29880
  }
@@ -28826,7 +29889,7 @@ function formatNotFound11(name, registry) {
28826
29889
  }
28827
29890
 
28828
29891
  // packages/dbx-components-mcp/src/tools/search-semantic-type.tool.ts
28829
- import { type as type59 } from "arktype";
29892
+ import { type as type61 } from "arktype";
28830
29893
  var DEFAULT_LIMIT4 = 25;
28831
29894
  var MAX_LIMIT4 = 100;
28832
29895
  var DBX_SEMANTIC_TYPE_SEARCH_TOOL = {
@@ -28859,7 +29922,7 @@ var DBX_SEMANTIC_TYPE_SEARCH_TOOL = {
28859
29922
  }
28860
29923
  }
28861
29924
  };
28862
- var SearchSemanticTypeArgsType = type59({
29925
+ var SearchSemanticTypeArgsType = type61({
28863
29926
  "topic?": "string",
28864
29927
  "baseType?": "string",
28865
29928
  "package?": "string",
@@ -28868,7 +29931,7 @@ var SearchSemanticTypeArgsType = type59({
28868
29931
  });
28869
29932
  function parseSearchArgs2(raw) {
28870
29933
  const parsed = SearchSemanticTypeArgsType(raw);
28871
- if (parsed instanceof type59.errors) {
29934
+ if (parsed instanceof type61.errors) {
28872
29935
  throw new TypeError(`Invalid arguments: ${parsed.summary}`);
28873
29936
  }
28874
29937
  const rawLimit = parsed.limit ?? DEFAULT_LIMIT4;
@@ -28894,7 +29957,7 @@ function nonEmpty(value) {
28894
29957
  }
28895
29958
  function createSemanticTypeSearchTool(config) {
28896
29959
  const { registry } = config;
28897
- function run10(rawArgs) {
29960
+ function run12(rawArgs) {
28898
29961
  let args;
28899
29962
  let result;
28900
29963
  try {
@@ -28907,7 +29970,7 @@ function createSemanticTypeSearchTool(config) {
28907
29970
  if (filterCount === 0) {
28908
29971
  result = toolError("At least one filter (topic, baseType, package, query) must be supplied.");
28909
29972
  } else {
28910
- const matches = applyFilters(registry, args);
29973
+ const matches = applyFilters3(registry, args);
28911
29974
  const limited = matches.slice(0, args.limit);
28912
29975
  const text = formatSemanticTypeSearchResults({
28913
29976
  query: describeFilters(args),
@@ -28919,11 +29982,11 @@ function createSemanticTypeSearchTool(config) {
28919
29982
  }
28920
29983
  const tool = {
28921
29984
  definition: DBX_SEMANTIC_TYPE_SEARCH_TOOL,
28922
- run: run10
29985
+ run: run12
28923
29986
  };
28924
29987
  return tool;
28925
29988
  }
28926
- function applyFilters(registry, args) {
29989
+ function applyFilters3(registry, args) {
28927
29990
  let candidates;
28928
29991
  if (args.topic !== void 0) {
28929
29992
  candidates = registry.findByTopic(args.topic);
@@ -28997,6 +30060,8 @@ var DBX_TOOLS = [
28997
30060
  modelFixtureLookupTool,
28998
30061
  modelFixtureScaffoldTool,
28999
30062
  modelFixtureForwardTool,
30063
+ modelTestTreeTool,
30064
+ modelTestSearchTool,
29000
30065
  // storagefile_m (model extension)
29001
30066
  storageFileMValidateAppTool,
29002
30067
  storageFileMListAppTool,