@dereekb/dbx-components-mcp 13.12.8 → 13.12.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dbx-components-mcp.js +200 -169
  2. package/package.json +3 -3
@@ -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.12.8",
8
+ version: "13.12.9",
9
9
  type: "module",
10
10
  bin: {
11
11
  "dbx-components-mcp": "dbx-components-mcp.js"
@@ -16,8 +16,8 @@ var package_default = {
16
16
  "ts-morph": "^21.0.0"
17
17
  },
18
18
  peerDependencies: {
19
- "@dereekb/dbx-cli": "13.12.8",
20
- "@dereekb/util": "13.12.8"
19
+ "@dereekb/dbx-cli": "13.12.9",
20
+ "@dereekb/util": "13.12.9"
21
21
  }
22
22
  };
23
23
 
@@ -120,18 +120,18 @@ var SPEC_SUFFIX = ".spec.ts";
120
120
  function classifySpecFile(config) {
121
121
  const { filename, parentFolderName } = config;
122
122
  let result;
123
- if (!filename.endsWith(SPEC_SUFFIX)) {
124
- result = { filename, group: "", kind: "non-spec", subgroups: [], isCanonical: false };
125
- } else {
123
+ if (filename.endsWith(SPEC_SUFFIX)) {
126
124
  const stem = filename.slice(0, -SPEC_SUFFIX.length);
127
125
  const parts = stem.split(".");
128
126
  const group = parts[0] ?? "";
129
- if (group !== parentFolderName) {
130
- result = { filename, group, kind: "non-group", subgroups: [], isCanonical: false };
131
- } else {
127
+ if (group === parentFolderName) {
132
128
  const rest = parts.slice(1);
133
129
  result = classifyRemainingSegments({ filename, group, rest });
130
+ } else {
131
+ result = { filename, group, kind: "non-group", subgroups: [], isCanonical: false };
134
132
  }
133
+ } else {
134
+ result = { filename, group: "", kind: "non-spec", subgroups: [], isCanonical: false };
135
135
  }
136
136
  return result;
137
137
  }
@@ -7425,19 +7425,24 @@ function collectLocalRoleConsts(project) {
7425
7425
  const arrays = /* @__PURE__ */ new Map();
7426
7426
  for (const sourceFile of project.getSourceFiles()) {
7427
7427
  for (const stmt of sourceFile.getVariableStatements()) {
7428
- if (!stmt.isExported()) continue;
7429
- for (const decl of stmt.getDeclarations()) {
7430
- const initializer = decl.getInitializer();
7431
- const name = decl.getName();
7432
- if (initializer === void 0) continue;
7433
- if (Node11.isStringLiteral(initializer) || Node11.isNoSubstitutionTemplateLiteral(initializer)) {
7434
- if (!scalars.has(name)) scalars.set(name, initializer.getLiteralText());
7435
- } else if (Node11.isArrayLiteralExpression(initializer) && !arrays.has(name)) arrays.set(name, initializer);
7436
- }
7428
+ collectRoleConstsFromVariableStatement(stmt, scalars, arrays);
7437
7429
  }
7438
7430
  }
7439
7431
  return { scalars, arrays };
7440
7432
  }
7433
+ function collectRoleConstsFromVariableStatement(stmt, scalars, arrays) {
7434
+ if (!stmt.isExported()) return;
7435
+ for (const decl of stmt.getDeclarations()) {
7436
+ const initializer = decl.getInitializer();
7437
+ if (initializer === void 0) continue;
7438
+ const name = decl.getName();
7439
+ if (Node11.isStringLiteral(initializer) || Node11.isNoSubstitutionTemplateLiteral(initializer)) {
7440
+ if (!scalars.has(name)) scalars.set(name, initializer.getLiteralText());
7441
+ } else if (Node11.isArrayLiteralExpression(initializer) && !arrays.has(name)) {
7442
+ arrays.set(name, initializer);
7443
+ }
7444
+ }
7445
+ }
7441
7446
  function mergeKnownRoles(builtins, localScalars) {
7442
7447
  const out = /* @__PURE__ */ new Map();
7443
7448
  for (const [name, role] of localScalars) out.set(name, role);
@@ -31443,38 +31448,57 @@ async function run5(rawArgs) {
31443
31448
  return toolError("Provide either `model` (PascalCase model name) or `identity` (the `<camelName>Identity` const string).");
31444
31449
  }
31445
31450
  const cwd = process.cwd();
31451
+ const ensureError = runEnsurePathInsideCwd(parsed.apiDir, cwd);
31446
31452
  let result;
31447
- let ensureError;
31448
- try {
31449
- ensurePathInsideCwd(parsed.apiDir, cwd);
31450
- } catch (err) {
31451
- ensureError = err instanceof Error ? err.message : String(err);
31452
- }
31453
- if (ensureError === void 0) {
31453
+ if (ensureError !== void 0) {
31454
+ result = toolError(ensureError);
31455
+ } else {
31454
31456
  const apiAbs = resolve39(cwd, parsed.apiDir);
31455
- let extraction;
31456
- let inspectError;
31457
- try {
31458
- extraction = await inspectAppFixtures(apiAbs, parsed.apiDir);
31459
- } catch (err) {
31460
- inspectError = `Failed to read fixture file: ${err instanceof Error ? err.message : String(err)}`;
31461
- }
31462
- if (inspectError === void 0 && extraction !== void 0) {
31463
- const lookupModel = parsed.model ?? identityToModel4(parsed.identity);
31464
- const entry = extraction.entries.find((e) => e.model === lookupModel);
31465
- if (entry) {
31466
- const text = parsed.format === "json" ? formatLookupAsJson2(extraction, entry) : formatLookupAsMarkdown2(extraction, entry);
31467
- result = { content: [{ type: "text", text }] };
31468
- } else {
31469
- const known = extraction.entries.map((e) => e.model).join(", ") || "(none)";
31470
- const usedIdentity = parsed.identity && !parsed.model ? ` (resolved \`identity="${parsed.identity}"\` \u2192 \`${lookupModel}\`)` : "";
31471
- result = toolError(`Model \`${lookupModel}\` not found in \`${extraction.fixturePath}\`${usedIdentity}. Known: ${known}.`);
31472
- }
31457
+ const inspection = await inspectFixturesSafe(apiAbs, parsed.apiDir);
31458
+ if (inspection.kind === "error") {
31459
+ result = toolError(inspection.message);
31473
31460
  } else {
31474
- result = toolError(inspectError ?? "Failed to inspect fixtures.");
31461
+ result = formatFixtureLookupResult({
31462
+ extraction: inspection.extraction,
31463
+ model: parsed.model,
31464
+ identity: parsed.identity,
31465
+ format: parsed.format
31466
+ });
31475
31467
  }
31468
+ }
31469
+ return result;
31470
+ }
31471
+ function runEnsurePathInsideCwd(apiDir, cwd) {
31472
+ let error;
31473
+ try {
31474
+ ensurePathInsideCwd(apiDir, cwd);
31475
+ } catch (err) {
31476
+ error = err instanceof Error ? err.message : String(err);
31477
+ }
31478
+ return error;
31479
+ }
31480
+ async function inspectFixturesSafe(apiAbs, apiDir) {
31481
+ let inspection;
31482
+ try {
31483
+ const extraction = await inspectAppFixtures(apiAbs, apiDir);
31484
+ inspection = { kind: "ok", extraction };
31485
+ } catch (err) {
31486
+ inspection = { kind: "error", message: `Failed to read fixture file: ${err instanceof Error ? err.message : String(err)}` };
31487
+ }
31488
+ return inspection;
31489
+ }
31490
+ function formatFixtureLookupResult(input) {
31491
+ const { extraction, model, identity, format } = input;
31492
+ const lookupModel = model ?? identityToModel4(identity);
31493
+ const entry = extraction.entries.find((e) => e.model === lookupModel);
31494
+ let result;
31495
+ if (entry) {
31496
+ const text = format === "json" ? formatLookupAsJson2(extraction, entry) : formatLookupAsMarkdown2(extraction, entry);
31497
+ result = { content: [{ type: "text", text }] };
31476
31498
  } else {
31477
- result = toolError(ensureError);
31499
+ const known = extraction.entries.map((e) => e.model).join(", ") || "(none)";
31500
+ const usedIdentity = identity && !model ? ` (resolved \`identity="${identity}"\` \u2192 \`${lookupModel}\`)` : "";
31501
+ result = toolError(`Model \`${lookupModel}\` not found in \`${extraction.fixturePath}\`${usedIdentity}. Known: ${known}.`);
31478
31502
  }
31479
31503
  return result;
31480
31504
  }
@@ -32927,9 +32951,7 @@ async function run8(rawArgs) {
32927
32951
  ensureError = err instanceof Error ? err.message : String(err);
32928
32952
  }
32929
32953
  let result;
32930
- if (ensureError !== void 0) {
32931
- result = toolError(ensureError);
32932
- } else {
32954
+ if (ensureError === void 0) {
32933
32955
  const apiAbs = resolve43(cwd, parsed.apiDir);
32934
32956
  let catalog;
32935
32957
  let discoveryError;
@@ -32938,13 +32960,15 @@ async function run8(rawArgs) {
32938
32960
  } catch (err) {
32939
32961
  discoveryError = `Failed to walk \`${parsed.apiDir}/src/app/function\`: ${err instanceof Error ? err.message : String(err)}`;
32940
32962
  }
32941
- if (catalog === void 0 || discoveryError !== void 0) {
32942
- result = toolError(discoveryError ?? "Failed to discover spec files.");
32943
- } else {
32963
+ if (catalog !== void 0 && discoveryError === void 0) {
32944
32964
  const filtered = parsed.group === void 0 ? catalog : filterCatalogByGroup(catalog, parsed.group);
32945
32965
  const text = parsed.format === "json" ? formatListAppAsJson(filtered) : formatListAppAsMarkdown(filtered, { group: parsed.group });
32946
32966
  result = { content: [{ type: "text", text }] };
32967
+ } else {
32968
+ result = toolError(discoveryError ?? "Failed to discover spec files.");
32947
32969
  }
32970
+ } else {
32971
+ result = toolError(ensureError);
32948
32972
  }
32949
32973
  return result;
32950
32974
  }
@@ -33237,21 +33261,15 @@ function bucketSummary(group, bucket) {
33237
33261
  var DRIFT_RULES = ["`<group>.<sub>.crud.spec.ts` \u2192 rename to `<group>.crud.<sub>.spec.ts` (`crud` belongs directly after the group name).", "`<group>.<sub>.scenario.spec.ts` \u2192 rename to `<group>.scenario.<sub>.spec.ts` (`scenario` belongs directly after the group name).", "`<group>.<rest>.spec.ts` with no `crud` / `scenario` segment \u2192 add one (default to `scenario` when in doubt)."];
33238
33262
  function formatMarkdown(report) {
33239
33263
  const lines = [];
33240
- lines.push(`# Spec convention for \`${report.group}\``, "");
33241
- lines.push(`Tests live under \`${report.apiDir}/src/app/function/${report.group}/\`. Canonical name segments:`, "");
33264
+ lines.push(`# Spec convention for \`${report.group}\``, "", `Tests live under \`${report.apiDir}/src/app/function/${report.group}/\`. Canonical name segments:`, "");
33242
33265
  for (const rec of report.recommendations) {
33243
- lines.push(`## ${rec.label} bucket`);
33244
- lines.push("", `- **Path:** \`${rec.canonicalPath}\``);
33245
- lines.push(`- **Filename:** \`${rec.canonicalFilename}\``);
33246
- lines.push(`- ${rec.summary}`);
33247
- lines.push("");
33266
+ lines.push(`## ${rec.label} bucket`, "", `- **Path:** \`${rec.canonicalPath}\``, `- **Filename:** \`${rec.canonicalFilename}\``, `- ${rec.summary}`, "");
33248
33267
  }
33249
33268
  lines.push("## Drift rules", "");
33250
33269
  for (const rule of report.driftRules) {
33251
33270
  lines.push(`- ${rule}`);
33252
33271
  }
33253
- lines.push("");
33254
- lines.push("For an inventory + drift audit across an existing API app, run `dbx_model_test_list_app`. For naming-convention enforcement (errors / warnings), run `dbx_model_test_validate_app`.");
33272
+ lines.push("", "For an inventory + drift audit across an existing API app, run `dbx_model_test_list_app`. For naming-convention enforcement (errors / warnings), run `dbx_model_test_validate_app`.");
33255
33273
  return lines.join("\n").trimEnd();
33256
33274
  }
33257
33275
  function formatJson(report) {
@@ -49770,22 +49788,9 @@ function parseArgs15(rawArgs, defaultCwd) {
49770
49788
  if (parsed instanceof type94.errors) {
49771
49789
  return `Invalid arguments: ${parsed.summary}`;
49772
49790
  }
49773
- let workspaceRoot = defaultCwd;
49774
- if (parsed.cwd !== void 0 && parsed.cwd.length > 0) {
49775
- workspaceRoot = resolve62(defaultCwd, parsed.cwd);
49776
- }
49791
+ const workspaceRoot = parsed.cwd !== void 0 && parsed.cwd.length > 0 ? resolve62(defaultCwd, parsed.cwd) : defaultCwd;
49792
+ const invalidDirError = validateExplicitDirs(parsed.explicitDirs, workspaceRoot);
49777
49793
  let result;
49778
- let invalidDirError;
49779
- if (parsed.explicitDirs !== void 0) {
49780
- for (const dir of parsed.explicitDirs) {
49781
- if (invalidDirError !== void 0) break;
49782
- try {
49783
- ensurePathInsideCwd(dir, workspaceRoot);
49784
- } catch (err) {
49785
- invalidDirError = err instanceof Error ? err.message : String(err);
49786
- }
49787
- }
49788
- }
49789
49794
  if (invalidDirError === void 0) {
49790
49795
  result = {
49791
49796
  op: parsed.op,
@@ -49798,6 +49803,20 @@ function parseArgs15(rawArgs, defaultCwd) {
49798
49803
  }
49799
49804
  return result;
49800
49805
  }
49806
+ function validateExplicitDirs(explicitDirs, workspaceRoot) {
49807
+ let invalidDirError;
49808
+ if (explicitDirs !== void 0) {
49809
+ for (const dir of explicitDirs) {
49810
+ if (invalidDirError !== void 0) break;
49811
+ try {
49812
+ ensurePathInsideCwd(dir, workspaceRoot);
49813
+ } catch (err) {
49814
+ invalidDirError = err instanceof Error ? err.message : String(err);
49815
+ }
49816
+ }
49817
+ }
49818
+ return invalidDirError;
49819
+ }
49801
49820
  async function run20(rawArgs) {
49802
49821
  const parsed = parseArgs15(rawArgs, process.cwd());
49803
49822
  if (typeof parsed === "string") return toolError(parsed);
@@ -49873,15 +49892,7 @@ async function discoverLogs(input) {
49873
49892
  } else {
49874
49893
  const primaryAbs = join24(input.basePath, input.project);
49875
49894
  const primaryExists = await pathIsDir(primaryAbs);
49876
- if (!primaryExists) {
49877
- if (input.includeSiblings) {
49878
- const siblings = await listChildDirs(input.basePath);
49879
- const logs = await collectFromProjects({ basePath: input.basePath, projects: siblings, since: input.since });
49880
- result = { logs, scannedProjects: siblings, missingBase: false, missingProject: true, fellBackToSiblings: true };
49881
- } else {
49882
- result = { logs: [], scannedProjects: [], missingBase: false, missingProject: true, fellBackToSiblings: false };
49883
- }
49884
- } else {
49895
+ if (primaryExists) {
49885
49896
  const primaryLogs = await collectFromProjects({ basePath: input.basePath, projects: [input.project], since: input.since });
49886
49897
  if (primaryLogs.length === 0 && input.includeSiblings) {
49887
49898
  const siblings = (await listChildDirs(input.basePath)).filter((p) => p !== input.project);
@@ -49890,6 +49901,12 @@ async function discoverLogs(input) {
49890
49901
  } else {
49891
49902
  result = { logs: primaryLogs, scannedProjects: [input.project], missingBase: false, missingProject: false, fellBackToSiblings: false };
49892
49903
  }
49904
+ } else if (input.includeSiblings) {
49905
+ const siblings = await listChildDirs(input.basePath);
49906
+ const logs = await collectFromProjects({ basePath: input.basePath, projects: siblings, since: input.since });
49907
+ result = { logs, scannedProjects: siblings, missingBase: false, missingProject: true, fellBackToSiblings: true };
49908
+ } else {
49909
+ result = { logs: [], scannedProjects: [], missingBase: false, missingProject: true, fellBackToSiblings: false };
49893
49910
  }
49894
49911
  }
49895
49912
  return result;
@@ -49917,40 +49934,55 @@ async function listChildDirs(absPath) {
49917
49934
  async function collectFromProjects(input) {
49918
49935
  const collected = [];
49919
49936
  for (const project of input.projects) {
49920
- const projectDir = join24(input.basePath, project);
49921
- let entries = [];
49922
- try {
49923
- const dirents = await readdir15(projectDir, { withFileTypes: true });
49924
- entries = dirents.map((d) => ({ name: d.name, isFile: d.isFile() || d.isSymbolicLink() }));
49925
- } catch {
49926
- entries = [];
49927
- }
49928
- for (const entry of entries) {
49929
- if (entry.isFile && entry.name.endsWith(".md")) {
49930
- const absolutePath = join24(projectDir, entry.name);
49931
- let info;
49932
- try {
49933
- info = await stat22(absolutePath);
49934
- } catch {
49935
- info = void 0;
49936
- }
49937
- if (info !== void 0 && info.isFile() && info.mtimeMs >= input.since) {
49938
- const ref = {
49939
- absolutePath,
49940
- relativePath: join24(project, entry.name),
49941
- project,
49942
- fileName: basename9(entry.name),
49943
- mtimeMs: info.mtimeMs,
49944
- sizeBytes: info.size
49945
- };
49946
- collected.push(ref);
49947
- }
49948
- }
49949
- }
49937
+ const refs = await collectProjectLogs({ basePath: input.basePath, project, since: input.since });
49938
+ collected.push(...refs);
49950
49939
  }
49951
49940
  collected.sort((a, b) => b.mtimeMs - a.mtimeMs);
49952
49941
  return collected;
49953
49942
  }
49943
+ async function collectProjectLogs(input) {
49944
+ const projectDir = join24(input.basePath, input.project);
49945
+ const entries = await readMarkdownEntries(projectDir);
49946
+ const refs = [];
49947
+ for (const entry of entries) {
49948
+ const ref = await buildLogRefIfRecent({ projectDir, project: input.project, fileName: entry, since: input.since });
49949
+ if (ref !== void 0) {
49950
+ refs.push(ref);
49951
+ }
49952
+ }
49953
+ return refs;
49954
+ }
49955
+ async function readMarkdownEntries(projectDir) {
49956
+ let entries = [];
49957
+ try {
49958
+ const dirents = await readdir15(projectDir, { withFileTypes: true });
49959
+ entries = dirents.filter((d) => (d.isFile() || d.isSymbolicLink()) && d.name.endsWith(".md")).map((d) => d.name);
49960
+ } catch {
49961
+ entries = [];
49962
+ }
49963
+ return entries;
49964
+ }
49965
+ async function buildLogRefIfRecent(input) {
49966
+ const absolutePath = join24(input.projectDir, input.fileName);
49967
+ let info;
49968
+ try {
49969
+ info = await stat22(absolutePath);
49970
+ } catch {
49971
+ info = void 0;
49972
+ }
49973
+ let ref;
49974
+ if (info !== void 0 && info.isFile() && info.mtimeMs >= input.since) {
49975
+ ref = {
49976
+ absolutePath,
49977
+ relativePath: join24(input.project, input.fileName),
49978
+ project: input.project,
49979
+ fileName: basename9(input.fileName),
49980
+ mtimeMs: info.mtimeMs,
49981
+ sizeBytes: info.size
49982
+ };
49983
+ }
49984
+ return ref;
49985
+ }
49954
49986
 
49955
49987
  // packages/dbx-components-mcp/src/tools/log-search/format-results.ts
49956
49988
  var MAX_LIST_SNIPPET_LENGTH = 240;
@@ -49991,13 +50023,7 @@ function formatKeywordResults(header, hits) {
49991
50023
  lines.push(`${hits.length} match(es) of ${header.totalCandidates} log(s) in window.`, "");
49992
50024
  for (const hit of hits) {
49993
50025
  const entry = hit.entry;
49994
- lines.push(`### ${entry.title}`);
49995
- lines.push(`_${formatMeta(entry)}_`);
49996
- lines.push("");
49997
- lines.push("```");
49998
- lines.push(sanitizeFence(hit.snippet));
49999
- lines.push("```");
50000
- lines.push("");
50026
+ lines.push(`### ${entry.title}`, `_${formatMeta(entry)}_`, "", "```", sanitizeFence(hit.snippet), "```", "");
50001
50027
  }
50002
50028
  }
50003
50029
  return lines.join("\n").trimEnd();
@@ -50009,14 +50035,10 @@ function buildHeading(header) {
50009
50035
  function renderEntry(entry, matchedSuffix, maxSnippetLen) {
50010
50036
  const lines = [];
50011
50037
  const suffix = matchedSuffix ?? "";
50012
- lines.push(`### ${entry.title}${suffix}`);
50013
- lines.push(`_${formatMeta(entry)}_`);
50038
+ lines.push(`### ${entry.title}${suffix}`, `_${formatMeta(entry)}_`);
50014
50039
  const snippet = pickSnippet(entry, maxSnippetLen);
50015
50040
  if (snippet !== void 0) {
50016
- lines.push("");
50017
- for (const line of snippet.split("\n")) {
50018
- lines.push(`> ${line}`);
50019
- }
50041
+ lines.push("", ...snippet.split("\n").map((line) => `> ${line}`));
50020
50042
  }
50021
50043
  lines.push("");
50022
50044
  return lines;
@@ -50042,7 +50064,7 @@ function pickSnippet(entry, maxLen) {
50042
50064
  return snippet === void 0 ? void 0 : sanitizeFence(snippet);
50043
50065
  }
50044
50066
  function sanitizeFence(text) {
50045
- return text.replace(/```/g, "`\u200B``");
50067
+ return text.replaceAll("```", "`\u200B``");
50046
50068
  }
50047
50069
 
50048
50070
  // packages/dbx-components-mcp/src/tools/log-search/keyword-match.ts
@@ -50143,34 +50165,35 @@ function extractSectionBody(lines, headingRegex) {
50143
50165
  return body;
50144
50166
  }
50145
50167
  function extractFirstFencedBlock(lines) {
50146
- let openIdx = -1;
50147
- for (const [i, line] of lines.entries()) {
50148
- if (line.startsWith("```")) {
50149
- openIdx = i;
50150
- break;
50151
- }
50152
- }
50168
+ const openIdx = findLineStarting(lines, "```", 0);
50153
50169
  let result = { subject: void 0, body: void 0 };
50154
50170
  if (openIdx >= 0) {
50155
- let closeIdx = -1;
50156
- for (let i = openIdx + 1; i < lines.length; i += 1) {
50157
- if (lines[i].startsWith("```")) {
50158
- closeIdx = i;
50159
- break;
50160
- }
50161
- }
50171
+ const closeIdx = findLineStarting(lines, "```", openIdx + 1);
50162
50172
  if (closeIdx > openIdx) {
50163
- const inner = lines.slice(openIdx + 1, closeIdx);
50164
- const subject = inner[0]?.trim();
50165
- const body = inner.slice(2).join("\n").trim();
50166
- result = {
50167
- subject: subject !== void 0 && subject.length > 0 ? subject : void 0,
50168
- body: body.length > 0 ? body : void 0
50169
- };
50173
+ result = sliceFencedBlock(lines, openIdx, closeIdx);
50170
50174
  }
50171
50175
  }
50172
50176
  return result;
50173
50177
  }
50178
+ function findLineStarting(lines, prefix, fromIndex) {
50179
+ let found = -1;
50180
+ for (let i = fromIndex; i < lines.length; i += 1) {
50181
+ if (lines[i].startsWith(prefix)) {
50182
+ found = i;
50183
+ break;
50184
+ }
50185
+ }
50186
+ return found;
50187
+ }
50188
+ function sliceFencedBlock(lines, openIdx, closeIdx) {
50189
+ const inner = lines.slice(openIdx + 1, closeIdx);
50190
+ const subject = inner[0]?.trim();
50191
+ const body = inner.slice(2).join("\n").trim();
50192
+ return {
50193
+ subject: subject !== void 0 && subject.length > 0 ? subject : void 0,
50194
+ body: body.length > 0 ? body : void 0
50195
+ };
50196
+ }
50174
50197
  function isIsoDate(value) {
50175
50198
  return value !== void 0 && /^\d{4}-\d{2}-\d{2}$/.test(value);
50176
50199
  }
@@ -53234,26 +53257,7 @@ function createAuthRoleLookupTool(input) {
53234
53257
  if (parsed instanceof type103.errors) {
53235
53258
  result = toolError(`Invalid arguments: ${parsed.summary}`);
53236
53259
  } else {
53237
- const { topic, tag, model, verb, depth = "full" } = parsed;
53238
- let text;
53239
- if (model !== void 0 || verb !== void 0) {
53240
- text = formatReverseLookup({ registry, model, verb });
53241
- } else if (tag !== void 0 && tag.length > 0) {
53242
- text = formatTagLookup(registry, tag, depth);
53243
- } else if (topic !== void 0 && topic.length > 0) {
53244
- const normalized = topic.trim();
53245
- if (isCatalogTopic3(normalized)) {
53246
- text = formatCatalog11(registry.roles);
53247
- } else {
53248
- const role = registry.findRole(normalized);
53249
- if (role === void 0) {
53250
- text = formatNotFound19(normalized, registry.roles);
53251
- } else {
53252
- const claims = registry.findClaimsForRole(role.role);
53253
- text = formatRole(role, claims, depth);
53254
- }
53255
- }
53256
- }
53260
+ const text = dispatchRoleLookup(registry, parsed);
53257
53261
  result = text === void 0 ? toolError("Provide one of `topic`, `tag`, or `model` + `verb`.") : { content: [{ type: "text", text }] };
53258
53262
  }
53259
53263
  return result;
@@ -53261,6 +53265,33 @@ function createAuthRoleLookupTool(input) {
53261
53265
  };
53262
53266
  return tool;
53263
53267
  }
53268
+ function dispatchRoleLookup(registry, args) {
53269
+ const { topic, tag, model, verb, depth = "full" } = args;
53270
+ let text;
53271
+ if (model !== void 0 || verb !== void 0) {
53272
+ text = formatReverseLookup({ registry, model, verb });
53273
+ } else if (tag !== void 0 && tag.length > 0) {
53274
+ text = formatTagLookup(registry, tag, depth);
53275
+ } else if (topic !== void 0 && topic.length > 0) {
53276
+ text = formatTopicLookup(registry, topic.trim(), depth);
53277
+ }
53278
+ return text;
53279
+ }
53280
+ function formatTopicLookup(registry, normalized, depth) {
53281
+ let text;
53282
+ if (isCatalogTopic3(normalized)) {
53283
+ text = formatCatalog11(registry.roles);
53284
+ } else {
53285
+ const role = registry.findRole(normalized);
53286
+ if (role === void 0) {
53287
+ text = formatNotFound19(normalized, registry.roles);
53288
+ } else {
53289
+ const claims = registry.findClaimsForRole(role.role);
53290
+ text = formatRole(role, claims, depth);
53291
+ }
53292
+ }
53293
+ return text;
53294
+ }
53264
53295
  function isCatalogTopic3(topic) {
53265
53296
  const lowered = topic.toLowerCase();
53266
53297
  return lowered === "list" || lowered === "all" || lowered === "catalog";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dereekb/dbx-components-mcp",
3
- "version": "13.12.8",
3
+ "version": "13.12.9",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "dbx-components-mcp": "dbx-components-mcp.js"
@@ -11,7 +11,7 @@
11
11
  "ts-morph": "^21.0.0"
12
12
  },
13
13
  "peerDependencies": {
14
- "@dereekb/dbx-cli": "13.12.8",
15
- "@dereekb/util": "13.12.8"
14
+ "@dereekb/dbx-cli": "13.12.9",
15
+ "@dereekb/util": "13.12.9"
16
16
  }
17
17
  }