gogcli-mcp-gmail 2.26.0 → 2.27.1
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 +481 -196
- package/manifest.json +1 -1
- package/mint.yaml +1 -1
- package/package.json +2 -2
- package/src/tools/gmail-extra.ts +5 -111
- package/tests/tools/gmail-extra.test.ts +0 -146
package/dist/index.js
CHANGED
|
@@ -3109,9 +3109,28 @@ var require_utils = __commonJS({
|
|
|
3109
3109
|
"use strict";
|
|
3110
3110
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
3111
3111
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
3112
|
+
var isPort = RegExp.prototype.test.bind(/^\d*$/u);
|
|
3112
3113
|
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
3113
3114
|
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
3114
|
-
var isPathCharacter = RegExp.prototype.test.bind(/^[
|
|
3115
|
+
var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
|
|
3116
|
+
var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/?]$/u);
|
|
3117
|
+
var isUserinfoCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:]$/u);
|
|
3118
|
+
var BYTE_HEX = new Array(256);
|
|
3119
|
+
{
|
|
3120
|
+
const HEX_DIGITS = "0123456789ABCDEF";
|
|
3121
|
+
for (let i = 0; i < 256; i++) {
|
|
3122
|
+
BYTE_HEX[i] = "%" + HEX_DIGITS[i >> 4] + HEX_DIGITS[i & 15];
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3125
|
+
function percentEncodeNonAscii(cp) {
|
|
3126
|
+
if (cp < 2048) {
|
|
3127
|
+
return BYTE_HEX[192 | cp >> 6] + BYTE_HEX[128 | cp & 63];
|
|
3128
|
+
}
|
|
3129
|
+
if (cp < 65536) {
|
|
3130
|
+
return BYTE_HEX[224 | cp >> 12] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
|
|
3131
|
+
}
|
|
3132
|
+
return BYTE_HEX[240 | cp >> 18] + BYTE_HEX[128 | cp >> 12 & 63] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
|
|
3133
|
+
}
|
|
3115
3134
|
function stringArrayToHexStripped(input) {
|
|
3116
3135
|
let acc = "";
|
|
3117
3136
|
let code = 0;
|
|
@@ -3136,91 +3155,105 @@ var require_utils = __commonJS({
|
|
|
3136
3155
|
}
|
|
3137
3156
|
return acc;
|
|
3138
3157
|
}
|
|
3158
|
+
var isHextet = RegExp.prototype.test.bind(/^[\dA-Fa-f]{1,4}$/);
|
|
3159
|
+
var isIPvFuture = RegExp.prototype.test.bind(/^[vV][\dA-Fa-f]+\.[A-Za-z\d\-._~!$&'()*+,;=:]+$/);
|
|
3160
|
+
var isZoneCharacter = RegExp.prototype.test.bind(/^[A-Za-z\d\-._~]$/);
|
|
3139
3161
|
var nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
|
|
3140
|
-
function
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
if (hex3 !== "") {
|
|
3148
|
-
address.push(hex3);
|
|
3149
|
-
} else {
|
|
3150
|
-
output.error = true;
|
|
3151
|
-
return false;
|
|
3162
|
+
function isZoneIdentifier(zone) {
|
|
3163
|
+
if (zone.length === 0) return false;
|
|
3164
|
+
for (let i = 0; i < zone.length; i++) {
|
|
3165
|
+
if (isZoneCharacter(zone[i])) continue;
|
|
3166
|
+
if (zone[i] === "%" && i + 2 < zone.length && isHexPair(zone.slice(i + 1, i + 3))) {
|
|
3167
|
+
i += 2;
|
|
3168
|
+
continue;
|
|
3152
3169
|
}
|
|
3153
|
-
|
|
3170
|
+
return false;
|
|
3154
3171
|
}
|
|
3155
3172
|
return true;
|
|
3156
3173
|
}
|
|
3157
|
-
function
|
|
3158
|
-
let
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
let
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
}
|
|
3170
|
-
if (cursor === ":") {
|
|
3171
|
-
if (endipv6Encountered === true) {
|
|
3172
|
-
endIpv6 = true;
|
|
3173
|
-
}
|
|
3174
|
-
if (!consume(buffer, address, output)) {
|
|
3175
|
-
break;
|
|
3176
|
-
}
|
|
3177
|
-
if (++tokenCount > 7) {
|
|
3178
|
-
output.error = true;
|
|
3179
|
-
break;
|
|
3174
|
+
function compressIPv6ZeroRun(hextets) {
|
|
3175
|
+
let bestStart = -1;
|
|
3176
|
+
let bestLength = 0;
|
|
3177
|
+
let runStart = -1;
|
|
3178
|
+
let runLength = 0;
|
|
3179
|
+
for (let i = 0; i < hextets.length; i++) {
|
|
3180
|
+
if (hextets[i] === "0") {
|
|
3181
|
+
if (runStart === -1) runStart = i;
|
|
3182
|
+
runLength++;
|
|
3183
|
+
if (runLength > bestLength) {
|
|
3184
|
+
bestLength = runLength;
|
|
3185
|
+
bestStart = runStart;
|
|
3180
3186
|
}
|
|
3181
|
-
if (i > 0 && input[i - 1] === ":") {
|
|
3182
|
-
endipv6Encountered = true;
|
|
3183
|
-
}
|
|
3184
|
-
address.push(":");
|
|
3185
|
-
continue;
|
|
3186
|
-
} else if (cursor === "%") {
|
|
3187
|
-
if (!consume(buffer, address, output)) {
|
|
3188
|
-
break;
|
|
3189
|
-
}
|
|
3190
|
-
consume = consumeIsZone;
|
|
3191
3187
|
} else {
|
|
3192
|
-
|
|
3188
|
+
runStart = -1;
|
|
3189
|
+
runLength = 0;
|
|
3190
|
+
}
|
|
3191
|
+
}
|
|
3192
|
+
if (bestLength < 2) return hextets.join(":");
|
|
3193
|
+
const head = hextets.slice(0, bestStart).join(":");
|
|
3194
|
+
const tail = hextets.slice(bestStart + bestLength).join(":");
|
|
3195
|
+
return head + "::" + tail;
|
|
3196
|
+
}
|
|
3197
|
+
function normalizeIPv6Address(input) {
|
|
3198
|
+
const compression = input.indexOf("::");
|
|
3199
|
+
if (compression !== -1 && input.indexOf("::", compression + 1) !== -1) return void 0;
|
|
3200
|
+
const left = compression === -1 ? input.split(":") : input.slice(0, compression).split(":");
|
|
3201
|
+
const right = compression === -1 ? [] : input.slice(compression + 2).split(":");
|
|
3202
|
+
if (compression !== -1) {
|
|
3203
|
+
if (left.length === 1 && left[0] === "") left.length = 0;
|
|
3204
|
+
if (right.length === 1 && right[0] === "") right.length = 0;
|
|
3205
|
+
}
|
|
3206
|
+
const parts = left.concat(right);
|
|
3207
|
+
let hextetCount = 0;
|
|
3208
|
+
for (let i = 0; i < parts.length; i++) {
|
|
3209
|
+
const part = parts[i];
|
|
3210
|
+
if (part === "") return void 0;
|
|
3211
|
+
if (part.indexOf(".") !== -1) {
|
|
3212
|
+
if (i !== parts.length - 1 || compression !== -1 && right.length === 0 || !isIPv4(part)) return void 0;
|
|
3213
|
+
hextetCount += 2;
|
|
3193
3214
|
continue;
|
|
3194
3215
|
}
|
|
3216
|
+
if (!isHextet(part)) return void 0;
|
|
3217
|
+
parts[i] = parseInt(part, 16).toString(16);
|
|
3218
|
+
hextetCount++;
|
|
3195
3219
|
}
|
|
3196
|
-
if (
|
|
3197
|
-
if (
|
|
3198
|
-
|
|
3199
|
-
} else if (endIpv6) {
|
|
3200
|
-
address.push(buffer.join(""));
|
|
3201
|
-
} else {
|
|
3202
|
-
address.push(stringArrayToHexStripped(buffer));
|
|
3203
|
-
}
|
|
3220
|
+
if (compression === -1) {
|
|
3221
|
+
if (hextetCount !== 8) return void 0;
|
|
3222
|
+
return compressIPv6ZeroRun(parts);
|
|
3204
3223
|
}
|
|
3205
|
-
|
|
3206
|
-
|
|
3224
|
+
if (hextetCount >= 8) return void 0;
|
|
3225
|
+
const expanded = parts.slice(0, left.length);
|
|
3226
|
+
for (let i = hextetCount; i < 8; i++) expanded.push("0");
|
|
3227
|
+
for (let i = left.length; i < parts.length; i++) expanded.push(parts[i]);
|
|
3228
|
+
return compressIPv6ZeroRun(expanded);
|
|
3207
3229
|
}
|
|
3208
3230
|
function normalizeIPv6(host) {
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
}
|
|
3212
|
-
|
|
3213
|
-
if (
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3231
|
+
const bracketed = host[0] === "[" && host[host.length - 1] === "]";
|
|
3232
|
+
const hasBracket = host[0] === "[" || host[host.length - 1] === "]";
|
|
3233
|
+
if (hasBracket && !bracketed) return { host, isIPV6: false, error: true };
|
|
3234
|
+
let input = bracketed ? host.slice(1, -1) : host;
|
|
3235
|
+
if (bracketed && isIPvFuture(input)) {
|
|
3236
|
+
input = input.toLowerCase();
|
|
3237
|
+
return { host: `[${input}]`, escapedHost: input, isIPV6: false, isIPVFuture: true };
|
|
3238
|
+
}
|
|
3239
|
+
if (findToken(input, ":") < 2) {
|
|
3240
|
+
return { host, isIPV6: false, error: bracketed };
|
|
3241
|
+
}
|
|
3242
|
+
let zoneIdentifier = "";
|
|
3243
|
+
const zoneSeparator = input.indexOf("%");
|
|
3244
|
+
if (zoneSeparator !== -1) {
|
|
3245
|
+
const separatorLength = input.slice(zoneSeparator, zoneSeparator + 3).toLowerCase() === "%25" ? 3 : 1;
|
|
3246
|
+
zoneIdentifier = input.slice(zoneSeparator + separatorLength);
|
|
3247
|
+
if (!isZoneIdentifier(zoneIdentifier)) return { host, isIPV6: false, error: true };
|
|
3248
|
+
input = input.slice(0, zoneSeparator);
|
|
3249
|
+
}
|
|
3250
|
+
const address = normalizeIPv6Address(input);
|
|
3251
|
+
if (address === void 0) return { host, isIPV6: false, error: true };
|
|
3252
|
+
return {
|
|
3253
|
+
host: address + (zoneIdentifier ? "%" + zoneIdentifier : ""),
|
|
3254
|
+
escapedHost: address + (zoneIdentifier ? "%25" + zoneIdentifier : ""),
|
|
3255
|
+
isIPV6: true
|
|
3256
|
+
};
|
|
3224
3257
|
}
|
|
3225
3258
|
function findToken(str, token) {
|
|
3226
3259
|
let ind = 0;
|
|
@@ -3339,7 +3372,8 @@ var require_utils = __commonJS({
|
|
|
3339
3372
|
function normalizePathEncoding(input) {
|
|
3340
3373
|
let output = "";
|
|
3341
3374
|
for (let i = 0; i < input.length; i++) {
|
|
3342
|
-
|
|
3375
|
+
const ch = input[i];
|
|
3376
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
3343
3377
|
const hex3 = input.slice(i + 1, i + 3);
|
|
3344
3378
|
if (isHexPair(hex3)) {
|
|
3345
3379
|
const normalizedHex = hex3.toUpperCase();
|
|
@@ -3353,10 +3387,152 @@ var require_utils = __commonJS({
|
|
|
3353
3387
|
continue;
|
|
3354
3388
|
}
|
|
3355
3389
|
}
|
|
3356
|
-
if (isPathCharacter(
|
|
3357
|
-
output +=
|
|
3390
|
+
if (isPathCharacter(ch)) {
|
|
3391
|
+
output += ch;
|
|
3392
|
+
} else {
|
|
3393
|
+
const code = input.charCodeAt(i);
|
|
3394
|
+
if (code < 128) {
|
|
3395
|
+
output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
|
|
3396
|
+
} else if (code < 55296 || code > 57343) {
|
|
3397
|
+
output += percentEncodeNonAscii(code);
|
|
3398
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
3399
|
+
const low = input.charCodeAt(i + 1);
|
|
3400
|
+
if (low >= 56320 && low <= 57343) {
|
|
3401
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
3402
|
+
i++;
|
|
3403
|
+
} else {
|
|
3404
|
+
output += percentEncodeNonAscii(65533);
|
|
3405
|
+
}
|
|
3406
|
+
} else {
|
|
3407
|
+
output += percentEncodeNonAscii(65533);
|
|
3408
|
+
}
|
|
3409
|
+
}
|
|
3410
|
+
}
|
|
3411
|
+
return output;
|
|
3412
|
+
}
|
|
3413
|
+
function serializePathEncoding(input, pathNoScheme = false) {
|
|
3414
|
+
let output = "";
|
|
3415
|
+
let firstSegment = pathNoScheme && input[0] !== "/";
|
|
3416
|
+
for (let i = 0; i < input.length; i++) {
|
|
3417
|
+
const ch = input[i];
|
|
3418
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
3419
|
+
const hex3 = input.slice(i + 1, i + 3);
|
|
3420
|
+
if (isHexPair(hex3)) {
|
|
3421
|
+
output += "%" + hex3.toUpperCase();
|
|
3422
|
+
i += 2;
|
|
3423
|
+
continue;
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
if (ch === "/") {
|
|
3427
|
+
firstSegment = false;
|
|
3428
|
+
}
|
|
3429
|
+
if (isPathCharacter(ch) && (ch !== ":" || !firstSegment)) {
|
|
3430
|
+
output += ch;
|
|
3431
|
+
} else {
|
|
3432
|
+
const code = input.charCodeAt(i);
|
|
3433
|
+
if (code < 128) {
|
|
3434
|
+
output += BYTE_HEX[code];
|
|
3435
|
+
} else if (code < 55296 || code > 57343) {
|
|
3436
|
+
output += percentEncodeNonAscii(code);
|
|
3437
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
3438
|
+
const low = input.charCodeAt(i + 1);
|
|
3439
|
+
if (low >= 56320 && low <= 57343) {
|
|
3440
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
3441
|
+
i++;
|
|
3442
|
+
} else {
|
|
3443
|
+
output += percentEncodeNonAscii(65533);
|
|
3444
|
+
}
|
|
3445
|
+
} else {
|
|
3446
|
+
output += percentEncodeNonAscii(65533);
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
return output;
|
|
3451
|
+
}
|
|
3452
|
+
function encodeComponent(input, isAllowed) {
|
|
3453
|
+
let output = "";
|
|
3454
|
+
for (let i = 0; i < input.length; i++) {
|
|
3455
|
+
const ch = input[i];
|
|
3456
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
3457
|
+
const hex3 = input.slice(i + 1, i + 3);
|
|
3458
|
+
if (isHexPair(hex3)) {
|
|
3459
|
+
output += "%" + hex3.toUpperCase();
|
|
3460
|
+
i += 2;
|
|
3461
|
+
continue;
|
|
3462
|
+
}
|
|
3463
|
+
}
|
|
3464
|
+
if (isAllowed(ch)) {
|
|
3465
|
+
output += ch;
|
|
3466
|
+
} else {
|
|
3467
|
+
const code = input.charCodeAt(i);
|
|
3468
|
+
if (code < 128) {
|
|
3469
|
+
output += BYTE_HEX[code];
|
|
3470
|
+
} else if (code < 55296 || code > 57343) {
|
|
3471
|
+
output += percentEncodeNonAscii(code);
|
|
3472
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
3473
|
+
const low = input.charCodeAt(i + 1);
|
|
3474
|
+
if (low >= 56320 && low <= 57343) {
|
|
3475
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
3476
|
+
i++;
|
|
3477
|
+
} else {
|
|
3478
|
+
output += percentEncodeNonAscii(65533);
|
|
3479
|
+
}
|
|
3480
|
+
} else {
|
|
3481
|
+
output += percentEncodeNonAscii(65533);
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3485
|
+
return output;
|
|
3486
|
+
}
|
|
3487
|
+
function encodeUserinfo(input) {
|
|
3488
|
+
return encodeComponent(input, isUserinfoCharacter);
|
|
3489
|
+
}
|
|
3490
|
+
function encodeQuery(input) {
|
|
3491
|
+
return encodeComponent(input, isQueryFragmentCharacter);
|
|
3492
|
+
}
|
|
3493
|
+
function encodeFragment(input) {
|
|
3494
|
+
return encodeComponent(input, isQueryFragmentCharacter);
|
|
3495
|
+
}
|
|
3496
|
+
function isEscapeSafe(cp) {
|
|
3497
|
+
return cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp === 42 || cp === 43 || cp === 45 || cp === 46 || cp === 47 || cp === 64 || cp === 95;
|
|
3498
|
+
}
|
|
3499
|
+
function normalizeQueryFragmentEncoding(input) {
|
|
3500
|
+
let output = "";
|
|
3501
|
+
for (let i = 0; i < input.length; i++) {
|
|
3502
|
+
const ch = input[i];
|
|
3503
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
3504
|
+
const hex3 = input.slice(i + 1, i + 3);
|
|
3505
|
+
if (isHexPair(hex3)) {
|
|
3506
|
+
const normalizedHex = hex3.toUpperCase();
|
|
3507
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
3508
|
+
if (isUnreserved(decoded)) {
|
|
3509
|
+
output += decoded;
|
|
3510
|
+
} else {
|
|
3511
|
+
output += "%" + normalizedHex;
|
|
3512
|
+
}
|
|
3513
|
+
i += 2;
|
|
3514
|
+
continue;
|
|
3515
|
+
}
|
|
3516
|
+
}
|
|
3517
|
+
if (isQueryFragmentCharacter(ch)) {
|
|
3518
|
+
output += ch;
|
|
3358
3519
|
} else {
|
|
3359
|
-
|
|
3520
|
+
const code = input.charCodeAt(i);
|
|
3521
|
+
if (code < 128) {
|
|
3522
|
+
output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
|
|
3523
|
+
} else if (code < 55296 || code > 57343) {
|
|
3524
|
+
output += percentEncodeNonAscii(code);
|
|
3525
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
3526
|
+
const low = input.charCodeAt(i + 1);
|
|
3527
|
+
if (low >= 56320 && low <= 57343) {
|
|
3528
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
3529
|
+
i++;
|
|
3530
|
+
} else {
|
|
3531
|
+
output += percentEncodeNonAscii(65533);
|
|
3532
|
+
}
|
|
3533
|
+
} else {
|
|
3534
|
+
output += percentEncodeNonAscii(65533);
|
|
3535
|
+
}
|
|
3360
3536
|
}
|
|
3361
3537
|
}
|
|
3362
3538
|
return output;
|
|
@@ -3379,14 +3555,18 @@ var require_utils = __commonJS({
|
|
|
3379
3555
|
function recomposeAuthority(component) {
|
|
3380
3556
|
const uriTokens = [];
|
|
3381
3557
|
if (component.userinfo !== void 0) {
|
|
3382
|
-
uriTokens.push(component.userinfo);
|
|
3558
|
+
uriTokens.push(encodeUserinfo(component.userinfo));
|
|
3383
3559
|
uriTokens.push("@");
|
|
3384
3560
|
}
|
|
3385
3561
|
if (component.host !== void 0) {
|
|
3386
|
-
let host =
|
|
3562
|
+
let host = component.host;
|
|
3387
3563
|
if (!isIPv4(host)) {
|
|
3388
|
-
|
|
3389
|
-
if (ipV6res.isIPV6
|
|
3564
|
+
let ipV6res = normalizeIPv6(host);
|
|
3565
|
+
if (ipV6res.isIPV6 !== true && ipV6res.isIPVFuture !== true) {
|
|
3566
|
+
host = normalizePercentEncoding(host, true);
|
|
3567
|
+
ipV6res = normalizeIPv6(host);
|
|
3568
|
+
}
|
|
3569
|
+
if (ipV6res.isIPV6 === true || ipV6res.isIPVFuture === true) {
|
|
3390
3570
|
host = `[${ipV6res.escapedHost}]`;
|
|
3391
3571
|
} else {
|
|
3392
3572
|
host = reescapeHostDelimiters(host, false);
|
|
@@ -3395,8 +3575,12 @@ var require_utils = __commonJS({
|
|
|
3395
3575
|
uriTokens.push(host);
|
|
3396
3576
|
}
|
|
3397
3577
|
if (typeof component.port === "number" || typeof component.port === "string") {
|
|
3578
|
+
const port = String(component.port);
|
|
3579
|
+
if (!isPort(port)) {
|
|
3580
|
+
throw new TypeError("URI port is malformed.");
|
|
3581
|
+
}
|
|
3398
3582
|
uriTokens.push(":");
|
|
3399
|
-
uriTokens.push(
|
|
3583
|
+
uriTokens.push(port);
|
|
3400
3584
|
}
|
|
3401
3585
|
return uriTokens.length ? uriTokens.join("") : void 0;
|
|
3402
3586
|
}
|
|
@@ -3406,6 +3590,11 @@ var require_utils = __commonJS({
|
|
|
3406
3590
|
reescapeHostDelimiters,
|
|
3407
3591
|
normalizePercentEncoding,
|
|
3408
3592
|
normalizePathEncoding,
|
|
3593
|
+
serializePathEncoding,
|
|
3594
|
+
normalizeQueryFragmentEncoding,
|
|
3595
|
+
encodeUserinfo,
|
|
3596
|
+
encodeQuery,
|
|
3597
|
+
encodeFragment,
|
|
3409
3598
|
escapePreservingEscapes,
|
|
3410
3599
|
removeDotSegments,
|
|
3411
3600
|
isIPv4,
|
|
@@ -3421,7 +3610,7 @@ var require_schemes = __commonJS({
|
|
|
3421
3610
|
"../../node_modules/fast-uri/lib/schemes.js"(exports, module) {
|
|
3422
3611
|
"use strict";
|
|
3423
3612
|
var { isUUID } = require_utils();
|
|
3424
|
-
var URN_REG =
|
|
3613
|
+
var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
|
|
3425
3614
|
var supportedSchemeNames = (
|
|
3426
3615
|
/** @type {const} */
|
|
3427
3616
|
[
|
|
@@ -3482,9 +3671,10 @@ var require_schemes = __commonJS({
|
|
|
3482
3671
|
wsComponent.secure = void 0;
|
|
3483
3672
|
}
|
|
3484
3673
|
if (wsComponent.resourceName) {
|
|
3485
|
-
const
|
|
3674
|
+
const queryIndex = wsComponent.resourceName.indexOf("?");
|
|
3675
|
+
const path = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
|
|
3486
3676
|
wsComponent.path = path && path !== "/" ? path : void 0;
|
|
3487
|
-
wsComponent.query =
|
|
3677
|
+
wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
|
|
3488
3678
|
wsComponent.resourceName = void 0;
|
|
3489
3679
|
}
|
|
3490
3680
|
wsComponent.fragment = void 0;
|
|
@@ -3496,7 +3686,7 @@ var require_schemes = __commonJS({
|
|
|
3496
3686
|
return urnComponent;
|
|
3497
3687
|
}
|
|
3498
3688
|
const matches = urnComponent.path.match(URN_REG);
|
|
3499
|
-
if (matches) {
|
|
3689
|
+
if (matches && matches[0] === urnComponent.path) {
|
|
3500
3690
|
const scheme = options.scheme || urnComponent.scheme || "urn";
|
|
3501
3691
|
urnComponent.nid = matches[1].toLowerCase();
|
|
3502
3692
|
urnComponent.nss = matches[2];
|
|
@@ -3630,8 +3820,17 @@ var require_schemes = __commonJS({
|
|
|
3630
3820
|
var require_fast_uri = __commonJS({
|
|
3631
3821
|
"../../node_modules/fast-uri/index.js"(exports, module) {
|
|
3632
3822
|
"use strict";
|
|
3633
|
-
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding,
|
|
3823
|
+
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
3634
3824
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
3825
|
+
var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
|
|
3826
|
+
var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
|
|
3827
|
+
function decodeValidScheme(scheme) {
|
|
3828
|
+
const decodedScheme = unescape(String(scheme));
|
|
3829
|
+
if (!VALID_SCHEME.test(decodedScheme)) {
|
|
3830
|
+
throw new TypeError(MALFORMED_SCHEME_ERROR);
|
|
3831
|
+
}
|
|
3832
|
+
return decodedScheme;
|
|
3833
|
+
}
|
|
3635
3834
|
function normalize(uri, options) {
|
|
3636
3835
|
if (typeof uri === "string") {
|
|
3637
3836
|
uri = /** @type {T} */
|
|
@@ -3644,12 +3843,34 @@ var require_fast_uri = __commonJS({
|
|
|
3644
3843
|
}
|
|
3645
3844
|
function resolve(baseURI, relativeURI, options) {
|
|
3646
3845
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3647
|
-
const {
|
|
3648
|
-
|
|
3649
|
-
|
|
3846
|
+
const {
|
|
3847
|
+
parsed: baseParsed,
|
|
3848
|
+
malformedAuthorityOrPort: baseMalformed,
|
|
3849
|
+
malformedPercentEncoding: baseMalformedPercentEncoding,
|
|
3850
|
+
malformedSchemeSpecific: baseMalformedSchemeSpecific,
|
|
3851
|
+
malformedHost: baseMalformedHost,
|
|
3852
|
+
malformedScheme: baseMalformedScheme
|
|
3853
|
+
} = parseWithStatus(baseURI, schemelessOptions);
|
|
3854
|
+
const {
|
|
3855
|
+
parsed: relativeParsed,
|
|
3856
|
+
malformedAuthorityOrPort: relativeMalformed,
|
|
3857
|
+
malformedPercentEncoding: relativeMalformedPercentEncoding,
|
|
3858
|
+
malformedSchemeSpecific: relativeMalformedSchemeSpecific,
|
|
3859
|
+
malformedHost: relativeMalformedHost,
|
|
3860
|
+
malformedScheme: relativeMalformedScheme
|
|
3861
|
+
} = parseWithStatus(relativeURI, schemelessOptions);
|
|
3862
|
+
if (baseMalformed || relativeMalformed || baseMalformedPercentEncoding || relativeMalformedPercentEncoding || baseMalformedSchemeSpecific || relativeMalformedSchemeSpecific || baseMalformedHost || relativeMalformedHost || baseMalformedScheme || relativeMalformedScheme) {
|
|
3650
3863
|
throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
|
|
3651
3864
|
}
|
|
3652
3865
|
const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
|
|
3866
|
+
const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
|
|
3867
|
+
const resolvedHost = resolved.host;
|
|
3868
|
+
const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
|
|
3869
|
+
canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
|
|
3870
|
+
const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !/\P{ASCII}/u.test(resolvedHost);
|
|
3871
|
+
if (resolved.error && !encodedASCIIHost) {
|
|
3872
|
+
throw new Error(resolved.error);
|
|
3873
|
+
}
|
|
3653
3874
|
schemelessOptions.skipEscape = true;
|
|
3654
3875
|
return serialize(resolved, schemelessOptions);
|
|
3655
3876
|
}
|
|
@@ -3709,7 +3930,7 @@ var require_fast_uri = __commonJS({
|
|
|
3709
3930
|
function equal(uriA, uriB, options) {
|
|
3710
3931
|
const normalizedA = normalizeComparableURI(uriA, options);
|
|
3711
3932
|
const normalizedB = normalizeComparableURI(uriB, options);
|
|
3712
|
-
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA
|
|
3933
|
+
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA === normalizedB;
|
|
3713
3934
|
}
|
|
3714
3935
|
function serialize(cmpts, opts) {
|
|
3715
3936
|
const component = {
|
|
@@ -3730,19 +3951,22 @@ var require_fast_uri = __commonJS({
|
|
|
3730
3951
|
};
|
|
3731
3952
|
const options = Object.assign({}, opts);
|
|
3732
3953
|
const uriTokens = [];
|
|
3954
|
+
if (component.scheme) {
|
|
3955
|
+
component.scheme = decodeValidScheme(component.scheme);
|
|
3956
|
+
}
|
|
3733
3957
|
const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
|
|
3734
3958
|
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
|
|
3959
|
+
const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
|
|
3960
|
+
const pathNoScheme = !options.skipEscape && component.scheme === void 0 && !hasAuthority;
|
|
3735
3961
|
if (component.path !== void 0) {
|
|
3736
3962
|
if (!options.skipEscape) {
|
|
3737
|
-
component.path =
|
|
3738
|
-
if (component.scheme !== void 0) {
|
|
3739
|
-
component.path = component.path.split("%3A").join(":");
|
|
3740
|
-
}
|
|
3963
|
+
component.path = serializePathEncoding(component.path, pathNoScheme);
|
|
3741
3964
|
} else {
|
|
3742
3965
|
component.path = normalizePercentEncoding(component.path);
|
|
3743
3966
|
}
|
|
3744
3967
|
}
|
|
3745
3968
|
if (options.reference !== "suffix" && component.scheme) {
|
|
3969
|
+
component.scheme = decodeValidScheme(component.scheme);
|
|
3746
3970
|
uriTokens.push(component.scheme, ":");
|
|
3747
3971
|
}
|
|
3748
3972
|
const authority = recomposeAuthority(component);
|
|
@@ -3760,16 +3984,19 @@ var require_fast_uri = __commonJS({
|
|
|
3760
3984
|
if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
|
|
3761
3985
|
s = removeDotSegments(s);
|
|
3762
3986
|
}
|
|
3987
|
+
if (pathNoScheme) {
|
|
3988
|
+
s = serializePathEncoding(s, true);
|
|
3989
|
+
}
|
|
3763
3990
|
if (authority === void 0 && s[0] === "/" && s[1] === "/") {
|
|
3764
3991
|
s = "/%2F" + s.slice(2);
|
|
3765
3992
|
}
|
|
3766
3993
|
uriTokens.push(s);
|
|
3767
3994
|
}
|
|
3768
3995
|
if (component.query !== void 0) {
|
|
3769
|
-
uriTokens.push("?", component.query);
|
|
3996
|
+
uriTokens.push("?", encodeQuery(component.query));
|
|
3770
3997
|
}
|
|
3771
3998
|
if (component.fragment !== void 0) {
|
|
3772
|
-
uriTokens.push("#", component.fragment);
|
|
3999
|
+
uriTokens.push("#", encodeFragment(component.fragment));
|
|
3773
4000
|
}
|
|
3774
4001
|
return uriTokens.join("");
|
|
3775
4002
|
}
|
|
@@ -3785,6 +4012,35 @@ var require_fast_uri = __commonJS({
|
|
|
3785
4012
|
}
|
|
3786
4013
|
return void 0;
|
|
3787
4014
|
}
|
|
4015
|
+
function hasMalformedPercentEncoding(component) {
|
|
4016
|
+
if (component === void 0) return false;
|
|
4017
|
+
let percent = component.indexOf("%");
|
|
4018
|
+
while (percent !== -1) {
|
|
4019
|
+
if (percent + 2 >= component.length || !/^[\da-f]{2}$/iu.test(component.slice(percent + 1, percent + 3))) {
|
|
4020
|
+
return true;
|
|
4021
|
+
}
|
|
4022
|
+
percent = component.indexOf("%", percent + 3);
|
|
4023
|
+
}
|
|
4024
|
+
return false;
|
|
4025
|
+
}
|
|
4026
|
+
function isIPLiteral(host) {
|
|
4027
|
+
return host[0] === "[" && host[host.length - 1] === "]";
|
|
4028
|
+
}
|
|
4029
|
+
function hasMalformedComponentPercentEncoding(matches) {
|
|
4030
|
+
const host = matches[4];
|
|
4031
|
+
return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
|
|
4032
|
+
}
|
|
4033
|
+
function canonicalizeHost(parsed, options, schemeHandler, isIP) {
|
|
4034
|
+
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
|
|
4035
|
+
try {
|
|
4036
|
+
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
4037
|
+
} catch (e) {
|
|
4038
|
+
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
4039
|
+
return true;
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4042
|
+
return false;
|
|
4043
|
+
}
|
|
3788
4044
|
function parseWithStatus(uri, opts) {
|
|
3789
4045
|
const options = Object.assign({}, opts);
|
|
3790
4046
|
const parsed = {
|
|
@@ -3797,6 +4053,11 @@ var require_fast_uri = __commonJS({
|
|
|
3797
4053
|
fragment: void 0
|
|
3798
4054
|
};
|
|
3799
4055
|
let malformedAuthorityOrPort = false;
|
|
4056
|
+
let malformedPercentEncoding = false;
|
|
4057
|
+
let malformedSchemeSpecific = false;
|
|
4058
|
+
let malformedHost = false;
|
|
4059
|
+
let malformedIPLiteral = false;
|
|
4060
|
+
let malformedScheme = false;
|
|
3800
4061
|
let isIP = false;
|
|
3801
4062
|
if (options.reference === "suffix") {
|
|
3802
4063
|
if (options.scheme) {
|
|
@@ -3833,6 +4094,19 @@ var require_fast_uri = __commonJS({
|
|
|
3833
4094
|
parsed.path = matches[6] || "";
|
|
3834
4095
|
parsed.query = matches[7];
|
|
3835
4096
|
parsed.fragment = matches[8];
|
|
4097
|
+
if (parsed.scheme !== void 0) {
|
|
4098
|
+
const decodedScheme = unescape(parsed.scheme);
|
|
4099
|
+
if (VALID_SCHEME.test(decodedScheme)) {
|
|
4100
|
+
parsed.scheme = decodedScheme.toLowerCase();
|
|
4101
|
+
} else {
|
|
4102
|
+
parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
|
|
4103
|
+
malformedScheme = true;
|
|
4104
|
+
}
|
|
4105
|
+
}
|
|
4106
|
+
malformedPercentEncoding = hasMalformedComponentPercentEncoding(matches);
|
|
4107
|
+
if (malformedPercentEncoding) {
|
|
4108
|
+
parsed.error = parsed.error || "URI contains malformed percent-encoding.";
|
|
4109
|
+
}
|
|
3836
4110
|
if (isNaN(parsed.port)) {
|
|
3837
4111
|
parsed.port = matches[5];
|
|
3838
4112
|
}
|
|
@@ -3844,9 +4118,16 @@ var require_fast_uri = __commonJS({
|
|
|
3844
4118
|
if (parsed.host) {
|
|
3845
4119
|
const ipv4result = isIPv4(parsed.host);
|
|
3846
4120
|
if (ipv4result === false) {
|
|
4121
|
+
const bracketedIPLiteral = isIPLiteral(parsed.host);
|
|
4122
|
+
const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
|
|
3847
4123
|
const ipv6result = normalizeIPv6(parsed.host);
|
|
3848
|
-
|
|
3849
|
-
|
|
4124
|
+
isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
|
|
4125
|
+
malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
|
|
4126
|
+
parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
|
|
4127
|
+
if (malformedIPLiteral) {
|
|
4128
|
+
parsed.error = parsed.error || "URI host is malformed.";
|
|
4129
|
+
malformedAuthorityOrPort = true;
|
|
4130
|
+
}
|
|
3850
4131
|
} else {
|
|
3851
4132
|
isIP = true;
|
|
3852
4133
|
}
|
|
@@ -3864,42 +4145,36 @@ var require_fast_uri = __commonJS({
|
|
|
3864
4145
|
parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
|
|
3865
4146
|
}
|
|
3866
4147
|
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
|
|
3867
|
-
if (!
|
|
3868
|
-
|
|
3869
|
-
try {
|
|
3870
|
-
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
3871
|
-
} catch (e) {
|
|
3872
|
-
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
3873
|
-
}
|
|
3874
|
-
}
|
|
4148
|
+
if (!malformedIPLiteral) {
|
|
4149
|
+
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
|
|
3875
4150
|
}
|
|
3876
4151
|
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
|
|
3877
4152
|
if (uri.indexOf("%") !== -1) {
|
|
3878
|
-
if (parsed.
|
|
3879
|
-
parsed.
|
|
3880
|
-
|
|
3881
|
-
if (parsed.host !== void 0) {
|
|
3882
|
-
parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
|
|
4153
|
+
if (parsed.host !== void 0 && !malformedIPLiteral) {
|
|
4154
|
+
const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
4155
|
+
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
3883
4156
|
}
|
|
3884
4157
|
}
|
|
3885
4158
|
if (parsed.path) {
|
|
3886
4159
|
parsed.path = normalizePathEncoding(parsed.path);
|
|
3887
4160
|
}
|
|
4161
|
+
if (parsed.query) {
|
|
4162
|
+
parsed.query = normalizeQueryFragmentEncoding(parsed.query);
|
|
4163
|
+
}
|
|
3888
4164
|
if (parsed.fragment) {
|
|
3889
|
-
|
|
3890
|
-
parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
|
|
3891
|
-
} catch {
|
|
3892
|
-
parsed.error = parsed.error || "URI malformed";
|
|
3893
|
-
}
|
|
4165
|
+
parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
|
|
3894
4166
|
}
|
|
3895
4167
|
}
|
|
3896
4168
|
if (schemeHandler && schemeHandler.parse) {
|
|
3897
4169
|
schemeHandler.parse(parsed, options);
|
|
4170
|
+
if (schemeHandler === SCHEMES.urn && parsed.nid === void 0) {
|
|
4171
|
+
malformedSchemeSpecific = true;
|
|
4172
|
+
}
|
|
3898
4173
|
}
|
|
3899
4174
|
} else {
|
|
3900
4175
|
parsed.error = parsed.error || "URI can not be parsed.";
|
|
3901
4176
|
}
|
|
3902
|
-
return { parsed, malformedAuthorityOrPort };
|
|
4177
|
+
return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
|
|
3903
4178
|
}
|
|
3904
4179
|
function parse3(uri, opts) {
|
|
3905
4180
|
return parseWithStatus(uri, opts).parsed;
|
|
@@ -3908,20 +4183,28 @@ var require_fast_uri = __commonJS({
|
|
|
3908
4183
|
return normalizeStringWithStatus(uri, opts).normalized;
|
|
3909
4184
|
}
|
|
3910
4185
|
function normalizeStringWithStatus(uri, opts) {
|
|
3911
|
-
const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
|
|
4186
|
+
const { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = parseWithStatus(uri, opts);
|
|
3912
4187
|
return {
|
|
3913
|
-
normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
|
|
3914
|
-
malformedAuthorityOrPort
|
|
4188
|
+
normalized: malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? uri : serialize(parsed, opts),
|
|
4189
|
+
malformedAuthorityOrPort,
|
|
4190
|
+
malformedPercentEncoding,
|
|
4191
|
+
malformedSchemeSpecific,
|
|
4192
|
+
malformedHost,
|
|
4193
|
+
malformedScheme
|
|
3915
4194
|
};
|
|
3916
4195
|
}
|
|
3917
4196
|
function normalizeComparableURI(uri, opts) {
|
|
3918
|
-
if (typeof uri
|
|
3919
|
-
|
|
3920
|
-
return malformedAuthorityOrPort ? void 0 : normalized;
|
|
4197
|
+
if (typeof uri !== "string" && typeof uri !== "object") {
|
|
4198
|
+
return void 0;
|
|
3921
4199
|
}
|
|
3922
|
-
|
|
3923
|
-
|
|
4200
|
+
let value;
|
|
4201
|
+
try {
|
|
4202
|
+
value = typeof uri === "string" ? uri : serialize(uri, opts);
|
|
4203
|
+
} catch {
|
|
4204
|
+
return void 0;
|
|
3924
4205
|
}
|
|
4206
|
+
const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value, opts);
|
|
4207
|
+
return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? void 0 : normalized;
|
|
3925
4208
|
}
|
|
3926
4209
|
var fastUri = {
|
|
3927
4210
|
SCHEMES,
|
|
@@ -31809,6 +32092,13 @@ function formatAuthHealth(raw, now) {
|
|
|
31809
32092
|
}
|
|
31810
32093
|
return accounts.map((a) => formatOneAccountHealth(a, now)).join("\n\n");
|
|
31811
32094
|
}
|
|
32095
|
+
function assertNotBoth(inlineParam, fileParam, inlineValue, fileValue) {
|
|
32096
|
+
if (inlineValue !== void 0 && fileValue !== void 0) {
|
|
32097
|
+
throw new Error(
|
|
32098
|
+
`${inlineParam} and ${fileParam} are mutually exclusive \u2014 gog accepts only one of them. Pass ${inlineParam} with the content itself (it is written to a temp file automatically when large), or ${fileParam} with a path that already exists on the gog server.`
|
|
32099
|
+
);
|
|
32100
|
+
}
|
|
32101
|
+
}
|
|
31812
32102
|
|
|
31813
32103
|
// ../gogcli-mcp/src/tools/auth.ts
|
|
31814
32104
|
function registerAuthToolsWith(server, defaultServices) {
|
|
@@ -32133,6 +32423,45 @@ function finish(base, itemsKey, merged, token) {
|
|
|
32133
32423
|
}
|
|
32134
32424
|
|
|
32135
32425
|
// ../gogcli-mcp/src/tools/gmail.ts
|
|
32426
|
+
var replySchema = {
|
|
32427
|
+
messageId: external_exports.string().describe("Gmail message ID to reply to \u2014 the short hex `id` from gog_gmail_get / _search (or gog_gmail_messages_search, gogcli-mcp-gmail only). NOT the threadId, NOT the RFC822 `<\u2026@host>` Message-Id header."),
|
|
32428
|
+
body: external_exports.string().optional().describe("Reply body (plain text; required unless bodyHtml or bodyHtmlFile is set). Any size \u2014 a large body is written to a temp file on the gog server rather than inlined into the command line. Note gog strips trailing newlines from a file-delivered body."),
|
|
32429
|
+
bodyHtml: external_exports.string().optional().describe("Reply body (HTML; optional). Pass the HTML itself at any size \u2014 a large body is written to a temp file on the gog server rather than inlined into the command line. Mutually exclusive with bodyHtmlFile."),
|
|
32430
|
+
bodyHtmlFile: external_exports.string().optional().describe(`Path to an HTML file that ALREADY EXISTS on the gog server for the reply body. gog also accepts "-" for stdin, but this server never writes to gog's stdin, so "-" would hang until the call times out. Mutually exclusive with bodyHtml \u2014 supplying both is rejected. You rarely need this: bodyHtml handles large bodies on its own.`),
|
|
32431
|
+
to: external_exports.array(external_exports.string()).optional().describe("Add or move recipients to To (repeatable). Added on top of the recipients inherited from the original message."),
|
|
32432
|
+
cc: external_exports.array(external_exports.string()).optional().describe("Add or move recipients to Cc (repeatable)"),
|
|
32433
|
+
bcc: external_exports.array(external_exports.string()).optional().describe("Add or move recipients to Bcc (repeatable)"),
|
|
32434
|
+
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."),
|
|
32435
|
+
subject: external_exports.string().optional().describe('Override reply subject (default: "Re: <original>"). A changed subject starts a NEW Gmail thread.'),
|
|
32436
|
+
noQuote: external_exports.boolean().optional().describe("Do not include the original message quoted below the reply (default: the original is quoted)"),
|
|
32437
|
+
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 the hosted connector or any GOG_RUNNER_URL backend 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.`),
|
|
32438
|
+
attachInline: attachInlineParam,
|
|
32439
|
+
from: external_exports.string().optional().describe("Send from this email address (must be a verified send-as alias)"),
|
|
32440
|
+
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."),
|
|
32441
|
+
signature: external_exports.boolean().optional().describe("Append the Gmail signature from the active send-as address"),
|
|
32442
|
+
signatureFrom: external_exports.string().optional().describe("Append the Gmail signature from this send-as email address"),
|
|
32443
|
+
signatureFile: external_exports.string().optional().describe("Append a local signature file (plain text or HTML), read on the gog server"),
|
|
32444
|
+
account: accountParam
|
|
32445
|
+
};
|
|
32446
|
+
function appendReplyFlags(args, f) {
|
|
32447
|
+
assertNotBoth("bodyHtml", "bodyHtmlFile", f.bodyHtml, f.bodyHtmlFile);
|
|
32448
|
+
if (f.body) args.push(payloadArg("body", "body-file", f.body));
|
|
32449
|
+
if (f.bodyHtml) args.push(payloadArg("body-html", "body-html-file", f.bodyHtml, "html"));
|
|
32450
|
+
else if (f.bodyHtmlFile) args.push(`--body-html-file=${f.bodyHtmlFile}`);
|
|
32451
|
+
if (f.to) for (const r of f.to) args.push(`--to=${r}`);
|
|
32452
|
+
if (f.cc) for (const r of f.cc) args.push(`--cc=${r}`);
|
|
32453
|
+
if (f.bcc) for (const r of f.bcc) args.push(`--bcc=${r}`);
|
|
32454
|
+
if (f.remove) for (const r of f.remove) args.push(`--remove=${r}`);
|
|
32455
|
+
if (f.subject) args.push(`--subject=${f.subject}`);
|
|
32456
|
+
if (f.noQuote) args.push("--no-quote");
|
|
32457
|
+
if (f.attach) for (const p of f.attach) args.push(`--attach=${p}`);
|
|
32458
|
+
args.push(...inlineAttachmentArgs("attach", f.attachInline, args));
|
|
32459
|
+
if (f.from) args.push(`--from=${f.from}`);
|
|
32460
|
+
if (f.signature) args.push("--signature");
|
|
32461
|
+
if (f.signatureFrom) args.push(`--signature-from=${f.signatureFrom}`);
|
|
32462
|
+
if (f.signatureFile) args.push(`--signature-file=${f.signatureFile}`);
|
|
32463
|
+
args.push(f.autoFromAddressedAlias ? "--auto-from-addressed-alias" : "--auto-from-addressed-alias=false");
|
|
32464
|
+
}
|
|
32136
32465
|
function registerGmailTools(server) {
|
|
32137
32466
|
server.registerTool("gog_gmail_search", {
|
|
32138
32467
|
description: 'Search Gmail threads using Gmail query syntax (e.g. "from:alice subject:invoice is:unread"). The query is passed verbatim to Gmail; a bare name token (from:alison) matches per Gmail\'s own heuristics, a full address (from:alison@example.com) is exact. To match a contact across several addresses, OR them: from:(a@x.com OR b@y.com). Results are ALWAYS newest-first by Gmail\'s internalDate \u2014 the wrapper sorts them, so the first result is the most recent match and a recent message can never be buried below older ones. IMPORTANT \u2014 a response carrying "truncated": true is an INCOMPLETE view of the matches: NEVER report that a message does not exist, or that there is no such mail, on the strength of one. Page through it (pass nextPageToken back as `pageToken`), set maxPages to walk several pages in one call, or narrow the query, and only then draw a conclusion. If you already know the thread, do not search for it at all \u2014 read it directly with gog_gmail_thread_get, which returns the whole thread and cannot be truncated or mis-ranked.',
|
|
@@ -32185,7 +32514,7 @@ function registerGmailTools(server) {
|
|
|
32185
32514
|
return runOrDiagnose(args, { account });
|
|
32186
32515
|
});
|
|
32187
32516
|
server.registerTool("gog_gmail_send", {
|
|
32188
|
-
description: 'Send an email. Two ways to attach a file: `attach` takes paths READ ON THE GOG SERVER, and `attachInline` takes the bytes themselves. Use attachInline unless you know the file exists on the same machine gog runs on \u2014 on the hosted connector and any remote deployment there is no shared filesystem, so no path you can name resolves there and `attach` will fail with "no such file or directory". When either is used, the JSON result echoes the attached filenames and byte sizes \u2014 check it to confirm the files were embedded.',
|
|
32517
|
+
description: 'Send an email. Two ways to attach a file: `attach` takes paths READ ON THE GOG SERVER, and `attachInline` takes the bytes themselves. Use attachInline unless you know the file exists on the same machine gog runs on \u2014 on the hosted connector and any remote deployment there is no shared filesystem, so no path you can name resolves there and `attach` will fail with "no such file or directory". When either is used, the JSON result echoes the attached filenames and byte sizes \u2014 check it to confirm the files were embedded. NOT the tool for answering a message: replyToMessageId only files this in the right thread \u2014 the subject, recipients and body are entirely yours, and the original is not quoted unless you set quote. Use gog_gmail_reply / gog_gmail_reply_all instead, which inherit all three.',
|
|
32189
32518
|
annotations: { destructiveHint: true },
|
|
32190
32519
|
inputSchema: {
|
|
32191
32520
|
to: external_exports.string().describe("Recipient(s), comma-separated"),
|
|
@@ -32193,23 +32522,43 @@ function registerGmailTools(server) {
|
|
|
32193
32522
|
body: external_exports.string().describe("Email body (plain text). Any size \u2014 a large body is written to a temp file on the gog server rather than inlined into the command line. Note gog strips trailing newlines from a file-delivered body."),
|
|
32194
32523
|
cc: external_exports.string().optional().describe("CC recipients, comma-separated"),
|
|
32195
32524
|
bcc: external_exports.string().optional().describe("BCC recipients, comma-separated"),
|
|
32196
|
-
replyToMessageId: external_exports.string().optional().describe(
|
|
32197
|
-
threadId: external_exports.string().optional().describe("Thread ID to
|
|
32525
|
+
replyToMessageId: external_exports.string().optional().describe('Message ID to thread this message against \u2014 sets In-Reply-To/References only. It does NOT quote the original (pass quote for that), inherit its recipients, or prefix the subject with "Re:". For an actual reply use gog_gmail_reply.'),
|
|
32526
|
+
threadId: external_exports.string().optional().describe("Thread ID to thread this message within. Same caveat as replyToMessageId: threading only, no quote and no inherited subject or recipients."),
|
|
32527
|
+
quote: external_exports.boolean().optional().describe("Include the original message quoted below the body. Requires replyToMessageId or threadId. gog quotes by DEFAULT on gmail reply but never on gmail send, so without this a threaded send arrives with the original nowhere in it."),
|
|
32198
32528
|
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 the hosted connector or any GOG_RUNNER_URL backend these paths do not exist and the call fails with "no such file or directory" \u2014 use attachInline there. Each file is read on the server, base64-encoded with a MIME type inferred from its extension, and added as a multipart attachment.`),
|
|
32199
32529
|
attachInline: attachInlineParam,
|
|
32200
32530
|
account: accountParam
|
|
32201
32531
|
}
|
|
32202
|
-
}, async ({ to, subject, body, cc, bcc, replyToMessageId, threadId, attach, attachInline, account }) => {
|
|
32532
|
+
}, async ({ to, subject, body, cc, bcc, replyToMessageId, threadId, quote, attach, attachInline, account }) => {
|
|
32203
32533
|
const args = ["gmail", "send", `--to=${to}`, `--subject=${subject}`, payloadArg("body", "body-file", body)];
|
|
32204
32534
|
if (cc) args.push(`--cc=${cc}`);
|
|
32205
32535
|
if (bcc) args.push(`--bcc=${bcc}`);
|
|
32206
32536
|
if (replyToMessageId) args.push(`--reply-to-message-id=${replyToMessageId}`);
|
|
32207
32537
|
if (threadId) args.push(`--thread-id=${threadId}`);
|
|
32538
|
+
if (quote) args.push("--quote");
|
|
32208
32539
|
if (attach) for (const path of attach) args.push(`--attach=${path}`);
|
|
32209
32540
|
const inline = inlineAttachmentArgs("attach", attachInline, args);
|
|
32210
32541
|
args.push(...inline);
|
|
32211
32542
|
return runOrDiagnose(args, { account });
|
|
32212
32543
|
});
|
|
32544
|
+
server.registerTool("gog_gmail_reply", {
|
|
32545
|
+
description: 'Reply to a Gmail message (goes to the original sender only). USE THIS, not gog_gmail_send, whenever you are answering a message: it threads off the original AND inherits its "Re:" subject and quotes its body below yours, which gog_gmail_send does not \u2014 a send with replyToMessageId lands in the right thread but reads as a brand-new message, with the original nowhere in it. To answer every participant use gog_gmail_reply_all. The gogcli-mcp-gmail package adds two more routes with the same composition: gog_gmail_autoreply to reply across every message matching a query, and gog_gmail_drafts_reply to stage this exact reply as a draft instead of sending it.',
|
|
32546
|
+
annotations: { destructiveHint: true },
|
|
32547
|
+
inputSchema: replySchema
|
|
32548
|
+
}, async ({ messageId, account, ...flags }) => {
|
|
32549
|
+
const args = ["gmail", "reply", messageId];
|
|
32550
|
+
appendReplyFlags(args, flags);
|
|
32551
|
+
return runOrDiagnose(args, { account });
|
|
32552
|
+
});
|
|
32553
|
+
server.registerTool("gog_gmail_reply_all", {
|
|
32554
|
+
description: 'Reply to all participants of a Gmail message (the sender plus every To/Cc recipient). Same inherited "Re:" subject and quoted original as gog_gmail_reply. Use the remove flag to drop specific recipients from the reply-all. To stage it as a draft rather than send it, use gog_gmail_drafts_reply_all (gogcli-mcp-gmail only).',
|
|
32555
|
+
annotations: { destructiveHint: true },
|
|
32556
|
+
inputSchema: replySchema
|
|
32557
|
+
}, async ({ messageId, account, ...flags }) => {
|
|
32558
|
+
const args = ["gmail", "reply-all", messageId];
|
|
32559
|
+
appendReplyFlags(args, flags);
|
|
32560
|
+
return runOrDiagnose(args, { account });
|
|
32561
|
+
});
|
|
32213
32562
|
registerRunTool(server, { service: "gmail", examples: '"archive", "mark-read", "labels"' });
|
|
32214
32563
|
}
|
|
32215
32564
|
|
|
@@ -32223,7 +32572,7 @@ var failIfNotEmptyParam = external_exports.boolean().optional().describe(
|
|
|
32223
32572
|
);
|
|
32224
32573
|
|
|
32225
32574
|
// ../gogcli-mcp/src/server.ts
|
|
32226
|
-
var VERSION = true ? "2.
|
|
32575
|
+
var VERSION = true ? "2.27.1" : "0.0.0";
|
|
32227
32576
|
|
|
32228
32577
|
// ../gogcli-mcp/src/auth-log.ts
|
|
32229
32578
|
var FAILURES = /* @__PURE__ */ new Set([
|
|
@@ -32710,13 +33059,6 @@ function useRemoteGogRunner(env = process.env) {
|
|
|
32710
33059
|
}
|
|
32711
33060
|
|
|
32712
33061
|
// src/tools/gmail-extra.ts
|
|
32713
|
-
function assertNotBoth(inlineParam, fileParam, inlineValue, fileValue) {
|
|
32714
|
-
if (inlineValue !== void 0 && fileValue !== void 0) {
|
|
32715
|
-
throw new Error(
|
|
32716
|
-
`${inlineParam} and ${fileParam} are mutually exclusive \u2014 gog accepts only one of them. Pass ${inlineParam} with the content itself (it is written to a temp file automatically when large), or ${fileParam} with a path that already exists on the gog server.`
|
|
32717
|
-
);
|
|
32718
|
-
}
|
|
32719
|
-
}
|
|
32720
33062
|
function resultText(result) {
|
|
32721
33063
|
const first = result.content[0];
|
|
32722
33064
|
return first?.type === "text" ? first.text : void 0;
|
|
@@ -34192,7 +34534,7 @@ function registerExtraGmailTools(server) {
|
|
|
34192
34534
|
replyToMessageId: external_exports.string().optional().describe("Reply to a specific Gmail MESSAGE id \u2014 the short hex `id` field from gog_gmail_get / _search / _thread_get (e.g. 19e7593d77fd9636), NOT a thread id and NOT the RFC822 `<\u2026@host>` Message-Id header. Anchors In-Reply-To/References to that exact message. To reply to a thread when you don't know the latest message, use replyToThreadId instead. If both are given, replyToMessageId wins."),
|
|
34193
34535
|
replyToThreadId: external_exports.string().optional().describe(`Reply to a Gmail THREAD id \u2014 passed to gog as --thread-id, which threads the draft using the thread's latest-message headers (In-Reply-To/References). This is what "reply to this thread" almost always means. Mutually exclusive with replyToMessageId (which wins if both are set). Thread ids and message ids are both 16-hex strings and easy to confuse \u2014 use this param, not replyToMessageId, when the id came from a thread.`),
|
|
34194
34536
|
replyTo: external_exports.string().optional().describe("Reply-To header address"),
|
|
34195
|
-
quote: external_exports.boolean().optional().describe(
|
|
34537
|
+
quote: external_exports.boolean().optional().describe('Include the original message quoted below the body. Requires replyToMessageId or replyToThreadId. DEFAULTS OFF: a draft created with a reply target but without this threads correctly and still reads as a brand-new message, because gog only quotes by default on its reply subcommands. For a real reply draft prefer gog_gmail_drafts_reply / gog_gmail_drafts_reply_all, which also inherit the recipients and the "Re:" subject that this tool leaves to you.'),
|
|
34196
34538
|
replyAll: external_exports.boolean().optional().describe("Auto-populate recipients from the original message (reply-all), inferring To/Cc from it. Requires replyToMessageId or replyToThreadId. Explicit to/cc/bcc still apply on top; omitRecipients still suppresses them."),
|
|
34197
34539
|
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 the hosted connector or any GOG_RUNNER_URL backend 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. The JSON result echoes attached filenames and byte sizes \u2014 check it to confirm the files were found and embedded. On gog_gmail_drafts_update, supplying attach REPLACES the draft's existing attachments; omitting it preserves them (use clearAttachments to remove all).`),
|
|
34198
34540
|
attachInline: attachInlineParam,
|
|
@@ -34380,63 +34722,6 @@ function registerExtraGmailTools(server) {
|
|
|
34380
34722
|
if (skipAttachments) args.push("--skip-attachments");
|
|
34381
34723
|
return runOrDiagnose(args, { account });
|
|
34382
34724
|
});
|
|
34383
|
-
const replySchema = {
|
|
34384
|
-
messageId: external_exports.string().describe("Gmail message ID to reply to \u2014 the short hex `id` from gog_gmail_get / _search / _messages_search (NOT the threadId, NOT the RFC822 `<\u2026@host>` Message-Id header)."),
|
|
34385
|
-
body: external_exports.string().optional().describe("Reply body (plain text; required unless bodyHtml or bodyHtmlFile is set). Any size \u2014 a large body is written to a temp file on the gog server rather than inlined into the command line. Note gog strips trailing newlines from a file-delivered body."),
|
|
34386
|
-
bodyHtml: external_exports.string().optional().describe("Reply body (HTML; optional). Pass the HTML itself at any size \u2014 a large body is written to a temp file on the gog server rather than inlined into the command line. Mutually exclusive with bodyHtmlFile."),
|
|
34387
|
-
bodyHtmlFile: external_exports.string().optional().describe(`Path to an HTML file that ALREADY EXISTS on the gog server for the reply body. gog also accepts "-" for stdin, but this server never writes to gog's stdin, so "-" would hang until the call times out. Mutually exclusive with bodyHtml \u2014 supplying both is rejected. You rarely need this: bodyHtml handles large bodies on its own.`),
|
|
34388
|
-
to: external_exports.array(external_exports.string()).optional().describe("Add or move recipients to To (repeatable). Added on top of the recipients inherited from the original message."),
|
|
34389
|
-
cc: external_exports.array(external_exports.string()).optional().describe("Add or move recipients to Cc (repeatable)"),
|
|
34390
|
-
bcc: external_exports.array(external_exports.string()).optional().describe("Add or move recipients to Bcc (repeatable)"),
|
|
34391
|
-
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."),
|
|
34392
|
-
subject: external_exports.string().optional().describe('Override reply subject (default: "Re: <original>"). A changed subject starts a NEW Gmail thread.'),
|
|
34393
|
-
noQuote: external_exports.boolean().optional().describe("Do not include the original message quoted below the reply (default: the original is quoted)"),
|
|
34394
|
-
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 the hosted connector or any GOG_RUNNER_URL backend 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.`),
|
|
34395
|
-
attachInline: attachInlineParam,
|
|
34396
|
-
from: external_exports.string().optional().describe("Send from this email address (must be a verified send-as alias)"),
|
|
34397
|
-
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."),
|
|
34398
|
-
signature: external_exports.boolean().optional().describe("Append the Gmail signature from the active send-as address"),
|
|
34399
|
-
signatureFrom: external_exports.string().optional().describe("Append the Gmail signature from this send-as email address"),
|
|
34400
|
-
signatureFile: external_exports.string().optional().describe("Append a local signature file (plain text or HTML), read on the gog server"),
|
|
34401
|
-
account: accountParam
|
|
34402
|
-
};
|
|
34403
|
-
function appendReplyFlags(args, f) {
|
|
34404
|
-
assertNotBoth("bodyHtml", "bodyHtmlFile", f.bodyHtml, f.bodyHtmlFile);
|
|
34405
|
-
if (f.body) args.push(payloadArg("body", "body-file", f.body));
|
|
34406
|
-
if (f.bodyHtml) args.push(payloadArg("body-html", "body-html-file", f.bodyHtml, "html"));
|
|
34407
|
-
else if (f.bodyHtmlFile) args.push(`--body-html-file=${f.bodyHtmlFile}`);
|
|
34408
|
-
if (f.to) for (const r of f.to) args.push(`--to=${r}`);
|
|
34409
|
-
if (f.cc) for (const r of f.cc) args.push(`--cc=${r}`);
|
|
34410
|
-
if (f.bcc) for (const r of f.bcc) args.push(`--bcc=${r}`);
|
|
34411
|
-
if (f.remove) for (const r of f.remove) args.push(`--remove=${r}`);
|
|
34412
|
-
if (f.subject) args.push(`--subject=${f.subject}`);
|
|
34413
|
-
if (f.noQuote) args.push("--no-quote");
|
|
34414
|
-
if (f.attach) for (const p of f.attach) args.push(`--attach=${p}`);
|
|
34415
|
-
args.push(...inlineAttachmentArgs("attach", f.attachInline, args));
|
|
34416
|
-
if (f.from) args.push(`--from=${f.from}`);
|
|
34417
|
-
if (f.signature) args.push("--signature");
|
|
34418
|
-
if (f.signatureFrom) args.push(`--signature-from=${f.signatureFrom}`);
|
|
34419
|
-
if (f.signatureFile) args.push(`--signature-file=${f.signatureFile}`);
|
|
34420
|
-
args.push(f.autoFromAddressedAlias ? "--auto-from-addressed-alias" : "--auto-from-addressed-alias=false");
|
|
34421
|
-
}
|
|
34422
|
-
server.registerTool("gog_gmail_reply", {
|
|
34423
|
-
description: 'Reply to a Gmail message (sends to the original sender only). Threads off the message and inherits a "Re:" subject and the quoted original by default. For replying to every participant use gog_gmail_reply_all; to reply across many messages matching a query use gog_gmail_autoreply; to stage this same reply without sending it use gog_gmail_drafts_reply, which composes exactly what this tool would send.',
|
|
34424
|
-
annotations: { destructiveHint: true },
|
|
34425
|
-
inputSchema: replySchema
|
|
34426
|
-
}, async ({ messageId, account, ...flags }) => {
|
|
34427
|
-
const args = ["gmail", "reply", messageId];
|
|
34428
|
-
appendReplyFlags(args, flags);
|
|
34429
|
-
return runOrDiagnose(args, { account });
|
|
34430
|
-
});
|
|
34431
|
-
server.registerTool("gog_gmail_reply_all", {
|
|
34432
|
-
description: 'Reply to all participants of a Gmail message (sender plus every To/Cc recipient). Same inherited "Re:" subject and quoting as gog_gmail_reply. Use the remove flag to drop specific recipients from the reply-all. To stage it without sending use gog_gmail_drafts_reply_all.',
|
|
34433
|
-
annotations: { destructiveHint: true },
|
|
34434
|
-
inputSchema: replySchema
|
|
34435
|
-
}, async ({ messageId, account, ...flags }) => {
|
|
34436
|
-
const args = ["gmail", "reply-all", messageId];
|
|
34437
|
-
appendReplyFlags(args, flags);
|
|
34438
|
-
return runOrDiagnose(args, { account });
|
|
34439
|
-
});
|
|
34440
34725
|
const draftReplyNote = ' Composes exactly what gog_gmail_reply%s would send \u2014 inherited recipients, "Re:" subject and quoted original \u2014 but SAVES IT AS A DRAFT instead of sending. Nothing leaves the mailbox; send it later with gog_gmail_drafts_send, or edit it first with gog_gmail_drafts_update (which overwrites the whole body, quote included \u2014 read the draft back before editing).';
|
|
34441
34726
|
server.registerTool("gog_gmail_drafts_reply", {
|
|
34442
34727
|
description: "Save a reply to a Gmail message as a draft (to the original sender only)." + draftReplyNote.replace("%s", "") + " Prefer this over gog_gmail_drafts_create + replyToMessageId when the draft is a real reply: that route threads the draft but leaves recipients and quoting for you to reconstruct.",
|