@modelcontextprotocol/inspector 2.13.0 → 2.14.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 +1013 -80
- package/clients/mcpdo/build/mcp-bin.js +50 -22
- package/clients/mcpdo/build/mcpdod.js +1 -1
- package/clients/mcpdo/build/{server-BHuKGkMj.js → server-Dv339Ejx.js} +886 -48
- package/clients/tui/build/index.js +781 -46
- package/clients/web/build/index.js +223 -124
- 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-BCud2uMC.js +1594 -0
- package/clients/web/dist/assets/{index-dqp8Sd8W.css → index-Dval2a7I.css} +1 -1
- package/clients/web/dist/assets/{prism-light-BIhJtJkv.js → prism-light-CoVRM9R2.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/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 +5 -4
- package/skills/mcpdo/SKILL.md +14 -0
- package/clients/web/dist/assets/index-BqEbhCDX.js +0 -1587
|
@@ -28,7 +28,10 @@ import { DispatchError, JsonRpcResponseError, TaskFailedError, createApplication
|
|
|
28
28
|
import { bindTaskReceiver } from "@modelcontextprotocol/ext-tasks/receiver";
|
|
29
29
|
import { runtimeCodecFromStandardSchema, taskId, toJsonValue } from "@modelcontextprotocol/ext-tasks/core";
|
|
30
30
|
import { TASKS_EXTENSION_ID_V2 as TASKS_EXTENSION_KEY } from "@modelcontextprotocol/ext-tasks/core/v2";
|
|
31
|
-
import
|
|
31
|
+
import Ajv from "ajv";
|
|
32
|
+
import { Ajv2019 } from "ajv/dist/2019.js";
|
|
33
|
+
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
34
|
+
import { addFormats } from "@modelcontextprotocol/client/validators/ajv";
|
|
32
35
|
import { createServer } from "node:http";
|
|
33
36
|
import open from "open";
|
|
34
37
|
import { createInterface as createInterface$1 } from "node:readline/promises";
|
|
@@ -4511,7 +4514,8 @@ const EXIT_CODES = {
|
|
|
4511
4514
|
SKILL_INCOMPLETE: 8,
|
|
4512
4515
|
SKILL_UNVERIFIABLE: 9,
|
|
4513
4516
|
LOAD_THRESHOLD_EXCEEDED: 10,
|
|
4514
|
-
RATE_LIMITED: 11
|
|
4517
|
+
RATE_LIMITED: 11,
|
|
4518
|
+
INTERRUPTED: 130
|
|
4515
4519
|
};
|
|
4516
4520
|
function rateLimitFieldsOf(error) {
|
|
4517
4521
|
const data = error?.data;
|
|
@@ -6171,6 +6175,14 @@ function expectedSecretFields(stored) {
|
|
|
6171
6175
|
if (isStdioStored(stored) && stored.env) for (const k of Object.keys(stored.env)) fields.push(envSecretField(k));
|
|
6172
6176
|
return fields;
|
|
6173
6177
|
}
|
|
6178
|
+
function adHocServerName(config) {
|
|
6179
|
+
if (config.type === "sse" || config.type === "streamable-http") try {
|
|
6180
|
+
return new URL(config.url).host || "server";
|
|
6181
|
+
} catch {
|
|
6182
|
+
return "server";
|
|
6183
|
+
}
|
|
6184
|
+
return config.command?.split(/[\\/]/).pop() || "server";
|
|
6185
|
+
}
|
|
6174
6186
|
//#endregion
|
|
6175
6187
|
//#region ../../core/mcp/node/config.ts
|
|
6176
6188
|
function parseKeyValuePair(value, previous = {}) {
|
|
@@ -6436,8 +6448,9 @@ async function loadServerEntries(serverOptions) {
|
|
|
6436
6448
|
}
|
|
6437
6449
|
const configs = resolveServerConfigs(serverOptions, "multi");
|
|
6438
6450
|
if (configs.length === 0) throw new Error("At least one server is required. Use --catalog/--config <path> or an ad-hoc target (command/URL).");
|
|
6439
|
-
|
|
6440
|
-
|
|
6451
|
+
const config = configs[0];
|
|
6452
|
+
return { [adHocServerName(config)]: {
|
|
6453
|
+
config,
|
|
6441
6454
|
settings: mergeSettings(void 0, serverOptions)
|
|
6442
6455
|
} };
|
|
6443
6456
|
}
|
|
@@ -6986,6 +6999,13 @@ function readInspectorVersion(callerUrl) {
|
|
|
6986
6999
|
}
|
|
6987
7000
|
throw new Error(`Could not locate the ${ROOT_PACKAGE_NAME} root package.json above ${startDir}`);
|
|
6988
7001
|
}
|
|
7002
|
+
function readInspectorVersionSafe(callerUrl) {
|
|
7003
|
+
try {
|
|
7004
|
+
return readInspectorVersion(callerUrl);
|
|
7005
|
+
} catch {
|
|
7006
|
+
return;
|
|
7007
|
+
}
|
|
7008
|
+
}
|
|
6989
7009
|
//#endregion
|
|
6990
7010
|
//#region src/daemon/paths.ts
|
|
6991
7011
|
const DAEMON_DIR_ENV = "MCP_INSPECTOR_DAEMON_DIR";
|
|
@@ -8439,6 +8459,7 @@ function resolveLoadOptions(flags) {
|
|
|
8439
8459
|
};
|
|
8440
8460
|
}
|
|
8441
8461
|
const OTHER_ERRORS = "(other)";
|
|
8462
|
+
const NO_TOOL_ERROR_TEXT = "(no text content)";
|
|
8442
8463
|
const yieldToEventLoop = () => new Promise((resolve) => setImmediate(resolve));
|
|
8443
8464
|
const realClock = {
|
|
8444
8465
|
now: () => performance.now(),
|
|
@@ -8508,10 +8529,45 @@ var ErrorTally = class {
|
|
|
8508
8529
|
return list;
|
|
8509
8530
|
}
|
|
8510
8531
|
};
|
|
8532
|
+
function isLoadStop(value) {
|
|
8533
|
+
if (typeof value !== "object" || value === null) return false;
|
|
8534
|
+
const { reason, detail } = value;
|
|
8535
|
+
return (reason === "interrupted" || reason === "connection_lost" || reason === "consecutive_errors") && typeof detail === "string";
|
|
8536
|
+
}
|
|
8537
|
+
function toolErrorText(content) {
|
|
8538
|
+
const blocks = Array.isArray(content) ? content : [];
|
|
8539
|
+
for (const block of blocks) {
|
|
8540
|
+
if (typeof block !== "object" || block === null) continue;
|
|
8541
|
+
const { type, text } = block;
|
|
8542
|
+
if (type !== "text" || typeof text !== "string") continue;
|
|
8543
|
+
const trimmed = text.trim();
|
|
8544
|
+
if (trimmed === "") continue;
|
|
8545
|
+
return trimmed.length > 200 ? `${trimmed.slice(0, 200)}…` : trimmed;
|
|
8546
|
+
}
|
|
8547
|
+
return NO_TOOL_ERROR_TEXT;
|
|
8548
|
+
}
|
|
8549
|
+
const LOAD_FLAG_CONFLICT = "load_flag_conflict";
|
|
8550
|
+
function loadSummaryWarnings(summary) {
|
|
8551
|
+
const warnings = [];
|
|
8552
|
+
const stop = summary.stoppedEarly;
|
|
8553
|
+
if (stop !== void 0 && stop.reason !== "interrupted") warnings.push(`Warning: the load run stopped early (${stop.reason}): ${stop.detail}.`);
|
|
8554
|
+
const shortfall = loadRateShortfallWarning(summary);
|
|
8555
|
+
if (shortfall !== void 0) warnings.push(shortfall);
|
|
8556
|
+
return warnings;
|
|
8557
|
+
}
|
|
8558
|
+
function loadRateShortfallWarning(summary) {
|
|
8559
|
+
const { rate, achievedRate, plannedStarts, droppedSlots } = summary;
|
|
8560
|
+
if (rate === void 0 || plannedStarts === void 0 || droppedSlots === void 0 || plannedStarts === 0) return;
|
|
8561
|
+
const started = plannedStarts - droppedSlots;
|
|
8562
|
+
if (started >= plannedStarts * .9) return void 0;
|
|
8563
|
+
return `Warning: --load-rate ${rate}/s was not reached: ${started} of ${plannedStarts} planned calls started (${achievedRate}/s); ${droppedSlots} slots were dropped because every worker was busy. Raise --load-concurrency or lower --load-rate.`;
|
|
8564
|
+
}
|
|
8511
8565
|
async function runLoad(call, options, clock = realClock, signal) {
|
|
8512
8566
|
const { concurrency, durationMs, requests, rate } = options;
|
|
8513
|
-
const
|
|
8567
|
+
const okLatencies = [];
|
|
8568
|
+
const errorLatencies = [];
|
|
8514
8569
|
const tally = new ErrorTally();
|
|
8570
|
+
const toolTally = new ErrorTally();
|
|
8515
8571
|
let ok = 0;
|
|
8516
8572
|
let toolErrors = 0;
|
|
8517
8573
|
let errors = 0;
|
|
@@ -8520,6 +8576,37 @@ async function runLoad(call, options, clock = realClock, signal) {
|
|
|
8520
8576
|
const deadline = durationMs === void 0 ? Infinity : start + durationMs;
|
|
8521
8577
|
const interval = rate === void 0 ? 0 : 1e3 / rate;
|
|
8522
8578
|
let nextStart = start;
|
|
8579
|
+
const halt = new AbortController();
|
|
8580
|
+
let stoppedEarly;
|
|
8581
|
+
let stoppedAt = 0;
|
|
8582
|
+
const stopRun = (stop) => {
|
|
8583
|
+
if (stoppedEarly) {
|
|
8584
|
+
if (stop.reason === "interrupted") stoppedEarly = stop;
|
|
8585
|
+
return;
|
|
8586
|
+
}
|
|
8587
|
+
stoppedEarly = stop;
|
|
8588
|
+
stoppedAt = clock.now();
|
|
8589
|
+
halt.abort();
|
|
8590
|
+
};
|
|
8591
|
+
const onAbort = () => {
|
|
8592
|
+
const reason = signal?.reason;
|
|
8593
|
+
stopRun(isLoadStop(reason) ? reason : {
|
|
8594
|
+
reason: "interrupted",
|
|
8595
|
+
detail: "the run was interrupted"
|
|
8596
|
+
});
|
|
8597
|
+
};
|
|
8598
|
+
if (signal?.aborted) onAbort();
|
|
8599
|
+
else signal?.addEventListener("abort", onAbort, { once: true });
|
|
8600
|
+
let errorStreak = 0;
|
|
8601
|
+
let streakSince = 0;
|
|
8602
|
+
const noteThrown = (now) => {
|
|
8603
|
+
if (errorStreak++ === 0) streakSince = now;
|
|
8604
|
+
const window = now - streakSince;
|
|
8605
|
+
if ((requests === void 0 || started < requests) && now < deadline && nextStart < deadline && (errorStreak >= 50 || errorStreak >= 5 && window >= 1e3)) stopRun({
|
|
8606
|
+
reason: "consecutive_errors",
|
|
8607
|
+
detail: `${errorStreak} calls in a row threw over ${round(window)}ms; the server looks unavailable`
|
|
8608
|
+
});
|
|
8609
|
+
};
|
|
8523
8610
|
let turnstile = Promise.resolve();
|
|
8524
8611
|
const claimSlot = async () => {
|
|
8525
8612
|
const ahead = turnstile;
|
|
@@ -8529,7 +8616,7 @@ async function runLoad(call, options, clock = realClock, signal) {
|
|
|
8529
8616
|
try {
|
|
8530
8617
|
if (started > 0 && started % 64 === 0) await yieldToEventLoop();
|
|
8531
8618
|
for (;;) {
|
|
8532
|
-
if (signal
|
|
8619
|
+
if (halt.signal.aborted) return false;
|
|
8533
8620
|
if (requests !== void 0 && started >= requests) return false;
|
|
8534
8621
|
const now = clock.now();
|
|
8535
8622
|
if (now >= deadline) return false;
|
|
@@ -8540,7 +8627,7 @@ async function runLoad(call, options, clock = realClock, signal) {
|
|
|
8540
8627
|
nextStart = now - nextStart < interval ? nextStart + interval : now + interval;
|
|
8541
8628
|
return true;
|
|
8542
8629
|
}
|
|
8543
|
-
await sleepUnlessAborted(clock, scheduled - now, signal);
|
|
8630
|
+
await sleepUnlessAborted(clock, scheduled - now, halt.signal);
|
|
8544
8631
|
}
|
|
8545
8632
|
} finally {
|
|
8546
8633
|
release();
|
|
@@ -8548,26 +8635,57 @@ async function runLoad(call, options, clock = realClock, signal) {
|
|
|
8548
8635
|
};
|
|
8549
8636
|
const worker = async (index) => {
|
|
8550
8637
|
while (await claimSlot()) {
|
|
8551
|
-
if (signal
|
|
8638
|
+
if (halt.signal.aborted) {
|
|
8639
|
+
started--;
|
|
8640
|
+
return;
|
|
8641
|
+
}
|
|
8552
8642
|
const t0 = clock.now();
|
|
8553
8643
|
try {
|
|
8554
|
-
|
|
8555
|
-
|
|
8644
|
+
const outcome = await call(index);
|
|
8645
|
+
const latency = clock.now() - t0;
|
|
8646
|
+
errorStreak = 0;
|
|
8647
|
+
if (outcome === "ok") {
|
|
8648
|
+
ok++;
|
|
8649
|
+
okLatencies.push(latency);
|
|
8650
|
+
} else {
|
|
8651
|
+
toolErrors++;
|
|
8652
|
+
errorLatencies.push(latency);
|
|
8653
|
+
toolTally.add(typeof outcome === "object" ? outcome.message : NO_TOOL_ERROR_TEXT);
|
|
8654
|
+
}
|
|
8556
8655
|
} catch (err) {
|
|
8656
|
+
const now = clock.now();
|
|
8557
8657
|
errors++;
|
|
8658
|
+
errorLatencies.push(now - t0);
|
|
8558
8659
|
tally.add(err instanceof Error ? err.message : String(err));
|
|
8660
|
+
noteThrown(now);
|
|
8559
8661
|
}
|
|
8560
|
-
latencies.push(clock.now() - t0);
|
|
8561
8662
|
}
|
|
8562
8663
|
};
|
|
8563
|
-
|
|
8564
|
-
|
|
8664
|
+
try {
|
|
8665
|
+
await Promise.all(Array.from({ length: concurrency }, (_, i) => worker(i)));
|
|
8666
|
+
} finally {
|
|
8667
|
+
signal?.removeEventListener("abort", onAbort);
|
|
8668
|
+
}
|
|
8669
|
+
const end = clock.now();
|
|
8670
|
+
const requestCapped = requests !== void 0 && started >= requests;
|
|
8671
|
+
const elapsedMs = durationMs !== void 0 && stoppedEarly === void 0 && !requestCapped ? Math.max(end - start, durationMs) : end - start;
|
|
8565
8672
|
const completed = ok + toolErrors + errors;
|
|
8673
|
+
const startWindowEnd = () => {
|
|
8674
|
+
let windowEnd = deadline;
|
|
8675
|
+
if (requestCapped) windowEnd = Math.min(windowEnd, nextStart);
|
|
8676
|
+
if (stoppedEarly !== void 0) windowEnd = Math.min(windowEnd, stoppedAt);
|
|
8677
|
+
/* v8 ignore next -- defensive: a run with no duration, no request cap
|
|
8678
|
+
and no stop never ends, so one of the three always applies. */
|
|
8679
|
+
return Number.isFinite(windowEnd) ? windowEnd : end;
|
|
8680
|
+
};
|
|
8566
8681
|
return {
|
|
8567
8682
|
concurrency,
|
|
8568
8683
|
...durationMs !== void 0 && { durationMs },
|
|
8569
8684
|
...requests !== void 0 && { requestLimit: requests },
|
|
8570
|
-
...rate !== void 0 &&
|
|
8685
|
+
...rate !== void 0 && rateFigures(rate, {
|
|
8686
|
+
started,
|
|
8687
|
+
windowMs: startWindowEnd() - start
|
|
8688
|
+
}),
|
|
8571
8689
|
requests: completed,
|
|
8572
8690
|
ok,
|
|
8573
8691
|
toolErrors,
|
|
@@ -8575,8 +8693,23 @@ async function runLoad(call, options, clock = realClock, signal) {
|
|
|
8575
8693
|
errorRate: completed === 0 ? 0 : round((toolErrors + errors) / completed, 4),
|
|
8576
8694
|
elapsedMs: round(elapsedMs),
|
|
8577
8695
|
throughput: elapsedMs > 0 ? round(completed * 1e3 / elapsedMs) : 0,
|
|
8578
|
-
|
|
8579
|
-
|
|
8696
|
+
okThroughput: elapsedMs > 0 ? round(ok * 1e3 / elapsedMs) : 0,
|
|
8697
|
+
latencyMs: summarizeLatency(okLatencies),
|
|
8698
|
+
errorLatencyMs: summarizeLatency(errorLatencies),
|
|
8699
|
+
errorMessages: tally.entries(),
|
|
8700
|
+
toolErrorMessages: toolTally.entries(),
|
|
8701
|
+
...stoppedEarly !== void 0 && { stoppedEarly }
|
|
8702
|
+
};
|
|
8703
|
+
}
|
|
8704
|
+
function rateFigures(rate, run) {
|
|
8705
|
+
const { started, windowMs } = run;
|
|
8706
|
+
const slots = Math.ceil(windowMs * rate / 1e3 - 1e-9);
|
|
8707
|
+
const plannedStarts = Math.max(started, slots);
|
|
8708
|
+
return {
|
|
8709
|
+
rate,
|
|
8710
|
+
plannedStarts,
|
|
8711
|
+
droppedSlots: plannedStarts - started,
|
|
8712
|
+
achievedRate: windowMs > 0 ? round(started * 1e3 / windowMs) : 0
|
|
8580
8713
|
};
|
|
8581
8714
|
}
|
|
8582
8715
|
async function runLoadAcrossConnections(primary, openConnection, callOn, options, clock = realClock, signal) {
|
|
@@ -8638,7 +8771,11 @@ async function runToolLoad(inspectorClient, args, options, extra = {}) {
|
|
|
8638
8771
|
/* v8 ignore next 3 -- defensive: `ToolCallInvocation.result` is nullable,
|
|
8639
8772
|
but both call paths throw on failure rather than return a null result. */
|
|
8640
8773
|
if (invocation.result === null) throw new Error(invocation.error ?? "Tool call failed");
|
|
8641
|
-
|
|
8774
|
+
if (invocation.result.isError !== true) return "ok";
|
|
8775
|
+
return {
|
|
8776
|
+
outcome: "tool_error",
|
|
8777
|
+
message: toolErrorText(invocation.result.content)
|
|
8778
|
+
};
|
|
8642
8779
|
};
|
|
8643
8780
|
const summary = await runLoadAcrossConnections(inspectorClient, extra.openConnection, call, options, extra.clock, extra.signal);
|
|
8644
8781
|
return {
|
|
@@ -9855,6 +9992,627 @@ function validateToolOutput(provider, tool, result) {
|
|
|
9855
9992
|
}
|
|
9856
9993
|
}
|
|
9857
9994
|
//#endregion
|
|
9995
|
+
//#region ../../core/json/linearRegExp.ts
|
|
9996
|
+
var CharMatcher = class {
|
|
9997
|
+
re;
|
|
9998
|
+
ascii = /* @__PURE__ */ new Uint8Array(128);
|
|
9999
|
+
constructor(source, unicode) {
|
|
10000
|
+
this.re = new RegExp(`^(?:${source})$`, unicode ? "u" : "");
|
|
10001
|
+
}
|
|
10002
|
+
matches(cp, unicode) {
|
|
10003
|
+
if (cp < 128) {
|
|
10004
|
+
const memo = this.ascii[cp];
|
|
10005
|
+
if (memo !== 0) return memo === 1;
|
|
10006
|
+
const result = this.re.test(String.fromCharCode(cp));
|
|
10007
|
+
this.ascii[cp] = result ? 1 : 2;
|
|
10008
|
+
return result;
|
|
10009
|
+
}
|
|
10010
|
+
return this.re.test(unicode ? String.fromCodePoint(cp) : String.fromCharCode(cp));
|
|
10011
|
+
}
|
|
10012
|
+
};
|
|
10013
|
+
var Unsupported = class extends Error {};
|
|
10014
|
+
const MAX_GROUP_DEPTH = 64;
|
|
10015
|
+
const MAX_PROGRAM_SIZE = 1e4;
|
|
10016
|
+
const MAX_COMPILE_STEPS = 10 * MAX_PROGRAM_SIZE;
|
|
10017
|
+
const MAX_PATTERN_LENGTH = 8192;
|
|
10018
|
+
const COMPILE_BUDGET_EXHAUSTED = "the patterns together exceed the compilation budget";
|
|
10019
|
+
function isCompileBudgetExhausted(budget) {
|
|
10020
|
+
return budget.steps < 0 || budget.size < 0;
|
|
10021
|
+
}
|
|
10022
|
+
const QUANTIFIER_BRACES = /\{(\d+)(?:(,)(\d*))?\}/y;
|
|
10023
|
+
const HEX4 = /^[0-9a-fA-F]{4}$/;
|
|
10024
|
+
const HEX2 = /^[0-9a-fA-F]{2}$/;
|
|
10025
|
+
var Parser = class {
|
|
10026
|
+
pos = 0;
|
|
10027
|
+
src;
|
|
10028
|
+
unicode;
|
|
10029
|
+
constructor(src, unicode) {
|
|
10030
|
+
this.src = src;
|
|
10031
|
+
this.unicode = unicode;
|
|
10032
|
+
}
|
|
10033
|
+
parse() {
|
|
10034
|
+
const node = this.parseAlternation(0);
|
|
10035
|
+
/* v8 ignore next -- the native RegExp constructor rejects an unbalanced `)` first */
|
|
10036
|
+
if (this.pos !== this.src.length) throw new Unsupported("unbalanced group");
|
|
10037
|
+
return node;
|
|
10038
|
+
}
|
|
10039
|
+
parseAlternation(depth) {
|
|
10040
|
+
const options = [this.parseSequence(depth)];
|
|
10041
|
+
while (this.src[this.pos] === "|") {
|
|
10042
|
+
this.pos++;
|
|
10043
|
+
options.push(this.parseSequence(depth));
|
|
10044
|
+
}
|
|
10045
|
+
return options.length === 1 ? options[0] : {
|
|
10046
|
+
kind: "alt",
|
|
10047
|
+
options
|
|
10048
|
+
};
|
|
10049
|
+
}
|
|
10050
|
+
parseSequence(depth) {
|
|
10051
|
+
const items = [];
|
|
10052
|
+
while (this.pos < this.src.length && this.src[this.pos] !== "|" && this.src[this.pos] !== ")") items.push(this.parseTerm(depth));
|
|
10053
|
+
return items.length === 1 ? items[0] : {
|
|
10054
|
+
kind: "seq",
|
|
10055
|
+
items
|
|
10056
|
+
};
|
|
10057
|
+
}
|
|
10058
|
+
parseTerm(depth) {
|
|
10059
|
+
const atom = this.parseAtom(depth);
|
|
10060
|
+
const quantifier = this.readQuantifier();
|
|
10061
|
+
if (!quantifier) return atom;
|
|
10062
|
+
if (this.src[this.pos] === "?") this.pos++;
|
|
10063
|
+
return {
|
|
10064
|
+
kind: "repeat",
|
|
10065
|
+
body: atom,
|
|
10066
|
+
...quantifier
|
|
10067
|
+
};
|
|
10068
|
+
}
|
|
10069
|
+
readQuantifier() {
|
|
10070
|
+
const c = this.src[this.pos];
|
|
10071
|
+
if (c === "*") {
|
|
10072
|
+
this.pos++;
|
|
10073
|
+
return {
|
|
10074
|
+
min: 0,
|
|
10075
|
+
max: Infinity
|
|
10076
|
+
};
|
|
10077
|
+
}
|
|
10078
|
+
if (c === "+") {
|
|
10079
|
+
this.pos++;
|
|
10080
|
+
return {
|
|
10081
|
+
min: 1,
|
|
10082
|
+
max: Infinity
|
|
10083
|
+
};
|
|
10084
|
+
}
|
|
10085
|
+
if (c === "?") {
|
|
10086
|
+
this.pos++;
|
|
10087
|
+
return {
|
|
10088
|
+
min: 0,
|
|
10089
|
+
max: 1
|
|
10090
|
+
};
|
|
10091
|
+
}
|
|
10092
|
+
if (c === "{") {
|
|
10093
|
+
QUANTIFIER_BRACES.lastIndex = this.pos;
|
|
10094
|
+
const m = QUANTIFIER_BRACES.exec(this.src);
|
|
10095
|
+
if (!m) return void 0;
|
|
10096
|
+
this.pos += m[0].length;
|
|
10097
|
+
const min = Number(m[1]);
|
|
10098
|
+
return {
|
|
10099
|
+
min,
|
|
10100
|
+
max: m[2] === void 0 ? min : m[3] ? Number(m[3]) : Infinity
|
|
10101
|
+
};
|
|
10102
|
+
}
|
|
10103
|
+
}
|
|
10104
|
+
parseAtom(depth) {
|
|
10105
|
+
switch (this.src[this.pos]) {
|
|
10106
|
+
case "(": return this.parseGroup(depth);
|
|
10107
|
+
case "[": return this.parseClass();
|
|
10108
|
+
case "\\": return this.parseEscape();
|
|
10109
|
+
case ".":
|
|
10110
|
+
this.pos++;
|
|
10111
|
+
return {
|
|
10112
|
+
kind: "char",
|
|
10113
|
+
source: "."
|
|
10114
|
+
};
|
|
10115
|
+
case "^":
|
|
10116
|
+
this.pos++;
|
|
10117
|
+
return {
|
|
10118
|
+
kind: "assert",
|
|
10119
|
+
assertion: "start"
|
|
10120
|
+
};
|
|
10121
|
+
case "$":
|
|
10122
|
+
this.pos++;
|
|
10123
|
+
return {
|
|
10124
|
+
kind: "assert",
|
|
10125
|
+
assertion: "end"
|
|
10126
|
+
};
|
|
10127
|
+
case "*":
|
|
10128
|
+
case "+":
|
|
10129
|
+
case "?":
|
|
10130
|
+
/* v8 ignore next -- "nothing to repeat" is a native syntax error */
|
|
10131
|
+
throw new Unsupported("nothing to repeat");
|
|
10132
|
+
case "{":
|
|
10133
|
+
QUANTIFIER_BRACES.lastIndex = this.pos;
|
|
10134
|
+
if (QUANTIFIER_BRACES.test(this.src))
|
|
10135
|
+
/* v8 ignore next -- rejected by the native RegExp constructor first */
|
|
10136
|
+
throw new Unsupported("nothing to repeat");
|
|
10137
|
+
this.pos++;
|
|
10138
|
+
return {
|
|
10139
|
+
kind: "char",
|
|
10140
|
+
source: "\\{"
|
|
10141
|
+
};
|
|
10142
|
+
default: {
|
|
10143
|
+
const width = this.codePointWidth(this.pos);
|
|
10144
|
+
const source = this.src.slice(this.pos, this.pos + width);
|
|
10145
|
+
this.pos += width;
|
|
10146
|
+
return {
|
|
10147
|
+
kind: "char",
|
|
10148
|
+
source
|
|
10149
|
+
};
|
|
10150
|
+
}
|
|
10151
|
+
}
|
|
10152
|
+
}
|
|
10153
|
+
codePointWidth(at) {
|
|
10154
|
+
if (!this.unicode) return 1;
|
|
10155
|
+
return this.src.codePointAt(at) > 65535 ? 2 : 1;
|
|
10156
|
+
}
|
|
10157
|
+
parseGroup(depth) {
|
|
10158
|
+
if (depth >= MAX_GROUP_DEPTH) throw new Unsupported("groups nested too deeply");
|
|
10159
|
+
this.pos++;
|
|
10160
|
+
if (this.src.startsWith("?:", this.pos)) this.pos += 2;
|
|
10161
|
+
else if (this.src.startsWith("?<", this.pos) && this.src[this.pos + 2] !== "=" && this.src[this.pos + 2] !== "!") {
|
|
10162
|
+
const close = this.src.indexOf(">", this.pos);
|
|
10163
|
+
/* v8 ignore next -- an unterminated group name is a native syntax error */
|
|
10164
|
+
if (close < 0) throw new Unsupported("unterminated group name");
|
|
10165
|
+
this.pos = close + 1;
|
|
10166
|
+
} else if (this.src[this.pos] === "?") throw new Unsupported("lookaround or group modifier");
|
|
10167
|
+
const body = this.parseAlternation(depth + 1);
|
|
10168
|
+
/* v8 ignore next -- an unterminated group is a native syntax error */
|
|
10169
|
+
if (this.src[this.pos] !== ")") throw new Unsupported("unterminated group");
|
|
10170
|
+
this.pos++;
|
|
10171
|
+
return body;
|
|
10172
|
+
}
|
|
10173
|
+
parseClass() {
|
|
10174
|
+
const start = this.pos;
|
|
10175
|
+
this.pos++;
|
|
10176
|
+
while (this.pos < this.src.length && this.src[this.pos] !== "]") this.pos += this.src[this.pos] === "\\" ? 2 : 1;
|
|
10177
|
+
/* v8 ignore next -- an unterminated class is a native syntax error */
|
|
10178
|
+
if (this.pos >= this.src.length) throw new Unsupported("unterminated class");
|
|
10179
|
+
this.pos++;
|
|
10180
|
+
return {
|
|
10181
|
+
kind: "char",
|
|
10182
|
+
source: this.src.slice(start, this.pos)
|
|
10183
|
+
};
|
|
10184
|
+
}
|
|
10185
|
+
parseEscape() {
|
|
10186
|
+
const next = this.src[this.pos + 1];
|
|
10187
|
+
/* v8 ignore next -- a trailing backslash is a native syntax error */
|
|
10188
|
+
if (next === void 0) throw new Unsupported("trailing backslash");
|
|
10189
|
+
switch (next) {
|
|
10190
|
+
case "b":
|
|
10191
|
+
this.pos += 2;
|
|
10192
|
+
return {
|
|
10193
|
+
kind: "assert",
|
|
10194
|
+
assertion: "wordBoundary"
|
|
10195
|
+
};
|
|
10196
|
+
case "B":
|
|
10197
|
+
this.pos += 2;
|
|
10198
|
+
return {
|
|
10199
|
+
kind: "assert",
|
|
10200
|
+
assertion: "notWordBoundary"
|
|
10201
|
+
};
|
|
10202
|
+
case "1":
|
|
10203
|
+
case "2":
|
|
10204
|
+
case "3":
|
|
10205
|
+
case "4":
|
|
10206
|
+
case "5":
|
|
10207
|
+
case "6":
|
|
10208
|
+
case "7":
|
|
10209
|
+
case "8":
|
|
10210
|
+
case "9":
|
|
10211
|
+
case "k": throw new Unsupported("backreference");
|
|
10212
|
+
case "0":
|
|
10213
|
+
if (/[0-9]/.test(this.src[this.pos + 2] ?? "")) throw new Unsupported("octal escape");
|
|
10214
|
+
return this.takeChar(2);
|
|
10215
|
+
case "c":
|
|
10216
|
+
if (!/[a-zA-Z]/.test(this.src[this.pos + 2] ?? "")) throw new Unsupported("incomplete control escape");
|
|
10217
|
+
return this.takeChar(3);
|
|
10218
|
+
case "p":
|
|
10219
|
+
case "P":
|
|
10220
|
+
if (this.unicode && this.src[this.pos + 2] === "{") return this.takeThrough("}");
|
|
10221
|
+
return this.takeChar(2);
|
|
10222
|
+
case "x": return this.takeChar(HEX2.test(this.src.slice(this.pos + 2, this.pos + 4)) ? 4 : 2);
|
|
10223
|
+
case "u": return this.parseUnicodeEscape();
|
|
10224
|
+
default: return this.takeChar(1 + this.codePointWidth(this.pos + 1));
|
|
10225
|
+
}
|
|
10226
|
+
}
|
|
10227
|
+
parseUnicodeEscape() {
|
|
10228
|
+
if (this.unicode && this.src[this.pos + 2] === "{") return this.takeThrough("}");
|
|
10229
|
+
const hex = this.src.slice(this.pos + 2, this.pos + 6);
|
|
10230
|
+
if (!HEX4.test(hex)) return this.takeChar(2);
|
|
10231
|
+
const unit = parseInt(hex, 16);
|
|
10232
|
+
if (this.unicode && unit >= 55296 && unit <= 56319 && this.src.startsWith("\\u", this.pos + 6)) {
|
|
10233
|
+
const low = this.src.slice(this.pos + 8, this.pos + 12);
|
|
10234
|
+
if (HEX4.test(low)) {
|
|
10235
|
+
const lowUnit = parseInt(low, 16);
|
|
10236
|
+
if (lowUnit >= 56320 && lowUnit <= 57343) return this.takeChar(12);
|
|
10237
|
+
}
|
|
10238
|
+
}
|
|
10239
|
+
return this.takeChar(6);
|
|
10240
|
+
}
|
|
10241
|
+
takeChar(length) {
|
|
10242
|
+
const source = this.src.slice(this.pos, this.pos + length);
|
|
10243
|
+
this.pos += length;
|
|
10244
|
+
return {
|
|
10245
|
+
kind: "char",
|
|
10246
|
+
source
|
|
10247
|
+
};
|
|
10248
|
+
}
|
|
10249
|
+
takeThrough(terminator) {
|
|
10250
|
+
const end = this.src.indexOf(terminator, this.pos);
|
|
10251
|
+
/* v8 ignore next -- an unterminated `\p{` / `\u{` is a native syntax error */
|
|
10252
|
+
if (end < 0) throw new Unsupported("unterminated escape");
|
|
10253
|
+
return this.takeChar(end + 1 - this.pos);
|
|
10254
|
+
}
|
|
10255
|
+
};
|
|
10256
|
+
var Compiler = class {
|
|
10257
|
+
prog = [];
|
|
10258
|
+
matchers = /* @__PURE__ */ new Map();
|
|
10259
|
+
unicode;
|
|
10260
|
+
budget;
|
|
10261
|
+
steps = 0;
|
|
10262
|
+
constructor(unicode, budget) {
|
|
10263
|
+
this.unicode = unicode;
|
|
10264
|
+
this.budget = budget;
|
|
10265
|
+
}
|
|
10266
|
+
emit(inst) {
|
|
10267
|
+
if (this.prog.length >= 1e4) throw new Unsupported("pattern too complex");
|
|
10268
|
+
if (this.budget && --this.budget.size < 0) throw new Unsupported(COMPILE_BUDGET_EXHAUSTED);
|
|
10269
|
+
this.prog.push(inst);
|
|
10270
|
+
return this.prog.length - 1;
|
|
10271
|
+
}
|
|
10272
|
+
matcher(source) {
|
|
10273
|
+
let matcher = this.matchers.get(source);
|
|
10274
|
+
if (!matcher) {
|
|
10275
|
+
try {
|
|
10276
|
+
matcher = new CharMatcher(source, this.unicode);
|
|
10277
|
+
} catch {
|
|
10278
|
+
/* v8 ignore start -- defensive: each atom is a slice the native constructor already accepted in context */
|
|
10279
|
+
throw new Unsupported("unrecognized character syntax");
|
|
10280
|
+
}
|
|
10281
|
+
this.matchers.set(source, matcher);
|
|
10282
|
+
}
|
|
10283
|
+
return matcher;
|
|
10284
|
+
}
|
|
10285
|
+
compile(node) {
|
|
10286
|
+
if (++this.steps > 1e5) throw new Unsupported("pattern too complex");
|
|
10287
|
+
if (this.budget && --this.budget.steps < 0) throw new Unsupported(COMPILE_BUDGET_EXHAUSTED);
|
|
10288
|
+
switch (node.kind) {
|
|
10289
|
+
case "char":
|
|
10290
|
+
this.emit({
|
|
10291
|
+
op: "char",
|
|
10292
|
+
matcher: this.matcher(node.source)
|
|
10293
|
+
});
|
|
10294
|
+
return;
|
|
10295
|
+
case "assert":
|
|
10296
|
+
this.emit({
|
|
10297
|
+
op: "assert",
|
|
10298
|
+
assertion: node.assertion
|
|
10299
|
+
});
|
|
10300
|
+
return;
|
|
10301
|
+
case "seq":
|
|
10302
|
+
for (const item of node.items) this.compile(item);
|
|
10303
|
+
return;
|
|
10304
|
+
case "alt":
|
|
10305
|
+
this.compileAlternation(node.options);
|
|
10306
|
+
return;
|
|
10307
|
+
case "repeat":
|
|
10308
|
+
this.compileRepeat(node.body, node.min, node.max);
|
|
10309
|
+
return;
|
|
10310
|
+
}
|
|
10311
|
+
}
|
|
10312
|
+
compileAlternation(options) {
|
|
10313
|
+
const jumps = [];
|
|
10314
|
+
for (let i = 0; i < options.length - 1; i++) {
|
|
10315
|
+
const split = this.emit({
|
|
10316
|
+
op: "split",
|
|
10317
|
+
a: 0,
|
|
10318
|
+
b: 0
|
|
10319
|
+
});
|
|
10320
|
+
this.patchSplit(split, split + 1, -1);
|
|
10321
|
+
this.compile(options[i]);
|
|
10322
|
+
jumps.push(this.emit({
|
|
10323
|
+
op: "jmp",
|
|
10324
|
+
to: 0
|
|
10325
|
+
}));
|
|
10326
|
+
this.patchSplit(split, -1, this.prog.length);
|
|
10327
|
+
}
|
|
10328
|
+
this.compile(options[options.length - 1]);
|
|
10329
|
+
for (const jump of jumps) this.patchJump(jump, this.prog.length);
|
|
10330
|
+
}
|
|
10331
|
+
compileRepeat(body, min, max) {
|
|
10332
|
+
for (let i = 0; i < min; i++) {
|
|
10333
|
+
const before = this.prog.length;
|
|
10334
|
+
this.compile(body);
|
|
10335
|
+
if (this.prog.length === before) return;
|
|
10336
|
+
}
|
|
10337
|
+
if (max === Infinity) {
|
|
10338
|
+
const split = this.emit({
|
|
10339
|
+
op: "split",
|
|
10340
|
+
a: 0,
|
|
10341
|
+
b: 0
|
|
10342
|
+
});
|
|
10343
|
+
this.compile(body);
|
|
10344
|
+
this.emit({
|
|
10345
|
+
op: "jmp",
|
|
10346
|
+
to: split
|
|
10347
|
+
});
|
|
10348
|
+
this.patchSplit(split, split + 1, this.prog.length);
|
|
10349
|
+
return;
|
|
10350
|
+
}
|
|
10351
|
+
const splits = [];
|
|
10352
|
+
for (let i = min; i < max; i++) {
|
|
10353
|
+
const split = this.emit({
|
|
10354
|
+
op: "split",
|
|
10355
|
+
a: 0,
|
|
10356
|
+
b: 0
|
|
10357
|
+
});
|
|
10358
|
+
this.patchSplit(split, split + 1, -1);
|
|
10359
|
+
splits.push(split);
|
|
10360
|
+
this.compile(body);
|
|
10361
|
+
}
|
|
10362
|
+
for (const split of splits) this.patchSplit(split, -1, this.prog.length);
|
|
10363
|
+
}
|
|
10364
|
+
patchSplit(at, a, b) {
|
|
10365
|
+
const inst = this.prog[at];
|
|
10366
|
+
if (a >= 0) inst.a = a;
|
|
10367
|
+
if (b >= 0) inst.b = b;
|
|
10368
|
+
}
|
|
10369
|
+
patchJump(at, to) {
|
|
10370
|
+
this.prog[at].to = to;
|
|
10371
|
+
}
|
|
10372
|
+
};
|
|
10373
|
+
function isWordUnit(unit) {
|
|
10374
|
+
return unit >= 48 && unit <= 57 || unit >= 65 && unit <= 90 || unit >= 97 && unit <= 122 || unit === 95;
|
|
10375
|
+
}
|
|
10376
|
+
var LinearRegExp = class {
|
|
10377
|
+
anchoredStart;
|
|
10378
|
+
prog;
|
|
10379
|
+
unicode;
|
|
10380
|
+
constructor(prog, unicode) {
|
|
10381
|
+
this.prog = prog;
|
|
10382
|
+
this.unicode = unicode;
|
|
10383
|
+
const first = prog[0];
|
|
10384
|
+
this.anchoredStart = first !== void 0 && first.op === "assert" && first.assertion === "start";
|
|
10385
|
+
}
|
|
10386
|
+
get size() {
|
|
10387
|
+
return this.prog.length;
|
|
10388
|
+
}
|
|
10389
|
+
cost(input) {
|
|
10390
|
+
return (input.length + 1) * this.prog.length;
|
|
10391
|
+
}
|
|
10392
|
+
search(input, budget) {
|
|
10393
|
+
if (this.cost(input) > budget) return void 0;
|
|
10394
|
+
const prog = this.prog;
|
|
10395
|
+
const size = prog.length;
|
|
10396
|
+
const mark = new Int32Array(size).fill(-1);
|
|
10397
|
+
const stack = [];
|
|
10398
|
+
let clist = new Int32Array(size);
|
|
10399
|
+
let nlist = new Int32Array(size);
|
|
10400
|
+
const add = (list, count, start, pos, generation) => {
|
|
10401
|
+
stack.push(start);
|
|
10402
|
+
while (stack.length > 0) {
|
|
10403
|
+
const pc = stack.pop();
|
|
10404
|
+
if (mark[pc] === generation) continue;
|
|
10405
|
+
mark[pc] = generation;
|
|
10406
|
+
const inst = prog[pc];
|
|
10407
|
+
switch (inst.op) {
|
|
10408
|
+
case "match":
|
|
10409
|
+
stack.length = 0;
|
|
10410
|
+
return -1;
|
|
10411
|
+
case "jmp":
|
|
10412
|
+
stack.push(inst.to);
|
|
10413
|
+
break;
|
|
10414
|
+
case "split":
|
|
10415
|
+
stack.push(inst.b, inst.a);
|
|
10416
|
+
break;
|
|
10417
|
+
case "assert":
|
|
10418
|
+
if (this.holds(inst.assertion, input, pos)) stack.push(pc + 1);
|
|
10419
|
+
break;
|
|
10420
|
+
case "char": list[count++] = pc;
|
|
10421
|
+
}
|
|
10422
|
+
}
|
|
10423
|
+
return count;
|
|
10424
|
+
};
|
|
10425
|
+
let pos = 0;
|
|
10426
|
+
let generation = 0;
|
|
10427
|
+
let clen = add(clist, 0, 0, pos, generation);
|
|
10428
|
+
if (clen < 0) return true;
|
|
10429
|
+
while (pos < input.length) {
|
|
10430
|
+
if (this.anchoredStart && clen === 0) return false;
|
|
10431
|
+
const cp = this.unicode ? input.codePointAt(pos) : input.charCodeAt(pos);
|
|
10432
|
+
const next = pos + (this.unicode && cp > 65535 ? 2 : 1);
|
|
10433
|
+
generation++;
|
|
10434
|
+
let nlen = 0;
|
|
10435
|
+
for (let i = 0; i < clen; i++) {
|
|
10436
|
+
const pc = clist[i];
|
|
10437
|
+
if (prog[pc].matcher.matches(cp, this.unicode)) {
|
|
10438
|
+
nlen = add(nlist, nlen, pc + 1, next, generation);
|
|
10439
|
+
if (nlen < 0) return true;
|
|
10440
|
+
}
|
|
10441
|
+
}
|
|
10442
|
+
nlen = add(nlist, nlen, 0, next, generation);
|
|
10443
|
+
if (nlen < 0) return true;
|
|
10444
|
+
[clist, nlist] = [nlist, clist];
|
|
10445
|
+
clen = nlen;
|
|
10446
|
+
pos = next;
|
|
10447
|
+
}
|
|
10448
|
+
return false;
|
|
10449
|
+
}
|
|
10450
|
+
holds(assertion, input, pos) {
|
|
10451
|
+
switch (assertion) {
|
|
10452
|
+
case "start": return pos === 0;
|
|
10453
|
+
case "end": return pos === input.length;
|
|
10454
|
+
case "wordBoundary":
|
|
10455
|
+
case "notWordBoundary": return (pos > 0 && isWordUnit(input.charCodeAt(pos - 1))) !== (pos < input.length && isWordUnit(input.charCodeAt(pos))) === (assertion === "wordBoundary");
|
|
10456
|
+
}
|
|
10457
|
+
}
|
|
10458
|
+
};
|
|
10459
|
+
function compileLinearRegExp(pattern, unicode, budget) {
|
|
10460
|
+
if (pattern.length > 8192) return {
|
|
10461
|
+
ok: false,
|
|
10462
|
+
reason: `pattern longer than ${MAX_PATTERN_LENGTH} characters`
|
|
10463
|
+
};
|
|
10464
|
+
if (budget) {
|
|
10465
|
+
budget.steps -= pattern.length;
|
|
10466
|
+
if (isCompileBudgetExhausted(budget)) return {
|
|
10467
|
+
ok: false,
|
|
10468
|
+
reason: COMPILE_BUDGET_EXHAUSTED
|
|
10469
|
+
};
|
|
10470
|
+
}
|
|
10471
|
+
new RegExp(pattern, unicode ? "u" : "");
|
|
10472
|
+
try {
|
|
10473
|
+
const ast = new Parser(pattern, unicode).parse();
|
|
10474
|
+
const compiler = new Compiler(unicode, budget);
|
|
10475
|
+
compiler.compile(ast);
|
|
10476
|
+
compiler.prog.push({ op: "match" });
|
|
10477
|
+
return {
|
|
10478
|
+
ok: true,
|
|
10479
|
+
regExp: new LinearRegExp(compiler.prog, unicode)
|
|
10480
|
+
};
|
|
10481
|
+
} catch (error) {
|
|
10482
|
+
/* v8 ignore next -- every throw inside the parser/compiler is an Unsupported */
|
|
10483
|
+
if (!(error instanceof Unsupported)) throw error;
|
|
10484
|
+
return {
|
|
10485
|
+
ok: false,
|
|
10486
|
+
reason: error.message
|
|
10487
|
+
};
|
|
10488
|
+
}
|
|
10489
|
+
}
|
|
10490
|
+
//#endregion
|
|
10491
|
+
//#region ../../core/mcp/linearPatternValidator.ts
|
|
10492
|
+
const PATTERN_EVALUATION_BUDGET = 2e7;
|
|
10493
|
+
const SCHEMA_COMPILE_BUDGET = {
|
|
10494
|
+
steps: 10 * MAX_COMPILE_STEPS,
|
|
10495
|
+
size: 10 * MAX_PROGRAM_SIZE
|
|
10496
|
+
};
|
|
10497
|
+
const MAX_QUOTED_PATTERN = 120;
|
|
10498
|
+
const DRAFT_2020_12 = /* @__PURE__ */ new Set(["https://json-schema.org/draft/2020-12/schema", "http://json-schema.org/draft/2020-12/schema"]);
|
|
10499
|
+
const DRAFT_2019_09 = /* @__PURE__ */ new Set(["https://json-schema.org/draft/2019-09/schema", "http://json-schema.org/draft/2019-09/schema"]);
|
|
10500
|
+
const DRAFT_07_OR_06 = /* @__PURE__ */ new Set([
|
|
10501
|
+
"https://json-schema.org/draft-07/schema",
|
|
10502
|
+
"http://json-schema.org/draft-07/schema",
|
|
10503
|
+
"https://json-schema.org/draft-06/schema",
|
|
10504
|
+
"http://json-schema.org/draft-06/schema"
|
|
10505
|
+
]);
|
|
10506
|
+
function declaredDialect(schema) {
|
|
10507
|
+
const declared = schema.$schema;
|
|
10508
|
+
if (typeof declared !== "string") return "2020-12";
|
|
10509
|
+
const uri = declared.replace(/#$/, "");
|
|
10510
|
+
if (DRAFT_2020_12.has(uri)) return "2020-12";
|
|
10511
|
+
if (DRAFT_2019_09.has(uri)) return "2019-09";
|
|
10512
|
+
if (DRAFT_07_OR_06.has(uri)) return "draft-7";
|
|
10513
|
+
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.`);
|
|
10514
|
+
}
|
|
10515
|
+
function quote(pattern) {
|
|
10516
|
+
return pattern.length > MAX_QUOTED_PATTERN ? `${pattern.slice(0, MAX_QUOTED_PATTERN)}…` : pattern;
|
|
10517
|
+
}
|
|
10518
|
+
var PatternLedger = class {
|
|
10519
|
+
remaining = PATTERN_EVALUATION_BUDGET;
|
|
10520
|
+
unevaluated = /* @__PURE__ */ new Set();
|
|
10521
|
+
reset() {
|
|
10522
|
+
this.remaining = PATTERN_EVALUATION_BUDGET;
|
|
10523
|
+
this.unevaluated.clear();
|
|
10524
|
+
}
|
|
10525
|
+
};
|
|
10526
|
+
var LinearPattern = class {
|
|
10527
|
+
source;
|
|
10528
|
+
flags;
|
|
10529
|
+
compiled;
|
|
10530
|
+
ledger;
|
|
10531
|
+
constructor(source, flags, compiled, ledger) {
|
|
10532
|
+
this.source = source;
|
|
10533
|
+
this.flags = flags;
|
|
10534
|
+
this.compiled = compiled;
|
|
10535
|
+
this.ledger = ledger;
|
|
10536
|
+
}
|
|
10537
|
+
test(input) {
|
|
10538
|
+
if (!this.compiled.ok) return this.skip(this.compiled.reason);
|
|
10539
|
+
const { regExp } = this.compiled;
|
|
10540
|
+
const cost = regExp.cost(input);
|
|
10541
|
+
if (cost > this.ledger.remaining) return this.skip(`checking a ${input.length}-character value would exceed the evaluation budget`);
|
|
10542
|
+
this.ledger.remaining -= cost;
|
|
10543
|
+
return regExp.search(input, cost) === true;
|
|
10544
|
+
}
|
|
10545
|
+
skip(reason) {
|
|
10546
|
+
this.ledger.unevaluated.add(`pattern "${quote(this.source)}" was not evaluated (${reason})`);
|
|
10547
|
+
return true;
|
|
10548
|
+
}
|
|
10549
|
+
toString() {
|
|
10550
|
+
return `/${this.source}/${this.flags}`;
|
|
10551
|
+
}
|
|
10552
|
+
};
|
|
10553
|
+
function createRegExpEngine(ledger, budget) {
|
|
10554
|
+
const engine = (pattern, flags) => new LinearPattern(pattern, flags, compileLinearRegExp(pattern, flags.includes("u"), budget()), ledger);
|
|
10555
|
+
return Object.assign(engine, { code: "linearRegExp" });
|
|
10556
|
+
}
|
|
10557
|
+
var LinearPatternJsonSchemaValidator = class {
|
|
10558
|
+
ledger = new PatternLedger();
|
|
10559
|
+
engines = /* @__PURE__ */ new Map();
|
|
10560
|
+
compileBudget = { ...SCHEMA_COMPILE_BUDGET };
|
|
10561
|
+
overBudget = /* @__PURE__ */ new WeakSet();
|
|
10562
|
+
engineFor(dialect) {
|
|
10563
|
+
let engine = this.engines.get(dialect);
|
|
10564
|
+
if (!engine) {
|
|
10565
|
+
const options = {
|
|
10566
|
+
strict: false,
|
|
10567
|
+
validateFormats: true,
|
|
10568
|
+
validateSchema: false,
|
|
10569
|
+
allErrors: true,
|
|
10570
|
+
code: { regExp: createRegExpEngine(this.ledger, () => this.compileBudget) }
|
|
10571
|
+
};
|
|
10572
|
+
engine = dialect === "2020-12" ? new Ajv2020(options) : dialect === "2019-09" ? new Ajv2019(options) : new Ajv(options);
|
|
10573
|
+
addFormats(engine);
|
|
10574
|
+
this.engines.set(dialect, engine);
|
|
10575
|
+
}
|
|
10576
|
+
return engine;
|
|
10577
|
+
}
|
|
10578
|
+
getValidator(schema) {
|
|
10579
|
+
const engine = this.engineFor(declaredDialect(schema));
|
|
10580
|
+
const id = schema.$id;
|
|
10581
|
+
const validate = this.tracked(() => (typeof id === "string" ? engine.getSchema(id) : void 0) ?? engine.compile(schema));
|
|
10582
|
+
const overBudget = this.overBudget.has(validate);
|
|
10583
|
+
return (input) => {
|
|
10584
|
+
this.ledger.reset();
|
|
10585
|
+
const valid = validate(input);
|
|
10586
|
+
const unevaluated = [...this.ledger.unevaluated];
|
|
10587
|
+
if (overBudget) unevaluated.unshift("the schema's patterns exceed the compilation budget");
|
|
10588
|
+
if (valid && unevaluated.length === 0) return {
|
|
10589
|
+
valid: true,
|
|
10590
|
+
data: input,
|
|
10591
|
+
errorMessage: void 0
|
|
10592
|
+
};
|
|
10593
|
+
const messages = valid ? [] : [engine.errorsText(validate.errors)];
|
|
10594
|
+
if (unevaluated.length > 0) messages.push(`${unevaluated.join("; ")}, so the value could not be verified against the schema`);
|
|
10595
|
+
return {
|
|
10596
|
+
valid: false,
|
|
10597
|
+
data: void 0,
|
|
10598
|
+
errorMessage: messages.join("; ")
|
|
10599
|
+
};
|
|
10600
|
+
};
|
|
10601
|
+
}
|
|
10602
|
+
tracked(run) {
|
|
10603
|
+
const outer = this.compileBudget;
|
|
10604
|
+
const budget = { ...SCHEMA_COMPILE_BUDGET };
|
|
10605
|
+
this.compileBudget = budget;
|
|
10606
|
+
try {
|
|
10607
|
+
const validate = run();
|
|
10608
|
+
if (isCompileBudgetExhausted(budget)) this.overBudget.add(validate);
|
|
10609
|
+
return validate;
|
|
10610
|
+
} finally {
|
|
10611
|
+
this.compileBudget = outer;
|
|
10612
|
+
}
|
|
10613
|
+
}
|
|
10614
|
+
};
|
|
10615
|
+
//#endregion
|
|
9858
10616
|
//#region ../../core/mcp/uriTemplate.ts
|
|
9859
10617
|
const OPERATORS = [
|
|
9860
10618
|
"+",
|
|
@@ -11490,6 +12248,16 @@ var RemoteClientTransport = class {
|
|
|
11490
12248
|
}
|
|
11491
12249
|
return await res.json();
|
|
11492
12250
|
}
|
|
12251
|
+
releaseOnPageHide() {
|
|
12252
|
+
if (!this._sessionId) return false;
|
|
12253
|
+
this.fetchFn(`${this.baseUrl}/api/mcp/disconnect`, {
|
|
12254
|
+
method: "POST",
|
|
12255
|
+
headers: this.headers,
|
|
12256
|
+
body: JSON.stringify({ sessionId: this._sessionId }),
|
|
12257
|
+
keepalive: true
|
|
12258
|
+
}).catch(() => {});
|
|
12259
|
+
return true;
|
|
12260
|
+
}
|
|
11493
12261
|
async close() {
|
|
11494
12262
|
if (this.closed) return;
|
|
11495
12263
|
this.closed = true;
|
|
@@ -12427,7 +13195,7 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
12427
13195
|
params: request.params,
|
|
12428
13196
|
signal: controller.signal
|
|
12429
13197
|
});
|
|
12430
|
-
this.outputValidator ??= new
|
|
13198
|
+
this.outputValidator ??= new LinearPatternJsonSchemaValidator();
|
|
12431
13199
|
const invalid = validateAppElicitResult(this.outputValidator, request.params, result);
|
|
12432
13200
|
if (invalid) {
|
|
12433
13201
|
this.logger.warn({
|
|
@@ -13026,7 +13794,7 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
13026
13794
|
});
|
|
13027
13795
|
}
|
|
13028
13796
|
validateToolOutput(tool, result) {
|
|
13029
|
-
this.outputValidator ??= new
|
|
13797
|
+
this.outputValidator ??= new LinearPatternJsonSchemaValidator();
|
|
13030
13798
|
return validateToolOutput(this.outputValidator, tool, result);
|
|
13031
13799
|
}
|
|
13032
13800
|
cancelPendingTaskInput(taskId) {
|
|
@@ -13873,6 +14641,10 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
13873
14641
|
getRemoteBackendSessionId() {
|
|
13874
14642
|
if (this.baseTransport instanceof RemoteClientTransport) return this.baseTransport.getRemoteBackendSessionId();
|
|
13875
14643
|
}
|
|
14644
|
+
releaseRemoteSessionOnPageHide() {
|
|
14645
|
+
if (this.baseTransport instanceof RemoteClientTransport) return this.baseTransport.releaseOnPageHide();
|
|
14646
|
+
return false;
|
|
14647
|
+
}
|
|
13876
14648
|
async resumeAfterOAuth(authorizationCode, options) {
|
|
13877
14649
|
await this.completeOAuthFlow(authorizationCode, options?.iss, options?.state);
|
|
13878
14650
|
const remoteSessionId = options?.remoteSessionId;
|
|
@@ -14338,21 +15110,38 @@ function isLoopbackHost(host) {
|
|
|
14338
15110
|
//#region ../../core/auth/node/oauth-callback-server.ts
|
|
14339
15111
|
const DEFAULT_HOSTNAME = "127.0.0.1";
|
|
14340
15112
|
const DEFAULT_CALLBACK_PATH = "/oauth/callback";
|
|
14341
|
-
const SUCCESS_HTML =
|
|
14342
|
-
|
|
14343
|
-
|
|
14344
|
-
|
|
14345
|
-
|
|
14346
|
-
function errorHtml(
|
|
15113
|
+
const SUCCESS_HTML = page("OAuth complete", "OAuth complete. You can close this window.");
|
|
15114
|
+
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.");
|
|
15115
|
+
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.");
|
|
15116
|
+
const ALREADY_HANDLED_HTML = page("OAuth callback already received", "This sign-in has already received its callback. You can close this window.");
|
|
15117
|
+
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.");
|
|
15118
|
+
function errorHtml(serverText) {
|
|
15119
|
+
return page("OAuth error", `OAuth failed. The authorization server said: ${serverText}`);
|
|
15120
|
+
}
|
|
15121
|
+
function exchangeErrorHtml(message) {
|
|
15122
|
+
return page("OAuth error", `OAuth failed: ${message}`);
|
|
15123
|
+
}
|
|
15124
|
+
function page(title, text) {
|
|
14347
15125
|
return `<!DOCTYPE html>
|
|
14348
15126
|
<html>
|
|
14349
|
-
<head><meta charset="utf-8"><title
|
|
14350
|
-
<body><p
|
|
15127
|
+
<head><meta charset="utf-8"><title>${escapeHtml(title)}</title></head>
|
|
15128
|
+
<body><p>${escapeHtml(text)}</p></body>
|
|
14351
15129
|
</html>`;
|
|
14352
15130
|
}
|
|
14353
15131
|
function escapeHtml(s) {
|
|
14354
15132
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
14355
15133
|
}
|
|
15134
|
+
const ANY_STATE = Symbol("any-state");
|
|
15135
|
+
const STOPPED = Symbol("stopped");
|
|
15136
|
+
function createStopSignal() {
|
|
15137
|
+
let fire;
|
|
15138
|
+
return {
|
|
15139
|
+
stopped: new Promise((resolve) => {
|
|
15140
|
+
fire = () => resolve(STOPPED);
|
|
15141
|
+
}),
|
|
15142
|
+
fire
|
|
15143
|
+
};
|
|
15144
|
+
}
|
|
14356
15145
|
var OAuthCallbackServer = class {
|
|
14357
15146
|
server = null;
|
|
14358
15147
|
port = 0;
|
|
@@ -14360,6 +15149,8 @@ var OAuthCallbackServer = class {
|
|
|
14360
15149
|
handled = false;
|
|
14361
15150
|
onCallback;
|
|
14362
15151
|
onError;
|
|
15152
|
+
expectedState = Promise.resolve(ANY_STATE);
|
|
15153
|
+
stopSignal = createStopSignal();
|
|
14363
15154
|
async start(options = {}) {
|
|
14364
15155
|
const { port = 0, hostname = DEFAULT_HOSTNAME, path = DEFAULT_CALLBACK_PATH, onCallback, onError } = options;
|
|
14365
15156
|
if (!path.startsWith("/")) return Promise.reject(/* @__PURE__ */ new Error("Callback path must start with '/' (absolute path)"));
|
|
@@ -14367,6 +15158,8 @@ var OAuthCallbackServer = class {
|
|
|
14367
15158
|
this.onError = onError;
|
|
14368
15159
|
this.handled = false;
|
|
14369
15160
|
this.callbackPath = path;
|
|
15161
|
+
this.stopSignal = createStopSignal();
|
|
15162
|
+
this.expectedState = "expectedState" in options ? Promise.race([Promise.resolve(options.expectedState).catch(() => STOPPED), this.stopSignal.stopped]) : Promise.resolve(ANY_STATE);
|
|
14370
15163
|
return new Promise((resolve, reject) => {
|
|
14371
15164
|
this.server = createServer((req, res) => this.handleRequest(req, res));
|
|
14372
15165
|
this.server.on("error", reject);
|
|
@@ -14390,6 +15183,7 @@ var OAuthCallbackServer = class {
|
|
|
14390
15183
|
}
|
|
14391
15184
|
async stop() {
|
|
14392
15185
|
if (!this.server) return;
|
|
15186
|
+
this.stopSignal.fire();
|
|
14393
15187
|
await new Promise((resolve) => {
|
|
14394
15188
|
this.server.close(() => resolve());
|
|
14395
15189
|
});
|
|
@@ -14398,11 +15192,14 @@ var OAuthCallbackServer = class {
|
|
|
14398
15192
|
handleRequest(req, res) {
|
|
14399
15193
|
const needJson = req.headers["accept"]?.includes("application/json");
|
|
14400
15194
|
const send = (status, body, contentType = "text/html; charset=utf-8") => {
|
|
14401
|
-
res.writeHead(status, {
|
|
15195
|
+
res.writeHead(status, {
|
|
15196
|
+
"Content-Type": contentType,
|
|
15197
|
+
Connection: "close"
|
|
15198
|
+
});
|
|
14402
15199
|
res.end(body);
|
|
14403
15200
|
};
|
|
14404
15201
|
if (req.method !== "GET") {
|
|
14405
|
-
send(405, needJson ? "{\"error\":\"Method Not Allowed\"}" :
|
|
15202
|
+
send(405, needJson ? "{\"error\":\"Method Not Allowed\"}" : NOT_CALLBACK_HTML);
|
|
14406
15203
|
return;
|
|
14407
15204
|
}
|
|
14408
15205
|
let pathname;
|
|
@@ -14419,15 +15216,26 @@ var OAuthCallbackServer = class {
|
|
|
14419
15216
|
search = u.search;
|
|
14420
15217
|
state = u.searchParams.get("state") ?? void 0;
|
|
14421
15218
|
} catch {
|
|
14422
|
-
send(400, needJson ? "{\"error\":\"Bad Request\"}" :
|
|
15219
|
+
send(400, needJson ? "{\"error\":\"Bad Request\"}" : NOT_CALLBACK_HTML);
|
|
14423
15220
|
return;
|
|
14424
15221
|
}
|
|
14425
15222
|
if (pathname !== this.callbackPath) {
|
|
14426
|
-
send(404, needJson ? "{\"error\":\"Not Found\"}" :
|
|
15223
|
+
send(404, needJson ? "{\"error\":\"Not Found\"}" : NOT_CALLBACK_HTML);
|
|
15224
|
+
return;
|
|
15225
|
+
}
|
|
15226
|
+
this.expectedState.then((expected) => this.handleCallback(expected, state, search, needJson, send));
|
|
15227
|
+
}
|
|
15228
|
+
handleCallback(expected, state, search, needJson, send) {
|
|
15229
|
+
if (expected === STOPPED) {
|
|
15230
|
+
send(503, needJson ? "{\"error\":\"Not waiting for a callback\"}" : STOPPED_HTML);
|
|
15231
|
+
return;
|
|
15232
|
+
}
|
|
15233
|
+
if (expected !== ANY_STATE && state !== expected) {
|
|
15234
|
+
send(400, needJson ? "{\"error\":\"State mismatch\"}" : STATE_MISMATCH_HTML);
|
|
14427
15235
|
return;
|
|
14428
15236
|
}
|
|
14429
15237
|
if (this.handled) {
|
|
14430
|
-
send(409, needJson ? "{\"error\":\"Callback already handled\"}" :
|
|
15238
|
+
send(409, needJson ? "{\"error\":\"Callback already handled\"}" : ALREADY_HANDLED_HTML);
|
|
14431
15239
|
return;
|
|
14432
15240
|
}
|
|
14433
15241
|
const params = parseOAuthCallbackParams(search);
|
|
@@ -14445,9 +15253,10 @@ var OAuthCallbackServer = class {
|
|
|
14445
15253
|
const msg = err instanceof Error ? err.message : String(err);
|
|
14446
15254
|
this.onError?.({
|
|
14447
15255
|
error: "callback_error",
|
|
14448
|
-
error_description: msg
|
|
15256
|
+
error_description: msg,
|
|
15257
|
+
source: "callback"
|
|
14449
15258
|
});
|
|
14450
|
-
send(500,
|
|
15259
|
+
send(500, exchangeErrorHtml(msg));
|
|
14451
15260
|
this.stop();
|
|
14452
15261
|
});
|
|
14453
15262
|
else {
|
|
@@ -14460,7 +15269,8 @@ var OAuthCallbackServer = class {
|
|
|
14460
15269
|
const msg = generateOAuthErrorDescription(params);
|
|
14461
15270
|
this.onError?.({
|
|
14462
15271
|
error: params.error,
|
|
14463
|
-
error_description: params.error_description ?? void 0
|
|
15272
|
+
error_description: params.error_description ?? void 0,
|
|
15273
|
+
source: "redirect"
|
|
14464
15274
|
});
|
|
14465
15275
|
send(400, errorHtml(msg));
|
|
14466
15276
|
}
|
|
@@ -14524,6 +15334,14 @@ function toRunnerOAuthError(err) {
|
|
|
14524
15334
|
}
|
|
14525
15335
|
return err instanceof Error ? err : new Error(String(err));
|
|
14526
15336
|
}
|
|
15337
|
+
function stateOf(authorizationUrl) {
|
|
15338
|
+
return authorizationUrl.searchParams.get("state") ?? void 0;
|
|
15339
|
+
}
|
|
15340
|
+
function callbackErrorMessage(params) {
|
|
15341
|
+
if (params.source === "callback") return params.error_description ?? "OAuth callback failed";
|
|
15342
|
+
if (!params.error && !params.error_description) return "OAuth error";
|
|
15343
|
+
return `OAuth authorization failed. The authorization server said: ${params.error_description ? `${params.error_description} (${params.error})` : params.error}`;
|
|
15344
|
+
}
|
|
14527
15345
|
async function runRunnerInteractiveOAuth(options) {
|
|
14528
15346
|
const server = (options.createCallbackServer ?? createOAuthCallbackServer)();
|
|
14529
15347
|
let flowResolve;
|
|
@@ -14553,11 +15371,16 @@ async function runRunnerInteractiveOAuth(options) {
|
|
|
14553
15371
|
process.on("SIGTERM", onSignal);
|
|
14554
15372
|
}
|
|
14555
15373
|
let timeoutId;
|
|
15374
|
+
let resolveExpectedState;
|
|
15375
|
+
const expectedState = new Promise((resolve) => {
|
|
15376
|
+
resolveExpectedState = resolve;
|
|
15377
|
+
});
|
|
14556
15378
|
try {
|
|
14557
15379
|
const { redirectUrl } = await racingSignals(server.start({
|
|
14558
15380
|
hostname: options.callbackListen.hostname,
|
|
14559
15381
|
port: options.callbackListen.port,
|
|
14560
15382
|
path: options.callbackListen.pathname,
|
|
15383
|
+
expectedState,
|
|
14561
15384
|
onCallback: async (params) => {
|
|
14562
15385
|
try {
|
|
14563
15386
|
await options.client.completeOAuthFlow(params.code, params.iss, params.state);
|
|
@@ -14567,10 +15390,7 @@ async function runRunnerInteractiveOAuth(options) {
|
|
|
14567
15390
|
}
|
|
14568
15391
|
},
|
|
14569
15392
|
onError: (params) => {
|
|
14570
|
-
flowReject(new Error(
|
|
14571
|
-
/* v8 ignore next -- params.error is a required non-null string, so the "OAuth error" fallback is unreachable */
|
|
14572
|
-
params.error_description ?? params.error ?? "OAuth error"
|
|
14573
|
-
));
|
|
15393
|
+
flowReject(new Error(callbackErrorMessage(params)));
|
|
14574
15394
|
}
|
|
14575
15395
|
}));
|
|
14576
15396
|
options.onCallbackServer?.(server);
|
|
@@ -14586,10 +15406,16 @@ async function runRunnerInteractiveOAuth(options) {
|
|
|
14586
15406
|
})]);
|
|
14587
15407
|
waitForCallback.catch(() => {});
|
|
14588
15408
|
if (options.authorizationUrl) {
|
|
15409
|
+
resolveExpectedState(stateOf(options.authorizationUrl));
|
|
14589
15410
|
await racingSignals(options.client.beginInteractiveAuthorization(options.authorizationUrl));
|
|
14590
15411
|
await waitForCallback;
|
|
14591
|
-
} else
|
|
14592
|
-
|
|
15412
|
+
} else {
|
|
15413
|
+
const authUrl = await racingSignals(options.client.authenticate());
|
|
15414
|
+
if (authUrl !== void 0) {
|
|
15415
|
+
resolveExpectedState(stateOf(authUrl));
|
|
15416
|
+
await waitForCallback;
|
|
15417
|
+
} else return { kind: "already_authorized" };
|
|
15418
|
+
}
|
|
14593
15419
|
if (options.authChallenge) {
|
|
14594
15420
|
if (!await racingSignals(options.client.checkAuthChallengeSatisfied(options.authChallenge, { scopeOnly: true }))) return {
|
|
14595
15421
|
kind: "insufficient_scope",
|
|
@@ -15655,6 +16481,7 @@ function connectCancelledError() {
|
|
|
15655
16481
|
}
|
|
15656
16482
|
//#endregion
|
|
15657
16483
|
//#region src/daemon/server.ts
|
|
16484
|
+
const DAEMON_VERSION = readInspectorVersionSafe(import.meta.url);
|
|
15658
16485
|
const MCPDO_RUN_OPTIONS = { skillBudgetHint: MCPDO_SKILL_BUDGET_HINT };
|
|
15659
16486
|
const autoCancelElicitationChannel = { request(frame) {
|
|
15660
16487
|
return Promise.resolve({
|
|
@@ -15828,7 +16655,8 @@ var DaemonServer = class DaemonServer {
|
|
|
15828
16655
|
result: {
|
|
15829
16656
|
pong: true,
|
|
15830
16657
|
pid: process.pid,
|
|
15831
|
-
stopping: this.stopping
|
|
16658
|
+
stopping: this.stopping,
|
|
16659
|
+
version: DAEMON_VERSION
|
|
15832
16660
|
}
|
|
15833
16661
|
} };
|
|
15834
16662
|
case "connect": {
|
|
@@ -15976,13 +16804,23 @@ var DaemonServer = class DaemonServer {
|
|
|
15976
16804
|
if (isTerminalStatus(client.getStatus())) throw new CliExitCodeError(EXIT_CODES.UNREACHABLE, "The connection dropped before this command could run; re-run the command to reconnect.", { code: "connection_stale" });
|
|
15977
16805
|
const unwire = wireElicitationBridge(client, autoCancelElicitationChannel, requestId);
|
|
15978
16806
|
const stop = new AbortController();
|
|
15979
|
-
const
|
|
16807
|
+
const abortRequests = new AbortController();
|
|
16808
|
+
const onCallerGone = () => {
|
|
16809
|
+
stop.abort();
|
|
16810
|
+
abortRequests.abort();
|
|
16811
|
+
};
|
|
15980
16812
|
signal?.addEventListener("abort", onCallerGone, { once: true });
|
|
15981
16813
|
const onStatus = (event) => {
|
|
15982
|
-
if (isTerminalStatus(event.detail))
|
|
16814
|
+
if (!isTerminalStatus(event.detail)) return;
|
|
16815
|
+
const lost = {
|
|
16816
|
+
reason: "connection_lost",
|
|
16817
|
+
detail: `the connection went ${event.detail}`
|
|
16818
|
+
};
|
|
16819
|
+
stop.abort(lost);
|
|
16820
|
+
abortRequests.abort(new DOMException(`load run stopped: ${lost.detail}`, "AbortError"));
|
|
15983
16821
|
};
|
|
15984
16822
|
client.addEventListener("statusChange", onStatus);
|
|
15985
|
-
const clearAmbientSignal = client.setAmbientRequestSignal(
|
|
16823
|
+
const clearAmbientSignal = client.setAmbientRequestSignal(abortRequests.signal);
|
|
15986
16824
|
const extras = [];
|
|
15987
16825
|
try {
|
|
15988
16826
|
return {
|
|
@@ -15990,8 +16828,8 @@ var DaemonServer = class DaemonServer {
|
|
|
15990
16828
|
summary: await runToolLoad(client, methodArgs, load, {
|
|
15991
16829
|
signal: stop.signal,
|
|
15992
16830
|
...openLoadClient && { openConnection: async () => {
|
|
15993
|
-
const extra = await openLoadClient(client,
|
|
15994
|
-
const clearExtraSignal = extra.setAmbientRequestSignal(
|
|
16831
|
+
const extra = await openLoadClient(client, abortRequests.signal);
|
|
16832
|
+
const clearExtraSignal = extra.setAmbientRequestSignal(abortRequests.signal);
|
|
15995
16833
|
const unwireExtra = wireElicitationBridge(extra, autoCancelElicitationChannel, requestId);
|
|
15996
16834
|
extras.push({
|
|
15997
16835
|
client: extra,
|
|
@@ -16277,4 +17115,4 @@ function raceCallOrElicitation(outcome, channel) {
|
|
|
16277
17115
|
}))]);
|
|
16278
17116
|
}
|
|
16279
17117
|
//#endregion
|
|
16280
|
-
export {
|
|
17118
|
+
export { withDefaultCatalogPath as $, resolveLoadOptions as A, assertSocketPathWithinLimit as B, clearAllOAuthClientState as C, loadSummaryWarnings as D, LOAD_FLAG_CONFLICT as E, generateDaemonToken as F, getDaemonSocketPath as G, ensureDaemonDir as H, getDaemonTokenFromEnv as I, loadServerEntries as J, readInspectorVersion as K, readDaemonTokenFile as L, sanitizeDeep as M, sanitizeText as N, positiveIntegerParser as O, encodeRequest as P, resolveServerSource as Q, DAEMON_DIR_ENV as R, NodeOAuthStorage as S, resetNodeOAuthStorageCache as T, getDaemonDir as U, createPrivateDaemonDir as V, getDaemonLogPath as W, parseHeaderPair as X, selectServerEntry as Y, parseKeyValuePair as Z, isCliAutoOpenForced as _, awaitableError as _t, obtainPendingUrlForKey as a, readOAuthStore as at, DEFAULT_CONNECT_TIMEOUT_MS as b, runAuthHelper as c, setSecretStorageWarningsQuiet as ct, emaLogin as d, CallbackNavigation as dt, DEFAULT_MAX_FETCH_REQUESTS as et, emaLogout as f, clearEmaIdpSession as ft, runEmaIdpInteractiveFlow as g, parseIdpOAuthStorageKey as gt, requireIdp as h, normalizeIdpIssuer as ht, obtainPendingAuthUrl as i, handleError as it, isSafeLinkTarget as j, positiveNumberParser as k, writePendingAuthMarker as l, warnAboutSecretStorage as lt, loadEmaIdpConfig as m, idpOAuthStorageKey as mt, AUTH_HELPER_COMMAND as n, CliExitCodeError as nt, pendingAuthMarkerPath as o, disallowMemorySecretStoreFallback as ot, getEmaStatus as p, getEmaIdpLoginState as pt, readInspectorVersionSafe as q, PENDING_AUTH_TTL_MS as r, EXIT_CODES as rt, removeOwnPendingAuthMarker as s, getSecretStorageInfo as st, DaemonServer as t, DEFAULT_TASK_TTL_MS as tt, authorizeInFrontend as u, InMemorySecretStore as ut, PLAIN as v, awaitableLog as vt, getStateFilePath as w, withConnectTimeout as x, styleFromOpts as y, DAEMON_TOKEN_ENV as z };
|