@chrischall/gemini-mcp 2.1.2 → 2.1.4
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/bundle.js +531 -139
- package/dist/client.js +22 -7
- package/dist/images.js +52 -2
- package/dist/library.js +3 -2
- package/dist/storage/media.js +3 -2
- package/dist/tenant.js +93 -0
- package/dist/tools/files.js +24 -9
- package/dist/version.js +1 -1
- package/package.json +3 -3
- package/server.json +2 -2
package/dist/bundle.js
CHANGED
|
@@ -41,6 +41,41 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
41
41
|
mod
|
|
42
42
|
));
|
|
43
43
|
|
|
44
|
+
// node_modules/@chrischall/mcp-utils/dist/cancel/index.js
|
|
45
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
46
|
+
function withCallSignal(signal, fn, request) {
|
|
47
|
+
return signal ? storage.run({ signal, ...request ? { request } : {} }, fn) : fn();
|
|
48
|
+
}
|
|
49
|
+
function currentCallSignal() {
|
|
50
|
+
return storage.getStore()?.signal;
|
|
51
|
+
}
|
|
52
|
+
function withAmbientCancellation(own2) {
|
|
53
|
+
const ambient = currentCallSignal();
|
|
54
|
+
if (!ambient)
|
|
55
|
+
return own2;
|
|
56
|
+
if (!own2)
|
|
57
|
+
return ambient;
|
|
58
|
+
return AbortSignal.any([own2, ambient]);
|
|
59
|
+
}
|
|
60
|
+
var storage;
|
|
61
|
+
var init_cancel = __esm({
|
|
62
|
+
"node_modules/@chrischall/mcp-utils/dist/cancel/index.js"() {
|
|
63
|
+
storage = new AsyncLocalStorage();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// node_modules/@chrischall/mcp-utils/dist/caller/index.js
|
|
68
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
69
|
+
function withCallerCapabilities(capabilities, fn) {
|
|
70
|
+
return capabilities ? storage2.run(capabilities, fn) : fn();
|
|
71
|
+
}
|
|
72
|
+
var storage2;
|
|
73
|
+
var init_caller = __esm({
|
|
74
|
+
"node_modules/@chrischall/mcp-utils/dist/caller/index.js"() {
|
|
75
|
+
storage2 = new AsyncLocalStorage2();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
44
79
|
// node_modules/@modelcontextprotocol/server/dist/chunk-Br0eD_fh.mjs
|
|
45
80
|
var __create2, __defProp2, __getOwnPropDesc2, __getOwnPropNames2, __getProtoOf2, __hasOwnProp2, __commonJSMin, __exportAll, __copyProps2, __toESM2;
|
|
46
81
|
var init_chunk_Br0eD_fh = __esm({
|
|
@@ -4926,7 +4961,7 @@ var require_memoizer = __commonJS({
|
|
|
4926
4961
|
var NONE2 = 0;
|
|
4927
4962
|
var ASSUMED2 = 1;
|
|
4928
4963
|
var PROVEN2 = 2;
|
|
4929
|
-
function isRecursive2(inst, stack,
|
|
4964
|
+
function isRecursive2(inst, stack, resolve4) {
|
|
4930
4965
|
const cached2 = recursive2.get(inst);
|
|
4931
4966
|
if (cached2 !== void 0)
|
|
4932
4967
|
return cached2 ? PROVEN2 : NONE2;
|
|
@@ -4936,7 +4971,7 @@ var require_memoizer = __commonJS({
|
|
|
4936
4971
|
let result = NONE2;
|
|
4937
4972
|
const check2 = (child) => {
|
|
4938
4973
|
if (result !== PROVEN2 && child?._zod) {
|
|
4939
|
-
const answer = isRecursive2(child, stack,
|
|
4974
|
+
const answer = isRecursive2(child, stack, resolve4);
|
|
4940
4975
|
if (answer > result)
|
|
4941
4976
|
result = answer;
|
|
4942
4977
|
}
|
|
@@ -4947,7 +4982,7 @@ var require_memoizer = __commonJS({
|
|
|
4947
4982
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
4948
4983
|
if (spread && !desc.enumerable)
|
|
4949
4984
|
continue;
|
|
4950
|
-
const child = desc.get ? ASSUMED2 : desc.value?._zod ? isRecursive2(desc.value, stack,
|
|
4985
|
+
const child = desc.get ? ASSUMED2 : desc.value?._zod ? isRecursive2(desc.value, stack, resolve4) : NONE2;
|
|
4951
4986
|
if (child > answer)
|
|
4952
4987
|
answer = child;
|
|
4953
4988
|
}
|
|
@@ -5011,7 +5046,7 @@ var require_memoizer = __commonJS({
|
|
|
5011
5046
|
break;
|
|
5012
5047
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
5013
5048
|
case "lazy": {
|
|
5014
|
-
const inner = def._cachedInner ?? (
|
|
5049
|
+
const inner = def._cachedInner ?? (resolve4 ? inst._zod.innerType : void 0);
|
|
5015
5050
|
merge2(inner ? isRecursive2(inner, stack, false) : ASSUMED2);
|
|
5016
5051
|
break;
|
|
5017
5052
|
}
|
|
@@ -26845,14 +26880,14 @@ function inputRequiredRoundsExceededMessage(method, maxRounds) {
|
|
|
26845
26880
|
return `Multi-round-trip request '${method}' still required input after ${maxRounds} rounds (inputRequired.maxRounds)`;
|
|
26846
26881
|
}
|
|
26847
26882
|
function sleep(ms, signal) {
|
|
26848
|
-
return new Promise((
|
|
26883
|
+
return new Promise((resolve4, reject) => {
|
|
26849
26884
|
if (signal?.aborted) {
|
|
26850
26885
|
reject(signal.reason instanceof SdkError ? signal.reason : new SdkError(SdkErrorCode.RequestTimeout, String(signal.reason)));
|
|
26851
26886
|
return;
|
|
26852
26887
|
}
|
|
26853
26888
|
const timer = setTimeout(() => {
|
|
26854
26889
|
signal?.removeEventListener("abort", onAbort);
|
|
26855
|
-
|
|
26890
|
+
resolve4();
|
|
26856
26891
|
}, ms);
|
|
26857
26892
|
const onAbort = () => {
|
|
26858
26893
|
clearTimeout(timer);
|
|
@@ -28648,7 +28683,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
28648
28683
|
const flowStartedAt = Date.now();
|
|
28649
28684
|
let onAbort;
|
|
28650
28685
|
let cleanupMessageId;
|
|
28651
|
-
return new Promise((
|
|
28686
|
+
return new Promise((resolve4, reject) => {
|
|
28652
28687
|
const earlyReject = (error62) => {
|
|
28653
28688
|
reject(error62);
|
|
28654
28689
|
};
|
|
@@ -28716,7 +28751,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
28716
28751
|
}
|
|
28717
28752
|
if (decoded.kind === "invalid") return reject(decoded.error);
|
|
28718
28753
|
if (decoded.kind === "input_required") {
|
|
28719
|
-
if (options?.allowInputRequired === true) return
|
|
28754
|
+
if (options?.allowInputRequired === true) return resolve4(manualInputRequiredValue(decoded));
|
|
28720
28755
|
const flow = {
|
|
28721
28756
|
codec: codec2,
|
|
28722
28757
|
request,
|
|
@@ -28728,11 +28763,11 @@ var init_src_CX2iR2pK = __esm({
|
|
|
28728
28763
|
params
|
|
28729
28764
|
}, resultSchema, legOptions)
|
|
28730
28765
|
};
|
|
28731
|
-
return
|
|
28766
|
+
return resolve4(this._resolveNonCompleteResult(decoded, flow));
|
|
28732
28767
|
}
|
|
28733
28768
|
const result = decoded.result;
|
|
28734
28769
|
validateStandardSchema(resultSchema, result).then((parseResult) => {
|
|
28735
|
-
if (parseResult.success)
|
|
28770
|
+
if (parseResult.success) resolve4(parseResult.data);
|
|
28736
28771
|
else reject(new SdkError(SdkErrorCode.InvalidResult, `Invalid result for ${request.method}: ${parseResult.error}`));
|
|
28737
28772
|
}, reject);
|
|
28738
28773
|
});
|
|
@@ -31548,7 +31583,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
31548
31583
|
ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, ref);
|
|
31549
31584
|
const schOrFunc = root.refs[ref];
|
|
31550
31585
|
if (schOrFunc) return schOrFunc;
|
|
31551
|
-
let _sch =
|
|
31586
|
+
let _sch = resolve4.call(this, root, ref);
|
|
31552
31587
|
if (_sch === void 0) {
|
|
31553
31588
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
31554
31589
|
const { schemaId } = this.opts;
|
|
@@ -31574,7 +31609,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
31574
31609
|
function sameSchemaEnv(s1, s2) {
|
|
31575
31610
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
31576
31611
|
}
|
|
31577
|
-
function
|
|
31612
|
+
function resolve4(root, ref) {
|
|
31578
31613
|
let sch;
|
|
31579
31614
|
while (typeof (sch = this.refs[ref]) == "string") ref = sch;
|
|
31580
31615
|
return sch || this.schemas[ref] || resolveSchema.call(this, root, ref);
|
|
@@ -32024,47 +32059,47 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
32024
32059
|
else if (typeof uri === "object") uri = parse3(serialize(uri, options), options);
|
|
32025
32060
|
return uri;
|
|
32026
32061
|
}
|
|
32027
|
-
function
|
|
32062
|
+
function resolve4(baseURI, relativeURI, options) {
|
|
32028
32063
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
32029
32064
|
const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
32030
32065
|
schemelessOptions.skipEscape = true;
|
|
32031
32066
|
return serialize(resolved, schemelessOptions);
|
|
32032
32067
|
}
|
|
32033
|
-
function resolveComponent(base,
|
|
32068
|
+
function resolveComponent(base, relative2, options, skipNormalization) {
|
|
32034
32069
|
const target = {};
|
|
32035
32070
|
if (!skipNormalization) {
|
|
32036
32071
|
base = parse3(serialize(base, options), options);
|
|
32037
|
-
|
|
32072
|
+
relative2 = parse3(serialize(relative2, options), options);
|
|
32038
32073
|
}
|
|
32039
32074
|
options = options || {};
|
|
32040
|
-
if (!options.tolerant &&
|
|
32041
|
-
target.scheme =
|
|
32042
|
-
target.userinfo =
|
|
32043
|
-
target.host =
|
|
32044
|
-
target.port =
|
|
32045
|
-
target.path = removeDotSegments(
|
|
32046
|
-
target.query =
|
|
32075
|
+
if (!options.tolerant && relative2.scheme) {
|
|
32076
|
+
target.scheme = relative2.scheme;
|
|
32077
|
+
target.userinfo = relative2.userinfo;
|
|
32078
|
+
target.host = relative2.host;
|
|
32079
|
+
target.port = relative2.port;
|
|
32080
|
+
target.path = removeDotSegments(relative2.path || "");
|
|
32081
|
+
target.query = relative2.query;
|
|
32047
32082
|
} else {
|
|
32048
|
-
if (
|
|
32049
|
-
target.userinfo =
|
|
32050
|
-
target.host =
|
|
32051
|
-
target.port =
|
|
32052
|
-
target.path = removeDotSegments(
|
|
32053
|
-
target.query =
|
|
32083
|
+
if (relative2.userinfo !== void 0 || relative2.host !== void 0 || relative2.port !== void 0) {
|
|
32084
|
+
target.userinfo = relative2.userinfo;
|
|
32085
|
+
target.host = relative2.host;
|
|
32086
|
+
target.port = relative2.port;
|
|
32087
|
+
target.path = removeDotSegments(relative2.path || "");
|
|
32088
|
+
target.query = relative2.query;
|
|
32054
32089
|
} else {
|
|
32055
|
-
if (!
|
|
32090
|
+
if (!relative2.path) {
|
|
32056
32091
|
target.path = base.path;
|
|
32057
|
-
if (
|
|
32092
|
+
if (relative2.query !== void 0) target.query = relative2.query;
|
|
32058
32093
|
else target.query = base.query;
|
|
32059
32094
|
} else {
|
|
32060
|
-
if (
|
|
32095
|
+
if (relative2.path[0] === "/") target.path = removeDotSegments(relative2.path);
|
|
32061
32096
|
else {
|
|
32062
|
-
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) target.path = "/" +
|
|
32063
|
-
else if (!base.path) target.path =
|
|
32064
|
-
else target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
32097
|
+
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) target.path = "/" + relative2.path;
|
|
32098
|
+
else if (!base.path) target.path = relative2.path;
|
|
32099
|
+
else target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative2.path;
|
|
32065
32100
|
target.path = removeDotSegments(target.path);
|
|
32066
32101
|
}
|
|
32067
|
-
target.query =
|
|
32102
|
+
target.query = relative2.query;
|
|
32068
32103
|
}
|
|
32069
32104
|
target.userinfo = base.userinfo;
|
|
32070
32105
|
target.host = base.host;
|
|
@@ -32072,7 +32107,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
32072
32107
|
}
|
|
32073
32108
|
target.scheme = base.scheme;
|
|
32074
32109
|
}
|
|
32075
|
-
target.fragment =
|
|
32110
|
+
target.fragment = relative2.fragment;
|
|
32076
32111
|
return target;
|
|
32077
32112
|
}
|
|
32078
32113
|
function equal(uriA, uriB, options) {
|
|
@@ -32198,7 +32233,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
32198
32233
|
const fastUri = {
|
|
32199
32234
|
SCHEMES,
|
|
32200
32235
|
normalize,
|
|
32201
|
-
resolve:
|
|
32236
|
+
resolve: resolve4,
|
|
32202
32237
|
resolveComponent,
|
|
32203
32238
|
equal,
|
|
32204
32239
|
serialize,
|
|
@@ -37890,7 +37925,7 @@ var init_stdio = __esm({
|
|
|
37890
37925
|
}
|
|
37891
37926
|
send(message) {
|
|
37892
37927
|
if (this._closed) return Promise.reject(/* @__PURE__ */ new Error("StdioServerTransport is closed"));
|
|
37893
|
-
return new Promise((
|
|
37928
|
+
return new Promise((resolve4, reject) => {
|
|
37894
37929
|
const json2 = serializeMessage(message);
|
|
37895
37930
|
let settled = false;
|
|
37896
37931
|
const onError = (error62) => {
|
|
@@ -37905,14 +37940,14 @@ var init_stdio = __esm({
|
|
|
37905
37940
|
settled = true;
|
|
37906
37941
|
this._stdout.off("error", onError);
|
|
37907
37942
|
this._stdout.off("drain", onDrain);
|
|
37908
|
-
|
|
37943
|
+
resolve4();
|
|
37909
37944
|
};
|
|
37910
37945
|
this._stdout.once("error", onError);
|
|
37911
37946
|
if (this._stdout.write(json2)) {
|
|
37912
37947
|
if (settled) return;
|
|
37913
37948
|
settled = true;
|
|
37914
37949
|
this._stdout.off("error", onError);
|
|
37915
|
-
|
|
37950
|
+
resolve4();
|
|
37916
37951
|
} else if (!settled) this._stdout.once("drain", onDrain);
|
|
37917
37952
|
});
|
|
37918
37953
|
}
|
|
@@ -37966,14 +38001,14 @@ var init_stdio = __esm({
|
|
|
37966
38001
|
*/
|
|
37967
38002
|
async whenRequestsAnswered(timeoutMs) {
|
|
37968
38003
|
if (this._closed || this._pendingRequests.size === 0) return true;
|
|
37969
|
-
return await new Promise((
|
|
38004
|
+
return await new Promise((resolve4) => {
|
|
37970
38005
|
const waiter = () => {
|
|
37971
38006
|
clearTimeout(timer);
|
|
37972
|
-
|
|
38007
|
+
resolve4(true);
|
|
37973
38008
|
};
|
|
37974
38009
|
const timer = setTimeout(() => {
|
|
37975
38010
|
this._drainWaiters = this._drainWaiters.filter((pending) => pending !== waiter);
|
|
37976
|
-
|
|
38011
|
+
resolve4(false);
|
|
37977
38012
|
}, timeoutMs);
|
|
37978
38013
|
this._drainWaiters.push(waiter);
|
|
37979
38014
|
});
|
|
@@ -38013,7 +38048,7 @@ var init_dist = __esm({
|
|
|
38013
38048
|
|
|
38014
38049
|
// node_modules/@chrischall/mcp-utils/dist/errors/index.js
|
|
38015
38050
|
function redactSecrets(text) {
|
|
38016
|
-
return text.replace(BEARER_RE, "$1[REDACTED]").replace(BASIC_AUTH_RE, "$1[REDACTED]").replace(SET_COOKIE_RE, "$1$2=[REDACTED]").replace(COOKIE_HEADER_RE, (_m, prefix, pairs) => `${prefix}${pairs.replace(/=[^;,\s]*/g, "=[REDACTED]")}`).replace(API_KEY_RE, "[REDACTED]").replace(QUERY_SECRET_RE, "$1[REDACTED]").replace(AWS_SIGV4_RE, "$1[REDACTED]").replace(JSON_SECRET_DQ_RE, "$1[REDACTED]$2").replace(JSON_SECRET_SQ_RE, "$1[REDACTED]$2").replace(JWT_RE, "[REDACTED]");
|
|
38051
|
+
return text.replace(BEARER_RE, "$1[REDACTED]").replace(BASIC_AUTH_RE, "$1[REDACTED]").replace(SET_COOKIE_RE, "$1$2=[REDACTED]").replace(COOKIE_HEADER_RE, (_m, prefix, pairs) => `${prefix}${pairs.replace(/=[^;,\s]*/g, "=[REDACTED]")}`).replace(API_KEY_RE, "[REDACTED]").replace(HEADER_SECRET_RE, "$1[REDACTED]").replace(QUERY_SECRET_RE, "$1[REDACTED]").replace(OAUTH_CODE_RE, "$1[REDACTED]").replace(FORM_PASSWORD_RE, "$1[REDACTED]").replace(AWS_SIGV4_RE, "$1[REDACTED]").replace(JSON_SECRET_DQ_RE, "$1[REDACTED]$2").replace(JSON_SECRET_SQ_RE, "$1[REDACTED]$2").replace(JWT_RE, "[REDACTED]");
|
|
38017
38052
|
}
|
|
38018
38053
|
function truncateErrorMessage(text, max = DEFAULT_ERROR_MESSAGE_MAX) {
|
|
38019
38054
|
const str = text === null || text === void 0 ? "" : String(text);
|
|
@@ -38027,7 +38062,7 @@ function messageOf(err) {
|
|
|
38027
38062
|
return err.message;
|
|
38028
38063
|
return String(err);
|
|
38029
38064
|
}
|
|
38030
|
-
var DEFAULT_ERROR_MESSAGE_MAX, McpToolError, BEARER_RE, JWT_RE, BASIC_AUTH_RE, SET_COOKIE_RE, COOKIE_HEADER_RE, API_KEY_RE, QUERY_SECRET_RE, AWS_SIGV4_RE, JSON_SECRET_KEYS, JSON_SECRET_DQ_RE, JSON_SECRET_SQ_RE;
|
|
38065
|
+
var DEFAULT_ERROR_MESSAGE_MAX, McpToolError, BEARER_RE, JWT_RE, BASIC_AUTH_RE, SET_COOKIE_RE, COOKIE_HEADER_RE, API_KEY_RE, QUERY_SECRET_RE, OAUTH_CODE_RE, FORM_PASSWORD_RE, HEADER_SECRET_RE, AWS_SIGV4_RE, JSON_SECRET_KEYS, JSON_SECRET_DQ_RE, JSON_SECRET_SQ_RE;
|
|
38031
38066
|
var init_errors = __esm({
|
|
38032
38067
|
"node_modules/@chrischall/mcp-utils/dist/errors/index.js"() {
|
|
38033
38068
|
DEFAULT_ERROR_MESSAGE_MAX = 500;
|
|
@@ -38061,11 +38096,26 @@ var init_errors = __esm({
|
|
|
38061
38096
|
"whsec_[A-Za-z0-9]{16,}\\b"
|
|
38062
38097
|
// webhook signing secret (Stripe-style)
|
|
38063
38098
|
].map((p) => `\\b${p}`).join("|"), "g");
|
|
38064
|
-
QUERY_SECRET_RE = /([?&](?:
|
|
38099
|
+
QUERY_SECRET_RE = /([?&](?:(?:access|refresh|id|auth|session|csrf|xsrf)[_-]?token|client[_-]?secret|api[_-]?secret|api[_-]?key|password|passwd|signature|token|key|sig)=)[^&#\s"'<>`]+/gi;
|
|
38100
|
+
OAUTH_CODE_RE = /([?&]code=)(?=[^&#\s"'<>`]{16,})[^&#\s"'<>`]+/gi;
|
|
38101
|
+
FORM_PASSWORD_RE = /((?:^|[\s,;:"'(\[{])(?:password|passwd)=)[^&#\s"'<>`]+/gim;
|
|
38102
|
+
HEADER_SECRET_RE = /(\b(?:x[-_][a-z0-9_-]*?(?:api[-_]?key|token|secret|auth)[a-z0-9_-]*|api[-_]?key)\s*:\s*)[^\s,;"'<>`]+/gi;
|
|
38065
38103
|
AWS_SIGV4_RE = /([?&]X-Amz-(?:Signature|Security-Token|Credential)=)[^&#\s"'<>`]+/gi;
|
|
38066
|
-
JSON_SECRET_KEYS =
|
|
38067
|
-
|
|
38068
|
-
|
|
38104
|
+
JSON_SECRET_KEYS = [
|
|
38105
|
+
"(?:access|refresh|id|auth|session|bearer|csrf|xsrf)[_-]?token",
|
|
38106
|
+
"client[_-]?secret",
|
|
38107
|
+
"api[_-]?secret",
|
|
38108
|
+
"(?:x[_-])?api[_-]?key",
|
|
38109
|
+
"private[_-]?key",
|
|
38110
|
+
"x[_-][a-z0-9_-]*?(?:api[_-]?key|token|secret|auth)[a-z0-9_-]*",
|
|
38111
|
+
"(?:proxy-)?authorization",
|
|
38112
|
+
"password",
|
|
38113
|
+
"passwd",
|
|
38114
|
+
"secret",
|
|
38115
|
+
"token"
|
|
38116
|
+
].join("|");
|
|
38117
|
+
JSON_SECRET_DQ_RE = new RegExp(`("(?:${JSON_SECRET_KEYS})"\\s*:\\s*")(?:[^"\\\\]|\\\\.)*(")`, "gi");
|
|
38118
|
+
JSON_SECRET_SQ_RE = new RegExp(`('(?:${JSON_SECRET_KEYS})'\\s*:\\s*')(?:[^'\\\\]|\\\\.)*(')`, "gi");
|
|
38069
38119
|
}
|
|
38070
38120
|
});
|
|
38071
38121
|
|
|
@@ -42565,7 +42615,7 @@ function isRef(value) {
|
|
|
42565
42615
|
function cloneIssues(issues) {
|
|
42566
42616
|
return issues.map((iss) => iss.path ? { ...iss, path: iss.path.slice() } : { ...iss });
|
|
42567
42617
|
}
|
|
42568
|
-
function isRecursive(inst, stack,
|
|
42618
|
+
function isRecursive(inst, stack, resolve4) {
|
|
42569
42619
|
const cached2 = recursive.get(inst);
|
|
42570
42620
|
if (cached2 !== void 0)
|
|
42571
42621
|
return cached2 ? PROVEN : NONE;
|
|
@@ -42575,7 +42625,7 @@ function isRecursive(inst, stack, resolve2) {
|
|
|
42575
42625
|
let result = NONE;
|
|
42576
42626
|
const check2 = (child) => {
|
|
42577
42627
|
if (result !== PROVEN && child?._zod) {
|
|
42578
|
-
const answer = isRecursive(child, stack,
|
|
42628
|
+
const answer = isRecursive(child, stack, resolve4);
|
|
42579
42629
|
if (answer > result)
|
|
42580
42630
|
result = answer;
|
|
42581
42631
|
}
|
|
@@ -42586,7 +42636,7 @@ function isRecursive(inst, stack, resolve2) {
|
|
|
42586
42636
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
42587
42637
|
if (spread && !desc.enumerable)
|
|
42588
42638
|
continue;
|
|
42589
|
-
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack,
|
|
42639
|
+
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve4) : NONE;
|
|
42590
42640
|
if (child > answer)
|
|
42591
42641
|
answer = child;
|
|
42592
42642
|
}
|
|
@@ -42650,7 +42700,7 @@ function isRecursive(inst, stack, resolve2) {
|
|
|
42650
42700
|
break;
|
|
42651
42701
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
42652
42702
|
case "lazy": {
|
|
42653
|
-
const inner = def._cachedInner ?? (
|
|
42703
|
+
const inner = def._cachedInner ?? (resolve4 ? inst._zod.innerType : void 0);
|
|
42654
42704
|
merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
|
|
42655
42705
|
break;
|
|
42656
42706
|
}
|
|
@@ -58466,6 +58516,7 @@ var init_response = __esm({
|
|
|
58466
58516
|
var init_confirmation = __esm({
|
|
58467
58517
|
"node_modules/@chrischall/mcp-utils/dist/server/confirmation.js"() {
|
|
58468
58518
|
init_dist();
|
|
58519
|
+
init_caller();
|
|
58469
58520
|
init_response();
|
|
58470
58521
|
}
|
|
58471
58522
|
});
|
|
@@ -58479,17 +58530,73 @@ Hint: ${err.hint}`);
|
|
|
58479
58530
|
}
|
|
58480
58531
|
throw err;
|
|
58481
58532
|
}
|
|
58533
|
+
function mcpRequestFrom(args) {
|
|
58534
|
+
const ctx = args.at(-1);
|
|
58535
|
+
if (typeof ctx !== "object" || ctx === null)
|
|
58536
|
+
return void 0;
|
|
58537
|
+
const req = ctx.mcpReq;
|
|
58538
|
+
if (typeof req !== "object" || req === null)
|
|
58539
|
+
return void 0;
|
|
58540
|
+
return typeof req.notify === "function" ? req : void 0;
|
|
58541
|
+
}
|
|
58542
|
+
function callSignalFrom(args) {
|
|
58543
|
+
const ctx = args.at(-1);
|
|
58544
|
+
if (typeof ctx !== "object" || ctx === null)
|
|
58545
|
+
return void 0;
|
|
58546
|
+
const req = ctx.mcpReq;
|
|
58547
|
+
if (typeof req !== "object" || req === null)
|
|
58548
|
+
return void 0;
|
|
58549
|
+
const signal = req.signal;
|
|
58550
|
+
return signal instanceof AbortSignal ? signal : void 0;
|
|
58551
|
+
}
|
|
58552
|
+
function declaredCapabilitiesFrom(server) {
|
|
58553
|
+
const inner = server.server;
|
|
58554
|
+
if (typeof inner !== "object" || inner === null)
|
|
58555
|
+
return void 0;
|
|
58556
|
+
const read = inner.getClientCapabilities;
|
|
58557
|
+
if (typeof read !== "function")
|
|
58558
|
+
return void 0;
|
|
58559
|
+
try {
|
|
58560
|
+
const declared = read.call(inner);
|
|
58561
|
+
return typeof declared === "object" && declared !== null ? declared : void 0;
|
|
58562
|
+
} catch {
|
|
58563
|
+
return void 0;
|
|
58564
|
+
}
|
|
58565
|
+
}
|
|
58482
58566
|
function surfaceToolHints(server) {
|
|
58483
58567
|
const register2 = server.registerTool.bind(server);
|
|
58484
|
-
server.registerTool = (name, config2, cb) => register2(name, config2, (...args) =>
|
|
58485
|
-
|
|
58486
|
-
|
|
58487
|
-
|
|
58488
|
-
|
|
58489
|
-
|
|
58490
|
-
|
|
58491
|
-
|
|
58492
|
-
|
|
58568
|
+
server.registerTool = (name, config2, cb) => register2(name, config2, (...args) => (
|
|
58569
|
+
// THE CALLER'S CANCELLATION, made ambient for the whole handler
|
|
58570
|
+
// (`cancel/index.ts`). The SDK delivers it and the fleet ignored it:
|
|
58571
|
+
// measured against @modelcontextprotocol/server 2.0.0, a cancelled
|
|
58572
|
+
// call aborts `ctx.mcpReq.signal` with the caller's reason and the
|
|
58573
|
+
// handler runs to completion regardless — so the HTTP request stays
|
|
58574
|
+
// in flight, the child keeps burning metered CPU, and the upstream
|
|
58575
|
+
// keeps being hit for somebody who has gone. claude.ai sent 101
|
|
58576
|
+
// cancellations in the week to 2026-09-20.
|
|
58577
|
+
//
|
|
58578
|
+
// Here because this is the one wrapper every tool already passes
|
|
58579
|
+
// through: threading the signal by hand would mean editing several
|
|
58580
|
+
// hundred handlers and missing exactly the ones nobody edits.
|
|
58581
|
+
withCallSignal(callSignalFrom(args), () => (
|
|
58582
|
+
// WHAT THE CALLER CAN DO, made ambient for the same reason and in
|
|
58583
|
+
// the same place (`caller/index.ts`). Only the 2025-era half needs
|
|
58584
|
+
// the wrapper — a 2026-07-28 request answers for itself off its own
|
|
58585
|
+
// envelope — but a guarded tool that cannot tell whether the caller
|
|
58586
|
+
// can be shown a prompt returns one the SDK then refuses to deliver,
|
|
58587
|
+
// and that refusal reaches the caller as an unexplained protocol
|
|
58588
|
+
// error it had no chance to catch.
|
|
58589
|
+
withCallerCapabilities(declaredCapabilitiesFrom(server), () => {
|
|
58590
|
+
let result;
|
|
58591
|
+
try {
|
|
58592
|
+
result = cb(...args);
|
|
58593
|
+
} catch (err) {
|
|
58594
|
+
return hintResultOrRethrow(err);
|
|
58595
|
+
}
|
|
58596
|
+
return result instanceof Promise ? result.catch(hintResultOrRethrow) : result;
|
|
58597
|
+
})
|
|
58598
|
+
), mcpRequestFrom(args))
|
|
58599
|
+
));
|
|
58493
58600
|
}
|
|
58494
58601
|
async function createMcpServer(opts) {
|
|
58495
58602
|
const server = new McpServer({ name: opts.name, version: opts.version }, { supportedProtocolVersions: [...SERVER_PROTOCOL_VERSIONS] });
|
|
@@ -58506,11 +58613,43 @@ async function createMcpServer(opts) {
|
|
|
58506
58613
|
}
|
|
58507
58614
|
function withGracefulShutdown(target, opts = {}) {
|
|
58508
58615
|
const shouldExit = opts.exit ?? true;
|
|
58616
|
+
if (opts.timeoutMs !== void 0 && !(Number.isFinite(opts.timeoutMs) && opts.timeoutMs > 0)) {
|
|
58617
|
+
throw new RangeError("withGracefulShutdown: timeoutMs must be a finite number greater than 0.");
|
|
58618
|
+
}
|
|
58619
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS;
|
|
58620
|
+
if (opts.repeatSignalGraceMs !== void 0 && !(Number.isFinite(opts.repeatSignalGraceMs) && opts.repeatSignalGraceMs >= 0)) {
|
|
58621
|
+
throw new RangeError("withGracefulShutdown: repeatSignalGraceMs must be a finite number >= 0.");
|
|
58622
|
+
}
|
|
58623
|
+
const repeatGraceMs = opts.repeatSignalGraceMs ?? DEFAULT_REPEAT_SIGNAL_GRACE_MS;
|
|
58509
58624
|
let shuttingDown = false;
|
|
58625
|
+
let firstSignalAt = 0;
|
|
58626
|
+
let exited = false;
|
|
58627
|
+
const exitOnce = () => {
|
|
58628
|
+
if (exited)
|
|
58629
|
+
return;
|
|
58630
|
+
exited = true;
|
|
58631
|
+
process.exit(0);
|
|
58632
|
+
};
|
|
58510
58633
|
const handler = (signal) => {
|
|
58511
|
-
if (shuttingDown)
|
|
58634
|
+
if (shuttingDown) {
|
|
58635
|
+
if (Date.now() - firstSignalAt < repeatGraceMs)
|
|
58636
|
+
return;
|
|
58637
|
+
if (shouldExit) {
|
|
58638
|
+
console.error(`[mcp-utils] second ${signal} during shutdown \u2014 exiting now`);
|
|
58639
|
+
exitOnce();
|
|
58640
|
+
}
|
|
58512
58641
|
return;
|
|
58642
|
+
}
|
|
58513
58643
|
shuttingDown = true;
|
|
58644
|
+
firstSignalAt = Date.now();
|
|
58645
|
+
let timer;
|
|
58646
|
+
if (shouldExit) {
|
|
58647
|
+
timer = setTimeout(() => {
|
|
58648
|
+
console.error(`[mcp-utils] graceful shutdown on ${signal} did not finish in ${timeoutMs}ms \u2014 exiting`);
|
|
58649
|
+
exitOnce();
|
|
58650
|
+
}, timeoutMs);
|
|
58651
|
+
timer.unref?.();
|
|
58652
|
+
}
|
|
58514
58653
|
void (async () => {
|
|
58515
58654
|
try {
|
|
58516
58655
|
if (opts.onSignal)
|
|
@@ -58519,8 +58658,10 @@ function withGracefulShutdown(target, opts = {}) {
|
|
|
58519
58658
|
} catch (err) {
|
|
58520
58659
|
console.error(`[mcp-utils] error during graceful shutdown on ${signal}: ${err instanceof Error ? err.message : String(err)}`);
|
|
58521
58660
|
} finally {
|
|
58661
|
+
if (timer !== void 0)
|
|
58662
|
+
clearTimeout(timer);
|
|
58522
58663
|
if (shouldExit)
|
|
58523
|
-
|
|
58664
|
+
exitOnce();
|
|
58524
58665
|
}
|
|
58525
58666
|
})();
|
|
58526
58667
|
};
|
|
@@ -58548,7 +58689,7 @@ function runMcp(opts) {
|
|
|
58548
58689
|
}
|
|
58549
58690
|
return handle;
|
|
58550
58691
|
}
|
|
58551
|
-
var SERVER_PROTOCOL_VERSIONS;
|
|
58692
|
+
var SERVER_PROTOCOL_VERSIONS, DEFAULT_SHUTDOWN_TIMEOUT_MS, DEFAULT_REPEAT_SIGNAL_GRACE_MS;
|
|
58552
58693
|
var init_server = __esm({
|
|
58553
58694
|
"node_modules/@chrischall/mcp-utils/dist/server/index.js"() {
|
|
58554
58695
|
init_stdio();
|
|
@@ -58556,14 +58697,20 @@ var init_server = __esm({
|
|
|
58556
58697
|
init_errors();
|
|
58557
58698
|
init_response();
|
|
58558
58699
|
init_confirmation();
|
|
58700
|
+
init_cancel();
|
|
58701
|
+
init_caller();
|
|
58559
58702
|
SERVER_PROTOCOL_VERSIONS = Object.freeze([
|
|
58560
58703
|
"2026-07-28",
|
|
58561
58704
|
...SUPPORTED_PROTOCOL_VERSIONS
|
|
58562
58705
|
]);
|
|
58706
|
+
DEFAULT_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
58707
|
+
DEFAULT_REPEAT_SIGNAL_GRACE_MS = 500;
|
|
58563
58708
|
}
|
|
58564
58709
|
});
|
|
58565
58710
|
|
|
58566
58711
|
// node_modules/@chrischall/mcp-utils/dist/config/index.js
|
|
58712
|
+
import { homedir } from "node:os";
|
|
58713
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
58567
58714
|
function readEnvVar(key, opts = {}) {
|
|
58568
58715
|
const env = opts.env ?? process.env;
|
|
58569
58716
|
const raw = env[key];
|
|
@@ -58575,6 +58722,15 @@ function readEnvVar(key, opts = {}) {
|
|
|
58575
58722
|
}
|
|
58576
58723
|
return opts.default;
|
|
58577
58724
|
}
|
|
58725
|
+
function expandPath(p) {
|
|
58726
|
+
let expanded = p;
|
|
58727
|
+
if (p === "~") {
|
|
58728
|
+
expanded = homedir();
|
|
58729
|
+
} else if (p.startsWith("~/")) {
|
|
58730
|
+
expanded = join(homedir(), p.slice(2));
|
|
58731
|
+
}
|
|
58732
|
+
return isAbsolute(expanded) ? expanded : resolve(expanded);
|
|
58733
|
+
}
|
|
58578
58734
|
async function loadDotenvSafely(opts = {}) {
|
|
58579
58735
|
try {
|
|
58580
58736
|
const mod = await import(
|
|
@@ -58598,19 +58754,61 @@ var init_config = __esm({
|
|
|
58598
58754
|
}
|
|
58599
58755
|
});
|
|
58600
58756
|
|
|
58757
|
+
// node_modules/@chrischall/mcp-utils/dist/fs/confine.js
|
|
58758
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
58759
|
+
import { dirname, isAbsolute as isAbsolute2, relative, resolve as resolve2, sep } from "node:path";
|
|
58760
|
+
function isInside(root, target) {
|
|
58761
|
+
const rel = relative(root, target);
|
|
58762
|
+
return rel === "" || !rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute2(rel);
|
|
58763
|
+
}
|
|
58764
|
+
function realPathAllowingMissing(p) {
|
|
58765
|
+
const abs = resolve2(p);
|
|
58766
|
+
let existing = abs;
|
|
58767
|
+
const tail = [];
|
|
58768
|
+
while (!existsSync(existing)) {
|
|
58769
|
+
const parent = dirname(existing);
|
|
58770
|
+
if (parent === existing)
|
|
58771
|
+
break;
|
|
58772
|
+
tail.unshift(existing.slice(parent.length).replace(/^[/\\]+/, ""));
|
|
58773
|
+
existing = parent;
|
|
58774
|
+
}
|
|
58775
|
+
let real;
|
|
58776
|
+
try {
|
|
58777
|
+
real = realpathSync(existing);
|
|
58778
|
+
} catch {
|
|
58779
|
+
real = existing;
|
|
58780
|
+
}
|
|
58781
|
+
return tail.length > 0 ? resolve2(real, ...tail) : real;
|
|
58782
|
+
}
|
|
58783
|
+
function assertPathWithinRoots(path, roots) {
|
|
58784
|
+
const target = realPathAllowingMissing(expandPath(path));
|
|
58785
|
+
for (const root of roots) {
|
|
58786
|
+
if (isInside(realPathAllowingMissing(expandPath(root)), target))
|
|
58787
|
+
return target;
|
|
58788
|
+
}
|
|
58789
|
+
throw new Error(`Path is outside the allowed directories: ${path}`);
|
|
58790
|
+
}
|
|
58791
|
+
var init_confine = __esm({
|
|
58792
|
+
"node_modules/@chrischall/mcp-utils/dist/fs/confine.js"() {
|
|
58793
|
+
init_config();
|
|
58794
|
+
}
|
|
58795
|
+
});
|
|
58796
|
+
|
|
58601
58797
|
// node_modules/@chrischall/mcp-utils/dist/fs/output.js
|
|
58602
58798
|
var init_output = __esm({
|
|
58603
58799
|
"node_modules/@chrischall/mcp-utils/dist/fs/output.js"() {
|
|
58604
58800
|
init_config();
|
|
58801
|
+
init_confine();
|
|
58605
58802
|
}
|
|
58606
58803
|
});
|
|
58607
58804
|
|
|
58608
58805
|
// node_modules/@chrischall/mcp-utils/dist/fs/index.js
|
|
58609
58806
|
import { openAsBlob } from "node:fs";
|
|
58610
58807
|
async function fileBlob(path, opts = {}) {
|
|
58808
|
+
const target = opts.allowedRoots ? assertPathWithinRoots(path, opts.allowedRoots) : path;
|
|
58611
58809
|
let blob;
|
|
58612
58810
|
try {
|
|
58613
|
-
blob = await openAsBlob(
|
|
58811
|
+
blob = await openAsBlob(target, opts.type !== void 0 ? { type: opts.type } : void 0);
|
|
58614
58812
|
} catch {
|
|
58615
58813
|
throw new Error(`Cannot read file for upload: ${path}`);
|
|
58616
58814
|
}
|
|
@@ -58621,7 +58819,9 @@ async function fileBlob(path, opts = {}) {
|
|
|
58621
58819
|
}
|
|
58622
58820
|
var init_fs = __esm({
|
|
58623
58821
|
"node_modules/@chrischall/mcp-utils/dist/fs/index.js"() {
|
|
58822
|
+
init_confine();
|
|
58624
58823
|
init_output();
|
|
58824
|
+
init_confine();
|
|
58625
58825
|
}
|
|
58626
58826
|
});
|
|
58627
58827
|
|
|
@@ -58672,23 +58872,78 @@ function createApiClient(opts) {
|
|
|
58672
58872
|
const retryStatuses = retry.statuses ?? [429];
|
|
58673
58873
|
const timeoutMs = opts.timeout;
|
|
58674
58874
|
const authHeader = (token) => !token ? {} : opts.tokenHeader ? { [opts.tokenHeader]: token } : { Authorization: `Bearer ${token}` };
|
|
58675
|
-
function withTimeout(run) {
|
|
58676
|
-
if (timeoutMs == null || timeoutMs <= 0)
|
|
58677
|
-
|
|
58875
|
+
async function withTimeout(run) {
|
|
58876
|
+
if (timeoutMs == null || timeoutMs <= 0) {
|
|
58877
|
+
const res2 = await run(withAmbientCancellation(void 0));
|
|
58878
|
+
return { res: res2, done: () => {
|
|
58879
|
+
}, expired: void 0 };
|
|
58880
|
+
}
|
|
58678
58881
|
const controller = new AbortController();
|
|
58679
58882
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
58680
|
-
|
|
58681
|
-
|
|
58883
|
+
let res;
|
|
58884
|
+
try {
|
|
58885
|
+
res = await run(withAmbientCancellation(controller.signal));
|
|
58886
|
+
} catch (err) {
|
|
58887
|
+
clearTimeout(timer);
|
|
58888
|
+
if (err instanceof Error && err.name === "AbortError" && controller.signal.aborted) {
|
|
58682
58889
|
throw new RequestTimeoutError(service, timeoutMs);
|
|
58890
|
+
}
|
|
58683
58891
|
throw err;
|
|
58684
|
-
}
|
|
58892
|
+
}
|
|
58893
|
+
const expired = new Promise((_resolve, reject) => {
|
|
58894
|
+
controller.signal.addEventListener("abort", () => reject(new RequestTimeoutError(service, timeoutMs)), {
|
|
58895
|
+
once: true
|
|
58896
|
+
});
|
|
58897
|
+
});
|
|
58898
|
+
expired.catch(() => {
|
|
58899
|
+
});
|
|
58900
|
+
return { res, done: () => clearTimeout(timer), expired };
|
|
58901
|
+
}
|
|
58902
|
+
async function readBody(attempt, read) {
|
|
58903
|
+
try {
|
|
58904
|
+
if (!attempt.expired)
|
|
58905
|
+
return await read(attempt.res);
|
|
58906
|
+
return await Promise.race([read(attempt.res), attempt.expired]);
|
|
58907
|
+
} catch (err) {
|
|
58908
|
+
if (err instanceof RequestTimeoutError) {
|
|
58909
|
+
attempt.res.body?.cancel().catch(() => {
|
|
58910
|
+
});
|
|
58911
|
+
}
|
|
58912
|
+
throw err;
|
|
58913
|
+
} finally {
|
|
58914
|
+
attempt.done();
|
|
58915
|
+
}
|
|
58916
|
+
}
|
|
58917
|
+
const baseParts = (() => {
|
|
58918
|
+
try {
|
|
58919
|
+
const u = new URL(base);
|
|
58920
|
+
return { origin: u.origin, username: u.username, password: u.password };
|
|
58921
|
+
} catch {
|
|
58922
|
+
return void 0;
|
|
58923
|
+
}
|
|
58924
|
+
})();
|
|
58925
|
+
const baseOrigin = baseParts?.origin;
|
|
58926
|
+
function resolveUrl2(path, query) {
|
|
58927
|
+
const url4 = `${base}${path}${query}`;
|
|
58928
|
+
if (baseOrigin === void 0)
|
|
58929
|
+
return url4;
|
|
58930
|
+
let parsed;
|
|
58931
|
+
try {
|
|
58932
|
+
parsed = new URL(url4);
|
|
58933
|
+
} catch {
|
|
58934
|
+
throw new Error(`Refusing request to ${service}: path ${JSON.stringify(path)} does not form a valid URL.`);
|
|
58935
|
+
}
|
|
58936
|
+
if (parsed.origin !== baseOrigin || parsed.username !== baseParts?.username || parsed.password !== baseParts?.password) {
|
|
58937
|
+
throw new Error(`Refusing request to ${service}: path ${JSON.stringify(path)} resolves outside the base origin ${baseOrigin}. Paths must be relative to baseUrl (start them with "/").`);
|
|
58938
|
+
}
|
|
58939
|
+
return url4;
|
|
58685
58940
|
}
|
|
58686
58941
|
async function send(method, path, opt) {
|
|
58687
58942
|
const isMultipart = opt.formData !== void 0;
|
|
58688
58943
|
const hasJsonBody = !isMultipart && opt.body !== void 0;
|
|
58689
58944
|
const reqBody = isMultipart ? opt.formData : hasJsonBody ? JSON.stringify(opt.body) : void 0;
|
|
58690
58945
|
const query = opt.query ? buildQueryString(opt.query) : "";
|
|
58691
|
-
const url4 =
|
|
58946
|
+
const url4 = resolveUrl2(path, query);
|
|
58692
58947
|
const bodyInit = reqBody !== void 0 ? { body: reqBody } : {};
|
|
58693
58948
|
const fetchWith = (token, signal) => doFetch(url4, {
|
|
58694
58949
|
method,
|
|
@@ -58705,8 +58960,10 @@ function createApiClient(opts) {
|
|
|
58705
58960
|
const once = () => withTimeout((signal) => opts.tokenManager ? opts.tokenManager.withAuth((token) => fetchWith(token, signal)) : (async () => fetchWith(await opts.getToken?.() || void 0, signal))());
|
|
58706
58961
|
let attempt = 0;
|
|
58707
58962
|
for (; ; ) {
|
|
58708
|
-
const
|
|
58963
|
+
const current = await once();
|
|
58964
|
+
const res = current.res;
|
|
58709
58965
|
if (retryStatuses.includes(res.status) && attempt < retry.count) {
|
|
58966
|
+
current.done();
|
|
58710
58967
|
attempt += 1;
|
|
58711
58968
|
const delay = retry.honorRetryAfter ? parseRetryAfterMs(res.headers.get("retry-after"), {
|
|
58712
58969
|
defaultMs: retry.delayMs,
|
|
@@ -58715,18 +58972,21 @@ function createApiClient(opts) {
|
|
|
58715
58972
|
await sleep2(delay);
|
|
58716
58973
|
continue;
|
|
58717
58974
|
}
|
|
58718
|
-
return
|
|
58975
|
+
return current;
|
|
58719
58976
|
}
|
|
58720
58977
|
}
|
|
58721
58978
|
async function fetchJson(method, path, opt = {}) {
|
|
58722
|
-
const
|
|
58979
|
+
const attempt = await send(method, path, opt);
|
|
58980
|
+
const res = attempt.res;
|
|
58981
|
+
if (res.status === 401 || res.status === 429 || res.status === 204)
|
|
58982
|
+
attempt.done();
|
|
58723
58983
|
if (res.status === 401)
|
|
58724
58984
|
throw unauthorized();
|
|
58725
58985
|
if (res.status === 429)
|
|
58726
58986
|
throw rateLimited();
|
|
58727
58987
|
if (res.status === 204)
|
|
58728
58988
|
return void 0;
|
|
58729
|
-
const text = await
|
|
58989
|
+
const text = await readBody(attempt, (r) => r.text());
|
|
58730
58990
|
if (!res.ok) {
|
|
58731
58991
|
throw new ApiError(res.status, formatApiError(res.status, method, path, text, { service }));
|
|
58732
58992
|
}
|
|
@@ -58736,12 +58996,15 @@ function createApiClient(opts) {
|
|
|
58736
58996
|
}
|
|
58737
58997
|
async function fetchHtml(method, path, opt = {}) {
|
|
58738
58998
|
const headers = { Accept: "text/html,*/*", ...opt.headers };
|
|
58739
|
-
const
|
|
58999
|
+
const attempt = await send(method, path, { ...opt, headers });
|
|
59000
|
+
const res = attempt.res;
|
|
59001
|
+
if (res.status === 401 || res.status === 429)
|
|
59002
|
+
attempt.done();
|
|
58740
59003
|
if (res.status === 401)
|
|
58741
59004
|
throw unauthorized();
|
|
58742
59005
|
if (res.status === 429)
|
|
58743
59006
|
throw rateLimited();
|
|
58744
|
-
const text = await
|
|
59007
|
+
const text = await readBody(attempt, (r) => r.text());
|
|
58745
59008
|
if (!res.ok) {
|
|
58746
59009
|
throw new ApiError(res.status, formatApiError(res.status, method, path, text, { service }));
|
|
58747
59010
|
}
|
|
@@ -58749,16 +59012,23 @@ function createApiClient(opts) {
|
|
|
58749
59012
|
}
|
|
58750
59013
|
async function fetchRaw(method, path, opt = {}) {
|
|
58751
59014
|
const headers = { Accept: "*/*", ...opt.headers };
|
|
58752
|
-
const
|
|
59015
|
+
const attempt = await send(method, path, { ...opt, headers });
|
|
59016
|
+
const res = attempt.res;
|
|
59017
|
+
if (res.status === 401 || res.status === 429)
|
|
59018
|
+
attempt.done();
|
|
58753
59019
|
if (res.status === 401)
|
|
58754
59020
|
throw unauthorized();
|
|
58755
59021
|
if (res.status === 429)
|
|
58756
59022
|
throw rateLimited();
|
|
58757
59023
|
if (!res.ok) {
|
|
58758
|
-
const text = await
|
|
59024
|
+
const text = await readBody(attempt, (r) => r.text()).catch((err) => {
|
|
59025
|
+
if (err instanceof RequestTimeoutError)
|
|
59026
|
+
throw err;
|
|
59027
|
+
return "";
|
|
59028
|
+
});
|
|
58759
59029
|
throw new ApiError(res.status, formatApiError(res.status, method, path, text, { service }));
|
|
58760
59030
|
}
|
|
58761
|
-
const bytes = new Uint8Array(await
|
|
59031
|
+
const bytes = new Uint8Array(await readBody(attempt, (r) => r.arrayBuffer()));
|
|
58762
59032
|
return {
|
|
58763
59033
|
status: res.status,
|
|
58764
59034
|
contentType: res.headers.get("content-type"),
|
|
@@ -58794,6 +59064,7 @@ function formatApiError(status, method, path, errorText, opts = {}) {
|
|
|
58794
59064
|
var DEFAULT_RETRY, defaultSleep, UnauthorizedError, RateLimitedError, RequestTimeoutError, ApiError;
|
|
58795
59065
|
var init_http = __esm({
|
|
58796
59066
|
"node_modules/@chrischall/mcp-utils/dist/http/index.js"() {
|
|
59067
|
+
init_cancel();
|
|
58797
59068
|
init_errors();
|
|
58798
59069
|
init_throttle();
|
|
58799
59070
|
init_response_cache();
|
|
@@ -58866,10 +59137,14 @@ var init_parse_lenient = __esm({
|
|
|
58866
59137
|
|
|
58867
59138
|
// node_modules/@chrischall/mcp-utils/dist/zod/index.js
|
|
58868
59139
|
function toolAnnotations(opts = {}) {
|
|
59140
|
+
if (opts.readOnly === true && opts.destructive === true) {
|
|
59141
|
+
throw new Error("toolAnnotations: readOnly: true contradicts destructive: true \u2014 a destructive tool is not read-only.");
|
|
59142
|
+
}
|
|
58869
59143
|
return {
|
|
58870
59144
|
...opts.title !== void 0 ? { title: opts.title } : {},
|
|
58871
|
-
readOnlyHint: opts.readOnly ??
|
|
59145
|
+
readOnlyHint: opts.readOnly ?? opts.destructive === void 0,
|
|
58872
59146
|
...opts.idempotent !== void 0 ? { idempotentHint: opts.idempotent } : {},
|
|
59147
|
+
...opts.destructive !== void 0 ? { destructiveHint: opts.destructive } : {},
|
|
58873
59148
|
...opts.openWorld !== void 0 ? { openWorldHint: opts.openWorld } : {}
|
|
58874
59149
|
};
|
|
58875
59150
|
}
|
|
@@ -58921,15 +59196,24 @@ var init_auth = __esm({
|
|
|
58921
59196
|
}
|
|
58922
59197
|
});
|
|
58923
59198
|
|
|
59199
|
+
// node_modules/@chrischall/mcp-utils/dist/internal/ascii.js
|
|
59200
|
+
var init_ascii = __esm({
|
|
59201
|
+
"node_modules/@chrischall/mcp-utils/dist/internal/ascii.js"() {
|
|
59202
|
+
}
|
|
59203
|
+
});
|
|
59204
|
+
|
|
58924
59205
|
// node_modules/@chrischall/mcp-utils/dist/scrape/index.js
|
|
58925
59206
|
var init_scrape = __esm({
|
|
58926
59207
|
"node_modules/@chrischall/mcp-utils/dist/scrape/index.js"() {
|
|
59208
|
+
init_ascii();
|
|
58927
59209
|
}
|
|
58928
59210
|
});
|
|
58929
59211
|
|
|
58930
59212
|
// node_modules/@chrischall/mcp-utils/dist/index.js
|
|
58931
59213
|
var init_dist2 = __esm({
|
|
58932
59214
|
"node_modules/@chrischall/mcp-utils/dist/index.js"() {
|
|
59215
|
+
init_cancel();
|
|
59216
|
+
init_caller();
|
|
58933
59217
|
init_server();
|
|
58934
59218
|
init_response();
|
|
58935
59219
|
init_errors();
|
|
@@ -58949,6 +59233,7 @@ var images_exports = {};
|
|
|
58949
59233
|
__export(images_exports, {
|
|
58950
59234
|
baseName: () => baseName,
|
|
58951
59235
|
decodeImageInput: () => decodeImageInput,
|
|
59236
|
+
detectUploadMime: () => detectUploadMime,
|
|
58952
59237
|
mediaExt: () => mediaExt,
|
|
58953
59238
|
previewImageInput: () => previewImageInput,
|
|
58954
59239
|
previewVideoInput: () => previewVideoInput,
|
|
@@ -58964,8 +59249,8 @@ __export(images_exports, {
|
|
|
58964
59249
|
writeSidecar: () => writeSidecar
|
|
58965
59250
|
});
|
|
58966
59251
|
import { mkdir, readFile, writeFile, access, stat, open as open2 } from "node:fs/promises";
|
|
58967
|
-
import { existsSync } from "node:fs";
|
|
58968
|
-
import { join as
|
|
59252
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
59253
|
+
import { join as join3, resolve as resolve3, isAbsolute as isAbsolute3 } from "node:path";
|
|
58969
59254
|
function slugify2(text, max = 40) {
|
|
58970
59255
|
const s = text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, max).replace(/-+$/g, "");
|
|
58971
59256
|
return s || "image";
|
|
@@ -58979,15 +59264,18 @@ async function exists(p) {
|
|
|
58979
59264
|
}
|
|
58980
59265
|
}
|
|
58981
59266
|
async function uniquePath(dir, base, ext) {
|
|
58982
|
-
let candidate =
|
|
59267
|
+
let candidate = join3(dir, `${base}.${ext}`);
|
|
58983
59268
|
let n = 2;
|
|
58984
59269
|
while (await exists(candidate)) {
|
|
58985
|
-
candidate =
|
|
59270
|
+
candidate = join3(dir, `${base}-${n}.${ext}`);
|
|
58986
59271
|
n++;
|
|
58987
59272
|
}
|
|
58988
59273
|
return candidate;
|
|
58989
59274
|
}
|
|
58990
59275
|
function sniffMimeBytes(buf) {
|
|
59276
|
+
return sniffImageMime(buf) ?? "image/png";
|
|
59277
|
+
}
|
|
59278
|
+
function sniffImageMime(buf) {
|
|
58991
59279
|
if (buf.length >= 4 && buf[0] === 137 && buf[1] === 80 && buf[2] === 78 && buf[3] === 71) {
|
|
58992
59280
|
return "image/png";
|
|
58993
59281
|
}
|
|
@@ -58997,7 +59285,7 @@ function sniffMimeBytes(buf) {
|
|
|
58997
59285
|
if (buf.length >= 12 && buf[0] === 82 && buf[1] === 73 && buf[2] === 70 && buf[3] === 70 && buf[8] === 87 && buf[9] === 69 && buf[10] === 66 && buf[11] === 80) {
|
|
58998
59286
|
return "image/webp";
|
|
58999
59287
|
}
|
|
59000
|
-
return
|
|
59288
|
+
return void 0;
|
|
59001
59289
|
}
|
|
59002
59290
|
function mediaExt(mimeType) {
|
|
59003
59291
|
const m = mimeType.toLowerCase();
|
|
@@ -59016,7 +59304,7 @@ async function writeMedia(dir, base, base643, mimeType) {
|
|
|
59016
59304
|
await mkdir(dir, { recursive: true });
|
|
59017
59305
|
const path = await uniquePath(dir, base, mediaExt(mimeType));
|
|
59018
59306
|
await writeFile(path, Buffer.from(base643, "base64"));
|
|
59019
|
-
return
|
|
59307
|
+
return resolve3(path);
|
|
59020
59308
|
}
|
|
59021
59309
|
async function writeImage(dir, base, base643, mimeType) {
|
|
59022
59310
|
return writeMedia(dir, base, base643, mimeType);
|
|
@@ -59025,14 +59313,14 @@ async function writeSidecar(imagePath, data) {
|
|
|
59025
59313
|
await writeFile(`${imagePath}.json`, JSON.stringify(data, null, 2));
|
|
59026
59314
|
}
|
|
59027
59315
|
function resolveInputPath(p, kind) {
|
|
59028
|
-
if (
|
|
59316
|
+
if (isAbsolute3(p) && existsSync2(p)) return p;
|
|
59029
59317
|
const inputDir = readEnvVar("GEMINI_INPUT_DIR");
|
|
59030
59318
|
if (inputDir) {
|
|
59031
|
-
const candidate =
|
|
59032
|
-
if (
|
|
59319
|
+
const candidate = join3(inputDir, p);
|
|
59320
|
+
if (existsSync2(candidate)) return resolve3(candidate);
|
|
59033
59321
|
}
|
|
59034
|
-
const cwd =
|
|
59035
|
-
if (
|
|
59322
|
+
const cwd = resolve3(p);
|
|
59323
|
+
if (existsSync2(cwd)) return cwd;
|
|
59036
59324
|
const hint = `Set GEMINI_INPUT_DIR to a directory containing your ${kind.toLowerCase()}s, or pass an absolute path.`;
|
|
59037
59325
|
throw new McpToolError(
|
|
59038
59326
|
`${kind} not found: ${p}` + (inputDir ? ` (also searched GEMINI_INPUT_DIR=${inputDir})` : ""),
|
|
@@ -59072,6 +59360,22 @@ async function previewVideoInput(path) {
|
|
|
59072
59360
|
const { size } = await stat(resolved);
|
|
59073
59361
|
return { path: resolved, mimeType: videoMimeType(resolved), size };
|
|
59074
59362
|
}
|
|
59363
|
+
async function readHead(path, n = 16) {
|
|
59364
|
+
const fh = await open2(path, "r");
|
|
59365
|
+
try {
|
|
59366
|
+
const head = Buffer.alloc(n);
|
|
59367
|
+
const { bytesRead } = await fh.read(head, 0, n, 0);
|
|
59368
|
+
return head.subarray(0, bytesRead);
|
|
59369
|
+
} finally {
|
|
59370
|
+
await fh.close();
|
|
59371
|
+
}
|
|
59372
|
+
}
|
|
59373
|
+
async function detectUploadMime(resolvedPath) {
|
|
59374
|
+
const sniffed = sniffImageMime(await readHead(resolvedPath));
|
|
59375
|
+
if (sniffed) return sniffed;
|
|
59376
|
+
const ext = resolvedPath.includes(".") ? resolvedPath.slice(resolvedPath.lastIndexOf(".") + 1).toLowerCase() : "";
|
|
59377
|
+
return UPLOAD_MIME_BY_EXT[ext];
|
|
59378
|
+
}
|
|
59075
59379
|
async function readImageAsInline(path) {
|
|
59076
59380
|
const resolved = resolveImagePath(path);
|
|
59077
59381
|
const buf = await readFile(resolved);
|
|
@@ -59099,7 +59403,7 @@ function baseName(name) {
|
|
|
59099
59403
|
function resolveOutputDir(perCall) {
|
|
59100
59404
|
return perCall?.trim() || readEnvVar("GEMINI_OUTPUT_DIR") || process.cwd();
|
|
59101
59405
|
}
|
|
59102
|
-
var VIDEO_MIME_BY_EXT;
|
|
59406
|
+
var VIDEO_MIME_BY_EXT, UPLOAD_MIME_BY_EXT;
|
|
59103
59407
|
var init_images = __esm({
|
|
59104
59408
|
"src/images.ts"() {
|
|
59105
59409
|
"use strict";
|
|
@@ -59116,6 +59420,23 @@ var init_images = __esm({
|
|
|
59116
59420
|
"3gp": "video/3gpp",
|
|
59117
59421
|
"3gpp": "video/3gpp"
|
|
59118
59422
|
};
|
|
59423
|
+
UPLOAD_MIME_BY_EXT = {
|
|
59424
|
+
png: "image/png",
|
|
59425
|
+
jpg: "image/jpeg",
|
|
59426
|
+
jpeg: "image/jpeg",
|
|
59427
|
+
webp: "image/webp",
|
|
59428
|
+
gif: "image/gif",
|
|
59429
|
+
heic: "image/heic",
|
|
59430
|
+
heif: "image/heif",
|
|
59431
|
+
wav: "audio/wav",
|
|
59432
|
+
mp3: "audio/mp3",
|
|
59433
|
+
aiff: "audio/aiff",
|
|
59434
|
+
aif: "audio/aiff",
|
|
59435
|
+
aac: "audio/aac",
|
|
59436
|
+
ogg: "audio/ogg",
|
|
59437
|
+
flac: "audio/flac",
|
|
59438
|
+
...VIDEO_MIME_BY_EXT
|
|
59439
|
+
};
|
|
59119
59440
|
}
|
|
59120
59441
|
});
|
|
59121
59442
|
|
|
@@ -59128,7 +59449,7 @@ import { execFile } from "node:child_process";
|
|
|
59128
59449
|
import { promisify } from "node:util";
|
|
59129
59450
|
import { readFile as readFile2, unlink } from "node:fs/promises";
|
|
59130
59451
|
import { tmpdir } from "node:os";
|
|
59131
|
-
import { join as
|
|
59452
|
+
import { join as join4 } from "node:path";
|
|
59132
59453
|
async function readClipboardImage(run = defaultRun) {
|
|
59133
59454
|
if (process.platform !== "darwin") {
|
|
59134
59455
|
throw new McpToolError("from_clipboard is only supported on macOS", {
|
|
@@ -59136,8 +59457,8 @@ async function readClipboardImage(run = defaultRun) {
|
|
|
59136
59457
|
});
|
|
59137
59458
|
}
|
|
59138
59459
|
const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
59139
|
-
const png =
|
|
59140
|
-
const jpg =
|
|
59460
|
+
const png = join4(tmpdir(), `gemini-clip-${id}.png`);
|
|
59461
|
+
const jpg = join4(tmpdir(), `gemini-clip-${id}.jpg`);
|
|
59141
59462
|
try {
|
|
59142
59463
|
try {
|
|
59143
59464
|
await run("osascript", [
|
|
@@ -59184,15 +59505,15 @@ init_dist2();
|
|
|
59184
59505
|
|
|
59185
59506
|
// src/dotenv.ts
|
|
59186
59507
|
init_dist2();
|
|
59187
|
-
import { dirname, join } from "node:path";
|
|
59508
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
59188
59509
|
import { fileURLToPath } from "node:url";
|
|
59189
59510
|
async function loadStdioDotenv() {
|
|
59190
|
-
const here =
|
|
59191
|
-
await loadDotenvSafely({ path:
|
|
59511
|
+
const here = dirname2(fileURLToPath(import.meta.url));
|
|
59512
|
+
await loadDotenvSafely({ path: join2(here, "..", ".env"), override: false });
|
|
59192
59513
|
}
|
|
59193
59514
|
|
|
59194
59515
|
// src/version.ts
|
|
59195
|
-
var VERSION = "2.1.
|
|
59516
|
+
var VERSION = "2.1.4";
|
|
59196
59517
|
|
|
59197
59518
|
// src/errors.ts
|
|
59198
59519
|
init_dist2();
|
|
@@ -59803,11 +60124,11 @@ async function resolveImageInputs(args, client2) {
|
|
|
59803
60124
|
async function resolveLocalPath(path, client2, onDisk, report) {
|
|
59804
60125
|
const { readImageAsInline: readImageAsInline2, resolveImagePath: resolveImagePath2 } = await Promise.resolve().then(() => (init_images(), images_exports));
|
|
59805
60126
|
if (!onDisk) return readImageAsInline2(path);
|
|
59806
|
-
const { stat:
|
|
60127
|
+
const { stat: stat4 } = await import("node:fs/promises");
|
|
59807
60128
|
const resolved = resolveImagePath2(path);
|
|
59808
60129
|
let key;
|
|
59809
60130
|
try {
|
|
59810
|
-
const { mtimeMs, size } = await
|
|
60131
|
+
const { mtimeMs, size } = await stat4(resolved);
|
|
59811
60132
|
key = `path\0${resolved}\0${mtimeMs}\0${size}`;
|
|
59812
60133
|
} catch {
|
|
59813
60134
|
return readImageAsInline2(path);
|
|
@@ -59910,6 +60231,61 @@ function signedLinks(baseUrl) {
|
|
|
59910
60231
|
};
|
|
59911
60232
|
}
|
|
59912
60233
|
|
|
60234
|
+
// src/tenant.ts
|
|
60235
|
+
var TENANT_PIN_KEY = "lib/tenant.json";
|
|
60236
|
+
var TENANT_SHAPE = /^[0-9a-f]{12}$/;
|
|
60237
|
+
async function readPin(bucket) {
|
|
60238
|
+
const object4 = await bucket.get(TENANT_PIN_KEY);
|
|
60239
|
+
if (!object4) return void 0;
|
|
60240
|
+
try {
|
|
60241
|
+
const parsed = JSON.parse(new TextDecoder().decode(await object4.arrayBuffer()));
|
|
60242
|
+
return typeof parsed.tenant === "string" && TENANT_SHAPE.test(parsed.tenant) ? parsed.tenant : void 0;
|
|
60243
|
+
} catch {
|
|
60244
|
+
return void 0;
|
|
60245
|
+
}
|
|
60246
|
+
}
|
|
60247
|
+
function pinnedTenant(bucket, derive) {
|
|
60248
|
+
let cached2;
|
|
60249
|
+
async function resolve4() {
|
|
60250
|
+
const pinned = await readPin(bucket);
|
|
60251
|
+
if (pinned) return { tenant: pinned, pinned: true };
|
|
60252
|
+
const tenant = await derive();
|
|
60253
|
+
try {
|
|
60254
|
+
await bucket.put(TENANT_PIN_KEY, JSON.stringify({ tenant }), {
|
|
60255
|
+
httpMetadata: { contentType: "application/json" }
|
|
60256
|
+
});
|
|
60257
|
+
return { tenant, pinned: true };
|
|
60258
|
+
} catch {
|
|
60259
|
+
return { tenant, pinned: false };
|
|
60260
|
+
}
|
|
60261
|
+
}
|
|
60262
|
+
return () => {
|
|
60263
|
+
if (cached2) return cached2;
|
|
60264
|
+
const attempt = resolve4().then(({ tenant, pinned }) => {
|
|
60265
|
+
if (!pinned && cached2 === attempt) cached2 = void 0;
|
|
60266
|
+
return tenant;
|
|
60267
|
+
});
|
|
60268
|
+
cached2 = attempt;
|
|
60269
|
+
attempt.catch(() => {
|
|
60270
|
+
if (cached2 === attempt) cached2 = void 0;
|
|
60271
|
+
});
|
|
60272
|
+
return attempt;
|
|
60273
|
+
};
|
|
60274
|
+
}
|
|
60275
|
+
function tenantResolver(source) {
|
|
60276
|
+
let cache;
|
|
60277
|
+
return () => {
|
|
60278
|
+
if (cache) return cache;
|
|
60279
|
+
const attempt = Promise.resolve(
|
|
60280
|
+
typeof source === "function" ? source() : source
|
|
60281
|
+
);
|
|
60282
|
+
attempt.catch(() => {
|
|
60283
|
+
if (cache === attempt) cache = void 0;
|
|
60284
|
+
});
|
|
60285
|
+
return cache = attempt;
|
|
60286
|
+
};
|
|
60287
|
+
}
|
|
60288
|
+
|
|
59913
60289
|
// src/storage/media.ts
|
|
59914
60290
|
function createDiskSink() {
|
|
59915
60291
|
return {
|
|
@@ -59967,8 +60343,7 @@ function createR2Sink(bucket, opts) {
|
|
|
59967
60343
|
const signedBase = opts.links?.base ?? opts.signedBaseUrl?.replace(/\/+$/, "");
|
|
59968
60344
|
const ttlMs = opts.urlTtlMs ?? 0;
|
|
59969
60345
|
const readPrefixes = [prefix, ...opts.readPrefixes ?? []];
|
|
59970
|
-
|
|
59971
|
-
const tenantId = () => tenantCache ??= Promise.resolve(typeof opts.tenant === "function" ? opts.tenant() : opts.tenant);
|
|
60346
|
+
const tenantId = tenantResolver(opts.tenant);
|
|
59972
60347
|
const ownPrefix = async () => {
|
|
59973
60348
|
const tenant = await tenantId();
|
|
59974
60349
|
return tenant ? `${prefix}/${tenant}/` : `${prefix}/`;
|
|
@@ -60510,8 +60885,8 @@ async function emitMedia(named, kind, opts, meta3, onWritten) {
|
|
|
60510
60885
|
...p.key ? { curl_hint: `curl -sS -o ${downloadFilename(p.key)} "${p.ref}"` } : {}
|
|
60511
60886
|
}))
|
|
60512
60887
|
} : {};
|
|
60513
|
-
const
|
|
60514
|
-
return minifiedResult({ [`${kind}s`]: refs, ...media, ...unavailable, ...note, ...
|
|
60888
|
+
const storage3 = sink.persistsFiles ? {} : { storage: sink.kind, storage_note: storageNote };
|
|
60889
|
+
return minifiedResult({ [`${kind}s`]: refs, ...media, ...unavailable, ...note, ...storage3, ...meta3 });
|
|
60515
60890
|
}
|
|
60516
60891
|
async function emit(named, opts, meta3, onWritten) {
|
|
60517
60892
|
return emitMedia(named.map((n) => ({ media: n.image, base: n.base })), "image", opts, meta3, onWritten);
|
|
@@ -60827,13 +61202,13 @@ function persistableResult(result) {
|
|
|
60827
61202
|
return { result };
|
|
60828
61203
|
}
|
|
60829
61204
|
function awaitWithBudget(promise2, waitMs) {
|
|
60830
|
-
return new Promise((
|
|
60831
|
-
const timer = setTimeout(() =>
|
|
61205
|
+
return new Promise((resolve4, reject) => {
|
|
61206
|
+
const timer = setTimeout(() => resolve4(void 0), waitMs);
|
|
60832
61207
|
timer.unref?.();
|
|
60833
61208
|
promise2.then(
|
|
60834
61209
|
(result) => {
|
|
60835
61210
|
clearTimeout(timer);
|
|
60836
|
-
|
|
61211
|
+
resolve4(result);
|
|
60837
61212
|
},
|
|
60838
61213
|
(err) => {
|
|
60839
61214
|
clearTimeout(timer);
|
|
@@ -60901,7 +61276,7 @@ var JobRegistry = class {
|
|
|
60901
61276
|
/** Await outstanding durable writes. Tests only — handlers never need it. */
|
|
60902
61277
|
async drain() {
|
|
60903
61278
|
for (let round = 0; round < 50; round++) {
|
|
60904
|
-
await new Promise((
|
|
61279
|
+
await new Promise((resolve4) => setTimeout(resolve4, 0));
|
|
60905
61280
|
if (!this.pending.size) return;
|
|
60906
61281
|
await Promise.allSettled([...this.pending]);
|
|
60907
61282
|
}
|
|
@@ -61691,8 +62066,7 @@ function isValidLibraryName(name) {
|
|
|
61691
62066
|
}
|
|
61692
62067
|
function createR2Library(bucket, opts) {
|
|
61693
62068
|
const now = opts.now ?? (() => /* @__PURE__ */ new Date());
|
|
61694
|
-
|
|
61695
|
-
const tenantId = () => tenantCache ??= Promise.resolve(typeof opts.tenant === "function" ? opts.tenant() : opts.tenant);
|
|
62069
|
+
const tenantId = tenantResolver(opts.tenant);
|
|
61696
62070
|
const assertName = (name) => {
|
|
61697
62071
|
if (!isValidLibraryName(name)) {
|
|
61698
62072
|
throw new Error(`Invalid library name "${name}" \u2014 use 1-40 lowercase letters, digits, "-" or "_" (e.g. "finn", "bold-cartoon-sports").`);
|
|
@@ -62299,6 +62673,17 @@ var GeminiClient = class {
|
|
|
62299
62673
|
const blob = await fileBlob(path, { type: mimeType, maxBytes: FILE_MAX_BYTES, label: "Video" });
|
|
62300
62674
|
return this.uploadToFilesApi(blob, mimeType, basename(path), blob.size);
|
|
62301
62675
|
}
|
|
62676
|
+
/**
|
|
62677
|
+
* Upload ANY local file (image, video, audio) by streaming it from disk —
|
|
62678
|
+
* the {@link uploadVideo} path without the video label. `gemini_upload_file`
|
|
62679
|
+
* `path` uses this: reading the file into a Buffer, base64-encoding it and
|
|
62680
|
+
* decoding it back held ~3x the file in memory and hit V8's max string
|
|
62681
|
+
* length on a few-hundred-MB video (chrischall/fleet-audit#117).
|
|
62682
|
+
*/
|
|
62683
|
+
async uploadFile(path, mimeType, displayName = basename(path)) {
|
|
62684
|
+
const blob = await fileBlob(path, { type: mimeType, maxBytes: FILE_MAX_BYTES, label: "File" });
|
|
62685
|
+
return this.uploadToFilesApi(blob, mimeType, displayName, blob.size);
|
|
62686
|
+
}
|
|
62302
62687
|
/**
|
|
62303
62688
|
* Upload already-in-memory bytes (a fetched `images_url`, a `data_base64`
|
|
62304
62689
|
* payload, an inline `gemini_upload_file` body) to the Files API. Same three
|
|
@@ -62924,10 +63309,9 @@ function isTransientPoll(err) {
|
|
|
62924
63309
|
function isDeliveryUnsupported(err) {
|
|
62925
63310
|
return err instanceof ApiError && err.status === 400 && /delivery/i.test(err.message);
|
|
62926
63311
|
}
|
|
62927
|
-
function hostedStorage() {
|
|
62928
|
-
const blob = blobStoreFromEnv();
|
|
63312
|
+
function hostedStorage(blob = blobStoreFromEnv()) {
|
|
62929
63313
|
if (!blob) return {};
|
|
62930
|
-
const tenant = () => tenantIdFor(readEnvVar("GEMINI_API_KEY") ?? "local");
|
|
63314
|
+
const tenant = pinnedTenant(blob.bucket, () => tenantIdFor(readEnvVar("GEMINI_API_KEY") ?? "local"));
|
|
62931
63315
|
return {
|
|
62932
63316
|
mediaSink: createR2Sink(blob.bucket, {
|
|
62933
63317
|
// The SAME `links` object the minter gets below. Media GETs and upload
|
|
@@ -62967,8 +63351,8 @@ init_images();
|
|
|
62967
63351
|
|
|
62968
63352
|
// src/sidecar.ts
|
|
62969
63353
|
import { readdir, readFile as readFile3, stat as stat2 } from "node:fs/promises";
|
|
62970
|
-
import { existsSync as
|
|
62971
|
-
import { join as
|
|
63354
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
63355
|
+
import { join as join5 } from "node:path";
|
|
62972
63356
|
var SIDECAR_SUFFIX2 = ".json";
|
|
62973
63357
|
async function readSidecars(dir) {
|
|
62974
63358
|
let entries;
|
|
@@ -62980,7 +63364,7 @@ async function readSidecars(dir) {
|
|
|
62980
63364
|
const records = [];
|
|
62981
63365
|
for (const entry of entries) {
|
|
62982
63366
|
if (!entry.endsWith(SIDECAR_SUFFIX2)) continue;
|
|
62983
|
-
const sidecarPath =
|
|
63367
|
+
const sidecarPath = join5(dir, entry);
|
|
62984
63368
|
try {
|
|
62985
63369
|
const parsed = JSON.parse(await readFile3(sidecarPath, "utf8"));
|
|
62986
63370
|
if (typeof parsed !== "object" || parsed === null) continue;
|
|
@@ -62990,7 +63374,7 @@ async function readSidecars(dir) {
|
|
|
62990
63374
|
records.push({
|
|
62991
63375
|
sidecarPath,
|
|
62992
63376
|
interactionId,
|
|
62993
|
-
images: paths.filter((p) =>
|
|
63377
|
+
images: paths.filter((p) => existsSync3(p)),
|
|
62994
63378
|
mtimeMs: (await stat2(sidecarPath)).mtimeMs
|
|
62995
63379
|
});
|
|
62996
63380
|
} catch {
|
|
@@ -63497,6 +63881,7 @@ function registerUsageTools(server, client2) {
|
|
|
63497
63881
|
// src/tools/files.ts
|
|
63498
63882
|
init_zod();
|
|
63499
63883
|
init_dist2();
|
|
63884
|
+
import { stat as stat3 } from "node:fs/promises";
|
|
63500
63885
|
var UPLOAD_URL_MAX_BYTES_DISK = 100 * 1024 * 1024;
|
|
63501
63886
|
var UPLOAD_URL_MAX_BYTES_HOSTED = 25 * 1024 * 1024;
|
|
63502
63887
|
var UPLOAD_ACCEPT = ["image/", "video/", "audio/"];
|
|
@@ -63547,6 +63932,7 @@ function registerFileTools(server, client2) {
|
|
|
63547
63932
|
sources.length === 0 ? "Provide exactly one of `url`, `data_base64`" + (onDisk ? " or `path`." : " or `r2_key`.") : `Provide exactly one source, not ${sources.length} (${sources.join(", ")}).`
|
|
63548
63933
|
);
|
|
63549
63934
|
}
|
|
63935
|
+
let localUpload;
|
|
63550
63936
|
if (args.path) {
|
|
63551
63937
|
if (!onDisk) {
|
|
63552
63938
|
throw new McpToolError(
|
|
@@ -63554,13 +63940,22 @@ function registerFileTools(server, client2) {
|
|
|
63554
63940
|
{ hint: "Use `url`, `r2_key` (gemini_get_upload_url), or `data_base64`." }
|
|
63555
63941
|
);
|
|
63556
63942
|
}
|
|
63557
|
-
const
|
|
63558
|
-
|
|
63559
|
-
|
|
63560
|
-
|
|
63561
|
-
|
|
63562
|
-
|
|
63563
|
-
|
|
63943
|
+
const { resolveImagePath: resolveImagePath2, detectUploadMime: detectUploadMime2 } = await Promise.resolve().then(() => (init_images(), images_exports));
|
|
63944
|
+
const resolved = resolveImagePath2(args.path);
|
|
63945
|
+
const mimeType = args.mime_type ?? await detectUploadMime2(resolved);
|
|
63946
|
+
if (!mimeType) {
|
|
63947
|
+
throw new McpToolError(
|
|
63948
|
+
`Cannot tell what kind of file ${resolved} is from its bytes or extension \u2014 pass \`mime_type\` (e.g. video/mp4, audio/mp3, image/gif) so it is not uploaded under the wrong type.`,
|
|
63949
|
+
{ hint: "Pass mime_type explicitly." }
|
|
63950
|
+
);
|
|
63951
|
+
}
|
|
63952
|
+
if (args.confirm !== true) {
|
|
63953
|
+
const { size } = await stat3(resolved);
|
|
63954
|
+
return previewUnlessConfirmed(args.confirm, "Upload a local file to the Gemini Files API", "POST", "/upload/v1beta/files", {
|
|
63955
|
+
inputs: [{ path: resolved, mimeType, size }]
|
|
63956
|
+
});
|
|
63957
|
+
}
|
|
63958
|
+
localUpload = { path: resolved, mimeType };
|
|
63564
63959
|
}
|
|
63565
63960
|
const uploaded = await withProgressHeartbeat(extra, "Uploading to the Gemini Files API", async () => {
|
|
63566
63961
|
if (args.url) {
|
|
@@ -63589,17 +63984,14 @@ function registerFileTools(server, client2) {
|
|
|
63589
63984
|
if (args.data_base64) {
|
|
63590
63985
|
const { decodeImageInput: decodeImageInput2 } = await Promise.resolve().then(() => (init_images(), images_exports));
|
|
63591
63986
|
const decoded = decodeImageInput2(args.data_base64);
|
|
63592
|
-
const
|
|
63593
|
-
return client2.uploadBytes(
|
|
63594
|
-
}
|
|
63595
|
-
const
|
|
63596
|
-
|
|
63597
|
-
|
|
63598
|
-
|
|
63599
|
-
|
|
63600
|
-
bytes,
|
|
63601
|
-
args.mime_type ?? inline.mimeType,
|
|
63602
|
-
args.display_name ?? (resolved.split(/[\\/]/).pop() || "upload")
|
|
63987
|
+
const bytes = base64ToBytes(decoded.base64);
|
|
63988
|
+
return client2.uploadBytes(bytes, args.mime_type ?? decoded.mimeType, args.display_name ?? "upload");
|
|
63989
|
+
}
|
|
63990
|
+
const local = localUpload;
|
|
63991
|
+
return client2.uploadFile(
|
|
63992
|
+
local.path,
|
|
63993
|
+
local.mimeType,
|
|
63994
|
+
args.display_name ?? (local.path.split(/[\\/]/).pop() || "upload")
|
|
63603
63995
|
);
|
|
63604
63996
|
});
|
|
63605
63997
|
return uploadResult(uploaded);
|