gogcli-mcp-sheets 4.2.5 → 4.4.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/index.js +474 -160
- package/manifest.json +9 -2
- package/package.json +2 -2
- package/server.json +2 -2
- package/src/tools/sheets-extra.ts +74 -69
- package/tests/tools/sheets-extra.test.ts +175 -137
- package/vitest.config.ts +5 -0
package/dist/index.js
CHANGED
|
@@ -2092,8 +2092,8 @@ function emoji() {
|
|
|
2092
2092
|
}
|
|
2093
2093
|
var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
|
|
2094
2094
|
var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
|
|
2095
|
-
var mac = (
|
|
2096
|
-
const escapedDelim = escapeRegex(
|
|
2095
|
+
var mac = (delimiter3) => {
|
|
2096
|
+
const escapedDelim = escapeRegex(delimiter3 ?? ":");
|
|
2097
2097
|
return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
|
|
2098
2098
|
};
|
|
2099
2099
|
var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
|
|
@@ -5121,7 +5121,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
|
|
|
5121
5121
|
var NONE = 0;
|
|
5122
5122
|
var ASSUMED = 1;
|
|
5123
5123
|
var PROVEN = 2;
|
|
5124
|
-
function isRecursive(inst, stack,
|
|
5124
|
+
function isRecursive(inst, stack, resolve4) {
|
|
5125
5125
|
const cached2 = recursive.get(inst);
|
|
5126
5126
|
if (cached2 !== void 0)
|
|
5127
5127
|
return cached2 ? PROVEN : NONE;
|
|
@@ -5131,7 +5131,7 @@ function isRecursive(inst, stack, resolve) {
|
|
|
5131
5131
|
let result = NONE;
|
|
5132
5132
|
const check2 = (child) => {
|
|
5133
5133
|
if (result !== PROVEN && child?._zod) {
|
|
5134
|
-
const answer = isRecursive(child, stack,
|
|
5134
|
+
const answer = isRecursive(child, stack, resolve4);
|
|
5135
5135
|
if (answer > result)
|
|
5136
5136
|
result = answer;
|
|
5137
5137
|
}
|
|
@@ -5142,7 +5142,7 @@ function isRecursive(inst, stack, resolve) {
|
|
|
5142
5142
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
5143
5143
|
if (spread && !desc.enumerable)
|
|
5144
5144
|
continue;
|
|
5145
|
-
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack,
|
|
5145
|
+
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve4) : NONE;
|
|
5146
5146
|
if (child > answer)
|
|
5147
5147
|
answer = child;
|
|
5148
5148
|
}
|
|
@@ -5206,7 +5206,7 @@ function isRecursive(inst, stack, resolve) {
|
|
|
5206
5206
|
break;
|
|
5207
5207
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
5208
5208
|
case "lazy": {
|
|
5209
|
-
const inner = def._cachedInner ?? (
|
|
5209
|
+
const inner = def._cachedInner ?? (resolve4 ? inst._zod.innerType : void 0);
|
|
5210
5210
|
merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
|
|
5211
5211
|
break;
|
|
5212
5212
|
}
|
|
@@ -24106,14 +24106,14 @@ function inputRequiredRoundsExceededMessage(method, maxRounds) {
|
|
|
24106
24106
|
return `Multi-round-trip request '${method}' still required input after ${maxRounds} rounds (inputRequired.maxRounds)`;
|
|
24107
24107
|
}
|
|
24108
24108
|
function sleep(ms, signal) {
|
|
24109
|
-
return new Promise((
|
|
24109
|
+
return new Promise((resolve4, reject) => {
|
|
24110
24110
|
if (signal?.aborted) {
|
|
24111
24111
|
reject(signal.reason instanceof SdkError ? signal.reason : new SdkError(SdkErrorCode.RequestTimeout, String(signal.reason)));
|
|
24112
24112
|
return;
|
|
24113
24113
|
}
|
|
24114
24114
|
const timer = setTimeout(() => {
|
|
24115
24115
|
signal?.removeEventListener("abort", onAbort);
|
|
24116
|
-
|
|
24116
|
+
resolve4();
|
|
24117
24117
|
}, ms);
|
|
24118
24118
|
const onAbort = () => {
|
|
24119
24119
|
clearTimeout(timer);
|
|
@@ -24907,7 +24907,7 @@ var Protocol = class {
|
|
|
24907
24907
|
const flowStartedAt = Date.now();
|
|
24908
24908
|
let onAbort;
|
|
24909
24909
|
let cleanupMessageId;
|
|
24910
|
-
return new Promise((
|
|
24910
|
+
return new Promise((resolve4, reject) => {
|
|
24911
24911
|
const earlyReject = (error62) => {
|
|
24912
24912
|
reject(error62);
|
|
24913
24913
|
};
|
|
@@ -24975,7 +24975,7 @@ var Protocol = class {
|
|
|
24975
24975
|
}
|
|
24976
24976
|
if (decoded.kind === "invalid") return reject(decoded.error);
|
|
24977
24977
|
if (decoded.kind === "input_required") {
|
|
24978
|
-
if (options?.allowInputRequired === true) return
|
|
24978
|
+
if (options?.allowInputRequired === true) return resolve4(manualInputRequiredValue(decoded));
|
|
24979
24979
|
const flow = {
|
|
24980
24980
|
codec: codec2,
|
|
24981
24981
|
request,
|
|
@@ -24987,11 +24987,11 @@ var Protocol = class {
|
|
|
24987
24987
|
params
|
|
24988
24988
|
}, resultSchema, legOptions)
|
|
24989
24989
|
};
|
|
24990
|
-
return
|
|
24990
|
+
return resolve4(this._resolveNonCompleteResult(decoded, flow));
|
|
24991
24991
|
}
|
|
24992
24992
|
const result = decoded.result;
|
|
24993
24993
|
validateStandardSchema(resultSchema, result).then((parseResult) => {
|
|
24994
|
-
if (parseResult.success)
|
|
24994
|
+
if (parseResult.success) resolve4(parseResult.data);
|
|
24995
24995
|
else reject(new SdkError(SdkErrorCode.InvalidResult, `Invalid result for ${request.method}: ${parseResult.error}`));
|
|
24996
24996
|
}, reject);
|
|
24997
24997
|
});
|
|
@@ -27903,7 +27903,7 @@ var require_compile = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
27903
27903
|
ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, ref);
|
|
27904
27904
|
const schOrFunc = root.refs[ref];
|
|
27905
27905
|
if (schOrFunc) return schOrFunc;
|
|
27906
|
-
let _sch =
|
|
27906
|
+
let _sch = resolve4.call(this, root, ref);
|
|
27907
27907
|
if (_sch === void 0) {
|
|
27908
27908
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
27909
27909
|
const { schemaId } = this.opts;
|
|
@@ -27929,7 +27929,7 @@ var require_compile = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
27929
27929
|
function sameSchemaEnv(s1, s2) {
|
|
27930
27930
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
27931
27931
|
}
|
|
27932
|
-
function
|
|
27932
|
+
function resolve4(root, ref) {
|
|
27933
27933
|
let sch;
|
|
27934
27934
|
while (typeof (sch = this.refs[ref]) == "string") ref = sch;
|
|
27935
27935
|
return sch || this.schemas[ref] || resolveSchema.call(this, root, ref);
|
|
@@ -28379,47 +28379,47 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
28379
28379
|
else if (typeof uri === "object") uri = parse3(serialize(uri, options), options);
|
|
28380
28380
|
return uri;
|
|
28381
28381
|
}
|
|
28382
|
-
function
|
|
28382
|
+
function resolve4(baseURI, relativeURI, options) {
|
|
28383
28383
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
28384
28384
|
const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
28385
28385
|
schemelessOptions.skipEscape = true;
|
|
28386
28386
|
return serialize(resolved, schemelessOptions);
|
|
28387
28387
|
}
|
|
28388
|
-
function resolveComponent(base,
|
|
28388
|
+
function resolveComponent(base, relative3, options, skipNormalization) {
|
|
28389
28389
|
const target = {};
|
|
28390
28390
|
if (!skipNormalization) {
|
|
28391
28391
|
base = parse3(serialize(base, options), options);
|
|
28392
|
-
|
|
28392
|
+
relative3 = parse3(serialize(relative3, options), options);
|
|
28393
28393
|
}
|
|
28394
28394
|
options = options || {};
|
|
28395
|
-
if (!options.tolerant &&
|
|
28396
|
-
target.scheme =
|
|
28397
|
-
target.userinfo =
|
|
28398
|
-
target.host =
|
|
28399
|
-
target.port =
|
|
28400
|
-
target.path = removeDotSegments(
|
|
28401
|
-
target.query =
|
|
28395
|
+
if (!options.tolerant && relative3.scheme) {
|
|
28396
|
+
target.scheme = relative3.scheme;
|
|
28397
|
+
target.userinfo = relative3.userinfo;
|
|
28398
|
+
target.host = relative3.host;
|
|
28399
|
+
target.port = relative3.port;
|
|
28400
|
+
target.path = removeDotSegments(relative3.path || "");
|
|
28401
|
+
target.query = relative3.query;
|
|
28402
28402
|
} else {
|
|
28403
|
-
if (
|
|
28404
|
-
target.userinfo =
|
|
28405
|
-
target.host =
|
|
28406
|
-
target.port =
|
|
28407
|
-
target.path = removeDotSegments(
|
|
28408
|
-
target.query =
|
|
28403
|
+
if (relative3.userinfo !== void 0 || relative3.host !== void 0 || relative3.port !== void 0) {
|
|
28404
|
+
target.userinfo = relative3.userinfo;
|
|
28405
|
+
target.host = relative3.host;
|
|
28406
|
+
target.port = relative3.port;
|
|
28407
|
+
target.path = removeDotSegments(relative3.path || "");
|
|
28408
|
+
target.query = relative3.query;
|
|
28409
28409
|
} else {
|
|
28410
|
-
if (!
|
|
28410
|
+
if (!relative3.path) {
|
|
28411
28411
|
target.path = base.path;
|
|
28412
|
-
if (
|
|
28412
|
+
if (relative3.query !== void 0) target.query = relative3.query;
|
|
28413
28413
|
else target.query = base.query;
|
|
28414
28414
|
} else {
|
|
28415
|
-
if (
|
|
28415
|
+
if (relative3.path[0] === "/") target.path = removeDotSegments(relative3.path);
|
|
28416
28416
|
else {
|
|
28417
|
-
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) target.path = "/" +
|
|
28418
|
-
else if (!base.path) target.path =
|
|
28419
|
-
else target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
28417
|
+
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) target.path = "/" + relative3.path;
|
|
28418
|
+
else if (!base.path) target.path = relative3.path;
|
|
28419
|
+
else target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative3.path;
|
|
28420
28420
|
target.path = removeDotSegments(target.path);
|
|
28421
28421
|
}
|
|
28422
|
-
target.query =
|
|
28422
|
+
target.query = relative3.query;
|
|
28423
28423
|
}
|
|
28424
28424
|
target.userinfo = base.userinfo;
|
|
28425
28425
|
target.host = base.host;
|
|
@@ -28427,7 +28427,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
28427
28427
|
}
|
|
28428
28428
|
target.scheme = base.scheme;
|
|
28429
28429
|
}
|
|
28430
|
-
target.fragment =
|
|
28430
|
+
target.fragment = relative3.fragment;
|
|
28431
28431
|
return target;
|
|
28432
28432
|
}
|
|
28433
28433
|
function equal(uriA, uriB, options) {
|
|
@@ -28553,7 +28553,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
28553
28553
|
const fastUri = {
|
|
28554
28554
|
SCHEMES,
|
|
28555
28555
|
normalize,
|
|
28556
|
-
resolve,
|
|
28556
|
+
resolve: resolve4,
|
|
28557
28557
|
resolveComponent,
|
|
28558
28558
|
equal,
|
|
28559
28559
|
serialize,
|
|
@@ -29335,14 +29335,14 @@ var require_ucs2length = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
29335
29335
|
function ucs2length(str) {
|
|
29336
29336
|
const len = str.length;
|
|
29337
29337
|
let length = 0;
|
|
29338
|
-
let
|
|
29338
|
+
let pos2 = 0;
|
|
29339
29339
|
let value;
|
|
29340
|
-
while (
|
|
29340
|
+
while (pos2 < len) {
|
|
29341
29341
|
length++;
|
|
29342
|
-
value = str.charCodeAt(
|
|
29343
|
-
if (value >= 55296 && value <= 56319 &&
|
|
29344
|
-
value = str.charCodeAt(
|
|
29345
|
-
if ((value & 64512) === 56320)
|
|
29342
|
+
value = str.charCodeAt(pos2++);
|
|
29343
|
+
if (value >= 55296 && value <= 56319 && pos2 < len) {
|
|
29344
|
+
value = str.charCodeAt(pos2);
|
|
29345
|
+
if ((value & 64512) === 56320) pos2++;
|
|
29346
29346
|
}
|
|
29347
29347
|
}
|
|
29348
29348
|
return length;
|
|
@@ -33926,7 +33926,7 @@ var StdioServerTransport = class {
|
|
|
33926
33926
|
}
|
|
33927
33927
|
send(message) {
|
|
33928
33928
|
if (this._closed) return Promise.reject(/* @__PURE__ */ new Error("StdioServerTransport is closed"));
|
|
33929
|
-
return new Promise((
|
|
33929
|
+
return new Promise((resolve4, reject) => {
|
|
33930
33930
|
const json2 = serializeMessage(message);
|
|
33931
33931
|
let settled = false;
|
|
33932
33932
|
const onError = (error62) => {
|
|
@@ -33941,14 +33941,14 @@ var StdioServerTransport = class {
|
|
|
33941
33941
|
settled = true;
|
|
33942
33942
|
this._stdout.off("error", onError);
|
|
33943
33943
|
this._stdout.off("drain", onDrain);
|
|
33944
|
-
|
|
33944
|
+
resolve4();
|
|
33945
33945
|
};
|
|
33946
33946
|
this._stdout.once("error", onError);
|
|
33947
33947
|
if (this._stdout.write(json2)) {
|
|
33948
33948
|
if (settled) return;
|
|
33949
33949
|
settled = true;
|
|
33950
33950
|
this._stdout.off("error", onError);
|
|
33951
|
-
|
|
33951
|
+
resolve4();
|
|
33952
33952
|
} else if (!settled) this._stdout.once("drain", onDrain);
|
|
33953
33953
|
});
|
|
33954
33954
|
}
|
|
@@ -34002,14 +34002,14 @@ var StdioConnectionChannel = class {
|
|
|
34002
34002
|
*/
|
|
34003
34003
|
async whenRequestsAnswered(timeoutMs) {
|
|
34004
34004
|
if (this._closed || this._pendingRequests.size === 0) return true;
|
|
34005
|
-
return await new Promise((
|
|
34005
|
+
return await new Promise((resolve4) => {
|
|
34006
34006
|
const waiter = () => {
|
|
34007
34007
|
clearTimeout(timer);
|
|
34008
|
-
|
|
34008
|
+
resolve4(true);
|
|
34009
34009
|
};
|
|
34010
34010
|
const timer = setTimeout(() => {
|
|
34011
34011
|
this._drainWaiters = this._drainWaiters.filter((pending) => pending !== waiter);
|
|
34012
|
-
|
|
34012
|
+
resolve4(false);
|
|
34013
34013
|
}, timeoutMs);
|
|
34014
34014
|
this._drainWaiters.push(waiter);
|
|
34015
34015
|
});
|
|
@@ -34379,13 +34379,28 @@ var API_KEY_RE = new RegExp([
|
|
|
34379
34379
|
"whsec_[A-Za-z0-9]{16,}\\b"
|
|
34380
34380
|
// webhook signing secret (Stripe-style)
|
|
34381
34381
|
].map((p) => `\\b${p}`).join("|"), "g");
|
|
34382
|
-
var QUERY_SECRET_RE = /([?&](?:
|
|
34382
|
+
var 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;
|
|
34383
|
+
var OAUTH_CODE_RE = /([?&]code=)(?=[^&#\s"'<>`]{16,})[^&#\s"'<>`]+/gi;
|
|
34384
|
+
var FORM_PASSWORD_RE = /((?:^|[\s,;:"'(\[{])(?:password|passwd)=)[^&#\s"'<>`]+/gim;
|
|
34385
|
+
var HEADER_SECRET_RE = /(\b(?:x[-_][a-z0-9_-]*?(?:api[-_]?key|token|secret|auth)[a-z0-9_-]*|api[-_]?key)\s*:\s*)[^\s,;"'<>`]+/gi;
|
|
34383
34386
|
var AWS_SIGV4_RE = /([?&]X-Amz-(?:Signature|Security-Token|Credential)=)[^&#\s"'<>`]+/gi;
|
|
34384
|
-
var JSON_SECRET_KEYS =
|
|
34385
|
-
|
|
34386
|
-
|
|
34387
|
+
var JSON_SECRET_KEYS = [
|
|
34388
|
+
"(?:access|refresh|id|auth|session|bearer|csrf|xsrf)[_-]?token",
|
|
34389
|
+
"client[_-]?secret",
|
|
34390
|
+
"api[_-]?secret",
|
|
34391
|
+
"(?:x[_-])?api[_-]?key",
|
|
34392
|
+
"private[_-]?key",
|
|
34393
|
+
"x[_-][a-z0-9_-]*?(?:api[_-]?key|token|secret|auth)[a-z0-9_-]*",
|
|
34394
|
+
"(?:proxy-)?authorization",
|
|
34395
|
+
"password",
|
|
34396
|
+
"passwd",
|
|
34397
|
+
"secret",
|
|
34398
|
+
"token"
|
|
34399
|
+
].join("|");
|
|
34400
|
+
var JSON_SECRET_DQ_RE = new RegExp(`("(?:${JSON_SECRET_KEYS})"\\s*:\\s*")(?:[^"\\\\]|\\\\.)*(")`, "gi");
|
|
34401
|
+
var JSON_SECRET_SQ_RE = new RegExp(`('(?:${JSON_SECRET_KEYS})'\\s*:\\s*')(?:[^'\\\\]|\\\\.)*(')`, "gi");
|
|
34387
34402
|
function redactSecrets(text) {
|
|
34388
|
-
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]");
|
|
34403
|
+
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]");
|
|
34389
34404
|
}
|
|
34390
34405
|
|
|
34391
34406
|
// ../../node_modules/@chrischall/mcp-utils/dist/response/view.js
|
|
@@ -34547,13 +34562,47 @@ async function createMcpServer(opts) {
|
|
|
34547
34562
|
}
|
|
34548
34563
|
return server;
|
|
34549
34564
|
}
|
|
34565
|
+
var DEFAULT_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
34566
|
+
var DEFAULT_REPEAT_SIGNAL_GRACE_MS = 500;
|
|
34550
34567
|
function withGracefulShutdown(target, opts = {}) {
|
|
34551
34568
|
const shouldExit = opts.exit ?? true;
|
|
34569
|
+
if (opts.timeoutMs !== void 0 && !(Number.isFinite(opts.timeoutMs) && opts.timeoutMs > 0)) {
|
|
34570
|
+
throw new RangeError("withGracefulShutdown: timeoutMs must be a finite number greater than 0.");
|
|
34571
|
+
}
|
|
34572
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS;
|
|
34573
|
+
if (opts.repeatSignalGraceMs !== void 0 && !(Number.isFinite(opts.repeatSignalGraceMs) && opts.repeatSignalGraceMs >= 0)) {
|
|
34574
|
+
throw new RangeError("withGracefulShutdown: repeatSignalGraceMs must be a finite number >= 0.");
|
|
34575
|
+
}
|
|
34576
|
+
const repeatGraceMs = opts.repeatSignalGraceMs ?? DEFAULT_REPEAT_SIGNAL_GRACE_MS;
|
|
34552
34577
|
let shuttingDown = false;
|
|
34578
|
+
let firstSignalAt = 0;
|
|
34579
|
+
let exited = false;
|
|
34580
|
+
const exitOnce = () => {
|
|
34581
|
+
if (exited)
|
|
34582
|
+
return;
|
|
34583
|
+
exited = true;
|
|
34584
|
+
process.exit(0);
|
|
34585
|
+
};
|
|
34553
34586
|
const handler = (signal) => {
|
|
34554
|
-
if (shuttingDown)
|
|
34587
|
+
if (shuttingDown) {
|
|
34588
|
+
if (Date.now() - firstSignalAt < repeatGraceMs)
|
|
34589
|
+
return;
|
|
34590
|
+
if (shouldExit) {
|
|
34591
|
+
console.error(`[mcp-utils] second ${signal} during shutdown \u2014 exiting now`);
|
|
34592
|
+
exitOnce();
|
|
34593
|
+
}
|
|
34555
34594
|
return;
|
|
34595
|
+
}
|
|
34556
34596
|
shuttingDown = true;
|
|
34597
|
+
firstSignalAt = Date.now();
|
|
34598
|
+
let timer;
|
|
34599
|
+
if (shouldExit) {
|
|
34600
|
+
timer = setTimeout(() => {
|
|
34601
|
+
console.error(`[mcp-utils] graceful shutdown on ${signal} did not finish in ${timeoutMs}ms \u2014 exiting`);
|
|
34602
|
+
exitOnce();
|
|
34603
|
+
}, timeoutMs);
|
|
34604
|
+
timer.unref?.();
|
|
34605
|
+
}
|
|
34557
34606
|
void (async () => {
|
|
34558
34607
|
try {
|
|
34559
34608
|
if (opts.onSignal)
|
|
@@ -34562,8 +34611,10 @@ function withGracefulShutdown(target, opts = {}) {
|
|
|
34562
34611
|
} catch (err) {
|
|
34563
34612
|
console.error(`[mcp-utils] error during graceful shutdown on ${signal}: ${err instanceof Error ? err.message : String(err)}`);
|
|
34564
34613
|
} finally {
|
|
34614
|
+
if (timer !== void 0)
|
|
34615
|
+
clearTimeout(timer);
|
|
34565
34616
|
if (shouldExit)
|
|
34566
|
-
|
|
34617
|
+
exitOnce();
|
|
34567
34618
|
}
|
|
34568
34619
|
})();
|
|
34569
34620
|
};
|
|
@@ -34593,6 +34644,8 @@ function runMcp(opts) {
|
|
|
34593
34644
|
}
|
|
34594
34645
|
|
|
34595
34646
|
// ../../node_modules/@chrischall/mcp-utils/dist/config/index.js
|
|
34647
|
+
import { homedir } from "node:os";
|
|
34648
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
34596
34649
|
var PLACEHOLDER_RE = /^\$\{[^}]*\}$/;
|
|
34597
34650
|
function readEnvVar(key, opts = {}) {
|
|
34598
34651
|
const env = opts.env ?? process.env;
|
|
@@ -34619,6 +34672,50 @@ function parseBoolEnv(key, opts = {}) {
|
|
|
34619
34672
|
return false;
|
|
34620
34673
|
return fallback;
|
|
34621
34674
|
}
|
|
34675
|
+
function expandPath(p) {
|
|
34676
|
+
let expanded = p;
|
|
34677
|
+
if (p === "~") {
|
|
34678
|
+
expanded = homedir();
|
|
34679
|
+
} else if (p.startsWith("~/")) {
|
|
34680
|
+
expanded = join(homedir(), p.slice(2));
|
|
34681
|
+
}
|
|
34682
|
+
return isAbsolute(expanded) ? expanded : resolve(expanded);
|
|
34683
|
+
}
|
|
34684
|
+
|
|
34685
|
+
// ../../node_modules/@chrischall/mcp-utils/dist/fs/confine.js
|
|
34686
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
34687
|
+
import { dirname, isAbsolute as isAbsolute2, relative, resolve as resolve2, sep } from "node:path";
|
|
34688
|
+
function isInside(root, target) {
|
|
34689
|
+
const rel = relative(root, target);
|
|
34690
|
+
return rel === "" || !rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute2(rel);
|
|
34691
|
+
}
|
|
34692
|
+
function realPathAllowingMissing(p) {
|
|
34693
|
+
const abs = resolve2(p);
|
|
34694
|
+
let existing = abs;
|
|
34695
|
+
const tail = [];
|
|
34696
|
+
while (!existsSync(existing)) {
|
|
34697
|
+
const parent = dirname(existing);
|
|
34698
|
+
if (parent === existing)
|
|
34699
|
+
break;
|
|
34700
|
+
tail.unshift(existing.slice(parent.length).replace(/^[/\\]+/, ""));
|
|
34701
|
+
existing = parent;
|
|
34702
|
+
}
|
|
34703
|
+
let real;
|
|
34704
|
+
try {
|
|
34705
|
+
real = realpathSync(existing);
|
|
34706
|
+
} catch {
|
|
34707
|
+
real = existing;
|
|
34708
|
+
}
|
|
34709
|
+
return tail.length > 0 ? resolve2(real, ...tail) : real;
|
|
34710
|
+
}
|
|
34711
|
+
function assertPathWithinRoots(path, roots) {
|
|
34712
|
+
const target = realPathAllowingMissing(expandPath(path));
|
|
34713
|
+
for (const root of roots) {
|
|
34714
|
+
if (isInside(realPathAllowingMissing(expandPath(root)), target))
|
|
34715
|
+
return target;
|
|
34716
|
+
}
|
|
34717
|
+
throw new Error(`Path is outside the allowed directories: ${path}`);
|
|
34718
|
+
}
|
|
34622
34719
|
|
|
34623
34720
|
// ../../node_modules/@chrischall/mcp-utils/dist/zod/index.js
|
|
34624
34721
|
var PositiveInt = external_exports.number().int().positive();
|
|
@@ -34640,7 +34737,7 @@ var pageSchema = {
|
|
|
34640
34737
|
};
|
|
34641
34738
|
|
|
34642
34739
|
// ../gogcli-mcp/src/runner.ts
|
|
34643
|
-
import { delimiter, join } from "node:path";
|
|
34740
|
+
import { delimiter, join as join2 } from "node:path";
|
|
34644
34741
|
|
|
34645
34742
|
// ../gogcli-mcp/src/timestamps.ts
|
|
34646
34743
|
var DEFAULT_DISPLAY_TZ = "America/New_York";
|
|
@@ -34841,9 +34938,48 @@ function normalizeTimestamps(text, tz = displayTimeZone(), naiveTz = naiveSource
|
|
|
34841
34938
|
return JSON.stringify(parsed, null, detectIndent(text));
|
|
34842
34939
|
}
|
|
34843
34940
|
|
|
34941
|
+
// ../gogcli-mcp/src/arg-guard.ts
|
|
34942
|
+
var FORBIDDEN_LONG_FLAG = /^--(readonly|enable-commands|enable-commands-exact|disable-commands|access-token|home|account|acct|client|gmail-no-send|no-input|non-interactive|noninteractive)(=|$)/i;
|
|
34943
|
+
var SHORT_ACCOUNT_CLUSTER = /^-(?!-)[A-Za-z]*a/;
|
|
34944
|
+
function forbiddenArgReason(arg) {
|
|
34945
|
+
if (arg === "--") {
|
|
34946
|
+
return 'The argument "--" is not allowed: it ends flag parsing and would disable safety flags appended after it.';
|
|
34947
|
+
}
|
|
34948
|
+
const match = FORBIDDEN_LONG_FLAG.exec(arg);
|
|
34949
|
+
if (match) {
|
|
34950
|
+
return `The flag ${arg} is not allowed here: --${match[1].toLowerCase()} is a safety/credential control set by the server operator, not a per-call option.`;
|
|
34951
|
+
}
|
|
34952
|
+
if (SHORT_ACCOUNT_CLUSTER.test(arg)) {
|
|
34953
|
+
return `The flag ${arg} is not allowed here: -a selects the account. Use the tool's account parameter instead.`;
|
|
34954
|
+
}
|
|
34955
|
+
return void 0;
|
|
34956
|
+
}
|
|
34957
|
+
function assertSafeForwardedArgs(args) {
|
|
34958
|
+
for (const arg of args) {
|
|
34959
|
+
const reason = forbiddenArgReason(arg);
|
|
34960
|
+
if (reason) throw new Error(reason);
|
|
34961
|
+
}
|
|
34962
|
+
}
|
|
34963
|
+
var SUBCOMMAND_SHAPE = /^[a-z][a-z0-9-]*$/;
|
|
34964
|
+
function assertSafeSubcommand(subcommand) {
|
|
34965
|
+
if (!SUBCOMMAND_SHAPE.test(subcommand)) {
|
|
34966
|
+
throw new Error(
|
|
34967
|
+
`Invalid subcommand ${JSON.stringify(subcommand)}: pass a single gog subcommand name such as "list" or "mark-read", and put its arguments in args.`
|
|
34968
|
+
);
|
|
34969
|
+
}
|
|
34970
|
+
}
|
|
34971
|
+
|
|
34972
|
+
// ../gogcli-mcp/src/argv.ts
|
|
34973
|
+
function pos(value) {
|
|
34974
|
+
return { kind: "positional", value };
|
|
34975
|
+
}
|
|
34976
|
+
function isGogPositional(arg) {
|
|
34977
|
+
return typeof arg === "object" && arg !== null && arg.kind === "positional";
|
|
34978
|
+
}
|
|
34979
|
+
|
|
34844
34980
|
// ../gogcli-mcp/src/runner.ts
|
|
34845
34981
|
function isGogFileArg(arg) {
|
|
34846
|
-
return typeof arg !== "string";
|
|
34982
|
+
return typeof arg !== "string" && arg.kind === "file";
|
|
34847
34983
|
}
|
|
34848
34984
|
var TIMEOUT_MS = 3e4;
|
|
34849
34985
|
function readonlyEnvEnabled() {
|
|
@@ -34927,8 +35063,8 @@ function formatTimeout(ms) {
|
|
|
34927
35063
|
}
|
|
34928
35064
|
async function spawnWithTempFiles(args, opts) {
|
|
34929
35065
|
const { mkdtemp, mkdir, writeFile, rm } = await import("node:fs/promises");
|
|
34930
|
-
const { tmpdir } = await import("node:os");
|
|
34931
|
-
const dir = await mkdtemp(
|
|
35066
|
+
const { tmpdir: tmpdir2 } = await import("node:os");
|
|
35067
|
+
const dir = await mkdtemp(join2(tmpdir2(), "gogcli-mcp-"));
|
|
34932
35068
|
try {
|
|
34933
35069
|
const argv = [];
|
|
34934
35070
|
let seq = 0;
|
|
@@ -34937,10 +35073,10 @@ async function spawnWithTempFiles(args, opts) {
|
|
|
34937
35073
|
argv.push(arg);
|
|
34938
35074
|
continue;
|
|
34939
35075
|
}
|
|
34940
|
-
const sub =
|
|
35076
|
+
const sub = join2(dir, String(seq));
|
|
34941
35077
|
seq += 1;
|
|
34942
35078
|
await mkdir(sub, { recursive: true, mode: 448 });
|
|
34943
|
-
const path =
|
|
35079
|
+
const path = join2(sub, arg.filename ?? `${arg.flag}.${arg.ext ?? "txt"}`);
|
|
34944
35080
|
const data = arg.encoding === "base64" ? Buffer.from(arg.contents, "base64") : Buffer.from(arg.contents, "utf8");
|
|
34945
35081
|
await writeFile(path, data, { mode: 384 });
|
|
34946
35082
|
argv.push(arg.positional ? path : `--${arg.flag}=${path}`);
|
|
@@ -34958,10 +35094,10 @@ function spawnExecutor(args, opts) {
|
|
|
34958
35094
|
return spawnGog(args, opts);
|
|
34959
35095
|
}
|
|
34960
35096
|
async function spawnGog(fullArgs, opts) {
|
|
34961
|
-
const { timeout, interactive = false, spawner, binary = false } = opts;
|
|
35097
|
+
const { timeout, interactive = false, spawner, binary = false, maxOutputBytes } = opts;
|
|
34962
35098
|
const spawn = spawner ?? (await import("node:child_process")).spawn;
|
|
34963
35099
|
const effectiveTimeout = timeout ?? TIMEOUT_MS;
|
|
34964
|
-
return new Promise((
|
|
35100
|
+
return new Promise((resolve4, reject) => {
|
|
34965
35101
|
const childEnv = { ...sanitizedEnv(), GOG_TIMEZONE: naiveSourceTimeZone(), PATH: augmentedPath() };
|
|
34966
35102
|
const child = spawn(readEnvVar("GOG_PATH") ?? "gog", fullArgs, { env: childEnv });
|
|
34967
35103
|
const stdoutChunks = [];
|
|
@@ -34979,7 +35115,17 @@ async function spawnGog(fullArgs, opts) {
|
|
|
34979
35115
|
child.kill();
|
|
34980
35116
|
reject(new Error(`gog timed out after ${formatTimeout(effectiveTimeout)}`));
|
|
34981
35117
|
}, effectiveTimeout);
|
|
35118
|
+
let stdoutBytes = 0;
|
|
34982
35119
|
child.stdout.on("data", (chunk) => {
|
|
35120
|
+
if (settled) return;
|
|
35121
|
+
stdoutBytes += chunk.length;
|
|
35122
|
+
if (maxOutputBytes !== void 0 && stdoutBytes > maxOutputBytes) {
|
|
35123
|
+
settled = true;
|
|
35124
|
+
stopWatching();
|
|
35125
|
+
child.kill();
|
|
35126
|
+
reject(new Error(`gog output exceeded the limit: more than ${maxOutputBytes} bytes`));
|
|
35127
|
+
return;
|
|
35128
|
+
}
|
|
34983
35129
|
stdoutChunks.push(chunk);
|
|
34984
35130
|
});
|
|
34985
35131
|
child.stderr.on("data", (chunk) => {
|
|
@@ -34996,14 +35142,14 @@ async function spawnGog(fullArgs, opts) {
|
|
|
34996
35142
|
const stderr = Buffer.concat(stderrChunks).toString().trim();
|
|
34997
35143
|
if (code === 0) {
|
|
34998
35144
|
if (binary) {
|
|
34999
|
-
|
|
35145
|
+
resolve4(Buffer.concat(stdoutChunks).toString("base64"));
|
|
35000
35146
|
return;
|
|
35001
35147
|
}
|
|
35002
35148
|
const stdout = Buffer.concat(stdoutChunks).toString();
|
|
35003
35149
|
if (interactive && stderr) {
|
|
35004
|
-
|
|
35150
|
+
resolve4(stdout + "\n" + stderr);
|
|
35005
35151
|
} else {
|
|
35006
|
-
|
|
35152
|
+
resolve4(stdout);
|
|
35007
35153
|
}
|
|
35008
35154
|
} else {
|
|
35009
35155
|
reject(new Error(stderr || `gog exited with code ${code}`));
|
|
@@ -35023,7 +35169,33 @@ async function spawnGog(fullArgs, opts) {
|
|
|
35023
35169
|
});
|
|
35024
35170
|
});
|
|
35025
35171
|
}
|
|
35172
|
+
function placePositionals(args) {
|
|
35173
|
+
const flags = [];
|
|
35174
|
+
const positionals = [];
|
|
35175
|
+
let afterSeparator = false;
|
|
35176
|
+
for (const arg of args) {
|
|
35177
|
+
if (arg === "--") {
|
|
35178
|
+
afterSeparator = true;
|
|
35179
|
+
} else if (isGogPositional(arg)) {
|
|
35180
|
+
positionals.push(arg.value);
|
|
35181
|
+
} else if (afterSeparator || isGogFileArg(arg) && arg.positional) {
|
|
35182
|
+
positionals.push(arg);
|
|
35183
|
+
} else {
|
|
35184
|
+
flags.push(arg);
|
|
35185
|
+
}
|
|
35186
|
+
}
|
|
35187
|
+
return { flags, positionals };
|
|
35188
|
+
}
|
|
35189
|
+
function assertNoSafetyOverrides(flags) {
|
|
35190
|
+
for (const arg of flags) {
|
|
35191
|
+
if (typeof arg !== "string") continue;
|
|
35192
|
+
const reason = forbiddenArgReason(arg);
|
|
35193
|
+
if (reason) throw new Error(reason);
|
|
35194
|
+
}
|
|
35195
|
+
}
|
|
35026
35196
|
function assembleArgs(args, opts) {
|
|
35197
|
+
const { flags, positionals } = placePositionals(args);
|
|
35198
|
+
assertNoSafetyOverrides(flags);
|
|
35027
35199
|
const effectiveAccount = opts.account ?? readEnvVar("GOG_ACCOUNT");
|
|
35028
35200
|
const fullArgs = ["--json", "--color=never"];
|
|
35029
35201
|
if (!opts.interactive) {
|
|
@@ -35032,17 +35204,21 @@ function assembleArgs(args, opts) {
|
|
|
35032
35204
|
if (opts.readonly || readonlyEnvEnabled()) {
|
|
35033
35205
|
fullArgs.push("--readonly");
|
|
35034
35206
|
}
|
|
35207
|
+
if (opts.gmailNoSend) {
|
|
35208
|
+
fullArgs.push("--gmail-no-send");
|
|
35209
|
+
}
|
|
35035
35210
|
if (effectiveAccount) {
|
|
35036
35211
|
fullArgs.push("--account", effectiveAccount);
|
|
35037
35212
|
}
|
|
35038
|
-
fullArgs.push(...
|
|
35213
|
+
fullArgs.push(...flags);
|
|
35214
|
+
if (positionals.length > 0) fullArgs.push("--", ...positionals);
|
|
35039
35215
|
return fullArgs;
|
|
35040
35216
|
}
|
|
35041
35217
|
async function run(args, options = {}) {
|
|
35042
|
-
const { account, spawner, interactive = false, timeout, readonly: readonly2 = false, redactMode = "full", opaqueFields } = options;
|
|
35218
|
+
const { account, spawner, interactive = false, timeout, readonly: readonly2 = false, redactMode = "full", opaqueFields, gmailNoSend = false } = options;
|
|
35043
35219
|
const base = redactMode === "tokens" ? redactGoogleTokens : redactSecrets2;
|
|
35044
35220
|
const redact = opaqueFields?.length ? (text) => redactPreservingOpaqueFields(text, opaqueFields, base) : base;
|
|
35045
|
-
const fullArgs = assembleArgs(args, { account, interactive, readonly: readonly2 });
|
|
35221
|
+
const fullArgs = assembleArgs(args, { account, interactive, readonly: readonly2, gmailNoSend });
|
|
35046
35222
|
try {
|
|
35047
35223
|
return redact(await spawnExecutor(fullArgs, { timeout, interactive, spawner }));
|
|
35048
35224
|
} catch (err) {
|
|
@@ -35070,6 +35246,111 @@ function stripConsumedPageToken(text) {
|
|
|
35070
35246
|
return JSON.stringify(obj, null, detectIndent2(text));
|
|
35071
35247
|
}
|
|
35072
35248
|
|
|
35249
|
+
// ../gogcli-mcp/src/file-roots.ts
|
|
35250
|
+
import { homedir as homedir2 } from "node:os";
|
|
35251
|
+
import { delimiter as delimiter2, join as join4 } from "node:path";
|
|
35252
|
+
|
|
35253
|
+
// ../gogcli-mcp/src/attachment-root.ts
|
|
35254
|
+
import { tmpdir, userInfo } from "node:os";
|
|
35255
|
+
import { dirname as dirname2, join as join3, relative as relative2, resolve as resolve3, isAbsolute as isAbsolute3, sep as sep2 } from "node:path";
|
|
35256
|
+
var ATTACHMENT_DOWNLOAD_ROOT = join3(tmpdir(), `gogcli-mcp-attachments-${userInfo().uid}`);
|
|
35257
|
+
var ATTACHMENT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
35258
|
+
|
|
35259
|
+
// ../gogcli-mcp/src/file-roots.ts
|
|
35260
|
+
var FILE_ROOTS_ENV = "GOG_FILE_ROOTS";
|
|
35261
|
+
function defaultFileRoot() {
|
|
35262
|
+
return join4(homedir2(), "gogcli-mcp-files");
|
|
35263
|
+
}
|
|
35264
|
+
function fileRoots() {
|
|
35265
|
+
const raw = readEnvVar(FILE_ROOTS_ENV);
|
|
35266
|
+
const roots = (raw ?? "").split(delimiter2).map((r) => r.trim()).filter(Boolean);
|
|
35267
|
+
return roots.length > 0 ? roots : [defaultFileRoot()];
|
|
35268
|
+
}
|
|
35269
|
+
function confinePath(path, param, opts = {}) {
|
|
35270
|
+
if (opts.allowDash && path === "-") return path;
|
|
35271
|
+
const roots = [...fileRoots(), ATTACHMENT_DOWNLOAD_ROOT];
|
|
35272
|
+
try {
|
|
35273
|
+
assertPathWithinRoots(path, roots);
|
|
35274
|
+
} catch {
|
|
35275
|
+
throw new Error(
|
|
35276
|
+
`${param} ${JSON.stringify(path)} is outside the directories this server may read or write (${roots.join(", ")}). Put the file in one of them, or ask the server operator to widen ${FILE_ROOTS_ENV}.`
|
|
35277
|
+
);
|
|
35278
|
+
}
|
|
35279
|
+
return path;
|
|
35280
|
+
}
|
|
35281
|
+
function confineAtFile(value, param) {
|
|
35282
|
+
if (value.startsWith("@")) confinePath(value.slice(1), param);
|
|
35283
|
+
return value;
|
|
35284
|
+
}
|
|
35285
|
+
|
|
35286
|
+
// ../gogcli-mcp/src/run-path-guard.ts
|
|
35287
|
+
var POSITIONAL_PATH_SUBCOMMANDS = {
|
|
35288
|
+
appscript: { pull: "gog_appscript_pull" },
|
|
35289
|
+
drive: { upload: "gog_drive_upload", sync: "gog_drive_sync_push" },
|
|
35290
|
+
gmail: { import: "gog_gmail_import" },
|
|
35291
|
+
slides: {
|
|
35292
|
+
"add-slide": "gog_slides_add_slide",
|
|
35293
|
+
"insert-image": "gog_slides_insert_image",
|
|
35294
|
+
"replace-slide": "gog_slides_replace_slide"
|
|
35295
|
+
}
|
|
35296
|
+
};
|
|
35297
|
+
var PATH_FLAGS = /* @__PURE__ */ new Set(["out", "output", "out-dir", "output-dir", "dir", "worker-dir", "attach", "file", "key", "cert", "replacements"]);
|
|
35298
|
+
var ID_FLAGS = {
|
|
35299
|
+
drive: /* @__PURE__ */ new Set(["file", "filter-file"])
|
|
35300
|
+
};
|
|
35301
|
+
var EXEC_FLAGS = /* @__PURE__ */ new Set(["on-change", "on-new", "mmdc"]);
|
|
35302
|
+
var SHORT_PATH_CLUSTER = /^-(?!-)[A-Za-z]*[of]/;
|
|
35303
|
+
var LONG_FLAG = /^--([A-Za-z0-9][A-Za-z0-9-]*)(?:=([\s\S]*))?$/;
|
|
35304
|
+
function isPathFlag(service, name) {
|
|
35305
|
+
if (ID_FLAGS[service]?.has(name)) return false;
|
|
35306
|
+
return PATH_FLAGS.has(name) || name.endsWith("-file");
|
|
35307
|
+
}
|
|
35308
|
+
function confineFlagValue(flag, value) {
|
|
35309
|
+
if (value === "-") return;
|
|
35310
|
+
confinePath(value, flag);
|
|
35311
|
+
for (const part of value.split(",")) {
|
|
35312
|
+
if (part !== "" && part !== "-") confinePath(part, flag);
|
|
35313
|
+
}
|
|
35314
|
+
}
|
|
35315
|
+
function positionalPathTool(service, subcommand) {
|
|
35316
|
+
return POSITIONAL_PATH_SUBCOMMANDS[service]?.[subcommand];
|
|
35317
|
+
}
|
|
35318
|
+
function assertRunPathsConfined(service, subcommand, args) {
|
|
35319
|
+
const dedicated = positionalPathTool(service, subcommand);
|
|
35320
|
+
if (dedicated) {
|
|
35321
|
+
throw new Error(
|
|
35322
|
+
`gog ${service} ${subcommand} reads or writes a local path given as a positional argument, so it is not available through gog_${service}_run. Use ${dedicated}, which confines the path to GOG_FILE_ROOTS.`
|
|
35323
|
+
);
|
|
35324
|
+
}
|
|
35325
|
+
for (let i = 0; i < args.length; i++) {
|
|
35326
|
+
const arg = args[i];
|
|
35327
|
+
if (SHORT_PATH_CLUSTER.test(arg)) {
|
|
35328
|
+
throw new Error(
|
|
35329
|
+
`The flag ${arg} is not allowed here: spell a path flag out as --out or --file (e.g. --out=<path>) so its path can be checked against GOG_FILE_ROOTS.`
|
|
35330
|
+
);
|
|
35331
|
+
}
|
|
35332
|
+
const match = LONG_FLAG.exec(arg);
|
|
35333
|
+
if (!match) continue;
|
|
35334
|
+
const name = match[1].toLowerCase();
|
|
35335
|
+
if (EXEC_FLAGS.has(name)) {
|
|
35336
|
+
throw new Error(`The flag --${name} is not allowed here: it runs a local program chosen by the caller.`);
|
|
35337
|
+
}
|
|
35338
|
+
const isJson = name.endsWith("-json");
|
|
35339
|
+
if (!isJson && !isPathFlag(service, name)) continue;
|
|
35340
|
+
let value = match[2];
|
|
35341
|
+
if (value === void 0) {
|
|
35342
|
+
value = args[i + 1];
|
|
35343
|
+
if (value === void 0) continue;
|
|
35344
|
+
i++;
|
|
35345
|
+
}
|
|
35346
|
+
if (isJson) {
|
|
35347
|
+
if (value.startsWith("@")) confineFlagValue(`--${name}`, value.slice(1));
|
|
35348
|
+
continue;
|
|
35349
|
+
}
|
|
35350
|
+
confineFlagValue(`--${name}`, value);
|
|
35351
|
+
}
|
|
35352
|
+
}
|
|
35353
|
+
|
|
35073
35354
|
// ../gogcli-mcp/src/tools/utils.ts
|
|
35074
35355
|
var PAYLOAD_INLINE_MAX = 4096;
|
|
35075
35356
|
function payloadArg(inlineFlag, fileFlag, value, ext) {
|
|
@@ -35118,9 +35399,17 @@ var paginationParams = {
|
|
|
35118
35399
|
all: external_exports.boolean().optional().describe("Fetch all pages")
|
|
35119
35400
|
};
|
|
35120
35401
|
function registerRunTool(server, options) {
|
|
35121
|
-
const { service, examples, omitAccount = false, note } = options;
|
|
35402
|
+
const { service, examples, omitAccount = false, note, allowedSubcommands, vet, gmailNoSend = false } = options;
|
|
35403
|
+
for (const [, example] of examples.matchAll(/"([^"]+)"/g)) {
|
|
35404
|
+
const refused = allowedSubcommands && !allowedSubcommands.includes(example) || vet?.(example, []) || positionalPathTool(service, example);
|
|
35405
|
+
if (refused) {
|
|
35406
|
+
throw new Error(`gog_${service}_run example "${example}" is refused by the tool itself; list a subcommand it runs.`);
|
|
35407
|
+
}
|
|
35408
|
+
}
|
|
35122
35409
|
const baseDescription = `Run any gog ${service} subcommand not covered by the other tools. Run \`gog ${service} --help\` for the full list of subcommands, or \`gog ${service} <subcommand> --help\` for flags on a specific subcommand.`;
|
|
35123
|
-
const
|
|
35410
|
+
const restriction = allowedSubcommands ? ` Only these subcommands are available: ${allowedSubcommands.join(", ")}.` : "";
|
|
35411
|
+
const safety = ' Flags that override server safety controls (--readonly, --enable-commands, --disable-commands, --account, --access-token, --home, --client, --gmail-no-send, --no-input) and a bare "--" are refused. Local file paths (--out, --out-dir, --attach, --file, --*-file, @file JSON) must be inside GOG_FILE_ROOTS; subcommands that take a local path positionally (e.g. drive upload) are refused in favour of their dedicated tools.';
|
|
35412
|
+
const description = `${baseDescription}${restriction}${safety}${note ? ` ${note}` : ""}`;
|
|
35124
35413
|
const inputSchema = {
|
|
35125
35414
|
subcommand: external_exports.string().describe(`The gog ${service} subcommand to run, e.g. ${examples}`),
|
|
35126
35415
|
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags")
|
|
@@ -35134,7 +35423,21 @@ function registerRunTool(server, options) {
|
|
|
35134
35423
|
inputSchema: external_exports.object(inputSchema)
|
|
35135
35424
|
}, async (rawArgs) => {
|
|
35136
35425
|
const { subcommand, args, account } = rawArgs;
|
|
35137
|
-
|
|
35426
|
+
try {
|
|
35427
|
+
assertSafeSubcommand(subcommand);
|
|
35428
|
+
assertSafeForwardedArgs(args);
|
|
35429
|
+
if (allowedSubcommands && !allowedSubcommands.includes(subcommand)) {
|
|
35430
|
+
throw new Error(
|
|
35431
|
+
`gog ${service} ${subcommand} is not available through gog_${service}_run. Allowed: ${allowedSubcommands.join(", ")}.`
|
|
35432
|
+
);
|
|
35433
|
+
}
|
|
35434
|
+
const refusal = vet?.(subcommand, args);
|
|
35435
|
+
if (refusal) throw new Error(refusal);
|
|
35436
|
+
assertRunPathsConfined(service, subcommand, args);
|
|
35437
|
+
} catch (err) {
|
|
35438
|
+
return errorResult(errorText(err));
|
|
35439
|
+
}
|
|
35440
|
+
return runOrDiagnose([service, subcommand, ...args], gmailNoSend ? { account, gmailNoSend } : { account });
|
|
35138
35441
|
});
|
|
35139
35442
|
}
|
|
35140
35443
|
function errorText(err) {
|
|
@@ -35255,7 +35558,13 @@ function formatAuthHealth(raw, now) {
|
|
|
35255
35558
|
return accounts.map((a) => formatOneAccountHealth(a, now)).join("\n\n");
|
|
35256
35559
|
}
|
|
35257
35560
|
|
|
35561
|
+
// ../gogcli-mcp/src/dispatch-confirmation.ts
|
|
35562
|
+
var confirmTokenParam = external_exports.string().optional().describe(
|
|
35563
|
+
`ONLY for the two-step fallback (client without MCP elicitation, server with GOG_SEND_CONFIRM_FALLBACK=token). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat \u2014 never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.`
|
|
35564
|
+
);
|
|
35565
|
+
|
|
35258
35566
|
// ../gogcli-mcp/src/tools/auth.ts
|
|
35567
|
+
var AUTH_RUN_SUBCOMMANDS = ["list", "status", "services", "remove", "alias"];
|
|
35259
35568
|
function registerAuthToolsWith(server, defaultServices) {
|
|
35260
35569
|
const servicesDescribe = `Services to authorize: "all" or comma-separated list (e.g. "sheets,gmail,calendar"). Default: "${defaultServices}". Prefer the narrowest set you need \u2014 requesting a service whose Google API is not enabled on the OAuth client's project makes Google reject the WHOLE request with invalid_scope.`;
|
|
35261
35570
|
const extraScopesDescribe = "Additional raw OAuth scope URIs to request, comma-separated, on top of the ones `services` implies. Use for scopes no service covers \u2014 e.g. https://www.googleapis.com/auth/bigquery.readonly, required before gog_sheets_datasource_* can read BigQuery-backed Connected Sheets. Leave unset otherwise: an extra scope whose API is not enabled on the OAuth client project makes Google reject the WHOLE authorization with invalid_scope.";
|
|
@@ -35313,7 +35622,7 @@ function registerAuthToolsWith(server, defaultServices) {
|
|
|
35313
35622
|
})
|
|
35314
35623
|
}, async ({ email: email3, services = defaultServices, extraScopes }) => {
|
|
35315
35624
|
try {
|
|
35316
|
-
const args = ["auth", "add", email3, "--services", services];
|
|
35625
|
+
const args = ["auth", "add", pos(email3), "--services", services];
|
|
35317
35626
|
if (extraScopes) args.push(`--extra-scopes=${extraScopes}`, "--force-consent");
|
|
35318
35627
|
return rawTextResult(await run(args, {
|
|
35319
35628
|
interactive: true,
|
|
@@ -35333,7 +35642,7 @@ function registerAuthToolsWith(server, defaultServices) {
|
|
|
35333
35642
|
})
|
|
35334
35643
|
}, async ({ email: email3, services = defaultServices, extraScopes }) => {
|
|
35335
35644
|
try {
|
|
35336
|
-
const args = ["auth", "add", email3, "--remote", "--step", "1", "--services", services, "--force-consent"];
|
|
35645
|
+
const args = ["auth", "add", pos(email3), "--remote", "--step", "1", "--services", services, "--force-consent"];
|
|
35337
35646
|
if (extraScopes) args.push(`--extra-scopes=${extraScopes}`);
|
|
35338
35647
|
return rawTextResult(await run(args, { redactMode: "tokens" }));
|
|
35339
35648
|
} catch (err) {
|
|
@@ -35360,7 +35669,7 @@ function registerAuthToolsWith(server, defaultServices) {
|
|
|
35360
35669
|
const args = [
|
|
35361
35670
|
"auth",
|
|
35362
35671
|
"add",
|
|
35363
|
-
email3,
|
|
35672
|
+
pos(email3),
|
|
35364
35673
|
"--remote",
|
|
35365
35674
|
"--step",
|
|
35366
35675
|
"2",
|
|
@@ -35380,6 +35689,7 @@ function registerAuthToolsWith(server, defaultServices) {
|
|
|
35380
35689
|
service: "auth",
|
|
35381
35690
|
examples: '"remove", "alias", "list"',
|
|
35382
35691
|
omitAccount: true,
|
|
35692
|
+
allowedSubcommands: AUTH_RUN_SUBCOMMANDS,
|
|
35383
35693
|
note: "For browser-based authorization, use gog_auth_add instead."
|
|
35384
35694
|
});
|
|
35385
35695
|
}
|
|
@@ -35429,7 +35739,7 @@ var replySchema = {
|
|
|
35429
35739
|
remove: external_exports.array(external_exports.string()).optional().describe("Remove these recipients from all fields (repeatable) \u2014 e.g. to drop someone from a reply-all."),
|
|
35430
35740
|
subject: external_exports.string().optional().describe('Override reply subject (default: "Re: <original>"). A changed subject starts a NEW Gmail thread.'),
|
|
35431
35741
|
noQuote: external_exports.boolean().optional().describe("Do not include the original message quoted below the reply (default: the original is quoted)"),
|
|
35432
|
-
attach: external_exports.array(external_exports.string()).optional().describe(`File paths to attach (repeatable), resolved ON THE GOG SERVER's filesystem \u2014 NOT this client's. Only usable when gog runs on the same machine you do (local stdio); on a hosted deployment (e.g. mcp-host) these paths do not exist and the call fails with "no such file or directory" \u2014 use attachInline there. Read on the server, base64-encoded with a MIME type inferred from the extension.`),
|
|
35742
|
+
attach: external_exports.array(external_exports.string()).optional().describe(`File paths to attach (repeatable), resolved ON THE GOG SERVER's filesystem \u2014 NOT this client's. Only usable when gog runs on the same machine you do (local stdio); on a hosted deployment (e.g. mcp-host) these paths do not exist and the call fails with "no such file or directory" \u2014 use attachInline there. Read on the server, base64-encoded with a MIME type inferred from the extension. Must be inside the server's GOG_FILE_ROOTS directories (default ~/gogcli-mcp-files).`),
|
|
35433
35743
|
attachInline: attachInlineParam,
|
|
35434
35744
|
from: external_exports.string().optional().describe("Send from this email address (must be a verified send-as alias)"),
|
|
35435
35745
|
autoFromAddressedAlias: external_exports.boolean().optional().describe("When from is omitted, send from the verified send-as alias the original message was addressed TO, instead of the account's primary address \u2014 so a reply to mail sent to an alias goes back out from that alias. Ignored when from is set."),
|
|
@@ -35438,7 +35748,7 @@ var replySchema = {
|
|
|
35438
35748
|
signatureFile: external_exports.string().optional().describe("Append a local signature file (plain text or HTML), read on the gog server"),
|
|
35439
35749
|
account: accountParam
|
|
35440
35750
|
};
|
|
35441
|
-
var sendReplySchema = external_exports.object(replySchema);
|
|
35751
|
+
var sendReplySchema = external_exports.object({ ...replySchema, confirmToken: confirmTokenParam });
|
|
35442
35752
|
|
|
35443
35753
|
// ../gogcli-mcp/src/tools/sheets-a1.ts
|
|
35444
35754
|
function colToLetter(n) {
|
|
@@ -35506,7 +35816,7 @@ function registerSheetsTools(server) {
|
|
|
35506
35816
|
account: accountParam
|
|
35507
35817
|
})
|
|
35508
35818
|
}, async ({ spreadsheetId, range, account }) => {
|
|
35509
|
-
return runOrDiagnose(["sheets", "get", spreadsheetId, range], { account });
|
|
35819
|
+
return runOrDiagnose(["sheets", "get", pos(spreadsheetId), pos(range)], { account });
|
|
35510
35820
|
});
|
|
35511
35821
|
server.registerTool("gog_sheets_update", {
|
|
35512
35822
|
description: 'Write values to a Google Sheets range, overwriting existing content. Values may be strings, numbers, booleans, or null. Strings starting with "=" are interpreted as formulas (e.g. "=SUM(A1:A10)").',
|
|
@@ -35526,7 +35836,7 @@ function registerSheetsTools(server) {
|
|
|
35526
35836
|
const readRange = expandAnchorRange(range, values.length, cols);
|
|
35527
35837
|
let existing;
|
|
35528
35838
|
try {
|
|
35529
|
-
existing = await run(["sheets", "get", spreadsheetId, readRange], { account });
|
|
35839
|
+
existing = await run(["sheets", "get", pos(spreadsheetId), pos(readRange)], { account });
|
|
35530
35840
|
} catch (err) {
|
|
35531
35841
|
return diagnose(err);
|
|
35532
35842
|
}
|
|
@@ -35538,7 +35848,7 @@ function registerSheetsTools(server) {
|
|
|
35538
35848
|
);
|
|
35539
35849
|
}
|
|
35540
35850
|
}
|
|
35541
|
-
const args = ["sheets", "update", spreadsheetId, range, `--values-json=${JSON.stringify(values)}`];
|
|
35851
|
+
const args = ["sheets", "update", pos(spreadsheetId), pos(range), `--values-json=${JSON.stringify(values)}`];
|
|
35542
35852
|
if (dry_run) args.push("--dry-run");
|
|
35543
35853
|
if (fail_on_formula_error) args.push("--fail-on-formula-error");
|
|
35544
35854
|
return runOrDiagnose(args, { account });
|
|
@@ -35554,7 +35864,7 @@ function registerSheetsTools(server) {
|
|
|
35554
35864
|
account: accountParam
|
|
35555
35865
|
})
|
|
35556
35866
|
}, async ({ spreadsheetId, range, values, account, dry_run }) => {
|
|
35557
|
-
const args = ["sheets", "append", spreadsheetId, range, `--values-json=${JSON.stringify(values)}`];
|
|
35867
|
+
const args = ["sheets", "append", pos(spreadsheetId), pos(range), `--values-json=${JSON.stringify(values)}`];
|
|
35558
35868
|
if (dry_run) args.push("--dry-run");
|
|
35559
35869
|
return runOrDiagnose(args, { account });
|
|
35560
35870
|
});
|
|
@@ -35568,7 +35878,7 @@ function registerSheetsTools(server) {
|
|
|
35568
35878
|
account: accountParam
|
|
35569
35879
|
})
|
|
35570
35880
|
}, async ({ spreadsheetId, range, account, dry_run }) => {
|
|
35571
|
-
const args = ["sheets", "clear", spreadsheetId, range];
|
|
35881
|
+
const args = ["sheets", "clear", pos(spreadsheetId), pos(range)];
|
|
35572
35882
|
if (dry_run) args.push("--dry-run");
|
|
35573
35883
|
return runOrDiagnose(args, { account });
|
|
35574
35884
|
});
|
|
@@ -35580,7 +35890,7 @@ function registerSheetsTools(server) {
|
|
|
35580
35890
|
account: accountParam
|
|
35581
35891
|
})
|
|
35582
35892
|
}, async ({ spreadsheetId, account }) => {
|
|
35583
|
-
return runOrDiagnose(["sheets", "metadata", spreadsheetId], { account });
|
|
35893
|
+
return runOrDiagnose(["sheets", "metadata", pos(spreadsheetId)], { account });
|
|
35584
35894
|
});
|
|
35585
35895
|
server.registerTool("gog_sheets_create", {
|
|
35586
35896
|
description: "Create a new Google Spreadsheet. Returns JSON with the new spreadsheetId and URL.",
|
|
@@ -35590,7 +35900,7 @@ function registerSheetsTools(server) {
|
|
|
35590
35900
|
account: accountParam
|
|
35591
35901
|
})
|
|
35592
35902
|
}, async ({ title, account }) => {
|
|
35593
|
-
return runOrDiagnose(["sheets", "create", title], { account });
|
|
35903
|
+
return runOrDiagnose(["sheets", "create", pos(title)], { account });
|
|
35594
35904
|
});
|
|
35595
35905
|
server.registerTool("gog_sheets_find_replace", {
|
|
35596
35906
|
description: "Find and replace text across an entire Google Spreadsheet.",
|
|
@@ -35602,16 +35912,16 @@ function registerSheetsTools(server) {
|
|
|
35602
35912
|
account: accountParam
|
|
35603
35913
|
})
|
|
35604
35914
|
}, async ({ spreadsheetId, find, replace, account }) => {
|
|
35605
|
-
return runOrDiagnose(["sheets", "find-replace", spreadsheetId, find, replace], { account });
|
|
35915
|
+
return runOrDiagnose(["sheets", "find-replace", pos(spreadsheetId), pos(find), pos(replace)], { account });
|
|
35606
35916
|
});
|
|
35607
35917
|
registerRunTool(server, { service: "sheets", examples: '"freeze", "add-tab", "rename-tab"' });
|
|
35608
35918
|
}
|
|
35609
35919
|
|
|
35610
35920
|
// ../gogcli-mcp/src/server.ts
|
|
35611
|
-
var VERSION = true ? "4.
|
|
35921
|
+
var VERSION = true ? "4.4.0" : "0.0.0";
|
|
35612
35922
|
|
|
35613
35923
|
// ../gogcli-mcp/src/bootstrap-auth.ts
|
|
35614
|
-
import { join as
|
|
35924
|
+
import { join as join5 } from "node:path";
|
|
35615
35925
|
var AUTH_BOOTSTRAP_MARKER = "auth-bootstrap.sha256";
|
|
35616
35926
|
var VARS = ["GOG_CLIENT_ID", "GOG_CLIENT_SECRET", "GOG_REFRESH_TOKEN", "GOG_ACCOUNT"];
|
|
35617
35927
|
var log = (line) => {
|
|
@@ -35648,8 +35958,8 @@ async function bootstrapGogAuth(env = process.env, options = {}) {
|
|
|
35648
35958
|
const { createHash } = await import("node:crypto");
|
|
35649
35959
|
const { mkdir, readFile, writeFile, chmod } = await import("node:fs/promises");
|
|
35650
35960
|
const home = options.home ?? (await import("node:os")).homedir();
|
|
35651
|
-
const dir =
|
|
35652
|
-
const marker =
|
|
35961
|
+
const dir = join5(home, ".gogcli-mcp");
|
|
35962
|
+
const marker = join5(dir, AUTH_BOOTSTRAP_MARKER);
|
|
35653
35963
|
const fingerprint = createHash("sha256").update(values.join("\0")).digest("hex");
|
|
35654
35964
|
const previous = await readFile(marker, "utf8").catch(() => void 0);
|
|
35655
35965
|
if (previous === fingerprint && await accountListed(account, spawner)) return "present";
|
|
@@ -35700,7 +36010,7 @@ function hexToRgb(hex3) {
|
|
|
35700
36010
|
}
|
|
35701
36011
|
async function checkDateFormatTarget(spreadsheetId, range, account) {
|
|
35702
36012
|
const peek = await runOrDiagnose(
|
|
35703
|
-
["sheets", "get", spreadsheetId, range, "--render=UNFORMATTED_VALUE"],
|
|
36013
|
+
["sheets", "get", pos(spreadsheetId), pos(range), "--render=UNFORMATTED_VALUE"],
|
|
35704
36014
|
{ account }
|
|
35705
36015
|
);
|
|
35706
36016
|
let parsed;
|
|
@@ -35735,7 +36045,7 @@ function registerExtraSheetsTools(server) {
|
|
|
35735
36045
|
})
|
|
35736
36046
|
}, async ({ spreadsheetId, account }) => {
|
|
35737
36047
|
return runOrDiagnose(
|
|
35738
|
-
["sheets", "metadata", spreadsheetId, "--select=sheets.properties.sheetId,sheets.properties.title,sheets.properties.index,sheets.properties.gridProperties"],
|
|
36048
|
+
["sheets", "metadata", pos(spreadsheetId), "--select=sheets.properties.sheetId,sheets.properties.title,sheets.properties.index,sheets.properties.gridProperties"],
|
|
35739
36049
|
{ account }
|
|
35740
36050
|
);
|
|
35741
36051
|
});
|
|
@@ -35748,7 +36058,7 @@ function registerExtraSheetsTools(server) {
|
|
|
35748
36058
|
account: accountParam
|
|
35749
36059
|
})
|
|
35750
36060
|
}, async ({ spreadsheetId, tabName, account }) => {
|
|
35751
|
-
return runOrDiagnose(["sheets", "add-tab", spreadsheetId, tabName], { account });
|
|
36061
|
+
return runOrDiagnose(["sheets", "add-tab", pos(spreadsheetId), pos(tabName)], { account });
|
|
35752
36062
|
});
|
|
35753
36063
|
server.registerTool("gog_sheets_delete_tab", {
|
|
35754
36064
|
description: "Delete a sheet tab from a spreadsheet.",
|
|
@@ -35759,7 +36069,7 @@ function registerExtraSheetsTools(server) {
|
|
|
35759
36069
|
account: accountParam
|
|
35760
36070
|
})
|
|
35761
36071
|
}, async ({ spreadsheetId, tabName, account }) => {
|
|
35762
|
-
return runOrDiagnose(["sheets", "delete-tab", spreadsheetId, tabName, "--force"], { account });
|
|
36072
|
+
return runOrDiagnose(["sheets", "delete-tab", pos(spreadsheetId), pos(tabName), "--force"], { account });
|
|
35763
36073
|
});
|
|
35764
36074
|
server.registerTool("gog_sheets_rename_tab", {
|
|
35765
36075
|
description: "Rename a sheet tab.",
|
|
@@ -35771,7 +36081,7 @@ function registerExtraSheetsTools(server) {
|
|
|
35771
36081
|
account: accountParam
|
|
35772
36082
|
})
|
|
35773
36083
|
}, async ({ spreadsheetId, oldName, newName, account }) => {
|
|
35774
|
-
return runOrDiagnose(["sheets", "rename-tab", spreadsheetId, oldName, newName], { account });
|
|
36084
|
+
return runOrDiagnose(["sheets", "rename-tab", pos(spreadsheetId), pos(oldName), pos(newName)], { account });
|
|
35775
36085
|
});
|
|
35776
36086
|
server.registerTool("gog_sheets_copy", {
|
|
35777
36087
|
description: "Copy a spreadsheet to a new spreadsheet with the given title.",
|
|
@@ -35783,13 +36093,14 @@ function registerExtraSheetsTools(server) {
|
|
|
35783
36093
|
account: accountParam
|
|
35784
36094
|
})
|
|
35785
36095
|
}, async ({ spreadsheetId, title, parent, account }) => {
|
|
35786
|
-
const args = ["sheets", "copy", spreadsheetId, title];
|
|
36096
|
+
const args = ["sheets", "copy", pos(spreadsheetId), pos(title)];
|
|
35787
36097
|
if (parent) args.push(`--parent=${parent}`);
|
|
35788
36098
|
return runOrDiagnose(args, { account });
|
|
35789
36099
|
});
|
|
35790
36100
|
server.registerTool("gog_sheets_export", {
|
|
35791
36101
|
description: "Export a spreadsheet as CSV, TSV, or PDF.",
|
|
35792
|
-
|
|
36102
|
+
// Writes a file on the gog host and can overwrite one: not read-only (audit SEC-4).
|
|
36103
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
35793
36104
|
inputSchema: external_exports.object({
|
|
35794
36105
|
spreadsheetId: external_exports.string().describe("Spreadsheet ID"),
|
|
35795
36106
|
format: external_exports.string().optional().describe("Export format: csv, tsv, pdf (default: csv)"),
|
|
@@ -35798,7 +36109,8 @@ function registerExtraSheetsTools(server) {
|
|
|
35798
36109
|
account: accountParam
|
|
35799
36110
|
})
|
|
35800
36111
|
}, async ({ spreadsheetId, format, out, overwrite, account }) => {
|
|
35801
|
-
|
|
36112
|
+
if (out) confinePath(out, "out");
|
|
36113
|
+
const args = ["sheets", "export", pos(spreadsheetId)];
|
|
35802
36114
|
if (format) args.push(`--format=${format}`);
|
|
35803
36115
|
if (out) args.push(`--out=${out}`);
|
|
35804
36116
|
if (overwrite) args.push("--overwrite");
|
|
@@ -35815,7 +36127,7 @@ function registerExtraSheetsTools(server) {
|
|
|
35815
36127
|
account: accountParam
|
|
35816
36128
|
})
|
|
35817
36129
|
}, async ({ spreadsheetId, rows, cols, sheet, account }) => {
|
|
35818
|
-
const args = ["sheets", "freeze", spreadsheetId];
|
|
36130
|
+
const args = ["sheets", "freeze", pos(spreadsheetId)];
|
|
35819
36131
|
if (rows !== void 0) args.push(`--rows=${rows}`);
|
|
35820
36132
|
if (cols !== void 0) args.push(`--cols=${cols}`);
|
|
35821
36133
|
if (sheet) args.push(`--sheet=${sheet}`);
|
|
@@ -35836,7 +36148,7 @@ function registerExtraSheetsTools(server) {
|
|
|
35836
36148
|
})
|
|
35837
36149
|
}, async ({ spreadsheetId, sheet, dimension, start, count, after, inheritFromBefore, account }) => {
|
|
35838
36150
|
const effectiveStart = start + 1;
|
|
35839
|
-
const args = ["sheets", "insert", spreadsheetId, sheet, dimension, String(effectiveStart)];
|
|
36151
|
+
const args = ["sheets", "insert", pos(spreadsheetId), pos(sheet), pos(dimension), pos(String(effectiveStart))];
|
|
35840
36152
|
if (count !== void 0) args.push(`--count=${count}`);
|
|
35841
36153
|
if (after) args.push("--after");
|
|
35842
36154
|
if (inheritFromBefore !== void 0) args.push(`--inherit-from-before=${inheritFromBefore}`);
|
|
@@ -35854,7 +36166,7 @@ function registerExtraSheetsTools(server) {
|
|
|
35854
36166
|
account: accountParam
|
|
35855
36167
|
})
|
|
35856
36168
|
}, async ({ spreadsheetId, source, dest, type, transpose, account }) => {
|
|
35857
|
-
const args = ["sheets", "copy-paste", spreadsheetId, source, dest];
|
|
36169
|
+
const args = ["sheets", "copy-paste", pos(spreadsheetId), pos(source), pos(dest)];
|
|
35858
36170
|
if (type) args.push(`--type=${type}`);
|
|
35859
36171
|
if (transpose) args.push("--transpose");
|
|
35860
36172
|
return runOrDiagnose(args, { account });
|
|
@@ -35869,7 +36181,7 @@ function registerExtraSheetsTools(server) {
|
|
|
35869
36181
|
account: accountParam
|
|
35870
36182
|
})
|
|
35871
36183
|
}, async ({ spreadsheetId, range, type, account }) => {
|
|
35872
|
-
const args = ["sheets", "merge", spreadsheetId, range];
|
|
36184
|
+
const args = ["sheets", "merge", pos(spreadsheetId), pos(range)];
|
|
35873
36185
|
if (type) args.push(`--type=${type}`);
|
|
35874
36186
|
return runOrDiagnose(args, { account });
|
|
35875
36187
|
});
|
|
@@ -35882,7 +36194,7 @@ function registerExtraSheetsTools(server) {
|
|
|
35882
36194
|
account: accountParam
|
|
35883
36195
|
})
|
|
35884
36196
|
}, async ({ spreadsheetId, range, account }) => {
|
|
35885
|
-
return runOrDiagnose(["sheets", "unmerge", spreadsheetId, range], { account });
|
|
36197
|
+
return runOrDiagnose(["sheets", "unmerge", pos(spreadsheetId), pos(range)], { account });
|
|
35886
36198
|
});
|
|
35887
36199
|
server.registerTool("gog_sheets_format", {
|
|
35888
36200
|
description: "Apply cell formatting to a range. The named flags (bold, italic, backgroundColor, etc.) compose into a Sheets API CellFormat \u2014 use them for the 90% case. For full API control, pass formatJson + formatFields (Sheets CellFormat + field mask) directly.",
|
|
@@ -35968,7 +36280,7 @@ function registerExtraSheetsTools(server) {
|
|
|
35968
36280
|
formatJson = JSON.stringify(cellFormat);
|
|
35969
36281
|
if (!formatFields) formatFields = fields.join(",");
|
|
35970
36282
|
}
|
|
35971
|
-
const args = ["sheets", "format", a.spreadsheetId, a.range, `--format-json=${formatJson}`];
|
|
36283
|
+
const args = ["sheets", "format", pos(a.spreadsheetId), pos(a.range), `--format-json=${formatJson}`];
|
|
35972
36284
|
if (formatFields) args.push(`--format-fields=${formatFields}`);
|
|
35973
36285
|
return runOrDiagnose(args, { account: a.account });
|
|
35974
36286
|
});
|
|
@@ -35986,7 +36298,7 @@ function registerExtraSheetsTools(server) {
|
|
|
35986
36298
|
}, async ({ spreadsheetId, range, type, pattern, force, account }) => {
|
|
35987
36299
|
const isDateType = type === "DATE" || type === "DATE_TIME";
|
|
35988
36300
|
const warning = isDateType && !force ? await checkDateFormatTarget(spreadsheetId, range, account) : null;
|
|
35989
|
-
const args = ["sheets", "number-format", spreadsheetId, range];
|
|
36301
|
+
const args = ["sheets", "number-format", pos(spreadsheetId), pos(range)];
|
|
35990
36302
|
if (type) args.push(`--type=${type}`);
|
|
35991
36303
|
if (pattern) args.push(`--pattern=${pattern}`);
|
|
35992
36304
|
const result = await runOrDiagnose(args, { account });
|
|
@@ -36007,7 +36319,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36007
36319
|
account: accountParam
|
|
36008
36320
|
})
|
|
36009
36321
|
}, async ({ spreadsheetId, range, effective, account }) => {
|
|
36010
|
-
const args = ["sheets", "read-format", spreadsheetId, range];
|
|
36322
|
+
const args = ["sheets", "read-format", pos(spreadsheetId), pos(range)];
|
|
36011
36323
|
if (effective) args.push("--effective");
|
|
36012
36324
|
return runOrDiagnose(args, { account });
|
|
36013
36325
|
});
|
|
@@ -36022,7 +36334,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36022
36334
|
account: accountParam
|
|
36023
36335
|
})
|
|
36024
36336
|
}, async ({ spreadsheetId, columns, width, auto, account }) => {
|
|
36025
|
-
const args = ["sheets", "resize-columns", spreadsheetId, columns];
|
|
36337
|
+
const args = ["sheets", "resize-columns", pos(spreadsheetId), pos(columns)];
|
|
36026
36338
|
if (width !== void 0) args.push(`--width=${width}`);
|
|
36027
36339
|
if (auto) args.push("--auto");
|
|
36028
36340
|
return runOrDiagnose(args, { account });
|
|
@@ -36038,7 +36350,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36038
36350
|
account: accountParam
|
|
36039
36351
|
})
|
|
36040
36352
|
}, async ({ spreadsheetId, rows, height, auto, account }) => {
|
|
36041
|
-
const args = ["sheets", "resize-rows", spreadsheetId, rows];
|
|
36353
|
+
const args = ["sheets", "resize-rows", pos(spreadsheetId), pos(rows)];
|
|
36042
36354
|
if (height !== void 0) args.push(`--height=${height}`);
|
|
36043
36355
|
if (auto) args.push("--auto");
|
|
36044
36356
|
return runOrDiagnose(args, { account });
|
|
@@ -36052,7 +36364,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36052
36364
|
account: accountParam
|
|
36053
36365
|
})
|
|
36054
36366
|
}, async ({ spreadsheetId, range, account }) => {
|
|
36055
|
-
return runOrDiagnose(["sheets", "notes", spreadsheetId, range], { account });
|
|
36367
|
+
return runOrDiagnose(["sheets", "notes", pos(spreadsheetId), pos(range)], { account });
|
|
36056
36368
|
});
|
|
36057
36369
|
server.registerTool("gog_sheets_update_note", {
|
|
36058
36370
|
description: "Add, update, or clear a cell note. Pass an empty string to clear the note.",
|
|
@@ -36065,7 +36377,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36065
36377
|
})
|
|
36066
36378
|
}, async ({ spreadsheetId, range, note, account }) => {
|
|
36067
36379
|
return runOrDiagnose(
|
|
36068
|
-
["sheets", "update-note", spreadsheetId, range, payloadArg("note", "note-file", note)],
|
|
36380
|
+
["sheets", "update-note", pos(spreadsheetId), pos(range), payloadArg("note", "note-file", note)],
|
|
36069
36381
|
{ account }
|
|
36070
36382
|
);
|
|
36071
36383
|
});
|
|
@@ -36078,7 +36390,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36078
36390
|
account: accountParam
|
|
36079
36391
|
})
|
|
36080
36392
|
}, async ({ spreadsheetId, range, account }) => {
|
|
36081
|
-
return runOrDiagnose(["sheets", "links", spreadsheetId, range], { account });
|
|
36393
|
+
return runOrDiagnose(["sheets", "links", pos(spreadsheetId), pos(range)], { account });
|
|
36082
36394
|
});
|
|
36083
36395
|
server.registerTool("gog_sheets_links_set", {
|
|
36084
36396
|
description: "Set cell hyperlinks in a Google Sheet. Three modes: (1) single link \u2014 pass cell + url (+ optional text); (2) multi-link cell \u2014 pass cell + runsJson, a JSON array of rich-text runs (a run with an empty uri is plain text); (3) batch \u2014 pass cellsJson, a JSON array of {cell,url,text} or {cell,runs:[...]} objects written in one request.",
|
|
@@ -36093,10 +36405,11 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36093
36405
|
account: accountParam
|
|
36094
36406
|
})
|
|
36095
36407
|
}, async ({ spreadsheetId, cell, url: url2, text, runsJson, cellsJson, account }) => {
|
|
36096
|
-
|
|
36097
|
-
|
|
36098
|
-
if (
|
|
36099
|
-
if (
|
|
36408
|
+
if (cellsJson) confineAtFile(cellsJson, "cellsJson");
|
|
36409
|
+
const args = ["sheets", "links", "set", pos(spreadsheetId)];
|
|
36410
|
+
if (cell) args.push(pos(cell));
|
|
36411
|
+
if (url2) args.push(pos(url2));
|
|
36412
|
+
if (text) args.push(pos(text));
|
|
36100
36413
|
if (runsJson) args.push(`--runs-json=${runsJson}`);
|
|
36101
36414
|
if (cellsJson) args.push(`--cells-json=${cellsJson}`);
|
|
36102
36415
|
return runOrDiagnose(args, { account });
|
|
@@ -36110,7 +36423,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36110
36423
|
account: accountParam
|
|
36111
36424
|
})
|
|
36112
36425
|
}, async ({ spreadsheetId, range, account }) => {
|
|
36113
|
-
return runOrDiagnose(["sheets", "validation", "get", spreadsheetId, range], { account });
|
|
36426
|
+
return runOrDiagnose(["sheets", "validation", "get", pos(spreadsheetId), pos(range)], { account });
|
|
36114
36427
|
});
|
|
36115
36428
|
server.registerTool("gog_sheets_validation_set", {
|
|
36116
36429
|
description: "Set a data-validation rule on a range \u2014 dropdowns (ONE_OF_LIST / ONE_OF_RANGE), checkboxes (BOOLEAN), number/date conditions, or custom formulas. Overwrites any existing rule on the range. Repeat values for list entries or between-bounds.",
|
|
@@ -36127,7 +36440,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36127
36440
|
account: accountParam
|
|
36128
36441
|
})
|
|
36129
36442
|
}, async ({ spreadsheetId, range, type, values, strict, inputMessage, showCustomUi, filteredRowsIncluded, account }) => {
|
|
36130
|
-
const args = ["sheets", "validation", "set", spreadsheetId, range, `--type=${type}`];
|
|
36443
|
+
const args = ["sheets", "validation", "set", pos(spreadsheetId), pos(range), `--type=${type}`];
|
|
36131
36444
|
if (values) for (const v of values) args.push(`--value=${v}`);
|
|
36132
36445
|
if (strict) args.push("--strict");
|
|
36133
36446
|
if (inputMessage) args.push(`--input-message=${inputMessage}`);
|
|
@@ -36145,7 +36458,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36145
36458
|
account: accountParam
|
|
36146
36459
|
})
|
|
36147
36460
|
}, async ({ spreadsheetId, range, filteredRowsIncluded, account }) => {
|
|
36148
|
-
const args = ["sheets", "validation", "clear", spreadsheetId, range];
|
|
36461
|
+
const args = ["sheets", "validation", "clear", pos(spreadsheetId), pos(range)];
|
|
36149
36462
|
if (filteredRowsIncluded) args.push("--filtered-rows-included");
|
|
36150
36463
|
return runOrDiagnose(args, { account });
|
|
36151
36464
|
});
|
|
@@ -36161,7 +36474,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36161
36474
|
account: accountParam
|
|
36162
36475
|
})
|
|
36163
36476
|
}, async ({ spreadsheetId, rangeOrSheet, dimension, start, end, account }) => {
|
|
36164
|
-
const args = ["sheets", "delete-dimension", spreadsheetId, rangeOrSheet, `--dimension=${dimension}`];
|
|
36477
|
+
const args = ["sheets", "delete-dimension", pos(spreadsheetId), pos(rangeOrSheet), `--dimension=${dimension}`];
|
|
36165
36478
|
if (start !== void 0) args.push(`--start=${start}`);
|
|
36166
36479
|
if (end !== void 0) args.push(`--end=${end}`);
|
|
36167
36480
|
args.push("--force");
|
|
@@ -36175,7 +36488,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36175
36488
|
account: accountParam
|
|
36176
36489
|
})
|
|
36177
36490
|
}, async ({ spreadsheetId, account }) => {
|
|
36178
|
-
return runOrDiagnose(["sheets", "named-ranges", "list", spreadsheetId], { account });
|
|
36491
|
+
return runOrDiagnose(["sheets", "named-ranges", "list", pos(spreadsheetId)], { account });
|
|
36179
36492
|
});
|
|
36180
36493
|
server.registerTool("gog_sheets_named_ranges_get", {
|
|
36181
36494
|
description: "Get a named range by name or ID.",
|
|
@@ -36186,7 +36499,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36186
36499
|
account: accountParam
|
|
36187
36500
|
})
|
|
36188
36501
|
}, async ({ spreadsheetId, nameOrId, account }) => {
|
|
36189
|
-
return runOrDiagnose(["sheets", "named-ranges", "get", spreadsheetId, nameOrId], { account });
|
|
36502
|
+
return runOrDiagnose(["sheets", "named-ranges", "get", pos(spreadsheetId), pos(nameOrId)], { account });
|
|
36190
36503
|
});
|
|
36191
36504
|
server.registerTool("gog_sheets_named_ranges_add", {
|
|
36192
36505
|
description: "Create a new named range.",
|
|
@@ -36198,7 +36511,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36198
36511
|
account: accountParam
|
|
36199
36512
|
})
|
|
36200
36513
|
}, async ({ spreadsheetId, name, range, account }) => {
|
|
36201
|
-
return runOrDiagnose(["sheets", "named-ranges", "add", spreadsheetId, name, range], { account });
|
|
36514
|
+
return runOrDiagnose(["sheets", "named-ranges", "add", pos(spreadsheetId), pos(name), pos(range)], { account });
|
|
36202
36515
|
});
|
|
36203
36516
|
server.registerTool("gog_sheets_named_ranges_update", {
|
|
36204
36517
|
description: "Update a named range (change its name, range, or both).",
|
|
@@ -36211,7 +36524,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36211
36524
|
account: accountParam
|
|
36212
36525
|
})
|
|
36213
36526
|
}, async ({ spreadsheetId, nameOrId, name, range, account }) => {
|
|
36214
|
-
const args = ["sheets", "named-ranges", "update", spreadsheetId, nameOrId];
|
|
36527
|
+
const args = ["sheets", "named-ranges", "update", pos(spreadsheetId), pos(nameOrId)];
|
|
36215
36528
|
if (name) args.push(`--name=${name}`);
|
|
36216
36529
|
if (range) args.push(`--range=${range}`);
|
|
36217
36530
|
return runOrDiagnose(args, { account });
|
|
@@ -36225,7 +36538,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36225
36538
|
account: accountParam
|
|
36226
36539
|
})
|
|
36227
36540
|
}, async ({ spreadsheetId, nameOrId, account }) => {
|
|
36228
|
-
return runOrDiagnose(["sheets", "named-ranges", "delete", spreadsheetId, nameOrId], { account });
|
|
36541
|
+
return runOrDiagnose(["sheets", "named-ranges", "delete", pos(spreadsheetId), pos(nameOrId)], { account });
|
|
36229
36542
|
});
|
|
36230
36543
|
server.registerTool("gog_sheets_batch_update", {
|
|
36231
36544
|
description: `Update values in multiple ranges with one Sheets API request. dataJson is a JSON array of {range, values} objects \u2014 pass it inline as a literal JSON string. Atomic \u2014 either all ranges update or none do. (The CLI also accepts "@/path/to/file.json", but that file is read on the gog server's filesystem, not the caller's, so inline JSON is the right form for remote MCP callers.)`,
|
|
@@ -36240,7 +36553,8 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36240
36553
|
account: accountParam
|
|
36241
36554
|
})
|
|
36242
36555
|
}, async ({ spreadsheetId, dataJson, input: input2, includeValuesInResponse, responseRender, responseDateTimeRender, account }) => {
|
|
36243
|
-
|
|
36556
|
+
confineAtFile(dataJson, "dataJson");
|
|
36557
|
+
const args = ["sheets", "batch-update", pos(spreadsheetId), `--data-json=${dataJson}`];
|
|
36244
36558
|
if (input2) args.push(`--input=${input2}`);
|
|
36245
36559
|
if (includeValuesInResponse) args.push("--include-values-in-response");
|
|
36246
36560
|
if (responseRender) args.push(`--response-render=${responseRender}`);
|
|
@@ -36258,7 +36572,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36258
36572
|
})
|
|
36259
36573
|
}, async ({ spreadsheetId, tab, to, account }) => {
|
|
36260
36574
|
return runOrDiagnose(
|
|
36261
|
-
["sheets", "reorder-tab", spreadsheetId, `--tab=${tab}`, `--to=${to}`],
|
|
36575
|
+
["sheets", "reorder-tab", pos(spreadsheetId), `--tab=${tab}`, `--to=${to}`],
|
|
36262
36576
|
{ account }
|
|
36263
36577
|
);
|
|
36264
36578
|
});
|
|
@@ -36270,7 +36584,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36270
36584
|
account: accountParam
|
|
36271
36585
|
})
|
|
36272
36586
|
}, async ({ spreadsheetId, account }) => {
|
|
36273
|
-
return runOrDiagnose(["sheets", "chart", "list", spreadsheetId], { account });
|
|
36587
|
+
return runOrDiagnose(["sheets", "chart", "list", pos(spreadsheetId)], { account });
|
|
36274
36588
|
});
|
|
36275
36589
|
server.registerTool("gog_sheets_chart_get", {
|
|
36276
36590
|
description: "Get the full definition (spec + position) of a single chart by its numeric chart ID.",
|
|
@@ -36281,7 +36595,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36281
36595
|
account: accountParam
|
|
36282
36596
|
})
|
|
36283
36597
|
}, async ({ spreadsheetId, chartId, account }) => {
|
|
36284
|
-
return runOrDiagnose(["sheets", "chart", "get", spreadsheetId, chartId], { account });
|
|
36598
|
+
return runOrDiagnose(["sheets", "chart", "get", pos(spreadsheetId), pos(chartId)], { account });
|
|
36285
36599
|
});
|
|
36286
36600
|
server.registerTool("gog_sheets_chart_create", {
|
|
36287
36601
|
description: "Create an embedded chart from a JSON spec. specJson is a Sheets API ChartSpec (or full EmbeddedChart) \u2014 inline or @/path/to/file.json. Anchor the chart with sheet + anchor (A1 cell), and optionally size it with width/height pixels.",
|
|
@@ -36296,7 +36610,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36296
36610
|
account: accountParam
|
|
36297
36611
|
})
|
|
36298
36612
|
}, async ({ spreadsheetId, specJson, sheet, anchor: anchor2, width, height, account }) => {
|
|
36299
|
-
const args = ["sheets", "chart", "create", spreadsheetId, `--spec-json=${specJson}`];
|
|
36613
|
+
const args = ["sheets", "chart", "create", pos(spreadsheetId), `--spec-json=${specJson}`];
|
|
36300
36614
|
if (sheet) args.push(`--sheet=${sheet}`);
|
|
36301
36615
|
if (anchor2) args.push(`--anchor=${anchor2}`);
|
|
36302
36616
|
if (width !== void 0) args.push(`--width=${width}`);
|
|
@@ -36314,7 +36628,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36314
36628
|
})
|
|
36315
36629
|
}, async ({ spreadsheetId, chartId, specJson, account }) => {
|
|
36316
36630
|
return runOrDiagnose(
|
|
36317
|
-
["sheets", "chart", "update", spreadsheetId, chartId, `--spec-json=${specJson}`],
|
|
36631
|
+
["sheets", "chart", "update", pos(spreadsheetId), pos(chartId), `--spec-json=${specJson}`],
|
|
36318
36632
|
{ account }
|
|
36319
36633
|
);
|
|
36320
36634
|
});
|
|
@@ -36327,7 +36641,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36327
36641
|
account: accountParam
|
|
36328
36642
|
})
|
|
36329
36643
|
}, async ({ spreadsheetId, chartId, account }) => {
|
|
36330
|
-
return runOrDiagnose(["sheets", "chart", "delete", spreadsheetId, chartId, "--force"], { account });
|
|
36644
|
+
return runOrDiagnose(["sheets", "chart", "delete", pos(spreadsheetId), pos(chartId), "--force"], { account });
|
|
36331
36645
|
});
|
|
36332
36646
|
server.registerTool("gog_sheets_table_list", {
|
|
36333
36647
|
description: "List Google Sheets tables in a spreadsheet (tableId, name, range).",
|
|
@@ -36337,7 +36651,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36337
36651
|
account: accountParam
|
|
36338
36652
|
})
|
|
36339
36653
|
}, async ({ spreadsheetId, account }) => {
|
|
36340
|
-
return runOrDiagnose(["sheets", "table", "list", spreadsheetId], { account });
|
|
36654
|
+
return runOrDiagnose(["sheets", "table", "list", pos(spreadsheetId)], { account });
|
|
36341
36655
|
});
|
|
36342
36656
|
server.registerTool("gog_sheets_table_get", {
|
|
36343
36657
|
description: "Get a single Google Sheets table (definition + columns) by its table ID.",
|
|
@@ -36348,7 +36662,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36348
36662
|
account: accountParam
|
|
36349
36663
|
})
|
|
36350
36664
|
}, async ({ spreadsheetId, tableId, account }) => {
|
|
36351
|
-
return runOrDiagnose(["sheets", "table", "get", spreadsheetId, tableId], { account });
|
|
36665
|
+
return runOrDiagnose(["sheets", "table", "get", pos(spreadsheetId), pos(tableId)], { account });
|
|
36352
36666
|
});
|
|
36353
36667
|
server.registerTool("gog_sheets_table_create", {
|
|
36354
36668
|
description: "Create a Google Sheets table over a range. columnsJson is a JSON array of column definitions (each {columnName, columnType?}); valid columnType values: TEXT, DOUBLE, BOOLEAN, DATE, DROPDOWN. Inline JSON or @/path/to/file.json.",
|
|
@@ -36362,7 +36676,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36362
36676
|
})
|
|
36363
36677
|
}, async ({ spreadsheetId, range, name, columnsJson, account }) => {
|
|
36364
36678
|
return runOrDiagnose(
|
|
36365
|
-
["sheets", "table", "create", spreadsheetId, range, `--name=${name}`, `--columns-json=${columnsJson}`],
|
|
36679
|
+
["sheets", "table", "create", pos(spreadsheetId), pos(range), `--name=${name}`, `--columns-json=${columnsJson}`],
|
|
36366
36680
|
{ account }
|
|
36367
36681
|
);
|
|
36368
36682
|
});
|
|
@@ -36377,7 +36691,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36377
36691
|
account: accountParam
|
|
36378
36692
|
})
|
|
36379
36693
|
}, async ({ spreadsheetId, tableId, valuesJson, input: input2, account }) => {
|
|
36380
|
-
const args = ["sheets", "table", "append", spreadsheetId, tableId, `--values-json=${valuesJson}`];
|
|
36694
|
+
const args = ["sheets", "table", "append", pos(spreadsheetId), pos(tableId), `--values-json=${valuesJson}`];
|
|
36381
36695
|
if (input2) args.push(`--input=${input2}`);
|
|
36382
36696
|
return runOrDiagnose(args, { account });
|
|
36383
36697
|
});
|
|
@@ -36390,7 +36704,7 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36390
36704
|
account: accountParam
|
|
36391
36705
|
})
|
|
36392
36706
|
}, async ({ spreadsheetId, tableId, account }) => {
|
|
36393
|
-
return runOrDiagnose(["sheets", "table", "clear", spreadsheetId, tableId, "--force"], { account });
|
|
36707
|
+
return runOrDiagnose(["sheets", "table", "clear", pos(spreadsheetId), pos(tableId), "--force"], { account });
|
|
36394
36708
|
});
|
|
36395
36709
|
server.registerTool("gog_sheets_table_delete", {
|
|
36396
36710
|
description: "Delete a Google Sheets table. WARNING: the underlying `gog`/Sheets behaviour is that deleting a table also DESTROYS every cell value in the table range \u2014 not just the table styling/columns. By default this tool prevents that data loss by emulating the Sheets UI's \"Convert to range\": it reads the table's cells (values AND formulas) first, deletes the table, then restores the data into the now-plain range. Formatting and banding are still lost; data-validation dropdowns are also not restored automatically, but you can snapshot them first with gog_sheets_validation_get and re-apply with gog_sheets_validation_set. Set keep_data=false to delete the table AND wipe its cell data (the raw destructive behaviour). To preserve everything, snapshot the whole spreadsheet first with gog_sheets_snapshot.",
|
|
@@ -36405,27 +36719,27 @@ ${resultText2(result) ?? ""}` }] };
|
|
|
36405
36719
|
})
|
|
36406
36720
|
}, async ({ spreadsheetId, tableId, keep_data = true, account }) => {
|
|
36407
36721
|
if (!keep_data) {
|
|
36408
|
-
return runOrDiagnose(["sheets", "table", "delete", spreadsheetId, tableId, "--discard-data", "--force"], { account });
|
|
36722
|
+
return runOrDiagnose(["sheets", "table", "delete", pos(spreadsheetId), pos(tableId), "--discard-data", "--force"], { account });
|
|
36409
36723
|
}
|
|
36410
36724
|
let range;
|
|
36411
36725
|
let values;
|
|
36412
36726
|
try {
|
|
36413
|
-
const parsed = JSON.parse(await run(["sheets", "table", "get", spreadsheetId, tableId], { account }));
|
|
36727
|
+
const parsed = JSON.parse(await run(["sheets", "table", "get", pos(spreadsheetId), pos(tableId)], { account }));
|
|
36414
36728
|
range = parsed.table?.a1;
|
|
36415
36729
|
if (!range) throw new Error(`could not determine the table's range (no "a1" in table get output) for table ${tableId}`);
|
|
36416
|
-
const read = JSON.parse(await run(["sheets", "get", spreadsheetId, range, "--render=FORMULA"], { account }));
|
|
36730
|
+
const read = JSON.parse(await run(["sheets", "get", pos(spreadsheetId), pos(range), "--render=FORMULA"], { account }));
|
|
36417
36731
|
values = read.values ?? [];
|
|
36418
36732
|
} catch (err) {
|
|
36419
36733
|
return diagnose(err);
|
|
36420
36734
|
}
|
|
36421
36735
|
try {
|
|
36422
|
-
await run(["sheets", "table", "delete", spreadsheetId, tableId, "--discard-data", "--force"], { account });
|
|
36736
|
+
await run(["sheets", "table", "delete", pos(spreadsheetId), pos(tableId), "--discard-data", "--force"], { account });
|
|
36423
36737
|
} catch (err) {
|
|
36424
36738
|
return diagnose(err);
|
|
36425
36739
|
}
|
|
36426
36740
|
if (values.length > 0) {
|
|
36427
36741
|
try {
|
|
36428
|
-
await run(["sheets", "update", spreadsheetId, range, `--values-json=${JSON.stringify(values)}`], { account });
|
|
36742
|
+
await run(["sheets", "update", pos(spreadsheetId), pos(range), `--values-json=${JSON.stringify(values)}`], { account });
|
|
36429
36743
|
} catch (err) {
|
|
36430
36744
|
return rawTextResult(
|
|
36431
36745
|
`Table ${tableId} was deleted, but restoring its data FAILED \u2014 re-apply the values below manually.
|
|
@@ -36448,7 +36762,7 @@ ${errorText(err)}`
|
|
|
36448
36762
|
account: accountParam
|
|
36449
36763
|
})
|
|
36450
36764
|
}, async ({ spreadsheetId, sheet, account }) => {
|
|
36451
|
-
const args = ["sheets", "banding", "list", spreadsheetId];
|
|
36765
|
+
const args = ["sheets", "banding", "list", pos(spreadsheetId)];
|
|
36452
36766
|
if (sheet) args.push(`--sheet=${sheet}`);
|
|
36453
36767
|
return runOrDiagnose(args, { account });
|
|
36454
36768
|
});
|
|
@@ -36463,7 +36777,7 @@ ${errorText(err)}`
|
|
|
36463
36777
|
account: accountParam
|
|
36464
36778
|
})
|
|
36465
36779
|
}, async ({ spreadsheetId, range, rowPropertiesJson, columnPropertiesJson, account }) => {
|
|
36466
|
-
const args = ["sheets", "banding", "set", spreadsheetId, range];
|
|
36780
|
+
const args = ["sheets", "banding", "set", pos(spreadsheetId), pos(range)];
|
|
36467
36781
|
if (rowPropertiesJson) args.push(`--row-properties-json=${rowPropertiesJson}`);
|
|
36468
36782
|
if (columnPropertiesJson) args.push(`--column-properties-json=${columnPropertiesJson}`);
|
|
36469
36783
|
return runOrDiagnose(args, { account });
|
|
@@ -36479,7 +36793,7 @@ ${errorText(err)}`
|
|
|
36479
36793
|
account: accountParam
|
|
36480
36794
|
})
|
|
36481
36795
|
}, async ({ spreadsheetId, id, all, sheet, account }) => {
|
|
36482
|
-
const args = ["sheets", "banding", "clear", spreadsheetId];
|
|
36796
|
+
const args = ["sheets", "banding", "clear", pos(spreadsheetId)];
|
|
36483
36797
|
if (id !== void 0) args.push(`--id=${id}`);
|
|
36484
36798
|
if (all) args.push("--all");
|
|
36485
36799
|
if (sheet) args.push(`--sheet=${sheet}`);
|
|
@@ -36496,7 +36810,7 @@ ${errorText(err)}`
|
|
|
36496
36810
|
account: accountParam
|
|
36497
36811
|
})
|
|
36498
36812
|
}, async ({ spreadsheetId, range, replace, account }) => {
|
|
36499
|
-
const args = ["sheets", "filter", "set", spreadsheetId, range];
|
|
36813
|
+
const args = ["sheets", "filter", "set", pos(spreadsheetId), pos(range)];
|
|
36500
36814
|
if (replace) args.push("--force");
|
|
36501
36815
|
return runOrDiagnose(args, { account });
|
|
36502
36816
|
});
|
|
@@ -36509,7 +36823,7 @@ ${errorText(err)}`
|
|
|
36509
36823
|
account: accountParam
|
|
36510
36824
|
})
|
|
36511
36825
|
}, async ({ spreadsheetId, sheet, account }) => {
|
|
36512
|
-
const args = ["sheets", "conditional-format", "list", spreadsheetId];
|
|
36826
|
+
const args = ["sheets", "conditional-format", "list", pos(spreadsheetId)];
|
|
36513
36827
|
if (sheet) args.push(`--sheet=${sheet}`);
|
|
36514
36828
|
return runOrDiagnose(args, { account });
|
|
36515
36829
|
});
|
|
@@ -36540,7 +36854,7 @@ ${errorText(err)}`
|
|
|
36540
36854
|
account: accountParam
|
|
36541
36855
|
})
|
|
36542
36856
|
}, async ({ spreadsheetId, range, type, formatJson, expr, formatFields, gradientRuleJson, account }) => {
|
|
36543
|
-
const args = ["sheets", "conditional-format", "add", spreadsheetId, range];
|
|
36857
|
+
const args = ["sheets", "conditional-format", "add", pos(spreadsheetId), pos(range)];
|
|
36544
36858
|
if (type) args.push(`--type=${type}`);
|
|
36545
36859
|
if (formatJson !== void 0) args.push(`--format-json=${formatJson}`);
|
|
36546
36860
|
if (expr !== void 0) args.push(`--expr=${expr}`);
|
|
@@ -36559,7 +36873,7 @@ ${errorText(err)}`
|
|
|
36559
36873
|
account: accountParam
|
|
36560
36874
|
})
|
|
36561
36875
|
}, async ({ spreadsheetId, sheet, index, all, account }) => {
|
|
36562
|
-
const args = ["sheets", "conditional-format", "clear", spreadsheetId, `--sheet=${sheet}`];
|
|
36876
|
+
const args = ["sheets", "conditional-format", "clear", pos(spreadsheetId), `--sheet=${sheet}`];
|
|
36563
36877
|
if (index !== void 0) args.push(`--index=${index}`);
|
|
36564
36878
|
if (all) args.push("--all");
|
|
36565
36879
|
args.push("--force");
|
|
@@ -36575,7 +36889,7 @@ ${errorText(err)}`
|
|
|
36575
36889
|
account: accountParam
|
|
36576
36890
|
})
|
|
36577
36891
|
}, async ({ spreadsheetId, name, parent, account }) => {
|
|
36578
|
-
const args = ["drive", "copy", spreadsheetId, name];
|
|
36892
|
+
const args = ["drive", "copy", pos(spreadsheetId), pos(name)];
|
|
36579
36893
|
if (parent) args.push(`--parent=${parent}`);
|
|
36580
36894
|
return runOrDiagnose(args, { account });
|
|
36581
36895
|
});
|
|
@@ -36588,7 +36902,7 @@ ${errorText(err)}`
|
|
|
36588
36902
|
account: accountParam
|
|
36589
36903
|
})
|
|
36590
36904
|
}, async ({ spreadsheetId, account }) => {
|
|
36591
|
-
return runOrDiagnose(["sheets", "datasource", "list", spreadsheetId], { account });
|
|
36905
|
+
return runOrDiagnose(["sheets", "datasource", "list", pos(spreadsheetId)], { account });
|
|
36592
36906
|
});
|
|
36593
36907
|
server.registerTool("gog_sheets_datasource_describe", {
|
|
36594
36908
|
description: "Describe one Connected Sheets data source in full: the complete API DataSource spec (including the BigQuery raw query, which gog_sheets_datasource_list withholds), its sheet properties, its DataExecutionStatus and any refresh schedules. Refreshes are asynchronous and this tool cannot start one \u2014 poll it until state is SUCCEEDED or FAILED, and read the status error text when it is FAILED." + bigQueryScopeNote,
|
|
@@ -36599,7 +36913,7 @@ ${errorText(err)}`
|
|
|
36599
36913
|
account: accountParam
|
|
36600
36914
|
})
|
|
36601
36915
|
}, async ({ spreadsheetId, dataSourceId, account }) => {
|
|
36602
|
-
return runOrDiagnose(["sheets", "datasource", "describe", spreadsheetId, dataSourceId], { account });
|
|
36916
|
+
return runOrDiagnose(["sheets", "datasource", "describe", pos(spreadsheetId), pos(dataSourceId)], { account });
|
|
36603
36917
|
});
|
|
36604
36918
|
server.registerTool("gog_sheets_datasource_table_list", {
|
|
36605
36919
|
description: `List the data-source tables \u2014 "extracts" in the Sheets editor \u2014 anchored in a spreadsheet. A data-source table has NO id of its own in the Sheets API: its definition lives on its top-left cell, so every extract is identified by a sheet-qualified A1 anchor (e.g. "Extracts!B3"). That anchor is what the describe and read tools take. Filter with dataSourceId to see only one source's extracts.` + bigQueryScopeNote,
|
|
@@ -36610,7 +36924,7 @@ ${errorText(err)}`
|
|
|
36610
36924
|
account: accountParam
|
|
36611
36925
|
})
|
|
36612
36926
|
}, async ({ spreadsheetId, dataSourceId, account }) => {
|
|
36613
|
-
const args = ["sheets", "datasource", "table", "list", spreadsheetId];
|
|
36927
|
+
const args = ["sheets", "datasource", "table", "list", pos(spreadsheetId)];
|
|
36614
36928
|
if (dataSourceId) args.push(`--data-source-id=${dataSourceId}`);
|
|
36615
36929
|
return runOrDiagnose(args, { account });
|
|
36616
36930
|
});
|
|
@@ -36623,7 +36937,7 @@ ${errorText(err)}`
|
|
|
36623
36937
|
account: accountParam
|
|
36624
36938
|
})
|
|
36625
36939
|
}, async ({ spreadsheetId, anchor: anchor2, account }) => {
|
|
36626
|
-
return runOrDiagnose(["sheets", "datasource", "table", "describe", spreadsheetId, anchor2], { account });
|
|
36940
|
+
return runOrDiagnose(["sheets", "datasource", "table", "describe", pos(spreadsheetId), pos(anchor2)], { account });
|
|
36627
36941
|
});
|
|
36628
36942
|
server.registerTool("gog_sheets_datasource_table_read", {
|
|
36629
36943
|
description: 'Read the values out of the data-source table (extract) anchored at an A1 cell. Bounded on purpose: at most maxRows data rows (gog default 1000) plus the header row, which is returned separately. The JSON reports "truncated": true when the configured extract can hold more rows than were returned \u2014 treat that exactly like a truncated search, i.e. do not conclude a value is absent from it; raise maxRows or narrow the extract instead. Use render=UNFORMATTED_VALUE for arithmetic (FORMATTED_VALUE returns display strings) or render=FORMULA to see the cell formulas.' + bigQueryScopeNote,
|
|
@@ -36636,7 +36950,7 @@ ${errorText(err)}`
|
|
|
36636
36950
|
account: accountParam
|
|
36637
36951
|
})
|
|
36638
36952
|
}, async ({ spreadsheetId, anchor: anchor2, maxRows, render, account }) => {
|
|
36639
|
-
const args = ["sheets", "datasource", "table", "read", spreadsheetId, anchor2];
|
|
36953
|
+
const args = ["sheets", "datasource", "table", "read", pos(spreadsheetId), pos(anchor2)];
|
|
36640
36954
|
if (maxRows !== void 0) args.push(`--max-rows=${maxRows}`);
|
|
36641
36955
|
if (render) args.push(`--render=${render}`);
|
|
36642
36956
|
return runOrDiagnose(args, { account });
|
|
@@ -36662,7 +36976,7 @@ ${errorText(err)}`
|
|
|
36662
36976
|
if (query === void 0 && !(dataset && table)) {
|
|
36663
36977
|
throw new Error("Pass query, or both --dataset and --table (tableProject alone is not a table).");
|
|
36664
36978
|
}
|
|
36665
|
-
const args = ["sheets", "datasource", "add", spreadsheetId, `--billing-project=${billingProject}`];
|
|
36979
|
+
const args = ["sheets", "datasource", "add", pos(spreadsheetId), `--billing-project=${billingProject}`];
|
|
36666
36980
|
if (query !== void 0) args.push(`--query=${query}`);
|
|
36667
36981
|
if (tableProject) args.push(`--table-project=${tableProject}`);
|
|
36668
36982
|
if (dataset) args.push(`--dataset=${dataset}`);
|
|
@@ -36690,7 +37004,7 @@ ${errorText(err)}`
|
|
|
36690
37004
|
if (billingProject === void 0 && query === void 0 && !tableFlags) {
|
|
36691
37005
|
throw new Error("nothing to update: pass billingProject, query, dataset, table or tableProject.");
|
|
36692
37006
|
}
|
|
36693
|
-
const args = ["sheets", "datasource", "update", spreadsheetId, dataSourceId];
|
|
37007
|
+
const args = ["sheets", "datasource", "update", pos(spreadsheetId), pos(dataSourceId)];
|
|
36694
37008
|
if (billingProject !== void 0) args.push(`--billing-project=${billingProject}`);
|
|
36695
37009
|
if (query !== void 0) args.push(`--query=${query}`);
|
|
36696
37010
|
if (tableProject !== void 0) args.push(`--table-project=${tableProject}`);
|
|
@@ -36708,7 +37022,7 @@ ${errorText(err)}`
|
|
|
36708
37022
|
account: accountParam
|
|
36709
37023
|
})
|
|
36710
37024
|
}, async ({ spreadsheetId, dataSourceId, forceRefresh, account }) => {
|
|
36711
|
-
const args = ["sheets", "datasource", "refresh", spreadsheetId, dataSourceId];
|
|
37025
|
+
const args = ["sheets", "datasource", "refresh", pos(spreadsheetId), pos(dataSourceId)];
|
|
36712
37026
|
if (forceRefresh) args.push("--force-refresh");
|
|
36713
37027
|
return runOrDiagnose(args, { account });
|
|
36714
37028
|
});
|
|
@@ -36721,7 +37035,7 @@ ${errorText(err)}`
|
|
|
36721
37035
|
account: accountParam
|
|
36722
37036
|
})
|
|
36723
37037
|
}, async ({ spreadsheetId, dataSourceId, account }) => {
|
|
36724
|
-
return runOrDiagnose(["sheets", "datasource", "delete", spreadsheetId, dataSourceId, "--force"], { account });
|
|
37038
|
+
return runOrDiagnose(["sheets", "datasource", "delete", pos(spreadsheetId), pos(dataSourceId), "--force"], { account });
|
|
36725
37039
|
});
|
|
36726
37040
|
}
|
|
36727
37041
|
|