callman-mcp 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CHANGELOG.md +37 -27
  2. package/README.md +33 -11
  3. package/dist/client/api.d.ts +83 -15
  4. package/dist/client/api.d.ts.map +1 -1
  5. package/dist/client/api.js +106 -21
  6. package/dist/client/api.js.map +1 -1
  7. package/dist/client/errors.d.ts.map +1 -1
  8. package/dist/client/errors.js +46 -11
  9. package/dist/client/errors.js.map +1 -1
  10. package/dist/client/types.d.ts +231 -14
  11. package/dist/client/types.d.ts.map +1 -1
  12. package/dist/domain/diagram/build.d.ts +17 -17
  13. package/dist/domain/diagram/build.d.ts.map +1 -1
  14. package/dist/domain/diagram/build.js +3 -3
  15. package/dist/domain/diagram/build.js.map +1 -1
  16. package/dist/domain/diagram/layout.d.ts +1 -3
  17. package/dist/domain/diagram/layout.d.ts.map +1 -1
  18. package/dist/domain/diagram/layout.js +3 -9
  19. package/dist/domain/diagram/layout.js.map +1 -1
  20. package/dist/domain/diagram/patch.d.ts +22 -723
  21. package/dist/domain/diagram/patch.d.ts.map +1 -1
  22. package/dist/domain/diagram/patch.js +0 -53
  23. package/dist/domain/diagram/patch.js.map +1 -1
  24. package/dist/domain/diagram/summarize.d.ts +0 -1
  25. package/dist/domain/diagram/summarize.d.ts.map +1 -1
  26. package/dist/domain/diagram/summarize.js +0 -1
  27. package/dist/domain/diagram/summarize.js.map +1 -1
  28. package/dist/domain/uiTest/compose.d.ts +55 -0
  29. package/dist/domain/uiTest/compose.d.ts.map +1 -0
  30. package/dist/domain/uiTest/compose.js +228 -0
  31. package/dist/domain/uiTest/compose.js.map +1 -0
  32. package/dist/domain/uiTest/summarize.d.ts +273 -0
  33. package/dist/domain/uiTest/summarize.d.ts.map +1 -0
  34. package/dist/domain/uiTest/summarize.js +145 -0
  35. package/dist/domain/uiTest/summarize.js.map +1 -0
  36. package/dist/lib/truncate.d.ts +1 -1
  37. package/dist/lib/truncate.d.ts.map +1 -1
  38. package/dist/lib/truncate.js.map +1 -1
  39. package/dist/resources/docs/diagramSchema.d.ts +1 -1
  40. package/dist/resources/docs/diagramSchema.d.ts.map +1 -1
  41. package/dist/resources/docs/diagramSchema.js +1 -33
  42. package/dist/resources/docs/diagramSchema.js.map +1 -1
  43. package/dist/resources/docs/overview.d.ts +1 -1
  44. package/dist/resources/docs/overview.d.ts.map +1 -1
  45. package/dist/resources/docs/overview.js +13 -7
  46. package/dist/resources/docs/overview.js.map +1 -1
  47. package/dist/resources/docs/uiTests.d.ts +2 -0
  48. package/dist/resources/docs/uiTests.d.ts.map +1 -0
  49. package/dist/resources/docs/uiTests.js +101 -0
  50. package/dist/resources/docs/uiTests.js.map +1 -0
  51. package/dist/resources/generated/aiPacks.d.ts +1 -1
  52. package/dist/resources/generated/aiPacks.js +2 -2
  53. package/dist/resources/index.d.ts.map +1 -1
  54. package/dist/resources/index.js +13 -2
  55. package/dist/resources/index.js.map +1 -1
  56. package/dist/server.d.ts +1 -1
  57. package/dist/server.d.ts.map +1 -1
  58. package/dist/server.js +2 -2
  59. package/dist/server.js.map +1 -1
  60. package/dist/tools/catalog.d.ts +1 -1
  61. package/dist/tools/catalog.d.ts.map +1 -1
  62. package/dist/tools/catalog.js +31 -5
  63. package/dist/tools/catalog.js.map +1 -1
  64. package/dist/tools/diagrams.d.ts.map +1 -1
  65. package/dist/tools/diagrams.js +42 -328
  66. package/dist/tools/diagrams.js.map +1 -1
  67. package/dist/tools/index.d.ts.map +1 -1
  68. package/dist/tools/index.js +6 -0
  69. package/dist/tools/index.js.map +1 -1
  70. package/dist/tools/lookups.d.ts +19 -5
  71. package/dist/tools/lookups.d.ts.map +1 -1
  72. package/dist/tools/lookups.js +77 -41
  73. package/dist/tools/lookups.js.map +1 -1
  74. package/dist/tools/shared.d.ts +5 -0
  75. package/dist/tools/shared.d.ts.map +1 -1
  76. package/dist/tools/shared.js +10 -0
  77. package/dist/tools/shared.js.map +1 -1
  78. package/dist/tools/uiTestAdmin.d.ts +4 -0
  79. package/dist/tools/uiTestAdmin.d.ts.map +1 -0
  80. package/dist/tools/uiTestAdmin.js +509 -0
  81. package/dist/tools/uiTestAdmin.js.map +1 -0
  82. package/dist/tools/uiTestRuns.d.ts +24 -0
  83. package/dist/tools/uiTestRuns.d.ts.map +1 -0
  84. package/dist/tools/uiTestRuns.js +367 -0
  85. package/dist/tools/uiTestRuns.js.map +1 -0
  86. package/dist/tools/uiTestShared.d.ts +236 -0
  87. package/dist/tools/uiTestShared.d.ts.map +1 -0
  88. package/dist/tools/uiTestShared.js +187 -0
  89. package/dist/tools/uiTestShared.js.map +1 -0
  90. package/dist/tools/uiTests.d.ts +4 -0
  91. package/dist/tools/uiTests.d.ts.map +1 -0
  92. package/dist/tools/uiTests.js +572 -0
  93. package/dist/tools/uiTests.js.map +1 -0
  94. package/dist-cjs/client/api.js +106 -21
  95. package/dist-cjs/client/errors.js +46 -11
  96. package/dist-cjs/domain/diagram/build.js +3 -3
  97. package/dist-cjs/domain/diagram/layout.js +3 -10
  98. package/dist-cjs/domain/diagram/patch.js +1 -54
  99. package/dist-cjs/domain/diagram/summarize.js +0 -1
  100. package/dist-cjs/domain/uiTest/compose.js +242 -0
  101. package/dist-cjs/domain/uiTest/summarize.js +155 -0
  102. package/dist-cjs/resources/docs/diagramSchema.js +1 -33
  103. package/dist-cjs/resources/docs/overview.js +13 -7
  104. package/dist-cjs/resources/docs/uiTests.js +103 -0
  105. package/dist-cjs/resources/generated/aiPacks.js +2 -2
  106. package/dist-cjs/resources/index.js +11 -0
  107. package/dist-cjs/server.js +2 -2
  108. package/dist-cjs/tools/catalog.js +31 -5
  109. package/dist-cjs/tools/diagrams.js +37 -323
  110. package/dist-cjs/tools/index.js +6 -0
  111. package/dist-cjs/tools/lookups.js +83 -46
  112. package/dist-cjs/tools/shared.js +12 -1
  113. package/dist-cjs/tools/uiTestAdmin.js +512 -0
  114. package/dist-cjs/tools/uiTestRuns.js +372 -0
  115. package/dist-cjs/tools/uiTestShared.js +202 -0
  116. package/dist-cjs/tools/uiTests.js +575 -0
  117. package/package.json +3 -3
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sameName = exports.connectionResolverFor = exports.loadConnections = exports.resolveDiagram = exports.resolveDiagramFolder = exports.diagramFolderPath = exports.diagramFolderRows = exports.loadDiagramFolders = exports.loadDiagrams = exports.resolveScenarioFolder = exports.resolveScenario = exports.loadScenarioCatalog = exports.resolveEnvironment = exports.loadEnvironments = exports.resolveRequest = exports.searchRequests = exports.requestIdsInFolder = exports.resolveFolder = exports.loadTree = exports.resolveCollection = exports.findEnvironment = exports.findRequest = exports.findCollection = exports.findInWorkspaces = exports.workspaceTag = exports.workspacesForListing = exports.isAllWorkspaces = exports.loadCollections = void 0;
3
+ exports.sameName = exports.connectionResolverFor = exports.loadConnections = exports.resolveUiTest = exports.resolveUiTestFolder = exports.uiTestFolderSubtree = exports.loadUiTestFolders = exports.loadUiTests = exports.resolveDiagram = exports.loadDiagrams = exports.resolveScenarioFolder = exports.resolveScenario = exports.loadScenarioCatalog = exports.resolveEnvironment = exports.loadEnvironments = exports.resolveRequest = exports.searchRequests = exports.requestIdsInFolder = exports.resolveFolder = exports.loadTree = exports.resolveCollection = exports.findEnvironment = exports.findRequest = exports.findCollection = exports.findInWorkspaces = exports.workspaceTag = exports.workspacesForListing = exports.isAllWorkspaces = exports.loadCollections = void 0;
4
4
  const errors_js_1 = require("../client/errors.js");
5
5
  const requestIntegrations_js_1 = require("../domain/requestIntegrations.js");
6
6
  const resolve_js_1 = require("../domain/resolve.js");
@@ -240,51 +240,6 @@ const resolveScenarioFolder = async (ctx, ws, ref) => (0, resolve_js_1.resolveRe
240
240
  exports.resolveScenarioFolder = resolveScenarioFolder;
241
241
  const loadDiagrams = (ctx) => ctx.cache.getOrSet("diagrams", () => ctx.api.listDiagrams());
242
242
  exports.loadDiagrams = loadDiagrams;
243
- // ── diagram folders (the token owner's private library tree) ──────────
244
- const loadDiagramFolders = (ctx) => ctx.cache.getOrSet("diagram-folders", () => ctx.api.listDiagramFolders());
245
- exports.loadDiagramFolders = loadDiagramFolders;
246
- // The tree as rows with paths ("Architecture/Payments"), depth-first,
247
- // siblings by name — what a model refers to folders by. An older backend
248
- // without the route yields no rows (every diagram is then at the top level).
249
- const diagramFolderRows = async (ctx) => {
250
- let folders;
251
- try {
252
- folders = await (0, exports.loadDiagramFolders)(ctx);
253
- }
254
- catch (error) {
255
- if (error instanceof errors_js_1.CallmanApiError && (error.status === 404 || error.status === 403))
256
- return [];
257
- throw error;
258
- }
259
- const byName = (a, b) => a.name.localeCompare(b.name, undefined, { numeric: true, sensitivity: "base" }) || a.id.localeCompare(b.id);
260
- const out = [];
261
- const seen = new Set();
262
- const walk = (parentId, prefix, depth) => {
263
- for (const folder of folders.filter((entry) => entry.parentId === parentId).sort(byName)) {
264
- if (seen.has(folder.id))
265
- continue; // a corrupt cycle must not recurse forever
266
- seen.add(folder.id);
267
- const path = prefix ? `${prefix}/${folder.name}` : folder.name;
268
- out.push({ id: folder.id, name: folder.name, parentId: folder.parentId, path, depth });
269
- walk(folder.id, path, depth + 1);
270
- }
271
- };
272
- walk(null, "", 0);
273
- return out;
274
- };
275
- exports.diagramFolderRows = diagramFolderRows;
276
- const diagramFolderPath = (rows, folderId) => folderId ? (rows.find((row) => row.id === folderId)?.path ?? null) : null;
277
- exports.diagramFolderPath = diagramFolderPath;
278
- // A folder by id, exact path, exact name (unique) or unique substring.
279
- const resolveDiagramFolder = async (ctx, ref, options = {}) => {
280
- const rows = await (0, exports.diagramFolderRows)(ctx);
281
- return (0, resolve_js_1.resolveRef)("diagram folder", ref, rows, {
282
- describe: (folder) => ({ path: folder.path }),
283
- aliases: (folder) => [folder.path],
284
- exact: options.exact,
285
- });
286
- };
287
- exports.resolveDiagramFolder = resolveDiagramFolder;
288
243
  const resolveDiagram = async (ctx, ref, options = {}) => {
289
244
  if ((0, ids_js_1.isObjectId)(ref))
290
245
  return { item: await ctx.api.getDiagram(ref), matched: "id" };
@@ -296,6 +251,88 @@ const resolveDiagram = async (ctx, ref, options = {}) => {
296
251
  return { ...resolved, item: await ctx.api.getDiagram(resolved.item.id) };
297
252
  };
298
253
  exports.resolveDiagram = resolveDiagram;
254
+ const loadUiTests = (ctx) => ctx.cache.getOrSet("uitests:list", () => ctx.api.listUiTests(true));
255
+ exports.loadUiTests = loadUiTests;
256
+ const loadUiTestFolders = (ctx) => ctx.cache.getOrSet("uitests:folders", async () => {
257
+ const raw = await ctx.api.listUiTestFolders();
258
+ const byId = new Map(raw.map((folder) => [folder.clientId, folder]));
259
+ const pathOf = (folder) => {
260
+ const names = [folder.name];
261
+ const seen = new Set([folder.clientId]);
262
+ let parent = folder.parentId ? byId.get(folder.parentId) : undefined;
263
+ while (parent && !seen.has(parent.clientId)) {
264
+ names.unshift(parent.name);
265
+ seen.add(parent.clientId);
266
+ parent = parent.parentId ? byId.get(parent.parentId) : undefined;
267
+ }
268
+ return { path: names.join("/"), depth: names.length - 1 };
269
+ };
270
+ return raw.map((folder) => ({
271
+ id: folder.clientId,
272
+ name: folder.name,
273
+ parentId: folder.parentId ?? null,
274
+ ...pathOf(folder),
275
+ workspaceId: folder.workspaceId,
276
+ groupId: folder.groupId ?? null,
277
+ sortOrder: folder.sortOrder ?? 0,
278
+ }));
279
+ });
280
+ exports.loadUiTestFolders = loadUiTestFolders;
281
+ // Folder ids of `folderId` and every folder below it.
282
+ const uiTestFolderSubtree = (folders, folderId) => {
283
+ const out = new Set([folderId]);
284
+ let grew = true;
285
+ while (grew) {
286
+ grew = false;
287
+ for (const folder of folders) {
288
+ if (folder.parentId && out.has(folder.parentId) && !out.has(folder.id)) {
289
+ out.add(folder.id);
290
+ grew = true;
291
+ }
292
+ }
293
+ }
294
+ return out;
295
+ };
296
+ exports.uiTestFolderSubtree = uiTestFolderSubtree;
297
+ const workspaceFilter = async (ctx, workspace) => workspace && workspace.trim() && !(0, exports.isAllWorkspaces)(workspace) ? ctx.resolveWorkspace(workspace) : null;
298
+ const resolveUiTestFolder = async (ctx, workspace, ref, options = {}) => {
299
+ const ws = await workspaceFilter(ctx, workspace);
300
+ const folders = (await (0, exports.loadUiTestFolders)(ctx)).filter((folder) => !ws || folder.workspaceId === ws.id);
301
+ return (0, resolve_js_1.resolveRef)("UI-test folder", ref, folders, { describe: (folder) => ({ path: folder.path }), aliases: (folder) => [folder.path], exact: options.exact });
302
+ };
303
+ exports.resolveUiTestFolder = resolveUiTestFolder;
304
+ // A flow by clientId or name (unique across the workspaces in scope). The
305
+ // cached list may miss a flow created a moment ago — an unknown ref is tried
306
+ // as a clientId before giving up.
307
+ const resolveUiTest = async (ctx, workspace, ref, options = {}) => {
308
+ const ws = await workspaceFilter(ctx, workspace);
309
+ const [flows, workspaces, folders] = await Promise.all([(0, exports.loadUiTests)(ctx), ctx.listWorkspaces(), (0, exports.loadUiTestFolders)(ctx).catch(() => [])]);
310
+ const workspaceName = new Map(workspaces.map((entry) => [entry.id, entry.name]));
311
+ const folderPath = new Map(folders.map((folder) => [folder.id, folder.path]));
312
+ const items = flows.filter((flow) => !ws || flow.workspaceId === ws.id).map((flow) => ({ ...flow, id: flow.clientId }));
313
+ try {
314
+ return (0, resolve_js_1.resolveRef)("UI test", ref, items, {
315
+ describe: (flow) => ({ platform: flow.platform, folder: flow.folderId ? (folderPath.get(flow.folderId) ?? null) : null, ...(workspaces.length > 1 ? { workspace: workspaceName.get(flow.workspaceId) ?? flow.workspaceId } : {}) }),
316
+ exact: options.exact,
317
+ });
318
+ }
319
+ catch (error) {
320
+ if (!(error instanceof errors_js_1.ToolInputError) || error.code !== "REF_NOT_FOUND" || /\s/.test(ref.trim()))
321
+ throw error;
322
+ try {
323
+ const fresh = await ctx.api.getUiTest(ref.trim());
324
+ if (ws && fresh.workspaceId !== ws.id)
325
+ throw error;
326
+ return { item: { ...fresh, id: fresh.clientId }, matched: "id" };
327
+ }
328
+ catch (lookup) {
329
+ if (lookup instanceof errors_js_1.CallmanApiError && (lookup.status === 404 || lookup.status === 400))
330
+ throw error;
331
+ throw lookup;
332
+ }
333
+ }
334
+ };
335
+ exports.resolveUiTest = resolveUiTest;
299
336
  const loadConnections = (ctx, ws) => ctx.cache.getOrSet(`connections:${ws}`, () => ctx.api.listConnections(ws));
300
337
  exports.loadConnections = loadConnections;
301
338
  // Connection resolver for request integration steps — loaded only when a
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.requireConfirm = exports.dryRunArg = exports.confirmArg = exports.cursorArgs = exports.refArg = exports.workspaceArg = exports.RUN = exports.DESTRUCTIVE = exports.IDEMPOTENT_WRITE = exports.WRITE = exports.READ = exports.guarded = exports.failureOf = exports.toolFailure = exports.ok = void 0;
3
+ exports.requireConfirm = exports.dryRunArg = exports.confirmArg = exports.cursorArgs = exports.refArg = exports.workspaceArg = exports.RUN = exports.DESTRUCTIVE = exports.IDEMPOTENT_WRITE = exports.WRITE = exports.READ = exports.guarded = exports.failureOf = exports.toolFailure = exports.okWithImages = exports.ok = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const errors_js_1 = require("../client/errors.js");
6
6
  const truncate_js_1 = require("../lib/truncate.js");
@@ -17,6 +17,17 @@ const ok = (structured, text) => ({
17
17
  structuredContent: structured,
18
18
  });
19
19
  exports.ok = ok;
20
+ // `ok` plus MCP image blocks (screenshots): the structured result stays JSON,
21
+ // each image follows as { type: "image", data: <base64>, mimeType } preceded
22
+ // by a one-line caption so the model knows which is which.
23
+ const okWithImages = (structured, images) => {
24
+ const result = (0, exports.ok)(structured);
25
+ for (const image of images) {
26
+ result.content.push({ type: "text", text: image.caption }, { type: "image", data: image.data, mimeType: image.mimeType });
27
+ }
28
+ return result;
29
+ };
30
+ exports.okWithImages = okWithImages;
20
31
  const toolFailure = (error) => {
21
32
  let payload;
22
33
  if (error instanceof errors_js_1.CallmanApiError) {