@modelcontextprotocol/inspector 2.13.0 → 2.15.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.
- package/README.md +1 -1
- package/clients/cli/build/index.js +5481 -1847
- package/clients/mcpdo/build/mcp-bin.js +925 -186
- package/clients/mcpdo/build/mcpdod.js +2 -3
- package/clients/mcpdo/build/{server-BHuKGkMj.js → server-B-CUVIBj.js} +3544 -995
- package/clients/tui/build/index.js +2126 -570
- package/clients/web/build/index.js +459 -280
- package/clients/web/dist/assets/fredoka-normal-hebrew-CjvktpUN.woff2 +0 -0
- package/clients/web/dist/assets/fredoka-normal-latin-DOQG_Jwn.woff2 +0 -0
- package/clients/web/dist/assets/fredoka-normal-latin-ext-tYNUQHO6.woff2 +0 -0
- package/clients/web/dist/assets/index-BZ94R6fh.js +1599 -0
- package/clients/web/dist/assets/{index-dqp8Sd8W.css → index-tBehH5iF.css} +1 -1
- package/clients/web/dist/assets/{prism-light-BIhJtJkv.js → prism-light-Crps--E8.js} +1 -1
- package/clients/web/dist/assets/roboto-mono-italic-cyrillic-C1E63de8.woff2 +0 -0
- package/clients/web/dist/assets/roboto-mono-italic-cyrillic-ext-DR9ovEqT.woff2 +0 -0
- package/clients/web/dist/assets/roboto-mono-italic-greek-Cs2u2nVh.woff2 +0 -0
- package/clients/web/dist/assets/roboto-mono-italic-latin-D_P-kX1t.woff2 +0 -0
- package/clients/web/dist/assets/roboto-mono-italic-latin-ext-CErTcBzw.woff2 +0 -0
- package/clients/web/dist/assets/roboto-mono-italic-vietnamese-D4UvzJMM.woff2 +0 -0
- package/clients/web/dist/assets/roboto-mono-normal-cyrillic-DfzWIUPd.woff2 +0 -0
- package/clients/web/dist/assets/roboto-mono-normal-cyrillic-ext-D8QBEkUe.woff2 +0 -0
- package/clients/web/dist/assets/roboto-mono-normal-greek-DlC4X1lQ.woff2 +0 -0
- package/clients/web/dist/assets/roboto-mono-normal-latin-BAKpfWyj.woff2 +0 -0
- package/clients/web/dist/assets/roboto-mono-normal-latin-ext-CSSVNFqV.woff2 +0 -0
- package/clients/web/dist/assets/roboto-mono-normal-vietnamese-DFkHeOHB.woff2 +0 -0
- package/clients/web/dist/assets/worker-json-DEGsizKa.js +7859 -0
- package/clients/web/dist/fonts/Fredoka-OFL.txt +93 -0
- package/clients/web/dist/fonts/RobotoMono-OFL.txt +93 -0
- package/clients/web/dist/index.html +2 -5
- package/clients/web/static/sandbox_proxy.html +177 -6
- package/package.json +8 -4
- package/skills/mcpdo/SKILL.md +63 -2
- package/clients/web/dist/assets/index-BqEbhCDX.js +0 -1587
- package/clients/web/dist/assets/worker-json-8CDXFfik.js +0 -1631
|
@@ -31,7 +31,10 @@ import { runtimeCodecFromStandardSchema, taskId, toJsonValue } from "@modelconte
|
|
|
31
31
|
import { CallToolResultSchema, ElicitResultSchema, EmptyResultSchema, GetPromptResultSchema, ListPromptsResultSchema, ListResourceTemplatesResultSchema, ListResourcesResultSchema, ListToolsResultSchema, NotificationSchema, OAuthClientInformationSchema, OAuthMetadataSchema, OAuthTokensSchema, OpenIdProviderDiscoveryMetadataSchema, ProgressTokenSchema, PromptSchema, ReadResourceResultSchema, RequestMetaSchema, ResourceSchema, ResourceTemplateSchema, TaskStatusNotificationSchema, ToolSchema } from "@modelcontextprotocol/core";
|
|
32
32
|
import { TASKS_EXTENSION_ID_V2 as TASKS_EXTENSION_KEY } from "@modelcontextprotocol/ext-tasks/core/v2";
|
|
33
33
|
import { RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/app-bridge";
|
|
34
|
-
import
|
|
34
|
+
import Ajv from "ajv";
|
|
35
|
+
import { Ajv2019 } from "ajv/dist/2019.js";
|
|
36
|
+
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
37
|
+
import { addFormats } from "@modelcontextprotocol/client/validators/ajv";
|
|
35
38
|
import { createServer } from "node:http";
|
|
36
39
|
import pino from "pino";
|
|
37
40
|
import open from "open";
|
|
@@ -40,15 +43,14 @@ import os from "node:os";
|
|
|
40
43
|
import process$1 from "node:process";
|
|
41
44
|
import tty from "node:tty";
|
|
42
45
|
import { isDeepStrictEqual } from "node:util";
|
|
43
|
-
|
|
46
|
+
// ../../core/storage/store-serialize.ts
|
|
44
47
|
function serializeStore(data) {
|
|
45
48
|
return JSON.stringify(data, null, 2);
|
|
46
49
|
}
|
|
47
50
|
function parseStore(raw) {
|
|
48
51
|
return JSON.parse(raw);
|
|
49
52
|
}
|
|
50
|
-
|
|
51
|
-
//#region ../../core/storage/store-io.ts
|
|
53
|
+
// ../../core/storage/store-io.ts
|
|
52
54
|
function getDefaultStorageDir() {
|
|
53
55
|
const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
|
|
54
56
|
return path$1.join(homeDir, ".mcp-inspector", "storage");
|
|
@@ -94,8 +96,7 @@ async function deleteStoreFile(filePath) {
|
|
|
94
96
|
if (error.code !== "ENOENT") throw error;
|
|
95
97
|
}
|
|
96
98
|
}
|
|
97
|
-
|
|
98
|
-
//#region ../../core/mcp/types.ts
|
|
99
|
+
// ../../core/mcp/types.ts
|
|
99
100
|
function isTerminalStatus(status) {
|
|
100
101
|
return status === "disconnected" || status === "error";
|
|
101
102
|
}
|
|
@@ -133,8 +134,7 @@ function eraToVersionNegotiation(era) {
|
|
|
133
134
|
case "legacy": return { mode: "legacy" };
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
|
-
|
|
137
|
-
//#region ../../core/extension/skills/schemas.ts
|
|
137
|
+
// ../../core/extension/skills/schemas.ts
|
|
138
138
|
const CACHE_FIELDS = {
|
|
139
139
|
ttlMs: ReadResourceDirectoryResultSchema.shape.ttlMs,
|
|
140
140
|
cacheScope: SkillCacheScopeSchema
|
|
@@ -167,8 +167,7 @@ const DirectoryReadResultSchema = ReadResourceDirectoryResultSchema.partial({
|
|
|
167
167
|
ttlMs: true,
|
|
168
168
|
cacheScope: true
|
|
169
169
|
});
|
|
170
|
-
|
|
171
|
-
//#region ../../core/extension/skills/sha256.ts
|
|
170
|
+
// ../../core/extension/skills/sha256.ts
|
|
172
171
|
const K = new Uint32Array([
|
|
173
172
|
1116352408,
|
|
174
173
|
1899447441,
|
|
@@ -294,8 +293,7 @@ function sha256Bytes(bytes) {
|
|
|
294
293
|
for (let i = 0; i < 8; i += 1) out.setUint32(i * 4, h[i]);
|
|
295
294
|
return digest;
|
|
296
295
|
}
|
|
297
|
-
|
|
298
|
-
//#region ../../core/extension/skills/skillFile.ts
|
|
296
|
+
// ../../core/extension/skills/skillFile.ts
|
|
299
297
|
function splitSkillFile(text) {
|
|
300
298
|
if (!/^---[ \t]*\r?\n/.test(text)) return { body: text };
|
|
301
299
|
const rest = text.slice(text.indexOf("\n") + 1);
|
|
@@ -343,8 +341,7 @@ function parseSkillFrontmatter(yamlText) {
|
|
|
343
341
|
if (graphError) return { error: graphError };
|
|
344
342
|
return { fields: parsed };
|
|
345
343
|
}
|
|
346
|
-
|
|
347
|
-
//#region ../../core/extension/skills/conformance.ts
|
|
344
|
+
// ../../core/extension/skills/conformance.ts
|
|
348
345
|
const SKILL_MAX_RESOURCE_ENTRIES = SKILL_LIMITS.files;
|
|
349
346
|
const SKILL_MAX_TOTAL_BYTES = SKILL_LIMITS.bytes;
|
|
350
347
|
const SKILL_MAX_CATALOG_BYTES = 67108864;
|
|
@@ -702,13 +699,11 @@ function checkSkillNameCollisions(entries) {
|
|
|
702
699
|
}
|
|
703
700
|
return issues;
|
|
704
701
|
}
|
|
705
|
-
|
|
706
|
-
//#region ../../core/auth/secret-fields.ts
|
|
702
|
+
// ../../core/auth/secret-fields.ts
|
|
707
703
|
const SECRET_FIELD_OAUTH_CLIENT_SECRET = "oauth-client-secret";
|
|
708
704
|
const SECRET_FIELD_IDP_CLIENT_SECRET = "idp-client-secret";
|
|
709
705
|
const envSecretField = (envKey) => `env:${envKey}`;
|
|
710
|
-
|
|
711
|
-
//#region ../../core/json/localRefs.ts
|
|
706
|
+
// ../../core/json/localRefs.ts
|
|
712
707
|
const SUBSCHEMA_KEYWORDS$1 = /* @__PURE__ */ new Set([
|
|
713
708
|
"items",
|
|
714
709
|
"contains",
|
|
@@ -863,8 +858,7 @@ function inlineLocalRefs(schema) {
|
|
|
863
858
|
cache.set(schema, resolved);
|
|
864
859
|
return resolved;
|
|
865
860
|
}
|
|
866
|
-
|
|
867
|
-
//#region ../../core/json/nullableUnion.ts
|
|
861
|
+
// ../../core/json/nullableUnion.ts
|
|
868
862
|
const RENDERABLE_TYPES = [
|
|
869
863
|
"string",
|
|
870
864
|
"number",
|
|
@@ -1017,8 +1011,7 @@ function normalizeNullableUnion(schema) {
|
|
|
1017
1011
|
}
|
|
1018
1012
|
return schema;
|
|
1019
1013
|
}
|
|
1020
|
-
|
|
1021
|
-
//#region ../../core/json/rootUnion.ts
|
|
1014
|
+
// ../../core/json/rootUnion.ts
|
|
1022
1015
|
function membersOf(value) {
|
|
1023
1016
|
return Array.isArray(value) ? value : [];
|
|
1024
1017
|
}
|
|
@@ -1238,8 +1231,7 @@ function narrowBySuppliedNames(branches, candidates, suppliedNames) {
|
|
|
1238
1231
|
const named = new Set(suppliedNames.map((name) => exclusiveTo.get(name)).filter((index) => index !== void 0 && index >= 0));
|
|
1239
1232
|
return named.size === 1 ? [...named][0] : null;
|
|
1240
1233
|
}
|
|
1241
|
-
|
|
1242
|
-
//#region ../../core/json/jsonUtils.ts
|
|
1234
|
+
// ../../core/json/jsonUtils.ts
|
|
1243
1235
|
function isSerializableJson(value) {
|
|
1244
1236
|
if (value === null) return true;
|
|
1245
1237
|
switch (typeof value) {
|
|
@@ -1340,8 +1332,7 @@ function convertPromptArguments(args) {
|
|
|
1340
1332
|
else stringArgs[key] = JSON.stringify(value);
|
|
1341
1333
|
return stringArgs;
|
|
1342
1334
|
}
|
|
1343
|
-
|
|
1344
|
-
//#region ../../core/mcp/serverList.ts
|
|
1335
|
+
// ../../core/mcp/serverList.ts
|
|
1345
1336
|
const VALID_SERVER_TYPES = /* @__PURE__ */ new Set([
|
|
1346
1337
|
"stdio",
|
|
1347
1338
|
"sse",
|
|
@@ -1607,8 +1598,15 @@ function expectedSecretFields(stored) {
|
|
|
1607
1598
|
if (isStdioStored(stored) && stored.env) for (const k of Object.keys(stored.env)) fields.push(envSecretField(k));
|
|
1608
1599
|
return fields;
|
|
1609
1600
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1601
|
+
function adHocServerName(config) {
|
|
1602
|
+
if (config.type === "sse" || config.type === "streamable-http") try {
|
|
1603
|
+
return new URL(config.url).host || "server";
|
|
1604
|
+
} catch {
|
|
1605
|
+
return "server";
|
|
1606
|
+
}
|
|
1607
|
+
return config.command?.split(/[\\/]/).pop() || "server";
|
|
1608
|
+
}
|
|
1609
|
+
// ../../core/storage/own-entry.ts
|
|
1612
1610
|
function setOwnEntry(map, key, value) {
|
|
1613
1611
|
Object.defineProperty(map, key, {
|
|
1614
1612
|
value,
|
|
@@ -1620,8 +1618,7 @@ function setOwnEntry(map, key, value) {
|
|
|
1620
1618
|
function getOwnEntry(map, key) {
|
|
1621
1619
|
return map !== void 0 && Object.hasOwn(map, key) ? map[key] : void 0;
|
|
1622
1620
|
}
|
|
1623
|
-
|
|
1624
|
-
//#region ../../core/mcp/node/config.ts
|
|
1621
|
+
// ../../core/mcp/node/config.ts
|
|
1625
1622
|
function parseKeyValuePair(value, previous = {}) {
|
|
1626
1623
|
const parts = value.split("=");
|
|
1627
1624
|
const key = parts[0] ?? "";
|
|
@@ -1812,8 +1809,7 @@ function resolveServerConfigs(options, mode) {
|
|
|
1812
1809
|
}
|
|
1813
1810
|
return [];
|
|
1814
1811
|
}
|
|
1815
|
-
|
|
1816
|
-
//#region ../../core/auth/secret-storage-info.ts
|
|
1812
|
+
// ../../core/auth/secret-storage-info.ts
|
|
1817
1813
|
function secretStorageLabel(info) {
|
|
1818
1814
|
switch (info.kind) {
|
|
1819
1815
|
case "keyring": return "OS keychain";
|
|
@@ -1840,8 +1836,7 @@ function secretStorageSummary(info) {
|
|
|
1840
1836
|
if (info.reason === "fallback") parts.push("— fell back from the OS keychain");
|
|
1841
1837
|
return parts.join(" ");
|
|
1842
1838
|
}
|
|
1843
|
-
|
|
1844
|
-
//#region ../../core/auth/node/secret-store.ts
|
|
1839
|
+
// ../../core/auth/node/secret-store.ts
|
|
1845
1840
|
const SERVICE_NAME = "mcp-inspector";
|
|
1846
1841
|
let keyringLoad;
|
|
1847
1842
|
var KeyringModuleShapeError = class extends Error {
|
|
@@ -2061,8 +2056,7 @@ var SessionSecretStore = class extends InMemorySecretStore {
|
|
|
2061
2056
|
return false;
|
|
2062
2057
|
}
|
|
2063
2058
|
};
|
|
2064
|
-
|
|
2065
|
-
//#region ../../core/auth/node/file-lock.ts
|
|
2059
|
+
// ../../core/auth/node/file-lock.ts
|
|
2066
2060
|
const STALE_MS = 1e4;
|
|
2067
2061
|
const RETRY = {
|
|
2068
2062
|
retries: 20,
|
|
@@ -2194,8 +2188,7 @@ async function withSecretFileLock(filePath, fn) {
|
|
|
2194
2188
|
await release();
|
|
2195
2189
|
}
|
|
2196
2190
|
}
|
|
2197
|
-
|
|
2198
|
-
//#region ../../core/auth/node/file-secret-store.ts
|
|
2191
|
+
// ../../core/auth/node/file-secret-store.ts
|
|
2199
2192
|
const scrypt = (passphrase, salt, keylen, options) => new Promise((resolve, reject) => {
|
|
2200
2193
|
crypto$1.scrypt(passphrase, salt, keylen, options, (err, key) => {
|
|
2201
2194
|
/* v8 ignore next -- @preserve: node validates the cost parameters
|
|
@@ -2603,8 +2596,7 @@ async function readSecretFilePermissions(filePath) {
|
|
|
2603
2596
|
};
|
|
2604
2597
|
}
|
|
2605
2598
|
}
|
|
2606
|
-
|
|
2607
|
-
//#region ../../core/auth/node/secret-store-selection.ts
|
|
2599
|
+
// ../../core/auth/node/secret-store-selection.ts
|
|
2608
2600
|
const SECRET_STORE_ENV = "MCP_INSPECTOR_SECRET_STORE";
|
|
2609
2601
|
const SECRET_FILE_ENV = "MCP_INSPECTOR_SECRET_FILE";
|
|
2610
2602
|
const STORAGE_DIR_ENV = "MCP_STORAGE_DIR";
|
|
@@ -2911,8 +2903,7 @@ function defaultSecretStore() {
|
|
|
2911
2903
|
async function resolveConcreteSecretStore(store) {
|
|
2912
2904
|
return store instanceof DeferredSecretStore ? (await resolveSecretStore()).store : store;
|
|
2913
2905
|
}
|
|
2914
|
-
|
|
2915
|
-
//#region ../../core/mcp/node/server-secrets.ts
|
|
2906
|
+
// ../../core/mcp/node/server-secrets.ts
|
|
2916
2907
|
async function rehydrateMcpConfigFromKeychain(config, secretStore) {
|
|
2917
2908
|
const entries = Object.entries(config.mcpServers);
|
|
2918
2909
|
const secrets = await secretStoreGetMany(secretStore, entries.map(([serverId, stored]) => ({
|
|
@@ -2923,8 +2914,7 @@ async function rehydrateMcpConfigFromKeychain(config, secretStore) {
|
|
|
2923
2914
|
for (const [id, stored] of entries) out.mcpServers[id] = mergeSecretsIntoStored(stored, secrets[id] ?? {});
|
|
2924
2915
|
return out;
|
|
2925
2916
|
}
|
|
2926
|
-
|
|
2927
|
-
//#region ../../core/mcp/node/servers.ts
|
|
2917
|
+
// ../../core/mcp/node/servers.ts
|
|
2928
2918
|
function headersToServerSettings(headers) {
|
|
2929
2919
|
if (!headers || Object.keys(headers).length === 0) return;
|
|
2930
2920
|
return {
|
|
@@ -2996,13 +2986,13 @@ async function loadServerEntries(serverOptions) {
|
|
|
2996
2986
|
}
|
|
2997
2987
|
const configs = resolveServerConfigs(serverOptions, "multi");
|
|
2998
2988
|
if (configs.length === 0) throw new Error("At least one server is required. Use --catalog/--config <path> or an ad-hoc target (command/URL).");
|
|
2999
|
-
|
|
3000
|
-
|
|
2989
|
+
const config = configs[0];
|
|
2990
|
+
return { [adHocServerName(config)]: {
|
|
2991
|
+
config,
|
|
3001
2992
|
settings: mergeSettings(void 0, serverOptions)
|
|
3002
2993
|
} };
|
|
3003
2994
|
}
|
|
3004
|
-
|
|
3005
|
-
//#region ../../core/mcp/config.ts
|
|
2995
|
+
// ../../core/mcp/config.ts
|
|
3006
2996
|
function getServerType(config) {
|
|
3007
2997
|
if (!("type" in config) || config.type === void 0) return "stdio";
|
|
3008
2998
|
const type = config.type;
|
|
@@ -3011,8 +3001,7 @@ function getServerType(config) {
|
|
|
3011
3001
|
if (type === "streamable-http") return "streamable-http";
|
|
3012
3002
|
throw new Error(`Invalid server type: ${type}. Valid types are: stdio, sse, streamable-http`);
|
|
3013
3003
|
}
|
|
3014
|
-
|
|
3015
|
-
//#region ../../core/mcp/fetchTracking.ts
|
|
3004
|
+
// ../../core/mcp/fetchTracking.ts
|
|
3016
3005
|
const SENSITIVE_HEADERS = /* @__PURE__ */ new Set([
|
|
3017
3006
|
"authorization",
|
|
3018
3007
|
"cookie",
|
|
@@ -3065,6 +3054,37 @@ function redactUrlQuery(url) {
|
|
|
3065
3054
|
}
|
|
3066
3055
|
}
|
|
3067
3056
|
const EMBEDDED_URL_PATTERN = /\bhttps?:\/\/(?:(?!https?:\/\/)[^\s"<>])+/gi;
|
|
3057
|
+
function newUrlScan() {
|
|
3058
|
+
return {
|
|
3059
|
+
phase: "path",
|
|
3060
|
+
name: "",
|
|
3061
|
+
inValue: false,
|
|
3062
|
+
sensitive: false,
|
|
3063
|
+
endsWithEquals: false
|
|
3064
|
+
};
|
|
3065
|
+
}
|
|
3066
|
+
function advanceUrlScan(scan, piece, sensitiveNames) {
|
|
3067
|
+
for (const char of piece) {
|
|
3068
|
+
if (scan.phase === "fragment") break;
|
|
3069
|
+
if (char === "#") scan.phase = "fragment";
|
|
3070
|
+
else if (scan.phase === "path") {
|
|
3071
|
+
if (char === "?") scan.phase = "query";
|
|
3072
|
+
} else if (char === "&") {
|
|
3073
|
+
scan.name = "";
|
|
3074
|
+
scan.inValue = false;
|
|
3075
|
+
scan.sensitive = false;
|
|
3076
|
+
} else if (!scan.inValue) {
|
|
3077
|
+
if (char === "=") {
|
|
3078
|
+
scan.inValue = true;
|
|
3079
|
+
scan.sensitive = [...new URLSearchParams(`&${scan.name}=`).keys()].some((key) => sensitiveNames.has(key.toLowerCase()));
|
|
3080
|
+
} else scan.name += char;
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
scan.endsWithEquals = scan.phase === "query" && scan.inValue && piece.endsWith("=");
|
|
3084
|
+
}
|
|
3085
|
+
function opensSensitiveValue(scan) {
|
|
3086
|
+
return scan.endsWithEquals && scan.sensitive;
|
|
3087
|
+
}
|
|
3068
3088
|
const TRAILING_PUNCTUATION = /* @__PURE__ */ new Set([
|
|
3069
3089
|
".",
|
|
3070
3090
|
",",
|
|
@@ -3082,10 +3102,37 @@ function trailingPunctuationStart(match) {
|
|
|
3082
3102
|
return end;
|
|
3083
3103
|
}
|
|
3084
3104
|
function redactUrlsInText(text) {
|
|
3085
|
-
return text
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3105
|
+
return mapUrlsInText(text, redactUrlQuery);
|
|
3106
|
+
}
|
|
3107
|
+
function mapUrlsInText(text, redact, sensitiveNames = SENSITIVE_BODY_FIELDS) {
|
|
3108
|
+
let out = "";
|
|
3109
|
+
let copied = 0;
|
|
3110
|
+
let pieces = [];
|
|
3111
|
+
let scan = newUrlScan();
|
|
3112
|
+
const flush = () => {
|
|
3113
|
+
if (pieces.length === 0) return;
|
|
3114
|
+
const joined = pieces.join("");
|
|
3115
|
+
const end = trailingPunctuationStart(joined);
|
|
3116
|
+
const redacted = redact(joined.slice(0, end));
|
|
3117
|
+
out += pieces.length > 1 && redacted === joined.slice(0, end) ? pieces.map((piece) => redactMatch(piece, redact)).join("") : redacted + joined.slice(end);
|
|
3118
|
+
};
|
|
3119
|
+
for (const match of text.matchAll(EMBEDDED_URL_PATTERN)) {
|
|
3120
|
+
if (match.index !== copied || !opensSensitiveValue(scan)) {
|
|
3121
|
+
flush();
|
|
3122
|
+
out += text.slice(copied, match.index);
|
|
3123
|
+
pieces = [];
|
|
3124
|
+
scan = newUrlScan();
|
|
3125
|
+
}
|
|
3126
|
+
pieces.push(match[0]);
|
|
3127
|
+
advanceUrlScan(scan, match[0], sensitiveNames);
|
|
3128
|
+
copied = match.index + match[0].length;
|
|
3129
|
+
}
|
|
3130
|
+
flush();
|
|
3131
|
+
return out + text.slice(copied);
|
|
3132
|
+
}
|
|
3133
|
+
function redactMatch(match, redact) {
|
|
3134
|
+
const end = trailingPunctuationStart(match);
|
|
3135
|
+
return redact(match.slice(0, end)) + match.slice(end);
|
|
3089
3136
|
}
|
|
3090
3137
|
function redactJsonValue(value) {
|
|
3091
3138
|
if (Array.isArray(value)) return value.map(redactJsonValue);
|
|
@@ -3144,14 +3191,15 @@ function isLongLivedStreamResponse(method, contentType) {
|
|
|
3144
3191
|
}
|
|
3145
3192
|
const CHALLENGE_BODY_MAX_BYTES = 65536;
|
|
3146
3193
|
const CHALLENGE_BODY_READ_MS = 2e3;
|
|
3194
|
+
const TRACKED_BODY_MAX_BYTES = 1048576;
|
|
3147
3195
|
const TRUNCATED_BODY_SUFFIX = "\n[truncated]";
|
|
3148
3196
|
const WITHHELD_TRUNCATED_JSON_BODY = "[truncated JSON body withheld: an incomplete body cannot be redacted]";
|
|
3149
|
-
function
|
|
3197
|
+
function recordableBody(read, contentType) {
|
|
3150
3198
|
if (!read.truncated) return redactBody(read.text, contentType);
|
|
3151
3199
|
if ((contentType ?? "").toLowerCase().includes("json") || /^\s*[{[]/.test(read.text)) return WITHHELD_TRUNCATED_JSON_BODY;
|
|
3152
3200
|
return redactBody(read.text, contentType) + TRUNCATED_BODY_SUFFIX;
|
|
3153
3201
|
}
|
|
3154
|
-
async function
|
|
3202
|
+
async function readCappedBody(response, maxBytes, timeoutMs) {
|
|
3155
3203
|
let reader;
|
|
3156
3204
|
try {
|
|
3157
3205
|
const body = response.clone().body;
|
|
@@ -3165,20 +3213,23 @@ async function readChallengeBody(response) {
|
|
|
3165
3213
|
let text = "";
|
|
3166
3214
|
let bytes = 0;
|
|
3167
3215
|
let timer;
|
|
3168
|
-
const deadline = new Promise((resolve) => {
|
|
3169
|
-
timer = setTimeout(() => resolve("timeout"),
|
|
3216
|
+
const deadline = timeoutMs === void 0 ? void 0 : new Promise((resolve) => {
|
|
3217
|
+
timer = setTimeout(() => resolve("timeout"), timeoutMs);
|
|
3170
3218
|
});
|
|
3171
3219
|
try {
|
|
3172
|
-
|
|
3173
|
-
const next = await Promise.race([reader.read(), deadline]);
|
|
3220
|
+
for (;;) {
|
|
3221
|
+
const next = await (deadline ? Promise.race([reader.read(), deadline]) : reader.read());
|
|
3174
3222
|
if (next === "timeout") break;
|
|
3175
3223
|
if (next.done) return {
|
|
3176
3224
|
text: text + decoder.decode(),
|
|
3177
3225
|
truncated: false
|
|
3178
3226
|
};
|
|
3179
|
-
|
|
3227
|
+
if (next.value.byteLength === 0) continue;
|
|
3228
|
+
if (bytes >= maxBytes) break;
|
|
3229
|
+
const chunk = next.value.subarray(0, maxBytes - bytes);
|
|
3180
3230
|
bytes += chunk.byteLength;
|
|
3181
3231
|
text += decoder.decode(chunk, { stream: true });
|
|
3232
|
+
if (chunk.byteLength < next.value.byteLength) break;
|
|
3182
3233
|
}
|
|
3183
3234
|
reader.cancel().catch(() => {});
|
|
3184
3235
|
return {
|
|
@@ -3191,6 +3242,9 @@ async function readChallengeBody(response) {
|
|
|
3191
3242
|
clearTimeout(timer);
|
|
3192
3243
|
}
|
|
3193
3244
|
}
|
|
3245
|
+
function readChallengeBody(response) {
|
|
3246
|
+
return readCappedBody(response, CHALLENGE_BODY_MAX_BYTES, CHALLENGE_BODY_READ_MS);
|
|
3247
|
+
}
|
|
3194
3248
|
function longLivedStreamFraming(contentType) {
|
|
3195
3249
|
return contentType?.toLowerCase().includes("application/x-ndjson") ? "ndjson" : "sse";
|
|
3196
3250
|
}
|
|
@@ -3356,7 +3410,7 @@ function createFetchTracker(baseFetch, callbacks) {
|
|
|
3356
3410
|
};
|
|
3357
3411
|
if ((responseStatus === 401 || responseStatus === 403) && response.body && !response.bodyUsed) {
|
|
3358
3412
|
const read = await readChallengeBody(response);
|
|
3359
|
-
entry.responseBody = read === void 0 ? void 0 :
|
|
3413
|
+
entry.responseBody = read === void 0 ? void 0 : recordableBody(read, response.headers.get("content-type"));
|
|
3360
3414
|
callbacks.trackRequest?.(entry);
|
|
3361
3415
|
return response;
|
|
3362
3416
|
}
|
|
@@ -3364,17 +3418,17 @@ function createFetchTracker(baseFetch, callbacks) {
|
|
|
3364
3418
|
if (isLongLivedStream && response.body && !response.bodyUsed) watchLongLivedStream(response, id, longLivedStreamFraming(response.headers.get("content-type")), callbacks);
|
|
3365
3419
|
if (!isLongLivedStream && response.body && !response.bodyUsed) {
|
|
3366
3420
|
const responseContentType = response.headers.get("content-type");
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3421
|
+
readCappedBody(response, TRACKED_BODY_MAX_BYTES).then((read) => {
|
|
3422
|
+
if (read === void 0) return;
|
|
3423
|
+
try {
|
|
3424
|
+
callbacks.updateResponseBody?.(id, recordableBody(read, responseContentType));
|
|
3425
|
+
} catch {}
|
|
3426
|
+
});
|
|
3372
3427
|
}
|
|
3373
3428
|
return response;
|
|
3374
3429
|
};
|
|
3375
3430
|
}
|
|
3376
|
-
|
|
3377
|
-
//#region ../../core/auth/utils.ts
|
|
3431
|
+
// ../../core/auth/utils.ts
|
|
3378
3432
|
function parseHttpUrl(value, label) {
|
|
3379
3433
|
const trimmed = value.trim();
|
|
3380
3434
|
try {
|
|
@@ -3453,8 +3507,7 @@ function isUnauthorizedErrorDeep(err, seen) {
|
|
|
3453
3507
|
if (data !== null && typeof data === "object" && "cause" in data && isUnauthorizedErrorDeep(data.cause, seen)) return true;
|
|
3454
3508
|
return false;
|
|
3455
3509
|
}
|
|
3456
|
-
|
|
3457
|
-
//#region ../../core/auth/challenge.ts
|
|
3510
|
+
// ../../core/auth/challenge.ts
|
|
3458
3511
|
const EMA_STEP_UP_PENDING_URL = new URL("mcp-inspector:ema-step-up");
|
|
3459
3512
|
var AuthChallengeError = class extends Error {
|
|
3460
3513
|
authChallenge;
|
|
@@ -3600,8 +3653,7 @@ function isAuthChallengeError(err) {
|
|
|
3600
3653
|
const wwwAuthenticate = authChallenge?.raw?.wwwAuthenticate ?? err.wwwAuthenticate ?? err.headers?.get?.("WWW-Authenticate") ?? void 0;
|
|
3601
3654
|
return wwwAuthenticate !== void 0 && wwwAuthenticate.length > 0;
|
|
3602
3655
|
}
|
|
3603
|
-
|
|
3604
|
-
//#region ../../core/mcp/node/authChallengeFetch.ts
|
|
3656
|
+
// ../../core/mcp/node/authChallengeFetch.ts
|
|
3605
3657
|
function createAuthChallengeInterceptFetch(baseFetch) {
|
|
3606
3658
|
return async (input, init) => {
|
|
3607
3659
|
const response = await baseFetch(input, init);
|
|
@@ -3622,8 +3674,7 @@ function createAuthChallengeObserverFetch(baseFetch, onChallenge) {
|
|
|
3622
3674
|
return response;
|
|
3623
3675
|
};
|
|
3624
3676
|
}
|
|
3625
|
-
|
|
3626
|
-
//#region ../../core/mcp/node/proxyFetch.ts
|
|
3677
|
+
// ../../core/mcp/node/proxyFetch.ts
|
|
3627
3678
|
function asUndiciInit(init) {
|
|
3628
3679
|
return init;
|
|
3629
3680
|
}
|
|
@@ -3713,8 +3764,7 @@ function createProxyFetch() {
|
|
|
3713
3764
|
return (await loadedProxiedFetch)(input, init);
|
|
3714
3765
|
};
|
|
3715
3766
|
}
|
|
3716
|
-
|
|
3717
|
-
//#region ../../core/auth/requestTimeout.ts
|
|
3767
|
+
// ../../core/auth/requestTimeout.ts
|
|
3718
3768
|
const DEFAULT_OAUTH_REQUEST_TIMEOUT_MS = 3e4;
|
|
3719
3769
|
var OAuthRequestTimeoutError = class extends Error {
|
|
3720
3770
|
url;
|
|
@@ -3842,11 +3892,39 @@ function withOAuthRequestTimeout(fetchFn, timeoutMs = DEFAULT_OAUTH_REQUEST_TIME
|
|
|
3842
3892
|
}
|
|
3843
3893
|
};
|
|
3844
3894
|
}
|
|
3845
|
-
|
|
3846
|
-
//#region ../../core/mcp/node/fetchGuard.ts
|
|
3895
|
+
// ../../core/auth/fetchRefusal.ts
|
|
3847
3896
|
var FetchTargetError = class extends Error {
|
|
3848
3897
|
name = "FetchTargetError";
|
|
3898
|
+
url;
|
|
3899
|
+
constructor(message, url) {
|
|
3900
|
+
super(message);
|
|
3901
|
+
if (url !== void 0) this.url = url;
|
|
3902
|
+
}
|
|
3849
3903
|
};
|
|
3904
|
+
function findFetchTargetError(err) {
|
|
3905
|
+
let current = err;
|
|
3906
|
+
for (let depth = 0; depth < 8 && current instanceof Error; depth++) {
|
|
3907
|
+
if (current instanceof FetchTargetError) return current;
|
|
3908
|
+
current = current.cause;
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
function formatFetchRefusal(refusal) {
|
|
3912
|
+
return `Refused to fetch ${refusal.url}: ${refusal.reason}`;
|
|
3913
|
+
}
|
|
3914
|
+
function withFetchRefusalReporting(base, onRefusal) {
|
|
3915
|
+
return async (input, init) => {
|
|
3916
|
+
try {
|
|
3917
|
+
return await base(input, init);
|
|
3918
|
+
} catch (err) {
|
|
3919
|
+
const refused = findFetchTargetError(err);
|
|
3920
|
+
if (refused) onRefusal({
|
|
3921
|
+
url: redactUrlQuery(refused.url ?? requestUrlOf$2(input)),
|
|
3922
|
+
reason: refused.message
|
|
3923
|
+
});
|
|
3924
|
+
throw err;
|
|
3925
|
+
}
|
|
3926
|
+
};
|
|
3927
|
+
}
|
|
3850
3928
|
const REDIRECT_STATUSES = /* @__PURE__ */ new Set([
|
|
3851
3929
|
301,
|
|
3852
3930
|
302,
|
|
@@ -3855,11 +3933,12 @@ const REDIRECT_STATUSES = /* @__PURE__ */ new Set([
|
|
|
3855
3933
|
308
|
|
3856
3934
|
]);
|
|
3857
3935
|
const resolveWithSystemDns = async (hostname) => (await lookup(hostname, { all: true })).map((r) => r.address);
|
|
3936
|
+
const METADATA_IPV4_ADDRESSES = /* @__PURE__ */ new Set(["100.100.100.200", "192.0.0.192"]);
|
|
3858
3937
|
function isBlockedAddress(ip) {
|
|
3859
3938
|
const kind = isIP(ip);
|
|
3860
3939
|
if (kind === 4) {
|
|
3861
3940
|
const [a, b] = ip.split(".").map(Number);
|
|
3862
|
-
return a === 169 && b === 254;
|
|
3941
|
+
return a === 169 && b === 254 || METADATA_IPV4_ADDRESSES.has(ip);
|
|
3863
3942
|
}
|
|
3864
3943
|
if (kind !== 6) return false;
|
|
3865
3944
|
const addr = ip.toLowerCase();
|
|
@@ -4016,27 +4095,35 @@ async function guardedFetch(url, init, options = {}) {
|
|
|
4016
4095
|
headers: init.headers
|
|
4017
4096
|
};
|
|
4018
4097
|
for (let hop = 0; hop <= 5; hop++) {
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4098
|
+
let res;
|
|
4099
|
+
try {
|
|
4100
|
+
await assertAllowedTarget(request.url, resolveHost, viaProxy, init.signal);
|
|
4101
|
+
res = await fetchFn(request.url.href, {
|
|
4102
|
+
method: request.method,
|
|
4103
|
+
headers: new Headers(request.headers),
|
|
4104
|
+
body: request.body,
|
|
4105
|
+
signal: init.signal,
|
|
4106
|
+
redirect: "manual"
|
|
4107
|
+
});
|
|
4108
|
+
} catch (err) {
|
|
4109
|
+
stampRefusedUrl(err, request.url);
|
|
4110
|
+
throw err;
|
|
4111
|
+
}
|
|
4027
4112
|
const location = res.headers.get("location");
|
|
4028
4113
|
if (!REDIRECT_STATUSES.has(res.status) || location === null) return res;
|
|
4029
4114
|
res.body?.cancel().catch(() => {});
|
|
4030
|
-
|
|
4115
|
+
try {
|
|
4116
|
+
request = nextRedirectRequest(request, res.status, location);
|
|
4117
|
+
} catch (err) {
|
|
4118
|
+
stampRefusedUrl(err, request.url);
|
|
4119
|
+
throw err;
|
|
4120
|
+
}
|
|
4031
4121
|
}
|
|
4032
|
-
throw new FetchTargetError(`Refusing to follow more than 5 redirects
|
|
4122
|
+
throw new FetchTargetError(`Refusing to follow more than 5 redirects`, request.url.href);
|
|
4033
4123
|
}
|
|
4034
|
-
function
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
if (current instanceof FetchTargetError) return current;
|
|
4038
|
-
current = current.cause;
|
|
4039
|
-
}
|
|
4124
|
+
function stampRefusedUrl(err, url) {
|
|
4125
|
+
const refused = findFetchTargetError(err);
|
|
4126
|
+
if (refused && refused.url === void 0) refused.url = url.href;
|
|
4040
4127
|
}
|
|
4041
4128
|
async function bodyText(input, init) {
|
|
4042
4129
|
const body = init?.body !== void 0 ? init.body : input instanceof Request && input.body !== null ? await input.clone().text() : void 0;
|
|
@@ -4063,8 +4150,7 @@ function createGuardedFetch(options = {}) {
|
|
|
4063
4150
|
}
|
|
4064
4151
|
};
|
|
4065
4152
|
}
|
|
4066
|
-
|
|
4067
|
-
//#region ../../core/auth/routeOAuthRequests.ts
|
|
4153
|
+
// ../../core/auth/routeOAuthRequests.ts
|
|
4068
4154
|
function isJsonRpcMessage(value) {
|
|
4069
4155
|
return typeof value === "object" && value !== null && value.jsonrpc === "2.0";
|
|
4070
4156
|
}
|
|
@@ -4088,8 +4174,7 @@ function isMcpShapedRequest(input, init) {
|
|
|
4088
4174
|
function routeOAuthRequests(mcpFetch, oauthFetch, isMcpEndpoint) {
|
|
4089
4175
|
return (input, init) => isMcpShapedRequest(input, init) && isMcpEndpoint(requestUrlOf$2(input), requestHeadersOf(input, init)) ? mcpFetch(input, init) : oauthFetch(input, init);
|
|
4090
4176
|
}
|
|
4091
|
-
|
|
4092
|
-
//#region ../../core/mcp/node/notificationHeadersFetch.ts
|
|
4177
|
+
// ../../core/mcp/node/notificationHeadersFetch.ts
|
|
4093
4178
|
function createNotificationHeadersFetch(baseFetch) {
|
|
4094
4179
|
return (input, init) => {
|
|
4095
4180
|
const method = modernNotificationMethod(init);
|
|
@@ -4125,8 +4210,7 @@ function modernNotificationMethod(init) {
|
|
|
4125
4210
|
function isRecord$4(value) {
|
|
4126
4211
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4127
4212
|
}
|
|
4128
|
-
|
|
4129
|
-
//#region ../../core/mcp/node/suppressNotificationStreamFetch.ts
|
|
4213
|
+
// ../../core/mcp/node/suppressNotificationStreamFetch.ts
|
|
4130
4214
|
function createSuppressNotificationStreamFetch(baseFetch, endpoint) {
|
|
4131
4215
|
return async (input, init) => {
|
|
4132
4216
|
if (isStandaloneStreamRequest(input, init, endpoint)) return new Response(null, {
|
|
@@ -4152,8 +4236,7 @@ function isStandaloneStreamRequest(input, init, endpoint) {
|
|
|
4152
4236
|
const headers = new Headers(init?.headers ?? request?.headers);
|
|
4153
4237
|
return (headers.get("accept")?.toLowerCase() ?? "").includes("text/event-stream") && !headers.has("last-event-id");
|
|
4154
4238
|
}
|
|
4155
|
-
|
|
4156
|
-
//#region ../../core/mcp/node/transport.ts
|
|
4239
|
+
// ../../core/mcp/node/transport.ts
|
|
4157
4240
|
function headersFromSettings(settings) {
|
|
4158
4241
|
if (!settings || settings.headers.length === 0) return void 0;
|
|
4159
4242
|
const out = {};
|
|
@@ -4235,8 +4318,7 @@ function createTransportNode(config, options = {}) {
|
|
|
4235
4318
|
}) };
|
|
4236
4319
|
}
|
|
4237
4320
|
}
|
|
4238
|
-
|
|
4239
|
-
//#region ../../core/client/config-parse.ts
|
|
4321
|
+
// ../../core/client/config-parse.ts
|
|
4240
4322
|
function isAbsoluteHttpUrl(value) {
|
|
4241
4323
|
let url;
|
|
4242
4324
|
try {
|
|
@@ -4319,8 +4401,7 @@ const ClientConfigSchema = z$1.object({
|
|
|
4319
4401
|
function parseClientConfig(raw) {
|
|
4320
4402
|
return ClientConfigSchema.parse(raw);
|
|
4321
4403
|
}
|
|
4322
|
-
|
|
4323
|
-
//#region ../../core/client/secrets.ts
|
|
4404
|
+
// ../../core/client/secrets.ts
|
|
4324
4405
|
const CLIENT_KEYCHAIN_ID = "client";
|
|
4325
4406
|
function hasClientPlaintextSecret(config) {
|
|
4326
4407
|
const secret = config.enterpriseManagedAuth?.idp?.clientSecret;
|
|
@@ -4361,8 +4442,7 @@ function mergeSecretsIntoClientConfig(config, secrets) {
|
|
|
4361
4442
|
}
|
|
4362
4443
|
};
|
|
4363
4444
|
}
|
|
4364
|
-
|
|
4365
|
-
//#region ../../core/client/node-persistence.ts
|
|
4445
|
+
// ../../core/client/node-persistence.ts
|
|
4366
4446
|
async function withClientConfigLock(filePath, action, body) {
|
|
4367
4447
|
let entered = false;
|
|
4368
4448
|
try {
|
|
@@ -4412,8 +4492,7 @@ async function readClientConfigStore(filePath, secretStore) {
|
|
|
4412
4492
|
const secrets = await readIdpSecretFromKeychain(secretStore);
|
|
4413
4493
|
return mergeSecretsIntoClientConfig(config, secrets);
|
|
4414
4494
|
}
|
|
4415
|
-
|
|
4416
|
-
//#region ../../core/client/config.ts
|
|
4495
|
+
// ../../core/client/config.ts
|
|
4417
4496
|
function getClientConfigFilePath(customPath) {
|
|
4418
4497
|
return customPath ?? getStoreFilePath(getDefaultStorageDir(), "client");
|
|
4419
4498
|
}
|
|
@@ -4424,8 +4503,7 @@ async function loadClientConfig(options) {
|
|
|
4424
4503
|
if (raw === null) return {};
|
|
4425
4504
|
return parseClientConfig(parseStore(raw));
|
|
4426
4505
|
}
|
|
4427
|
-
|
|
4428
|
-
//#region ../../core/client/types.ts
|
|
4506
|
+
// ../../core/client/types.ts
|
|
4429
4507
|
function isEnterpriseManagedAuthEnabled(config) {
|
|
4430
4508
|
const ema = config.enterpriseManagedAuth;
|
|
4431
4509
|
if (!ema?.idp) return false;
|
|
@@ -4442,8 +4520,7 @@ function getActiveCimdClientMetadataUrl(config) {
|
|
|
4442
4520
|
if (!isCimdEnabled(config)) return void 0;
|
|
4443
4521
|
return config.cimd?.clientMetadataUrl?.trim() || void 0;
|
|
4444
4522
|
}
|
|
4445
|
-
|
|
4446
|
-
//#region ../../core/client/runner.ts
|
|
4523
|
+
// ../../core/client/runner.ts
|
|
4447
4524
|
async function loadRunnerClientConfig(options) {
|
|
4448
4525
|
return loadClientConfig({
|
|
4449
4526
|
filePath: options?.clientConfigPath?.trim() || process.env.MCP_CLIENT_CONFIG_PATH?.trim() || void 0,
|
|
@@ -4486,8 +4563,7 @@ function buildRunnerClientAuthOptions(clientConfig, savedSettings, cliOverrides)
|
|
|
4486
4563
|
...oauth && { directAuthRecovery: true }
|
|
4487
4564
|
};
|
|
4488
4565
|
}
|
|
4489
|
-
|
|
4490
|
-
//#region ../../core/node/version.ts
|
|
4566
|
+
// ../../core/node/version.ts
|
|
4491
4567
|
const ROOT_PACKAGE_NAME = "@modelcontextprotocol/inspector";
|
|
4492
4568
|
function readInspectorVersion(callerUrl) {
|
|
4493
4569
|
const startDir = dirname$1(fileURLToPath$1(callerUrl));
|
|
@@ -4504,8 +4580,7 @@ function readInspectorVersion(callerUrl) {
|
|
|
4504
4580
|
}
|
|
4505
4581
|
throw new Error(`Could not locate the ${ROOT_PACKAGE_NAME} root package.json above ${startDir}`);
|
|
4506
4582
|
}
|
|
4507
|
-
|
|
4508
|
-
//#region ../../core/node/hostUrl.ts
|
|
4583
|
+
// ../../core/node/hostUrl.ts
|
|
4509
4584
|
function stripBrackets(host) {
|
|
4510
4585
|
return host.replace(/^\[(.*)\]$/, "$1");
|
|
4511
4586
|
}
|
|
@@ -4533,8 +4608,7 @@ function isLoopbackHost(host) {
|
|
|
4533
4608
|
const h = canonicalUrlHost(host).replace(/\.$/, "");
|
|
4534
4609
|
return h === "localhost" || h === "[::1]" || /^127(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/.test(h);
|
|
4535
4610
|
}
|
|
4536
|
-
|
|
4537
|
-
//#region ../../core/auth/node/runner-oauth-callback.ts
|
|
4611
|
+
// ../../core/auth/node/runner-oauth-callback.ts
|
|
4538
4612
|
const RUNNER_OAUTH_CALLBACK_DEFAULT_HOSTNAME = "127.0.0.1";
|
|
4539
4613
|
const RUNNER_OAUTH_CALLBACK_DEFAULT_PORT = 6276;
|
|
4540
4614
|
const RUNNER_OAUTH_CALLBACK_PATH = "/oauth/callback";
|
|
@@ -4578,8 +4652,7 @@ function parseRunnerOAuthCallbackUrl(cliCallbackUrl) {
|
|
|
4578
4652
|
function formatRunnerOAuthRedirectUrl(config) {
|
|
4579
4653
|
return `http://${formatHostForUrl(config.hostname)}:${config.port}${config.pathname}`;
|
|
4580
4654
|
}
|
|
4581
|
-
|
|
4582
|
-
//#region ../../core/json/xMcpHeader.ts
|
|
4655
|
+
// ../../core/json/xMcpHeader.ts
|
|
4583
4656
|
const X_MCP_HEADER_KEY = "x-mcp-header";
|
|
4584
4657
|
const MCP_PARAM_HEADER_PREFIX = "Mcp-Param-";
|
|
4585
4658
|
const RFC9110_TOKEN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
@@ -4727,8 +4800,7 @@ function mcpParamHeadersForTool(tool, args) {
|
|
|
4727
4800
|
if (!scan.valid || scan.declarations.length === 0) return {};
|
|
4728
4801
|
return buildMcpParamHeaders(scan.declarations, args);
|
|
4729
4802
|
}
|
|
4730
|
-
|
|
4731
|
-
//#region ../../core/mcp/subscriptionAck.ts
|
|
4803
|
+
// ../../core/mcp/subscriptionAck.ts
|
|
4732
4804
|
const NEVER_ACKNOWLEDGED_SDK_MESSAGE = "closed the subscription gracefully before acknowledging";
|
|
4733
4805
|
const NEVER_ACKNOWLEDGED_SUBSCRIPTION_MESSAGE = "The server closed the subscription without acknowledging it. A subscriptions/listen request must first be answered with a notifications/subscriptions/acknowledged notification; a JSON-RPC result for the listen id means graceful closure. Not retrying — the server would answer the same way again.";
|
|
4734
4806
|
function isNeverAcknowledgedSubscriptionClose(error) {
|
|
@@ -4738,8 +4810,7 @@ function subscriptionFailureMessage(error) {
|
|
|
4738
4810
|
if (isNeverAcknowledgedSubscriptionClose(error)) return NEVER_ACKNOWLEDGED_SUBSCRIPTION_MESSAGE;
|
|
4739
4811
|
return error instanceof Error ? error.message : String(error);
|
|
4740
4812
|
}
|
|
4741
|
-
|
|
4742
|
-
//#region ../../core/mcp/subscriptionRefusal.ts
|
|
4813
|
+
// ../../core/mcp/subscriptionRefusal.ts
|
|
4743
4814
|
const REFUSAL_STATUSES = /* @__PURE__ */ new Set([
|
|
4744
4815
|
400,
|
|
4745
4816
|
403,
|
|
@@ -4756,8 +4827,7 @@ function subscriptionListenRefusal(error) {
|
|
|
4756
4827
|
function subscriptionListenRefusalMessage(refusal) {
|
|
4757
4828
|
return `The server refused subscriptions/listen (HTTP ${refusal.statusText ? `${refusal.status} ${refusal.statusText}` : String(refusal.status)}). Not retrying — the server would answer the same way again.`;
|
|
4758
4829
|
}
|
|
4759
|
-
|
|
4760
|
-
//#region ../../core/mcp/messageTrackingTransport.ts
|
|
4830
|
+
// ../../core/mcp/messageTrackingTransport.ts
|
|
4761
4831
|
var MessageTrackingTransport = class {
|
|
4762
4832
|
baseTransport;
|
|
4763
4833
|
callbacks;
|
|
@@ -4830,8 +4900,7 @@ var MessageTrackingTransport = class {
|
|
|
4830
4900
|
return this.negotiatedProtocolVersion;
|
|
4831
4901
|
}
|
|
4832
4902
|
};
|
|
4833
|
-
|
|
4834
|
-
//#region ../../core/extension/tasks/errors.ts
|
|
4903
|
+
// ../../core/extension/tasks/errors.ts
|
|
4835
4904
|
function abortError(signal) {
|
|
4836
4905
|
return signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted", "AbortError");
|
|
4837
4906
|
}
|
|
@@ -4845,14 +4914,12 @@ function toProtocolError(reason) {
|
|
|
4845
4914
|
const normalized = unwrapTaskDispatchError(reason);
|
|
4846
4915
|
return normalized instanceof ProtocolError ? normalized : new ProtocolError(ProtocolErrorCode.InternalError, normalized instanceof Error ? normalized.message : String(normalized));
|
|
4847
4916
|
}
|
|
4848
|
-
|
|
4849
|
-
//#region ../../core/extension/tasks/notificationSchemas.ts
|
|
4917
|
+
// ../../core/extension/tasks/notificationSchemas.ts
|
|
4850
4918
|
const TasksListChangedNotificationSchema = NotificationSchema.extend({
|
|
4851
4919
|
method: z.literal("notifications/tasks/list_changed"),
|
|
4852
4920
|
params: z.record(z.string(), z.unknown()).optional()
|
|
4853
4921
|
});
|
|
4854
|
-
|
|
4855
|
-
//#region ../../core/extension/tasks/progress.ts
|
|
4922
|
+
// ../../core/extension/tasks/progress.ts
|
|
4856
4923
|
var TaskProgressRouter = class {
|
|
4857
4924
|
taskIds = /* @__PURE__ */ new Map();
|
|
4858
4925
|
owners = /* @__PURE__ */ new Map();
|
|
@@ -4883,8 +4950,7 @@ var TaskProgressRouter = class {
|
|
|
4883
4950
|
this.owners.clear();
|
|
4884
4951
|
}
|
|
4885
4952
|
};
|
|
4886
|
-
|
|
4887
|
-
//#region ../../core/extension/tasks/rawWireChannel.ts
|
|
4953
|
+
// ../../core/extension/tasks/rawWireChannel.ts
|
|
4888
4954
|
const RAW_WIRE_ID_PREFIX = "inspector-ext-";
|
|
4889
4955
|
var RawWireChannel = class {
|
|
4890
4956
|
pending = /* @__PURE__ */ new Map();
|
|
@@ -5013,8 +5079,7 @@ var RawWireChannel = class {
|
|
|
5013
5079
|
}
|
|
5014
5080
|
}
|
|
5015
5081
|
};
|
|
5016
|
-
|
|
5017
|
-
//#region ../../core/extension/tasks/session.ts
|
|
5082
|
+
// ../../core/extension/tasks/session.ts
|
|
5018
5083
|
function taskSessionEndpointId(config, clientInfo) {
|
|
5019
5084
|
return createTaskSessionEndpointId("inspector", config.type === "sse" || config.type === "streamable-http" ? {
|
|
5020
5085
|
host: clientInfo,
|
|
@@ -5037,8 +5102,7 @@ function isTasksExtensionNegotiated(era, capabilities) {
|
|
|
5037
5102
|
const extension = capabilities?.extensions?.[TASKS_EXTENSION_KEY];
|
|
5038
5103
|
return extension !== null && typeof extension === "object" && !Array.isArray(extension) && Object.keys(extension).length === 0;
|
|
5039
5104
|
}
|
|
5040
|
-
|
|
5041
|
-
//#region ../../core/extension/tasks/wire.ts
|
|
5105
|
+
// ../../core/extension/tasks/wire.ts
|
|
5042
5106
|
const taskToolResultCodec = runtimeCodecFromStandardSchema({ "~standard": {
|
|
5043
5107
|
version: 1,
|
|
5044
5108
|
vendor: "mcp-inspector",
|
|
@@ -5075,8 +5139,7 @@ function taskInputOrigin(delivery) {
|
|
|
5075
5139
|
if (delivery === "request-retry") return "input-required";
|
|
5076
5140
|
return "server-request";
|
|
5077
5141
|
}
|
|
5078
|
-
|
|
5079
|
-
//#region ../../core/mcp/extensions.ts
|
|
5142
|
+
// ../../core/mcp/extensions.ts
|
|
5080
5143
|
const EMA_EXTENSION_KEY = "io.modelcontextprotocol/enterprise-managed-authorization";
|
|
5081
5144
|
const UI_EXTENSION_KEY = "io.modelcontextprotocol/ui";
|
|
5082
5145
|
const MCP_APP_MIME_TYPE = RESOURCE_MIME_TYPE;
|
|
@@ -5113,8 +5176,7 @@ function buildClientExtensions(input) {
|
|
|
5113
5176
|
if (input.enterpriseManaged) map[EMA_EXTENSION_KEY] = {};
|
|
5114
5177
|
return map;
|
|
5115
5178
|
}
|
|
5116
|
-
|
|
5117
|
-
//#region ../../core/mcp/appElicitation.ts
|
|
5179
|
+
// ../../core/mcp/appElicitation.ts
|
|
5118
5180
|
function uiExtension(capabilities) {
|
|
5119
5181
|
const ext = capabilities?.extensions?.[UI_EXTENSION_KEY];
|
|
5120
5182
|
return typeof ext === "object" && ext !== null ? ext : void 0;
|
|
@@ -5169,8 +5231,7 @@ function validateAppElicitResult(provider, params, result) {
|
|
|
5169
5231
|
return;
|
|
5170
5232
|
}
|
|
5171
5233
|
}
|
|
5172
|
-
|
|
5173
|
-
//#region ../../core/mcp/toolOutputValidation.ts
|
|
5234
|
+
// ../../core/mcp/toolOutputValidation.ts
|
|
5174
5235
|
function validateToolOutput(provider, tool, result) {
|
|
5175
5236
|
if (!tool.outputSchema) return void 0;
|
|
5176
5237
|
const structured = result.structuredContent;
|
|
@@ -5182,6 +5243,625 @@ function validateToolOutput(provider, tool, result) {
|
|
|
5182
5243
|
return;
|
|
5183
5244
|
}
|
|
5184
5245
|
}
|
|
5246
|
+
// ../../core/json/linearRegExp.ts
|
|
5247
|
+
var CharMatcher = class {
|
|
5248
|
+
re;
|
|
5249
|
+
ascii = /* @__PURE__ */ new Uint8Array(128);
|
|
5250
|
+
constructor(source, unicode) {
|
|
5251
|
+
this.re = new RegExp(`^(?:${source})$`, unicode ? "u" : "");
|
|
5252
|
+
}
|
|
5253
|
+
matches(cp, unicode) {
|
|
5254
|
+
if (cp < 128) {
|
|
5255
|
+
const memo = this.ascii[cp];
|
|
5256
|
+
if (memo !== 0) return memo === 1;
|
|
5257
|
+
const result = this.re.test(String.fromCharCode(cp));
|
|
5258
|
+
this.ascii[cp] = result ? 1 : 2;
|
|
5259
|
+
return result;
|
|
5260
|
+
}
|
|
5261
|
+
return this.re.test(unicode ? String.fromCodePoint(cp) : String.fromCharCode(cp));
|
|
5262
|
+
}
|
|
5263
|
+
};
|
|
5264
|
+
var Unsupported = class extends Error {};
|
|
5265
|
+
const MAX_GROUP_DEPTH = 64;
|
|
5266
|
+
const MAX_PROGRAM_SIZE = 1e4;
|
|
5267
|
+
const MAX_COMPILE_STEPS = 10 * MAX_PROGRAM_SIZE;
|
|
5268
|
+
const MAX_PATTERN_LENGTH = 8192;
|
|
5269
|
+
const COMPILE_BUDGET_EXHAUSTED = "the patterns together exceed the compilation budget";
|
|
5270
|
+
function isCompileBudgetExhausted(budget) {
|
|
5271
|
+
return budget.steps < 0 || budget.size < 0;
|
|
5272
|
+
}
|
|
5273
|
+
const QUANTIFIER_BRACES = /\{(\d+)(?:(,)(\d*))?\}/y;
|
|
5274
|
+
const HEX4 = /^[0-9a-fA-F]{4}$/;
|
|
5275
|
+
const HEX2 = /^[0-9a-fA-F]{2}$/;
|
|
5276
|
+
var Parser = class {
|
|
5277
|
+
pos = 0;
|
|
5278
|
+
src;
|
|
5279
|
+
unicode;
|
|
5280
|
+
constructor(src, unicode) {
|
|
5281
|
+
this.src = src;
|
|
5282
|
+
this.unicode = unicode;
|
|
5283
|
+
}
|
|
5284
|
+
parse() {
|
|
5285
|
+
const node = this.parseAlternation(0);
|
|
5286
|
+
/* v8 ignore next -- the native RegExp constructor rejects an unbalanced `)` first */
|
|
5287
|
+
if (this.pos !== this.src.length) throw new Unsupported("unbalanced group");
|
|
5288
|
+
return node;
|
|
5289
|
+
}
|
|
5290
|
+
parseAlternation(depth) {
|
|
5291
|
+
const options = [this.parseSequence(depth)];
|
|
5292
|
+
while (this.src[this.pos] === "|") {
|
|
5293
|
+
this.pos++;
|
|
5294
|
+
options.push(this.parseSequence(depth));
|
|
5295
|
+
}
|
|
5296
|
+
return options.length === 1 ? options[0] : {
|
|
5297
|
+
kind: "alt",
|
|
5298
|
+
options
|
|
5299
|
+
};
|
|
5300
|
+
}
|
|
5301
|
+
parseSequence(depth) {
|
|
5302
|
+
const items = [];
|
|
5303
|
+
while (this.pos < this.src.length && this.src[this.pos] !== "|" && this.src[this.pos] !== ")") items.push(this.parseTerm(depth));
|
|
5304
|
+
return items.length === 1 ? items[0] : {
|
|
5305
|
+
kind: "seq",
|
|
5306
|
+
items
|
|
5307
|
+
};
|
|
5308
|
+
}
|
|
5309
|
+
parseTerm(depth) {
|
|
5310
|
+
const atom = this.parseAtom(depth);
|
|
5311
|
+
const quantifier = this.readQuantifier();
|
|
5312
|
+
if (!quantifier) return atom;
|
|
5313
|
+
if (this.src[this.pos] === "?") this.pos++;
|
|
5314
|
+
return {
|
|
5315
|
+
kind: "repeat",
|
|
5316
|
+
body: atom,
|
|
5317
|
+
...quantifier
|
|
5318
|
+
};
|
|
5319
|
+
}
|
|
5320
|
+
readQuantifier() {
|
|
5321
|
+
const c = this.src[this.pos];
|
|
5322
|
+
if (c === "*") {
|
|
5323
|
+
this.pos++;
|
|
5324
|
+
return {
|
|
5325
|
+
min: 0,
|
|
5326
|
+
max: Infinity
|
|
5327
|
+
};
|
|
5328
|
+
}
|
|
5329
|
+
if (c === "+") {
|
|
5330
|
+
this.pos++;
|
|
5331
|
+
return {
|
|
5332
|
+
min: 1,
|
|
5333
|
+
max: Infinity
|
|
5334
|
+
};
|
|
5335
|
+
}
|
|
5336
|
+
if (c === "?") {
|
|
5337
|
+
this.pos++;
|
|
5338
|
+
return {
|
|
5339
|
+
min: 0,
|
|
5340
|
+
max: 1
|
|
5341
|
+
};
|
|
5342
|
+
}
|
|
5343
|
+
if (c === "{") {
|
|
5344
|
+
QUANTIFIER_BRACES.lastIndex = this.pos;
|
|
5345
|
+
const m = QUANTIFIER_BRACES.exec(this.src);
|
|
5346
|
+
if (!m) return void 0;
|
|
5347
|
+
this.pos += m[0].length;
|
|
5348
|
+
const min = Number(m[1]);
|
|
5349
|
+
return {
|
|
5350
|
+
min,
|
|
5351
|
+
max: m[2] === void 0 ? min : m[3] ? Number(m[3]) : Infinity
|
|
5352
|
+
};
|
|
5353
|
+
}
|
|
5354
|
+
}
|
|
5355
|
+
parseAtom(depth) {
|
|
5356
|
+
switch (this.src[this.pos]) {
|
|
5357
|
+
case "(": return this.parseGroup(depth);
|
|
5358
|
+
case "[": return this.parseClass();
|
|
5359
|
+
case "\\": return this.parseEscape();
|
|
5360
|
+
case ".":
|
|
5361
|
+
this.pos++;
|
|
5362
|
+
return {
|
|
5363
|
+
kind: "char",
|
|
5364
|
+
source: "."
|
|
5365
|
+
};
|
|
5366
|
+
case "^":
|
|
5367
|
+
this.pos++;
|
|
5368
|
+
return {
|
|
5369
|
+
kind: "assert",
|
|
5370
|
+
assertion: "start"
|
|
5371
|
+
};
|
|
5372
|
+
case "$":
|
|
5373
|
+
this.pos++;
|
|
5374
|
+
return {
|
|
5375
|
+
kind: "assert",
|
|
5376
|
+
assertion: "end"
|
|
5377
|
+
};
|
|
5378
|
+
case "*":
|
|
5379
|
+
case "+":
|
|
5380
|
+
case "?":
|
|
5381
|
+
/* v8 ignore next -- "nothing to repeat" is a native syntax error */
|
|
5382
|
+
throw new Unsupported("nothing to repeat");
|
|
5383
|
+
case "{":
|
|
5384
|
+
QUANTIFIER_BRACES.lastIndex = this.pos;
|
|
5385
|
+
if (QUANTIFIER_BRACES.test(this.src))
|
|
5386
|
+
/* v8 ignore next -- rejected by the native RegExp constructor first */
|
|
5387
|
+
throw new Unsupported("nothing to repeat");
|
|
5388
|
+
this.pos++;
|
|
5389
|
+
return {
|
|
5390
|
+
kind: "char",
|
|
5391
|
+
source: "\\{"
|
|
5392
|
+
};
|
|
5393
|
+
default: {
|
|
5394
|
+
const width = this.codePointWidth(this.pos);
|
|
5395
|
+
const source = this.src.slice(this.pos, this.pos + width);
|
|
5396
|
+
this.pos += width;
|
|
5397
|
+
return {
|
|
5398
|
+
kind: "char",
|
|
5399
|
+
source
|
|
5400
|
+
};
|
|
5401
|
+
}
|
|
5402
|
+
}
|
|
5403
|
+
}
|
|
5404
|
+
codePointWidth(at) {
|
|
5405
|
+
if (!this.unicode) return 1;
|
|
5406
|
+
return this.src.codePointAt(at) > 65535 ? 2 : 1;
|
|
5407
|
+
}
|
|
5408
|
+
parseGroup(depth) {
|
|
5409
|
+
if (depth >= MAX_GROUP_DEPTH) throw new Unsupported("groups nested too deeply");
|
|
5410
|
+
this.pos++;
|
|
5411
|
+
if (this.src.startsWith("?:", this.pos)) this.pos += 2;
|
|
5412
|
+
else if (this.src.startsWith("?<", this.pos) && this.src[this.pos + 2] !== "=" && this.src[this.pos + 2] !== "!") {
|
|
5413
|
+
const close = this.src.indexOf(">", this.pos);
|
|
5414
|
+
/* v8 ignore next -- an unterminated group name is a native syntax error */
|
|
5415
|
+
if (close < 0) throw new Unsupported("unterminated group name");
|
|
5416
|
+
this.pos = close + 1;
|
|
5417
|
+
} else if (this.src[this.pos] === "?") throw new Unsupported("lookaround or group modifier");
|
|
5418
|
+
const body = this.parseAlternation(depth + 1);
|
|
5419
|
+
/* v8 ignore next -- an unterminated group is a native syntax error */
|
|
5420
|
+
if (this.src[this.pos] !== ")") throw new Unsupported("unterminated group");
|
|
5421
|
+
this.pos++;
|
|
5422
|
+
return body;
|
|
5423
|
+
}
|
|
5424
|
+
parseClass() {
|
|
5425
|
+
const start = this.pos;
|
|
5426
|
+
this.pos++;
|
|
5427
|
+
while (this.pos < this.src.length && this.src[this.pos] !== "]") this.pos += this.src[this.pos] === "\\" ? 2 : 1;
|
|
5428
|
+
/* v8 ignore next -- an unterminated class is a native syntax error */
|
|
5429
|
+
if (this.pos >= this.src.length) throw new Unsupported("unterminated class");
|
|
5430
|
+
this.pos++;
|
|
5431
|
+
return {
|
|
5432
|
+
kind: "char",
|
|
5433
|
+
source: this.src.slice(start, this.pos)
|
|
5434
|
+
};
|
|
5435
|
+
}
|
|
5436
|
+
parseEscape() {
|
|
5437
|
+
const next = this.src[this.pos + 1];
|
|
5438
|
+
/* v8 ignore next -- a trailing backslash is a native syntax error */
|
|
5439
|
+
if (next === void 0) throw new Unsupported("trailing backslash");
|
|
5440
|
+
switch (next) {
|
|
5441
|
+
case "b":
|
|
5442
|
+
this.pos += 2;
|
|
5443
|
+
return {
|
|
5444
|
+
kind: "assert",
|
|
5445
|
+
assertion: "wordBoundary"
|
|
5446
|
+
};
|
|
5447
|
+
case "B":
|
|
5448
|
+
this.pos += 2;
|
|
5449
|
+
return {
|
|
5450
|
+
kind: "assert",
|
|
5451
|
+
assertion: "notWordBoundary"
|
|
5452
|
+
};
|
|
5453
|
+
case "1":
|
|
5454
|
+
case "2":
|
|
5455
|
+
case "3":
|
|
5456
|
+
case "4":
|
|
5457
|
+
case "5":
|
|
5458
|
+
case "6":
|
|
5459
|
+
case "7":
|
|
5460
|
+
case "8":
|
|
5461
|
+
case "9":
|
|
5462
|
+
case "k": throw new Unsupported("backreference");
|
|
5463
|
+
case "0":
|
|
5464
|
+
if (/[0-9]/.test(this.src[this.pos + 2] ?? "")) throw new Unsupported("octal escape");
|
|
5465
|
+
return this.takeChar(2);
|
|
5466
|
+
case "c":
|
|
5467
|
+
if (!/[a-zA-Z]/.test(this.src[this.pos + 2] ?? "")) throw new Unsupported("incomplete control escape");
|
|
5468
|
+
return this.takeChar(3);
|
|
5469
|
+
case "p":
|
|
5470
|
+
case "P":
|
|
5471
|
+
if (this.unicode && this.src[this.pos + 2] === "{") return this.takeThrough("}");
|
|
5472
|
+
return this.takeChar(2);
|
|
5473
|
+
case "x": return this.takeChar(HEX2.test(this.src.slice(this.pos + 2, this.pos + 4)) ? 4 : 2);
|
|
5474
|
+
case "u": return this.parseUnicodeEscape();
|
|
5475
|
+
default: return this.takeChar(1 + this.codePointWidth(this.pos + 1));
|
|
5476
|
+
}
|
|
5477
|
+
}
|
|
5478
|
+
parseUnicodeEscape() {
|
|
5479
|
+
if (this.unicode && this.src[this.pos + 2] === "{") return this.takeThrough("}");
|
|
5480
|
+
const hex = this.src.slice(this.pos + 2, this.pos + 6);
|
|
5481
|
+
if (!HEX4.test(hex)) return this.takeChar(2);
|
|
5482
|
+
const unit = parseInt(hex, 16);
|
|
5483
|
+
if (this.unicode && unit >= 55296 && unit <= 56319 && this.src.startsWith("\\u", this.pos + 6)) {
|
|
5484
|
+
const low = this.src.slice(this.pos + 8, this.pos + 12);
|
|
5485
|
+
if (HEX4.test(low)) {
|
|
5486
|
+
const lowUnit = parseInt(low, 16);
|
|
5487
|
+
if (lowUnit >= 56320 && lowUnit <= 57343) return this.takeChar(12);
|
|
5488
|
+
}
|
|
5489
|
+
}
|
|
5490
|
+
return this.takeChar(6);
|
|
5491
|
+
}
|
|
5492
|
+
takeChar(length) {
|
|
5493
|
+
const source = this.src.slice(this.pos, this.pos + length);
|
|
5494
|
+
this.pos += length;
|
|
5495
|
+
return {
|
|
5496
|
+
kind: "char",
|
|
5497
|
+
source
|
|
5498
|
+
};
|
|
5499
|
+
}
|
|
5500
|
+
takeThrough(terminator) {
|
|
5501
|
+
const end = this.src.indexOf(terminator, this.pos);
|
|
5502
|
+
/* v8 ignore next -- an unterminated `\p{` / `\u{` is a native syntax error */
|
|
5503
|
+
if (end < 0) throw new Unsupported("unterminated escape");
|
|
5504
|
+
return this.takeChar(end + 1 - this.pos);
|
|
5505
|
+
}
|
|
5506
|
+
};
|
|
5507
|
+
var Compiler = class {
|
|
5508
|
+
prog = [];
|
|
5509
|
+
matchers = /* @__PURE__ */ new Map();
|
|
5510
|
+
unicode;
|
|
5511
|
+
budget;
|
|
5512
|
+
steps = 0;
|
|
5513
|
+
constructor(unicode, budget) {
|
|
5514
|
+
this.unicode = unicode;
|
|
5515
|
+
this.budget = budget;
|
|
5516
|
+
}
|
|
5517
|
+
emit(inst) {
|
|
5518
|
+
if (this.prog.length >= 1e4) throw new Unsupported("pattern too complex");
|
|
5519
|
+
if (this.budget && --this.budget.size < 0) throw new Unsupported(COMPILE_BUDGET_EXHAUSTED);
|
|
5520
|
+
this.prog.push(inst);
|
|
5521
|
+
return this.prog.length - 1;
|
|
5522
|
+
}
|
|
5523
|
+
matcher(source) {
|
|
5524
|
+
let matcher = this.matchers.get(source);
|
|
5525
|
+
if (!matcher) {
|
|
5526
|
+
try {
|
|
5527
|
+
matcher = new CharMatcher(source, this.unicode);
|
|
5528
|
+
} catch {
|
|
5529
|
+
/* v8 ignore start -- defensive: each atom is a slice the native constructor already accepted in context */
|
|
5530
|
+
throw new Unsupported("unrecognized character syntax");
|
|
5531
|
+
}
|
|
5532
|
+
this.matchers.set(source, matcher);
|
|
5533
|
+
}
|
|
5534
|
+
return matcher;
|
|
5535
|
+
}
|
|
5536
|
+
compile(node) {
|
|
5537
|
+
if (++this.steps > 1e5) throw new Unsupported("pattern too complex");
|
|
5538
|
+
if (this.budget && --this.budget.steps < 0) throw new Unsupported(COMPILE_BUDGET_EXHAUSTED);
|
|
5539
|
+
switch (node.kind) {
|
|
5540
|
+
case "char":
|
|
5541
|
+
this.emit({
|
|
5542
|
+
op: "char",
|
|
5543
|
+
matcher: this.matcher(node.source)
|
|
5544
|
+
});
|
|
5545
|
+
return;
|
|
5546
|
+
case "assert":
|
|
5547
|
+
this.emit({
|
|
5548
|
+
op: "assert",
|
|
5549
|
+
assertion: node.assertion
|
|
5550
|
+
});
|
|
5551
|
+
return;
|
|
5552
|
+
case "seq":
|
|
5553
|
+
for (const item of node.items) this.compile(item);
|
|
5554
|
+
return;
|
|
5555
|
+
case "alt":
|
|
5556
|
+
this.compileAlternation(node.options);
|
|
5557
|
+
return;
|
|
5558
|
+
case "repeat":
|
|
5559
|
+
this.compileRepeat(node.body, node.min, node.max);
|
|
5560
|
+
return;
|
|
5561
|
+
}
|
|
5562
|
+
}
|
|
5563
|
+
compileAlternation(options) {
|
|
5564
|
+
const jumps = [];
|
|
5565
|
+
for (let i = 0; i < options.length - 1; i++) {
|
|
5566
|
+
const split = this.emit({
|
|
5567
|
+
op: "split",
|
|
5568
|
+
a: 0,
|
|
5569
|
+
b: 0
|
|
5570
|
+
});
|
|
5571
|
+
this.patchSplit(split, split + 1, -1);
|
|
5572
|
+
this.compile(options[i]);
|
|
5573
|
+
jumps.push(this.emit({
|
|
5574
|
+
op: "jmp",
|
|
5575
|
+
to: 0
|
|
5576
|
+
}));
|
|
5577
|
+
this.patchSplit(split, -1, this.prog.length);
|
|
5578
|
+
}
|
|
5579
|
+
this.compile(options[options.length - 1]);
|
|
5580
|
+
for (const jump of jumps) this.patchJump(jump, this.prog.length);
|
|
5581
|
+
}
|
|
5582
|
+
compileRepeat(body, min, max) {
|
|
5583
|
+
for (let i = 0; i < min; i++) {
|
|
5584
|
+
const before = this.prog.length;
|
|
5585
|
+
this.compile(body);
|
|
5586
|
+
if (this.prog.length === before) return;
|
|
5587
|
+
}
|
|
5588
|
+
if (max === Infinity) {
|
|
5589
|
+
const split = this.emit({
|
|
5590
|
+
op: "split",
|
|
5591
|
+
a: 0,
|
|
5592
|
+
b: 0
|
|
5593
|
+
});
|
|
5594
|
+
this.compile(body);
|
|
5595
|
+
this.emit({
|
|
5596
|
+
op: "jmp",
|
|
5597
|
+
to: split
|
|
5598
|
+
});
|
|
5599
|
+
this.patchSplit(split, split + 1, this.prog.length);
|
|
5600
|
+
return;
|
|
5601
|
+
}
|
|
5602
|
+
const splits = [];
|
|
5603
|
+
for (let i = min; i < max; i++) {
|
|
5604
|
+
const split = this.emit({
|
|
5605
|
+
op: "split",
|
|
5606
|
+
a: 0,
|
|
5607
|
+
b: 0
|
|
5608
|
+
});
|
|
5609
|
+
this.patchSplit(split, split + 1, -1);
|
|
5610
|
+
splits.push(split);
|
|
5611
|
+
this.compile(body);
|
|
5612
|
+
}
|
|
5613
|
+
for (const split of splits) this.patchSplit(split, -1, this.prog.length);
|
|
5614
|
+
}
|
|
5615
|
+
patchSplit(at, a, b) {
|
|
5616
|
+
const inst = this.prog[at];
|
|
5617
|
+
if (a >= 0) inst.a = a;
|
|
5618
|
+
if (b >= 0) inst.b = b;
|
|
5619
|
+
}
|
|
5620
|
+
patchJump(at, to) {
|
|
5621
|
+
this.prog[at].to = to;
|
|
5622
|
+
}
|
|
5623
|
+
};
|
|
5624
|
+
function isWordUnit(unit) {
|
|
5625
|
+
return unit >= 48 && unit <= 57 || unit >= 65 && unit <= 90 || unit >= 97 && unit <= 122 || unit === 95;
|
|
5626
|
+
}
|
|
5627
|
+
var LinearRegExp = class {
|
|
5628
|
+
anchoredStart;
|
|
5629
|
+
prog;
|
|
5630
|
+
unicode;
|
|
5631
|
+
constructor(prog, unicode) {
|
|
5632
|
+
this.prog = prog;
|
|
5633
|
+
this.unicode = unicode;
|
|
5634
|
+
const first = prog[0];
|
|
5635
|
+
this.anchoredStart = first !== void 0 && first.op === "assert" && first.assertion === "start";
|
|
5636
|
+
}
|
|
5637
|
+
get size() {
|
|
5638
|
+
return this.prog.length;
|
|
5639
|
+
}
|
|
5640
|
+
cost(input) {
|
|
5641
|
+
return (input.length + 1) * this.prog.length;
|
|
5642
|
+
}
|
|
5643
|
+
search(input, budget) {
|
|
5644
|
+
if (this.cost(input) > budget) return void 0;
|
|
5645
|
+
const prog = this.prog;
|
|
5646
|
+
const size = prog.length;
|
|
5647
|
+
const mark = new Int32Array(size).fill(-1);
|
|
5648
|
+
const stack = [];
|
|
5649
|
+
let clist = new Int32Array(size);
|
|
5650
|
+
let nlist = new Int32Array(size);
|
|
5651
|
+
const add = (list, count, start, pos, generation) => {
|
|
5652
|
+
stack.push(start);
|
|
5653
|
+
while (stack.length > 0) {
|
|
5654
|
+
const pc = stack.pop();
|
|
5655
|
+
if (mark[pc] === generation) continue;
|
|
5656
|
+
mark[pc] = generation;
|
|
5657
|
+
const inst = prog[pc];
|
|
5658
|
+
switch (inst.op) {
|
|
5659
|
+
case "match":
|
|
5660
|
+
stack.length = 0;
|
|
5661
|
+
return -1;
|
|
5662
|
+
case "jmp":
|
|
5663
|
+
stack.push(inst.to);
|
|
5664
|
+
break;
|
|
5665
|
+
case "split":
|
|
5666
|
+
stack.push(inst.b, inst.a);
|
|
5667
|
+
break;
|
|
5668
|
+
case "assert":
|
|
5669
|
+
if (this.holds(inst.assertion, input, pos)) stack.push(pc + 1);
|
|
5670
|
+
break;
|
|
5671
|
+
case "char": list[count++] = pc;
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
5674
|
+
return count;
|
|
5675
|
+
};
|
|
5676
|
+
let pos = 0;
|
|
5677
|
+
let generation = 0;
|
|
5678
|
+
let clen = add(clist, 0, 0, pos, generation);
|
|
5679
|
+
if (clen < 0) return true;
|
|
5680
|
+
while (pos < input.length) {
|
|
5681
|
+
if (this.anchoredStart && clen === 0) return false;
|
|
5682
|
+
const cp = this.unicode ? input.codePointAt(pos) : input.charCodeAt(pos);
|
|
5683
|
+
const next = pos + (this.unicode && cp > 65535 ? 2 : 1);
|
|
5684
|
+
generation++;
|
|
5685
|
+
let nlen = 0;
|
|
5686
|
+
for (let i = 0; i < clen; i++) {
|
|
5687
|
+
const pc = clist[i];
|
|
5688
|
+
if (prog[pc].matcher.matches(cp, this.unicode)) {
|
|
5689
|
+
nlen = add(nlist, nlen, pc + 1, next, generation);
|
|
5690
|
+
if (nlen < 0) return true;
|
|
5691
|
+
}
|
|
5692
|
+
}
|
|
5693
|
+
nlen = add(nlist, nlen, 0, next, generation);
|
|
5694
|
+
if (nlen < 0) return true;
|
|
5695
|
+
[clist, nlist] = [nlist, clist];
|
|
5696
|
+
clen = nlen;
|
|
5697
|
+
pos = next;
|
|
5698
|
+
}
|
|
5699
|
+
return false;
|
|
5700
|
+
}
|
|
5701
|
+
holds(assertion, input, pos) {
|
|
5702
|
+
switch (assertion) {
|
|
5703
|
+
case "start": return pos === 0;
|
|
5704
|
+
case "end": return pos === input.length;
|
|
5705
|
+
case "wordBoundary":
|
|
5706
|
+
case "notWordBoundary": return (pos > 0 && isWordUnit(input.charCodeAt(pos - 1))) !== (pos < input.length && isWordUnit(input.charCodeAt(pos))) === (assertion === "wordBoundary");
|
|
5707
|
+
}
|
|
5708
|
+
}
|
|
5709
|
+
};
|
|
5710
|
+
function compileLinearRegExp(pattern, unicode, budget) {
|
|
5711
|
+
if (pattern.length > 8192) return {
|
|
5712
|
+
ok: false,
|
|
5713
|
+
reason: `pattern longer than ${MAX_PATTERN_LENGTH} characters`
|
|
5714
|
+
};
|
|
5715
|
+
if (budget) {
|
|
5716
|
+
budget.steps -= pattern.length;
|
|
5717
|
+
if (isCompileBudgetExhausted(budget)) return {
|
|
5718
|
+
ok: false,
|
|
5719
|
+
reason: COMPILE_BUDGET_EXHAUSTED
|
|
5720
|
+
};
|
|
5721
|
+
}
|
|
5722
|
+
new RegExp(pattern, unicode ? "u" : "");
|
|
5723
|
+
try {
|
|
5724
|
+
const ast = new Parser(pattern, unicode).parse();
|
|
5725
|
+
const compiler = new Compiler(unicode, budget);
|
|
5726
|
+
compiler.compile(ast);
|
|
5727
|
+
compiler.prog.push({ op: "match" });
|
|
5728
|
+
return {
|
|
5729
|
+
ok: true,
|
|
5730
|
+
regExp: new LinearRegExp(compiler.prog, unicode)
|
|
5731
|
+
};
|
|
5732
|
+
} catch (error) {
|
|
5733
|
+
/* v8 ignore next -- every throw inside the parser/compiler is an Unsupported */
|
|
5734
|
+
if (!(error instanceof Unsupported)) throw error;
|
|
5735
|
+
return {
|
|
5736
|
+
ok: false,
|
|
5737
|
+
reason: error.message
|
|
5738
|
+
};
|
|
5739
|
+
}
|
|
5740
|
+
}
|
|
5741
|
+
// ../../core/mcp/linearPatternValidator.ts
|
|
5742
|
+
const PATTERN_EVALUATION_BUDGET = 2e7;
|
|
5743
|
+
const SCHEMA_COMPILE_BUDGET = {
|
|
5744
|
+
steps: 10 * MAX_COMPILE_STEPS,
|
|
5745
|
+
size: 10 * MAX_PROGRAM_SIZE
|
|
5746
|
+
};
|
|
5747
|
+
const MAX_QUOTED_PATTERN = 120;
|
|
5748
|
+
const DRAFT_2020_12 = /* @__PURE__ */ new Set(["https://json-schema.org/draft/2020-12/schema", "http://json-schema.org/draft/2020-12/schema"]);
|
|
5749
|
+
const DRAFT_2019_09 = /* @__PURE__ */ new Set(["https://json-schema.org/draft/2019-09/schema", "http://json-schema.org/draft/2019-09/schema"]);
|
|
5750
|
+
const DRAFT_07_OR_06 = /* @__PURE__ */ new Set([
|
|
5751
|
+
"https://json-schema.org/draft-07/schema",
|
|
5752
|
+
"http://json-schema.org/draft-07/schema",
|
|
5753
|
+
"https://json-schema.org/draft-06/schema",
|
|
5754
|
+
"http://json-schema.org/draft-06/schema"
|
|
5755
|
+
]);
|
|
5756
|
+
function declaredDialect(schema) {
|
|
5757
|
+
const declared = schema.$schema;
|
|
5758
|
+
if (typeof declared !== "string") return "2020-12";
|
|
5759
|
+
const uri = declared.replace(/#$/, "");
|
|
5760
|
+
if (DRAFT_2020_12.has(uri)) return "2020-12";
|
|
5761
|
+
if (DRAFT_2019_09.has(uri)) return "2019-09";
|
|
5762
|
+
if (DRAFT_07_OR_06.has(uri)) return "draft-7";
|
|
5763
|
+
throw new Error(`JSON Schema declares an unsupported dialect ("$schema": "${declared.slice(0, 200)}"). Supported: JSON Schema 2020-12, 2019-09, draft-07, and draft-06.`);
|
|
5764
|
+
}
|
|
5765
|
+
function quote(pattern) {
|
|
5766
|
+
return pattern.length > MAX_QUOTED_PATTERN ? `${pattern.slice(0, MAX_QUOTED_PATTERN)}…` : pattern;
|
|
5767
|
+
}
|
|
5768
|
+
var PatternLedger = class {
|
|
5769
|
+
remaining = PATTERN_EVALUATION_BUDGET;
|
|
5770
|
+
unevaluated = /* @__PURE__ */ new Set();
|
|
5771
|
+
reset() {
|
|
5772
|
+
this.remaining = PATTERN_EVALUATION_BUDGET;
|
|
5773
|
+
this.unevaluated.clear();
|
|
5774
|
+
}
|
|
5775
|
+
};
|
|
5776
|
+
var LinearPattern = class {
|
|
5777
|
+
source;
|
|
5778
|
+
flags;
|
|
5779
|
+
compiled;
|
|
5780
|
+
ledger;
|
|
5781
|
+
constructor(source, flags, compiled, ledger) {
|
|
5782
|
+
this.source = source;
|
|
5783
|
+
this.flags = flags;
|
|
5784
|
+
this.compiled = compiled;
|
|
5785
|
+
this.ledger = ledger;
|
|
5786
|
+
}
|
|
5787
|
+
test(input) {
|
|
5788
|
+
if (!this.compiled.ok) return this.skip(this.compiled.reason);
|
|
5789
|
+
const { regExp } = this.compiled;
|
|
5790
|
+
const cost = regExp.cost(input);
|
|
5791
|
+
if (cost > this.ledger.remaining) return this.skip(`checking a ${input.length}-character value would exceed the evaluation budget`);
|
|
5792
|
+
this.ledger.remaining -= cost;
|
|
5793
|
+
return regExp.search(input, cost) === true;
|
|
5794
|
+
}
|
|
5795
|
+
skip(reason) {
|
|
5796
|
+
this.ledger.unevaluated.add(`pattern "${quote(this.source)}" was not evaluated (${reason})`);
|
|
5797
|
+
return true;
|
|
5798
|
+
}
|
|
5799
|
+
toString() {
|
|
5800
|
+
return `/${this.source}/${this.flags}`;
|
|
5801
|
+
}
|
|
5802
|
+
};
|
|
5803
|
+
function createRegExpEngine(ledger, budget) {
|
|
5804
|
+
const engine = (pattern, flags) => new LinearPattern(pattern, flags, compileLinearRegExp(pattern, flags.includes("u"), budget()), ledger);
|
|
5805
|
+
return Object.assign(engine, { code: "linearRegExp" });
|
|
5806
|
+
}
|
|
5807
|
+
var LinearPatternJsonSchemaValidator = class {
|
|
5808
|
+
ledger = new PatternLedger();
|
|
5809
|
+
engines = /* @__PURE__ */ new Map();
|
|
5810
|
+
compileBudget = { ...SCHEMA_COMPILE_BUDGET };
|
|
5811
|
+
overBudget = /* @__PURE__ */ new WeakSet();
|
|
5812
|
+
engineFor(dialect) {
|
|
5813
|
+
let engine = this.engines.get(dialect);
|
|
5814
|
+
if (!engine) {
|
|
5815
|
+
const options = {
|
|
5816
|
+
strict: false,
|
|
5817
|
+
validateFormats: true,
|
|
5818
|
+
validateSchema: false,
|
|
5819
|
+
allErrors: true,
|
|
5820
|
+
code: { regExp: createRegExpEngine(this.ledger, () => this.compileBudget) }
|
|
5821
|
+
};
|
|
5822
|
+
engine = dialect === "2020-12" ? new Ajv2020(options) : dialect === "2019-09" ? new Ajv2019(options) : new Ajv(options);
|
|
5823
|
+
addFormats(engine);
|
|
5824
|
+
this.engines.set(dialect, engine);
|
|
5825
|
+
}
|
|
5826
|
+
return engine;
|
|
5827
|
+
}
|
|
5828
|
+
getValidator(schema) {
|
|
5829
|
+
const engine = this.engineFor(declaredDialect(schema));
|
|
5830
|
+
const id = schema.$id;
|
|
5831
|
+
const validate = this.tracked(() => (typeof id === "string" ? engine.getSchema(id) : void 0) ?? engine.compile(schema));
|
|
5832
|
+
const overBudget = this.overBudget.has(validate);
|
|
5833
|
+
return (input) => {
|
|
5834
|
+
this.ledger.reset();
|
|
5835
|
+
const valid = validate(input);
|
|
5836
|
+
const unevaluated = [...this.ledger.unevaluated];
|
|
5837
|
+
if (overBudget) unevaluated.unshift("the schema's patterns exceed the compilation budget");
|
|
5838
|
+
if (valid && unevaluated.length === 0) return {
|
|
5839
|
+
valid: true,
|
|
5840
|
+
data: input,
|
|
5841
|
+
errorMessage: void 0
|
|
5842
|
+
};
|
|
5843
|
+
const messages = valid ? [] : [engine.errorsText(validate.errors)];
|
|
5844
|
+
if (unevaluated.length > 0) messages.push(`${unevaluated.join("; ")}, so the value could not be verified against the schema`);
|
|
5845
|
+
return {
|
|
5846
|
+
valid: false,
|
|
5847
|
+
data: void 0,
|
|
5848
|
+
errorMessage: messages.join("; ")
|
|
5849
|
+
};
|
|
5850
|
+
};
|
|
5851
|
+
}
|
|
5852
|
+
tracked(run) {
|
|
5853
|
+
const outer = this.compileBudget;
|
|
5854
|
+
const budget = { ...SCHEMA_COMPILE_BUDGET };
|
|
5855
|
+
this.compileBudget = budget;
|
|
5856
|
+
try {
|
|
5857
|
+
const validate = run();
|
|
5858
|
+
if (isCompileBudgetExhausted(budget)) this.overBudget.add(validate);
|
|
5859
|
+
return validate;
|
|
5860
|
+
} finally {
|
|
5861
|
+
this.compileBudget = outer;
|
|
5862
|
+
}
|
|
5863
|
+
}
|
|
5864
|
+
};
|
|
5185
5865
|
function listPaginationExceeded(method) {
|
|
5186
5866
|
return /* @__PURE__ */ new Error(`Salvage walk for ${method} exceeded 64 pages without the server's pagination converging`);
|
|
5187
5867
|
}
|
|
@@ -5282,8 +5962,7 @@ function stripExecution(tool) {
|
|
|
5282
5962
|
function eraToolItemSchema(wire, normalize) {
|
|
5283
5963
|
return wire.transform((parsed) => normalize(parsed));
|
|
5284
5964
|
}
|
|
5285
|
-
|
|
5286
|
-
//#region ../../core/mcp/uriTemplate.ts
|
|
5965
|
+
// ../../core/mcp/uriTemplate.ts
|
|
5287
5966
|
const OPERATORS = [
|
|
5288
5967
|
"+",
|
|
5289
5968
|
"#",
|
|
@@ -5508,8 +6187,7 @@ function valueLengthError(values, names) {
|
|
|
5508
6187
|
function declaredNames(parts) {
|
|
5509
6188
|
return [...new Set(parts.flatMap((part) => part.kind === "expression" ? part.names : []))];
|
|
5510
6189
|
}
|
|
5511
|
-
|
|
5512
|
-
//#region ../../core/mcp/typedEventTarget.ts
|
|
6190
|
+
// ../../core/mcp/typedEventTarget.ts
|
|
5513
6191
|
var TypedEventGeneric = class extends CustomEvent {
|
|
5514
6192
|
constructor(type, detail) {
|
|
5515
6193
|
super(type, { detail });
|
|
@@ -5535,11 +6213,9 @@ var TypedEventTarget = class extends EventTarget {
|
|
|
5535
6213
|
super.removeEventListener(type, listener, options);
|
|
5536
6214
|
}
|
|
5537
6215
|
};
|
|
5538
|
-
|
|
5539
|
-
//#region ../../core/mcp/inspectorClientEventTarget.ts
|
|
6216
|
+
// ../../core/mcp/inspectorClientEventTarget.ts
|
|
5540
6217
|
var InspectorClientEventTarget = class extends TypedEventTarget {};
|
|
5541
|
-
|
|
5542
|
-
//#region ../../core/mcp/samplingCreateMessage.ts
|
|
6218
|
+
// ../../core/mcp/samplingCreateMessage.ts
|
|
5543
6219
|
var SamplingCreateMessage = class {
|
|
5544
6220
|
id;
|
|
5545
6221
|
timestamp;
|
|
@@ -5583,8 +6259,7 @@ var SamplingCreateMessage = class {
|
|
|
5583
6259
|
this.onRemove(this.id);
|
|
5584
6260
|
}
|
|
5585
6261
|
};
|
|
5586
|
-
|
|
5587
|
-
//#region ../../core/mcp/elicitationCreateMessage.ts
|
|
6262
|
+
// ../../core/mcp/elicitationCreateMessage.ts
|
|
5588
6263
|
var ElicitationCreateMessage = class {
|
|
5589
6264
|
id;
|
|
5590
6265
|
timestamp;
|
|
@@ -5631,8 +6306,7 @@ var ElicitationCreateMessage = class {
|
|
|
5631
6306
|
this.onRemove(this.id);
|
|
5632
6307
|
}
|
|
5633
6308
|
};
|
|
5634
|
-
|
|
5635
|
-
//#region ../../core/mcp/urlElicitation.ts
|
|
6309
|
+
// ../../core/mcp/urlElicitation.ts
|
|
5636
6310
|
var UrlElicitationLoopError = class extends Error {
|
|
5637
6311
|
url;
|
|
5638
6312
|
constructor(url) {
|
|
@@ -5646,8 +6320,7 @@ function getUrlElicitationsFromError(error) {
|
|
|
5646
6320
|
if (error instanceof ProtocolError && error.code === ProtocolErrorCode.UrlElicitationRequired) return error.data?.elicitations ?? [];
|
|
5647
6321
|
return null;
|
|
5648
6322
|
}
|
|
5649
|
-
|
|
5650
|
-
//#region ../../core/mcp/toolCallCancelledError.ts
|
|
6323
|
+
// ../../core/mcp/toolCallCancelledError.ts
|
|
5651
6324
|
var ToolCallCancelledError = class extends Error {
|
|
5652
6325
|
toolName;
|
|
5653
6326
|
constructor(toolName) {
|
|
@@ -5656,8 +6329,7 @@ var ToolCallCancelledError = class extends Error {
|
|
|
5656
6329
|
this.toolName = toolName;
|
|
5657
6330
|
}
|
|
5658
6331
|
};
|
|
5659
|
-
|
|
5660
|
-
//#region ../../core/auth/endpointOverrides.ts
|
|
6332
|
+
// ../../core/auth/endpointOverrides.ts
|
|
5661
6333
|
const OVERRIDE_FIELDS = {
|
|
5662
6334
|
authorizationUrl: "authorization_endpoint",
|
|
5663
6335
|
tokenUrl: "token_endpoint"
|
|
@@ -5834,8 +6506,7 @@ function withOAuthEndpointOverrides(fetchFn, getOverrides) {
|
|
|
5834
6506
|
return responseWithBody(response, JSON.stringify(applyOAuthEndpointOverrides(parsed, overrides)));
|
|
5835
6507
|
};
|
|
5836
6508
|
}
|
|
5837
|
-
|
|
5838
|
-
//#region ../../core/auth/oidcDiscoveryCompat.ts
|
|
6509
|
+
// ../../core/auth/oidcDiscoveryCompat.ts
|
|
5839
6510
|
const RFC8414_WELL_KNOWN = "/.well-known/oauth-authorization-server";
|
|
5840
6511
|
const OIDC_WELL_KNOWN$1 = "/.well-known/openid-configuration";
|
|
5841
6512
|
const COMPAT_SOURCE_HEADER = "x-inspector-oauth-metadata-source";
|
|
@@ -5957,8 +6628,7 @@ function withRfc8414OidcCompat(fetchFn) {
|
|
|
5957
6628
|
return response;
|
|
5958
6629
|
};
|
|
5959
6630
|
}
|
|
5960
|
-
|
|
5961
|
-
//#region ../../core/logging/logger.ts
|
|
6631
|
+
// ../../core/logging/logger.ts
|
|
5962
6632
|
const noop = () => {};
|
|
5963
6633
|
function createSilentLogger() {
|
|
5964
6634
|
const logger = {
|
|
@@ -5975,8 +6645,7 @@ function createSilentLogger() {
|
|
|
5975
6645
|
return logger;
|
|
5976
6646
|
}
|
|
5977
6647
|
const silentLogger = createSilentLogger();
|
|
5978
|
-
|
|
5979
|
-
//#region ../../core/mcp/connectionDiagnostics.ts
|
|
6648
|
+
// ../../core/mcp/connectionDiagnostics.ts
|
|
5980
6649
|
function isRequestTimeoutData(value) {
|
|
5981
6650
|
return typeof value === "object" && value !== null && typeof value.timeout === "number";
|
|
5982
6651
|
}
|
|
@@ -5998,7 +6667,7 @@ function httpStatusTextOf(err) {
|
|
|
5998
6667
|
if (typeof err !== "object" || err === null || !("statusText" in err)) return;
|
|
5999
6668
|
return typeof err.statusText === "string" ? err.statusText : void 0;
|
|
6000
6669
|
}
|
|
6001
|
-
function formatDuration(ms) {
|
|
6670
|
+
function formatDuration$1(ms) {
|
|
6002
6671
|
const clamped = Math.max(0, ms);
|
|
6003
6672
|
if (clamped < 1e3) return `${Math.round(clamped)}ms`;
|
|
6004
6673
|
const totalSeconds = Math.round(clamped / 1e3);
|
|
@@ -6021,7 +6690,7 @@ function plural(count, noun) {
|
|
|
6021
6690
|
}
|
|
6022
6691
|
function describeOutstanding(requests, now) {
|
|
6023
6692
|
if (requests.length === 0) return "No requests are unanswered.";
|
|
6024
|
-
const listed = requests.slice(0, 5).map((r) => `${r.method} (sent ${formatDuration(now - r.sentAt)} ago)`);
|
|
6693
|
+
const listed = requests.slice(0, 5).map((r) => `${r.method} (sent ${formatDuration$1(now - r.sentAt)} ago)`);
|
|
6025
6694
|
const rest = requests.length - listed.length;
|
|
6026
6695
|
const tail = rest > 0 ? `, and ${rest} more` : "";
|
|
6027
6696
|
const verb = requests.length === 1 ? "is" : "are";
|
|
@@ -6029,14 +6698,14 @@ function describeOutstanding(requests, now) {
|
|
|
6029
6698
|
}
|
|
6030
6699
|
function describeLastResponse(lastResponse, now) {
|
|
6031
6700
|
if (!lastResponse) return "No response has been received this session.";
|
|
6032
|
-
return `Last response received ${formatDuration(now - lastResponse.receivedAt)} ago (${lastResponse.method}).`;
|
|
6701
|
+
return `Last response received ${formatDuration$1(now - lastResponse.receivedAt)} ago (${lastResponse.method}).`;
|
|
6033
6702
|
}
|
|
6034
6703
|
function describeStream(stream, now) {
|
|
6035
6704
|
if (!stream) return void 0;
|
|
6036
6705
|
const endpoint = describeStreamEndpoint(stream.url);
|
|
6037
6706
|
const events = plural(stream.eventCount, "event");
|
|
6038
|
-
if (stream.closedAt !== void 0) return `Notification stream (${endpoint}) closed ${formatDuration(now - stream.closedAt)} ago after ${formatDuration(stream.closedAt - stream.openedAt)}, ${events} delivered.`;
|
|
6039
|
-
return `Notification stream (${endpoint}) open for ${formatDuration(now - stream.openedAt)}, ${events} delivered.`;
|
|
6707
|
+
if (stream.closedAt !== void 0) return `Notification stream (${endpoint}) closed ${formatDuration$1(now - stream.closedAt)} ago after ${formatDuration$1(stream.closedAt - stream.openedAt)}, ${events} delivered.`;
|
|
6708
|
+
return `Notification stream (${endpoint}) open for ${formatDuration$1(now - stream.openedAt)}, ${events} delivered.`;
|
|
6040
6709
|
}
|
|
6041
6710
|
function describeConnectionDiagnostics(diagnostics) {
|
|
6042
6711
|
const now = diagnostics.capturedAt;
|
|
@@ -6053,7 +6722,7 @@ function annotateRequestTimeout(err, method, diagnostics) {
|
|
|
6053
6722
|
method,
|
|
6054
6723
|
diagnostics
|
|
6055
6724
|
};
|
|
6056
|
-
const message = `Request timed out after ${formatDuration(err.data.timeout)} (${method}). ${describeConnectionDiagnostics(diagnostics)}`;
|
|
6725
|
+
const message = `Request timed out after ${formatDuration$1(err.data.timeout)} (${method}). ${describeConnectionDiagnostics(diagnostics)}`;
|
|
6057
6726
|
const annotated = new SdkError(SdkErrorCode.RequestTimeout, message, data);
|
|
6058
6727
|
annotated.cause = err;
|
|
6059
6728
|
return annotated;
|
|
@@ -6123,7 +6792,7 @@ function attachRetryAfter(err, retryAfter) {
|
|
|
6123
6792
|
err.data.retryAfter = retryAfter;
|
|
6124
6793
|
}
|
|
6125
6794
|
function describeRetry(retryAfter, retryAfterMs) {
|
|
6126
|
-
if (retryAfterMs !== void 0) return `The server asked to retry after ${formatDuration(retryAfterMs)}.`;
|
|
6795
|
+
if (retryAfterMs !== void 0) return `The server asked to retry after ${formatDuration$1(retryAfterMs)}.`;
|
|
6127
6796
|
if (retryAfter !== void 0) return `The server sent an unparseable Retry-After (${retryAfter}).`;
|
|
6128
6797
|
return "The server sent no Retry-After header.";
|
|
6129
6798
|
}
|
|
@@ -6168,8 +6837,7 @@ function applyAuthorizationParams(authorizationUrl, params) {
|
|
|
6168
6837
|
for (const [key, value] of applicable) merged.searchParams.set(key.trim(), value);
|
|
6169
6838
|
return merged;
|
|
6170
6839
|
}
|
|
6171
|
-
|
|
6172
|
-
//#region ../../core/auth/scopes.ts
|
|
6840
|
+
// ../../core/auth/scopes.ts
|
|
6173
6841
|
const computeScopeUnion$1 = computeScopeUnion;
|
|
6174
6842
|
const isStrictScopeSuperset$1 = isStrictScopeSuperset;
|
|
6175
6843
|
const OFFLINE_ACCESS_SCOPE = "offline_access";
|
|
@@ -6197,8 +6865,7 @@ function resolveEffectiveGrantedScope(storedScope, tokenScope) {
|
|
|
6197
6865
|
if (granted) return granted;
|
|
6198
6866
|
return computeScopeUnion$1(storedScope, tokenScope);
|
|
6199
6867
|
}
|
|
6200
|
-
|
|
6201
|
-
//#region ../../core/auth/providers.ts
|
|
6868
|
+
// ../../core/auth/providers.ts
|
|
6202
6869
|
var MutableRedirectUrlProvider = class {
|
|
6203
6870
|
redirectUrl = "";
|
|
6204
6871
|
getRedirectUrl() {
|
|
@@ -6429,8 +7096,7 @@ var BaseOAuthClientProvider = class {
|
|
|
6429
7096
|
}
|
|
6430
7097
|
}
|
|
6431
7098
|
};
|
|
6432
|
-
|
|
6433
|
-
//#region ../../core/auth/types.ts
|
|
7099
|
+
// ../../core/auth/types.ts
|
|
6434
7100
|
function authProtocolFromEnterpriseManaged(enterpriseManaged) {
|
|
6435
7101
|
return enterpriseManaged ? "ema" : "standard";
|
|
6436
7102
|
}
|
|
@@ -6451,8 +7117,7 @@ const EMPTY_OAUTH_FLOW_STATE = {
|
|
|
6451
7117
|
statusMessage: null,
|
|
6452
7118
|
validationError: null
|
|
6453
7119
|
};
|
|
6454
|
-
|
|
6455
|
-
//#region ../../core/auth/mcpAuth.ts
|
|
7120
|
+
// ../../core/auth/mcpAuth.ts
|
|
6456
7121
|
async function mcpAuth(provider, options) {
|
|
6457
7122
|
if (options.forceReauthorization && options.authorizationCode !== void 0) throw new Error("forceReauthorization cannot be combined with authorizationCode");
|
|
6458
7123
|
return auth(provider, {
|
|
@@ -6723,8 +7388,7 @@ async function runPlan(plan, params) {
|
|
|
6723
7388
|
}
|
|
6724
7389
|
return aggregateOutcomes(outcomes);
|
|
6725
7390
|
}
|
|
6726
|
-
|
|
6727
|
-
//#region ../../core/auth/ema/clientConfigError.ts
|
|
7391
|
+
// ../../core/auth/ema/clientConfigError.ts
|
|
6728
7392
|
function emaClientNotConfiguredMessage(reason) {
|
|
6729
7393
|
if (reason === "disabled") return "This server uses enterprise-managed authorization, but Enterprise IdP is turned off in Client Settings. Open Client Settings, enable \"Enterprise IdP configuration\", then try connecting again.";
|
|
6730
7394
|
return "This server uses enterprise-managed authorization, but the Inspector client IdP is not configured. Open Client Settings, enable Enterprise IdP, and set issuer, client ID, and client secret.";
|
|
@@ -6740,12 +7404,10 @@ var EmaClientNotConfiguredError = class extends Error {
|
|
|
6740
7404
|
function isEmaClientNotConfiguredError(err) {
|
|
6741
7405
|
return err instanceof EmaClientNotConfiguredError;
|
|
6742
7406
|
}
|
|
6743
|
-
|
|
6744
|
-
//#region ../../core/auth/ema/constants.ts
|
|
7407
|
+
// ../../core/auth/ema/constants.ts
|
|
6745
7408
|
const GRANT_TYPE_JWT_BEARER = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
|
6746
7409
|
const IDP_OIDC_SCOPES = "openid offline_access";
|
|
6747
|
-
|
|
6748
|
-
//#region ../../core/auth/ema/jwt.ts
|
|
7410
|
+
// ../../core/auth/ema/jwt.ts
|
|
6749
7411
|
function decodeBase64Url(segment) {
|
|
6750
7412
|
const base64 = segment.replace(/-/g, "+").replace(/_/g, "/");
|
|
6751
7413
|
const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
|
|
@@ -6772,8 +7434,19 @@ function isJwtFormat(token) {
|
|
|
6772
7434
|
const parts = token.split(".");
|
|
6773
7435
|
return parts.length === 3 && parts[0].length > 0 && parts[1].length > 0 && parts[2] !== void 0;
|
|
6774
7436
|
}
|
|
6775
|
-
|
|
6776
|
-
|
|
7437
|
+
function decodeJwtPayload(token) {
|
|
7438
|
+
if (!isJwtFormat(token)) return void 0;
|
|
7439
|
+
const parts = token.split(".");
|
|
7440
|
+
try {
|
|
7441
|
+
return {
|
|
7442
|
+
header: JSON.parse(decodeBase64Url(parts[0])),
|
|
7443
|
+
payload: JSON.parse(decodeBase64Url(parts[1]))
|
|
7444
|
+
};
|
|
7445
|
+
} catch {
|
|
7446
|
+
return;
|
|
7447
|
+
}
|
|
7448
|
+
}
|
|
7449
|
+
// ../../core/auth/ema/storage.ts
|
|
6777
7450
|
function normalizeIdpIssuer(issuer) {
|
|
6778
7451
|
return issuer.replace(/\/$/, "");
|
|
6779
7452
|
}
|
|
@@ -6781,8 +7454,7 @@ const IDP_OAUTH_KEY_PREFIX = "ema-idp:";
|
|
|
6781
7454
|
function idpOAuthStorageKey(issuer) {
|
|
6782
7455
|
return `${IDP_OAUTH_KEY_PREFIX}${normalizeIdpIssuer(issuer)}`;
|
|
6783
7456
|
}
|
|
6784
|
-
|
|
6785
|
-
//#region ../../core/auth/ema/tokenEndpoint.ts
|
|
7457
|
+
// ../../core/auth/ema/tokenEndpoint.ts
|
|
6786
7458
|
async function parseOAuthTokenErrorResponse(response, step) {
|
|
6787
7459
|
let body;
|
|
6788
7460
|
try {
|
|
@@ -6826,8 +7498,7 @@ async function postOAuthTokenRequest(tokenUrl, body, metadata, clientInformation
|
|
|
6826
7498
|
body
|
|
6827
7499
|
});
|
|
6828
7500
|
}
|
|
6829
|
-
|
|
6830
|
-
//#region ../../core/auth/ema/idpOidc.ts
|
|
7501
|
+
// ../../core/auth/ema/idpOidc.ts
|
|
6831
7502
|
function idpClientInformation(idp) {
|
|
6832
7503
|
return {
|
|
6833
7504
|
client_id: idp.clientId,
|
|
@@ -6950,8 +7621,7 @@ async function getValidIdToken(params) {
|
|
|
6950
7621
|
return;
|
|
6951
7622
|
}
|
|
6952
7623
|
}
|
|
6953
|
-
|
|
6954
|
-
//#region ../../core/auth/discovery.ts
|
|
7624
|
+
// ../../core/auth/discovery.ts
|
|
6955
7625
|
function serverUrlAsAuthorizationServer(serverUrl) {
|
|
6956
7626
|
try {
|
|
6957
7627
|
const url = new URL(serverUrl);
|
|
@@ -6993,8 +7663,7 @@ async function discoverAuthorizationServerMetadataFromCandidates(candidates, dis
|
|
|
6993
7663
|
async function discoverAuthorizationServerMetadataForServer(serverUrl, resourceMetadata, fetchFn) {
|
|
6994
7664
|
return (await discoverAuthorizationServerMetadataFromCandidates(getAuthorizationServerUrlCandidates(serverUrl, resourceMetadata), (candidate) => discoverAuthorizationServerMetadata(candidate, { fetchFn })))?.metadata;
|
|
6995
7665
|
}
|
|
6996
|
-
|
|
6997
|
-
//#region ../../core/auth/ema/resourceContext.ts
|
|
7666
|
+
// ../../core/auth/ema/resourceContext.ts
|
|
6998
7667
|
function resolveEmaScopes(resourceMetadata, configuredScope) {
|
|
6999
7668
|
const trimmed = configuredScope?.trim();
|
|
7000
7669
|
if (trimmed) return trimmed;
|
|
@@ -7027,8 +7696,7 @@ async function discoverResourceAsMetadata(resourceAsUrl, fetchFn) {
|
|
|
7027
7696
|
if (!metadata) throw new Error("Failed to discover resource authorization server metadata");
|
|
7028
7697
|
return metadata;
|
|
7029
7698
|
}
|
|
7030
|
-
|
|
7031
|
-
//#region ../../core/auth/ema/wire.ts
|
|
7699
|
+
// ../../core/auth/ema/wire.ts
|
|
7032
7700
|
async function exchangeIdJag(params) {
|
|
7033
7701
|
const issuer = normalizeIdpIssuer(params.idp.issuer);
|
|
7034
7702
|
const resource = params.resource.trim();
|
|
@@ -7072,8 +7740,7 @@ async function redeemIdJagForAccessToken(params) {
|
|
|
7072
7740
|
if (!response.ok) throw await parseOAuthTokenErrorResponse(response, "EMA leg 3 (resource AS JWT bearer grant)");
|
|
7073
7741
|
return OAuthTokensSchema.parse(await response.json());
|
|
7074
7742
|
}
|
|
7075
|
-
|
|
7076
|
-
//#region ../../core/auth/ema/emaFlow.ts
|
|
7743
|
+
// ../../core/auth/ema/emaFlow.ts
|
|
7077
7744
|
function wrapEmaMintError(err) {
|
|
7078
7745
|
const message = err instanceof Error ? err.message : String(err);
|
|
7079
7746
|
return new Error(`EMA legs 2–3 (resource token mint): ${message}`, { cause: err });
|
|
@@ -7173,8 +7840,7 @@ async function refreshEmaResourceTokens(config) {
|
|
|
7173
7840
|
await saveMintedTokens(config, minted);
|
|
7174
7841
|
return minted.tokens;
|
|
7175
7842
|
}
|
|
7176
|
-
|
|
7177
|
-
//#region ../../core/auth/ema/idpSession.ts
|
|
7843
|
+
// ../../core/auth/ema/idpSession.ts
|
|
7178
7844
|
async function getEmaIdpLoginState(storage, issuer) {
|
|
7179
7845
|
const normalized = normalizeIdpIssuer(issuer);
|
|
7180
7846
|
if (!normalized) return "none";
|
|
@@ -7184,8 +7850,7 @@ async function getEmaIdpLoginState(storage, issuer) {
|
|
|
7184
7850
|
if (session.refreshToken) return "logged_in";
|
|
7185
7851
|
return "expired";
|
|
7186
7852
|
}
|
|
7187
|
-
|
|
7188
|
-
//#region ../../core/auth/connection-state.ts
|
|
7853
|
+
// ../../core/auth/connection-state.ts
|
|
7189
7854
|
function isAccessTokenUsable$1(tokens) {
|
|
7190
7855
|
if (!tokens?.access_token) return false;
|
|
7191
7856
|
return !isJwtExpired(tokens.access_token);
|
|
@@ -7268,8 +7933,7 @@ async function hasPersistedOAuthServerState(storage, serverUrl) {
|
|
|
7268
7933
|
function protocolFromOAuthConfig(config) {
|
|
7269
7934
|
return authProtocolFromEnterpriseManaged(config.enterpriseManaged);
|
|
7270
7935
|
}
|
|
7271
|
-
|
|
7272
|
-
//#region ../../core/auth/cimd.ts
|
|
7936
|
+
// ../../core/auth/cimd.ts
|
|
7273
7937
|
async function ensureCimdClientRegistration(params) {
|
|
7274
7938
|
const clientMetadataUrl = params.provider.clientMetadataUrl?.trim();
|
|
7275
7939
|
if (!clientMetadataUrl) return;
|
|
@@ -7295,8 +7959,7 @@ async function ensureCimdClientRegistration(params) {
|
|
|
7295
7959
|
...issuer && { issuer }
|
|
7296
7960
|
});
|
|
7297
7961
|
}
|
|
7298
|
-
|
|
7299
|
-
//#region ../../core/auth/ema/transportProvider.ts
|
|
7962
|
+
// ../../core/auth/ema/transportProvider.ts
|
|
7300
7963
|
function isAccessTokenUsable(tokens, skewMs = 6e4) {
|
|
7301
7964
|
if (!tokens.access_token) return false;
|
|
7302
7965
|
return !isJwtExpired(tokens.access_token, skewMs);
|
|
@@ -7356,8 +8019,7 @@ var EmaTransportOAuthProvider = class {
|
|
|
7356
8019
|
return this.inner.codeVerifier();
|
|
7357
8020
|
}
|
|
7358
8021
|
};
|
|
7359
|
-
|
|
7360
|
-
//#region ../../core/auth/oauthUx.ts
|
|
8022
|
+
// ../../core/auth/oauthUx.ts
|
|
7361
8023
|
function isStandardOAuthStepUp(challenge, options) {
|
|
7362
8024
|
return challenge.reason === "insufficient_scope" && !options?.enterpriseManaged;
|
|
7363
8025
|
}
|
|
@@ -7429,8 +8091,7 @@ function issuerBindingFailureCopy(failure, options) {
|
|
|
7429
8091
|
})
|
|
7430
8092
|
};
|
|
7431
8093
|
}
|
|
7432
|
-
|
|
7433
|
-
//#region ../../core/mcp/oauthManager.ts
|
|
8094
|
+
// ../../core/mcp/oauthManager.ts
|
|
7434
8095
|
var OAuthManager = class {
|
|
7435
8096
|
params;
|
|
7436
8097
|
oauthConfig;
|
|
@@ -7913,8 +8574,7 @@ var OAuthManager = class {
|
|
|
7913
8574
|
return provider;
|
|
7914
8575
|
}
|
|
7915
8576
|
};
|
|
7916
|
-
|
|
7917
|
-
//#region ../../core/mcp/remote/types.ts
|
|
8577
|
+
// ../../core/mcp/remote/types.ts
|
|
7918
8578
|
function oauthTokensToRemoteAuthState(tokens) {
|
|
7919
8579
|
return { oauthTokens: {
|
|
7920
8580
|
access_token: tokens.access_token,
|
|
@@ -7925,8 +8585,7 @@ function oauthTokensToRemoteAuthState(tokens) {
|
|
|
7925
8585
|
id_token: tokens.id_token
|
|
7926
8586
|
} };
|
|
7927
8587
|
}
|
|
7928
|
-
|
|
7929
|
-
//#region ../../core/mcp/remote/progressToken.ts
|
|
8588
|
+
// ../../core/mcp/remote/progressToken.ts
|
|
7930
8589
|
function progressTokenOf(message) {
|
|
7931
8590
|
if ("method" in message && message.method === "notifications/progress" && "params" in message && typeof message.params === "object" && message.params !== null) {
|
|
7932
8591
|
const parsed = ProgressTokenSchema.safeParse(message.params.progressToken);
|
|
@@ -7939,8 +8598,7 @@ function waitForProgressToken(waits, token) {
|
|
|
7939
8598
|
const numeric = Number(token);
|
|
7940
8599
|
return Number.isSafeInteger(numeric) ? waits.get(numeric) : void 0;
|
|
7941
8600
|
}
|
|
7942
|
-
|
|
7943
|
-
//#region ../../core/mcp/remote/remoteClientTransport.ts
|
|
8601
|
+
// ../../core/mcp/remote/remoteClientTransport.ts
|
|
7944
8602
|
const DEFAULT_SSE_RESPONSE_TIMEOUT_MS = 6e4;
|
|
7945
8603
|
function requestIdForMessage(message) {
|
|
7946
8604
|
if ("method" in message && "id" in message && message.id !== null && message.id !== void 0) {
|
|
@@ -8084,7 +8742,8 @@ var RemoteClientTransport = class {
|
|
|
8084
8742
|
const body = {
|
|
8085
8743
|
config: this.config,
|
|
8086
8744
|
...authState && { authState },
|
|
8087
|
-
...this.options.settings && { settings: this.options.settings }
|
|
8745
|
+
...this.options.settings && { settings: this.options.settings },
|
|
8746
|
+
...this.options.serverName && { serverName: this.options.serverName }
|
|
8088
8747
|
};
|
|
8089
8748
|
const res = await this.fetchFn(`${this.baseUrl}/api/mcp/connect`, {
|
|
8090
8749
|
method: "POST",
|
|
@@ -8333,6 +8992,16 @@ var RemoteClientTransport = class {
|
|
|
8333
8992
|
}
|
|
8334
8993
|
return await res.json();
|
|
8335
8994
|
}
|
|
8995
|
+
releaseOnPageHide() {
|
|
8996
|
+
if (!this._sessionId) return false;
|
|
8997
|
+
this.fetchFn(`${this.baseUrl}/api/mcp/disconnect`, {
|
|
8998
|
+
method: "POST",
|
|
8999
|
+
headers: this.headers,
|
|
9000
|
+
body: JSON.stringify({ sessionId: this._sessionId }),
|
|
9001
|
+
keepalive: true
|
|
9002
|
+
}).catch(() => {});
|
|
9003
|
+
return true;
|
|
9004
|
+
}
|
|
8336
9005
|
async close() {
|
|
8337
9006
|
if (this.closed) return;
|
|
8338
9007
|
this.closed = true;
|
|
@@ -8360,8 +9029,25 @@ var RemoteClientTransport = class {
|
|
|
8360
9029
|
onerror;
|
|
8361
9030
|
onmessage;
|
|
8362
9031
|
};
|
|
8363
|
-
|
|
8364
|
-
|
|
9032
|
+
// ../../core/mcp/sessionTermination.ts
|
|
9033
|
+
function canTerminateSession(transport) {
|
|
9034
|
+
return typeof transport === "object" && transport !== null && "terminateSession" in transport && typeof transport.terminateSession === "function";
|
|
9035
|
+
}
|
|
9036
|
+
const SESSION_TERMINATE_TIMEOUT_MS = 3e3;
|
|
9037
|
+
async function terminateSessionBestEffort(transport, timeoutMs = SESSION_TERMINATE_TIMEOUT_MS) {
|
|
9038
|
+
if (!canTerminateSession(transport) || !transport.sessionId) return false;
|
|
9039
|
+
let timer;
|
|
9040
|
+
const timedOut = new Promise((resolve) => {
|
|
9041
|
+
timer = setTimeout(() => resolve(false), timeoutMs);
|
|
9042
|
+
});
|
|
9043
|
+
const terminated = new Promise((resolve) => resolve(transport.terminateSession())).then(() => true, () => false);
|
|
9044
|
+
try {
|
|
9045
|
+
return await Promise.race([terminated, timedOut]);
|
|
9046
|
+
} finally {
|
|
9047
|
+
clearTimeout(timer);
|
|
9048
|
+
}
|
|
9049
|
+
}
|
|
9050
|
+
// ../../core/mcp/inspectorClient.ts
|
|
8365
9051
|
const corePackageJson = {
|
|
8366
9052
|
name: "mcp-inspector",
|
|
8367
9053
|
version: "0.0.0"
|
|
@@ -8490,6 +9176,7 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
8490
9176
|
transportClientFactory;
|
|
8491
9177
|
fetchFn;
|
|
8492
9178
|
effectiveAuthFetch;
|
|
9179
|
+
fetchRefusals = [];
|
|
8493
9180
|
sessionId;
|
|
8494
9181
|
transportConfig;
|
|
8495
9182
|
directAuthRecoveryActive = null;
|
|
@@ -8525,8 +9212,9 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
8525
9212
|
resources: options.listChangedNotifications?.resources ?? true,
|
|
8526
9213
|
prompts: options.listChangedNotifications?.prompts ?? true
|
|
8527
9214
|
};
|
|
8528
|
-
const
|
|
8529
|
-
const
|
|
9215
|
+
const reportRefusal = (refusal) => this.recordFetchRefusal(refusal);
|
|
9216
|
+
const transportBase = withFetchRefusalReporting(this.fetchFn ?? fetch, reportRefusal);
|
|
9217
|
+
const oauthBase = options.environment.oauthFetch && withFetchRefusalReporting(options.environment.oauthFetch, reportRefusal);
|
|
8530
9218
|
const isMcpEndpoint = exemptMcpEndpoint(() => this.getServerUrl(), () => this.transportConfig?.type === "sse");
|
|
8531
9219
|
const getOverrides = () => this.oauthManager?.getEndpointOverrides();
|
|
8532
9220
|
const withOverrides = withOAuthEndpointOverrides(oauthBase ? routeOAuthRequests(transportBase, oauthBase, isMcpEndpoint) : transportBase, getOverrides);
|
|
@@ -9063,6 +9751,7 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
9063
9751
|
while (handlers?.size !== void 0 && handlers.size > 0 && Date.now() < deadline) await new Promise((r) => setTimeout(r, 10));
|
|
9064
9752
|
}
|
|
9065
9753
|
await this.closeTaskSessionBestEffort();
|
|
9754
|
+
await terminateSessionBestEffort(this.baseTransport);
|
|
9066
9755
|
try {
|
|
9067
9756
|
await this.client.close();
|
|
9068
9757
|
} catch {}
|
|
@@ -9105,6 +9794,14 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
9105
9794
|
this.dispatchTypedEvent("excludedToolsChange", this.excludedTools);
|
|
9106
9795
|
this.dispatchTypedEvent("malformedListItemsChange", []);
|
|
9107
9796
|
}
|
|
9797
|
+
getFetchRefusals() {
|
|
9798
|
+
return [...this.fetchRefusals];
|
|
9799
|
+
}
|
|
9800
|
+
recordFetchRefusal(refusal) {
|
|
9801
|
+
if (this.fetchRefusals.some((r) => r.url === refusal.url && r.reason === refusal.reason)) return;
|
|
9802
|
+
this.fetchRefusals = [...this.fetchRefusals, refusal].slice(-20);
|
|
9803
|
+
this.dispatchTypedEvent("fetchRefused", refusal);
|
|
9804
|
+
}
|
|
9108
9805
|
getAppRendererClient() {
|
|
9109
9806
|
if (!this.client || this.status !== "connected") return null;
|
|
9110
9807
|
return this.client;
|
|
@@ -9270,7 +9967,7 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
9270
9967
|
params: request.params,
|
|
9271
9968
|
signal: controller.signal
|
|
9272
9969
|
});
|
|
9273
|
-
this.outputValidator ??= new
|
|
9970
|
+
this.outputValidator ??= new LinearPatternJsonSchemaValidator();
|
|
9274
9971
|
const invalid = validateAppElicitResult(this.outputValidator, request.params, result);
|
|
9275
9972
|
if (invalid) {
|
|
9276
9973
|
this.logger.warn({
|
|
@@ -9869,7 +10566,7 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
9869
10566
|
});
|
|
9870
10567
|
}
|
|
9871
10568
|
validateToolOutput(tool, result) {
|
|
9872
|
-
this.outputValidator ??= new
|
|
10569
|
+
this.outputValidator ??= new LinearPatternJsonSchemaValidator();
|
|
9873
10570
|
return validateToolOutput(this.outputValidator, tool, result);
|
|
9874
10571
|
}
|
|
9875
10572
|
cancelPendingTaskInput(taskId) {
|
|
@@ -10716,6 +11413,10 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
10716
11413
|
getRemoteBackendSessionId() {
|
|
10717
11414
|
if (this.baseTransport instanceof RemoteClientTransport) return this.baseTransport.getRemoteBackendSessionId();
|
|
10718
11415
|
}
|
|
11416
|
+
releaseRemoteSessionOnPageHide() {
|
|
11417
|
+
if (this.baseTransport instanceof RemoteClientTransport) return this.baseTransport.releaseOnPageHide();
|
|
11418
|
+
return false;
|
|
11419
|
+
}
|
|
10719
11420
|
async resumeAfterOAuth(authorizationCode, options) {
|
|
10720
11421
|
await this.completeOAuthFlow(authorizationCode, options?.iss, options?.state);
|
|
10721
11422
|
const remoteSessionId = options?.remoteSessionId;
|
|
@@ -10753,8 +11454,7 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
10753
11454
|
return this.oauthManager.getOAuthState();
|
|
10754
11455
|
}
|
|
10755
11456
|
};
|
|
10756
|
-
|
|
10757
|
-
//#region ../../core/mcp/state/managedListState.ts
|
|
11457
|
+
// ../../core/mcp/state/managedListState.ts
|
|
10758
11458
|
var ManagedListState = class extends TypedEventTarget {
|
|
10759
11459
|
items = [];
|
|
10760
11460
|
client = null;
|
|
@@ -10899,8 +11599,7 @@ var ManagedListState = class extends TypedEventTarget {
|
|
|
10899
11599
|
this.loaded = false;
|
|
10900
11600
|
}
|
|
10901
11601
|
};
|
|
10902
|
-
|
|
10903
|
-
//#region ../../core/mcp/state/managedToolsState.ts
|
|
11602
|
+
// ../../core/mcp/state/managedToolsState.ts
|
|
10904
11603
|
var ManagedToolsState = class extends ManagedListState {
|
|
10905
11604
|
constructor(client, debounceMs = 250) {
|
|
10906
11605
|
super(client, {
|
|
@@ -10923,8 +11622,7 @@ var ManagedToolsState = class extends ManagedListState {
|
|
|
10923
11622
|
return this.getItems();
|
|
10924
11623
|
}
|
|
10925
11624
|
};
|
|
10926
|
-
|
|
10927
|
-
//#region ../../core/mcp/state/messageLogState.ts
|
|
11625
|
+
// ../../core/mcp/state/messageLogState.ts
|
|
10928
11626
|
var MessageLogState = class extends TypedEventTarget {
|
|
10929
11627
|
messages = [];
|
|
10930
11628
|
pendingRequestEntries = /* @__PURE__ */ new Map();
|
|
@@ -10941,6 +11639,16 @@ var MessageLogState = class extends TypedEventTarget {
|
|
|
10941
11639
|
this.dispatchTypedEvent("message", entry);
|
|
10942
11640
|
this.dispatchTypedEvent("messagesChange", this.getMessages());
|
|
10943
11641
|
};
|
|
11642
|
+
const replaceEntry = (entry, changes) => {
|
|
11643
|
+
const index = this.messages.lastIndexOf(entry);
|
|
11644
|
+
if (index < 0) return void 0;
|
|
11645
|
+
const updated = {
|
|
11646
|
+
...entry,
|
|
11647
|
+
...changes
|
|
11648
|
+
};
|
|
11649
|
+
this.messages[index] = updated;
|
|
11650
|
+
return updated;
|
|
11651
|
+
};
|
|
10944
11652
|
const onMessage = (event) => {
|
|
10945
11653
|
const entry = event.detail;
|
|
10946
11654
|
if (entry.direction === "request") {
|
|
@@ -10954,9 +11662,12 @@ var MessageLogState = class extends TypedEventTarget {
|
|
|
10954
11662
|
const requestEntry = messageId !== void 0 ? this.pendingRequestEntries.get(messageId) : void 0;
|
|
10955
11663
|
if (requestEntry) {
|
|
10956
11664
|
this.pendingRequestEntries.delete(messageId);
|
|
10957
|
-
|
|
10958
|
-
|
|
10959
|
-
|
|
11665
|
+
const updated = replaceEntry(requestEntry, {
|
|
11666
|
+
response: entry.message,
|
|
11667
|
+
duration: entry.timestamp.getTime() - requestEntry.timestamp.getTime()
|
|
11668
|
+
});
|
|
11669
|
+
if (!updated) return;
|
|
11670
|
+
this.dispatchTypedEvent("message", updated);
|
|
10960
11671
|
this.dispatchTypedEvent("messagesChange", this.getMessages());
|
|
10961
11672
|
return;
|
|
10962
11673
|
}
|
|
@@ -10970,8 +11681,12 @@ var MessageLogState = class extends TypedEventTarget {
|
|
|
10970
11681
|
if (entry.message.id !== id) continue;
|
|
10971
11682
|
if (entry.direction === "notification") continue;
|
|
10972
11683
|
if (entry.direction === "request" && !entry.response) continue;
|
|
10973
|
-
|
|
10974
|
-
|
|
11684
|
+
const updated = {
|
|
11685
|
+
...entry,
|
|
11686
|
+
clientError: reason
|
|
11687
|
+
};
|
|
11688
|
+
this.messages[i] = updated;
|
|
11689
|
+
this.dispatchTypedEvent("message", updated);
|
|
10975
11690
|
this.dispatchTypedEvent("messagesChange", this.getMessages());
|
|
10976
11691
|
return;
|
|
10977
11692
|
}
|
|
@@ -10981,9 +11696,12 @@ var MessageLogState = class extends TypedEventTarget {
|
|
|
10981
11696
|
const requestEntry = this.pendingRequestEntries.get(id);
|
|
10982
11697
|
if (!requestEntry) return;
|
|
10983
11698
|
this.pendingRequestEntries.delete(id);
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
|
|
11699
|
+
const updated = replaceEntry(requestEntry, {
|
|
11700
|
+
clientError: reason,
|
|
11701
|
+
duration: Date.now() - requestEntry.timestamp.getTime()
|
|
11702
|
+
});
|
|
11703
|
+
if (!updated) return;
|
|
11704
|
+
this.dispatchTypedEvent("message", updated);
|
|
10987
11705
|
this.dispatchTypedEvent("messagesChange", this.getMessages());
|
|
10988
11706
|
};
|
|
10989
11707
|
const onStatusChange = () => {
|
|
@@ -11027,8 +11745,7 @@ var MessageLogState = class extends TypedEventTarget {
|
|
|
11027
11745
|
this.pendingRequestEntries.clear();
|
|
11028
11746
|
}
|
|
11029
11747
|
};
|
|
11030
|
-
|
|
11031
|
-
//#region ../../core/mcp/state/fetchRequestLogState.ts
|
|
11748
|
+
// ../../core/mcp/state/fetchRequestLogState.ts
|
|
11032
11749
|
var FetchRequestLogState = class extends TypedEventTarget {
|
|
11033
11750
|
fetchRequests = [];
|
|
11034
11751
|
client = null;
|
|
@@ -11147,8 +11864,7 @@ var FetchRequestLogState = class extends TypedEventTarget {
|
|
|
11147
11864
|
this.fetchRequests = [];
|
|
11148
11865
|
}
|
|
11149
11866
|
};
|
|
11150
|
-
|
|
11151
|
-
//#region ../../core/mcp/state/stderrLogState.ts
|
|
11867
|
+
// ../../core/mcp/state/stderrLogState.ts
|
|
11152
11868
|
var StderrLogState = class extends TypedEventTarget {
|
|
11153
11869
|
stderrLogs = [];
|
|
11154
11870
|
client = null;
|
|
@@ -11185,8 +11901,7 @@ var StderrLogState = class extends TypedEventTarget {
|
|
|
11185
11901
|
this.stderrLogs = [];
|
|
11186
11902
|
}
|
|
11187
11903
|
};
|
|
11188
|
-
|
|
11189
|
-
//#region ../../core/mcp/state/managedResourcesState.ts
|
|
11904
|
+
// ../../core/mcp/state/managedResourcesState.ts
|
|
11190
11905
|
var ManagedResourcesState = class extends ManagedListState {
|
|
11191
11906
|
constructor(client, debounceMs = 250) {
|
|
11192
11907
|
super(client, {
|
|
@@ -11209,8 +11924,7 @@ var ManagedResourcesState = class extends ManagedListState {
|
|
|
11209
11924
|
return this.getItems();
|
|
11210
11925
|
}
|
|
11211
11926
|
};
|
|
11212
|
-
|
|
11213
|
-
//#region ../../core/mcp/state/managedResourceTemplatesState.ts
|
|
11927
|
+
// ../../core/mcp/state/managedResourceTemplatesState.ts
|
|
11214
11928
|
var ManagedResourceTemplatesState = class extends ManagedListState {
|
|
11215
11929
|
constructor(client, debounceMs = 250) {
|
|
11216
11930
|
super(client, {
|
|
@@ -11233,8 +11947,7 @@ var ManagedResourceTemplatesState = class extends ManagedListState {
|
|
|
11233
11947
|
return this.getItems();
|
|
11234
11948
|
}
|
|
11235
11949
|
};
|
|
11236
|
-
|
|
11237
|
-
//#region ../../core/mcp/state/managedPromptsState.ts
|
|
11950
|
+
// ../../core/mcp/state/managedPromptsState.ts
|
|
11238
11951
|
var ManagedPromptsState = class extends ManagedListState {
|
|
11239
11952
|
constructor(client, debounceMs = 250) {
|
|
11240
11953
|
super(client, {
|
|
@@ -11257,8 +11970,7 @@ var ManagedPromptsState = class extends ManagedListState {
|
|
|
11257
11970
|
return this.getItems();
|
|
11258
11971
|
}
|
|
11259
11972
|
};
|
|
11260
|
-
|
|
11261
|
-
//#region ../../core/mcp/state/mergeTaskIntoList.ts
|
|
11973
|
+
// ../../core/mcp/state/mergeTaskIntoList.ts
|
|
11262
11974
|
function mergeTaskIntoList(tasks, taskId, task) {
|
|
11263
11975
|
const normalized = {
|
|
11264
11976
|
...task,
|
|
@@ -11271,8 +11983,7 @@ function mergeTaskIntoList(tasks, taskId, task) {
|
|
|
11271
11983
|
next[idx] = normalized;
|
|
11272
11984
|
return next;
|
|
11273
11985
|
}
|
|
11274
|
-
|
|
11275
|
-
//#region ../../core/mcp/state/managedRequestorTasksState.ts
|
|
11986
|
+
// ../../core/mcp/state/managedRequestorTasksState.ts
|
|
11276
11987
|
const MAX_PAGES = 100;
|
|
11277
11988
|
const TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
11278
11989
|
"completed",
|
|
@@ -11407,8 +12118,7 @@ var ManagedRequestorTasksState = class extends TypedEventTarget {
|
|
|
11407
12118
|
this.cancelledTaskIds.clear();
|
|
11408
12119
|
}
|
|
11409
12120
|
};
|
|
11410
|
-
|
|
11411
|
-
//#region ../../core/mcp/state/resourceSubscriptionsState.ts
|
|
12121
|
+
// ../../core/mcp/state/resourceSubscriptionsState.ts
|
|
11412
12122
|
var ResourceSubscriptionsState = class extends TypedEventTarget {
|
|
11413
12123
|
subscribedUris = [];
|
|
11414
12124
|
lastUpdatedByUri = /* @__PURE__ */ new Map();
|
|
@@ -11497,8 +12207,7 @@ var ResourceSubscriptionsState = class extends TypedEventTarget {
|
|
|
11497
12207
|
this.streamState = INACTIVE_SUBSCRIPTION_STREAM_STATE;
|
|
11498
12208
|
}
|
|
11499
12209
|
};
|
|
11500
|
-
|
|
11501
|
-
//#region ../../core/mcp/state/managedSkillsState.ts
|
|
12210
|
+
// ../../core/mcp/state/managedSkillsState.ts
|
|
11502
12211
|
const REPEATED_CURSOR_MESSAGE = "Server repeated a pagination cursor in skills/list; stopped to avoid an infinite walk.";
|
|
11503
12212
|
const SKILLS_MAX_PAGES = 64;
|
|
11504
12213
|
const SKILLS_PAGE_LIMIT_MESSAGE = `skills/list exceeded ${SKILLS_MAX_PAGES} pages without the server's pagination converging`;
|
|
@@ -11607,17 +12316,45 @@ var ManagedSkillsState = class extends TypedEventTarget {
|
|
|
11607
12316
|
this.error = null;
|
|
11608
12317
|
}
|
|
11609
12318
|
};
|
|
11610
|
-
|
|
11611
|
-
|
|
11612
|
-
|
|
12319
|
+
// ../../core/react/notifyScheduler.ts
|
|
12320
|
+
function coalesce(onChange, schedule) {
|
|
12321
|
+
let cancelPending = null;
|
|
12322
|
+
return {
|
|
12323
|
+
notify: () => {
|
|
12324
|
+
if (cancelPending) return;
|
|
12325
|
+
cancelPending = schedule(() => {
|
|
12326
|
+
cancelPending = null;
|
|
12327
|
+
onChange();
|
|
12328
|
+
});
|
|
12329
|
+
},
|
|
12330
|
+
cancel: () => {
|
|
12331
|
+
cancelPending?.();
|
|
12332
|
+
cancelPending = null;
|
|
12333
|
+
}
|
|
12334
|
+
};
|
|
12335
|
+
}
|
|
12336
|
+
// ../../core/react/useStoreSnapshot.ts
|
|
12337
|
+
function useStoreSnapshot(store, event, read, whenAbsent, schedule) {
|
|
11613
12338
|
const cache = useRef(null);
|
|
11614
12339
|
const subscribe = useCallback((onStoreChange) => {
|
|
11615
12340
|
if (!store) return () => {};
|
|
11616
|
-
|
|
12341
|
+
if (!schedule) {
|
|
12342
|
+
store.addEventListener(event, onStoreChange);
|
|
12343
|
+
return () => {
|
|
12344
|
+
store.removeEventListener(event, onStoreChange);
|
|
12345
|
+
};
|
|
12346
|
+
}
|
|
12347
|
+
const { notify, cancel } = coalesce(onStoreChange, schedule);
|
|
12348
|
+
store.addEventListener(event, notify);
|
|
11617
12349
|
return () => {
|
|
11618
|
-
store.removeEventListener(event,
|
|
12350
|
+
store.removeEventListener(event, notify);
|
|
12351
|
+
cancel();
|
|
11619
12352
|
};
|
|
11620
|
-
}, [
|
|
12353
|
+
}, [
|
|
12354
|
+
store,
|
|
12355
|
+
event,
|
|
12356
|
+
schedule
|
|
12357
|
+
]);
|
|
11621
12358
|
const getSnapshot = useCallback(() => {
|
|
11622
12359
|
const revision = store ? store.getEventRevision(event) : 0;
|
|
11623
12360
|
const cached = cache.current;
|
|
@@ -11640,8 +12377,7 @@ function useStoreSnapshot(store, event, read, whenAbsent) {
|
|
|
11640
12377
|
]);
|
|
11641
12378
|
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
11642
12379
|
}
|
|
11643
|
-
|
|
11644
|
-
//#region ../../core/react/useInspectorClient.ts
|
|
12380
|
+
// ../../core/react/useInspectorClient.ts
|
|
11645
12381
|
const EMPTY_CLIENT_CAPABILITIES = Object.freeze({});
|
|
11646
12382
|
const NO_EXCLUDED_TOOLS = [];
|
|
11647
12383
|
const NO_MALFORMED_LIST_ITEMS = [];
|
|
@@ -11659,7 +12395,7 @@ const readDiscoverResult = (client) => client.getDiscoverResult();
|
|
|
11659
12395
|
const readExcludedTools = (client) => client.getExcludedTools();
|
|
11660
12396
|
const readMalformedListItems = (client) => client.getMalformedListItems();
|
|
11661
12397
|
const readConnectionDiagnostics = (client) => client.getConnectionDiagnostics?.() ?? NO_CONNECTION_DIAGNOSTICS;
|
|
11662
|
-
function useInspectorClient(inspectorClient) {
|
|
12398
|
+
function useInspectorClient(inspectorClient, diagnosticsSchedule) {
|
|
11663
12399
|
const status = useStoreSnapshot(inspectorClient, "statusChange", readStatus, "disconnected");
|
|
11664
12400
|
const capabilities = useStoreSnapshot(inspectorClient, "capabilitiesChange", readCapabilities, void 0);
|
|
11665
12401
|
const serverInfo = useStoreSnapshot(inspectorClient, "serverInfoChange", readServerInfo, void 0);
|
|
@@ -11669,7 +12405,7 @@ function useInspectorClient(inspectorClient) {
|
|
|
11669
12405
|
const discoverResult = useStoreSnapshot(inspectorClient, "discoverResultChange", readDiscoverResult, void 0);
|
|
11670
12406
|
const excludedTools = useStoreSnapshot(inspectorClient, "excludedToolsChange", readExcludedTools, NO_EXCLUDED_TOOLS);
|
|
11671
12407
|
const malformedListItems = useStoreSnapshot(inspectorClient, "malformedListItemsChange", readMalformedListItems, NO_MALFORMED_LIST_ITEMS);
|
|
11672
|
-
const connectionDiagnostics = useStoreSnapshot(inspectorClient, "connectionDiagnosticsChange", readConnectionDiagnostics, NO_CONNECTION_DIAGNOSTICS);
|
|
12408
|
+
const connectionDiagnostics = useStoreSnapshot(inspectorClient, "connectionDiagnosticsChange", readConnectionDiagnostics, NO_CONNECTION_DIAGNOSTICS, diagnosticsSchedule);
|
|
11673
12409
|
const [errorState, setErrorState] = useState({ client: inspectorClient });
|
|
11674
12410
|
if (errorState.client !== inspectorClient) setErrorState({ client: inspectorClient });
|
|
11675
12411
|
const lastError = errorState.client === inspectorClient ? errorState.message : void 0;
|
|
@@ -11717,8 +12453,7 @@ function useInspectorClient(inspectorClient) {
|
|
|
11717
12453
|
disconnect
|
|
11718
12454
|
};
|
|
11719
12455
|
}
|
|
11720
|
-
|
|
11721
|
-
//#region ../../core/react/useListError.ts
|
|
12456
|
+
// ../../core/react/useListError.ts
|
|
11722
12457
|
function useListError(state) {
|
|
11723
12458
|
const subscribe = useCallback((onStoreChange) => {
|
|
11724
12459
|
if (!state) return () => {};
|
|
@@ -11731,8 +12466,7 @@ function useListError(state) {
|
|
|
11731
12466
|
const getSnapshot = useCallback(() => state?.getError() ?? null, [state]);
|
|
11732
12467
|
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
11733
12468
|
}
|
|
11734
|
-
|
|
11735
|
-
//#region ../../core/react/useManagedTools.ts
|
|
12469
|
+
// ../../core/react/useManagedTools.ts
|
|
11736
12470
|
const NO_TOOLS = [];
|
|
11737
12471
|
const readTools = (state) => state.getTools();
|
|
11738
12472
|
const readListChanged$2 = (state) => state.getListChanged();
|
|
@@ -11756,8 +12490,18 @@ function useManagedTools(client, managedToolsState) {
|
|
|
11756
12490
|
}, [managedToolsState])
|
|
11757
12491
|
};
|
|
11758
12492
|
}
|
|
11759
|
-
|
|
11760
|
-
|
|
12493
|
+
// ../../core/mcp/toolOrder.ts
|
|
12494
|
+
const toolLabelCollator = new Intl.Collator(void 0, {
|
|
12495
|
+
sensitivity: "base",
|
|
12496
|
+
numeric: true
|
|
12497
|
+
});
|
|
12498
|
+
function compareToolLabels(a, b) {
|
|
12499
|
+
return toolLabelCollator.compare(a, b);
|
|
12500
|
+
}
|
|
12501
|
+
function compareToolsByName(a, b) {
|
|
12502
|
+
return compareToolLabels(a.name, b.name);
|
|
12503
|
+
}
|
|
12504
|
+
// ../../core/react/useManagedResources.ts
|
|
11761
12505
|
const NO_RESOURCES = [];
|
|
11762
12506
|
const readResources = (state) => state.getResources();
|
|
11763
12507
|
const readListChanged$1 = (state) => state.getListChanged();
|
|
@@ -11781,8 +12525,7 @@ function useManagedResources(client, managedResourcesState) {
|
|
|
11781
12525
|
}, [managedResourcesState])
|
|
11782
12526
|
};
|
|
11783
12527
|
}
|
|
11784
|
-
|
|
11785
|
-
//#region ../../core/react/useManagedResourceTemplates.ts
|
|
12528
|
+
// ../../core/react/useManagedResourceTemplates.ts
|
|
11786
12529
|
const NO_RESOURCE_TEMPLATES = [];
|
|
11787
12530
|
const readResourceTemplates = (state) => state.getResourceTemplates();
|
|
11788
12531
|
function useManagedResourceTemplates(client, managedResourceTemplatesState) {
|
|
@@ -11795,8 +12538,7 @@ function useManagedResourceTemplates(client, managedResourceTemplatesState) {
|
|
|
11795
12538
|
}, [client, managedResourceTemplatesState])
|
|
11796
12539
|
};
|
|
11797
12540
|
}
|
|
11798
|
-
|
|
11799
|
-
//#region ../../core/react/useManagedPrompts.ts
|
|
12541
|
+
// ../../core/react/useManagedPrompts.ts
|
|
11800
12542
|
const NO_PROMPTS = [];
|
|
11801
12543
|
const readPrompts = (state) => state.getPrompts();
|
|
11802
12544
|
const readListChanged = (state) => state.getListChanged();
|
|
@@ -11820,8 +12562,7 @@ function useManagedPrompts(client, managedPromptsState) {
|
|
|
11820
12562
|
}, [managedPromptsState])
|
|
11821
12563
|
};
|
|
11822
12564
|
}
|
|
11823
|
-
|
|
11824
|
-
//#region ../../core/react/useManagedSkills.ts
|
|
12565
|
+
// ../../core/react/useManagedSkills.ts
|
|
11825
12566
|
const NO_SKILLS = [];
|
|
11826
12567
|
const NO_SKILLS_PAGINATION = Object.freeze({ pageCount: 0 });
|
|
11827
12568
|
const readSkills = (state) => state.getSkills();
|
|
@@ -11839,29 +12580,25 @@ function useManagedSkills(client, managedSkillsState) {
|
|
|
11839
12580
|
}, [client, managedSkillsState])
|
|
11840
12581
|
};
|
|
11841
12582
|
}
|
|
11842
|
-
|
|
11843
|
-
//#region ../../core/react/useMessageLog.ts
|
|
12583
|
+
// ../../core/react/useMessageLog.ts
|
|
11844
12584
|
const NO_MESSAGES = [];
|
|
11845
12585
|
const readMessages = (state) => state.getMessages();
|
|
11846
|
-
function useMessageLog(messageLogState) {
|
|
11847
|
-
return { messages: useStoreSnapshot(messageLogState, "messagesChange", readMessages, NO_MESSAGES) };
|
|
12586
|
+
function useMessageLog(messageLogState, schedule) {
|
|
12587
|
+
return { messages: useStoreSnapshot(messageLogState, "messagesChange", readMessages, NO_MESSAGES, schedule) };
|
|
11848
12588
|
}
|
|
11849
|
-
|
|
11850
|
-
//#region ../../core/react/useFetchRequestLog.ts
|
|
12589
|
+
// ../../core/react/useFetchRequestLog.ts
|
|
11851
12590
|
const NO_FETCH_REQUESTS = [];
|
|
11852
12591
|
const readFetchRequests = (state) => state.getFetchRequests();
|
|
11853
|
-
function useFetchRequestLog(fetchRequestLogState) {
|
|
11854
|
-
return { fetchRequests: useStoreSnapshot(fetchRequestLogState, "fetchRequestsChange", readFetchRequests, NO_FETCH_REQUESTS) };
|
|
12592
|
+
function useFetchRequestLog(fetchRequestLogState, schedule) {
|
|
12593
|
+
return { fetchRequests: useStoreSnapshot(fetchRequestLogState, "fetchRequestsChange", readFetchRequests, NO_FETCH_REQUESTS, schedule) };
|
|
11855
12594
|
}
|
|
11856
|
-
|
|
11857
|
-
//#region ../../core/react/useStderrLog.ts
|
|
12595
|
+
// ../../core/react/useStderrLog.ts
|
|
11858
12596
|
const NO_STDERR_LOGS = [];
|
|
11859
12597
|
const readStderrLogs = (state) => state.getStderrLogs();
|
|
11860
|
-
function useStderrLog(stderrLogState) {
|
|
11861
|
-
return { stderrLogs: useStoreSnapshot(stderrLogState, "stderrLogsChange", readStderrLogs, NO_STDERR_LOGS) };
|
|
12598
|
+
function useStderrLog(stderrLogState, schedule) {
|
|
12599
|
+
return { stderrLogs: useStoreSnapshot(stderrLogState, "stderrLogsChange", readStderrLogs, NO_STDERR_LOGS, schedule) };
|
|
11862
12600
|
}
|
|
11863
|
-
|
|
11864
|
-
//#region ../../core/react/useManagedRequestorTasks.ts
|
|
12601
|
+
// ../../core/react/useManagedRequestorTasks.ts
|
|
11865
12602
|
const NO_TASKS = [];
|
|
11866
12603
|
const readTasks = (state) => state.getTasks();
|
|
11867
12604
|
function useManagedRequestorTasks(client, managedRequestorTasksState) {
|
|
@@ -11876,8 +12613,7 @@ function useManagedRequestorTasks(client, managedRequestorTasksState) {
|
|
|
11876
12613
|
}, [managedRequestorTasksState])
|
|
11877
12614
|
};
|
|
11878
12615
|
}
|
|
11879
|
-
|
|
11880
|
-
//#region ../../core/react/useResourceSubscriptions.ts
|
|
12616
|
+
// ../../core/react/useResourceSubscriptions.ts
|
|
11881
12617
|
const NO_SUBSCRIPTIONS = [];
|
|
11882
12618
|
const readSubscriptions = (state) => state.getSubscriptions();
|
|
11883
12619
|
const readStreamState = (state) => state.getStreamState();
|
|
@@ -11887,8 +12623,18 @@ function useResourceSubscriptions(state) {
|
|
|
11887
12623
|
streamState: useStoreSnapshot(state, "streamStateChange", readStreamState, INACTIVE_SUBSCRIPTION_STREAM_STATE)
|
|
11888
12624
|
};
|
|
11889
12625
|
}
|
|
11890
|
-
|
|
11891
|
-
|
|
12626
|
+
// ../../core/react/usePendingClientRequests.ts
|
|
12627
|
+
const NO_SAMPLES = [];
|
|
12628
|
+
const NO_ELICITATIONS = [];
|
|
12629
|
+
const readPendingSamples = (client) => client.getPendingSamples();
|
|
12630
|
+
const readPendingElicitations = (client) => client.getPendingElicitations();
|
|
12631
|
+
function usePendingClientRequests(inspectorClient) {
|
|
12632
|
+
return {
|
|
12633
|
+
pendingSamples: useStoreSnapshot(inspectorClient, "pendingSamplesChange", readPendingSamples, NO_SAMPLES),
|
|
12634
|
+
pendingElicitations: useStoreSnapshot(inspectorClient, "pendingElicitationsChange", readPendingElicitations, NO_ELICITATIONS)
|
|
12635
|
+
};
|
|
12636
|
+
}
|
|
12637
|
+
// ../../core/auth/issuerBinding.ts
|
|
11892
12638
|
const MISSING_DISCOVERY_STATE_PHRASE = "discoveryState was not available";
|
|
11893
12639
|
function isAuthorizationServerMismatchShape(err) {
|
|
11894
12640
|
if (err === null || typeof err !== "object") return false;
|
|
@@ -11928,8 +12674,7 @@ function classifyAuthorizationServerMismatch(err) {
|
|
|
11928
12674
|
currentIssuer: err.currentIssuer
|
|
11929
12675
|
};
|
|
11930
12676
|
}
|
|
11931
|
-
|
|
11932
|
-
//#region ../../core/auth/oauth-storage.ts
|
|
12677
|
+
// ../../core/auth/oauth-storage.ts
|
|
11933
12678
|
function withIssuer(value, issuer) {
|
|
11934
12679
|
return issuer === void 0 ? value : {
|
|
11935
12680
|
...value,
|
|
@@ -12206,8 +12951,7 @@ var OAuthStorageBase = class {
|
|
|
12206
12951
|
await this.persist({ servers });
|
|
12207
12952
|
}
|
|
12208
12953
|
};
|
|
12209
|
-
|
|
12210
|
-
//#region ../../core/auth/store.ts
|
|
12954
|
+
// ../../core/auth/store.ts
|
|
12211
12955
|
var OAuthMemoryStore = class {
|
|
12212
12956
|
servers = {};
|
|
12213
12957
|
idpSessions = {};
|
|
@@ -12270,8 +13014,7 @@ var OAuthMemoryStore = class {
|
|
|
12270
13014
|
this.idpSessions = { ...snapshot.idpSessions ?? {} };
|
|
12271
13015
|
}
|
|
12272
13016
|
};
|
|
12273
|
-
|
|
12274
|
-
//#region ../../core/auth/oauth-persist.ts
|
|
13017
|
+
// ../../core/auth/oauth-persist.ts
|
|
12275
13018
|
function mergeOAuthSections(disk, snapshot, sections) {
|
|
12276
13019
|
const merged = {
|
|
12277
13020
|
servers: { ...disk?.servers },
|
|
@@ -12336,8 +13079,7 @@ function parseOAuthPersistBlob(raw) {
|
|
|
12336
13079
|
function serializeOAuthPersistBlob(snapshot) {
|
|
12337
13080
|
return serializeStore(snapshot);
|
|
12338
13081
|
}
|
|
12339
|
-
|
|
12340
|
-
//#region ../../core/auth/node/oauth-secrets.ts
|
|
13082
|
+
// ../../core/auth/node/oauth-secrets.ts
|
|
12341
13083
|
const PERSIST_TOKENS_ENV = "MCP_INSPECTOR_PERSIST_TOKENS";
|
|
12342
13084
|
const warnedPolicyValues = /* @__PURE__ */ new Set();
|
|
12343
13085
|
function getPersistTokensPolicy(env = process.env) {
|
|
@@ -12607,8 +13349,7 @@ function snapshotHasPlaintextSecrets(snapshot) {
|
|
|
12607
13349
|
for (const session of Object.values(snapshot.idpSessions)) if (session.idToken !== void 0 || session.refreshToken !== void 0) return true;
|
|
12608
13350
|
return false;
|
|
12609
13351
|
}
|
|
12610
|
-
|
|
12611
|
-
//#region ../../core/auth/node/oauth-namespace-ledger.ts
|
|
13352
|
+
// ../../core/auth/node/oauth-namespace-ledger.ts
|
|
12612
13353
|
const namespaceLedgerPath = (stateFilePath) => `${stateFilePath}.namespaces.json`;
|
|
12613
13354
|
const KEYRING_LOCATION = "keyring";
|
|
12614
13355
|
const FILE_LOCATION_PREFIX = "file:";
|
|
@@ -12866,8 +13607,7 @@ async function purgeSupersededNamespaces(stateFilePath, secretStore, current, ow
|
|
|
12866
13607
|
warnLedgerFailure("update", error);
|
|
12867
13608
|
}
|
|
12868
13609
|
}
|
|
12869
|
-
|
|
12870
|
-
//#region ../../core/auth/node/oauth-persist-file.ts
|
|
13610
|
+
// ../../core/auth/node/oauth-persist-file.ts
|
|
12871
13611
|
const warnedStoreFailures = /* @__PURE__ */ new Set();
|
|
12872
13612
|
function warnStoreWriteFailure(error) {
|
|
12873
13613
|
const reason = error instanceof Error ? error.message : String(error);
|
|
@@ -13413,8 +14153,7 @@ function createFileOAuthPersistBackend(options) {
|
|
|
13413
14153
|
}
|
|
13414
14154
|
};
|
|
13415
14155
|
}
|
|
13416
|
-
|
|
13417
|
-
//#region ../../core/auth/node/storage-node.ts
|
|
14156
|
+
// ../../core/auth/node/storage-node.ts
|
|
13418
14157
|
const DEFAULT_STATE_PATH = getStoreFilePath(getDefaultStorageDir(), "oauth");
|
|
13419
14158
|
function getStateFilePath(customPath) {
|
|
13420
14159
|
if (customPath) return customPath;
|
|
@@ -13445,25 +14184,41 @@ var NodeOAuthStorage = class extends OAuthStorageBase {
|
|
|
13445
14184
|
}), shared.coordination);
|
|
13446
14185
|
}
|
|
13447
14186
|
};
|
|
13448
|
-
|
|
13449
|
-
//#region ../../core/auth/node/oauth-callback-server.ts
|
|
14187
|
+
// ../../core/auth/node/oauth-callback-server.ts
|
|
13450
14188
|
const DEFAULT_HOSTNAME = "127.0.0.1";
|
|
13451
14189
|
const DEFAULT_CALLBACK_PATH = "/oauth/callback";
|
|
13452
|
-
const SUCCESS_HTML =
|
|
13453
|
-
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
|
|
13457
|
-
function errorHtml(
|
|
14190
|
+
const SUCCESS_HTML = page("OAuth complete", "OAuth complete. You can close this window.");
|
|
14191
|
+
const NOT_CALLBACK_HTML = page("Not the OAuth callback", "This address is not the OAuth callback the Inspector is waiting for. Sign-in has not finished; return to the Inspector to continue.");
|
|
14192
|
+
const STATE_MISMATCH_HTML = page("OAuth callback ignored", "This callback does not belong to the sign-in in progress and was ignored. Sign-in has not finished; the Inspector is still waiting for the authorization server.");
|
|
14193
|
+
const ALREADY_HANDLED_HTML = page("OAuth callback already received", "This sign-in has already received its callback. You can close this window.");
|
|
14194
|
+
const STOPPED_HTML = page("OAuth callback not expected", "The Inspector is no longer waiting for this sign-in. Start sign-in again from the Inspector.");
|
|
14195
|
+
function errorHtml(serverText) {
|
|
14196
|
+
return page("OAuth error", `OAuth failed. The authorization server said: ${serverText}`);
|
|
14197
|
+
}
|
|
14198
|
+
function exchangeErrorHtml(message) {
|
|
14199
|
+
return page("OAuth error", `OAuth failed: ${message}`);
|
|
14200
|
+
}
|
|
14201
|
+
function page(title, text) {
|
|
13458
14202
|
return `<!DOCTYPE html>
|
|
13459
14203
|
<html>
|
|
13460
|
-
<head><meta charset="utf-8"><title
|
|
13461
|
-
<body><p
|
|
14204
|
+
<head><meta charset="utf-8"><title>${escapeHtml(title)}</title></head>
|
|
14205
|
+
<body><p>${escapeHtml(text)}</p></body>
|
|
13462
14206
|
</html>`;
|
|
13463
14207
|
}
|
|
13464
14208
|
function escapeHtml(s) {
|
|
13465
14209
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
13466
14210
|
}
|
|
14211
|
+
const ANY_STATE = Symbol("any-state");
|
|
14212
|
+
const STOPPED = Symbol("stopped");
|
|
14213
|
+
function createStopSignal() {
|
|
14214
|
+
let fire;
|
|
14215
|
+
return {
|
|
14216
|
+
stopped: new Promise((resolve) => {
|
|
14217
|
+
fire = () => resolve(STOPPED);
|
|
14218
|
+
}),
|
|
14219
|
+
fire
|
|
14220
|
+
};
|
|
14221
|
+
}
|
|
13467
14222
|
var OAuthCallbackServer = class {
|
|
13468
14223
|
server = null;
|
|
13469
14224
|
port = 0;
|
|
@@ -13471,6 +14226,8 @@ var OAuthCallbackServer = class {
|
|
|
13471
14226
|
handled = false;
|
|
13472
14227
|
onCallback;
|
|
13473
14228
|
onError;
|
|
14229
|
+
expectedState = Promise.resolve(ANY_STATE);
|
|
14230
|
+
stopSignal = createStopSignal();
|
|
13474
14231
|
async start(options = {}) {
|
|
13475
14232
|
const { port = 0, hostname = DEFAULT_HOSTNAME, path = DEFAULT_CALLBACK_PATH, onCallback, onError } = options;
|
|
13476
14233
|
if (!path.startsWith("/")) return Promise.reject(/* @__PURE__ */ new Error("Callback path must start with '/' (absolute path)"));
|
|
@@ -13478,6 +14235,8 @@ var OAuthCallbackServer = class {
|
|
|
13478
14235
|
this.onError = onError;
|
|
13479
14236
|
this.handled = false;
|
|
13480
14237
|
this.callbackPath = path;
|
|
14238
|
+
this.stopSignal = createStopSignal();
|
|
14239
|
+
this.expectedState = "expectedState" in options ? Promise.race([Promise.resolve(options.expectedState).catch(() => STOPPED), this.stopSignal.stopped]) : Promise.resolve(ANY_STATE);
|
|
13481
14240
|
return new Promise((resolve, reject) => {
|
|
13482
14241
|
this.server = createServer((req, res) => this.handleRequest(req, res));
|
|
13483
14242
|
this.server.on("error", reject);
|
|
@@ -13501,6 +14260,7 @@ var OAuthCallbackServer = class {
|
|
|
13501
14260
|
}
|
|
13502
14261
|
async stop() {
|
|
13503
14262
|
if (!this.server) return;
|
|
14263
|
+
this.stopSignal.fire();
|
|
13504
14264
|
await new Promise((resolve) => {
|
|
13505
14265
|
this.server.close(() => resolve());
|
|
13506
14266
|
});
|
|
@@ -13509,11 +14269,14 @@ var OAuthCallbackServer = class {
|
|
|
13509
14269
|
handleRequest(req, res) {
|
|
13510
14270
|
const needJson = req.headers["accept"]?.includes("application/json");
|
|
13511
14271
|
const send = (status, body, contentType = "text/html; charset=utf-8") => {
|
|
13512
|
-
res.writeHead(status, {
|
|
14272
|
+
res.writeHead(status, {
|
|
14273
|
+
"Content-Type": contentType,
|
|
14274
|
+
Connection: "close"
|
|
14275
|
+
});
|
|
13513
14276
|
res.end(body);
|
|
13514
14277
|
};
|
|
13515
14278
|
if (req.method !== "GET") {
|
|
13516
|
-
send(405, needJson ? "{\"error\":\"Method Not Allowed\"}" :
|
|
14279
|
+
send(405, needJson ? "{\"error\":\"Method Not Allowed\"}" : NOT_CALLBACK_HTML);
|
|
13517
14280
|
return;
|
|
13518
14281
|
}
|
|
13519
14282
|
let pathname;
|
|
@@ -13530,15 +14293,26 @@ var OAuthCallbackServer = class {
|
|
|
13530
14293
|
search = u.search;
|
|
13531
14294
|
state = u.searchParams.get("state") ?? void 0;
|
|
13532
14295
|
} catch {
|
|
13533
|
-
send(400, needJson ? "{\"error\":\"Bad Request\"}" :
|
|
14296
|
+
send(400, needJson ? "{\"error\":\"Bad Request\"}" : NOT_CALLBACK_HTML);
|
|
13534
14297
|
return;
|
|
13535
14298
|
}
|
|
13536
14299
|
if (pathname !== this.callbackPath) {
|
|
13537
|
-
send(404, needJson ? "{\"error\":\"Not Found\"}" :
|
|
14300
|
+
send(404, needJson ? "{\"error\":\"Not Found\"}" : NOT_CALLBACK_HTML);
|
|
14301
|
+
return;
|
|
14302
|
+
}
|
|
14303
|
+
this.expectedState.then((expected) => this.handleCallback(expected, state, search, needJson, send));
|
|
14304
|
+
}
|
|
14305
|
+
handleCallback(expected, state, search, needJson, send) {
|
|
14306
|
+
if (expected === STOPPED) {
|
|
14307
|
+
send(503, needJson ? "{\"error\":\"Not waiting for a callback\"}" : STOPPED_HTML);
|
|
14308
|
+
return;
|
|
14309
|
+
}
|
|
14310
|
+
if (expected !== ANY_STATE && state !== expected) {
|
|
14311
|
+
send(400, needJson ? "{\"error\":\"State mismatch\"}" : STATE_MISMATCH_HTML);
|
|
13538
14312
|
return;
|
|
13539
14313
|
}
|
|
13540
14314
|
if (this.handled) {
|
|
13541
|
-
send(409, needJson ? "{\"error\":\"Callback already handled\"}" :
|
|
14315
|
+
send(409, needJson ? "{\"error\":\"Callback already handled\"}" : ALREADY_HANDLED_HTML);
|
|
13542
14316
|
return;
|
|
13543
14317
|
}
|
|
13544
14318
|
const params = parseOAuthCallbackParams(search);
|
|
@@ -13556,9 +14330,10 @@ var OAuthCallbackServer = class {
|
|
|
13556
14330
|
const msg = err instanceof Error ? err.message : String(err);
|
|
13557
14331
|
this.onError?.({
|
|
13558
14332
|
error: "callback_error",
|
|
13559
|
-
error_description: msg
|
|
14333
|
+
error_description: msg,
|
|
14334
|
+
source: "callback"
|
|
13560
14335
|
});
|
|
13561
|
-
send(500,
|
|
14336
|
+
send(500, exchangeErrorHtml(msg));
|
|
13562
14337
|
this.stop();
|
|
13563
14338
|
});
|
|
13564
14339
|
else {
|
|
@@ -13571,7 +14346,8 @@ var OAuthCallbackServer = class {
|
|
|
13571
14346
|
const msg = generateOAuthErrorDescription(params);
|
|
13572
14347
|
this.onError?.({
|
|
13573
14348
|
error: params.error,
|
|
13574
|
-
error_description: params.error_description ?? void 0
|
|
14349
|
+
error_description: params.error_description ?? void 0,
|
|
14350
|
+
source: "redirect"
|
|
13575
14351
|
});
|
|
13576
14352
|
send(400, errorHtml(msg));
|
|
13577
14353
|
}
|
|
@@ -13582,6 +14358,28 @@ function createOAuthCallbackServer() {
|
|
|
13582
14358
|
function buildRedirectUrl(host, port, path) {
|
|
13583
14359
|
return `http://${formatHostForUrl(host)}:${port}${path}`;
|
|
13584
14360
|
}
|
|
14361
|
+
var OAuthCallbackError = class extends Error {
|
|
14362
|
+
name = "OAuthCallbackError";
|
|
14363
|
+
oauthError;
|
|
14364
|
+
oauthErrorDescription;
|
|
14365
|
+
source;
|
|
14366
|
+
constructor(params) {
|
|
14367
|
+
super(callbackErrorMessage(params));
|
|
14368
|
+
this.source = params.source;
|
|
14369
|
+
if (params.source === "redirect") {
|
|
14370
|
+
if (params.error) this.oauthError = params.error;
|
|
14371
|
+
if (params.error_description) this.oauthErrorDescription = params.error_description;
|
|
14372
|
+
}
|
|
14373
|
+
}
|
|
14374
|
+
};
|
|
14375
|
+
var OAuthCallbackTimeoutError = class extends Error {
|
|
14376
|
+
name = "OAuthCallbackTimeoutError";
|
|
14377
|
+
timeoutMs;
|
|
14378
|
+
constructor(timeoutMs) {
|
|
14379
|
+
super(`OAuth callback timed out after ${Math.round(timeoutMs / 1e3)}s`);
|
|
14380
|
+
this.timeoutMs = timeoutMs;
|
|
14381
|
+
}
|
|
14382
|
+
};
|
|
13585
14383
|
function toRunnerOAuthError(err) {
|
|
13586
14384
|
const failure = findIssuerBindingFailure(err);
|
|
13587
14385
|
if (failure) {
|
|
@@ -13590,6 +14388,14 @@ function toRunnerOAuthError(err) {
|
|
|
13590
14388
|
}
|
|
13591
14389
|
return err instanceof Error ? err : new Error(String(err));
|
|
13592
14390
|
}
|
|
14391
|
+
function stateOf(authorizationUrl) {
|
|
14392
|
+
return authorizationUrl.searchParams.get("state") ?? void 0;
|
|
14393
|
+
}
|
|
14394
|
+
function callbackErrorMessage(params) {
|
|
14395
|
+
if (params.source === "callback") return params.error_description ?? "OAuth callback failed";
|
|
14396
|
+
if (!params.error && !params.error_description) return "OAuth error";
|
|
14397
|
+
return `OAuth authorization failed. The authorization server said: ${params.error_description ? `${params.error_description} (${params.error})` : params.error}`;
|
|
14398
|
+
}
|
|
13593
14399
|
async function runRunnerInteractiveOAuth(options) {
|
|
13594
14400
|
const server = (options.createCallbackServer ?? createOAuthCallbackServer)();
|
|
13595
14401
|
let flowResolve;
|
|
@@ -13619,11 +14425,16 @@ async function runRunnerInteractiveOAuth(options) {
|
|
|
13619
14425
|
process.on("SIGTERM", onSignal);
|
|
13620
14426
|
}
|
|
13621
14427
|
let timeoutId;
|
|
14428
|
+
let resolveExpectedState;
|
|
14429
|
+
const expectedState = new Promise((resolve) => {
|
|
14430
|
+
resolveExpectedState = resolve;
|
|
14431
|
+
});
|
|
13622
14432
|
try {
|
|
13623
14433
|
const { redirectUrl } = await racingSignals(server.start({
|
|
13624
14434
|
hostname: options.callbackListen.hostname,
|
|
13625
14435
|
port: options.callbackListen.port,
|
|
13626
14436
|
path: options.callbackListen.pathname,
|
|
14437
|
+
expectedState,
|
|
13627
14438
|
onCallback: async (params) => {
|
|
13628
14439
|
try {
|
|
13629
14440
|
await options.client.completeOAuthFlow(params.code, params.iss, params.state);
|
|
@@ -13633,10 +14444,7 @@ async function runRunnerInteractiveOAuth(options) {
|
|
|
13633
14444
|
}
|
|
13634
14445
|
},
|
|
13635
14446
|
onError: (params) => {
|
|
13636
|
-
flowReject(new
|
|
13637
|
-
/* v8 ignore next -- params.error is a required non-null string, so the "OAuth error" fallback is unreachable */
|
|
13638
|
-
params.error_description ?? params.error ?? "OAuth error"
|
|
13639
|
-
));
|
|
14447
|
+
flowReject(new OAuthCallbackError(params));
|
|
13640
14448
|
}
|
|
13641
14449
|
}));
|
|
13642
14450
|
options.onCallbackServer?.(server);
|
|
@@ -13647,15 +14455,21 @@ async function runRunnerInteractiveOAuth(options) {
|
|
|
13647
14455
|
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
13648
14456
|
}), new Promise((_, reject) => {
|
|
13649
14457
|
timeoutId = setTimeout(() => {
|
|
13650
|
-
reject(
|
|
14458
|
+
reject(new OAuthCallbackTimeoutError(timeoutMs));
|
|
13651
14459
|
}, timeoutMs);
|
|
13652
14460
|
})]);
|
|
13653
14461
|
waitForCallback.catch(() => {});
|
|
13654
14462
|
if (options.authorizationUrl) {
|
|
14463
|
+
resolveExpectedState(stateOf(options.authorizationUrl));
|
|
13655
14464
|
await racingSignals(options.client.beginInteractiveAuthorization(options.authorizationUrl));
|
|
13656
14465
|
await waitForCallback;
|
|
13657
|
-
} else
|
|
13658
|
-
|
|
14466
|
+
} else {
|
|
14467
|
+
const authUrl = await racingSignals(options.client.authenticate());
|
|
14468
|
+
if (authUrl !== void 0) {
|
|
14469
|
+
resolveExpectedState(stateOf(authUrl));
|
|
14470
|
+
await waitForCallback;
|
|
14471
|
+
} else return { kind: "already_authorized" };
|
|
14472
|
+
}
|
|
13659
14473
|
if (options.authChallenge) {
|
|
13660
14474
|
if (!await racingSignals(options.client.checkAuthChallengeSatisfied(options.authChallenge, { scopeOnly: true }))) return {
|
|
13661
14475
|
kind: "insufficient_scope",
|
|
@@ -13672,13 +14486,11 @@ async function runRunnerInteractiveOAuth(options) {
|
|
|
13672
14486
|
await server.stop().catch(() => {});
|
|
13673
14487
|
}
|
|
13674
14488
|
}
|
|
13675
|
-
|
|
13676
|
-
//#region src/oauthMessageTone.ts
|
|
14489
|
+
// src/oauthMessageTone.ts
|
|
13677
14490
|
function oauthMessageToneFor(message, warningText) {
|
|
13678
14491
|
return message !== null && message === warningText ? "warning" : "info";
|
|
13679
14492
|
}
|
|
13680
|
-
|
|
13681
|
-
//#region src/logger.ts
|
|
14493
|
+
// src/logger.ts
|
|
13682
14494
|
let tuiLoggerInstance;
|
|
13683
14495
|
function getTuiLogger() {
|
|
13684
14496
|
if (!tuiLoggerInstance) {
|
|
@@ -13695,8 +14507,7 @@ function getTuiLogger() {
|
|
|
13695
14507
|
}
|
|
13696
14508
|
return tuiLoggerInstance;
|
|
13697
14509
|
}
|
|
13698
|
-
|
|
13699
|
-
//#region ../../core/node/openUrl.ts
|
|
14510
|
+
// ../../core/node/openUrl.ts
|
|
13700
14511
|
const OPEN_URL_TIMEOUT_MS = 5e3;
|
|
13701
14512
|
const OPENABLE_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
13702
14513
|
function toOpenableHref(href) {
|
|
@@ -13724,8 +14535,7 @@ async function openUrl$1(url, timeoutMs = OPEN_URL_TIMEOUT_MS) {
|
|
|
13724
14535
|
clearTimeout(timer);
|
|
13725
14536
|
}
|
|
13726
14537
|
}
|
|
13727
|
-
|
|
13728
|
-
//#region src/utils/openUrl.ts
|
|
14538
|
+
// src/utils/openUrl.ts
|
|
13729
14539
|
function browserOpenFailedMessage(href) {
|
|
13730
14540
|
return `Could not open a browser automatically. Open this URL manually to authorize: ${href}`;
|
|
13731
14541
|
}
|
|
@@ -13737,13 +14547,11 @@ async function openUrl(url, onFailure) {
|
|
|
13737
14547
|
onFailure?.(browserOpenFailedMessage(href));
|
|
13738
14548
|
}
|
|
13739
14549
|
}
|
|
13740
|
-
|
|
13741
|
-
//#region src/utils/tuiOAuth.ts
|
|
14550
|
+
// src/utils/tuiOAuth.ts
|
|
13742
14551
|
function isStepUpConfirmation(challenge, settings) {
|
|
13743
14552
|
return isStepUpConfirmation$1(challenge, { enterpriseManaged: settings?.enterpriseManaged });
|
|
13744
14553
|
}
|
|
13745
|
-
|
|
13746
|
-
//#region src/components/tabsConfig.ts
|
|
14554
|
+
// src/components/tabsConfig.ts
|
|
13747
14555
|
const tabs = [
|
|
13748
14556
|
{
|
|
13749
14557
|
id: "info",
|
|
@@ -13829,8 +14637,7 @@ function tabBarRows(visible, counts, width) {
|
|
|
13829
14637
|
}
|
|
13830
14638
|
return rows;
|
|
13831
14639
|
}
|
|
13832
|
-
|
|
13833
|
-
//#region src/components/Tabs.tsx
|
|
14640
|
+
// src/components/Tabs.tsx
|
|
13834
14641
|
function splitLabelAtAccelerator(label, accelerator) {
|
|
13835
14642
|
const idx = label.toLowerCase().indexOf(accelerator.toLowerCase());
|
|
13836
14643
|
if (idx < 0) return {
|
|
@@ -13891,8 +14698,7 @@ function Tabs({ activeTab, width, counts = {}, focused = false, showAuth = true,
|
|
|
13891
14698
|
})
|
|
13892
14699
|
});
|
|
13893
14700
|
}
|
|
13894
|
-
|
|
13895
|
-
//#region node_modules/ink-scroll-view/dist/index.js
|
|
14701
|
+
// node_modules/ink-scroll-view/dist/index.js
|
|
13896
14702
|
var MeasurableItem = ({ children, onMeasure, index, width, measureKey }) => {
|
|
13897
14703
|
const ref = useRef(null);
|
|
13898
14704
|
useLayoutEffect(() => {
|
|
@@ -14174,8 +14980,7 @@ var ScrollView = forwardRef(({ onScroll, onViewportSizeChange, onContentHeightCh
|
|
|
14174
14980
|
...boxProps
|
|
14175
14981
|
});
|
|
14176
14982
|
});
|
|
14177
|
-
|
|
14178
|
-
//#region src/components/InfoTab.tsx
|
|
14983
|
+
// src/components/InfoTab.tsx
|
|
14179
14984
|
function InfoTab({ serverName, serverConfig, serverSettings = null, serverState, width, height, focused = false, roots = [], onEditRoots }) {
|
|
14180
14985
|
const headerPairs = serverSettings?.headers ?? [];
|
|
14181
14986
|
const headersBlock = headerPairs.length > 0 ? /* @__PURE__ */ jsx(Box, {
|
|
@@ -14414,8 +15219,7 @@ function InfoTab({ serverName, serverConfig, serverSettings = null, serverState,
|
|
|
14414
15219
|
})] }) : null]
|
|
14415
15220
|
});
|
|
14416
15221
|
}
|
|
14417
|
-
|
|
14418
|
-
//#region src/components/SelectableItem.tsx
|
|
15222
|
+
// src/components/SelectableItem.tsx
|
|
14419
15223
|
function SelectableItem({ isSelected, bold, children }) {
|
|
14420
15224
|
return /* @__PURE__ */ jsxs(Box, {
|
|
14421
15225
|
flexShrink: 0,
|
|
@@ -14432,8 +15236,7 @@ function SelectableItem({ isSelected, bold, children }) {
|
|
|
14432
15236
|
})]
|
|
14433
15237
|
});
|
|
14434
15238
|
}
|
|
14435
|
-
|
|
14436
|
-
//#region src/utils/clipboard.ts
|
|
15239
|
+
// src/utils/clipboard.ts
|
|
14437
15240
|
const OSC52_LARGE_PAYLOAD_BYTES = 1e5;
|
|
14438
15241
|
function toCopyText(value) {
|
|
14439
15242
|
if (typeof value === "string") return value;
|
|
@@ -14533,8 +15336,7 @@ function useCopyKeys(value, label) {
|
|
|
14533
15336
|
function copyStatusColor(tone) {
|
|
14534
15337
|
return tone === "success" ? "green" : tone === "warning" ? "yellow" : "red";
|
|
14535
15338
|
}
|
|
14536
|
-
|
|
14537
|
-
//#region src/utils/oauthDisplay.ts
|
|
15339
|
+
// src/utils/oauthDisplay.ts
|
|
14538
15340
|
function formatAuthProtocol(protocol) {
|
|
14539
15341
|
return protocol === "ema" ? "Enterprise-managed" : "Standard";
|
|
14540
15342
|
}
|
|
@@ -14556,8 +15358,7 @@ function formatScopes(state) {
|
|
|
14556
15358
|
const scopes = (state.grantedScope ?? state.configuredScope)?.split(" ").filter(Boolean);
|
|
14557
15359
|
return scopes && scopes.length > 0 ? scopes.join(", ") : void 0;
|
|
14558
15360
|
}
|
|
14559
|
-
|
|
14560
|
-
//#region src/utils/errorText.ts
|
|
15361
|
+
// src/utils/errorText.ts
|
|
14561
15362
|
function errorMessage$1(err) {
|
|
14562
15363
|
return redactUrlsInText(err instanceof Error ? err.message : String(err));
|
|
14563
15364
|
}
|
|
@@ -14567,8 +15368,128 @@ function redactErrorText(text) {
|
|
|
14567
15368
|
function redactedJson(value) {
|
|
14568
15369
|
return redactUrlsInText(JSON.stringify(value, null, 2) ?? String(value));
|
|
14569
15370
|
}
|
|
14570
|
-
|
|
14571
|
-
|
|
15371
|
+
// ../../core/auth/accessTokenClaims.ts
|
|
15372
|
+
const CONTROL_CHARS = /[\u0000-\u001F\u007F-\u009F]/g;
|
|
15373
|
+
function clean(value) {
|
|
15374
|
+
return value.replace(CONTROL_CHARS, "");
|
|
15375
|
+
}
|
|
15376
|
+
function stringClaim(value) {
|
|
15377
|
+
if (typeof value !== "string") return void 0;
|
|
15378
|
+
const cleaned = clean(value).trim();
|
|
15379
|
+
return cleaned.length > 0 ? cleaned : void 0;
|
|
15380
|
+
}
|
|
15381
|
+
function listClaim(value) {
|
|
15382
|
+
const strings = (Array.isArray(value) ? value : [value]).map(stringClaim).filter((s) => s !== void 0);
|
|
15383
|
+
return strings.length > 0 ? strings : void 0;
|
|
15384
|
+
}
|
|
15385
|
+
function scopeString(value) {
|
|
15386
|
+
const s = stringClaim(value);
|
|
15387
|
+
if (s === void 0) return void 0;
|
|
15388
|
+
return s.split(/\s+/).filter(Boolean);
|
|
15389
|
+
}
|
|
15390
|
+
function numericClaim(value) {
|
|
15391
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
15392
|
+
}
|
|
15393
|
+
function summarizeAccessToken(tokens) {
|
|
15394
|
+
const claims = decodeJwtPayload(tokens.access_token)?.payload;
|
|
15395
|
+
if (claims && typeof claims === "object" && !Array.isArray(claims)) return {
|
|
15396
|
+
format: "jwt",
|
|
15397
|
+
issuer: stringClaim(claims.iss),
|
|
15398
|
+
audience: listClaim(claims.aud),
|
|
15399
|
+
subject: stringClaim(claims.sub),
|
|
15400
|
+
clientId: stringClaim(claims.client_id) ?? stringClaim(claims.azp),
|
|
15401
|
+
scopes: scopeString(claims.scope) ?? (typeof claims.scp === "string" ? scopeString(claims.scp) : listClaim(claims.scp)),
|
|
15402
|
+
issuedAt: numericClaim(claims.iat),
|
|
15403
|
+
expiresAt: numericClaim(claims.exp)
|
|
15404
|
+
};
|
|
15405
|
+
return {
|
|
15406
|
+
format: "opaque",
|
|
15407
|
+
scopes: scopeString(tokens.scope),
|
|
15408
|
+
expiresIn: numericClaim(tokens.expires_in)
|
|
15409
|
+
};
|
|
15410
|
+
}
|
|
15411
|
+
function isAccessTokenSummaryExpired(summary, nowMs) {
|
|
15412
|
+
return summary.expiresAt !== void 0 && summary.expiresAt * 1e3 <= nowMs;
|
|
15413
|
+
}
|
|
15414
|
+
function formatDuration(seconds) {
|
|
15415
|
+
const s = Math.floor(Math.abs(seconds));
|
|
15416
|
+
if (s < 60) return `${s}s`;
|
|
15417
|
+
const m = Math.floor(s / 60);
|
|
15418
|
+
if (m < 60) return `${m}m`;
|
|
15419
|
+
const h = Math.floor(m / 60);
|
|
15420
|
+
if (h < 24) return m % 60 === 0 ? `${h}h` : `${h}h ${m % 60}m`;
|
|
15421
|
+
const d = Math.floor(h / 24);
|
|
15422
|
+
return h % 24 === 0 ? `${d}d` : `${d}d ${h % 24}h`;
|
|
15423
|
+
}
|
|
15424
|
+
function formatEpoch(epochSeconds) {
|
|
15425
|
+
const date = /* @__PURE__ */ new Date(epochSeconds * 1e3);
|
|
15426
|
+
return Number.isNaN(date.getTime()) ? String(epochSeconds) : date.toISOString();
|
|
15427
|
+
}
|
|
15428
|
+
function relativeTo(epochSeconds, nowMs) {
|
|
15429
|
+
const delta = epochSeconds - nowMs / 1e3;
|
|
15430
|
+
return delta >= 0 ? `in ${formatDuration(delta)}` : `${formatDuration(delta)} ago`;
|
|
15431
|
+
}
|
|
15432
|
+
function accessTokenDetailLines(summary, nowMs) {
|
|
15433
|
+
const lines = [];
|
|
15434
|
+
if (summary.format === "jwt") {
|
|
15435
|
+
lines.push({
|
|
15436
|
+
label: "Format",
|
|
15437
|
+
value: "JWT (signature not verified)"
|
|
15438
|
+
});
|
|
15439
|
+
if (summary.issuer) lines.push({
|
|
15440
|
+
label: "Issuer",
|
|
15441
|
+
value: summary.issuer
|
|
15442
|
+
});
|
|
15443
|
+
if (summary.audience) lines.push({
|
|
15444
|
+
label: "Audience",
|
|
15445
|
+
value: summary.audience.join(", ")
|
|
15446
|
+
});
|
|
15447
|
+
if (summary.subject) lines.push({
|
|
15448
|
+
label: "Subject",
|
|
15449
|
+
value: summary.subject
|
|
15450
|
+
});
|
|
15451
|
+
if (summary.clientId) lines.push({
|
|
15452
|
+
label: "Client",
|
|
15453
|
+
value: summary.clientId
|
|
15454
|
+
});
|
|
15455
|
+
if (summary.scopes) lines.push({
|
|
15456
|
+
label: "Scopes",
|
|
15457
|
+
value: summary.scopes.join(", ")
|
|
15458
|
+
});
|
|
15459
|
+
if (summary.issuedAt !== void 0) lines.push({
|
|
15460
|
+
label: "Issued",
|
|
15461
|
+
value: `${formatEpoch(summary.issuedAt)} (${relativeTo(summary.issuedAt, nowMs)})`
|
|
15462
|
+
});
|
|
15463
|
+
if (summary.expiresAt !== void 0) {
|
|
15464
|
+
const expired = isAccessTokenSummaryExpired(summary, nowMs);
|
|
15465
|
+
const rel = relativeTo(summary.expiresAt, nowMs);
|
|
15466
|
+
lines.push({
|
|
15467
|
+
label: "Expires",
|
|
15468
|
+
value: `${formatEpoch(summary.expiresAt)} (${expired ? `expired ${rel}` : rel})`
|
|
15469
|
+
});
|
|
15470
|
+
} else lines.push({
|
|
15471
|
+
label: "Expires",
|
|
15472
|
+
value: "no exp claim"
|
|
15473
|
+
});
|
|
15474
|
+
return lines;
|
|
15475
|
+
}
|
|
15476
|
+
lines.push({
|
|
15477
|
+
label: "Format",
|
|
15478
|
+
value: "Opaque (not a JWT)"
|
|
15479
|
+
});
|
|
15480
|
+
if (summary.scopes) lines.push({
|
|
15481
|
+
label: "Scopes",
|
|
15482
|
+
value: summary.scopes.join(", ")
|
|
15483
|
+
});
|
|
15484
|
+
lines.push({
|
|
15485
|
+
label: "Expires in",
|
|
15486
|
+
value: summary.expiresIn !== void 0 ? `${formatDuration(summary.expiresIn)} from issuance (token response expires_in)` : "not stated by the token response"
|
|
15487
|
+
});
|
|
15488
|
+
return lines;
|
|
15489
|
+
}
|
|
15490
|
+
// src/components/AuthTab.tsx
|
|
15491
|
+
const NO_REFUSALS = [];
|
|
15492
|
+
const readFetchRefusals = (client) => client.getFetchRefusals();
|
|
14572
15493
|
function OAuthDetailRow({ label, value }) {
|
|
14573
15494
|
return /* @__PURE__ */ jsxs(Box, {
|
|
14574
15495
|
flexDirection: "row",
|
|
@@ -14654,6 +15575,7 @@ function AuthTab({ serverName, inspectorClient, oauthStatus, oauthMessage, oauth
|
|
|
14654
15575
|
inspectorClient.removeEventListener("oauthComplete", update);
|
|
14655
15576
|
};
|
|
14656
15577
|
}, [inspectorClient, refreshOAuthState]);
|
|
15578
|
+
const fetchRefusals = useStoreSnapshot(inspectorClient, "fetchRefused", readFetchRefusals, NO_REFUSALS);
|
|
14657
15579
|
const accessToken = oauthState?.tokens?.access_token;
|
|
14658
15580
|
const { handleCopyKey, status: copyStatus } = useCopyKeys(accessToken, "access token");
|
|
14659
15581
|
useInput((input, key) => {
|
|
@@ -14725,6 +15647,7 @@ function AuthTab({ serverName, inspectorClient, oauthStatus, oauthMessage, oauth
|
|
|
14725
15647
|
})
|
|
14726
15648
|
});
|
|
14727
15649
|
const scopes = oauthState ? formatScopes(oauthState) : void 0;
|
|
15650
|
+
const tokenDetails = oauthState?.tokens?.access_token ? accessTokenDetailLines(summarizeAccessToken(oauthState.tokens), Date.now()) : [];
|
|
14728
15651
|
return /* @__PURE__ */ jsxs(Box, {
|
|
14729
15652
|
width,
|
|
14730
15653
|
height,
|
|
@@ -14763,6 +15686,19 @@ function AuthTab({ serverName, inspectorClient, oauthStatus, oauthMessage, oauth
|
|
|
14763
15686
|
color: oauthMessageTone === "warning" ? "yellow" : "cyan",
|
|
14764
15687
|
children: oauthMessage
|
|
14765
15688
|
}),
|
|
15689
|
+
fetchRefusals.length > 0 && /* @__PURE__ */ jsxs(Box, {
|
|
15690
|
+
marginTop: 1,
|
|
15691
|
+
flexDirection: "column",
|
|
15692
|
+
gap: 0,
|
|
15693
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
15694
|
+
bold: true,
|
|
15695
|
+
color: "yellow",
|
|
15696
|
+
children: "Refused requests"
|
|
15697
|
+
}), fetchRefusals.map((refusal) => /* @__PURE__ */ jsx(Text, {
|
|
15698
|
+
color: "yellow",
|
|
15699
|
+
children: formatFetchRefusal(refusal)
|
|
15700
|
+
}, `${refusal.url} ${refusal.reason}`))]
|
|
15701
|
+
}),
|
|
14766
15702
|
pendingStepUp ? /* @__PURE__ */ jsxs(Box, {
|
|
14767
15703
|
marginTop: 1,
|
|
14768
15704
|
flexDirection: "column",
|
|
@@ -14824,53 +15760,68 @@ function AuthTab({ serverName, inspectorClient, oauthStatus, oauthMessage, oauth
|
|
|
14824
15760
|
flexDirection: "column",
|
|
14825
15761
|
marginTop: 1,
|
|
14826
15762
|
gap: 0,
|
|
14827
|
-
children: [
|
|
14828
|
-
|
|
14829
|
-
|
|
14830
|
-
|
|
14831
|
-
|
|
14832
|
-
|
|
14833
|
-
|
|
14834
|
-
|
|
14835
|
-
|
|
14836
|
-
|
|
14837
|
-
|
|
14838
|
-
|
|
14839
|
-
|
|
14840
|
-
|
|
14841
|
-
|
|
14842
|
-
|
|
14843
|
-
|
|
14844
|
-
|
|
14845
|
-
|
|
14846
|
-
|
|
14847
|
-
|
|
14848
|
-
|
|
14849
|
-
|
|
14850
|
-
|
|
14851
|
-
|
|
14852
|
-
|
|
14853
|
-
|
|
14854
|
-
|
|
14855
|
-
|
|
14856
|
-
|
|
14857
|
-
|
|
14858
|
-
|
|
14859
|
-
|
|
14860
|
-
|
|
14861
|
-
|
|
14862
|
-
|
|
14863
|
-
|
|
14864
|
-
|
|
14865
|
-
|
|
14866
|
-
|
|
14867
|
-
|
|
14868
|
-
|
|
14869
|
-
|
|
14870
|
-
|
|
14871
|
-
|
|
14872
|
-
|
|
14873
|
-
|
|
15763
|
+
children: [
|
|
15764
|
+
/* @__PURE__ */ jsx(Text, {
|
|
15765
|
+
bold: true,
|
|
15766
|
+
children: "OAuth Details"
|
|
15767
|
+
}),
|
|
15768
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
15769
|
+
marginTop: 1,
|
|
15770
|
+
flexDirection: "column",
|
|
15771
|
+
paddingLeft: 0,
|
|
15772
|
+
gap: 0,
|
|
15773
|
+
children: [
|
|
15774
|
+
/* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15775
|
+
label: "Protocol",
|
|
15776
|
+
value: formatAuthProtocol(oauthState.protocol)
|
|
15777
|
+
}),
|
|
15778
|
+
/* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15779
|
+
label: "Status",
|
|
15780
|
+
value: oauthState.authorized ? "Authorized" : "Not authorized"
|
|
15781
|
+
}),
|
|
15782
|
+
oauthState.client?.clientId && /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15783
|
+
label: "Client ID",
|
|
15784
|
+
value: oauthState.client.clientId
|
|
15785
|
+
}),
|
|
15786
|
+
oauthState.client?.registrationKind && /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15787
|
+
label: "Client registration",
|
|
15788
|
+
value: formatClientRegistrationKind(oauthState.client.registrationKind)
|
|
15789
|
+
}),
|
|
15790
|
+
oauthState.protocol === "ema" && oauthState.ema?.idpSession && /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15791
|
+
label: "IdP session",
|
|
15792
|
+
value: formatIdpSession(oauthState.ema.idpSession)
|
|
15793
|
+
}),
|
|
15794
|
+
oauthState.authorizationServerMetadata?.authorization_endpoint && /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15795
|
+
label: "Auth URL",
|
|
15796
|
+
value: oauthState.authorizationServerMetadata.authorization_endpoint
|
|
15797
|
+
}),
|
|
15798
|
+
scopes && /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15799
|
+
label: "Scopes",
|
|
15800
|
+
value: scopes
|
|
15801
|
+
}),
|
|
15802
|
+
accessToken && /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15803
|
+
label: "Access token",
|
|
15804
|
+
value: `${accessToken.slice(0, 24)}…`
|
|
15805
|
+
}),
|
|
15806
|
+
accessToken && copyStatus && /* @__PURE__ */ jsx(Text, {
|
|
15807
|
+
color: copyStatusColor(copyStatus.tone),
|
|
15808
|
+
children: copyStatus.message
|
|
15809
|
+
})
|
|
15810
|
+
]
|
|
15811
|
+
}),
|
|
15812
|
+
tokenDetails.length > 0 && /* @__PURE__ */ jsxs(Box, {
|
|
15813
|
+
marginTop: 1,
|
|
15814
|
+
flexDirection: "column",
|
|
15815
|
+
gap: 0,
|
|
15816
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
15817
|
+
bold: true,
|
|
15818
|
+
children: "Access Token Details"
|
|
15819
|
+
}), tokenDetails.map((line) => /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15820
|
+
label: line.label,
|
|
15821
|
+
value: line.value
|
|
15822
|
+
}, line.label))]
|
|
15823
|
+
})
|
|
15824
|
+
]
|
|
14874
15825
|
}) : oauthStatus !== "authenticating" && /* @__PURE__ */ jsxs(Box, {
|
|
14875
15826
|
marginTop: 1,
|
|
14876
15827
|
flexDirection: "column",
|
|
@@ -14932,8 +15883,7 @@ function AuthTab({ serverName, inspectorClient, oauthStatus, oauthMessage, oauth
|
|
|
14932
15883
|
]
|
|
14933
15884
|
});
|
|
14934
15885
|
}
|
|
14935
|
-
|
|
14936
|
-
//#region src/hooks/useSelectableList.ts
|
|
15886
|
+
// src/hooks/useSelectableList.ts
|
|
14937
15887
|
function clampFirstVisible(first, selected, visibleCount) {
|
|
14938
15888
|
if (selected < first) return selected;
|
|
14939
15889
|
if (selected >= first + visibleCount) return selected - visibleCount + 1;
|
|
@@ -14965,12 +15915,11 @@ function useSelectableList(itemCount, visibleCount, options) {
|
|
|
14965
15915
|
]);
|
|
14966
15916
|
return {
|
|
14967
15917
|
selectedIndex,
|
|
14968
|
-
firstVisible,
|
|
15918
|
+
firstVisible: clampFirstVisible(firstVisible, selectedIndex, visibleCount),
|
|
14969
15919
|
setSelection
|
|
14970
15920
|
};
|
|
14971
15921
|
}
|
|
14972
|
-
|
|
14973
|
-
//#region src/hooks/useListFilter.ts
|
|
15922
|
+
// src/hooks/useListFilter.ts
|
|
14974
15923
|
function printable(input) {
|
|
14975
15924
|
return input.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
14976
15925
|
}
|
|
@@ -15097,8 +16046,7 @@ function ListFilterBar({ query, editing, focused }) {
|
|
|
15097
16046
|
function filterCount(active, shown, total) {
|
|
15098
16047
|
return active ? `${shown}/${total}` : String(total);
|
|
15099
16048
|
}
|
|
15100
|
-
|
|
15101
|
-
//#region src/components/ResourcesTab.tsx
|
|
16049
|
+
// src/components/ResourcesTab.tsx
|
|
15102
16050
|
function resourceFilterFields(item) {
|
|
15103
16051
|
return item.type === "resource" ? [
|
|
15104
16052
|
item.data.name,
|
|
@@ -15277,7 +16225,10 @@ function ResourcesTab({ resources, resourceTemplates = [], inspectorClient, widt
|
|
|
15277
16225
|
return /* @__PURE__ */ jsx(Box, {
|
|
15278
16226
|
paddingY: 0,
|
|
15279
16227
|
flexShrink: 0,
|
|
15280
|
-
children: /* @__PURE__ */ jsxs(Text, {
|
|
16228
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
16229
|
+
wrap: "truncate-end",
|
|
16230
|
+
children: [isSelected ? "▶ " : " ", label]
|
|
16231
|
+
})
|
|
15281
16232
|
}, key);
|
|
15282
16233
|
})
|
|
15283
16234
|
})
|
|
@@ -15435,8 +16386,7 @@ function ResourcesTab({ resources, resourceTemplates = [], inspectorClient, widt
|
|
|
15435
16386
|
})]
|
|
15436
16387
|
});
|
|
15437
16388
|
}
|
|
15438
|
-
|
|
15439
|
-
//#region src/components/PromptsTab.tsx
|
|
16389
|
+
// src/components/PromptsTab.tsx
|
|
15440
16390
|
function promptFilterFields(prompt) {
|
|
15441
16391
|
return [prompt.name, prompt.title];
|
|
15442
16392
|
}
|
|
@@ -15561,7 +16511,10 @@ function PromptsTab({ prompts, inspectorClient, width, height, focusedPane = nul
|
|
|
15561
16511
|
return /* @__PURE__ */ jsx(Box, {
|
|
15562
16512
|
paddingY: 0,
|
|
15563
16513
|
flexShrink: 0,
|
|
15564
|
-
children: /* @__PURE__ */ jsxs(Text, {
|
|
16514
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
16515
|
+
wrap: "truncate-end",
|
|
16516
|
+
children: [isSelected ? "▶ " : " ", prompt.name || `Prompt ${ordinal + 1}`]
|
|
16517
|
+
})
|
|
15565
16518
|
}, `${ordinal}:${prompt.name}`);
|
|
15566
16519
|
})
|
|
15567
16520
|
})
|
|
@@ -15649,8 +16602,7 @@ function PromptsTab({ prompts, inspectorClient, width, height, focusedPane = nul
|
|
|
15649
16602
|
})]
|
|
15650
16603
|
});
|
|
15651
16604
|
}
|
|
15652
|
-
|
|
15653
|
-
//#region ../../core/extension/skills/verification.ts
|
|
16605
|
+
// ../../core/extension/skills/verification.ts
|
|
15654
16606
|
const DEFAULT_SKILL_BUDGET_HINT = {
|
|
15655
16607
|
raise: "with the server's skillCatalogMaxSkills / skillCatalogMaxBytes settings",
|
|
15656
16608
|
verifyOne: "by verifying this skill alone"
|
|
@@ -15823,8 +16775,7 @@ async function verifySkills(client, entries, metadata, budgetHint = DEFAULT_SKIL
|
|
|
15823
16775
|
}
|
|
15824
16776
|
return reports;
|
|
15825
16777
|
}
|
|
15826
|
-
|
|
15827
|
-
//#region src/components/SkillsTab.tsx
|
|
16778
|
+
// src/components/SkillsTab.tsx
|
|
15828
16779
|
function skillFilterFields(skill) {
|
|
15829
16780
|
return [skillDisplayName(skill), skill.frontmatter.name];
|
|
15830
16781
|
}
|
|
@@ -16279,8 +17230,7 @@ function SkillsTab({ skills, pageCount, loadError = null, inspectorClient, width
|
|
|
16279
17230
|
})]
|
|
16280
17231
|
});
|
|
16281
17232
|
}
|
|
16282
|
-
|
|
16283
|
-
//#region ../../core/json/schemaLint.ts
|
|
17233
|
+
// ../../core/json/schemaLint.ts
|
|
16284
17234
|
const BOOLEAN_VALUED_KEYWORDS = /* @__PURE__ */ new Set([
|
|
16285
17235
|
"additionalProperties",
|
|
16286
17236
|
"unevaluatedProperties",
|
|
@@ -16474,8 +17424,7 @@ function lintToolSchemas(tool) {
|
|
|
16474
17424
|
if (tool.outputSchema !== void 0) lintSchema(tool.outputSchema, "outputSchema", findings);
|
|
16475
17425
|
return findings;
|
|
16476
17426
|
}
|
|
16477
|
-
|
|
16478
|
-
//#region src/components/ToolsTab.tsx
|
|
17427
|
+
// src/components/ToolsTab.tsx
|
|
16479
17428
|
const SEVERITY_MARKER = {
|
|
16480
17429
|
error: {
|
|
16481
17430
|
glyph: "!",
|
|
@@ -16603,17 +17552,19 @@ function ToolsTab({ tools, isConnected, width, height, focusedPane = null, onTes
|
|
|
16603
17552
|
const isSelected = index === selectedIndex;
|
|
16604
17553
|
const marker = schemaMarker(findingsByTool.get(tool));
|
|
16605
17554
|
const ordinal = filter.indices[index];
|
|
16606
|
-
return /* @__PURE__ */
|
|
17555
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
16607
17556
|
paddingY: 0,
|
|
16608
17557
|
flexShrink: 0,
|
|
16609
|
-
children: /* @__PURE__ */ jsxs(Text, {
|
|
16610
|
-
|
|
16611
|
-
tool.name || `Tool ${ordinal + 1}
|
|
16612
|
-
|
|
17558
|
+
children: [/* @__PURE__ */ jsxs(Text, {
|
|
17559
|
+
wrap: "truncate-end",
|
|
17560
|
+
children: [isSelected ? "▶ " : " ", tool.name || `Tool ${ordinal + 1}`]
|
|
17561
|
+
}), marker && /* @__PURE__ */ jsx(Box, {
|
|
17562
|
+
flexShrink: 0,
|
|
17563
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
16613
17564
|
color: marker.color,
|
|
16614
17565
|
children: [" ", marker.glyph]
|
|
16615
17566
|
})
|
|
16616
|
-
|
|
17567
|
+
})]
|
|
16617
17568
|
}, `${ordinal}:${tool.name}`);
|
|
16618
17569
|
})
|
|
16619
17570
|
})
|
|
@@ -16628,18 +17579,23 @@ function ToolsTab({ tools, isConnected, width, height, focusedPane = null, onTes
|
|
|
16628
17579
|
/* @__PURE__ */ jsxs(Box, {
|
|
16629
17580
|
flexShrink: 0,
|
|
16630
17581
|
flexDirection: "row",
|
|
17582
|
+
flexWrap: "wrap",
|
|
16631
17583
|
justifyContent: "space-between",
|
|
17584
|
+
columnGap: 1,
|
|
16632
17585
|
paddingTop: 1,
|
|
16633
17586
|
children: [/* @__PURE__ */ jsx(Text, {
|
|
16634
17587
|
bold: true,
|
|
16635
17588
|
backgroundColor: focusedPane === "details" ? "yellow" : void 0,
|
|
16636
17589
|
...focusedPane === "details" ? {} : { color: "cyan" },
|
|
16637
17590
|
children: selectedTool.name
|
|
16638
|
-
}), isConnected && /* @__PURE__ */ jsx(
|
|
16639
|
-
|
|
16640
|
-
|
|
16641
|
-
|
|
16642
|
-
|
|
17591
|
+
}), isConnected && /* @__PURE__ */ jsx(Box, {
|
|
17592
|
+
flexShrink: 0,
|
|
17593
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
17594
|
+
color: "cyan",
|
|
17595
|
+
bold: true,
|
|
17596
|
+
children: "[Enter to Test]"
|
|
17597
|
+
})
|
|
17598
|
+
})]
|
|
16643
17599
|
}),
|
|
16644
17600
|
/* @__PURE__ */ jsxs(ScrollView, {
|
|
16645
17601
|
ref: scrollViewRef,
|
|
@@ -16732,8 +17688,7 @@ function ToolsTab({ tools, isConnected, width, height, focusedPane = null, onTes
|
|
|
16732
17688
|
})]
|
|
16733
17689
|
});
|
|
16734
17690
|
}
|
|
16735
|
-
|
|
16736
|
-
//#region src/components/NotificationsTab.tsx
|
|
17691
|
+
// src/components/NotificationsTab.tsx
|
|
16737
17692
|
function NotificationsTab({ stderrLogs, width, height, onCountChange, focused = false }) {
|
|
16738
17693
|
const scrollViewRef = useRef(null);
|
|
16739
17694
|
const onCountChangeRef = useRef(onCountChange);
|
|
@@ -16821,8 +17776,7 @@ function layoutBody(body, maxLines = 500, maxLineChars = MAX_BODY_LINE_CHARS) {
|
|
|
16821
17776
|
totalLines: all.length
|
|
16822
17777
|
};
|
|
16823
17778
|
}
|
|
16824
|
-
|
|
16825
|
-
//#region src/components/BodyLines.tsx
|
|
17779
|
+
// src/components/BodyLines.tsx
|
|
16826
17780
|
function BodyLines({ body, keyPrefix }) {
|
|
16827
17781
|
const { lines, hiddenLines, totalLines } = layoutBody(body);
|
|
16828
17782
|
return /* @__PURE__ */ jsxs(Fragment, { children: [lines.map((line, idx) => /* @__PURE__ */ jsx(Box, {
|
|
@@ -16849,8 +17803,7 @@ function BodyLines({ body, keyPrefix }) {
|
|
|
16849
17803
|
})
|
|
16850
17804
|
})] });
|
|
16851
17805
|
}
|
|
16852
|
-
|
|
16853
|
-
//#region src/components/HistoryTab.tsx
|
|
17806
|
+
// src/components/HistoryTab.tsx
|
|
16854
17807
|
function HistoryTab({ messages, width, height, onCountChange, focusedPane = null, onViewDetails, modalOpen = false }) {
|
|
16855
17808
|
const visibleCount = Math.max(1, height - 7);
|
|
16856
17809
|
const { selectedIndex, firstVisible, setSelection } = useSelectableList(messages.length, visibleCount);
|
|
@@ -17058,8 +18011,7 @@ function HistoryTab({ messages, width, height, onCountChange, focusedPane = null
|
|
|
17058
18011
|
})]
|
|
17059
18012
|
});
|
|
17060
18013
|
}
|
|
17061
|
-
|
|
17062
|
-
//#region src/components/RequestsTab.tsx
|
|
18014
|
+
// src/components/RequestsTab.tsx
|
|
17063
18015
|
function RequestsTab({ requests, width, height, onCountChange, focusedPane = null, onViewDetails, modalOpen = false }) {
|
|
17064
18016
|
const visibleCount = Math.max(1, height - 7);
|
|
17065
18017
|
const { selectedIndex, firstVisible, setSelection } = useSelectableList(requests.length, visibleCount);
|
|
@@ -17355,8 +18307,7 @@ function RequestsTab({ requests, width, height, onCountChange, focusedPane = nul
|
|
|
17355
18307
|
})]
|
|
17356
18308
|
});
|
|
17357
18309
|
}
|
|
17358
|
-
|
|
17359
|
-
//#region node_modules/ink-form/lib/FormHeader.js
|
|
18310
|
+
// node_modules/ink-form/lib/FormHeader.js
|
|
17360
18311
|
const FormHeader = (props) => {
|
|
17361
18312
|
const sections = props.form.sections;
|
|
17362
18313
|
useInput((input, key) => {
|
|
@@ -17375,8 +18326,7 @@ const FormHeader = (props) => {
|
|
|
17375
18326
|
underline: props.currentTab === id
|
|
17376
18327
|
}, section.title), React$1.createElement(Text, null, " "))) : React$1.createElement(Box, null, React$1.createElement(Text, null, "Editing ", props.editingField)))));
|
|
17377
18328
|
};
|
|
17378
|
-
|
|
17379
|
-
//#region node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
18329
|
+
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
17380
18330
|
const ANSI_BACKGROUND_OFFSET = 10;
|
|
17381
18331
|
const wrapAnsi16 = (offset = 0) => (code) => `\u001B[${code + offset}m`;
|
|
17382
18332
|
const wrapAnsi256 = (offset = 0) => (code) => `\u001B[${38 + offset};5;${code}m`;
|
|
@@ -17539,8 +18489,7 @@ function assembleStyles() {
|
|
|
17539
18489
|
return styles$1;
|
|
17540
18490
|
}
|
|
17541
18491
|
const ansiStyles = assembleStyles();
|
|
17542
|
-
|
|
17543
|
-
//#region node_modules/chalk/source/vendor/supports-color/index.js
|
|
18492
|
+
// node_modules/chalk/source/vendor/supports-color/index.js
|
|
17544
18493
|
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process$1.argv) {
|
|
17545
18494
|
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
17546
18495
|
const position = argv.indexOf(prefix + flag);
|
|
@@ -17627,8 +18576,7 @@ const supportsColor = {
|
|
|
17627
18576
|
stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
|
|
17628
18577
|
stderr: createSupportsColor({ isTTY: tty.isatty(2) })
|
|
17629
18578
|
};
|
|
17630
|
-
|
|
17631
|
-
//#region node_modules/chalk/source/utilities.js
|
|
18579
|
+
// node_modules/chalk/source/utilities.js
|
|
17632
18580
|
function stringReplaceAll(string, substring, replacer) {
|
|
17633
18581
|
let index = string.indexOf(substring);
|
|
17634
18582
|
if (index === -1) return string;
|
|
@@ -17655,8 +18603,7 @@ function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
|
|
|
17655
18603
|
returnValue += string.slice(endIndex);
|
|
17656
18604
|
return returnValue;
|
|
17657
18605
|
}
|
|
17658
|
-
|
|
17659
|
-
//#region node_modules/chalk/source/index.js
|
|
18606
|
+
// node_modules/chalk/source/index.js
|
|
17660
18607
|
const { stdout: stdoutColor, stderr: stderrColor } = supportsColor;
|
|
17661
18608
|
const GENERATOR = Symbol("GENERATOR");
|
|
17662
18609
|
const STYLER = Symbol("STYLER");
|
|
@@ -17777,8 +18724,7 @@ const applyStyle = (self, string) => {
|
|
|
17777
18724
|
Object.defineProperties(createChalk.prototype, styles);
|
|
17778
18725
|
const chalk = createChalk();
|
|
17779
18726
|
createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
17780
|
-
|
|
17781
|
-
//#region node_modules/ink-text-input/build/index.js
|
|
18727
|
+
// node_modules/ink-text-input/build/index.js
|
|
17782
18728
|
function TextInput({ value: originalValue, placeholder = "", focus = true, mask, highlightPastedText = false, showCursor = true, onChange, onSubmit }) {
|
|
17783
18729
|
const [state, setState] = useState({
|
|
17784
18730
|
cursorOffset: (originalValue || "").length,
|
|
@@ -17847,8 +18793,7 @@ function TextInput({ value: originalValue, placeholder = "", focus = true, mask,
|
|
|
17847
18793
|
}, { isActive: focus });
|
|
17848
18794
|
return React.createElement(Text, null, placeholder ? value.length > 0 ? renderedValue : renderedPlaceholder : renderedValue);
|
|
17849
18795
|
}
|
|
17850
|
-
|
|
17851
|
-
//#region node_modules/ink-form/lib/NumberFieldRenderer.js
|
|
18796
|
+
// node_modules/ink-form/lib/NumberFieldRenderer.js
|
|
17852
18797
|
const FLOAT_REGEX = /^-?((\d+)|(\d*\.\d+))$/;
|
|
17853
18798
|
const INTEGER_REGEX = /^-?\d+$/;
|
|
17854
18799
|
const NumberFieldRenderer = (props) => {
|
|
@@ -17897,8 +18842,7 @@ const NumberFieldRenderer = (props) => {
|
|
|
17897
18842
|
onSubmit: () => props.onSetEditingField(void 0)
|
|
17898
18843
|
})), React.createElement(Box, null, React.createElement(Text, { dimColor: true }, "Press UP/DOWN to increase or decrease the value.")));
|
|
17899
18844
|
};
|
|
17900
|
-
|
|
17901
|
-
//#region node_modules/ink-form/lib/managers/FloatFormFieldManager.js
|
|
18845
|
+
// node_modules/ink-form/lib/managers/FloatFormFieldManager.js
|
|
17902
18846
|
var FloatFormFieldManager = class {
|
|
17903
18847
|
type = "float";
|
|
17904
18848
|
renderField = (props) => React.createElement(NumberFieldRenderer, {
|
|
@@ -17907,8 +18851,7 @@ var FloatFormFieldManager = class {
|
|
|
17907
18851
|
});
|
|
17908
18852
|
renderValue = (props) => React.createElement(React.Fragment, null, props.value);
|
|
17909
18853
|
};
|
|
17910
|
-
|
|
17911
|
-
//#region node_modules/ink-form/lib/managers/IntegerFormFieldManager.js
|
|
18854
|
+
// node_modules/ink-form/lib/managers/IntegerFormFieldManager.js
|
|
17912
18855
|
var IntegerFormFieldManager = class {
|
|
17913
18856
|
type = "integer";
|
|
17914
18857
|
renderField = (props) => React.createElement(NumberFieldRenderer, {
|
|
@@ -17917,16 +18860,14 @@ var IntegerFormFieldManager = class {
|
|
|
17917
18860
|
});
|
|
17918
18861
|
renderValue = (props) => React.createElement(React.Fragment, null, props.value);
|
|
17919
18862
|
};
|
|
17920
|
-
|
|
17921
|
-
//#region node_modules/is-unicode-supported/index.js
|
|
18863
|
+
// node_modules/is-unicode-supported/index.js
|
|
17922
18864
|
function isUnicodeSupported() {
|
|
17923
18865
|
const { env } = process$1;
|
|
17924
18866
|
const { TERM, TERM_PROGRAM } = env;
|
|
17925
18867
|
if (process$1.platform !== "win32") return TERM !== "linux";
|
|
17926
18868
|
return Boolean(env.WT_SESSION) || Boolean(env.TERMINUS_SUBLIME) || env.ConEmuTask === "{cmd::Cmder}" || TERM_PROGRAM === "Terminus-Sublime" || TERM_PROGRAM === "vscode" || TERM === "xterm-256color" || TERM === "alacritty" || TERM === "rxvt-unicode" || TERM === "rxvt-unicode-256color" || env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
17927
18869
|
}
|
|
17928
|
-
|
|
17929
|
-
//#region node_modules/figures/index.js
|
|
18870
|
+
// node_modules/figures/index.js
|
|
17930
18871
|
const common = {
|
|
17931
18872
|
circleQuestionMark: "(?)",
|
|
17932
18873
|
questionMarkPrefix: "(?)",
|
|
@@ -18205,18 +19146,15 @@ const fallbackSymbols = {
|
|
|
18205
19146
|
};
|
|
18206
19147
|
const figures = isUnicodeSupported() ? mainSymbols : fallbackSymbols;
|
|
18207
19148
|
Object.entries(specialMainSymbols);
|
|
18208
|
-
|
|
18209
|
-
//#region node_modules/ink-select-input/build/Indicator.js
|
|
19149
|
+
// node_modules/ink-select-input/build/Indicator.js
|
|
18210
19150
|
function Indicator({ isSelected = false }) {
|
|
18211
19151
|
return React.createElement(Box, { marginRight: 1 }, isSelected ? React.createElement(Text, { color: "blue" }, figures.pointer) : React.createElement(Text, null, " "));
|
|
18212
19152
|
}
|
|
18213
|
-
|
|
18214
|
-
//#region node_modules/ink-select-input/build/Item.js
|
|
19153
|
+
// node_modules/ink-select-input/build/Item.js
|
|
18215
19154
|
function Item({ isSelected = false, label }) {
|
|
18216
19155
|
return React$1.createElement(Text, { color: isSelected ? "blue" : void 0 }, label);
|
|
18217
19156
|
}
|
|
18218
|
-
|
|
18219
|
-
//#region node_modules/to-rotated/index.js
|
|
19157
|
+
// node_modules/to-rotated/index.js
|
|
18220
19158
|
function toRotated(array, steps) {
|
|
18221
19159
|
if (!Array.isArray(array)) throw new TypeError(`Expected an array, got \`${typeof array}\`.`);
|
|
18222
19160
|
if (!Number.isSafeInteger(steps)) throw new TypeError(`The \`steps\` parameter must be an integer, got ${steps}.`);
|
|
@@ -18226,8 +19164,7 @@ function toRotated(array, steps) {
|
|
|
18226
19164
|
if (normalizedSteps === 0) return [...array];
|
|
18227
19165
|
return [...array.slice(-normalizedSteps), ...array.slice(0, -normalizedSteps)];
|
|
18228
19166
|
}
|
|
18229
|
-
|
|
18230
|
-
//#region node_modules/ink-select-input/build/SelectInput.js
|
|
19167
|
+
// node_modules/ink-select-input/build/SelectInput.js
|
|
18231
19168
|
function SelectInput({ items = [], isFocused = true, initialIndex = 0, indicatorComponent = Indicator, itemComponent = Item, limit: customLimit, onSelect, onHighlight }) {
|
|
18232
19169
|
const hasLimit = typeof customLimit === "number" && items.length > customLimit;
|
|
18233
19170
|
const limit = hasLimit ? Math.min(customLimit, items.length) : items.length;
|
|
@@ -18294,8 +19231,7 @@ function SelectInput({ items = [], isFocused = true, initialIndex = 0, indicator
|
|
|
18294
19231
|
}));
|
|
18295
19232
|
}));
|
|
18296
19233
|
}
|
|
18297
|
-
|
|
18298
|
-
//#region node_modules/ink-form/lib/managers/SelectFormFieldManager.js
|
|
19234
|
+
// node_modules/ink-form/lib/managers/SelectFormFieldManager.js
|
|
18299
19235
|
var SelectFormFieldManager = class {
|
|
18300
19236
|
type = "select";
|
|
18301
19237
|
renderField = (props) => React.createElement(Box, {
|
|
@@ -18311,8 +19247,7 @@ var SelectFormFieldManager = class {
|
|
|
18311
19247
|
}));
|
|
18312
19248
|
renderValue = (props) => React.createElement(React.Fragment, null, props.field.options.find((option) => option.value === props.value)?.label ?? props.value ?? "No value");
|
|
18313
19249
|
};
|
|
18314
|
-
|
|
18315
|
-
//#region node_modules/ink-form/lib/managers/StringFormFieldManager.js
|
|
19250
|
+
// node_modules/ink-form/lib/managers/StringFormFieldManager.js
|
|
18316
19251
|
var StringFormFieldManager = class {
|
|
18317
19252
|
type = "string";
|
|
18318
19253
|
renderField = (props) => React.createElement(Box, {
|
|
@@ -18331,8 +19266,7 @@ var StringFormFieldManager = class {
|
|
|
18331
19266
|
}));
|
|
18332
19267
|
renderValue = (props) => React.createElement(Transform, { transform: props.value !== void 0 && props.field.mask ? (text) => text.split("").map((char) => "*").join("") : (text) => text }, props.value);
|
|
18333
19268
|
};
|
|
18334
|
-
|
|
18335
|
-
//#region node_modules/ink-form/lib/managers/BooleanFormFieldManager.js
|
|
19269
|
+
// node_modules/ink-form/lib/managers/BooleanFormFieldManager.js
|
|
18336
19270
|
var BooleanFormFieldManager = class {
|
|
18337
19271
|
type = "boolean";
|
|
18338
19272
|
renderField = (props) => {
|
|
@@ -18348,8 +19282,7 @@ var BooleanFormFieldManager = class {
|
|
|
18348
19282
|
};
|
|
18349
19283
|
renderValue = (props) => React.createElement(Text, null, props.value === void 0 ? "[Not set]" : props.value ? "[True]" : "[False]");
|
|
18350
19284
|
};
|
|
18351
|
-
|
|
18352
|
-
//#region node_modules/ink-form/lib/managers/managers.js
|
|
19285
|
+
// node_modules/ink-form/lib/managers/managers.js
|
|
18353
19286
|
const managers = [
|
|
18354
19287
|
new FloatFormFieldManager(),
|
|
18355
19288
|
new IntegerFormFieldManager(),
|
|
@@ -18360,8 +19293,7 @@ const managers = [
|
|
|
18360
19293
|
const getManager = (formFieldType, customManagers = []) => {
|
|
18361
19294
|
return [...managers, ...customManagers].find((manager) => manager.type === formFieldType);
|
|
18362
19295
|
};
|
|
18363
|
-
|
|
18364
|
-
//#region node_modules/ink-form/lib/DescriptionRenderer.js
|
|
19296
|
+
// node_modules/ink-form/lib/DescriptionRenderer.js
|
|
18365
19297
|
const DescriptionRenderer = (props) => {
|
|
18366
19298
|
if (!props.description) return null;
|
|
18367
19299
|
else if (props.description.type) return props.description;
|
|
@@ -18372,8 +19304,7 @@ const DescriptionRenderer = (props) => {
|
|
|
18372
19304
|
}, React.createElement(Text, null, line))));
|
|
18373
19305
|
else return React.createElement(Text, null, props.description);
|
|
18374
19306
|
};
|
|
18375
|
-
|
|
18376
|
-
//#region node_modules/ink-form/lib/FormFieldRenderer.js
|
|
19307
|
+
// node_modules/ink-form/lib/FormFieldRenderer.js
|
|
18377
19308
|
const FormFieldRenderer = (props) => {
|
|
18378
19309
|
const manager = getManager(props.field.type, props.customManagers);
|
|
18379
19310
|
const [error, setError] = useState();
|
|
@@ -18439,13 +19370,11 @@ const FormFieldRenderer = (props) => {
|
|
|
18439
19370
|
}, React.createElement(Box, null, React.createElement(Text, null, props.field.label ?? props.field.name), props.field.required && React.createElement(Text, { color: "red" }, "*"), React.createElement(Text, null, ": ")), React.createElement(Box, null, component), props.field.description && React.createElement(Box, null, React.createElement(Text, { dimColor: true }, React.createElement(DescriptionRenderer, { description: props.field.description }))), error && React.createElement(Box, null, React.createElement(Text, { color: "red" }, "Error: ", error)), React.createElement(Box, { marginTop: 2 }, React.createElement(Text, { dimColor: true }, error ? React.createElement(React.Fragment, null, "Press ESC to cancel.") : React.createElement(React.Fragment, null, "Press ", manager?.needCtrlToReturnSave ? "CTRL+Enter" : "Enter", " to complete field, or ESC to cancel."))));
|
|
18440
19371
|
}
|
|
18441
19372
|
};
|
|
18442
|
-
|
|
18443
|
-
//#region node_modules/ink-form/lib/canSubmit.js
|
|
19373
|
+
// node_modules/ink-form/lib/canSubmit.js
|
|
18444
19374
|
const canSubmit = (form, value) => {
|
|
18445
19375
|
return form.sections.map((section) => section.fields).reduce((fields1, fields2) => [...fields1, ...fields2], []).map((field) => !field.required || value[field.name] !== void 0 && value[field.name] !== "").reduce((field1, field2) => field1 && field2, true);
|
|
18446
19376
|
};
|
|
18447
|
-
|
|
18448
|
-
//#region node_modules/ink-form/lib/SubmitButton.js
|
|
19377
|
+
// node_modules/ink-form/lib/SubmitButton.js
|
|
18449
19378
|
const SubmitButton = (props) => {
|
|
18450
19379
|
const { isFocused } = useFocus({ isActive: props.canSubmit });
|
|
18451
19380
|
useInput((input, key) => {
|
|
@@ -18464,8 +19393,7 @@ const SubmitButton = (props) => {
|
|
|
18464
19393
|
underline: isFocused
|
|
18465
19394
|
}, props.canSubmit ? "Submit form" : "Cannot submit form yet")));
|
|
18466
19395
|
};
|
|
18467
|
-
|
|
18468
|
-
//#region node_modules/ink-form/lib/Form.js
|
|
19396
|
+
// node_modules/ink-form/lib/Form.js
|
|
18469
19397
|
const Form = (props) => {
|
|
18470
19398
|
const isControlled = props.value !== void 0;
|
|
18471
19399
|
const [currentTab, setCurrentTab] = useState(0);
|
|
@@ -18525,8 +19453,29 @@ const Form = (props) => {
|
|
|
18525
19453
|
onSubmit: () => props.onSubmit?.(value)
|
|
18526
19454
|
})));
|
|
18527
19455
|
};
|
|
18528
|
-
|
|
18529
|
-
|
|
19456
|
+
// src/utils/multiSelectField.ts
|
|
19457
|
+
const MULTISELECT_FIELD_TYPE = "multiselect";
|
|
19458
|
+
function toggleChoice(selected, value, options) {
|
|
19459
|
+
const next = new Set(selected);
|
|
19460
|
+
if (next.has(value)) next.delete(value);
|
|
19461
|
+
else next.add(value);
|
|
19462
|
+
return options.map((option) => option.value).filter((each) => next.has(each));
|
|
19463
|
+
}
|
|
19464
|
+
function boundsHint(minItems, maxItems) {
|
|
19465
|
+
if (minItems !== void 0 && maxItems !== void 0) return minItems === maxItems ? `Choose exactly ${minItems}` : `Choose ${minItems} to ${maxItems}`;
|
|
19466
|
+
if (minItems !== void 0) return `Choose at least ${minItems}`;
|
|
19467
|
+
if (maxItems !== void 0) return `Choose at most ${maxItems}`;
|
|
19468
|
+
}
|
|
19469
|
+
function selectionLabel(options, value) {
|
|
19470
|
+
if (value === void 0) return "No value";
|
|
19471
|
+
if (value.length === 0) return "None selected";
|
|
19472
|
+
return value.map((each) => options.find((option) => option.value === each)?.label ?? each).join(", ");
|
|
19473
|
+
}
|
|
19474
|
+
function windowStart(cursor, count, limit) {
|
|
19475
|
+
if (count <= limit) return 0;
|
|
19476
|
+
return Math.min(Math.max(0, cursor - Math.floor(limit / 2)), count - limit);
|
|
19477
|
+
}
|
|
19478
|
+
// src/utils/schemaToForm.ts
|
|
18530
19479
|
function toSelectOptions(values, names) {
|
|
18531
19480
|
const useNames = names !== void 0 && names.length === values.length;
|
|
18532
19481
|
return values.map((val, index) => ({
|
|
@@ -18534,6 +19483,19 @@ function toSelectOptions(values, names) {
|
|
|
18534
19483
|
value: String(val)
|
|
18535
19484
|
}));
|
|
18536
19485
|
}
|
|
19486
|
+
function choiceOptions(members, names) {
|
|
19487
|
+
return toSelectOptions(members, names).map((option, index) => ({
|
|
19488
|
+
label: option.label,
|
|
19489
|
+
value: String(index)
|
|
19490
|
+
}));
|
|
19491
|
+
}
|
|
19492
|
+
function choiceIds(members, chosen) {
|
|
19493
|
+
return chosen.map((value) => members.findIndex((member) => sameJsonValue(member, value))).filter((index) => index >= 0).map(String);
|
|
19494
|
+
}
|
|
19495
|
+
function memberForChoiceId(members, id) {
|
|
19496
|
+
const index = typeof id === "string" && /^\d+$/.test(id) ? Number(id) : -1;
|
|
19497
|
+
return index >= 0 && index < members.length ? members[index] : id;
|
|
19498
|
+
}
|
|
18537
19499
|
function generatedNames(base, branches) {
|
|
18538
19500
|
const declared = [...Object.keys(base.properties ?? {}), ...branches.flatMap((branch) => branch.declaredFields)];
|
|
18539
19501
|
let variant = "__variant";
|
|
@@ -18570,6 +19532,12 @@ function constOf(schema) {
|
|
|
18570
19532
|
if (typeof schema !== "object" || schema === null) return void 0;
|
|
18571
19533
|
return schema.const;
|
|
18572
19534
|
}
|
|
19535
|
+
function isChoiceArray(property) {
|
|
19536
|
+
return property.type === "array" && Array.isArray(property.items?.enum);
|
|
19537
|
+
}
|
|
19538
|
+
function declarationOf(prop) {
|
|
19539
|
+
return normalizeNullableUnion(typeof prop === "object" && prop !== null ? prop : {});
|
|
19540
|
+
}
|
|
18573
19541
|
function schemaToForm(schema, toolName) {
|
|
18574
19542
|
const title = `Test Tool: ${toolName}`;
|
|
18575
19543
|
if (!schema) return {
|
|
@@ -18625,7 +19593,7 @@ function schemaToForm(schema, toolName) {
|
|
|
18625
19593
|
}
|
|
18626
19594
|
function decodeFormValues(schema, values) {
|
|
18627
19595
|
const { base, branches } = resolveRootUnion(schema ?? {});
|
|
18628
|
-
if (branches.length === 0) return applyConstants(base.properties ?? {}, values, requiredOf(base));
|
|
19596
|
+
if (branches.length === 0) return restoreChoices(base.properties ?? {}, applyConstants(base.properties ?? {}, values, requiredOf(base)), requiredOf(base));
|
|
18629
19597
|
const { variant, prefix } = generatedNames(base, branches);
|
|
18630
19598
|
const branchIndex = selectedBranchIndex(base, branches, values);
|
|
18631
19599
|
const branch = branches[branchIndex];
|
|
@@ -18635,7 +19603,9 @@ function decodeFormValues(schema, values) {
|
|
|
18635
19603
|
});
|
|
18636
19604
|
const decoded = Object.fromEntries([...Object.entries(values).filter(([name]) => !generated.has(name)), ...branchFields(base, branches, branchIndex).map((name) => [name, values[branchFieldName(prefix, branchIndex, name)]]).filter(([, value]) => value !== void 0)]);
|
|
18637
19605
|
/* v8 ignore next -- an offerable branch always carries properties */
|
|
18638
|
-
|
|
19606
|
+
const properties = branch.schema.properties ?? {};
|
|
19607
|
+
const required = requiredOf(branch.schema);
|
|
19608
|
+
return restoreChoices(properties, applyConstants(properties, decoded, required), required);
|
|
18639
19609
|
}
|
|
18640
19610
|
function selectedBranchIndex(base, branches, values) {
|
|
18641
19611
|
const { variant } = generatedNames(base, branches);
|
|
@@ -18647,12 +19617,24 @@ function applyConstants(properties, values, required) {
|
|
|
18647
19617
|
if (pinned.length === 0) return values;
|
|
18648
19618
|
return Object.fromEntries([...Object.entries(values), ...pinned.map(([name, schema]) => [name, constOf(schema)])]);
|
|
18649
19619
|
}
|
|
19620
|
+
function restoreChoices(properties, values, required) {
|
|
19621
|
+
const choiceFields = Object.entries(properties).map(([name, prop]) => [name, declarationOf(prop)]).filter(([name, property]) => isChoiceArray(property) && property.const === void 0 && Object.hasOwn(values, name) && Array.isArray(values[name]));
|
|
19622
|
+
if (choiceFields.length === 0) return values;
|
|
19623
|
+
const restored = new Map(choiceFields.map(([name, property]) => {
|
|
19624
|
+
const chosen = values[name];
|
|
19625
|
+
if (chosen.length === 0 && !required.includes(name)) return [name, void 0];
|
|
19626
|
+
/* v8 ignore next -- `isChoiceArray` guarantees `items.enum` above */
|
|
19627
|
+
const members = property.items?.enum ?? [];
|
|
19628
|
+
return [name, chosen.map((each) => memberForChoiceId(members, each))];
|
|
19629
|
+
}));
|
|
19630
|
+
return Object.fromEntries(Object.entries(values).map(([name, value]) => restored.has(name) ? [name, restored.get(name)] : [name, value]).filter(([, value]) => value !== void 0));
|
|
19631
|
+
}
|
|
18650
19632
|
function buildFields(schema, { optional = false } = {}) {
|
|
18651
19633
|
const fields = [];
|
|
18652
19634
|
const properties = schema.properties || {};
|
|
18653
19635
|
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
18654
19636
|
for (const [key, prop] of Object.entries(properties)) {
|
|
18655
|
-
const property =
|
|
19637
|
+
const property = declarationOf(prop);
|
|
18656
19638
|
const baseField = {
|
|
18657
19639
|
name: key,
|
|
18658
19640
|
label: property.title || key,
|
|
@@ -18673,12 +19655,18 @@ function buildFields(schema, { optional = false } = {}) {
|
|
|
18673
19655
|
});
|
|
18674
19656
|
continue;
|
|
18675
19657
|
}
|
|
18676
|
-
if (property
|
|
18677
|
-
|
|
18678
|
-
|
|
18679
|
-
|
|
18680
|
-
|
|
18681
|
-
|
|
19658
|
+
if (isChoiceArray(property)) {
|
|
19659
|
+
const multi = {
|
|
19660
|
+
type: MULTISELECT_FIELD_TYPE,
|
|
19661
|
+
...baseField,
|
|
19662
|
+
options: choiceOptions(property.items.enum, property.items.enumNames),
|
|
19663
|
+
...typeof property.minItems === "number" && { minItems: property.minItems },
|
|
19664
|
+
...typeof property.maxItems === "number" && { maxItems: property.maxItems },
|
|
19665
|
+
...Array.isArray(property.default) && { initialValue: choiceIds(property.items.enum, property.default) }
|
|
19666
|
+
};
|
|
19667
|
+
fields.push(multi);
|
|
19668
|
+
continue;
|
|
19669
|
+
} else if (isStringEnum(property.enum)) field = {
|
|
18682
19670
|
type: "select",
|
|
18683
19671
|
...baseField,
|
|
18684
19672
|
/* v8 ignore next -- guarded by `isStringEnum(property.enum)` above */
|
|
@@ -18738,8 +19726,95 @@ function missingRequiredFields(schema, decoded, rawValues = {}) {
|
|
|
18738
19726
|
return value === void 0;
|
|
18739
19727
|
});
|
|
18740
19728
|
}
|
|
18741
|
-
|
|
18742
|
-
|
|
19729
|
+
function selectionCountErrors(schema, decoded, rawValues = {}) {
|
|
19730
|
+
const { base, branches } = resolveRootUnion(schema ?? {});
|
|
19731
|
+
/* v8 ignore next -- an offerable branch always carries properties */
|
|
19732
|
+
const properties = (branches.length === 0 ? base : branches[selectedBranchIndex(base, branches, rawValues)].schema).properties ?? {};
|
|
19733
|
+
return Object.entries(properties).flatMap(([name, prop]) => {
|
|
19734
|
+
const value = Object.hasOwn(decoded, name) ? decoded[name] : void 0;
|
|
19735
|
+
if (!Array.isArray(value)) return [];
|
|
19736
|
+
const { minItems, maxItems } = declarationOf(prop);
|
|
19737
|
+
if (typeof minItems === "number" && value.length < minItems) return [`${name}: choose at least ${minItems}`];
|
|
19738
|
+
if (typeof maxItems === "number" && value.length > maxItems) return [`${name}: choose at most ${maxItems}`];
|
|
19739
|
+
return [];
|
|
19740
|
+
});
|
|
19741
|
+
}
|
|
19742
|
+
function MultiSelectInput({ field, value, onChange }) {
|
|
19743
|
+
const [cursor, setCursor] = useState(0);
|
|
19744
|
+
const selected = value ?? [];
|
|
19745
|
+
const count = field.options.length;
|
|
19746
|
+
useInput((input, key) => {
|
|
19747
|
+
if (key.upArrow) setCursor((current) => Math.max(0, current - 1));
|
|
19748
|
+
else if (key.downArrow) setCursor((current) => Math.min(count - 1, current + 1));
|
|
19749
|
+
else if (input === " ") {
|
|
19750
|
+
const option = field.options[cursor];
|
|
19751
|
+
if (option) onChange(toggleChoice(selected, option.value, field.options));
|
|
19752
|
+
}
|
|
19753
|
+
});
|
|
19754
|
+
const start = windowStart(cursor, count, 8);
|
|
19755
|
+
const hint = boundsHint(field.minItems, field.maxItems);
|
|
19756
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
19757
|
+
width: "100%",
|
|
19758
|
+
borderStyle: "round",
|
|
19759
|
+
flexDirection: "column",
|
|
19760
|
+
children: [
|
|
19761
|
+
field.options.slice(start, start + 8).map((option, offset) => {
|
|
19762
|
+
const active = start + offset === cursor;
|
|
19763
|
+
const checked = selected.includes(option.value);
|
|
19764
|
+
return /* @__PURE__ */ jsxs(Text, {
|
|
19765
|
+
color: active ? "blue" : void 0,
|
|
19766
|
+
children: [
|
|
19767
|
+
active ? "❯ " : " ",
|
|
19768
|
+
checked ? "[x] " : "[ ] ",
|
|
19769
|
+
option.label ?? option.value
|
|
19770
|
+
]
|
|
19771
|
+
}, option.value);
|
|
19772
|
+
}),
|
|
19773
|
+
count > 8 && /* @__PURE__ */ jsxs(Text, {
|
|
19774
|
+
dimColor: true,
|
|
19775
|
+
children: [
|
|
19776
|
+
start + 1,
|
|
19777
|
+
"-",
|
|
19778
|
+
start + 8,
|
|
19779
|
+
" of ",
|
|
19780
|
+
count
|
|
19781
|
+
]
|
|
19782
|
+
}),
|
|
19783
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
19784
|
+
dimColor: true,
|
|
19785
|
+
children: [
|
|
19786
|
+
"Up/Down to move, Space to toggle (",
|
|
19787
|
+
selected.length,
|
|
19788
|
+
" selected)",
|
|
19789
|
+
hint ? `. ${hint}` : ""
|
|
19790
|
+
]
|
|
19791
|
+
})
|
|
19792
|
+
]
|
|
19793
|
+
});
|
|
19794
|
+
}
|
|
19795
|
+
function isMultiSelectField(field) {
|
|
19796
|
+
return field.type === MULTISELECT_FIELD_TYPE;
|
|
19797
|
+
}
|
|
19798
|
+
function asSelection(value) {
|
|
19799
|
+
return Array.isArray(value) ? value.filter((each) => typeof each === "string") : void 0;
|
|
19800
|
+
}
|
|
19801
|
+
const FORM_FIELD_MANAGERS = [{
|
|
19802
|
+
type: MULTISELECT_FIELD_TYPE,
|
|
19803
|
+
renderField: (props) => isMultiSelectField(props.field) ? /* @__PURE__ */ jsx(MultiSelectInput, {
|
|
19804
|
+
field: props.field,
|
|
19805
|
+
value: asSelection(props.value),
|
|
19806
|
+
onChange: props.onChange
|
|
19807
|
+
}) : null,
|
|
19808
|
+
renderValue: (props) => isMultiSelectField(props.field) ? /* @__PURE__ */ jsx(Fragment, { children: selectionLabel(props.field.options, asSelection(props.value)) }) : null
|
|
19809
|
+
}];
|
|
19810
|
+
// src/utils/formHeader.ts
|
|
19811
|
+
function untitledForm(form) {
|
|
19812
|
+
return {
|
|
19813
|
+
...form,
|
|
19814
|
+
title: void 0
|
|
19815
|
+
};
|
|
19816
|
+
}
|
|
19817
|
+
// ../../core/mcp/resultFile.ts
|
|
18743
19818
|
var RawResultUnavailableError = class extends Error {
|
|
18744
19819
|
method;
|
|
18745
19820
|
binaryCount;
|
|
@@ -18785,8 +19860,7 @@ function renderResultForFile(result, method, format) {
|
|
|
18785
19860
|
function renderedByteLength(data) {
|
|
18786
19861
|
return typeof data === "string" ? new TextEncoder().encode(data).length : data.length;
|
|
18787
19862
|
}
|
|
18788
|
-
|
|
18789
|
-
//#region src/utils/saveResult.ts
|
|
19863
|
+
// src/utils/saveResult.ts
|
|
18790
19864
|
function fileSafe(name) {
|
|
18791
19865
|
const safe = name.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
18792
19866
|
return safe === "" ? "tool" : safe;
|
|
@@ -18830,8 +19904,7 @@ async function writeResult(result, path, format, cwd) {
|
|
|
18830
19904
|
function errorMessage(err) {
|
|
18831
19905
|
return err instanceof Error ? err.message : String(err);
|
|
18832
19906
|
}
|
|
18833
|
-
|
|
18834
|
-
//#region src/components/SaveResultBar.tsx
|
|
19907
|
+
// src/components/SaveResultBar.tsx
|
|
18835
19908
|
function SaveResultBar({ prompt, status }) {
|
|
18836
19909
|
if (prompt) return /* @__PURE__ */ jsxs(Box, {
|
|
18837
19910
|
flexShrink: 0,
|
|
@@ -18866,9 +19939,8 @@ function SaveResultBar({ prompt, status }) {
|
|
|
18866
19939
|
});
|
|
18867
19940
|
return null;
|
|
18868
19941
|
}
|
|
18869
|
-
|
|
18870
|
-
|
|
18871
|
-
function ToolTestModal({ tool, inspectorClient, width, height, onClose, onAuthRecoveryRequired }) {
|
|
19942
|
+
// src/components/ToolTestModal.tsx
|
|
19943
|
+
function ToolTestModal({ tool, inspectorClient, width, height, onClose, inputActive = true, onAuthRecoveryRequired }) {
|
|
18872
19944
|
const [state, setState] = useState("form");
|
|
18873
19945
|
const [result, setResult] = useState(null);
|
|
18874
19946
|
const [savePrompt, setSavePromptState] = useState(null);
|
|
@@ -18942,7 +20014,7 @@ function ToolTestModal({ tool, inspectorClient, width, height, onClose, onAuthRe
|
|
|
18942
20014
|
}
|
|
18943
20015
|
}
|
|
18944
20016
|
};
|
|
18945
|
-
useInput((input, key) => handleInputRef.current(input, key), { isActive:
|
|
20017
|
+
useInput((input, key) => handleInputRef.current(input, key), { isActive: inputActive });
|
|
18946
20018
|
const openSavePrompt = () => {
|
|
18947
20019
|
if (!result?.callResult) {
|
|
18948
20020
|
setSaveStatus({
|
|
@@ -19014,6 +20086,7 @@ function ToolTestModal({ tool, inspectorClient, width, height, onClose, onAuthRe
|
|
|
19014
20086
|
}
|
|
19015
20087
|
};
|
|
19016
20088
|
const handleFormSubmit = async (rawValues) => {
|
|
20089
|
+
if (!inputActive) return;
|
|
19017
20090
|
if (!inspectorClient || !tool) return;
|
|
19018
20091
|
const values = decodeFormValues(inputSchema, rawValues);
|
|
19019
20092
|
const missing = missingRequiredFields(inputSchema, values, rawValues);
|
|
@@ -19027,6 +20100,17 @@ function ToolTestModal({ tool, inspectorClient, width, height, onClose, onAuthRe
|
|
|
19027
20100
|
setState("results");
|
|
19028
20101
|
return;
|
|
19029
20102
|
}
|
|
20103
|
+
const outOfBounds = selectionCountErrors(inputSchema, values, rawValues);
|
|
20104
|
+
if (outOfBounds.length > 0) {
|
|
20105
|
+
setResult({
|
|
20106
|
+
input: values,
|
|
20107
|
+
output: null,
|
|
20108
|
+
error: `Invalid argument${outOfBounds.length > 1 ? "s" : ""}: ${outOfBounds.join("; ")}`,
|
|
20109
|
+
duration: 0
|
|
20110
|
+
});
|
|
20111
|
+
setState("results");
|
|
20112
|
+
return;
|
|
20113
|
+
}
|
|
19030
20114
|
setState("loading");
|
|
19031
20115
|
const startTime = Date.now();
|
|
19032
20116
|
try {
|
|
@@ -19116,7 +20200,8 @@ function ToolTestModal({ tool, inspectorClient, width, height, onClose, onAuthRe
|
|
|
19116
20200
|
flexGrow: 1,
|
|
19117
20201
|
width: "100%",
|
|
19118
20202
|
children: /* @__PURE__ */ jsx(Form, {
|
|
19119
|
-
form: formStructure,
|
|
20203
|
+
form: untitledForm(formStructure),
|
|
20204
|
+
customManagers: FORM_FIELD_MANAGERS,
|
|
19120
20205
|
onSubmit: (value) => void handleFormSubmit(value)
|
|
19121
20206
|
})
|
|
19122
20207
|
}),
|
|
@@ -19224,8 +20309,7 @@ function ToolTestModal({ tool, inspectorClient, width, height, onClose, onAuthRe
|
|
|
19224
20309
|
})
|
|
19225
20310
|
});
|
|
19226
20311
|
}
|
|
19227
|
-
|
|
19228
|
-
//#region src/utils/uriTemplateToForm.ts
|
|
20312
|
+
// src/utils/uriTemplateToForm.ts
|
|
19229
20313
|
function uriTemplateToForm(uriTemplate, templateName) {
|
|
19230
20314
|
let fields = [];
|
|
19231
20315
|
try {
|
|
@@ -19249,15 +20333,14 @@ function uriTemplateToForm(uriTemplate, templateName) {
|
|
|
19249
20333
|
sections
|
|
19250
20334
|
};
|
|
19251
20335
|
}
|
|
19252
|
-
|
|
19253
|
-
//#region src/components/ResourceTestModal.tsx
|
|
20336
|
+
// src/components/ResourceTestModal.tsx
|
|
19254
20337
|
function getErrorMessage$1(error) {
|
|
19255
20338
|
if (error instanceof Error) return error.message;
|
|
19256
20339
|
if (typeof error === "string") return error;
|
|
19257
20340
|
if (error && typeof error === "object" && "message" in error) return String(error.message);
|
|
19258
20341
|
return "Unknown error";
|
|
19259
20342
|
}
|
|
19260
|
-
function ResourceTestModal({ template, inspectorClient, width, height, onClose, onAuthRecoveryRequired }) {
|
|
20343
|
+
function ResourceTestModal({ template, inspectorClient, width, height, onClose, inputActive = true, onAuthRecoveryRequired }) {
|
|
19261
20344
|
const [state, setState] = useState("form");
|
|
19262
20345
|
const [result, setResult] = useState(null);
|
|
19263
20346
|
const scrollViewRef = React.useRef(null);
|
|
@@ -19304,8 +20387,9 @@ function ResourceTestModal({ template, inspectorClient, width, height, onClose,
|
|
|
19304
20387
|
scrollViewRef.current?.scrollBy(-viewportHeight);
|
|
19305
20388
|
}
|
|
19306
20389
|
}
|
|
19307
|
-
}, { isActive:
|
|
20390
|
+
}, { isActive: inputActive });
|
|
19308
20391
|
const handleFormSubmit = async (values) => {
|
|
20392
|
+
if (!inputActive) return;
|
|
19309
20393
|
if (!inspectorClient || !template) return;
|
|
19310
20394
|
const unmetGroups = unmetRequiredGroups(requiredGroups(template.uriTemplate), values);
|
|
19311
20395
|
if (unmetGroups.length > 0) {
|
|
@@ -19408,7 +20492,7 @@ function ResourceTestModal({ template, inspectorClient, width, height, onClose,
|
|
|
19408
20492
|
children: template.description
|
|
19409
20493
|
})
|
|
19410
20494
|
}), /* @__PURE__ */ jsx(Form, {
|
|
19411
|
-
form: formStructure,
|
|
20495
|
+
form: untitledForm(formStructure),
|
|
19412
20496
|
onSubmit: (values) => handleFormSubmit(values)
|
|
19413
20497
|
})]
|
|
19414
20498
|
}),
|
|
@@ -19533,8 +20617,7 @@ function ResourceTestModal({ template, inspectorClient, width, height, onClose,
|
|
|
19533
20617
|
})
|
|
19534
20618
|
});
|
|
19535
20619
|
}
|
|
19536
|
-
|
|
19537
|
-
//#region src/utils/promptArgsToForm.ts
|
|
20620
|
+
// src/utils/promptArgsToForm.ts
|
|
19538
20621
|
function promptArgsToForm(promptArguments, promptName) {
|
|
19539
20622
|
const fields = [];
|
|
19540
20623
|
if (!promptArguments || promptArguments.length === 0) return {
|
|
@@ -19563,15 +20646,14 @@ function promptArgsToForm(promptArguments, promptName) {
|
|
|
19563
20646
|
sections
|
|
19564
20647
|
};
|
|
19565
20648
|
}
|
|
19566
|
-
|
|
19567
|
-
//#region src/components/PromptTestModal.tsx
|
|
20649
|
+
// src/components/PromptTestModal.tsx
|
|
19568
20650
|
function getErrorMessage(error) {
|
|
19569
20651
|
if (error instanceof Error) return error.message;
|
|
19570
20652
|
if (typeof error === "string") return error;
|
|
19571
20653
|
if (error && typeof error === "object" && "message" in error) return String(error.message);
|
|
19572
20654
|
return "Unknown error";
|
|
19573
20655
|
}
|
|
19574
|
-
function PromptTestModal({ prompt, inspectorClient, width, height, onClose, onAuthRecoveryRequired }) {
|
|
20656
|
+
function PromptTestModal({ prompt, inspectorClient, width, height, onClose, inputActive = true, onAuthRecoveryRequired }) {
|
|
19575
20657
|
const [state, setState] = useState("form");
|
|
19576
20658
|
const [result, setResult] = useState(null);
|
|
19577
20659
|
const scrollViewRef = React.useRef(null);
|
|
@@ -19618,8 +20700,9 @@ function PromptTestModal({ prompt, inspectorClient, width, height, onClose, onAu
|
|
|
19618
20700
|
scrollViewRef.current?.scrollBy(-viewportHeight);
|
|
19619
20701
|
}
|
|
19620
20702
|
}
|
|
19621
|
-
}, { isActive:
|
|
20703
|
+
}, { isActive: inputActive });
|
|
19622
20704
|
const handleFormSubmit = async (values) => {
|
|
20705
|
+
if (!inputActive) return;
|
|
19623
20706
|
if (!inspectorClient || !prompt) return;
|
|
19624
20707
|
setState("loading");
|
|
19625
20708
|
const startTime = Date.now();
|
|
@@ -19705,7 +20788,7 @@ function PromptTestModal({ prompt, inspectorClient, width, height, onClose, onAu
|
|
|
19705
20788
|
children: prompt.description
|
|
19706
20789
|
})
|
|
19707
20790
|
}), /* @__PURE__ */ jsx(Form, {
|
|
19708
|
-
form: formStructure,
|
|
20791
|
+
form: untitledForm(formStructure),
|
|
19709
20792
|
onSubmit: (values) => handleFormSubmit(values)
|
|
19710
20793
|
})]
|
|
19711
20794
|
}),
|
|
@@ -19818,9 +20901,8 @@ function PromptTestModal({ prompt, inspectorClient, width, height, onClose, onAu
|
|
|
19818
20901
|
})
|
|
19819
20902
|
});
|
|
19820
20903
|
}
|
|
19821
|
-
|
|
19822
|
-
|
|
19823
|
-
function DetailsModal({ title, content, width, height, onClose, copyText }) {
|
|
20904
|
+
// src/components/DetailsModal.tsx
|
|
20905
|
+
function DetailsModal({ title, content, width, height, onClose, inputActive = true, copyText }) {
|
|
19824
20906
|
const scrollViewRef = useRef(null);
|
|
19825
20907
|
const { handleCopyKey, status: copyStatus } = useCopyKeys(copyText, "details");
|
|
19826
20908
|
const [terminalDimensions, setTerminalDimensions] = React.useState({
|
|
@@ -19852,7 +20934,7 @@ function DetailsModal({ title, content, width, height, onClose, copyText }) {
|
|
|
19852
20934
|
const viewportHeight = scrollViewRef.current?.getViewportHeight() || 1;
|
|
19853
20935
|
scrollViewRef.current?.scrollBy(-viewportHeight);
|
|
19854
20936
|
}
|
|
19855
|
-
}, { isActive:
|
|
20937
|
+
}, { isActive: inputActive });
|
|
19856
20938
|
const modalWidth = terminalDimensions.width - 2;
|
|
19857
20939
|
const modalHeight = terminalDimensions.height - 2;
|
|
19858
20940
|
return /* @__PURE__ */ jsx(Box, {
|
|
@@ -19909,8 +20991,7 @@ function DetailsModal({ title, content, width, height, onClose, copyText }) {
|
|
|
19909
20991
|
})
|
|
19910
20992
|
});
|
|
19911
20993
|
}
|
|
19912
|
-
|
|
19913
|
-
//#region src/utils/keybindings.ts
|
|
20994
|
+
// src/utils/keybindings.ts
|
|
19914
20995
|
function tabAcceleratorBinding(visible) {
|
|
19915
20996
|
return {
|
|
19916
20997
|
keys: visible.map((tab) => tab.accelerator).join(" "),
|
|
@@ -20157,10 +21238,9 @@ function keyColumnWidth(sections) {
|
|
|
20157
21238
|
for (const section of sections) for (const binding of section.bindings) width = Math.max(width, binding.keys.length);
|
|
20158
21239
|
return width;
|
|
20159
21240
|
}
|
|
20160
|
-
|
|
20161
|
-
//#region src/components/HelpOverlay.tsx
|
|
21241
|
+
// src/components/HelpOverlay.tsx
|
|
20162
21242
|
const COLUMN_GAP = 2;
|
|
20163
|
-
function HelpOverlay({ sections, width, height, onClose }) {
|
|
21243
|
+
function HelpOverlay({ sections, width, height, onClose, inputActive = true }) {
|
|
20164
21244
|
const scrollViewRef = useRef(null);
|
|
20165
21245
|
const keysWidth = keyColumnWidth(sections) + COLUMN_GAP;
|
|
20166
21246
|
useInput((input, key) => {
|
|
@@ -20170,7 +21250,7 @@ function HelpOverlay({ sections, width, height, onClose }) {
|
|
|
20170
21250
|
else if (key.upArrow) view?.scrollBy(-1);
|
|
20171
21251
|
else if (key.pageDown) view?.scrollBy(view.getViewportHeight());
|
|
20172
21252
|
else if (key.pageUp) view?.scrollBy(-view.getViewportHeight());
|
|
20173
|
-
});
|
|
21253
|
+
}, { isActive: inputActive });
|
|
20174
21254
|
return /* @__PURE__ */ jsx(Box, {
|
|
20175
21255
|
position: "absolute",
|
|
20176
21256
|
width,
|
|
@@ -20229,8 +21309,7 @@ function HelpOverlay({ sections, width, height, onClose }) {
|
|
|
20229
21309
|
})
|
|
20230
21310
|
});
|
|
20231
21311
|
}
|
|
20232
|
-
|
|
20233
|
-
//#region src/components/TasksTab.tsx
|
|
21312
|
+
// src/components/TasksTab.tsx
|
|
20234
21313
|
const STATUS_STYLE = {
|
|
20235
21314
|
working: {
|
|
20236
21315
|
glyph: "◐",
|
|
@@ -20582,8 +21661,7 @@ function subscribableResources(resources, subscriptions) {
|
|
|
20582
21661
|
}
|
|
20583
21662
|
return rows;
|
|
20584
21663
|
}
|
|
20585
|
-
|
|
20586
|
-
//#region src/components/SubscriptionsTab.tsx
|
|
21664
|
+
// src/components/SubscriptionsTab.tsx
|
|
20587
21665
|
const STREAM_STATUS_TEXT = {
|
|
20588
21666
|
connecting: {
|
|
20589
21667
|
text: "connecting…",
|
|
@@ -20863,8 +21941,7 @@ function SubscriptionsTab({ resources, subscriptions, streamState, messages, ins
|
|
|
20863
21941
|
})]
|
|
20864
21942
|
});
|
|
20865
21943
|
}
|
|
20866
|
-
|
|
20867
|
-
//#region src/components/RootsModal.tsx
|
|
21944
|
+
// src/components/RootsModal.tsx
|
|
20868
21945
|
const ADD_ROOT_FORM = {
|
|
20869
21946
|
title: "Add Root",
|
|
20870
21947
|
sections: [{
|
|
@@ -20890,7 +21967,7 @@ function rootFromForm(values) {
|
|
|
20890
21967
|
name
|
|
20891
21968
|
} : { uri };
|
|
20892
21969
|
}
|
|
20893
|
-
function RootsModal({ roots, inspectorClient, connected, width, height, onClose }) {
|
|
21970
|
+
function RootsModal({ roots, inspectorClient, connected, width, height, onClose, inputActive = true }) {
|
|
20894
21971
|
const [mode, setMode] = useState("list");
|
|
20895
21972
|
const [error, setError] = useState(null);
|
|
20896
21973
|
const [saving, setSaving] = useState(false);
|
|
@@ -20915,6 +21992,7 @@ function RootsModal({ roots, inspectorClient, connected, width, height, onClose
|
|
|
20915
21992
|
}
|
|
20916
21993
|
};
|
|
20917
21994
|
const handleSubmit = (values) => {
|
|
21995
|
+
if (!inputActive) return;
|
|
20918
21996
|
const root = rootFromForm(values);
|
|
20919
21997
|
if ("error" in root) {
|
|
20920
21998
|
setError(root.error);
|
|
@@ -20946,7 +22024,7 @@ function RootsModal({ roots, inspectorClient, connected, width, height, onClose
|
|
|
20946
22024
|
}
|
|
20947
22025
|
save(roots.filter((_, i) => i !== selectedIndex));
|
|
20948
22026
|
}
|
|
20949
|
-
});
|
|
22027
|
+
}, { isActive: inputActive });
|
|
20950
22028
|
return /* @__PURE__ */ jsx(Box, {
|
|
20951
22029
|
position: "absolute",
|
|
20952
22030
|
width,
|
|
@@ -21057,8 +22135,468 @@ function RootsModal({ roots, inspectorClient, connected, width, height, onClose
|
|
|
21057
22135
|
})
|
|
21058
22136
|
});
|
|
21059
22137
|
}
|
|
21060
|
-
|
|
21061
|
-
|
|
22138
|
+
// src/utils/pendingRequests.ts
|
|
22139
|
+
const SAMPLING_STOP_REASONS = [
|
|
22140
|
+
"endTurn",
|
|
22141
|
+
"stopSequence",
|
|
22142
|
+
"maxTokens"
|
|
22143
|
+
];
|
|
22144
|
+
const DEFAULT_SAMPLING_MODEL = "stub-model";
|
|
22145
|
+
const SAMPLING_RESPONSE_FORM = { sections: [{
|
|
22146
|
+
title: "Response",
|
|
22147
|
+
fields: [
|
|
22148
|
+
{
|
|
22149
|
+
type: "string",
|
|
22150
|
+
name: "text",
|
|
22151
|
+
label: "Response text"
|
|
22152
|
+
},
|
|
22153
|
+
{
|
|
22154
|
+
type: "string",
|
|
22155
|
+
name: "model",
|
|
22156
|
+
label: "Model",
|
|
22157
|
+
required: true,
|
|
22158
|
+
initialValue: DEFAULT_SAMPLING_MODEL
|
|
22159
|
+
},
|
|
22160
|
+
{
|
|
22161
|
+
type: "select",
|
|
22162
|
+
name: "stopReason",
|
|
22163
|
+
label: "Stop reason",
|
|
22164
|
+
required: true,
|
|
22165
|
+
initialValue: "endTurn",
|
|
22166
|
+
options: SAMPLING_STOP_REASONS.map((reason) => ({
|
|
22167
|
+
label: reason,
|
|
22168
|
+
value: reason
|
|
22169
|
+
}))
|
|
22170
|
+
}
|
|
22171
|
+
]
|
|
22172
|
+
}] };
|
|
22173
|
+
function samplingResultFromForm(values) {
|
|
22174
|
+
const text = typeof values.text === "string" ? values.text : "";
|
|
22175
|
+
return {
|
|
22176
|
+
role: "assistant",
|
|
22177
|
+
model: typeof values.model === "string" && values.model.trim() !== "" ? values.model.trim() : DEFAULT_SAMPLING_MODEL,
|
|
22178
|
+
stopReason: typeof values.stopReason === "string" ? values.stopReason : "endTurn",
|
|
22179
|
+
content: {
|
|
22180
|
+
type: "text",
|
|
22181
|
+
text
|
|
22182
|
+
}
|
|
22183
|
+
};
|
|
22184
|
+
}
|
|
22185
|
+
function describeBlock(block) {
|
|
22186
|
+
if (typeof block !== "object" || block === null) return String(block);
|
|
22187
|
+
const typed = block;
|
|
22188
|
+
if (typed.type === "text" && typeof typed.text === "string") return typed.text;
|
|
22189
|
+
if (typeof typed.mimeType === "string") return `[${String(typed.type)}: ${typed.mimeType}]`;
|
|
22190
|
+
if (typeof typed.name === "string") return `[${String(typed.type)}: ${typed.name}]`;
|
|
22191
|
+
return `[${String(typed.type ?? "unknown")}]`;
|
|
22192
|
+
}
|
|
22193
|
+
function describeSamplingRequest(params) {
|
|
22194
|
+
const lines = [];
|
|
22195
|
+
if (params.systemPrompt) lines.push(`System prompt: ${params.systemPrompt}`);
|
|
22196
|
+
lines.push(`Max tokens: ${params.maxTokens}`);
|
|
22197
|
+
const hints = (params.modelPreferences?.hints ?? []).map((hint) => hint.name).filter((name) => typeof name === "string");
|
|
22198
|
+
if (hints.length > 0) lines.push(`Model hints: ${hints.join(", ")}`);
|
|
22199
|
+
lines.push("");
|
|
22200
|
+
for (const message of params.messages) {
|
|
22201
|
+
const [first = "", ...rest] = (Array.isArray(message.content) ? message.content : [message.content]).map(describeBlock).join(" ").split("\n");
|
|
22202
|
+
lines.push(`${message.role}: ${first}`);
|
|
22203
|
+
for (const line of rest) lines.push(` ${line}`);
|
|
22204
|
+
}
|
|
22205
|
+
return lines;
|
|
22206
|
+
}
|
|
22207
|
+
function constOptions(members) {
|
|
22208
|
+
if (!Array.isArray(members) || members.length === 0) return void 0;
|
|
22209
|
+
const values = [];
|
|
22210
|
+
const names = [];
|
|
22211
|
+
for (const member of members) {
|
|
22212
|
+
if (typeof member !== "object" || member === null) return void 0;
|
|
22213
|
+
const { const: value, title } = member;
|
|
22214
|
+
if (typeof value !== "string") return void 0;
|
|
22215
|
+
values.push(value);
|
|
22216
|
+
names.push(typeof title === "string" ? title : value);
|
|
22217
|
+
}
|
|
22218
|
+
return {
|
|
22219
|
+
values,
|
|
22220
|
+
names
|
|
22221
|
+
};
|
|
22222
|
+
}
|
|
22223
|
+
function normalizeElicitationSchema(schema) {
|
|
22224
|
+
const properties = Object.fromEntries(Object.entries(schema.properties).map(([name, property]) => {
|
|
22225
|
+
const { oneOf, items, ...rest } = property;
|
|
22226
|
+
const single = constOptions(oneOf);
|
|
22227
|
+
if (single) return [name, {
|
|
22228
|
+
...rest,
|
|
22229
|
+
enum: single.values,
|
|
22230
|
+
enumNames: single.names
|
|
22231
|
+
}];
|
|
22232
|
+
const multi = constOptions(items?.anyOf);
|
|
22233
|
+
if (multi) return [name, {
|
|
22234
|
+
...rest,
|
|
22235
|
+
items: {
|
|
22236
|
+
enum: multi.values,
|
|
22237
|
+
enumNames: multi.names
|
|
22238
|
+
}
|
|
22239
|
+
}];
|
|
22240
|
+
return [name, property];
|
|
22241
|
+
}));
|
|
22242
|
+
return {
|
|
22243
|
+
...schema,
|
|
22244
|
+
properties
|
|
22245
|
+
};
|
|
22246
|
+
}
|
|
22247
|
+
function elicitationForm(schema) {
|
|
22248
|
+
const [first, ...rest] = schemaToForm(normalizeElicitationSchema(schema), "elicitation").sections;
|
|
22249
|
+
return { sections: [{
|
|
22250
|
+
...first,
|
|
22251
|
+
title: "Response"
|
|
22252
|
+
}, ...rest] };
|
|
22253
|
+
}
|
|
22254
|
+
function elicitationContentFromForm(schema, rawValues) {
|
|
22255
|
+
const normalized = normalizeElicitationSchema(schema);
|
|
22256
|
+
const decoded = decodeFormValues(normalized, rawValues);
|
|
22257
|
+
const missing = missingRequiredFields(normalized, decoded, rawValues);
|
|
22258
|
+
if (missing.length > 0) return { missing };
|
|
22259
|
+
const invalid = selectionCountErrors(normalized, decoded, rawValues);
|
|
22260
|
+
if (invalid.length > 0) return { invalid };
|
|
22261
|
+
return { result: {
|
|
22262
|
+
action: "accept",
|
|
22263
|
+
content: Object.fromEntries(Object.entries(decoded).filter(([, value]) => value !== void 0 && value !== null).map(([name, value]) => {
|
|
22264
|
+
return [name, normalized.properties[name]?.type === "array" && typeof value === "string" ? [value] : value];
|
|
22265
|
+
}))
|
|
22266
|
+
} };
|
|
22267
|
+
}
|
|
22268
|
+
function messageBoxHeight(message, columns, terminalRows) {
|
|
22269
|
+
const perRow = Math.max(1, columns);
|
|
22270
|
+
const wrapped = message.split("\n").reduce((rows, line) => rows + Math.max(1, Math.ceil(line.length / perRow)), 0);
|
|
22271
|
+
return Math.max(1, Math.min(wrapped, Math.floor(terminalRows / 3)));
|
|
22272
|
+
}
|
|
22273
|
+
function elicitationUrlRefusal(url) {
|
|
22274
|
+
try {
|
|
22275
|
+
const { protocol } = new URL(url);
|
|
22276
|
+
if (protocol === "http:" || protocol === "https:") return void 0;
|
|
22277
|
+
} catch {}
|
|
22278
|
+
return "Refusing to open this URL: only http: and https: URLs can be opened from an elicitation request.";
|
|
22279
|
+
}
|
|
22280
|
+
// src/components/PendingRequestModal.tsx
|
|
22281
|
+
function useSettle(onError) {
|
|
22282
|
+
const busyRef = useRef(false);
|
|
22283
|
+
return (action) => {
|
|
22284
|
+
if (busyRef.current) return;
|
|
22285
|
+
busyRef.current = true;
|
|
22286
|
+
action().catch((err) => {
|
|
22287
|
+
busyRef.current = false;
|
|
22288
|
+
onError(errorMessage$1(err));
|
|
22289
|
+
});
|
|
22290
|
+
};
|
|
22291
|
+
}
|
|
22292
|
+
function useDismissPrompt() {
|
|
22293
|
+
const [confirming, setConfirming] = useState(false);
|
|
22294
|
+
const openRef = useRef(false);
|
|
22295
|
+
const closingRef = useRef(false);
|
|
22296
|
+
return {
|
|
22297
|
+
confirming,
|
|
22298
|
+
isOpen: () => openRef.current,
|
|
22299
|
+
open: () => {
|
|
22300
|
+
openRef.current = true;
|
|
22301
|
+
setConfirming(true);
|
|
22302
|
+
},
|
|
22303
|
+
close: () => {
|
|
22304
|
+
openRef.current = false;
|
|
22305
|
+
closingRef.current = true;
|
|
22306
|
+
setConfirming(false);
|
|
22307
|
+
setTimeout(() => {
|
|
22308
|
+
closingRef.current = false;
|
|
22309
|
+
}, 0);
|
|
22310
|
+
},
|
|
22311
|
+
submitBlocked: () => openRef.current || closingRef.current
|
|
22312
|
+
};
|
|
22313
|
+
}
|
|
22314
|
+
function originNote(origin, taskId) {
|
|
22315
|
+
if (origin === "task-input-required") return `Requested by task ${taskId ?? "(unknown)"} (input_required)`;
|
|
22316
|
+
if (origin === "input-required") return "Requested mid-call (input_required round)";
|
|
22317
|
+
return null;
|
|
22318
|
+
}
|
|
22319
|
+
function ModalFrame({ title, hint, queueLabel, note, status, width, height, children }) {
|
|
22320
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
22321
|
+
position: "absolute",
|
|
22322
|
+
width,
|
|
22323
|
+
height,
|
|
22324
|
+
flexDirection: "column",
|
|
22325
|
+
justifyContent: "center",
|
|
22326
|
+
alignItems: "center",
|
|
22327
|
+
children: /* @__PURE__ */ jsxs(Box, {
|
|
22328
|
+
width: width - 2,
|
|
22329
|
+
height: height - 2,
|
|
22330
|
+
borderStyle: "single",
|
|
22331
|
+
borderColor: "yellow",
|
|
22332
|
+
flexDirection: "column",
|
|
22333
|
+
paddingX: 1,
|
|
22334
|
+
paddingY: 1,
|
|
22335
|
+
backgroundColor: "black",
|
|
22336
|
+
children: [
|
|
22337
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
22338
|
+
flexShrink: 0,
|
|
22339
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
22340
|
+
bold: true,
|
|
22341
|
+
color: "yellow",
|
|
22342
|
+
children: title
|
|
22343
|
+
}), queueLabel && /* @__PURE__ */ jsxs(Text, {
|
|
22344
|
+
dimColor: true,
|
|
22345
|
+
children: [
|
|
22346
|
+
" (",
|
|
22347
|
+
queueLabel,
|
|
22348
|
+
")"
|
|
22349
|
+
]
|
|
22350
|
+
})]
|
|
22351
|
+
}),
|
|
22352
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22353
|
+
flexShrink: 0,
|
|
22354
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22355
|
+
dimColor: true,
|
|
22356
|
+
children: hint
|
|
22357
|
+
})
|
|
22358
|
+
}),
|
|
22359
|
+
note && /* @__PURE__ */ jsx(Box, {
|
|
22360
|
+
flexShrink: 0,
|
|
22361
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22362
|
+
dimColor: true,
|
|
22363
|
+
children: note
|
|
22364
|
+
})
|
|
22365
|
+
}),
|
|
22366
|
+
status && /* @__PURE__ */ jsx(Box, {
|
|
22367
|
+
flexShrink: 0,
|
|
22368
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22369
|
+
color: "red",
|
|
22370
|
+
children: status
|
|
22371
|
+
})
|
|
22372
|
+
}),
|
|
22373
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22374
|
+
flexGrow: 1,
|
|
22375
|
+
flexDirection: "column",
|
|
22376
|
+
overflow: "hidden",
|
|
22377
|
+
marginTop: 1,
|
|
22378
|
+
children
|
|
22379
|
+
})
|
|
22380
|
+
]
|
|
22381
|
+
})
|
|
22382
|
+
});
|
|
22383
|
+
}
|
|
22384
|
+
function DismissPrompt({ choices }) {
|
|
22385
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
22386
|
+
flexShrink: 0,
|
|
22387
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22388
|
+
color: "yellow",
|
|
22389
|
+
children: choices
|
|
22390
|
+
})
|
|
22391
|
+
});
|
|
22392
|
+
}
|
|
22393
|
+
function SamplingRequest({ sample, queueLabel, width, height }) {
|
|
22394
|
+
const [status, setStatus] = useState(null);
|
|
22395
|
+
const settle = useSettle(setStatus);
|
|
22396
|
+
const prompt = useDismissPrompt();
|
|
22397
|
+
const scrollViewRef = useRef(null);
|
|
22398
|
+
useInput((input, key) => {
|
|
22399
|
+
if (prompt.isOpen()) {
|
|
22400
|
+
prompt.close();
|
|
22401
|
+
if (input === "r") settle(() => sample.reject(/* @__PURE__ */ new Error("Sampling request rejected by user.")));
|
|
22402
|
+
return;
|
|
22403
|
+
}
|
|
22404
|
+
if (key.escape) prompt.open();
|
|
22405
|
+
else if (key.pageDown) scrollViewRef.current?.scrollBy(1);
|
|
22406
|
+
else if (key.pageUp) scrollViewRef.current?.scrollBy(-1);
|
|
22407
|
+
});
|
|
22408
|
+
const summaryHeight = Math.max(3, Math.floor((height - 8) * .4));
|
|
22409
|
+
return /* @__PURE__ */ jsxs(ModalFrame, {
|
|
22410
|
+
title: "Sampling request",
|
|
22411
|
+
hint: "(Enter on Submit to approve, ESC to reject, PgUp/PgDn to scroll)",
|
|
22412
|
+
queueLabel,
|
|
22413
|
+
note: originNote(sample.origin, sample.taskId),
|
|
22414
|
+
status,
|
|
22415
|
+
width,
|
|
22416
|
+
height,
|
|
22417
|
+
children: [
|
|
22418
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22419
|
+
height: summaryHeight,
|
|
22420
|
+
flexShrink: 0,
|
|
22421
|
+
flexDirection: "column",
|
|
22422
|
+
overflow: "hidden",
|
|
22423
|
+
children: /* @__PURE__ */ jsx(ScrollView, {
|
|
22424
|
+
ref: scrollViewRef,
|
|
22425
|
+
children: describeSamplingRequest(sample.request.params).map((line, idx) => /* @__PURE__ */ jsx(Text, { children: line || " " }, idx))
|
|
22426
|
+
})
|
|
22427
|
+
}),
|
|
22428
|
+
prompt.confirming && /* @__PURE__ */ jsx(DismissPrompt, { choices: "Reject this sampling request? r: reject any other key: back" }),
|
|
22429
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22430
|
+
flexGrow: 1,
|
|
22431
|
+
width: "100%",
|
|
22432
|
+
children: /* @__PURE__ */ jsx(Form, {
|
|
22433
|
+
form: SAMPLING_RESPONSE_FORM,
|
|
22434
|
+
onSubmit: (values) => {
|
|
22435
|
+
if (prompt.submitBlocked()) return;
|
|
22436
|
+
settle(() => sample.respond(samplingResultFromForm(values)));
|
|
22437
|
+
}
|
|
22438
|
+
})
|
|
22439
|
+
})
|
|
22440
|
+
]
|
|
22441
|
+
});
|
|
22442
|
+
}
|
|
22443
|
+
function settleElicitation(elicitation, result, inspectorClient) {
|
|
22444
|
+
if (result.action === "cancel" && elicitation.origin === "task-input-required" && elicitation.taskId && inspectorClient) return inspectorClient.cancelRequestorTask(elicitation.taskId);
|
|
22445
|
+
return elicitation.respond(result);
|
|
22446
|
+
}
|
|
22447
|
+
function ElicitationFormRequest({ elicitation, params, inspectorClient, queueLabel, width, height }) {
|
|
22448
|
+
const [status, setStatus] = useState(null);
|
|
22449
|
+
const settleWith = useSettle(setStatus);
|
|
22450
|
+
const prompt = useDismissPrompt();
|
|
22451
|
+
const messageRef = useRef(null);
|
|
22452
|
+
const [form] = useState(() => elicitationForm(params.requestedSchema));
|
|
22453
|
+
const settle = (result) => settleWith(() => settleElicitation(elicitation, result, inspectorClient));
|
|
22454
|
+
useInput((input, key) => {
|
|
22455
|
+
if (prompt.isOpen()) {
|
|
22456
|
+
prompt.close();
|
|
22457
|
+
if (input === "d") settle({ action: "decline" });
|
|
22458
|
+
else if (input === "c") settle({ action: "cancel" });
|
|
22459
|
+
return;
|
|
22460
|
+
}
|
|
22461
|
+
if (key.escape) prompt.open();
|
|
22462
|
+
else if (key.pageDown) messageRef.current?.scrollBy(1);
|
|
22463
|
+
else if (key.pageUp) messageRef.current?.scrollBy(-1);
|
|
22464
|
+
});
|
|
22465
|
+
const handleSubmit = (values) => {
|
|
22466
|
+
if (prompt.submitBlocked()) return;
|
|
22467
|
+
const outcome = elicitationContentFromForm(params.requestedSchema, values);
|
|
22468
|
+
if ("missing" in outcome) {
|
|
22469
|
+
setStatus(`Missing required field${outcome.missing.length > 1 ? "s" : ""}: ${outcome.missing.join(", ")}`);
|
|
22470
|
+
return;
|
|
22471
|
+
}
|
|
22472
|
+
if ("invalid" in outcome) {
|
|
22473
|
+
setStatus(`Invalid field${outcome.invalid.length > 1 ? "s" : ""}: ${outcome.invalid.join("; ")}`);
|
|
22474
|
+
return;
|
|
22475
|
+
}
|
|
22476
|
+
settle(outcome.result);
|
|
22477
|
+
};
|
|
22478
|
+
return /* @__PURE__ */ jsxs(ModalFrame, {
|
|
22479
|
+
title: "Elicitation request",
|
|
22480
|
+
hint: "(Enter on Submit to accept, ESC to decline or cancel, PgUp/PgDn to scroll)",
|
|
22481
|
+
queueLabel,
|
|
22482
|
+
note: originNote(elicitation.origin, elicitation.taskId),
|
|
22483
|
+
status,
|
|
22484
|
+
width,
|
|
22485
|
+
height,
|
|
22486
|
+
children: [
|
|
22487
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22488
|
+
height: messageBoxHeight(params.message, width - 6, height),
|
|
22489
|
+
flexShrink: 0,
|
|
22490
|
+
flexDirection: "column",
|
|
22491
|
+
overflow: "hidden",
|
|
22492
|
+
marginBottom: 1,
|
|
22493
|
+
children: /* @__PURE__ */ jsx(ScrollView, {
|
|
22494
|
+
ref: messageRef,
|
|
22495
|
+
children: /* @__PURE__ */ jsx(Text, { children: params.message })
|
|
22496
|
+
})
|
|
22497
|
+
}),
|
|
22498
|
+
prompt.confirming && /* @__PURE__ */ jsx(DismissPrompt, { choices: "Dismiss this request? d: decline c: cancel any other key: back" }),
|
|
22499
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22500
|
+
flexGrow: 1,
|
|
22501
|
+
width: "100%",
|
|
22502
|
+
children: /* @__PURE__ */ jsx(Form, {
|
|
22503
|
+
form,
|
|
22504
|
+
customManagers: FORM_FIELD_MANAGERS,
|
|
22505
|
+
onSubmit: (values) => handleSubmit(values)
|
|
22506
|
+
})
|
|
22507
|
+
})
|
|
22508
|
+
]
|
|
22509
|
+
});
|
|
22510
|
+
}
|
|
22511
|
+
function ElicitationUrlRequest({ elicitation, message, url, inspectorClient, queueLabel, width, height }) {
|
|
22512
|
+
const [status, setStatus] = useState(null);
|
|
22513
|
+
const settleWith = useSettle(setStatus);
|
|
22514
|
+
const refusal = elicitationUrlRefusal(url);
|
|
22515
|
+
const messageRef = useRef(null);
|
|
22516
|
+
const settle = (result) => settleWith(() => settleElicitation(elicitation, result, inspectorClient));
|
|
22517
|
+
useInput((input, key) => {
|
|
22518
|
+
if (input === "o") {
|
|
22519
|
+
if (refusal) {
|
|
22520
|
+
setStatus(refusal);
|
|
22521
|
+
return;
|
|
22522
|
+
}
|
|
22523
|
+
openUrl(url, setStatus);
|
|
22524
|
+
} else if (key.return) settle({ action: "accept" });
|
|
22525
|
+
else if (input === "d") settle({ action: "decline" });
|
|
22526
|
+
else if (key.escape || input === "c") settle({ action: "cancel" });
|
|
22527
|
+
else if (key.pageDown) messageRef.current?.scrollBy(1);
|
|
22528
|
+
else if (key.pageUp) messageRef.current?.scrollBy(-1);
|
|
22529
|
+
});
|
|
22530
|
+
return /* @__PURE__ */ jsxs(ModalFrame, {
|
|
22531
|
+
title: "Elicitation request (URL)",
|
|
22532
|
+
hint: "(o: open in browser, Enter: done, d: decline, ESC: cancel, PgUp/PgDn: scroll)",
|
|
22533
|
+
queueLabel,
|
|
22534
|
+
note: originNote(elicitation.origin, elicitation.taskId),
|
|
22535
|
+
status,
|
|
22536
|
+
width,
|
|
22537
|
+
height,
|
|
22538
|
+
children: [
|
|
22539
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22540
|
+
flexShrink: 0,
|
|
22541
|
+
marginBottom: 1,
|
|
22542
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22543
|
+
color: "cyan",
|
|
22544
|
+
children: url
|
|
22545
|
+
})
|
|
22546
|
+
}),
|
|
22547
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22548
|
+
height: messageBoxHeight(message, width - 6, height),
|
|
22549
|
+
flexShrink: 0,
|
|
22550
|
+
flexDirection: "column",
|
|
22551
|
+
overflow: "hidden",
|
|
22552
|
+
children: /* @__PURE__ */ jsx(ScrollView, {
|
|
22553
|
+
ref: messageRef,
|
|
22554
|
+
children: /* @__PURE__ */ jsx(Text, { children: message })
|
|
22555
|
+
})
|
|
22556
|
+
}),
|
|
22557
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22558
|
+
flexShrink: 0,
|
|
22559
|
+
marginTop: 1,
|
|
22560
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22561
|
+
dimColor: true,
|
|
22562
|
+
children: "Complete the flow in your browser, then press Enter. The Inspector cannot observe the external flow finishing."
|
|
22563
|
+
})
|
|
22564
|
+
})
|
|
22565
|
+
]
|
|
22566
|
+
});
|
|
22567
|
+
}
|
|
22568
|
+
function PendingRequestModal({ pendingSamples, pendingElicitations, inspectorClient, width, height }) {
|
|
22569
|
+
const total = pendingSamples.length + pendingElicitations.length;
|
|
22570
|
+
const queueLabel = total > 1 ? `${total} pending` : "";
|
|
22571
|
+
const sample = pendingSamples[0];
|
|
22572
|
+
if (sample) return /* @__PURE__ */ jsx(SamplingRequest, {
|
|
22573
|
+
sample,
|
|
22574
|
+
queueLabel,
|
|
22575
|
+
width,
|
|
22576
|
+
height
|
|
22577
|
+
}, sample.id);
|
|
22578
|
+
const elicitation = pendingElicitations[0];
|
|
22579
|
+
if (!elicitation) return null;
|
|
22580
|
+
const params = elicitation.request.params;
|
|
22581
|
+
if (params.mode === "url") return /* @__PURE__ */ jsx(ElicitationUrlRequest, {
|
|
22582
|
+
elicitation,
|
|
22583
|
+
message: params.message,
|
|
22584
|
+
url: params.url,
|
|
22585
|
+
inspectorClient,
|
|
22586
|
+
queueLabel,
|
|
22587
|
+
width,
|
|
22588
|
+
height
|
|
22589
|
+
}, elicitation.id);
|
|
22590
|
+
return /* @__PURE__ */ jsx(ElicitationFormRequest, {
|
|
22591
|
+
elicitation,
|
|
22592
|
+
params,
|
|
22593
|
+
inspectorClient,
|
|
22594
|
+
queueLabel,
|
|
22595
|
+
width,
|
|
22596
|
+
height
|
|
22597
|
+
}, elicitation.id);
|
|
22598
|
+
}
|
|
22599
|
+
// src/App.tsx
|
|
21062
22600
|
const APP_NAME = "MCP Inspector TUI";
|
|
21063
22601
|
const APP_DESCRIPTION = "Terminal User Interface for the Model Context Protocol Inspector";
|
|
21064
22602
|
const APP_VERSION = readInspectorVersion(import.meta.url);
|
|
@@ -21075,7 +22613,6 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
21075
22613
|
const [activeTab, setActiveTab] = useState("info");
|
|
21076
22614
|
const [paneFocus, setFocus] = useState("serverList");
|
|
21077
22615
|
const [helpOpen, setHelpOpen] = useState(false);
|
|
21078
|
-
const focus = helpOpen ? "help" : paneFocus;
|
|
21079
22616
|
const [listFilterEditing, setListFilterEditing] = useState(false);
|
|
21080
22617
|
const [listFilterClaimsEscape, setListFilterClaimsEscape] = useState(false);
|
|
21081
22618
|
const [tabCounts, setTabCounts] = useState({});
|
|
@@ -21178,6 +22715,11 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
21178
22715
|
...defaultMetadata && Object.keys(defaultMetadata).length > 0 && { defaultMetadata },
|
|
21179
22716
|
...savedSettings && { serverSettings: savedSettings },
|
|
21180
22717
|
roots: cleanRoots(savedSettings?.roots ?? []),
|
|
22718
|
+
sample: true,
|
|
22719
|
+
elicit: {
|
|
22720
|
+
form: true,
|
|
22721
|
+
url: true
|
|
22722
|
+
},
|
|
21181
22723
|
...savedSettings?.protocolEra && { versionNegotiation: eraToVersionNegotiation(savedSettings.protocolEra) },
|
|
21182
22724
|
...clientAuthOptions
|
|
21183
22725
|
};
|
|
@@ -21333,6 +22875,9 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
21333
22875
|
if (activeTab === "auth" && selectedServerConfig && !isOAuthCapableServerConfig(selectedServerConfig)) setActiveTab("info");
|
|
21334
22876
|
}, [activeTab, selectedServerConfig]);
|
|
21335
22877
|
const selectedInspectorClient = useMemo(() => selectedServer ? inspectorClients[selectedServer] : null, [selectedServer, inspectorClients]);
|
|
22878
|
+
const { pendingSamples, pendingElicitations } = usePendingClientRequests(selectedInspectorClient);
|
|
22879
|
+
const pendingRequestOpen = pendingSamples.length + pendingElicitations.length > 0;
|
|
22880
|
+
const focus = helpOpen || pendingRequestOpen ? "overlay" : paneFocus;
|
|
21336
22881
|
const { status: inspectorStatus, capabilities: inspectorCapabilities, serverInfo: inspectorServerInfo, instructions: inspectorInstructions, connect: connectInspector, disconnect: disconnectInspector, lastError: inspectorLastError } = useInspectorClient(selectedInspectorClient);
|
|
21337
22882
|
const selectedMessageLogState = useMemo(() => selectedServer && messageLogStates[selectedServer] ? messageLogStates[selectedServer] : null, [selectedServer, messageLogStates]);
|
|
21338
22883
|
const selectedFetchRequestLogState = useMemo(() => selectedServer && fetchRequestLogStates[selectedServer] ? fetchRequestLogStates[selectedServer] : null, [selectedServer, fetchRequestLogStates]);
|
|
@@ -21341,6 +22886,7 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
21341
22886
|
const { fetchRequests: inspectorFetchRequests } = useFetchRequestLog(selectedFetchRequestLogState);
|
|
21342
22887
|
const { stderrLogs: inspectorStderrLogs } = useStderrLog(selectedStderrLogState);
|
|
21343
22888
|
const { tools: managedTools } = useManagedTools(selectedInspectorClient, useMemo(() => selectedServer && managedToolsStates[selectedServer] ? managedToolsStates[selectedServer] : null, [selectedServer, managedToolsStates]));
|
|
22889
|
+
const sortedTools = useMemo(() => [...managedTools].sort(compareToolsByName), [managedTools]);
|
|
21344
22890
|
const selectedManagedResourcesState = useMemo(() => selectedServer && managedResourcesStates[selectedServer] ? managedResourcesStates[selectedServer] : null, [selectedServer, managedResourcesStates]);
|
|
21345
22891
|
const selectedManagedResourceTemplatesState = useMemo(() => selectedServer && managedResourceTemplatesStates[selectedServer] ? managedResourceTemplatesStates[selectedServer] : null, [selectedServer, managedResourceTemplatesStates]);
|
|
21346
22892
|
const selectedManagedPromptsState = useMemo(() => selectedServer && managedPromptsStates[selectedServer] ? managedPromptsStates[selectedServer] : null, [selectedServer, managedPromptsStates]);
|
|
@@ -21640,7 +23186,7 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
21640
23186
|
resources: managedResources,
|
|
21641
23187
|
resourceTemplates: managedResourceTemplates,
|
|
21642
23188
|
prompts: managedPrompts,
|
|
21643
|
-
tools:
|
|
23189
|
+
tools: sortedTools,
|
|
21644
23190
|
stderrLogs: inspectorStderrLogs
|
|
21645
23191
|
};
|
|
21646
23192
|
}, [
|
|
@@ -21654,7 +23200,7 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
21654
23200
|
managedResources,
|
|
21655
23201
|
managedResourceTemplates,
|
|
21656
23202
|
managedPrompts,
|
|
21657
|
-
|
|
23203
|
+
sortedTools,
|
|
21658
23204
|
inspectorStderrLogs
|
|
21659
23205
|
]);
|
|
21660
23206
|
const renderResourceDetails = (resource) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -22041,7 +23587,7 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
22041
23587
|
inspectorClients
|
|
22042
23588
|
]);
|
|
22043
23589
|
useInput((input, key) => {
|
|
22044
|
-
if (toolTestModal || resourceTestModal || promptTestModal || detailsModal || helpOpen || rootsModalOpen) return;
|
|
23590
|
+
if (toolTestModal || resourceTestModal || promptTestModal || detailsModal || helpOpen || rootsModalOpen || pendingRequestOpen) return;
|
|
22045
23591
|
if (key.ctrl && input === "c") exit();
|
|
22046
23592
|
if (listFilterEditing) return;
|
|
22047
23593
|
if (input === "?") {
|
|
@@ -22668,6 +24214,7 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
22668
24214
|
width: dimensions.width,
|
|
22669
24215
|
height: dimensions.height,
|
|
22670
24216
|
onClose: () => setToolTestModal(null),
|
|
24217
|
+
inputActive: !pendingRequestOpen,
|
|
22671
24218
|
onAuthRecoveryRequired: (error) => {
|
|
22672
24219
|
onAuthRecoveryRequired(error);
|
|
22673
24220
|
setToolTestModal(null);
|
|
@@ -22679,6 +24226,7 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
22679
24226
|
width: dimensions.width,
|
|
22680
24227
|
height: dimensions.height,
|
|
22681
24228
|
onClose: () => setResourceTestModal(null),
|
|
24229
|
+
inputActive: !pendingRequestOpen,
|
|
22682
24230
|
onAuthRecoveryRequired: (error) => {
|
|
22683
24231
|
onAuthRecoveryRequired(error);
|
|
22684
24232
|
setResourceTestModal(null);
|
|
@@ -22690,6 +24238,7 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
22690
24238
|
width: dimensions.width,
|
|
22691
24239
|
height: dimensions.height,
|
|
22692
24240
|
onClose: () => setPromptTestModal(null),
|
|
24241
|
+
inputActive: !pendingRequestOpen,
|
|
22693
24242
|
onAuthRecoveryRequired: (error) => {
|
|
22694
24243
|
onAuthRecoveryRequired(error);
|
|
22695
24244
|
setPromptTestModal(null);
|
|
@@ -22699,7 +24248,8 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
22699
24248
|
sections: keybindingSections(activeTab, shownTabs),
|
|
22700
24249
|
width: dimensions.width,
|
|
22701
24250
|
height: dimensions.height,
|
|
22702
|
-
onClose: () => setHelpOpen(false)
|
|
24251
|
+
onClose: () => setHelpOpen(false),
|
|
24252
|
+
inputActive: !pendingRequestOpen
|
|
22703
24253
|
}),
|
|
22704
24254
|
rootsModalOpen && /* @__PURE__ */ jsx(RootsModal, {
|
|
22705
24255
|
roots: advertisedRoots,
|
|
@@ -22707,7 +24257,8 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
22707
24257
|
connected: inspectorStatus === "connected",
|
|
22708
24258
|
width: dimensions.width,
|
|
22709
24259
|
height: dimensions.height,
|
|
22710
|
-
onClose: () => setRootsModalOpen(false)
|
|
24260
|
+
onClose: () => setRootsModalOpen(false),
|
|
24261
|
+
inputActive: !pendingRequestOpen
|
|
22711
24262
|
}),
|
|
22712
24263
|
detailsModal && !helpOpen && /* @__PURE__ */ jsx(DetailsModal, {
|
|
22713
24264
|
title: detailsModal.title,
|
|
@@ -22715,13 +24266,20 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
22715
24266
|
width: dimensions.width,
|
|
22716
24267
|
height: dimensions.height,
|
|
22717
24268
|
onClose: () => setDetailsModal(null),
|
|
22718
|
-
copyText: detailsModal.copyText
|
|
24269
|
+
copyText: detailsModal.copyText,
|
|
24270
|
+
inputActive: !pendingRequestOpen
|
|
24271
|
+
}),
|
|
24272
|
+
/* @__PURE__ */ jsx(PendingRequestModal, {
|
|
24273
|
+
pendingSamples,
|
|
24274
|
+
pendingElicitations,
|
|
24275
|
+
inspectorClient: selectedInspectorClient,
|
|
24276
|
+
width: dimensions.width,
|
|
24277
|
+
height: dimensions.height
|
|
22719
24278
|
})
|
|
22720
24279
|
]
|
|
22721
24280
|
});
|
|
22722
24281
|
}
|
|
22723
|
-
|
|
22724
|
-
//#region tui.tsx
|
|
24282
|
+
// tui.tsx
|
|
22725
24283
|
async function runTui(args) {
|
|
22726
24284
|
const program = new Command();
|
|
22727
24285
|
program.name("mcp-inspector-tui").description("Terminal UI for MCP Inspector").version(readInspectorVersion(import.meta.url), "-V, --version", "Print the Inspector version").option("--catalog <path>", "Writable catalog file (created if missing; default: ~/.mcp-inspector/mcp.json, or MCP_CATALOG_PATH)").option("--config <path>", "Read-only session config file (served as-is, never written or seeded; errors if absent)").option("-e <key=value...>", "Environment variables for stdio servers", parseKeyValuePair, {}).option("--cwd <path>", "Working directory for stdio servers").option("--header <header...>", "HTTP headers as \"Name: Value\"", parseHeaderPair, {}).option("--protocol-era <era>", "Protocol era to negotiate: legacy, auto, or modern (overrides the file's protocolEra; default legacy)", parseProtocolEra).option("--skill-catalog-max-skills <n>", "Skills catalog budget: the most skills one multi-skill verification run reads (positive integer; overrides the file's skillCatalogMaxSkills; default 256). Bounds the Skills pane's v (verify all); Enter verifies one skill in full", skillCatalogLimitParser("--skill-catalog-max-skills")).option("--skill-catalog-max-bytes <n>", "Skills catalog budget: the most bytes one multi-skill verification run reads (positive integer; overrides the file's skillCatalogMaxBytes; default 64 MiB). Bounds the Skills pane's v (verify all); Enter verifies one skill in full", skillCatalogLimitParser("--skill-catalog-max-bytes")).option("--client-id <id>", "OAuth client ID (static client) for HTTP servers").option("--client-secret <secret>", "OAuth client secret (for confidential clients)").option("--client-metadata-url <url>", "OAuth Client ID Metadata Document URL (CIMD) for HTTP servers").option("--client-config <path>", "Install-level client config (default: ~/.mcp-inspector/storage/client.json, or MCP_CLIENT_CONFIG_PATH)").option("--callback-url <url>", `OAuth redirect/callback listener URL; must be loopback (default: ${DEFAULT_RUNNER_OAUTH_CALLBACK_URL}, or MCP_OAUTH_CALLBACK_URL)`).argument("[target...]", "Command and args or URL for a single ad-hoc server (when not using --config)").option("--transport <type>", "Transport: stdio, sse, or http (ad-hoc only)").option("--server-url <url>", "Server URL (ad-hoc only)").parse(args ?? process.argv);
|
|
@@ -22776,8 +24334,7 @@ async function runTui(args) {
|
|
|
22776
24334
|
process.exit(1);
|
|
22777
24335
|
}
|
|
22778
24336
|
}
|
|
22779
|
-
|
|
22780
|
-
//#region index.ts
|
|
24337
|
+
// index.ts
|
|
22781
24338
|
const __filename = fileURLToPath(import.meta.url);
|
|
22782
24339
|
if (process.argv[1] !== void 0 && resolve(process.argv[1]) === resolve(__filename)) runTui(process.argv).catch((err) => {
|
|
22783
24340
|
console.error("Error:", err instanceof Error ? err.message : err);
|
|
@@ -22788,5 +24345,4 @@ if (process.argv[1] !== void 0 && resolve(process.argv[1]) === resolve(__filenam
|
|
|
22788
24345
|
if ((debugOn(process.env.MCP_DEBUG) || debugOn(process.env.DEBUG)) && err instanceof Error) console.error(err.stack);
|
|
22789
24346
|
process.exit(1);
|
|
22790
24347
|
});
|
|
22791
|
-
//#endregion
|
|
22792
24348
|
export { runTui };
|