gogcli-mcp-drive 4.2.4 → 4.3.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/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 = (delimiter2) => {
2096
- const escapedDelim = escapeRegex(delimiter2 ?? ":");
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, resolve) {
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, resolve);
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, resolve) : NONE;
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 ?? (resolve ? inst._zod.innerType : void 0);
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((resolve, reject) => {
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
- resolve();
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((resolve, reject) => {
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 resolve(manualInputRequiredValue(decoded));
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 resolve(this._resolveNonCompleteResult(decoded, flow));
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) resolve(parseResult.data);
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 = resolve.call(this, root, ref);
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 resolve(root, ref) {
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 resolve(baseURI, relativeURI, options) {
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, relative, options, skipNormalization) {
28388
+ function resolveComponent(base, relative3, options, skipNormalization) {
28389
28389
  const target = {};
28390
28390
  if (!skipNormalization) {
28391
28391
  base = parse3(serialize(base, options), options);
28392
- relative = parse3(serialize(relative, options), options);
28392
+ relative3 = parse3(serialize(relative3, options), options);
28393
28393
  }
28394
28394
  options = options || {};
28395
- if (!options.tolerant && relative.scheme) {
28396
- target.scheme = relative.scheme;
28397
- target.userinfo = relative.userinfo;
28398
- target.host = relative.host;
28399
- target.port = relative.port;
28400
- target.path = removeDotSegments(relative.path || "");
28401
- target.query = relative.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 (relative.userinfo !== void 0 || relative.host !== void 0 || relative.port !== void 0) {
28404
- target.userinfo = relative.userinfo;
28405
- target.host = relative.host;
28406
- target.port = relative.port;
28407
- target.path = removeDotSegments(relative.path || "");
28408
- target.query = relative.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 (!relative.path) {
28410
+ if (!relative3.path) {
28411
28411
  target.path = base.path;
28412
- if (relative.query !== void 0) target.query = relative.query;
28412
+ if (relative3.query !== void 0) target.query = relative3.query;
28413
28413
  else target.query = base.query;
28414
28414
  } else {
28415
- if (relative.path[0] === "/") target.path = removeDotSegments(relative.path);
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 = "/" + relative.path;
28418
- else if (!base.path) target.path = relative.path;
28419
- else target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative.path;
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 = relative.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 = relative.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 pos = 0;
29338
+ let pos2 = 0;
29339
29339
  let value;
29340
- while (pos < len) {
29340
+ while (pos2 < len) {
29341
29341
  length++;
29342
- value = str.charCodeAt(pos++);
29343
- if (value >= 55296 && value <= 56319 && pos < len) {
29344
- value = str.charCodeAt(pos);
29345
- if ((value & 64512) === 56320) pos++;
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((resolve, reject) => {
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
- resolve();
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
- resolve();
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((resolve) => {
34005
+ return await new Promise((resolve4) => {
34006
34006
  const waiter = () => {
34007
34007
  clearTimeout(timer);
34008
- resolve(true);
34008
+ resolve4(true);
34009
34009
  };
34010
34010
  const timer = setTimeout(() => {
34011
34011
  this._drainWaiters = this._drainWaiters.filter((pending) => pending !== waiter);
34012
- resolve(false);
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 = /([?&](?:access_token|refresh_token|client_secret|api_?key|signature|token|key|sig)=)[^&#\s"'<>`]+/gi;
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 = "access_token|refresh_token|client_secret|api_?key|password|passwd|secret|token";
34385
- var JSON_SECRET_DQ_RE = new RegExp(`("(?:${JSON_SECRET_KEYS})"\\s*:\\s*")[^"]*(")`, "gi");
34386
- var JSON_SECRET_SQ_RE = new RegExp(`('(?:${JSON_SECRET_KEYS})'\\s*:\\s*')[^']*(')`, "gi");
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
@@ -34568,13 +34583,47 @@ async function createMcpServer(opts) {
34568
34583
  }
34569
34584
  return server;
34570
34585
  }
34586
+ var DEFAULT_SHUTDOWN_TIMEOUT_MS = 5e3;
34587
+ var DEFAULT_REPEAT_SIGNAL_GRACE_MS = 500;
34571
34588
  function withGracefulShutdown(target, opts = {}) {
34572
34589
  const shouldExit = opts.exit ?? true;
34590
+ if (opts.timeoutMs !== void 0 && !(Number.isFinite(opts.timeoutMs) && opts.timeoutMs > 0)) {
34591
+ throw new RangeError("withGracefulShutdown: timeoutMs must be a finite number greater than 0.");
34592
+ }
34593
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS;
34594
+ if (opts.repeatSignalGraceMs !== void 0 && !(Number.isFinite(opts.repeatSignalGraceMs) && opts.repeatSignalGraceMs >= 0)) {
34595
+ throw new RangeError("withGracefulShutdown: repeatSignalGraceMs must be a finite number >= 0.");
34596
+ }
34597
+ const repeatGraceMs = opts.repeatSignalGraceMs ?? DEFAULT_REPEAT_SIGNAL_GRACE_MS;
34573
34598
  let shuttingDown = false;
34599
+ let firstSignalAt = 0;
34600
+ let exited = false;
34601
+ const exitOnce = () => {
34602
+ if (exited)
34603
+ return;
34604
+ exited = true;
34605
+ process.exit(0);
34606
+ };
34574
34607
  const handler = (signal) => {
34575
- if (shuttingDown)
34608
+ if (shuttingDown) {
34609
+ if (Date.now() - firstSignalAt < repeatGraceMs)
34610
+ return;
34611
+ if (shouldExit) {
34612
+ console.error(`[mcp-utils] second ${signal} during shutdown \u2014 exiting now`);
34613
+ exitOnce();
34614
+ }
34576
34615
  return;
34616
+ }
34577
34617
  shuttingDown = true;
34618
+ firstSignalAt = Date.now();
34619
+ let timer;
34620
+ if (shouldExit) {
34621
+ timer = setTimeout(() => {
34622
+ console.error(`[mcp-utils] graceful shutdown on ${signal} did not finish in ${timeoutMs}ms \u2014 exiting`);
34623
+ exitOnce();
34624
+ }, timeoutMs);
34625
+ timer.unref?.();
34626
+ }
34578
34627
  void (async () => {
34579
34628
  try {
34580
34629
  if (opts.onSignal)
@@ -34583,8 +34632,10 @@ function withGracefulShutdown(target, opts = {}) {
34583
34632
  } catch (err) {
34584
34633
  console.error(`[mcp-utils] error during graceful shutdown on ${signal}: ${err instanceof Error ? err.message : String(err)}`);
34585
34634
  } finally {
34635
+ if (timer !== void 0)
34636
+ clearTimeout(timer);
34586
34637
  if (shouldExit)
34587
- process.exit(0);
34638
+ exitOnce();
34588
34639
  }
34589
34640
  })();
34590
34641
  };
@@ -34614,6 +34665,8 @@ function runMcp(opts) {
34614
34665
  }
34615
34666
 
34616
34667
  // ../../node_modules/@chrischall/mcp-utils/dist/config/index.js
34668
+ import { homedir } from "node:os";
34669
+ import { isAbsolute, join, resolve } from "node:path";
34617
34670
  var PLACEHOLDER_RE = /^\$\{[^}]*\}$/;
34618
34671
  function readEnvVar(key, opts = {}) {
34619
34672
  const env = opts.env ?? process.env;
@@ -34640,6 +34693,50 @@ function parseBoolEnv(key, opts = {}) {
34640
34693
  return false;
34641
34694
  return fallback;
34642
34695
  }
34696
+ function expandPath(p) {
34697
+ let expanded = p;
34698
+ if (p === "~") {
34699
+ expanded = homedir();
34700
+ } else if (p.startsWith("~/")) {
34701
+ expanded = join(homedir(), p.slice(2));
34702
+ }
34703
+ return isAbsolute(expanded) ? expanded : resolve(expanded);
34704
+ }
34705
+
34706
+ // ../../node_modules/@chrischall/mcp-utils/dist/fs/confine.js
34707
+ import { existsSync, realpathSync } from "node:fs";
34708
+ import { dirname, isAbsolute as isAbsolute2, relative, resolve as resolve2, sep } from "node:path";
34709
+ function isInside(root, target) {
34710
+ const rel = relative(root, target);
34711
+ return rel === "" || !rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute2(rel);
34712
+ }
34713
+ function realPathAllowingMissing(p) {
34714
+ const abs = resolve2(p);
34715
+ let existing = abs;
34716
+ const tail = [];
34717
+ while (!existsSync(existing)) {
34718
+ const parent = dirname(existing);
34719
+ if (parent === existing)
34720
+ break;
34721
+ tail.unshift(existing.slice(parent.length).replace(/^[/\\]+/, ""));
34722
+ existing = parent;
34723
+ }
34724
+ let real;
34725
+ try {
34726
+ real = realpathSync(existing);
34727
+ } catch {
34728
+ real = existing;
34729
+ }
34730
+ return tail.length > 0 ? resolve2(real, ...tail) : real;
34731
+ }
34732
+ function assertPathWithinRoots(path, roots) {
34733
+ const target = realPathAllowingMissing(expandPath(path));
34734
+ for (const root of roots) {
34735
+ if (isInside(realPathAllowingMissing(expandPath(root)), target))
34736
+ return target;
34737
+ }
34738
+ throw new Error(`Path is outside the allowed directories: ${path}`);
34739
+ }
34643
34740
 
34644
34741
  // ../../node_modules/@chrischall/mcp-utils/dist/zod/index.js
34645
34742
  var PositiveInt = external_exports.number().int().positive();
@@ -34661,7 +34758,7 @@ var pageSchema = {
34661
34758
  };
34662
34759
 
34663
34760
  // ../gogcli-mcp/src/runner.ts
34664
- import { delimiter, join } from "node:path";
34761
+ import { delimiter, join as join2 } from "node:path";
34665
34762
 
34666
34763
  // ../gogcli-mcp/src/timestamps.ts
34667
34764
  var DEFAULT_DISPLAY_TZ = "America/New_York";
@@ -34862,9 +34959,48 @@ function normalizeTimestamps(text, tz = displayTimeZone(), naiveTz = naiveSource
34862
34959
  return JSON.stringify(parsed, null, detectIndent(text));
34863
34960
  }
34864
34961
 
34962
+ // ../gogcli-mcp/src/arg-guard.ts
34963
+ 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;
34964
+ var SHORT_ACCOUNT_CLUSTER = /^-(?!-)[A-Za-z]*a/;
34965
+ function forbiddenArgReason(arg) {
34966
+ if (arg === "--") {
34967
+ return 'The argument "--" is not allowed: it ends flag parsing and would disable safety flags appended after it.';
34968
+ }
34969
+ const match = FORBIDDEN_LONG_FLAG.exec(arg);
34970
+ if (match) {
34971
+ 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.`;
34972
+ }
34973
+ if (SHORT_ACCOUNT_CLUSTER.test(arg)) {
34974
+ return `The flag ${arg} is not allowed here: -a selects the account. Use the tool's account parameter instead.`;
34975
+ }
34976
+ return void 0;
34977
+ }
34978
+ function assertSafeForwardedArgs(args) {
34979
+ for (const arg of args) {
34980
+ const reason = forbiddenArgReason(arg);
34981
+ if (reason) throw new Error(reason);
34982
+ }
34983
+ }
34984
+ var SUBCOMMAND_SHAPE = /^[a-z][a-z0-9-]*$/;
34985
+ function assertSafeSubcommand(subcommand) {
34986
+ if (!SUBCOMMAND_SHAPE.test(subcommand)) {
34987
+ throw new Error(
34988
+ `Invalid subcommand ${JSON.stringify(subcommand)}: pass a single gog subcommand name such as "list" or "mark-read", and put its arguments in args.`
34989
+ );
34990
+ }
34991
+ }
34992
+
34993
+ // ../gogcli-mcp/src/argv.ts
34994
+ function pos(value) {
34995
+ return { kind: "positional", value };
34996
+ }
34997
+ function isGogPositional(arg) {
34998
+ return typeof arg === "object" && arg !== null && arg.kind === "positional";
34999
+ }
35000
+
34865
35001
  // ../gogcli-mcp/src/runner.ts
34866
35002
  function isGogFileArg(arg) {
34867
- return typeof arg !== "string";
35003
+ return typeof arg !== "string" && arg.kind === "file";
34868
35004
  }
34869
35005
  var TIMEOUT_MS = 3e4;
34870
35006
  function readonlyEnvEnabled() {
@@ -34948,8 +35084,8 @@ function formatTimeout(ms) {
34948
35084
  }
34949
35085
  async function spawnWithTempFiles(args, opts) {
34950
35086
  const { mkdtemp, mkdir, writeFile, rm } = await import("node:fs/promises");
34951
- const { tmpdir } = await import("node:os");
34952
- const dir = await mkdtemp(join(tmpdir(), "gogcli-mcp-"));
35087
+ const { tmpdir: tmpdir2 } = await import("node:os");
35088
+ const dir = await mkdtemp(join2(tmpdir2(), "gogcli-mcp-"));
34953
35089
  try {
34954
35090
  const argv = [];
34955
35091
  let seq = 0;
@@ -34958,10 +35094,10 @@ async function spawnWithTempFiles(args, opts) {
34958
35094
  argv.push(arg);
34959
35095
  continue;
34960
35096
  }
34961
- const sub = join(dir, String(seq));
35097
+ const sub = join2(dir, String(seq));
34962
35098
  seq += 1;
34963
35099
  await mkdir(sub, { recursive: true, mode: 448 });
34964
- const path = join(sub, arg.filename ?? `${arg.flag}.${arg.ext ?? "txt"}`);
35100
+ const path = join2(sub, arg.filename ?? `${arg.flag}.${arg.ext ?? "txt"}`);
34965
35101
  const data = arg.encoding === "base64" ? Buffer.from(arg.contents, "base64") : Buffer.from(arg.contents, "utf8");
34966
35102
  await writeFile(path, data, { mode: 384 });
34967
35103
  argv.push(arg.positional ? path : `--${arg.flag}=${path}`);
@@ -34979,10 +35115,10 @@ function spawnExecutor(args, opts) {
34979
35115
  return spawnGog(args, opts);
34980
35116
  }
34981
35117
  async function spawnGog(fullArgs, opts) {
34982
- const { timeout, interactive = false, spawner, binary = false } = opts;
35118
+ const { timeout, interactive = false, spawner, binary = false, maxOutputBytes } = opts;
34983
35119
  const spawn = spawner ?? (await import("node:child_process")).spawn;
34984
35120
  const effectiveTimeout = timeout ?? TIMEOUT_MS;
34985
- return new Promise((resolve, reject) => {
35121
+ return new Promise((resolve4, reject) => {
34986
35122
  const childEnv = { ...sanitizedEnv(), GOG_TIMEZONE: naiveSourceTimeZone(), PATH: augmentedPath() };
34987
35123
  const child = spawn(readEnvVar("GOG_PATH") ?? "gog", fullArgs, { env: childEnv });
34988
35124
  const stdoutChunks = [];
@@ -35000,7 +35136,17 @@ async function spawnGog(fullArgs, opts) {
35000
35136
  child.kill();
35001
35137
  reject(new Error(`gog timed out after ${formatTimeout(effectiveTimeout)}`));
35002
35138
  }, effectiveTimeout);
35139
+ let stdoutBytes = 0;
35003
35140
  child.stdout.on("data", (chunk) => {
35141
+ if (settled) return;
35142
+ stdoutBytes += chunk.length;
35143
+ if (maxOutputBytes !== void 0 && stdoutBytes > maxOutputBytes) {
35144
+ settled = true;
35145
+ stopWatching();
35146
+ child.kill();
35147
+ reject(new Error(`gog output exceeded the limit: more than ${maxOutputBytes} bytes`));
35148
+ return;
35149
+ }
35004
35150
  stdoutChunks.push(chunk);
35005
35151
  });
35006
35152
  child.stderr.on("data", (chunk) => {
@@ -35017,14 +35163,14 @@ async function spawnGog(fullArgs, opts) {
35017
35163
  const stderr = Buffer.concat(stderrChunks).toString().trim();
35018
35164
  if (code === 0) {
35019
35165
  if (binary) {
35020
- resolve(Buffer.concat(stdoutChunks).toString("base64"));
35166
+ resolve4(Buffer.concat(stdoutChunks).toString("base64"));
35021
35167
  return;
35022
35168
  }
35023
35169
  const stdout = Buffer.concat(stdoutChunks).toString();
35024
35170
  if (interactive && stderr) {
35025
- resolve(stdout + "\n" + stderr);
35171
+ resolve4(stdout + "\n" + stderr);
35026
35172
  } else {
35027
- resolve(stdout);
35173
+ resolve4(stdout);
35028
35174
  }
35029
35175
  } else {
35030
35176
  reject(new Error(stderr || `gog exited with code ${code}`));
@@ -35044,7 +35190,33 @@ async function spawnGog(fullArgs, opts) {
35044
35190
  });
35045
35191
  });
35046
35192
  }
35193
+ function placePositionals(args) {
35194
+ const flags = [];
35195
+ const positionals = [];
35196
+ let afterSeparator = false;
35197
+ for (const arg of args) {
35198
+ if (arg === "--") {
35199
+ afterSeparator = true;
35200
+ } else if (isGogPositional(arg)) {
35201
+ positionals.push(arg.value);
35202
+ } else if (afterSeparator || isGogFileArg(arg) && arg.positional) {
35203
+ positionals.push(arg);
35204
+ } else {
35205
+ flags.push(arg);
35206
+ }
35207
+ }
35208
+ return { flags, positionals };
35209
+ }
35210
+ function assertNoSafetyOverrides(flags) {
35211
+ for (const arg of flags) {
35212
+ if (typeof arg !== "string") continue;
35213
+ const reason = forbiddenArgReason(arg);
35214
+ if (reason) throw new Error(reason);
35215
+ }
35216
+ }
35047
35217
  function assembleArgs(args, opts) {
35218
+ const { flags, positionals } = placePositionals(args);
35219
+ assertNoSafetyOverrides(flags);
35048
35220
  const effectiveAccount = opts.account ?? readEnvVar("GOG_ACCOUNT");
35049
35221
  const fullArgs = ["--json", "--color=never"];
35050
35222
  if (!opts.interactive) {
@@ -35053,17 +35225,21 @@ function assembleArgs(args, opts) {
35053
35225
  if (opts.readonly || readonlyEnvEnabled()) {
35054
35226
  fullArgs.push("--readonly");
35055
35227
  }
35228
+ if (opts.gmailNoSend) {
35229
+ fullArgs.push("--gmail-no-send");
35230
+ }
35056
35231
  if (effectiveAccount) {
35057
35232
  fullArgs.push("--account", effectiveAccount);
35058
35233
  }
35059
- fullArgs.push(...args);
35234
+ fullArgs.push(...flags);
35235
+ if (positionals.length > 0) fullArgs.push("--", ...positionals);
35060
35236
  return fullArgs;
35061
35237
  }
35062
35238
  async function run(args, options = {}) {
35063
- const { account, spawner, interactive = false, timeout, readonly: readonly2 = false, redactMode = "full", opaqueFields } = options;
35239
+ const { account, spawner, interactive = false, timeout, readonly: readonly2 = false, redactMode = "full", opaqueFields, gmailNoSend = false } = options;
35064
35240
  const base = redactMode === "tokens" ? redactGoogleTokens : redactSecrets2;
35065
35241
  const redact = opaqueFields?.length ? (text) => redactPreservingOpaqueFields(text, opaqueFields, base) : base;
35066
- const fullArgs = assembleArgs(args, { account, interactive, readonly: readonly2 });
35242
+ const fullArgs = assembleArgs(args, { account, interactive, readonly: readonly2, gmailNoSend });
35067
35243
  try {
35068
35244
  return redact(await spawnExecutor(fullArgs, { timeout, interactive, spawner }));
35069
35245
  } catch (err) {
@@ -35071,9 +35247,9 @@ async function run(args, options = {}) {
35071
35247
  }
35072
35248
  }
35073
35249
  async function runBinary(args, options = {}) {
35074
- const { account, spawner, timeout, readonly: readonly2 = false } = options;
35075
- const fullArgs = assembleArgs(args, { account, interactive: false, readonly: readonly2 });
35076
- return spawnExecutor(fullArgs, { timeout, interactive: false, spawner, binary: true });
35250
+ const { account, spawner, timeout, readonly: readonly2 = false, gmailNoSend = false, maxOutputBytes } = options;
35251
+ const fullArgs = assembleArgs(args, { account, interactive: false, readonly: readonly2, gmailNoSend });
35252
+ return spawnExecutor(fullArgs, { timeout, interactive: false, spawner, binary: true, maxOutputBytes });
35077
35253
  }
35078
35254
 
35079
35255
  // ../gogcli-mcp/src/pagination.ts
@@ -35096,6 +35272,107 @@ function stripConsumedPageToken(text) {
35096
35272
  return JSON.stringify(obj, null, detectIndent2(text));
35097
35273
  }
35098
35274
 
35275
+ // ../gogcli-mcp/src/file-roots.ts
35276
+ import { homedir as homedir2 } from "node:os";
35277
+ import { delimiter as delimiter2, join as join4 } from "node:path";
35278
+
35279
+ // ../gogcli-mcp/src/attachment-root.ts
35280
+ import { tmpdir, userInfo } from "node:os";
35281
+ import { dirname as dirname2, join as join3, relative as relative2, resolve as resolve3, isAbsolute as isAbsolute3, sep as sep2 } from "node:path";
35282
+ var ATTACHMENT_DOWNLOAD_ROOT = join3(tmpdir(), `gogcli-mcp-attachments-${userInfo().uid}`);
35283
+ var ATTACHMENT_TTL_MS = 24 * 60 * 60 * 1e3;
35284
+
35285
+ // ../gogcli-mcp/src/file-roots.ts
35286
+ var FILE_ROOTS_ENV = "GOG_FILE_ROOTS";
35287
+ function defaultFileRoot() {
35288
+ return join4(homedir2(), "gogcli-mcp-files");
35289
+ }
35290
+ function fileRoots() {
35291
+ const raw = readEnvVar(FILE_ROOTS_ENV);
35292
+ const roots = (raw ?? "").split(delimiter2).map((r) => r.trim()).filter(Boolean);
35293
+ return roots.length > 0 ? roots : [defaultFileRoot()];
35294
+ }
35295
+ function confinePath(path, param, opts = {}) {
35296
+ if (opts.allowDash && path === "-") return path;
35297
+ const roots = [...fileRoots(), ATTACHMENT_DOWNLOAD_ROOT];
35298
+ try {
35299
+ assertPathWithinRoots(path, roots);
35300
+ } catch {
35301
+ throw new Error(
35302
+ `${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}.`
35303
+ );
35304
+ }
35305
+ return path;
35306
+ }
35307
+
35308
+ // ../gogcli-mcp/src/run-path-guard.ts
35309
+ var POSITIONAL_PATH_SUBCOMMANDS = {
35310
+ appscript: { pull: "gog_appscript_pull" },
35311
+ drive: { upload: "gog_drive_upload", sync: "gog_drive_sync_push" },
35312
+ gmail: { import: "gog_gmail_import" },
35313
+ slides: {
35314
+ "add-slide": "gog_slides_add_slide",
35315
+ "insert-image": "gog_slides_insert_image",
35316
+ "replace-slide": "gog_slides_replace_slide"
35317
+ }
35318
+ };
35319
+ var PATH_FLAGS = /* @__PURE__ */ new Set(["out", "output", "out-dir", "output-dir", "dir", "worker-dir", "attach", "file", "key", "cert", "replacements"]);
35320
+ var ID_FLAGS = {
35321
+ drive: /* @__PURE__ */ new Set(["file", "filter-file"])
35322
+ };
35323
+ var EXEC_FLAGS = /* @__PURE__ */ new Set(["on-change", "on-new", "mmdc"]);
35324
+ var SHORT_PATH_CLUSTER = /^-(?!-)[A-Za-z]*[of]/;
35325
+ var LONG_FLAG = /^--([A-Za-z0-9][A-Za-z0-9-]*)(?:=([\s\S]*))?$/;
35326
+ function isPathFlag(service, name) {
35327
+ if (ID_FLAGS[service]?.has(name)) return false;
35328
+ return PATH_FLAGS.has(name) || name.endsWith("-file");
35329
+ }
35330
+ function confineFlagValue(flag, value) {
35331
+ if (value === "-") return;
35332
+ confinePath(value, flag);
35333
+ for (const part of value.split(",")) {
35334
+ if (part !== "" && part !== "-") confinePath(part, flag);
35335
+ }
35336
+ }
35337
+ function positionalPathTool(service, subcommand) {
35338
+ return POSITIONAL_PATH_SUBCOMMANDS[service]?.[subcommand];
35339
+ }
35340
+ function assertRunPathsConfined(service, subcommand, args) {
35341
+ const dedicated = positionalPathTool(service, subcommand);
35342
+ if (dedicated) {
35343
+ throw new Error(
35344
+ `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.`
35345
+ );
35346
+ }
35347
+ for (let i = 0; i < args.length; i++) {
35348
+ const arg = args[i];
35349
+ if (SHORT_PATH_CLUSTER.test(arg)) {
35350
+ throw new Error(
35351
+ `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.`
35352
+ );
35353
+ }
35354
+ const match = LONG_FLAG.exec(arg);
35355
+ if (!match) continue;
35356
+ const name = match[1].toLowerCase();
35357
+ if (EXEC_FLAGS.has(name)) {
35358
+ throw new Error(`The flag --${name} is not allowed here: it runs a local program chosen by the caller.`);
35359
+ }
35360
+ const isJson = name.endsWith("-json");
35361
+ if (!isJson && !isPathFlag(service, name)) continue;
35362
+ let value = match[2];
35363
+ if (value === void 0) {
35364
+ value = args[i + 1];
35365
+ if (value === void 0) continue;
35366
+ i++;
35367
+ }
35368
+ if (isJson) {
35369
+ if (value.startsWith("@")) confineFlagValue(`--${name}`, value.slice(1));
35370
+ continue;
35371
+ }
35372
+ confineFlagValue(`--${name}`, value);
35373
+ }
35374
+ }
35375
+
35099
35376
  // ../gogcli-mcp/src/tools/utils.ts
35100
35377
  var accountParam = external_exports.string().optional().describe(
35101
35378
  "Google account email to use, e.g. you@gmail.com \u2014 must be the full address, not a bare username. Overrides the GOG_ACCOUNT env var. Omit to use the single configured account."
@@ -35146,9 +35423,17 @@ function pushPaginationFlags(args, p) {
35146
35423
  if (p.all) args.push("--all");
35147
35424
  }
35148
35425
  function registerRunTool(server, options) {
35149
- const { service, examples, omitAccount = false, note } = options;
35426
+ const { service, examples, omitAccount = false, note, allowedSubcommands, vet, gmailNoSend = false } = options;
35427
+ for (const [, example] of examples.matchAll(/"([^"]+)"/g)) {
35428
+ const refused = allowedSubcommands && !allowedSubcommands.includes(example) || vet?.(example, []) || positionalPathTool(service, example);
35429
+ if (refused) {
35430
+ throw new Error(`gog_${service}_run example "${example}" is refused by the tool itself; list a subcommand it runs.`);
35431
+ }
35432
+ }
35150
35433
  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.`;
35151
- const description = note ? `${baseDescription} ${note}` : baseDescription;
35434
+ const restriction = allowedSubcommands ? ` Only these subcommands are available: ${allowedSubcommands.join(", ")}.` : "";
35435
+ 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.';
35436
+ const description = `${baseDescription}${restriction}${safety}${note ? ` ${note}` : ""}`;
35152
35437
  const inputSchema = {
35153
35438
  subcommand: external_exports.string().describe(`The gog ${service} subcommand to run, e.g. ${examples}`),
35154
35439
  args: external_exports.array(external_exports.string()).describe("Additional positional args and flags")
@@ -35162,7 +35447,21 @@ function registerRunTool(server, options) {
35162
35447
  inputSchema: external_exports.object(inputSchema)
35163
35448
  }, async (rawArgs) => {
35164
35449
  const { subcommand, args, account } = rawArgs;
35165
- return runOrDiagnose([service, subcommand, ...args], { account });
35450
+ try {
35451
+ assertSafeSubcommand(subcommand);
35452
+ assertSafeForwardedArgs(args);
35453
+ if (allowedSubcommands && !allowedSubcommands.includes(subcommand)) {
35454
+ throw new Error(
35455
+ `gog ${service} ${subcommand} is not available through gog_${service}_run. Allowed: ${allowedSubcommands.join(", ")}.`
35456
+ );
35457
+ }
35458
+ const refusal = vet?.(subcommand, args);
35459
+ if (refusal) throw new Error(refusal);
35460
+ assertRunPathsConfined(service, subcommand, args);
35461
+ } catch (err) {
35462
+ return errorResult(errorText(err));
35463
+ }
35464
+ return runOrDiagnose([service, subcommand, ...args], gmailNoSend ? { account, gmailNoSend } : { account });
35166
35465
  });
35167
35466
  }
35168
35467
  function errorText(err) {
@@ -35284,6 +35583,7 @@ function formatAuthHealth(raw, now) {
35284
35583
  }
35285
35584
 
35286
35585
  // ../gogcli-mcp/src/tools/auth.ts
35586
+ var AUTH_RUN_SUBCOMMANDS = ["list", "status", "services", "remove", "alias"];
35287
35587
  function registerAuthToolsWith(server, defaultServices) {
35288
35588
  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.`;
35289
35589
  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.";
@@ -35341,7 +35641,7 @@ function registerAuthToolsWith(server, defaultServices) {
35341
35641
  })
35342
35642
  }, async ({ email: email3, services = defaultServices, extraScopes }) => {
35343
35643
  try {
35344
- const args = ["auth", "add", email3, "--services", services];
35644
+ const args = ["auth", "add", pos(email3), "--services", services];
35345
35645
  if (extraScopes) args.push(`--extra-scopes=${extraScopes}`, "--force-consent");
35346
35646
  return rawTextResult(await run(args, {
35347
35647
  interactive: true,
@@ -35361,7 +35661,7 @@ function registerAuthToolsWith(server, defaultServices) {
35361
35661
  })
35362
35662
  }, async ({ email: email3, services = defaultServices, extraScopes }) => {
35363
35663
  try {
35364
- const args = ["auth", "add", email3, "--remote", "--step", "1", "--services", services, "--force-consent"];
35664
+ const args = ["auth", "add", pos(email3), "--remote", "--step", "1", "--services", services, "--force-consent"];
35365
35665
  if (extraScopes) args.push(`--extra-scopes=${extraScopes}`);
35366
35666
  return rawTextResult(await run(args, { redactMode: "tokens" }));
35367
35667
  } catch (err) {
@@ -35388,7 +35688,7 @@ function registerAuthToolsWith(server, defaultServices) {
35388
35688
  const args = [
35389
35689
  "auth",
35390
35690
  "add",
35391
- email3,
35691
+ pos(email3),
35392
35692
  "--remote",
35393
35693
  "--step",
35394
35694
  "2",
@@ -35408,6 +35708,7 @@ function registerAuthToolsWith(server, defaultServices) {
35408
35708
  service: "auth",
35409
35709
  examples: '"remove", "alias", "list"',
35410
35710
  omitAccount: true,
35711
+ allowedSubcommands: AUTH_RUN_SUBCOMMANDS,
35411
35712
  note: "For browser-based authorization, use gog_auth_add instead."
35412
35713
  });
35413
35714
  }
@@ -35485,8 +35786,10 @@ var GOOGLE_DOC_MIME = "application/vnd.google-apps.document";
35485
35786
  function fileMeta(raw) {
35486
35787
  const parsed = JSON.parse(raw);
35487
35788
  const f = parsed.file ?? parsed;
35488
- return { name: f.name, mimeType: f.mimeType };
35789
+ const size = f.size === void 0 ? void 0 : Number(f.size);
35790
+ return { name: f.name, mimeType: f.mimeType, size: Number.isFinite(size) ? size : void 0 };
35489
35791
  }
35792
+ var MAX_DRIVE_READ_BYTES = MAX_INLINE_ATTACHMENT_BYTES;
35490
35793
  var DRIVE_LS_COMPACT_FIELDS = "nextPageToken,files(id,name,mimeType,modifiedTime,size,webViewLink)";
35491
35794
  function registerDriveTools(server) {
35492
35795
  server.registerTool("gog_drive_ls", {
@@ -35530,7 +35833,7 @@ function registerDriveTools(server) {
35530
35833
  account: accountParam
35531
35834
  })
35532
35835
  }, async ({ query, view, account }) => {
35533
- return runOrDiagnose(["drive", "search", query], {
35836
+ return runOrDiagnose(["drive", "search", pos(query)], {
35534
35837
  account,
35535
35838
  stripMedia: resolveView(view, ["compact", "full"]) === "compact"
35536
35839
  });
@@ -35550,7 +35853,7 @@ function registerDriveTools(server) {
35550
35853
  account: accountParam
35551
35854
  })
35552
35855
  }, async ({ fileId, view, account }) => {
35553
- return runOrDiagnose(["drive", "get", fileId], {
35856
+ return runOrDiagnose(["drive", "get", pos(fileId)], {
35554
35857
  account,
35555
35858
  stripMedia: resolveView(view, ["compact", "full"]) === "compact"
35556
35859
  });
@@ -35563,7 +35866,7 @@ function registerDriveTools(server) {
35563
35866
  account: accountParam
35564
35867
  })
35565
35868
  }, async ({ name, account }) => {
35566
- return runOrDiagnose(["drive", "mkdir", name], { account });
35869
+ return runOrDiagnose(["drive", "mkdir", pos(name)], { account });
35567
35870
  });
35568
35871
  server.registerTool("gog_drive_rename", {
35569
35872
  description: "Rename a file or folder in Google Drive.",
@@ -35574,7 +35877,7 @@ function registerDriveTools(server) {
35574
35877
  account: accountParam
35575
35878
  })
35576
35879
  }, async ({ fileId, newName, account }) => {
35577
- return runOrDiagnose(["drive", "rename", fileId, newName], { account });
35880
+ return runOrDiagnose(["drive", "rename", pos(fileId), pos(newName)], { account });
35578
35881
  });
35579
35882
  server.registerTool("gog_drive_move", {
35580
35883
  description: "Move a file to a different folder in Google Drive.",
@@ -35585,7 +35888,7 @@ function registerDriveTools(server) {
35585
35888
  account: accountParam
35586
35889
  })
35587
35890
  }, async ({ fileId, parentId, account }) => {
35588
- return runOrDiagnose(["drive", "move", fileId, `--parent=${parentId}`], { account });
35891
+ return runOrDiagnose(["drive", "move", pos(fileId), `--parent=${parentId}`], { account });
35589
35892
  });
35590
35893
  server.registerTool("gog_drive_delete", {
35591
35894
  description: "Move a Google Drive file to trash, or permanently delete it with permanent=true (irreversible).",
@@ -35596,7 +35899,7 @@ function registerDriveTools(server) {
35596
35899
  account: accountParam
35597
35900
  })
35598
35901
  }, async ({ fileId, permanent, account }) => {
35599
- const args = ["drive", "delete", fileId];
35902
+ const args = ["drive", "delete", pos(fileId)];
35600
35903
  if (permanent) args.push("--permanent");
35601
35904
  args.push("--force");
35602
35905
  return runOrDiagnose(args, { account });
@@ -35613,7 +35916,7 @@ function registerDriveTools(server) {
35613
35916
  account: accountParam
35614
35917
  })
35615
35918
  }, async ({ fileId, to, email: email3, domain: domain2, role, account }) => {
35616
- const args = ["drive", "share", fileId, `--to=${to}`];
35919
+ const args = ["drive", "share", pos(fileId), `--to=${to}`];
35617
35920
  if (email3) args.push(`--email=${email3}`);
35618
35921
  if (domain2) args.push(`--domain=${domain2}`);
35619
35922
  if (role) args.push(`--role=${role}`);
@@ -35636,7 +35939,7 @@ function registerDriveTools(server) {
35636
35939
  }, async ({ fileId, ocrLanguage, offset = 0, maxChars, account }) => {
35637
35940
  let tempDocId;
35638
35941
  try {
35639
- const { name, mimeType } = fileMeta(await run(["drive", "get", fileId], { account }));
35942
+ const { name, mimeType } = fileMeta(await run(["drive", "get", pos(fileId)], { account }));
35640
35943
  let sourceId = fileId;
35641
35944
  if (mimeType !== GOOGLE_DOC_MIME) {
35642
35945
  const params = JSON.stringify({ fileId, ...ocrLanguage ? { ocrLanguage } : {} });
@@ -35681,13 +35984,13 @@ function registerDriveTools(server) {
35681
35984
  return diagnose(err);
35682
35985
  } finally {
35683
35986
  if (tempDocId) {
35684
- await run(["drive", "delete", tempDocId, "--permanent", "--force"], { account }).catch(() => {
35987
+ await run(["drive", "delete", pos(tempDocId), "--permanent", "--force"], { account }).catch(() => {
35685
35988
  });
35686
35989
  }
35687
35990
  }
35688
35991
  });
35689
35992
  server.registerTool("gog_drive_read_bytes", {
35690
- description: "Fetch a Drive file's raw bytes and return them base64-encoded as an embedded resource \u2014 the generic fallback for callers that want the file itself (to parse locally) rather than extracted text. For readable text from a PDF, prefer gog_drive_extract_text.",
35993
+ description: "Fetch a Drive file's raw bytes and return them base64-encoded as an embedded resource \u2014 the generic fallback for callers that want the file itself (to parse locally) rather than extracted text. Files over 8 MiB are refused (checked before downloading). For readable text from a PDF, prefer gog_drive_extract_text.",
35691
35994
  annotations: { readOnlyHint: true },
35692
35995
  inputSchema: external_exports.object({
35693
35996
  fileId: external_exports.string().describe("Drive file ID"),
@@ -35695,9 +35998,17 @@ function registerDriveTools(server) {
35695
35998
  })
35696
35999
  }, async ({ fileId, account }) => {
35697
36000
  try {
35698
- const { name, mimeType } = fileMeta(await run(["drive", "get", fileId], { account }));
36001
+ const { name, mimeType, size } = fileMeta(await run(["drive", "get", pos(fileId)], { account }));
36002
+ if (size !== void 0 && size > MAX_DRIVE_READ_BYTES) {
36003
+ return errorResult(
36004
+ `${name ?? fileId} is ${size} bytes, over the 8 MiB this tool returns inline. Use gog_drive_extract_text for its text, or share its webViewLink (gog_drive_get) instead.`
36005
+ );
36006
+ }
35699
36007
  const params = JSON.stringify({ fileId, alt: "media" });
35700
- const blob = await runBinary(["api", "call", "drive", "v3", "files.get", `--params=${params}`], { account });
36008
+ const blob = await runBinary(
36009
+ ["api", "call", "drive", "v3", "files.get", `--params=${params}`],
36010
+ { account, maxOutputBytes: MAX_DRIVE_READ_BYTES }
36011
+ );
35701
36012
  const type = mimeType ?? "application/octet-stream";
35702
36013
  const unrenderableHint = type.startsWith("image/") ? "" : ` If your client does not render a ${type} resource, gog_drive_extract_text returns the same file as text (PDFs included, via OCR).`;
35703
36014
  return {
@@ -35717,7 +36028,7 @@ function registerDriveTools(server) {
35717
36028
  return diagnose(err);
35718
36029
  }
35719
36030
  });
35720
- registerRunTool(server, { service: "drive", examples: '"copy", "upload", "download", "permissions"' });
36031
+ registerRunTool(server, { service: "drive", examples: '"copy", "download", "permissions"' });
35721
36032
  }
35722
36033
 
35723
36034
  // ../gogcli-mcp/src/tools/gmail.ts
@@ -35732,7 +36043,7 @@ var replySchema = {
35732
36043
  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."),
35733
36044
  subject: external_exports.string().optional().describe('Override reply subject (default: "Re: <original>"). A changed subject starts a NEW Gmail thread.'),
35734
36045
  noQuote: external_exports.boolean().optional().describe("Do not include the original message quoted below the reply (default: the original is quoted)"),
35735
- 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.`),
36046
+ 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).`),
35736
36047
  attachInline: attachInlineParam,
35737
36048
  from: external_exports.string().optional().describe("Send from this email address (must be a verified send-as alias)"),
35738
36049
  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."),
@@ -35753,10 +36064,10 @@ var failIfNotEmptyParam = external_exports.boolean().optional().describe(
35753
36064
  );
35754
36065
 
35755
36066
  // ../gogcli-mcp/src/server.ts
35756
- var VERSION = true ? "4.2.4" : "0.0.0";
36067
+ var VERSION = true ? "4.3.0" : "0.0.0";
35757
36068
 
35758
36069
  // ../gogcli-mcp/src/bootstrap-auth.ts
35759
- import { join as join2 } from "node:path";
36070
+ import { join as join5 } from "node:path";
35760
36071
  var AUTH_BOOTSTRAP_MARKER = "auth-bootstrap.sha256";
35761
36072
  var VARS = ["GOG_CLIENT_ID", "GOG_CLIENT_SECRET", "GOG_REFRESH_TOKEN", "GOG_ACCOUNT"];
35762
36073
  var log = (line) => {
@@ -35793,8 +36104,8 @@ async function bootstrapGogAuth(env = process.env, options = {}) {
35793
36104
  const { createHash } = await import("node:crypto");
35794
36105
  const { mkdir, readFile, writeFile, chmod } = await import("node:fs/promises");
35795
36106
  const home = options.home ?? (await import("node:os")).homedir();
35796
- const dir = join2(home, ".gogcli-mcp");
35797
- const marker = join2(dir, AUTH_BOOTSTRAP_MARKER);
36107
+ const dir = join5(home, ".gogcli-mcp");
36108
+ const marker = join5(dir, AUTH_BOOTSTRAP_MARKER);
35798
36109
  const fingerprint = createHash("sha256").update(values.join("\0")).digest("hex");
35799
36110
  const previous = await readFile(marker, "utf8").catch(() => void 0);
35800
36111
  if (previous === fingerprint && await accountListed(account, spawner)) return "present";
@@ -35831,7 +36142,8 @@ var MAX_BLOB_UPLOAD_BYTES = 100 * 1024 * 1024;
35831
36142
  function registerExtraDriveTools(server) {
35832
36143
  server.registerTool("gog_drive_download", {
35833
36144
  description: "Download a Drive file to the local filesystem. For Google Docs formats, specify an export format (pdf, csv, xlsx, pptx, txt, png, docx, md).",
35834
- annotations: { readOnlyHint: true },
36145
+ // Writes a file on the gog host and can overwrite one: not read-only (audit SEC-4).
36146
+ annotations: { readOnlyHint: false, destructiveHint: true },
35835
36147
  inputSchema: external_exports.object({
35836
36148
  fileId: external_exports.string().describe("File ID to download"),
35837
36149
  out: external_exports.string().optional().describe("Output file path (default: gogcli config dir)"),
@@ -35840,7 +36152,8 @@ function registerExtraDriveTools(server) {
35840
36152
  account: accountParam
35841
36153
  })
35842
36154
  }, async ({ fileId, out, format, overwrite, account }) => {
35843
- const args = ["drive", "download", fileId];
36155
+ if (out) confinePath(out, "out");
36156
+ const args = ["drive", "download", pos(fileId)];
35844
36157
  if (out) args.push(`--out=${out}`);
35845
36158
  if (format) args.push(`--format=${format}`);
35846
36159
  if (overwrite) args.push("--overwrite");
@@ -35850,7 +36163,7 @@ function registerExtraDriveTools(server) {
35850
36163
  description: `Upload a file to Drive. Supply it EITHER as localPath (a path on the gog server's own filesystem \u2014 local stdio deployments only) OR as content (the bytes, base64-encoded, carried with the request), which is what works when this server runs remotely from you and no path you can name exists on it. Use replace to replace the content of an existing file (preserves link/permissions), or convert to auto-convert to a Google format. Pair replace with ifVersion to make the overwrite conditional: gog sends an atomic If-Match precondition and reports a conflict \u2014 applying nothing \u2014 if the file changed since you read it, instead of silently clobbering a concurrent edit. No read tool surfaces the version number: fetch it immediately before uploading with gog_drive_run { subcommand: "raw", args: ["<fileId>", "--fields=version"] } \u2014 it comes back as a JSON string, so pass it on as a number. Conditional replacement refuses Google Workspace files (Docs/Sheets/Slides), which have no replaceable binary content.`,
35851
36164
  annotations: { destructiveHint: false },
35852
36165
  inputSchema: external_exports.object({
35853
- localPath: external_exports.string().optional().describe(`Path to the file to upload, 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) this path does not exist and the call fails with "no such file or directory" \u2014 use content there. Exactly one of localPath / content is required.`),
36166
+ localPath: external_exports.string().optional().describe(`Path to the file to upload, 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) this path does not exist and the call fails with "no such file or directory" \u2014 use content there. Exactly one of localPath / content is required. Must be inside the server's GOG_FILE_ROOTS directories (default ~/gogcli-mcp-files).`),
35854
36167
  content: external_exports.string().optional().describe("The file's bytes, base64-encoded (standard alphabet, with padding) \u2014 upload a file you hold without it existing anywhere on the gog server. This is the only route that works when the caller and gog share no filesystem. Requires name (there is no path to take a filename from). Max 8 MiB; for anything larger use localPath from a local deployment. Exactly one of localPath / content is required \u2014 supplying both is an error, not a precedence rule."),
35855
36168
  name: external_exports.string().optional().describe("Override filename (create) or rename target (replace)"),
35856
36169
  parent: external_exports.string().optional().describe("Destination folder ID (create only)"),
@@ -35875,7 +36188,7 @@ function registerExtraDriveTools(server) {
35875
36188
  }
35876
36189
  let pathArg;
35877
36190
  if (localPath !== void 0) {
35878
- pathArg = localPath;
36191
+ pathArg = confinePath(localPath, "localPath");
35879
36192
  } else {
35880
36193
  if (!name) {
35881
36194
  throw new Error("content requires name: there is no path to derive the Drive filename from.");
@@ -35886,7 +36199,7 @@ function registerExtraDriveTools(server) {
35886
36199
  { positional: true, where: "content" }
35887
36200
  ).arg;
35888
36201
  }
35889
- const args = ["drive", "upload", pathArg];
36202
+ const args = ["drive", "upload", typeof pathArg === "string" ? pos(pathArg) : pathArg];
35890
36203
  if (name) args.push(`--name=${name}`);
35891
36204
  if (parent) args.push(`--parent=${parent}`);
35892
36205
  if (replace) args.push(`--replace=${replace}`);
@@ -35901,14 +36214,15 @@ function registerExtraDriveTools(server) {
35901
36214
  description: "Recursively push a local directory's contents into an existing Drive folder \u2014 uploads new files, updates changed ones (matched by name + MD5), and creates missing subfolders. One-way and additive: it never deletes anything on Drive. Use dryRun to preview the planned actions first.",
35902
36215
  annotations: { destructiveHint: true },
35903
36216
  inputSchema: external_exports.object({
35904
- localPath: external_exports.string().describe("Local directory to push (its contents are mirrored into the parent folder)"),
36217
+ localPath: external_exports.string().describe("Local directory to push (its contents are mirrored into the parent folder). Must be inside the server's GOG_FILE_ROOTS directories (default ~/gogcli-mcp-files)."),
35905
36218
  parent: external_exports.string().describe("Existing destination Drive folder ID"),
35906
36219
  dryRun: external_exports.boolean().optional().describe("Preview the planned actions without making any changes"),
35907
36220
  allDrives: external_exports.boolean().optional().describe("Include shared drives (default: true; set false for My Drive only)"),
35908
36221
  account: accountParam
35909
36222
  })
35910
36223
  }, async ({ localPath, parent, dryRun, allDrives, account }) => {
35911
- const args = ["drive", "sync", "push", localPath, `--parent=${parent}`];
36224
+ confinePath(localPath, "localPath");
36225
+ const args = ["drive", "sync", "push", pos(localPath), `--parent=${parent}`];
35912
36226
  if (dryRun) args.push("--dry-run");
35913
36227
  if (allDrives === false) args.push("--no-all-drives");
35914
36228
  return runOrDiagnose(args, { account });
@@ -35923,7 +36237,7 @@ function registerExtraDriveTools(server) {
35923
36237
  account: accountParam
35924
36238
  })
35925
36239
  }, async ({ fileId, name, parent, account }) => {
35926
- const args = ["drive", "copy", fileId, name];
36240
+ const args = ["drive", "copy", pos(fileId), pos(name)];
35927
36241
  if (parent) args.push(`--parent=${parent}`);
35928
36242
  return runOrDiagnose(args, { account });
35929
36243
  });
@@ -35935,7 +36249,7 @@ function registerExtraDriveTools(server) {
35935
36249
  account: accountParam
35936
36250
  })
35937
36251
  }, async ({ fileIds, account }) => {
35938
- return runOrDiagnose(["drive", "url", ...fileIds], { account });
36252
+ return runOrDiagnose(["drive", "url", ...fileIds.map(pos)], { account });
35939
36253
  });
35940
36254
  server.registerTool("gog_drive_permissions", {
35941
36255
  description: "List permissions on a Drive file.",
@@ -35948,7 +36262,7 @@ function registerExtraDriveTools(server) {
35948
36262
  account: accountParam
35949
36263
  })
35950
36264
  }, async ({ fileId, max, pageToken, page, account }) => {
35951
- const args = ["drive", "permissions", fileId];
36265
+ const args = ["drive", "permissions", pos(fileId)];
35952
36266
  if (max !== void 0) args.push(`--max=${max}`);
35953
36267
  const token = resolvePageToken({ pageToken, page });
35954
36268
  if (token) args.push(`--page=${token}`);
@@ -35963,7 +36277,7 @@ function registerExtraDriveTools(server) {
35963
36277
  account: accountParam
35964
36278
  })
35965
36279
  }, async ({ fileId, permissionId, account }) => {
35966
- return runOrDiagnose(["drive", "unshare", fileId, permissionId, "--force"], { account });
36280
+ return runOrDiagnose(["drive", "unshare", pos(fileId), pos(permissionId), "--force"], { account });
35967
36281
  });
35968
36282
  server.registerTool("gog_drive_drives_list", {
35969
36283
  description: "List shared drives (Team Drives) accessible to the account.",
@@ -35996,7 +36310,7 @@ function registerExtraDriveTools(server) {
35996
36310
  account: accountParam
35997
36311
  })
35998
36312
  }, async ({ fileId, since, includeQuoted, max, page, all, account }) => {
35999
- const args = ["drive", "comments", "list", fileId];
36313
+ const args = ["drive", "comments", "list", pos(fileId)];
36000
36314
  if (since) args.push(`--since=${since}`);
36001
36315
  if (includeQuoted) args.push("--include-quoted");
36002
36316
  pushPaginationFlags(args, { max, page, all });
@@ -36011,7 +36325,7 @@ function registerExtraDriveTools(server) {
36011
36325
  account: accountParam
36012
36326
  })
36013
36327
  }, async ({ fileId, commentId, account }) => {
36014
- return runOrDiagnose(["drive", "comments", "get", fileId, commentId], { account });
36328
+ return runOrDiagnose(["drive", "comments", "get", pos(fileId), pos(commentId)], { account });
36015
36329
  });
36016
36330
  server.registerTool("gog_drive_comments_add", {
36017
36331
  description: "Add a new comment to a Drive file.",
@@ -36022,7 +36336,7 @@ function registerExtraDriveTools(server) {
36022
36336
  account: accountParam
36023
36337
  })
36024
36338
  }, async ({ fileId, content, account }) => {
36025
- return runOrDiagnose(["drive", "comments", "create", fileId, content], { account });
36339
+ return runOrDiagnose(["drive", "comments", "create", pos(fileId), pos(content)], { account });
36026
36340
  });
36027
36341
  server.registerTool("gog_drive_comments_update", {
36028
36342
  description: "Update the text of an existing comment.",
@@ -36034,7 +36348,7 @@ function registerExtraDriveTools(server) {
36034
36348
  account: accountParam
36035
36349
  })
36036
36350
  }, async ({ fileId, commentId, content, account }) => {
36037
- return runOrDiagnose(["drive", "comments", "update", fileId, commentId, content], { account });
36351
+ return runOrDiagnose(["drive", "comments", "update", pos(fileId), pos(commentId), pos(content)], { account });
36038
36352
  });
36039
36353
  server.registerTool("gog_drive_comments_delete", {
36040
36354
  description: "Delete a comment from a Drive file.",
@@ -36045,7 +36359,7 @@ function registerExtraDriveTools(server) {
36045
36359
  account: accountParam
36046
36360
  })
36047
36361
  }, async ({ fileId, commentId, account }) => {
36048
- return runOrDiagnose(["drive", "comments", "delete", fileId, commentId, "--force"], { account });
36362
+ return runOrDiagnose(["drive", "comments", "delete", pos(fileId), pos(commentId), "--force"], { account });
36049
36363
  });
36050
36364
  server.registerTool("gog_drive_comments_reply", {
36051
36365
  description: 'Reply to an existing comment on a Drive file. Pass `action: "resolve"` or `"reopen"` to atomically flip the parent comment\'s resolved state via the Drive API\'s Reply.action field \u2014 avoids the older workaround of deleting the comment (which destroys review-thread context).',
@@ -36058,7 +36372,7 @@ function registerExtraDriveTools(server) {
36058
36372
  account: accountParam
36059
36373
  })
36060
36374
  }, async ({ fileId, commentId, content, action, account }) => {
36061
- const args = ["drive", "comments", "reply", fileId, commentId, content];
36375
+ const args = ["drive", "comments", "reply", pos(fileId), pos(commentId), pos(content)];
36062
36376
  if (action) args.push(`--action=${action}`);
36063
36377
  return runOrDiagnose(args, { account });
36064
36378
  });
@@ -36071,7 +36385,7 @@ function registerExtraDriveTools(server) {
36071
36385
  account: accountParam
36072
36386
  })
36073
36387
  }, async ({ fileId, commentId, account }) => {
36074
- return runOrDiagnose(["drive", "comments", "resolve", fileId, commentId], { account });
36388
+ return runOrDiagnose(["drive", "comments", "resolve", pos(fileId), pos(commentId)], { account });
36075
36389
  });
36076
36390
  server.registerTool("gog_drive_comments_reopen", {
36077
36391
  description: 'Reopen a previously resolved comment on a Drive file. To reopen while replying, use gog_drive_comments_reply with action: "reopen".',
@@ -36082,7 +36396,7 @@ function registerExtraDriveTools(server) {
36082
36396
  account: accountParam
36083
36397
  })
36084
36398
  }, async ({ fileId, commentId, account }) => {
36085
- return runOrDiagnose(["drive", "comments", "reopen", fileId, commentId], { account });
36399
+ return runOrDiagnose(["drive", "comments", "reopen", pos(fileId), pos(commentId)], { account });
36086
36400
  });
36087
36401
  server.registerTool("gog_drive_du", {
36088
36402
  description: "Summarize Drive folder sizes (disk-usage style) starting from a folder.",
@@ -36168,7 +36482,7 @@ function registerExtraDriveTools(server) {
36168
36482
  account: accountParam
36169
36483
  })
36170
36484
  }, async ({ fileId, max, page, all, account }) => {
36171
- const args = ["drive", "revisions", "list", fileId];
36485
+ const args = ["drive", "revisions", "list", pos(fileId)];
36172
36486
  pushPaginationFlags(args, { max, page, all });
36173
36487
  return runOrDiagnose(args, { account });
36174
36488
  });
@@ -36181,7 +36495,7 @@ function registerExtraDriveTools(server) {
36181
36495
  account: accountParam
36182
36496
  })
36183
36497
  }, async ({ fileId, revisionId, account }) => {
36184
- return runOrDiagnose(["drive", "revisions", "get", fileId, revisionId], { account });
36498
+ return runOrDiagnose(["drive", "revisions", "get", pos(fileId), pos(revisionId)], { account });
36185
36499
  });
36186
36500
  server.registerTool("gog_drive_shortcut_create", {
36187
36501
  description: "Create a Drive shortcut to a file or folder inside a destination folder. Shortcuts are classified distinctly in listing/tree output and are never followed by tree scans.",
@@ -36193,7 +36507,7 @@ function registerExtraDriveTools(server) {
36193
36507
  account: accountParam
36194
36508
  })
36195
36509
  }, async ({ targetId, parent, name, account }) => {
36196
- const args = ["drive", "shortcut", "create", targetId, `--parent=${parent}`];
36510
+ const args = ["drive", "shortcut", "create", pos(targetId), `--parent=${parent}`];
36197
36511
  if (name) args.push(`--name=${name}`);
36198
36512
  return runOrDiagnose(args, { account });
36199
36513
  });
@@ -36234,7 +36548,7 @@ function registerExtraDriveTools(server) {
36234
36548
  account: accountParam
36235
36549
  })
36236
36550
  }, async ({ name, language, view, adminAccess, account }) => {
36237
- const args = ["drive", "labels", "get", name];
36551
+ const args = ["drive", "labels", "get", pos(name)];
36238
36552
  if (language) args.push(`--language=${language}`);
36239
36553
  if (view) args.push(`--view=${view}`);
36240
36554
  if (adminAccess) args.push("--admin-access");
@@ -36251,7 +36565,7 @@ function registerExtraDriveTools(server) {
36251
36565
  account: accountParam
36252
36566
  })
36253
36567
  }, async ({ fileId, max, pageToken, page, account }) => {
36254
- const args = ["drive", "labels", "file", "list", fileId];
36568
+ const args = ["drive", "labels", "file", "list", pos(fileId)];
36255
36569
  if (max !== void 0) args.push(`--max=${max}`);
36256
36570
  const token = resolvePageToken({ pageToken, page });
36257
36571
  if (token) args.push(`--page=${token}`);
@@ -36273,7 +36587,7 @@ function registerExtraDriveTools(server) {
36273
36587
  account: accountParam
36274
36588
  })
36275
36589
  }, async ({ fileId, labelId, text, selection, integer: integer2, date: date5, user, unset, fieldsJson, account }) => {
36276
- const args = ["drive", "labels", "file", "apply", fileId, labelId];
36590
+ const args = ["drive", "labels", "file", "apply", pos(fileId), pos(labelId)];
36277
36591
  if (text) for (const t of text) args.push(`--text=${t}`);
36278
36592
  if (selection) for (const s of selection) args.push(`--selection=${s}`);
36279
36593
  if (integer2) for (const i of integer2) args.push(`--integer=${i}`);
@@ -36292,7 +36606,7 @@ function registerExtraDriveTools(server) {
36292
36606
  account: accountParam
36293
36607
  })
36294
36608
  }, async ({ fileId, labelId, account }) => {
36295
- return runOrDiagnose(["drive", "labels", "file", "remove", fileId, labelId, "--force"], { account });
36609
+ return runOrDiagnose(["drive", "labels", "file", "remove", pos(fileId), pos(labelId), "--force"], { account });
36296
36610
  });
36297
36611
  server.registerTool("gog_drive_activity", {
36298
36612
  description: "Query the Drive Activity API for audit events (edits, creates, deletes, moves, shares, etc.) scoped to a file or folder and/or time range.",
@@ -36365,7 +36679,7 @@ function registerExtraDriveTools(server) {
36365
36679
  account: accountParam
36366
36680
  })
36367
36681
  }, async ({ user, file: file2, parent, depth, max, noAllDrives, account }) => {
36368
- const args = ["drive", "audit", "user", user];
36682
+ const args = ["drive", "audit", "user", pos(user)];
36369
36683
  if (file2) args.push(`--file=${file2}`);
36370
36684
  if (parent) args.push(`--parent=${parent}`);
36371
36685
  if (depth !== void 0) args.push(`--depth=${depth}`);