@frontmcp/plugin-dashboard 1.8.7 → 1.9.1-rc.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.
package/esm/index.mjs CHANGED
@@ -1,3 +1,6 @@
1
+ var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : undefined;
2
+ const require = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || 'file:///') : undefined;
3
+ // __frontmcpCreateRequire
1
4
  var __create = Object.create;
2
5
  var __defProp = Object.defineProperty;
3
6
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -443,7 +446,6 @@ import { hkdf } from "@noble/hashes/hkdf.js";
443
446
  import { randomBytes as nobleRandomBytes } from "@noble/hashes/utils.js";
444
447
  import { gcm } from "@noble/ciphers/aes.js";
445
448
  import { analyzeForReDoS, REDOS_THRESHOLDS } from "@enclave-vm/ast";
446
- import { z as z3 } from "@frontmcp/lazy-zod";
447
449
  var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : void 0;
448
450
  var require2 = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || "file:///") : void 0;
449
451
  var __defProp2 = Object.defineProperty;
@@ -781,8 +783,8 @@ var init_key_persistence = __esm({
781
783
  */
782
784
  async get(kid) {
783
785
  if (this.enableCache) {
784
- const cached4 = this.cache.get(kid);
785
- if (cached4) return cached4;
786
+ const cached = this.cache.get(kid);
787
+ if (cached) return cached;
786
788
  }
787
789
  const raw = await this.storage.get(kid);
788
790
  if (!raw) return null;
@@ -1038,6 +1040,61 @@ var init_errors = __esm({
1038
1040
  };
1039
1041
  }
1040
1042
  });
1043
+ function globToRegex(pattern) {
1044
+ if (pattern.length > MAX_PATTERN_LENGTH) {
1045
+ throw new StoragePatternError(
1046
+ pattern.substring(0, 50) + "...",
1047
+ `Pattern exceeds maximum length of ${MAX_PATTERN_LENGTH} characters`
1048
+ );
1049
+ }
1050
+ const wildcardCount = (pattern.match(/[*?]/g) || []).length;
1051
+ if (wildcardCount > MAX_WILDCARDS) {
1052
+ throw new StoragePatternError(pattern, `Pattern has too many wildcards (max: ${MAX_WILDCARDS})`);
1053
+ }
1054
+ if (pattern === "" || pattern === "*") {
1055
+ return /^.*$/;
1056
+ }
1057
+ let regexStr = "^";
1058
+ let prevChar = "";
1059
+ for (let i = 0; i < pattern.length; i++) {
1060
+ const char = pattern[i];
1061
+ switch (char) {
1062
+ case "*":
1063
+ if (prevChar !== "*") {
1064
+ regexStr += ".*";
1065
+ }
1066
+ break;
1067
+ case "?":
1068
+ regexStr += ".";
1069
+ break;
1070
+ default:
1071
+ regexStr += char.replace(REGEX_SPECIAL_CHARS, "\\$&");
1072
+ }
1073
+ prevChar = char;
1074
+ }
1075
+ regexStr += "$";
1076
+ try {
1077
+ return new RegExp(regexStr);
1078
+ } catch {
1079
+ throw new StoragePatternError(pattern, "Failed to compile pattern to regex");
1080
+ }
1081
+ }
1082
+ function matchesPattern(key, pattern) {
1083
+ const regex = globToRegex(pattern);
1084
+ return regex.test(key);
1085
+ }
1086
+ var MAX_PATTERN_LENGTH;
1087
+ var MAX_WILDCARDS;
1088
+ var REGEX_SPECIAL_CHARS;
1089
+ var init_pattern = __esm({
1090
+ "libs/utils/src/storage/utils/pattern.ts"() {
1091
+ "use strict";
1092
+ init_errors();
1093
+ MAX_PATTERN_LENGTH = 500;
1094
+ MAX_WILDCARDS = 20;
1095
+ REGEX_SPECIAL_CHARS = /[.+^${}()|[\]\\]/g;
1096
+ }
1097
+ });
1041
1098
  function validateTTL(ttlSeconds) {
1042
1099
  if (typeof ttlSeconds !== "number") {
1043
1100
  throw new StorageTTLError(ttlSeconds, `TTL must be a number, got ${typeof ttlSeconds}`);
@@ -1146,6 +1203,17 @@ var init_base = __esm({
1146
1203
  const matchedKeys = await this.keys(pattern);
1147
1204
  return matchedKeys.length;
1148
1205
  }
1206
+ /**
1207
+ * Default: not supported, since a read followed by a delete is not atomic.
1208
+ * Override in adapters whose backend can compare and delete in one step.
1209
+ */
1210
+ async deleteIfEquals(_key, _expectedValue) {
1211
+ throw new StorageNotSupportedError(
1212
+ "deleteIfEquals",
1213
+ this.backendName,
1214
+ "Use the memory, Redis, Upstash or Vercel KV adapter for an atomic compare-and-delete."
1215
+ );
1216
+ }
1149
1217
  // ============================================
1150
1218
  // Pub/Sub (default: not supported)
1151
1219
  // ============================================
@@ -1193,71 +1261,16 @@ var init_base = __esm({
1193
1261
  };
1194
1262
  }
1195
1263
  });
1196
- function globToRegex(pattern) {
1197
- if (pattern.length > MAX_PATTERN_LENGTH) {
1198
- throw new StoragePatternError(
1199
- pattern.substring(0, 50) + "...",
1200
- `Pattern exceeds maximum length of ${MAX_PATTERN_LENGTH} characters`
1201
- );
1202
- }
1203
- const wildcardCount = (pattern.match(/[*?]/g) || []).length;
1204
- if (wildcardCount > MAX_WILDCARDS) {
1205
- throw new StoragePatternError(pattern, `Pattern has too many wildcards (max: ${MAX_WILDCARDS})`);
1206
- }
1207
- if (pattern === "" || pattern === "*") {
1208
- return /^.*$/;
1209
- }
1210
- let regexStr = "^";
1211
- let prevChar = "";
1212
- for (let i = 0; i < pattern.length; i++) {
1213
- const char = pattern[i];
1214
- switch (char) {
1215
- case "*":
1216
- if (prevChar !== "*") {
1217
- regexStr += ".*";
1218
- }
1219
- break;
1220
- case "?":
1221
- regexStr += ".";
1222
- break;
1223
- default:
1224
- regexStr += char.replace(REGEX_SPECIAL_CHARS, "\\$&");
1225
- }
1226
- prevChar = char;
1227
- }
1228
- regexStr += "$";
1229
- try {
1230
- return new RegExp(regexStr);
1231
- } catch {
1232
- throw new StoragePatternError(pattern, "Failed to compile pattern to regex");
1233
- }
1234
- }
1235
- function matchesPattern(key, pattern) {
1236
- const regex = globToRegex(pattern);
1237
- return regex.test(key);
1238
- }
1239
- var MAX_PATTERN_LENGTH;
1240
- var MAX_WILDCARDS;
1241
- var REGEX_SPECIAL_CHARS;
1242
- var init_pattern = __esm({
1243
- "libs/utils/src/storage/utils/pattern.ts"() {
1244
- "use strict";
1245
- init_errors();
1246
- MAX_PATTERN_LENGTH = 500;
1247
- MAX_WILDCARDS = 20;
1248
- REGEX_SPECIAL_CHARS = /[.+^${}()|[\]\\]/g;
1249
- }
1250
- });
1251
1264
  var DEFAULT_SWEEP_INTERVAL_SECONDS;
1252
1265
  var MAX_TIMEOUT_MS;
1253
1266
  var MemoryStorageAdapter;
1254
1267
  var init_memory = __esm({
1255
1268
  "libs/utils/src/storage/adapters/memory.ts"() {
1256
1269
  "use strict";
1257
- init_base();
1258
1270
  init_errors();
1259
1271
  init_pattern();
1260
1272
  init_ttl();
1273
+ init_base();
1261
1274
  DEFAULT_SWEEP_INTERVAL_SECONDS = 60;
1262
1275
  MAX_TIMEOUT_MS = 2147483647;
1263
1276
  MemoryStorageAdapter = class extends BaseStorageAdapter {
@@ -1349,6 +1362,12 @@ var init_memory = __esm({
1349
1362
  this.ensureConnected();
1350
1363
  return this.deleteEntry(key);
1351
1364
  }
1365
+ async deleteIfEquals(key, expectedValue) {
1366
+ this.ensureConnected();
1367
+ const entry = this.store.get(key);
1368
+ if (!entry || isExpired(entry.expiresAt) || entry.value !== expectedValue) return false;
1369
+ return this.deleteEntry(key);
1370
+ }
1352
1371
  async exists(key) {
1353
1372
  this.ensureConnected();
1354
1373
  const entry = this.store.get(key);
@@ -2726,6 +2745,13 @@ var init_utils = __esm({
2726
2745
  init_ttl();
2727
2746
  }
2728
2747
  });
2748
+ var COMPARE_AND_DELETE_SCRIPT;
2749
+ var init_compare_and_delete = __esm({
2750
+ "libs/utils/src/storage/utils/compare-and-delete.ts"() {
2751
+ "use strict";
2752
+ COMPARE_AND_DELETE_SCRIPT = `if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) end return 0`;
2753
+ }
2754
+ });
2729
2755
  var redis_exports = {};
2730
2756
  __export(redis_exports, {
2731
2757
  RedisStorageAdapter: () => RedisStorageAdapter,
@@ -2768,6 +2794,7 @@ var init_redis = __esm({
2768
2794
  init_errors();
2769
2795
  init_redis_error_listener();
2770
2796
  init_utils();
2797
+ init_compare_and_delete();
2771
2798
  init_base();
2772
2799
  RedisStorageAdapter = class extends BaseStorageAdapter {
2773
2800
  backendName = "redis";
@@ -2922,6 +2949,15 @@ var init_redis = __esm({
2922
2949
  const result = await this.getConnectedClient().del(this.prefixKey(key));
2923
2950
  return result > 0;
2924
2951
  }
2952
+ async deleteIfEquals(key, expectedValue) {
2953
+ const deleted = await this.getConnectedClient().eval(
2954
+ COMPARE_AND_DELETE_SCRIPT,
2955
+ 1,
2956
+ this.prefixKey(key),
2957
+ expectedValue
2958
+ );
2959
+ return deleted === 1;
2960
+ }
2925
2961
  async exists(key) {
2926
2962
  const result = await this.getConnectedClient().exists(this.prefixKey(key));
2927
2963
  return result > 0;
@@ -3128,9 +3164,12 @@ var vercel_kv_exports = {};
3128
3164
  __export(vercel_kv_exports, {
3129
3165
  VercelKvStorageAdapter: () => VercelKvStorageAdapter
3130
3166
  });
3131
- function getVercelKv() {
3167
+ async function loadVercelKv() {
3132
3168
  try {
3133
- return __require2("@vercel/kv");
3169
+ const mod = await import("@vercel/kv");
3170
+ const resolved = typeof mod.createClient === "function" ? mod : mod.default;
3171
+ if (!resolved || typeof resolved.createClient !== "function") throw new Error("createClient missing");
3172
+ return resolved;
3134
3173
  } catch {
3135
3174
  throw new Error("@vercel/kv is required for Vercel KV storage adapter. Install it with: npm install @vercel/kv");
3136
3175
  }
@@ -3139,9 +3178,10 @@ var VercelKvStorageAdapter;
3139
3178
  var init_vercel_kv = __esm({
3140
3179
  "libs/utils/src/storage/adapters/vercel-kv.ts"() {
3141
3180
  "use strict";
3142
- init_base();
3143
3181
  init_errors();
3182
+ init_compare_and_delete();
3144
3183
  init_ttl();
3184
+ init_base();
3145
3185
  VercelKvStorageAdapter = class extends BaseStorageAdapter {
3146
3186
  backendName = "vercel-kv";
3147
3187
  client;
@@ -3166,17 +3206,13 @@ var init_vercel_kv = __esm({
3166
3206
  async connect() {
3167
3207
  if (this.connected) return;
3168
3208
  try {
3169
- const { createClient, kv } = getVercelKv();
3170
- if (this.options.url === process.env["KV_REST_API_URL"]) {
3171
- this.client = kv;
3172
- } else {
3173
- const url = this.options.url;
3174
- const token = this.options.token;
3175
- if (!url || !token) {
3176
- throw new StorageConfigError("vercel-kv", "URL and token are required");
3177
- }
3178
- this.client = createClient({ url, token });
3209
+ const { createClient } = await loadVercelKv();
3210
+ const url = this.options.url;
3211
+ const token = this.options.token;
3212
+ if (!url || !token) {
3213
+ throw new StorageConfigError("vercel-kv", "URL and token are required");
3179
3214
  }
3215
+ this.client = createClient({ url, token, cache: void 0, automaticDeserialization: false });
3180
3216
  await this.client.exists("__healthcheck__");
3181
3217
  this.connected = true;
3182
3218
  } catch (e) {
@@ -3217,8 +3253,7 @@ var init_vercel_kv = __esm({
3217
3253
  // Core Operations
3218
3254
  // ============================================
3219
3255
  async get(key) {
3220
- const result = await this.getConnectedClient().get(this.prefixKey(key));
3221
- return result;
3256
+ return this.getConnectedClient().get(this.prefixKey(key));
3222
3257
  }
3223
3258
  async doSet(key, value, options) {
3224
3259
  const client = this.getConnectedClient();
@@ -3238,6 +3273,14 @@ var init_vercel_kv = __esm({
3238
3273
  const result = await this.getConnectedClient().del(this.prefixKey(key));
3239
3274
  return result > 0;
3240
3275
  }
3276
+ async deleteIfEquals(key, expectedValue) {
3277
+ const deleted = await this.getConnectedClient().eval(
3278
+ COMPARE_AND_DELETE_SCRIPT,
3279
+ [this.prefixKey(key)],
3280
+ [expectedValue]
3281
+ );
3282
+ return deleted === 1;
3283
+ }
3241
3284
  async exists(key) {
3242
3285
  const result = await this.getConnectedClient().exists(this.prefixKey(key));
3243
3286
  return result > 0;
@@ -3354,9 +3397,10 @@ var UpstashStorageAdapter;
3354
3397
  var init_upstash = __esm({
3355
3398
  "libs/utils/src/storage/adapters/upstash.ts"() {
3356
3399
  "use strict";
3357
- init_base();
3358
3400
  init_errors();
3401
+ init_compare_and_delete();
3359
3402
  init_ttl();
3403
+ init_base();
3360
3404
  PUBSUB_POLL_INTERVAL_MS = 100;
3361
3405
  UpstashStorageAdapter = class extends BaseStorageAdapter {
3362
3406
  backendName = "upstash";
@@ -3393,7 +3437,7 @@ var init_upstash = __esm({
3393
3437
  if (!url || !token) {
3394
3438
  throw new StorageConfigError("upstash", "URL and token are required");
3395
3439
  }
3396
- this.client = new Redis({ url, token });
3440
+ this.client = new Redis({ url, token, automaticDeserialization: false });
3397
3441
  await this.client.exists("__healthcheck__");
3398
3442
  this.connected = true;
3399
3443
  } catch (e) {
@@ -3440,8 +3484,7 @@ var init_upstash = __esm({
3440
3484
  // Core Operations
3441
3485
  // ============================================
3442
3486
  async get(key) {
3443
- const result = await this.getConnectedClient().get(this.prefixKey(key));
3444
- return result;
3487
+ return this.getConnectedClient().get(this.prefixKey(key));
3445
3488
  }
3446
3489
  async doSet(key, value, options) {
3447
3490
  const client = this.getConnectedClient();
@@ -3461,6 +3504,14 @@ var init_upstash = __esm({
3461
3504
  const result = await this.getConnectedClient().del(this.prefixKey(key));
3462
3505
  return result > 0;
3463
3506
  }
3507
+ async deleteIfEquals(key, expectedValue) {
3508
+ const deleted = await this.getConnectedClient().eval(
3509
+ COMPARE_AND_DELETE_SCRIPT,
3510
+ [this.prefixKey(key)],
3511
+ [expectedValue]
3512
+ );
3513
+ return deleted === 1;
3514
+ }
3464
3515
  async exists(key) {
3465
3516
  const result = await this.getConnectedClient().exists(this.prefixKey(key));
3466
3517
  return result > 0;
@@ -3649,7 +3700,9 @@ var init_cloudflare_kv = __esm({
3649
3700
  constructor(options) {
3650
3701
  super();
3651
3702
  if (!options?.namespace) {
3652
- throw new Error("CloudflareKvStorageAdapter: a bound KV `namespace` is required (resolve it from the Worker `env`).");
3703
+ throw new Error(
3704
+ "CloudflareKvStorageAdapter: a bound KV `namespace` is required (resolve it from the Worker `env`)."
3705
+ );
3653
3706
  }
3654
3707
  this.kv = options.namespace;
3655
3708
  this.keyPrefix = options.keyPrefix ?? "";
@@ -3743,6 +3796,13 @@ var init_cloudflare_kv = __esm({
3743
3796
  "Cloudflare KV has no atomic increment (a get+put is racy under eventual consistency). Use a Durable Object for atomic counters."
3744
3797
  );
3745
3798
  }
3799
+ async deleteIfEquals(_key, _expectedValue) {
3800
+ throw new StorageNotSupportedError(
3801
+ "deleteIfEquals",
3802
+ this.backendName,
3803
+ "Cloudflare KV has no compare-and-set; use a Durable Object for an atomic compare-and-delete."
3804
+ );
3805
+ }
3746
3806
  // ── Pub/Sub (unsupported) ────────────────────────────────────────────────
3747
3807
  getPubSubSuggestion() {
3748
3808
  return "Cloudflare KV does not support pub/sub. Use a Durable Object (or Queues) for fan-out.";
@@ -3856,16 +3916,7 @@ function compileBlocks(entries, parseNetwork) {
3856
3916
  }
3857
3917
  init_fs2();
3858
3918
  init_crypto();
3859
- var entryAvailabilitySchema = z3.object({
3860
- os: z3.array(z3.string().min(1)).optional(),
3861
- platform: z3.array(z3.string().min(1)).optional(),
3862
- runtime: z3.array(z3.string().min(1)).optional(),
3863
- deployment: z3.array(z3.string().min(1)).optional(),
3864
- provider: z3.array(z3.string().min(1)).optional(),
3865
- target: z3.array(z3.string().min(1)).optional(),
3866
- surface: z3.array(z3.enum(["mcp", "cli", "http-trigger", "job", "agent"])).optional(),
3867
- env: z3.array(z3.string().min(1)).optional()
3868
- }).strict();
3919
+ init_errors();
3869
3920
  init_errors();
3870
3921
  init_memory();
3871
3922
  init_redis_error_listener();
@@ -4838,11 +4889,11 @@ GraphDataProvider = __decorateClass([
4838
4889
  ], GraphDataProvider);
4839
4890
 
4840
4891
  // plugins/plugin-dashboard/src/tools/graph.tool.ts
4841
- import { z as z4 } from "@frontmcp/lazy-zod";
4892
+ import { z as z3 } from "@frontmcp/lazy-zod";
4842
4893
  import { Tool, ToolContext } from "@frontmcp/sdk";
4843
4894
  var graphToolInputSchema = {
4844
- includeSchemas: z4.boolean().optional().default(false).describe("Include full input/output schemas in the response"),
4845
- refresh: z4.boolean().optional().default(false).describe("Force refresh the graph data (bypass cache)")
4895
+ includeSchemas: z3.boolean().optional().default(false).describe("Include full input/output schemas in the response"),
4896
+ refresh: z3.boolean().optional().default(false).describe("Force refresh the graph data (bypass cache)")
4846
4897
  };
4847
4898
  var GraphTool = class extends ToolContext {
4848
4899
  async execute(input) {
@@ -4880,7 +4931,7 @@ GraphTool = __decorateClass([
4880
4931
  ], GraphTool);
4881
4932
 
4882
4933
  // plugins/plugin-dashboard/src/tools/list-resources.tool.ts
4883
- import { z as z5 } from "@frontmcp/lazy-zod";
4934
+ import { z as z4 } from "@frontmcp/lazy-zod";
4884
4935
  import { Tool as Tool2, ToolContext as ToolContext2 } from "@frontmcp/sdk";
4885
4936
 
4886
4937
  // plugins/plugin-dashboard/src/shared/safe-regex.ts
@@ -4899,20 +4950,20 @@ function safeRegex(pattern) {
4899
4950
 
4900
4951
  // plugins/plugin-dashboard/src/tools/list-resources.tool.ts
4901
4952
  var listResourcesInputSchema = {
4902
- filter: z5.string().optional().describe("Filter resources by name or URI pattern (regex supported)"),
4903
- includeTemplates: z5.boolean().default(true).describe("Include resource templates in the response")
4953
+ filter: z4.string().optional().describe("Filter resources by name or URI pattern (regex supported)"),
4954
+ includeTemplates: z4.boolean().default(true).describe("Include resource templates in the response")
4904
4955
  };
4905
- var listResourcesOutputSchema = z5.object({
4906
- resources: z5.array(
4907
- z5.object({
4908
- name: z5.string(),
4909
- uri: z5.string(),
4910
- description: z5.string().optional(),
4911
- mimeType: z5.string().optional(),
4912
- isTemplate: z5.boolean()
4956
+ var listResourcesOutputSchema = z4.object({
4957
+ resources: z4.array(
4958
+ z4.object({
4959
+ name: z4.string(),
4960
+ uri: z4.string(),
4961
+ description: z4.string().optional(),
4962
+ mimeType: z4.string().optional(),
4963
+ isTemplate: z4.boolean()
4913
4964
  })
4914
4965
  ),
4915
- count: z5.number()
4966
+ count: z4.number()
4916
4967
  });
4917
4968
  var ListResourcesTool = class extends ToolContext2 {
4918
4969
  async execute(input) {
@@ -4974,25 +5025,25 @@ ListResourcesTool = __decorateClass([
4974
5025
  ], ListResourcesTool);
4975
5026
 
4976
5027
  // plugins/plugin-dashboard/src/tools/list-tools.tool.ts
4977
- import { z as z6 } from "@frontmcp/lazy-zod";
5028
+ import { z as z5 } from "@frontmcp/lazy-zod";
4978
5029
  import { Tool as Tool3, ToolContext as ToolContext3 } from "@frontmcp/sdk";
4979
5030
  var listToolsInputSchema = {
4980
- filter: z6.string().optional().describe("Filter tools by name pattern (regex supported)"),
4981
- includePlugins: z6.boolean().default(true).describe("Include tools from plugins"),
4982
- includeSchemas: z6.boolean().default(false).describe("Include input/output schemas in the response")
5031
+ filter: z5.string().optional().describe("Filter tools by name pattern (regex supported)"),
5032
+ includePlugins: z5.boolean().default(true).describe("Include tools from plugins"),
5033
+ includeSchemas: z5.boolean().default(false).describe("Include input/output schemas in the response")
4983
5034
  };
4984
- var listToolsOutputSchema = z6.object({
4985
- tools: z6.array(
4986
- z6.object({
4987
- name: z6.string(),
4988
- fullName: z6.string(),
4989
- description: z6.string().optional(),
4990
- tags: z6.array(z6.string()).optional(),
4991
- inputSchema: z6.unknown().optional(),
4992
- outputSchema: z6.unknown().optional()
5035
+ var listToolsOutputSchema = z5.object({
5036
+ tools: z5.array(
5037
+ z5.object({
5038
+ name: z5.string(),
5039
+ fullName: z5.string(),
5040
+ description: z5.string().optional(),
5041
+ tags: z5.array(z5.string()).optional(),
5042
+ inputSchema: z5.unknown().optional(),
5043
+ outputSchema: z5.unknown().optional()
4993
5044
  })
4994
5045
  ),
4995
- count: z6.number()
5046
+ count: z5.number()
4996
5047
  });
4997
5048
  var ListToolsTool = class extends ToolContext3 {
4998
5049
  async execute(input) {
package/esm/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/plugin-dashboard",
3
- "version": "1.8.7",
3
+ "version": "1.9.1-rc.1",
4
4
  "description": "Dashboard plugin for FrontMCP - visual monitoring and introspection of MCP servers",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
@@ -47,12 +47,12 @@
47
47
  }
48
48
  },
49
49
  "dependencies": {
50
- "@frontmcp/sdk": "1.8.7"
50
+ "@frontmcp/sdk": "1.9.1-rc.1"
51
51
  },
52
52
  "devDependencies": {
53
53
  "reflect-metadata": "^0.2.2"
54
54
  },
55
55
  "peerDependencies": {
56
- "@frontmcp/lazy-zod": "1.8.7"
56
+ "@frontmcp/lazy-zod": "1.9.1-rc.1"
57
57
  }
58
58
  }
package/index.js CHANGED
@@ -454,7 +454,6 @@ var import_utils = require("@noble/hashes/utils.js");
454
454
  var import_aes = require("@noble/ciphers/aes.js");
455
455
  var import_crypto_provider = __toESM(require_node(), 1);
456
456
  var import_ast = require("@enclave-vm/ast");
457
- var import_lazy_zod4 = require("@frontmcp/lazy-zod");
458
457
  var import_meta = {};
459
458
  var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : void 0;
460
459
  var require2 = __frontmcpModule ? __frontmcpModule.createRequire(import_meta.url || "file:///") : void 0;
@@ -793,8 +792,8 @@ var init_key_persistence = __esm({
793
792
  */
794
793
  async get(kid) {
795
794
  if (this.enableCache) {
796
- const cached4 = this.cache.get(kid);
797
- if (cached4) return cached4;
795
+ const cached = this.cache.get(kid);
796
+ if (cached) return cached;
798
797
  }
799
798
  const raw = await this.storage.get(kid);
800
799
  if (!raw) return null;
@@ -1050,6 +1049,61 @@ var init_errors = __esm({
1050
1049
  };
1051
1050
  }
1052
1051
  });
1052
+ function globToRegex(pattern) {
1053
+ if (pattern.length > MAX_PATTERN_LENGTH) {
1054
+ throw new StoragePatternError(
1055
+ pattern.substring(0, 50) + "...",
1056
+ `Pattern exceeds maximum length of ${MAX_PATTERN_LENGTH} characters`
1057
+ );
1058
+ }
1059
+ const wildcardCount = (pattern.match(/[*?]/g) || []).length;
1060
+ if (wildcardCount > MAX_WILDCARDS) {
1061
+ throw new StoragePatternError(pattern, `Pattern has too many wildcards (max: ${MAX_WILDCARDS})`);
1062
+ }
1063
+ if (pattern === "" || pattern === "*") {
1064
+ return /^.*$/;
1065
+ }
1066
+ let regexStr = "^";
1067
+ let prevChar = "";
1068
+ for (let i = 0; i < pattern.length; i++) {
1069
+ const char = pattern[i];
1070
+ switch (char) {
1071
+ case "*":
1072
+ if (prevChar !== "*") {
1073
+ regexStr += ".*";
1074
+ }
1075
+ break;
1076
+ case "?":
1077
+ regexStr += ".";
1078
+ break;
1079
+ default:
1080
+ regexStr += char.replace(REGEX_SPECIAL_CHARS, "\\$&");
1081
+ }
1082
+ prevChar = char;
1083
+ }
1084
+ regexStr += "$";
1085
+ try {
1086
+ return new RegExp(regexStr);
1087
+ } catch {
1088
+ throw new StoragePatternError(pattern, "Failed to compile pattern to regex");
1089
+ }
1090
+ }
1091
+ function matchesPattern(key, pattern) {
1092
+ const regex = globToRegex(pattern);
1093
+ return regex.test(key);
1094
+ }
1095
+ var MAX_PATTERN_LENGTH;
1096
+ var MAX_WILDCARDS;
1097
+ var REGEX_SPECIAL_CHARS;
1098
+ var init_pattern = __esm({
1099
+ "libs/utils/src/storage/utils/pattern.ts"() {
1100
+ "use strict";
1101
+ init_errors();
1102
+ MAX_PATTERN_LENGTH = 500;
1103
+ MAX_WILDCARDS = 20;
1104
+ REGEX_SPECIAL_CHARS = /[.+^${}()|[\]\\]/g;
1105
+ }
1106
+ });
1053
1107
  function validateTTL(ttlSeconds) {
1054
1108
  if (typeof ttlSeconds !== "number") {
1055
1109
  throw new StorageTTLError(ttlSeconds, `TTL must be a number, got ${typeof ttlSeconds}`);
@@ -1158,6 +1212,17 @@ var init_base = __esm({
1158
1212
  const matchedKeys = await this.keys(pattern);
1159
1213
  return matchedKeys.length;
1160
1214
  }
1215
+ /**
1216
+ * Default: not supported, since a read followed by a delete is not atomic.
1217
+ * Override in adapters whose backend can compare and delete in one step.
1218
+ */
1219
+ async deleteIfEquals(_key, _expectedValue) {
1220
+ throw new StorageNotSupportedError(
1221
+ "deleteIfEquals",
1222
+ this.backendName,
1223
+ "Use the memory, Redis, Upstash or Vercel KV adapter for an atomic compare-and-delete."
1224
+ );
1225
+ }
1161
1226
  // ============================================
1162
1227
  // Pub/Sub (default: not supported)
1163
1228
  // ============================================
@@ -1205,71 +1270,16 @@ var init_base = __esm({
1205
1270
  };
1206
1271
  }
1207
1272
  });
1208
- function globToRegex(pattern) {
1209
- if (pattern.length > MAX_PATTERN_LENGTH) {
1210
- throw new StoragePatternError(
1211
- pattern.substring(0, 50) + "...",
1212
- `Pattern exceeds maximum length of ${MAX_PATTERN_LENGTH} characters`
1213
- );
1214
- }
1215
- const wildcardCount = (pattern.match(/[*?]/g) || []).length;
1216
- if (wildcardCount > MAX_WILDCARDS) {
1217
- throw new StoragePatternError(pattern, `Pattern has too many wildcards (max: ${MAX_WILDCARDS})`);
1218
- }
1219
- if (pattern === "" || pattern === "*") {
1220
- return /^.*$/;
1221
- }
1222
- let regexStr = "^";
1223
- let prevChar = "";
1224
- for (let i = 0; i < pattern.length; i++) {
1225
- const char = pattern[i];
1226
- switch (char) {
1227
- case "*":
1228
- if (prevChar !== "*") {
1229
- regexStr += ".*";
1230
- }
1231
- break;
1232
- case "?":
1233
- regexStr += ".";
1234
- break;
1235
- default:
1236
- regexStr += char.replace(REGEX_SPECIAL_CHARS, "\\$&");
1237
- }
1238
- prevChar = char;
1239
- }
1240
- regexStr += "$";
1241
- try {
1242
- return new RegExp(regexStr);
1243
- } catch {
1244
- throw new StoragePatternError(pattern, "Failed to compile pattern to regex");
1245
- }
1246
- }
1247
- function matchesPattern(key, pattern) {
1248
- const regex = globToRegex(pattern);
1249
- return regex.test(key);
1250
- }
1251
- var MAX_PATTERN_LENGTH;
1252
- var MAX_WILDCARDS;
1253
- var REGEX_SPECIAL_CHARS;
1254
- var init_pattern = __esm({
1255
- "libs/utils/src/storage/utils/pattern.ts"() {
1256
- "use strict";
1257
- init_errors();
1258
- MAX_PATTERN_LENGTH = 500;
1259
- MAX_WILDCARDS = 20;
1260
- REGEX_SPECIAL_CHARS = /[.+^${}()|[\]\\]/g;
1261
- }
1262
- });
1263
1273
  var DEFAULT_SWEEP_INTERVAL_SECONDS;
1264
1274
  var MAX_TIMEOUT_MS;
1265
1275
  var MemoryStorageAdapter;
1266
1276
  var init_memory = __esm({
1267
1277
  "libs/utils/src/storage/adapters/memory.ts"() {
1268
1278
  "use strict";
1269
- init_base();
1270
1279
  init_errors();
1271
1280
  init_pattern();
1272
1281
  init_ttl();
1282
+ init_base();
1273
1283
  DEFAULT_SWEEP_INTERVAL_SECONDS = 60;
1274
1284
  MAX_TIMEOUT_MS = 2147483647;
1275
1285
  MemoryStorageAdapter = class extends BaseStorageAdapter {
@@ -1361,6 +1371,12 @@ var init_memory = __esm({
1361
1371
  this.ensureConnected();
1362
1372
  return this.deleteEntry(key);
1363
1373
  }
1374
+ async deleteIfEquals(key, expectedValue) {
1375
+ this.ensureConnected();
1376
+ const entry = this.store.get(key);
1377
+ if (!entry || isExpired(entry.expiresAt) || entry.value !== expectedValue) return false;
1378
+ return this.deleteEntry(key);
1379
+ }
1364
1380
  async exists(key) {
1365
1381
  this.ensureConnected();
1366
1382
  const entry = this.store.get(key);
@@ -2738,6 +2754,13 @@ var init_utils = __esm({
2738
2754
  init_ttl();
2739
2755
  }
2740
2756
  });
2757
+ var COMPARE_AND_DELETE_SCRIPT;
2758
+ var init_compare_and_delete = __esm({
2759
+ "libs/utils/src/storage/utils/compare-and-delete.ts"() {
2760
+ "use strict";
2761
+ COMPARE_AND_DELETE_SCRIPT = `if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) end return 0`;
2762
+ }
2763
+ });
2741
2764
  var redis_exports = {};
2742
2765
  __export2(redis_exports, {
2743
2766
  RedisStorageAdapter: () => RedisStorageAdapter,
@@ -2780,6 +2803,7 @@ var init_redis = __esm({
2780
2803
  init_errors();
2781
2804
  init_redis_error_listener();
2782
2805
  init_utils();
2806
+ init_compare_and_delete();
2783
2807
  init_base();
2784
2808
  RedisStorageAdapter = class extends BaseStorageAdapter {
2785
2809
  backendName = "redis";
@@ -2934,6 +2958,15 @@ var init_redis = __esm({
2934
2958
  const result = await this.getConnectedClient().del(this.prefixKey(key));
2935
2959
  return result > 0;
2936
2960
  }
2961
+ async deleteIfEquals(key, expectedValue) {
2962
+ const deleted = await this.getConnectedClient().eval(
2963
+ COMPARE_AND_DELETE_SCRIPT,
2964
+ 1,
2965
+ this.prefixKey(key),
2966
+ expectedValue
2967
+ );
2968
+ return deleted === 1;
2969
+ }
2937
2970
  async exists(key) {
2938
2971
  const result = await this.getConnectedClient().exists(this.prefixKey(key));
2939
2972
  return result > 0;
@@ -3140,9 +3173,12 @@ var vercel_kv_exports = {};
3140
3173
  __export2(vercel_kv_exports, {
3141
3174
  VercelKvStorageAdapter: () => VercelKvStorageAdapter
3142
3175
  });
3143
- function getVercelKv() {
3176
+ async function loadVercelKv() {
3144
3177
  try {
3145
- return __require("@vercel/kv");
3178
+ const mod = await import("@vercel/kv");
3179
+ const resolved = typeof mod.createClient === "function" ? mod : mod.default;
3180
+ if (!resolved || typeof resolved.createClient !== "function") throw new Error("createClient missing");
3181
+ return resolved;
3146
3182
  } catch {
3147
3183
  throw new Error("@vercel/kv is required for Vercel KV storage adapter. Install it with: npm install @vercel/kv");
3148
3184
  }
@@ -3151,9 +3187,10 @@ var VercelKvStorageAdapter;
3151
3187
  var init_vercel_kv = __esm({
3152
3188
  "libs/utils/src/storage/adapters/vercel-kv.ts"() {
3153
3189
  "use strict";
3154
- init_base();
3155
3190
  init_errors();
3191
+ init_compare_and_delete();
3156
3192
  init_ttl();
3193
+ init_base();
3157
3194
  VercelKvStorageAdapter = class extends BaseStorageAdapter {
3158
3195
  backendName = "vercel-kv";
3159
3196
  client;
@@ -3178,17 +3215,13 @@ var init_vercel_kv = __esm({
3178
3215
  async connect() {
3179
3216
  if (this.connected) return;
3180
3217
  try {
3181
- const { createClient, kv } = getVercelKv();
3182
- if (this.options.url === process.env["KV_REST_API_URL"]) {
3183
- this.client = kv;
3184
- } else {
3185
- const url = this.options.url;
3186
- const token = this.options.token;
3187
- if (!url || !token) {
3188
- throw new StorageConfigError("vercel-kv", "URL and token are required");
3189
- }
3190
- this.client = createClient({ url, token });
3218
+ const { createClient } = await loadVercelKv();
3219
+ const url = this.options.url;
3220
+ const token = this.options.token;
3221
+ if (!url || !token) {
3222
+ throw new StorageConfigError("vercel-kv", "URL and token are required");
3191
3223
  }
3224
+ this.client = createClient({ url, token, cache: void 0, automaticDeserialization: false });
3192
3225
  await this.client.exists("__healthcheck__");
3193
3226
  this.connected = true;
3194
3227
  } catch (e) {
@@ -3229,8 +3262,7 @@ var init_vercel_kv = __esm({
3229
3262
  // Core Operations
3230
3263
  // ============================================
3231
3264
  async get(key) {
3232
- const result = await this.getConnectedClient().get(this.prefixKey(key));
3233
- return result;
3265
+ return this.getConnectedClient().get(this.prefixKey(key));
3234
3266
  }
3235
3267
  async doSet(key, value, options) {
3236
3268
  const client = this.getConnectedClient();
@@ -3250,6 +3282,14 @@ var init_vercel_kv = __esm({
3250
3282
  const result = await this.getConnectedClient().del(this.prefixKey(key));
3251
3283
  return result > 0;
3252
3284
  }
3285
+ async deleteIfEquals(key, expectedValue) {
3286
+ const deleted = await this.getConnectedClient().eval(
3287
+ COMPARE_AND_DELETE_SCRIPT,
3288
+ [this.prefixKey(key)],
3289
+ [expectedValue]
3290
+ );
3291
+ return deleted === 1;
3292
+ }
3253
3293
  async exists(key) {
3254
3294
  const result = await this.getConnectedClient().exists(this.prefixKey(key));
3255
3295
  return result > 0;
@@ -3366,9 +3406,10 @@ var UpstashStorageAdapter;
3366
3406
  var init_upstash = __esm({
3367
3407
  "libs/utils/src/storage/adapters/upstash.ts"() {
3368
3408
  "use strict";
3369
- init_base();
3370
3409
  init_errors();
3410
+ init_compare_and_delete();
3371
3411
  init_ttl();
3412
+ init_base();
3372
3413
  PUBSUB_POLL_INTERVAL_MS = 100;
3373
3414
  UpstashStorageAdapter = class extends BaseStorageAdapter {
3374
3415
  backendName = "upstash";
@@ -3405,7 +3446,7 @@ var init_upstash = __esm({
3405
3446
  if (!url || !token) {
3406
3447
  throw new StorageConfigError("upstash", "URL and token are required");
3407
3448
  }
3408
- this.client = new Redis({ url, token });
3449
+ this.client = new Redis({ url, token, automaticDeserialization: false });
3409
3450
  await this.client.exists("__healthcheck__");
3410
3451
  this.connected = true;
3411
3452
  } catch (e) {
@@ -3452,8 +3493,7 @@ var init_upstash = __esm({
3452
3493
  // Core Operations
3453
3494
  // ============================================
3454
3495
  async get(key) {
3455
- const result = await this.getConnectedClient().get(this.prefixKey(key));
3456
- return result;
3496
+ return this.getConnectedClient().get(this.prefixKey(key));
3457
3497
  }
3458
3498
  async doSet(key, value, options) {
3459
3499
  const client = this.getConnectedClient();
@@ -3473,6 +3513,14 @@ var init_upstash = __esm({
3473
3513
  const result = await this.getConnectedClient().del(this.prefixKey(key));
3474
3514
  return result > 0;
3475
3515
  }
3516
+ async deleteIfEquals(key, expectedValue) {
3517
+ const deleted = await this.getConnectedClient().eval(
3518
+ COMPARE_AND_DELETE_SCRIPT,
3519
+ [this.prefixKey(key)],
3520
+ [expectedValue]
3521
+ );
3522
+ return deleted === 1;
3523
+ }
3476
3524
  async exists(key) {
3477
3525
  const result = await this.getConnectedClient().exists(this.prefixKey(key));
3478
3526
  return result > 0;
@@ -3661,7 +3709,9 @@ var init_cloudflare_kv = __esm({
3661
3709
  constructor(options) {
3662
3710
  super();
3663
3711
  if (!options?.namespace) {
3664
- throw new Error("CloudflareKvStorageAdapter: a bound KV `namespace` is required (resolve it from the Worker `env`).");
3712
+ throw new Error(
3713
+ "CloudflareKvStorageAdapter: a bound KV `namespace` is required (resolve it from the Worker `env`)."
3714
+ );
3665
3715
  }
3666
3716
  this.kv = options.namespace;
3667
3717
  this.keyPrefix = options.keyPrefix ?? "";
@@ -3755,6 +3805,13 @@ var init_cloudflare_kv = __esm({
3755
3805
  "Cloudflare KV has no atomic increment (a get+put is racy under eventual consistency). Use a Durable Object for atomic counters."
3756
3806
  );
3757
3807
  }
3808
+ async deleteIfEquals(_key, _expectedValue) {
3809
+ throw new StorageNotSupportedError(
3810
+ "deleteIfEquals",
3811
+ this.backendName,
3812
+ "Cloudflare KV has no compare-and-set; use a Durable Object for an atomic compare-and-delete."
3813
+ );
3814
+ }
3758
3815
  // ── Pub/Sub (unsupported) ────────────────────────────────────────────────
3759
3816
  getPubSubSuggestion() {
3760
3817
  return "Cloudflare KV does not support pub/sub. Use a Durable Object (or Queues) for fan-out.";
@@ -3868,16 +3925,7 @@ function compileBlocks(entries, parseNetwork) {
3868
3925
  }
3869
3926
  init_fs2();
3870
3927
  init_crypto();
3871
- var entryAvailabilitySchema = import_lazy_zod4.z.object({
3872
- os: import_lazy_zod4.z.array(import_lazy_zod4.z.string().min(1)).optional(),
3873
- platform: import_lazy_zod4.z.array(import_lazy_zod4.z.string().min(1)).optional(),
3874
- runtime: import_lazy_zod4.z.array(import_lazy_zod4.z.string().min(1)).optional(),
3875
- deployment: import_lazy_zod4.z.array(import_lazy_zod4.z.string().min(1)).optional(),
3876
- provider: import_lazy_zod4.z.array(import_lazy_zod4.z.string().min(1)).optional(),
3877
- target: import_lazy_zod4.z.array(import_lazy_zod4.z.string().min(1)).optional(),
3878
- surface: import_lazy_zod4.z.array(import_lazy_zod4.z.enum(["mcp", "cli", "http-trigger", "job", "agent"])).optional(),
3879
- env: import_lazy_zod4.z.array(import_lazy_zod4.z.string().min(1)).optional()
3880
- }).strict();
3928
+ init_errors();
3881
3929
  init_errors();
3882
3930
  init_memory();
3883
3931
  init_redis_error_listener();
@@ -4850,11 +4898,11 @@ GraphDataProvider = __decorateClass([
4850
4898
  ], GraphDataProvider);
4851
4899
 
4852
4900
  // plugins/plugin-dashboard/src/tools/graph.tool.ts
4853
- var import_lazy_zod5 = require("@frontmcp/lazy-zod");
4901
+ var import_lazy_zod4 = require("@frontmcp/lazy-zod");
4854
4902
  var import_sdk4 = require("@frontmcp/sdk");
4855
4903
  var graphToolInputSchema = {
4856
- includeSchemas: import_lazy_zod5.z.boolean().optional().default(false).describe("Include full input/output schemas in the response"),
4857
- refresh: import_lazy_zod5.z.boolean().optional().default(false).describe("Force refresh the graph data (bypass cache)")
4904
+ includeSchemas: import_lazy_zod4.z.boolean().optional().default(false).describe("Include full input/output schemas in the response"),
4905
+ refresh: import_lazy_zod4.z.boolean().optional().default(false).describe("Force refresh the graph data (bypass cache)")
4858
4906
  };
4859
4907
  var GraphTool = class extends import_sdk4.ToolContext {
4860
4908
  async execute(input) {
@@ -4892,7 +4940,7 @@ GraphTool = __decorateClass([
4892
4940
  ], GraphTool);
4893
4941
 
4894
4942
  // plugins/plugin-dashboard/src/tools/list-resources.tool.ts
4895
- var import_lazy_zod6 = require("@frontmcp/lazy-zod");
4943
+ var import_lazy_zod5 = require("@frontmcp/lazy-zod");
4896
4944
  var import_sdk5 = require("@frontmcp/sdk");
4897
4945
 
4898
4946
  // plugins/plugin-dashboard/src/shared/safe-regex.ts
@@ -4911,20 +4959,20 @@ function safeRegex(pattern) {
4911
4959
 
4912
4960
  // plugins/plugin-dashboard/src/tools/list-resources.tool.ts
4913
4961
  var listResourcesInputSchema = {
4914
- filter: import_lazy_zod6.z.string().optional().describe("Filter resources by name or URI pattern (regex supported)"),
4915
- includeTemplates: import_lazy_zod6.z.boolean().default(true).describe("Include resource templates in the response")
4962
+ filter: import_lazy_zod5.z.string().optional().describe("Filter resources by name or URI pattern (regex supported)"),
4963
+ includeTemplates: import_lazy_zod5.z.boolean().default(true).describe("Include resource templates in the response")
4916
4964
  };
4917
- var listResourcesOutputSchema = import_lazy_zod6.z.object({
4918
- resources: import_lazy_zod6.z.array(
4919
- import_lazy_zod6.z.object({
4920
- name: import_lazy_zod6.z.string(),
4921
- uri: import_lazy_zod6.z.string(),
4922
- description: import_lazy_zod6.z.string().optional(),
4923
- mimeType: import_lazy_zod6.z.string().optional(),
4924
- isTemplate: import_lazy_zod6.z.boolean()
4965
+ var listResourcesOutputSchema = import_lazy_zod5.z.object({
4966
+ resources: import_lazy_zod5.z.array(
4967
+ import_lazy_zod5.z.object({
4968
+ name: import_lazy_zod5.z.string(),
4969
+ uri: import_lazy_zod5.z.string(),
4970
+ description: import_lazy_zod5.z.string().optional(),
4971
+ mimeType: import_lazy_zod5.z.string().optional(),
4972
+ isTemplate: import_lazy_zod5.z.boolean()
4925
4973
  })
4926
4974
  ),
4927
- count: import_lazy_zod6.z.number()
4975
+ count: import_lazy_zod5.z.number()
4928
4976
  });
4929
4977
  var ListResourcesTool = class extends import_sdk5.ToolContext {
4930
4978
  async execute(input) {
@@ -4986,25 +5034,25 @@ ListResourcesTool = __decorateClass([
4986
5034
  ], ListResourcesTool);
4987
5035
 
4988
5036
  // plugins/plugin-dashboard/src/tools/list-tools.tool.ts
4989
- var import_lazy_zod7 = require("@frontmcp/lazy-zod");
5037
+ var import_lazy_zod6 = require("@frontmcp/lazy-zod");
4990
5038
  var import_sdk6 = require("@frontmcp/sdk");
4991
5039
  var listToolsInputSchema = {
4992
- filter: import_lazy_zod7.z.string().optional().describe("Filter tools by name pattern (regex supported)"),
4993
- includePlugins: import_lazy_zod7.z.boolean().default(true).describe("Include tools from plugins"),
4994
- includeSchemas: import_lazy_zod7.z.boolean().default(false).describe("Include input/output schemas in the response")
5040
+ filter: import_lazy_zod6.z.string().optional().describe("Filter tools by name pattern (regex supported)"),
5041
+ includePlugins: import_lazy_zod6.z.boolean().default(true).describe("Include tools from plugins"),
5042
+ includeSchemas: import_lazy_zod6.z.boolean().default(false).describe("Include input/output schemas in the response")
4995
5043
  };
4996
- var listToolsOutputSchema = import_lazy_zod7.z.object({
4997
- tools: import_lazy_zod7.z.array(
4998
- import_lazy_zod7.z.object({
4999
- name: import_lazy_zod7.z.string(),
5000
- fullName: import_lazy_zod7.z.string(),
5001
- description: import_lazy_zod7.z.string().optional(),
5002
- tags: import_lazy_zod7.z.array(import_lazy_zod7.z.string()).optional(),
5003
- inputSchema: import_lazy_zod7.z.unknown().optional(),
5004
- outputSchema: import_lazy_zod7.z.unknown().optional()
5044
+ var listToolsOutputSchema = import_lazy_zod6.z.object({
5045
+ tools: import_lazy_zod6.z.array(
5046
+ import_lazy_zod6.z.object({
5047
+ name: import_lazy_zod6.z.string(),
5048
+ fullName: import_lazy_zod6.z.string(),
5049
+ description: import_lazy_zod6.z.string().optional(),
5050
+ tags: import_lazy_zod6.z.array(import_lazy_zod6.z.string()).optional(),
5051
+ inputSchema: import_lazy_zod6.z.unknown().optional(),
5052
+ outputSchema: import_lazy_zod6.z.unknown().optional()
5005
5053
  })
5006
5054
  ),
5007
- count: import_lazy_zod7.z.number()
5055
+ count: import_lazy_zod6.z.number()
5008
5056
  });
5009
5057
  var ListToolsTool = class extends import_sdk6.ToolContext {
5010
5058
  async execute(input) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/plugin-dashboard",
3
- "version": "1.8.7",
3
+ "version": "1.9.1-rc.1",
4
4
  "description": "Dashboard plugin for FrontMCP - visual monitoring and introspection of MCP servers",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
@@ -47,12 +47,12 @@
47
47
  }
48
48
  },
49
49
  "dependencies": {
50
- "@frontmcp/sdk": "1.8.7"
50
+ "@frontmcp/sdk": "1.9.1-rc.1"
51
51
  },
52
52
  "devDependencies": {
53
53
  "reflect-metadata": "^0.2.2"
54
54
  },
55
55
  "peerDependencies": {
56
- "@frontmcp/lazy-zod": "1.8.7"
56
+ "@frontmcp/lazy-zod": "1.9.1-rc.1"
57
57
  }
58
58
  }