@frontmcp/testing 0.12.2 → 1.0.0-beta.1

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 (42) hide show
  1. package/assertions/mcp-assertions.d.ts +1 -1
  2. package/assertions/mcp-assertions.d.ts.map +1 -1
  3. package/client/mcp-test-client.builder.d.ts +1 -1
  4. package/client/mcp-test-client.d.ts.map +1 -1
  5. package/client/mcp-test-client.types.d.ts +3 -3
  6. package/client/mcp-test-client.types.d.ts.map +1 -1
  7. package/errors/index.d.ts.map +1 -1
  8. package/esm/fixtures/index.mjs +239 -36
  9. package/esm/index.mjs +267 -112
  10. package/esm/matchers/index.mjs +8 -32
  11. package/esm/package.json +5 -5
  12. package/esm/perf/index.mjs +239 -36
  13. package/esm/setup.mjs +8 -32
  14. package/example-tools/index.d.ts +1 -1
  15. package/example-tools/index.d.ts.map +1 -1
  16. package/example-tools/tool-configs.d.ts +4 -10
  17. package/example-tools/tool-configs.d.ts.map +1 -1
  18. package/fixtures/index.js +232 -36
  19. package/index.d.ts +2 -1
  20. package/index.d.ts.map +1 -1
  21. package/index.js +264 -114
  22. package/matchers/index.js +8 -32
  23. package/package.json +5 -5
  24. package/perf/index.js +232 -36
  25. package/platform/platform-client-info.d.ts +2 -1
  26. package/platform/platform-client-info.d.ts.map +1 -1
  27. package/platform/platform-types.d.ts +11 -16
  28. package/platform/platform-types.d.ts.map +1 -1
  29. package/playwright/index.d.ts +1 -1
  30. package/raw-client/index.d.ts +7 -0
  31. package/raw-client/index.d.ts.map +1 -0
  32. package/server/index.d.ts +1 -1
  33. package/server/index.d.ts.map +1 -1
  34. package/server/port-registry.d.ts +24 -6
  35. package/server/port-registry.d.ts.map +1 -1
  36. package/server/test-server.d.ts +1 -1
  37. package/server/test-server.d.ts.map +1 -1
  38. package/setup.js +8 -32
  39. package/ui/ui-assertions.d.ts +3 -4
  40. package/ui/ui-assertions.d.ts.map +1 -1
  41. package/ui/ui-matchers.d.ts +1 -2
  42. package/ui/ui-matchers.d.ts.map +1 -1
package/esm/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/testing",
3
- "version": "0.12.2",
3
+ "version": "1.0.0-beta.1",
4
4
  "description": "E2E testing framework for FrontMCP servers - MCP client, auth mocks, Playwright integration",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "homepage": "https://docs.agentfront.dev",
@@ -87,8 +87,8 @@
87
87
  "./esm": null
88
88
  },
89
89
  "peerDependencies": {
90
- "@frontmcp/sdk": "0.12.2",
91
- "@frontmcp/ui": "0.12.2",
90
+ "@frontmcp/sdk": "1.0.0-beta.1",
91
+ "@frontmcp/ui": "1.0.0-beta.1",
92
92
  "@playwright/test": "^1.40.0",
93
93
  "jest": "^29.0.0",
94
94
  "@jest/globals": "^29.0.0"
@@ -111,8 +111,8 @@
111
111
  "node": ">=22.0.0"
112
112
  },
113
113
  "dependencies": {
114
- "@frontmcp/utils": "0.12.2",
115
- "@modelcontextprotocol/sdk": "1.26.0",
114
+ "@frontmcp/utils": "1.0.0-beta.1",
115
+ "@frontmcp/protocol": "1.0.0-beta.1",
116
116
  "jose": "^6.0.11",
117
117
  "tslib": "^2.3.0"
118
118
  },
@@ -1,3 +1,10 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
1
8
  // libs/testing/src/perf/metrics-collector.ts
2
9
  function isGcAvailable() {
3
10
  return typeof global.gc === "function";
@@ -829,7 +836,7 @@ function getPlatformCapabilities(platform) {
829
836
  ...baseCapabilities,
830
837
  experimental: {
831
838
  [MCP_APPS_EXTENSION_KEY]: {
832
- mimeTypes: ["text/html+mcp"]
839
+ mimeTypes: ["text/html;profile=mcp-app"]
833
840
  }
834
841
  }
835
842
  };
@@ -950,7 +957,7 @@ var McpTestClientBuilder = class {
950
957
  * .withCapabilities({
951
958
  * sampling: {},
952
959
  * experimental: {
953
- * 'io.modelcontextprotocol/ui': { mimeTypes: ['text/html+mcp'] }
960
+ * 'io.modelcontextprotocol/ui': { mimeTypes: ['text/html;profile=mcp-app'] }
954
961
  * }
955
962
  * })
956
963
  * .buildAndConnect();
@@ -1932,11 +1939,24 @@ var McpTestClient = class {
1932
1939
  this.log("debug", `Connecting to ${this.config.baseUrl}...`);
1933
1940
  this.transport = this.createTransport();
1934
1941
  await this.transport.connect();
1935
- const initResponse = await this.initialize();
1936
- if (!initResponse.success || !initResponse.data) {
1937
- throw new Error(`Failed to initialize MCP connection: ${initResponse.error?.message ?? "Unknown error"}`);
1942
+ const maxRetries = 3;
1943
+ const retryDelayMs = 500;
1944
+ let lastError;
1945
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
1946
+ const initResponse = await this.initialize();
1947
+ if (initResponse.success && initResponse.data) {
1948
+ this.initResult = initResponse.data;
1949
+ break;
1950
+ }
1951
+ lastError = initResponse.error?.message ?? "Unknown error";
1952
+ if (attempt < maxRetries) {
1953
+ this.log("debug", `MCP init attempt ${attempt} failed (${lastError}), retrying in ${retryDelayMs}ms...`);
1954
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
1955
+ }
1956
+ }
1957
+ if (!this.initResult) {
1958
+ throw new Error(`Failed to initialize MCP connection after ${maxRetries} attempts: ${lastError}`);
1938
1959
  }
1939
- this.initResult = initResponse.data;
1940
1960
  this._sessionId = this.transport.getSessionId();
1941
1961
  this._sessionInfo = {
1942
1962
  id: this._sessionId ?? `session-${Date.now()}`,
@@ -2627,7 +2647,7 @@ var McpTestClient = class {
2627
2647
  const raw = response.data ?? { content: [] };
2628
2648
  const isError = !response.success || raw.isError === true;
2629
2649
  const meta = raw._meta;
2630
- const hasUI = meta?.["ui/html"] !== void 0 || meta?.["ui/component"] !== void 0 || meta?.["openai/html"] !== void 0 || meta?.["frontmcp/html"] !== void 0;
2650
+ const hasUI = meta?.["ui/html"] !== void 0 || meta?.["ui/component"] !== void 0;
2631
2651
  const structuredContent = raw["structuredContent"];
2632
2652
  return {
2633
2653
  raw,
@@ -2979,6 +2999,7 @@ var TestTokenFactory = class {
2979
2999
 
2980
3000
  // libs/testing/src/server/test-server.ts
2981
3001
  import { spawn } from "child_process";
3002
+ import { sha256Hex } from "@frontmcp/utils";
2982
3003
 
2983
3004
  // libs/testing/src/errors/index.ts
2984
3005
  var TestClientError = class extends Error {
@@ -3026,9 +3047,16 @@ var E2E_PORT_RANGES = {
3026
3047
  "demo-e2e-agents": { start: 50270, size: 10 },
3027
3048
  "demo-e2e-transport-recreation": { start: 50280, size: 10 },
3028
3049
  "demo-e2e-jobs": { start: 50290, size: 10 },
3029
- // Infrastructure E2E tests (50300-50399)
3050
+ // Infrastructure E2E tests (50300-50409)
3030
3051
  "demo-e2e-redis": { start: 50300, size: 10 },
3031
3052
  "demo-e2e-serverless": { start: 50310, size: 10 },
3053
+ "demo-e2e-uipack": { start: 50320, size: 10 },
3054
+ "demo-e2e-agent-adapters": { start: 50330, size: 10 },
3055
+ "demo-e2e-guard": { start: 50340, size: 10 },
3056
+ // ESM E2E tests (50400-50449)
3057
+ "esm-package-server": { start: 50400, size: 10 },
3058
+ "esm-package-server-hot-reload": { start: 50410, size: 10 },
3059
+ "esm-package-server-cli": { start: 50420, size: 10 },
3032
3060
  // Mock servers and utilities (50900-50999)
3033
3061
  "mock-oauth": { start: 50900, size: 10 },
3034
3062
  "mock-api": { start: 50910, size: 10 },
@@ -3100,7 +3128,7 @@ async function tryReservePort(port, project) {
3100
3128
  server.once("error", () => {
3101
3129
  resolve(false);
3102
3130
  });
3103
- server.listen(port, "::", () => {
3131
+ server.listen(port, () => {
3104
3132
  reservedPorts.set(port, {
3105
3133
  port,
3106
3134
  project,
@@ -3141,7 +3169,7 @@ async function isPortAvailable(port) {
3141
3169
  server.once("error", () => {
3142
3170
  resolve(false);
3143
3171
  });
3144
- server.listen(port, "::", () => {
3172
+ server.listen(port, () => {
3145
3173
  server.close(() => {
3146
3174
  resolve(true);
3147
3175
  });
@@ -3179,15 +3207,37 @@ var TestServer = class _TestServer {
3179
3207
  */
3180
3208
  static async start(options) {
3181
3209
  const project = options.project ?? "default";
3182
- const { port, release } = await reservePort(project, options.port);
3183
- const server = new _TestServer(options, port, release);
3184
- try {
3185
- await server.startProcess();
3186
- } catch (error) {
3187
- await server.stop();
3188
- throw error;
3210
+ const maxAttempts = 3;
3211
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
3212
+ const { port, release } = await reservePort(project, options.port);
3213
+ const server = new _TestServer(options, port, release);
3214
+ try {
3215
+ await server.startProcess();
3216
+ return server;
3217
+ } catch (error) {
3218
+ try {
3219
+ await server.stop();
3220
+ } catch (cleanupError) {
3221
+ if (options.debug || DEBUG_SERVER) {
3222
+ const msg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
3223
+ console.warn(`[TestServer] Cleanup failed after startup error: ${msg}`);
3224
+ }
3225
+ }
3226
+ const isEADDRINUSE = error instanceof Error && (error.message.includes("EADDRINUSE") || server.getLogs().some((l) => l.includes("EADDRINUSE")));
3227
+ if (isEADDRINUSE && attempt < maxAttempts) {
3228
+ const delayMs = attempt * 500;
3229
+ if (options.debug || DEBUG_SERVER) {
3230
+ console.warn(
3231
+ `[TestServer] EADDRINUSE on port ${port}, retrying in ${delayMs}ms (attempt ${attempt}/${maxAttempts})`
3232
+ );
3233
+ }
3234
+ await sleep4(delayMs);
3235
+ continue;
3236
+ }
3237
+ throw error;
3238
+ }
3189
3239
  }
3190
- return server;
3240
+ throw new Error(`[TestServer] Failed to start after ${maxAttempts} attempts`);
3191
3241
  }
3192
3242
  /**
3193
3243
  * Start an Nx project as test server
@@ -3198,22 +3248,44 @@ var TestServer = class _TestServer {
3198
3248
  `Invalid project name: ${project}. Must contain only alphanumeric, underscore, and hyphen characters.`
3199
3249
  );
3200
3250
  }
3201
- const { port, release } = await reservePort(project, options.port);
3202
- const serverOptions = {
3203
- ...options,
3204
- port,
3205
- project,
3206
- command: `npx nx serve ${project} --port ${port}`,
3207
- cwd: options.cwd ?? process.cwd()
3208
- };
3209
- const server = new _TestServer(serverOptions, port, release);
3210
- try {
3211
- await server.startProcess();
3212
- } catch (error) {
3213
- await server.stop();
3214
- throw error;
3251
+ const maxAttempts = 3;
3252
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
3253
+ const { port, release } = await reservePort(project, options.port);
3254
+ const serverOptions = {
3255
+ ...options,
3256
+ port,
3257
+ project,
3258
+ command: `npx nx serve ${project} --port ${port}`,
3259
+ cwd: options.cwd ?? process.cwd()
3260
+ };
3261
+ const server = new _TestServer(serverOptions, port, release);
3262
+ try {
3263
+ await server.startProcess();
3264
+ return server;
3265
+ } catch (error) {
3266
+ try {
3267
+ await server.stop();
3268
+ } catch (cleanupError) {
3269
+ if (options.debug || DEBUG_SERVER) {
3270
+ const msg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
3271
+ console.warn(`[TestServer] Cleanup failed after startup error: ${msg}`);
3272
+ }
3273
+ }
3274
+ const isEADDRINUSE = error instanceof Error && (error.message.includes("EADDRINUSE") || server.getLogs().some((l) => l.includes("EADDRINUSE")));
3275
+ if (isEADDRINUSE && attempt < maxAttempts) {
3276
+ const delayMs = attempt * 500;
3277
+ if (options.debug || DEBUG_SERVER) {
3278
+ console.warn(
3279
+ `[TestServer] EADDRINUSE on port ${port}, retrying in ${delayMs}ms (attempt ${attempt}/${maxAttempts})`
3280
+ );
3281
+ }
3282
+ await sleep4(delayMs);
3283
+ continue;
3284
+ }
3285
+ throw error;
3286
+ }
3215
3287
  }
3216
- return server;
3288
+ throw new Error(`[TestServer] Failed to start after ${maxAttempts} attempts`);
3217
3289
  }
3218
3290
  /**
3219
3291
  * Create a test server connected to an already running server
@@ -3250,7 +3322,21 @@ var TestServer = class _TestServer {
3250
3322
  }
3251
3323
  if (this.process) {
3252
3324
  this.log("Stopping server...");
3253
- this.process.kill("SIGTERM");
3325
+ if (this.process.exitCode !== null || this.process.signalCode !== null) {
3326
+ this.log(`Server already exited (code: ${this.process.exitCode}, signal: ${this.process.signalCode})`);
3327
+ this.process = null;
3328
+ return;
3329
+ }
3330
+ const pid = this.process.pid;
3331
+ try {
3332
+ if (pid !== void 0) {
3333
+ process.kill(-pid, "SIGTERM");
3334
+ } else {
3335
+ this.process.kill("SIGTERM");
3336
+ }
3337
+ } catch {
3338
+ this.process.kill("SIGTERM");
3339
+ }
3254
3340
  const exitPromise = new Promise((resolve) => {
3255
3341
  if (this.process) {
3256
3342
  this.process.once("exit", () => resolve());
@@ -3261,7 +3347,16 @@ var TestServer = class _TestServer {
3261
3347
  const killTimeout = setTimeout(() => {
3262
3348
  if (this.process) {
3263
3349
  this.log("Force killing server after timeout...");
3264
- this.process.kill("SIGKILL");
3350
+ const killPid = this.process.pid;
3351
+ try {
3352
+ if (killPid !== void 0) {
3353
+ process.kill(-killPid, "SIGKILL");
3354
+ } else {
3355
+ this.process.kill("SIGKILL");
3356
+ }
3357
+ } catch {
3358
+ this.process.kill("SIGKILL");
3359
+ }
3265
3360
  }
3266
3361
  }, 5e3);
3267
3362
  await exitPromise;
@@ -3326,14 +3421,17 @@ var TestServer = class _TestServer {
3326
3421
  ...this.options.env,
3327
3422
  PORT: String(this.options.port)
3328
3423
  };
3424
+ const runtimeEnv = withWorkspaceProtocolFallback(env, this.options.cwd);
3329
3425
  if (this.portRelease) {
3330
3426
  await this.portRelease();
3331
3427
  this.portRelease = null;
3428
+ await sleep4(300);
3332
3429
  }
3333
3430
  this.process = spawn(this.options.command, [], {
3334
3431
  cwd: this.options.cwd,
3335
- env,
3432
+ env: runtimeEnv,
3336
3433
  shell: true,
3434
+ detached: true,
3337
3435
  stdio: ["pipe", "pipe", "pipe"]
3338
3436
  });
3339
3437
  if (this.process.pid !== void 0) {
@@ -3485,6 +3583,111 @@ TIP: Set DEBUG_SERVER=1 or DEBUG=1 environment variable for verbose output`
3485
3583
  function sleep4(ms) {
3486
3584
  return new Promise((resolve) => setTimeout(resolve, ms));
3487
3585
  }
3586
+ function withWorkspaceProtocolFallback(env, cwd) {
3587
+ if (findInstalledProtocolPackageDir(cwd)) {
3588
+ return env;
3589
+ }
3590
+ try {
3591
+ const workspacePackageDir = findWorkspaceProtocolDir(cwd);
3592
+ if (!workspacePackageDir) {
3593
+ return env;
3594
+ }
3595
+ ensureWorkspaceProtocolLink(cwd, workspacePackageDir);
3596
+ if (findInstalledProtocolPackageDir(cwd)) {
3597
+ return env;
3598
+ }
3599
+ return withProtocolNodePathAlias(env, cwd, workspacePackageDir);
3600
+ } catch (err) {
3601
+ if (DEBUG_SERVER) {
3602
+ console.error(
3603
+ `[TestServer] Workspace protocol fallback failed: ${err instanceof Error ? err.message : String(err)}`
3604
+ );
3605
+ }
3606
+ return env;
3607
+ }
3608
+ }
3609
+ function ensureWorkspaceProtocolLink(cwd, workspacePackageDir) {
3610
+ const fs = __require("node:fs");
3611
+ const path = __require("node:path");
3612
+ const nodeModulesDir = findWorkspaceNodeModulesDir(cwd);
3613
+ if (!nodeModulesDir) {
3614
+ return;
3615
+ }
3616
+ const scopeDir = path.join(nodeModulesDir, "@frontmcp");
3617
+ const aliasPackageDir = path.join(scopeDir, "protocol");
3618
+ if (fs.existsSync(aliasPackageDir)) {
3619
+ return;
3620
+ }
3621
+ fs.mkdirSync(scopeDir, { recursive: true });
3622
+ try {
3623
+ fs.symlinkSync(workspacePackageDir, aliasPackageDir, process.platform === "win32" ? "junction" : "dir");
3624
+ } catch (error) {
3625
+ const err = error;
3626
+ if (err.code !== "EEXIST") {
3627
+ throw error;
3628
+ }
3629
+ }
3630
+ }
3631
+ function withProtocolNodePathAlias(env, cwd, workspacePackageDir) {
3632
+ const fs = __require("node:fs");
3633
+ const os = __require("node:os");
3634
+ const path = __require("node:path");
3635
+ const aliasRoot = path.join(os.tmpdir(), "frontmcp-test-node-path", sha256Hex(cwd).slice(0, 12));
3636
+ const scopeDir = path.join(aliasRoot, "@frontmcp");
3637
+ const aliasPackageDir = path.join(scopeDir, "protocol");
3638
+ fs.mkdirSync(scopeDir, { recursive: true });
3639
+ try {
3640
+ if (!fs.existsSync(aliasPackageDir)) {
3641
+ fs.symlinkSync(workspacePackageDir, aliasPackageDir, process.platform === "win32" ? "junction" : "dir");
3642
+ }
3643
+ } catch (error) {
3644
+ const err = error;
3645
+ if (err.code !== "EEXIST") throw error;
3646
+ }
3647
+ const existingNodePath = env["NODE_PATH"];
3648
+ const nodePathEntries = [aliasRoot, ...existingNodePath ? existingNodePath.split(path.delimiter) : []].filter(
3649
+ Boolean
3650
+ );
3651
+ return {
3652
+ ...env,
3653
+ NODE_PATH: [...new Set(nodePathEntries)].join(path.delimiter)
3654
+ };
3655
+ }
3656
+ function findUp(startDir, testFn) {
3657
+ const path = __require("node:path");
3658
+ let currentDir = startDir;
3659
+ while (true) {
3660
+ const result = testFn(currentDir);
3661
+ if (result !== void 0) return result;
3662
+ const parentDir = path.dirname(currentDir);
3663
+ if (parentDir === currentDir) return void 0;
3664
+ currentDir = parentDir;
3665
+ }
3666
+ }
3667
+ function findWorkspaceProtocolDir(startDir) {
3668
+ const fs = __require("node:fs");
3669
+ const path = __require("node:path");
3670
+ return findUp(startDir, (dir) => {
3671
+ const candidate = path.join(dir, "libs", "protocol");
3672
+ return fs.existsSync(path.join(candidate, "dist", "index.js")) ? candidate : void 0;
3673
+ });
3674
+ }
3675
+ function findInstalledProtocolPackageDir(startDir) {
3676
+ const fs = __require("node:fs");
3677
+ const path = __require("node:path");
3678
+ return findUp(startDir, (dir) => {
3679
+ const candidate = path.join(dir, "node_modules", "@frontmcp", "protocol");
3680
+ return fs.existsSync(path.join(candidate, "package.json")) ? candidate : void 0;
3681
+ });
3682
+ }
3683
+ function findWorkspaceNodeModulesDir(startDir) {
3684
+ const fs = __require("node:fs");
3685
+ const path = __require("node:path");
3686
+ return findUp(startDir, (dir) => {
3687
+ const candidate = path.join(dir, "node_modules");
3688
+ return fs.existsSync(candidate) ? candidate : void 0;
3689
+ });
3690
+ }
3488
3691
 
3489
3692
  // libs/testing/src/perf/perf-test.ts
3490
3693
  var currentConfig = {};
package/esm/setup.mjs CHANGED
@@ -8,23 +8,13 @@ var __commonJS = (cb, mod) => function __require() {
8
8
 
9
9
  // libs/testing/src/platform/platform-types.ts
10
10
  function getPlatformMimeType(platform) {
11
- return platform === "openai" ? "text/html+skybridge" : "text/html+mcp";
11
+ return "text/html;profile=mcp-app";
12
12
  }
13
13
  function getToolCallMetaPrefixes(platform) {
14
- switch (platform) {
15
- case "openai":
16
- return ["openai/"];
17
- default:
18
- return ["ui/"];
19
- }
14
+ return ["ui/"];
20
15
  }
21
16
  function getForbiddenMetaPrefixes(platform) {
22
- switch (platform) {
23
- case "openai":
24
- return ["ui/", "frontmcp/"];
25
- default:
26
- return ["openai/", "frontmcp/"];
27
- }
17
+ return ["openai/", "frontmcp/"];
28
18
  }
29
19
  var init_platform_types = __esm({
30
20
  "libs/testing/src/platform/platform-types.ts"() {
@@ -141,12 +131,12 @@ var init_ui_matchers = __esm({
141
131
  };
142
132
  }
143
133
  const hasUiHtml = Boolean(meta["ui/html"]);
144
- const hasOutputTemplate = Boolean(meta["openai/outputTemplate"]);
145
134
  const hasMimeType = Boolean(meta["ui/mimeType"]);
146
- const pass = hasUiHtml || hasOutputTemplate || hasMimeType;
135
+ const hasUiObject = Boolean(meta["ui"] && typeof meta["ui"] === "object");
136
+ const pass = hasUiHtml || hasMimeType || hasUiObject;
147
137
  return {
148
138
  pass,
149
- message: () => pass ? "Expected result not to have widget metadata" : "Expected _meta to have widget metadata (ui/html, openai/outputTemplate, or ui/mimeType)"
139
+ message: () => pass ? "Expected result not to have widget metadata" : "Expected _meta to have widget metadata (ui/html, ui/mimeType, or ui object)"
150
140
  };
151
141
  };
152
142
  toHaveCssClass = function(received, className) {
@@ -309,14 +299,7 @@ var init_ui_matchers = __esm({
309
299
  message: () => `Expected _meta to have MIME type "${expectedMimeType}" for platform "${platform}", but no _meta found`
310
300
  };
311
301
  }
312
- let mimeTypeKey;
313
- switch (platform) {
314
- case "openai":
315
- mimeTypeKey = "openai/mimeType";
316
- break;
317
- default:
318
- mimeTypeKey = "ui/mimeType";
319
- }
302
+ const mimeTypeKey = "ui/mimeType";
320
303
  const actualMimeType = meta[mimeTypeKey];
321
304
  const pass = actualMimeType === expectedMimeType;
322
305
  return {
@@ -332,14 +315,7 @@ var init_ui_matchers = __esm({
332
315
  message: () => `Expected _meta to have platform HTML for "${platform}", but no _meta found`
333
316
  };
334
317
  }
335
- let htmlKey;
336
- switch (platform) {
337
- case "openai":
338
- htmlKey = "openai/html";
339
- break;
340
- default:
341
- htmlKey = "ui/html";
342
- }
318
+ const htmlKey = "ui/html";
343
319
  const html = meta[htmlKey];
344
320
  const pass = typeof html === "string" && html.length > 0;
345
321
  return {
@@ -16,5 +16,5 @@
16
16
  */
17
17
  export { BASIC_UI_TOOL_CONFIG, FULL_UI_TOOL_CONFIG, basicUIToolInputSchema, basicUIToolOutputSchema, fullUIToolInputSchema, fullUIToolOutputSchema, } from './tool-configs';
18
18
  export { generateBasicUIToolOutput, generateFullUIToolOutput } from './tool-configs';
19
- export { EXPECTED_OPENAI_TOOLS_LIST_META_KEYS, EXPECTED_OPENAI_TOOL_CALL_META_KEYS, EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS, EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS, EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS, EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS, } from './tool-configs';
19
+ export { EXPECTED_OPENAI_TOOLS_LIST_META_KEYS, EXPECTED_OPENAI_TOOL_CALL_META_KEYS, EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS, EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS, EXPECTED_GENERIC_TOOLS_LIST_META_KEYS, EXPECTED_GENERIC_TOOL_CALL_META_KEYS, } from './tool-configs';
20
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/example-tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAGrF,OAAO,EACL,oCAAoC,EACpC,mCAAmC,EACnC,qCAAqC,EACrC,oCAAoC,EACpC,sCAAsC,EACtC,qCAAqC,GACtC,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/example-tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAGrF,OAAO,EACL,oCAAoC,EACpC,mCAAmC,EACnC,qCAAqC,EACrC,oCAAoC,EACpC,qCAAqC,EACrC,oCAAoC,GACrC,MAAM,gBAAgB,CAAC"}
@@ -146,12 +146,14 @@ export declare function generateFullUIToolOutput(input: z.infer<typeof fullUIToo
146
146
  };
147
147
  /**
148
148
  * Expected meta keys for OpenAI platform in tools/list response.
149
+ * OpenAI now uses the standard ui/* namespace like all other platforms.
149
150
  */
150
- export declare const EXPECTED_OPENAI_TOOLS_LIST_META_KEYS: readonly ["openai/outputTemplate", "openai/resultCanProduceWidget", "openai/widgetAccessible"];
151
+ export declare const EXPECTED_OPENAI_TOOLS_LIST_META_KEYS: readonly ["ui/resourceUri", "ui/mimeType", "ui/cdn", "ui/type"];
151
152
  /**
152
153
  * Expected meta keys for OpenAI platform in tools/call response.
154
+ * OpenAI now uses the standard ui/* namespace like all other platforms.
153
155
  */
154
- export declare const EXPECTED_OPENAI_TOOL_CALL_META_KEYS: readonly ["openai/html", "openai/mimeType", "openai/type"];
156
+ export declare const EXPECTED_OPENAI_TOOL_CALL_META_KEYS: readonly ["ui/html", "ui/mimeType", "ui/type"];
155
157
  /**
156
158
  * Expected meta keys for ext-apps platform in tools/list response (SEP-1865).
157
159
  */
@@ -170,12 +172,4 @@ export declare const EXPECTED_GENERIC_TOOLS_LIST_META_KEYS: readonly ["ui/resour
170
172
  * Uses ui/* namespace only.
171
173
  */
172
174
  export declare const EXPECTED_GENERIC_TOOL_CALL_META_KEYS: readonly ["ui/html", "ui/mimeType", "ui/type"];
173
- /**
174
- * @deprecated Use EXPECTED_GENERIC_TOOLS_LIST_META_KEYS instead
175
- */
176
- export declare const EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS: readonly ["ui/resourceUri", "ui/mimeType", "ui/cdn", "ui/type"];
177
- /**
178
- * @deprecated Use EXPECTED_GENERIC_TOOL_CALL_META_KEYS instead
179
- */
180
- export declare const EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS: readonly ["ui/html", "ui/mimeType", "ui/type"];
181
175
  //# sourceMappingURL=tool-configs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-configs.d.ts","sourceRoot":"","sources":["../../src/example-tools/tool-configs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;GAEG;AACH,eAAO,MAAM,sBAAsB;;iBAEjC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;iBAGlC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;QAM7B;;;WAGG;;;CASG,CAAC;AAMX;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;iBAGhC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;iBAKjC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;QAM5B;;WAEG;;QAqBH;;WAEG;;QAEH;;WAEG;;;;;QAKH;;WAEG;;;;;QAKH;;WAEG;;QAEH;;WAEG;;QAEH;;WAEG;;;CAGG,CAAC;AAMX;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC;;;EAKtF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC;;;;;EAWpF;AAMD;;GAEG;AACH,eAAO,MAAM,oCAAoC,gGAIvC,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,mCAAmC,4DAA6D,CAAC;AAE9G;;GAEG;AACH,eAAO,MAAM,qCAAqC,iEAAkE,CAAC;AAErH;;GAEG;AACH,eAAO,MAAM,oCAAoC,gDAAiD,CAAC;AAEnG;;;GAGG;AACH,eAAO,MAAM,qCAAqC,iEAAkE,CAAC;AAErH;;;GAGG;AACH,eAAO,MAAM,oCAAoC,gDAAiD,CAAC;AAEnG;;GAEG;AACH,eAAO,MAAM,sCAAsC,iEAAwC,CAAC;AAE5F;;GAEG;AACH,eAAO,MAAM,qCAAqC,gDAAuC,CAAC"}
1
+ {"version":3,"file":"tool-configs.d.ts","sourceRoot":"","sources":["../../src/example-tools/tool-configs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;GAEG;AACH,eAAO,MAAM,sBAAsB;;iBAEjC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;iBAGlC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;QAM7B;;;WAGG;;;CASG,CAAC;AAMX;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;iBAGhC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;iBAKjC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;QAM5B;;WAEG;;QAqBH;;WAEG;;QAEH;;WAEG;;;;;QAKH;;WAEG;;;;;QAKH;;WAEG;;QAEH;;WAEG;;QAEH;;WAEG;;;CAGG,CAAC;AAMX;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC;;;EAKtF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC;;;;;EAWpF;AAMD;;;GAGG;AACH,eAAO,MAAM,oCAAoC,iEAAkE,CAAC;AAEpH;;;GAGG;AACH,eAAO,MAAM,mCAAmC,gDAAiD,CAAC;AAElG;;GAEG;AACH,eAAO,MAAM,qCAAqC,iEAAkE,CAAC;AAErH;;GAEG;AACH,eAAO,MAAM,oCAAoC,gDAAiD,CAAC;AAEnG;;;GAGG;AACH,eAAO,MAAM,qCAAqC,iEAAkE,CAAC;AAErH;;;GAGG;AACH,eAAO,MAAM,oCAAoC,gDAAiD,CAAC"}