mcp-google-multi 5.4.1-alpha.2 → 6.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -16
- package/dist/accounts.d.ts +44 -5
- package/dist/accounts.js +267 -25
- package/dist/auth.d.ts +11 -4
- package/dist/auth.js +85 -78
- package/dist/client-config.d.ts +90 -0
- package/dist/client-config.js +282 -0
- package/dist/client.js +10 -4
- package/dist/config-file.d.ts +38 -0
- package/dist/config-file.js +117 -0
- package/dist/discover.js +57 -3
- package/dist/doctor.d.ts +86 -0
- package/dist/doctor.js +384 -0
- package/dist/env-load.d.ts +11 -0
- package/dist/env-load.js +52 -0
- package/dist/executor.d.ts +2 -0
- package/dist/executor.js +2 -1
- package/dist/fanout.js +8 -5
- package/dist/fs-atomic.d.ts +3 -0
- package/dist/fs-atomic.js +123 -0
- package/dist/http-config.d.ts +35 -0
- package/dist/http-config.js +113 -0
- package/dist/http-transport.d.ts +59 -0
- package/dist/http-transport.js +269 -0
- package/dist/identity.d.ts +24 -0
- package/dist/identity.js +19 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +199 -18
- package/dist/master-key.d.ts +53 -0
- package/dist/master-key.js +242 -0
- package/dist/mcp-token.d.ts +81 -0
- package/dist/mcp-token.js +176 -0
- package/dist/migrate-config.d.ts +7 -0
- package/dist/migrate-config.js +103 -0
- package/dist/migrate-tokens.js +4 -3
- package/dist/net-tuning.d.ts +8 -0
- package/dist/net-tuning.js +25 -0
- package/dist/oauth-as.d.ts +52 -0
- package/dist/oauth-as.js +457 -0
- package/dist/oauth-consent.d.ts +28 -0
- package/dist/oauth-consent.js +109 -0
- package/dist/open-url.d.ts +1 -0
- package/dist/open-url.js +30 -0
- package/dist/reauth-hint.d.ts +2 -0
- package/dist/reauth-hint.js +15 -0
- package/dist/registry-transfer.d.ts +41 -0
- package/dist/registry-transfer.js +219 -0
- package/dist/registry.d.ts +27 -1
- package/dist/registry.js +117 -6
- package/dist/scope-catalog.d.ts +19 -0
- package/dist/scope-catalog.js +182 -0
- package/dist/scope-observability.d.ts +78 -0
- package/dist/scope-observability.js +192 -0
- package/dist/services.js +1 -1
- package/dist/setup-prompt.d.ts +9 -0
- package/dist/setup-prompt.js +59 -0
- package/dist/ssrf-guard.d.ts +48 -0
- package/dist/ssrf-guard.js +242 -0
- package/dist/token-store.js +23 -125
- package/dist/tools/_errors.d.ts +8 -2
- package/dist/tools/_errors.js +97 -6
- package/dist/tools/account-wizard.d.ts +33 -0
- package/dist/tools/account-wizard.js +284 -0
- package/dist/tools/accounts-tool.d.ts +8 -5
- package/dist/tools/accounts-tool.js +38 -15
- package/dist/tools/admin.js +2 -2
- package/dist/tools/calendar.js +2 -2
- package/dist/tools/chat.js +2 -2
- package/dist/tools/contacts.d.ts +40 -0
- package/dist/tools/contacts.js +135 -2
- package/dist/tools/docs.d.ts +3 -0
- package/dist/tools/docs.js +60 -9
- package/dist/tools/drive.d.ts +3 -0
- package/dist/tools/drive.js +60 -8
- package/dist/tools/forms.js +4 -2
- package/dist/tools/generated/_shared.d.ts +1 -3
- package/dist/tools/generated/_shared.js +3 -3
- package/dist/tools/generated/admin.js +175 -132
- package/dist/tools/generated/appsmarket.js +6 -2
- package/dist/tools/generated/calendar.js +45 -27
- package/dist/tools/generated/chat.js +81 -47
- package/dist/tools/generated/classroom.js +131 -104
- package/dist/tools/generated/cloudidentity.js +73 -61
- package/dist/tools/generated/cloudsearch.js +59 -49
- package/dist/tools/generated/contacts.js +22 -14
- package/dist/tools/generated/drive.js +51 -35
- package/dist/tools/generated/driveactivity.js +5 -1
- package/dist/tools/generated/drivelabels.js +30 -25
- package/dist/tools/generated/forms.js +7 -3
- package/dist/tools/generated/gmail.js +73 -58
- package/dist/tools/generated/groupsmigration.js +5 -1
- package/dist/tools/generated/groupssettings.js +7 -3
- package/dist/tools/generated/keep.js +12 -7
- package/dist/tools/generated/licensing.js +11 -7
- package/dist/tools/generated/meet.js +20 -13
- package/dist/tools/generated/postmaster.js +8 -4
- package/dist/tools/generated/reseller.js +22 -17
- package/dist/tools/generated/script.js +26 -16
- package/dist/tools/generated/sheets.js +11 -7
- package/dist/tools/generated/tasks.js +6 -2
- package/dist/tools/generated/vault.js +38 -33
- package/dist/tools/generated/workspaceevents.js +12 -7
- package/dist/tools/gmail-mime.d.ts +38 -8
- package/dist/tools/gmail-mime.js +75 -71
- package/dist/tools/gmail.d.ts +31 -0
- package/dist/tools/gmail.js +483 -99
- package/dist/tools/google-api.js +7 -4
- package/dist/tools/meet.js +2 -2
- package/dist/tools/searchconsole.js +2 -2
- package/dist/tools/sheets.js +6 -2
- package/dist/tools/slides.js +4 -2
- package/dist/tools/tasks.js +2 -2
- package/dist/types.d.ts +1 -1
- package/dist/write-control.d.ts +24 -1
- package/dist/write-control.js +26 -1
- package/package.json +26 -7
package/dist/tools/google-api.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { isAllowed, writeDisabledResult } from '../write-control.js';
|
|
3
|
-
import {
|
|
3
|
+
import { accountAliasSchema } from '../accounts.js';
|
|
4
4
|
import { getClient } from '../client.js';
|
|
5
5
|
import { coerceJson } from './_coerce.js';
|
|
6
6
|
import { getToolsets, toolsetEnabled } from '../toolsets.js';
|
|
7
7
|
import { executeApiMethod, jsonResult } from '../executor.js';
|
|
8
8
|
import { WORKSPACE_APIS, cudFromMethod, loadMethodIndex, searchMethods, } from '../discovery-client.js';
|
|
9
|
-
const accountEnum =
|
|
9
|
+
const accountEnum = accountAliasSchema.optional();
|
|
10
10
|
// Policy/toolset namespace for each API alias must match the NAMED tools' service
|
|
11
11
|
// names, or user deny globs and GOOGLE_TOOLSETS silently miss escape-hatch calls.
|
|
12
12
|
const SERVICE_FOR_ALIAS = {
|
|
@@ -95,7 +95,7 @@ export function registerEscapeTools(registry, policy, deps = {}) {
|
|
|
95
95
|
'policy as named tools. Returns JSON only — for binary/file content (media downloads, ' +
|
|
96
96
|
'drive.files.export) use drive_download / drive_export instead.',
|
|
97
97
|
inputSchema: {
|
|
98
|
-
account: accountEnum.describe('Google account alias'),
|
|
98
|
+
account: accountEnum.describe('Google account alias (omit for the default account)'),
|
|
99
99
|
api: z.string().describe(`API alias: ${apiList}`),
|
|
100
100
|
methodId: z.string().describe('Discovery method id, e.g. "drive.revisions.list"'),
|
|
101
101
|
pathParams: coerceJson(z.record(z.string(), z.union([z.string(), z.number()])).optional())
|
|
@@ -110,7 +110,10 @@ export function registerEscapeTools(registry, policy, deps = {}) {
|
|
|
110
110
|
.optional()).describe('Query-string parameters; use an array for repeated params (e.g. resourceNames)'),
|
|
111
111
|
body: coerceJson(z.record(z.string(), z.unknown()).optional()).describe('JSON request body'),
|
|
112
112
|
},
|
|
113
|
-
|
|
113
|
+
// idempotentHint:false is load-bearing: the computed default (cud=read)
|
|
114
|
+
// would invite retries that duplicate sends through the escape hatch.
|
|
115
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
116
|
+
_meta: { 'anthropic/maxResultSizeChars': 100_000 },
|
|
114
117
|
}, async ({ account, api, methodId, pathParams, queryParams, body }) => {
|
|
115
118
|
if (!WORKSPACE_APIS[api]) {
|
|
116
119
|
return jsonResult({ error: 'unknown_api', message: `Unknown api "${api}".`, hint: `Known APIs: ${apiList}`, retriable: false, account }, true);
|
package/dist/tools/meet.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { meet as meetClient } from '@googleapis/meet';
|
|
3
|
-
import {
|
|
3
|
+
import { accountAliasSchema } from '../accounts.js';
|
|
4
4
|
import { getClient } from '../client.js';
|
|
5
5
|
import { handleGoogleApiError } from './_errors.js';
|
|
6
|
-
const accountEnum =
|
|
6
|
+
const accountEnum = accountAliasSchema.optional();
|
|
7
7
|
export function registerMeetTools(server) {
|
|
8
8
|
// ─── Conference records (past meetings) ────────────────────────────────
|
|
9
9
|
server.registerTool('meet_conference_records_list', {
|
|
@@ -2,10 +2,10 @@ import { z } from 'zod';
|
|
|
2
2
|
import { coerceArray, coerceJson } from './_coerce.js';
|
|
3
3
|
import { searchconsole as searchconsoleClient } from '@googleapis/searchconsole';
|
|
4
4
|
import { webmasters as webmastersClient } from '@googleapis/webmasters';
|
|
5
|
-
import {
|
|
5
|
+
import { accountAliasSchema } from '../accounts.js';
|
|
6
6
|
import { getClient } from '../client.js';
|
|
7
7
|
import { handleGoogleApiError } from './_errors.js';
|
|
8
|
-
const accountEnum =
|
|
8
|
+
const accountEnum = accountAliasSchema.optional();
|
|
9
9
|
export function registerSearchConsoleTools(server) {
|
|
10
10
|
// ─── Sites ───────────────────────────────────────────────
|
|
11
11
|
server.registerTool('searchconsole_sites_list', {
|
package/dist/tools/sheets.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { coerceArray, coerceBoolean, coerceJson } from './_coerce.js';
|
|
3
3
|
import { sheets as sheetsClient } from '@googleapis/sheets';
|
|
4
|
-
import {
|
|
4
|
+
import { accountAliasSchema } from '../accounts.js';
|
|
5
5
|
import { getClient } from '../client.js';
|
|
6
6
|
import { handleGoogleApiError } from './_errors.js';
|
|
7
|
-
const accountEnum =
|
|
7
|
+
const accountEnum = accountAliasSchema.optional();
|
|
8
8
|
export function registerSheetsTools(server) {
|
|
9
9
|
server.registerTool('sheets_create', {
|
|
10
10
|
description: 'Create a new Google Sheets spreadsheet',
|
|
@@ -793,6 +793,8 @@ export function registerSheetsTools(server) {
|
|
|
793
793
|
}
|
|
794
794
|
});
|
|
795
795
|
server.registerTool('sheets_find_replace', {
|
|
796
|
+
// Insert/append-capable or non-convergent: a retry duplicates content.
|
|
797
|
+
annotations: { idempotentHint: false },
|
|
796
798
|
description: 'Find and replace text across a range, a sheet, or all sheets. Supports case sensitivity, full-cell match, regex, and formula scope.',
|
|
797
799
|
inputSchema: {
|
|
798
800
|
account: accountEnum.describe('Google account alias'),
|
|
@@ -1070,6 +1072,8 @@ export function registerSheetsTools(server) {
|
|
|
1070
1072
|
}
|
|
1071
1073
|
});
|
|
1072
1074
|
server.registerTool('sheets_batch_update', {
|
|
1075
|
+
// Insert/append-capable or non-convergent: a retry duplicates content.
|
|
1076
|
+
annotations: { idempotentHint: false },
|
|
1073
1077
|
description: 'Generic spreadsheets.batchUpdate pass-through. Accepts the full Request union (~70 types). Use this for advanced operations not covered by a dedicated tool. See https://developers.google.com/workspace/sheets/api/reference/rest/v4/spreadsheets/request',
|
|
1074
1078
|
inputSchema: {
|
|
1075
1079
|
account: accountEnum.describe('Google account alias'),
|
package/dist/tools/slides.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { slides as slidesClient } from '@googleapis/slides';
|
|
3
|
-
import {
|
|
3
|
+
import { accountAliasSchema } from '../accounts.js';
|
|
4
4
|
import { getClient } from '../client.js';
|
|
5
5
|
import { handleGoogleApiError } from './_errors.js';
|
|
6
6
|
import { coerceArray, coerceBoolean, coerceJson } from './_coerce.js';
|
|
7
7
|
import { sliceClean } from '../trim.js';
|
|
8
|
-
const accountEnum =
|
|
8
|
+
const accountEnum = accountAliasSchema.optional();
|
|
9
9
|
const SLIDE_TEXT_DIGEST_CHARS = 200;
|
|
10
10
|
export function registerSlidesTools(server) {
|
|
11
11
|
server.registerTool('slides_create', {
|
|
@@ -102,6 +102,8 @@ export function registerSlidesTools(server) {
|
|
|
102
102
|
}
|
|
103
103
|
});
|
|
104
104
|
server.registerTool('slides_batch_update', {
|
|
105
|
+
// Insert/append-capable or non-convergent: a retry duplicates content.
|
|
106
|
+
annotations: { idempotentHint: false },
|
|
105
107
|
description: 'Generic presentations.batchUpdate pass-through. Accepts the full Request union (create/move/delete slides, insert text/shapes/images/tables, styling, replaceAllText, …). See https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/request',
|
|
106
108
|
inputSchema: {
|
|
107
109
|
account: accountEnum.describe('Google account alias'),
|
package/dist/tools/tasks.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { coerceBoolean } from './_coerce.js';
|
|
3
3
|
import { tasks as tasksClient } from '@googleapis/tasks';
|
|
4
|
-
import {
|
|
4
|
+
import { accountAliasSchema } from '../accounts.js';
|
|
5
5
|
import { getClient } from '../client.js';
|
|
6
6
|
import { handleGoogleApiError } from './_errors.js';
|
|
7
|
-
const accountEnum =
|
|
7
|
+
const accountEnum = accountAliasSchema.optional();
|
|
8
8
|
export function registerTasksTools(server) {
|
|
9
9
|
// ─── Tasklists ─────────────────────────────────────────────────────────
|
|
10
10
|
server.registerTool('tasks_lists_list', {
|
package/dist/types.d.ts
CHANGED
package/dist/write-control.d.ts
CHANGED
|
@@ -1,17 +1,40 @@
|
|
|
1
1
|
import type { Cud } from './registry.js';
|
|
2
2
|
export type Profile = 'read-only' | 'safe-writes' | 'full-writes';
|
|
3
|
+
export type Transport = 'stdio' | 'http';
|
|
3
4
|
export interface Policy {
|
|
4
5
|
profile: Profile;
|
|
5
6
|
readOnly: boolean;
|
|
6
7
|
allow: string[];
|
|
7
8
|
deny: string[];
|
|
9
|
+
/**
|
|
10
|
+
* B14 reserved seam (cc-write-control "HTTP posture", LOCKED to OQ-5
|
|
11
|
+
* "annotations only"): the dispatch transport is threaded into the resolved
|
|
12
|
+
* policy for the EE/future seam, but in v6 alpha it does NOT stiffen the
|
|
13
|
+
* profile or alter any `isAllowed` verdict. "Stricter on HTTP" is achieved
|
|
14
|
+
* entirely by the `anthropic/requiresUserInteraction` annotation on the
|
|
15
|
+
* irreversible set (A12), emitted identically on both transports.
|
|
16
|
+
* Optional so existing Policy literals (codegen/tests) need no change;
|
|
17
|
+
* resolvePolicy always populates it.
|
|
18
|
+
*/
|
|
19
|
+
transport?: Transport;
|
|
8
20
|
}
|
|
9
21
|
interface ToolRef {
|
|
10
22
|
name: string;
|
|
11
23
|
service: string;
|
|
12
24
|
cud: Cud;
|
|
13
25
|
}
|
|
14
|
-
|
|
26
|
+
/** The irreversible set (frozen, cc-write-control): real sends leave the
|
|
27
|
+
* user's (or org's) identity unrecallably; permanent deletes bypass Trash.
|
|
28
|
+
* Includes the callable GENERATED twins of the curated ops — the surface is
|
|
29
|
+
* always callable by name, so a prompt-free twin would defeat the layer.
|
|
30
|
+
* Reversible mutations (trash/untrash, draft create/update, labels, calendar
|
|
31
|
+
* edits) are deliberately excluded so the approval prompt never nags. The
|
|
32
|
+
* escape hatch is documented as outside this layer (server write-control
|
|
33
|
+
* still gates it). */
|
|
34
|
+
export declare const IRREVERSIBLE_TOOLS: Set<string>;
|
|
35
|
+
export declare function resolvePolicy(env?: NodeJS.ProcessEnv, opts?: {
|
|
36
|
+
transport?: Transport;
|
|
37
|
+
}): Policy;
|
|
15
38
|
export declare function isAllowed(tool: ToolRef, policy: Policy): boolean;
|
|
16
39
|
export declare function writeDisabledResult(tool: ToolRef, policy: Policy): {
|
|
17
40
|
content: {
|
package/dist/write-control.js
CHANGED
|
@@ -1,8 +1,31 @@
|
|
|
1
1
|
const PROFILES = ['read-only', 'safe-writes', 'full-writes'];
|
|
2
|
+
/** The irreversible set (frozen, cc-write-control): real sends leave the
|
|
3
|
+
* user's (or org's) identity unrecallably; permanent deletes bypass Trash.
|
|
4
|
+
* Includes the callable GENERATED twins of the curated ops — the surface is
|
|
5
|
+
* always callable by name, so a prompt-free twin would defeat the layer.
|
|
6
|
+
* Reversible mutations (trash/untrash, draft create/update, labels, calendar
|
|
7
|
+
* edits) are deliberately excluded so the approval prompt never nags. The
|
|
8
|
+
* escape hatch is documented as outside this layer (server write-control
|
|
9
|
+
* still gates it). */
|
|
10
|
+
export const IRREVERSIBLE_TOOLS = new Set([
|
|
11
|
+
// curated
|
|
12
|
+
'gmail_send',
|
|
13
|
+
'gmail_send_draft',
|
|
14
|
+
'gmail_delete',
|
|
15
|
+
'gmail_batch_delete',
|
|
16
|
+
'drive_delete',
|
|
17
|
+
'drive_empty_trash',
|
|
18
|
+
// generated twins (permanent deletes / real sends)
|
|
19
|
+
'gmail_users_threads_delete',
|
|
20
|
+
'gmail_users_drafts_delete',
|
|
21
|
+
'chat_spaces_messages_delete',
|
|
22
|
+
'cloudidentity_customers_userinvitations_send',
|
|
23
|
+
'vault_matters_holds_delete',
|
|
24
|
+
]);
|
|
2
25
|
function parseGlobs(value) {
|
|
3
26
|
return (value ?? '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
4
27
|
}
|
|
5
|
-
export function resolvePolicy(env = process.env) {
|
|
28
|
+
export function resolvePolicy(env = process.env, opts = {}) {
|
|
6
29
|
const raw = (env.GOOGLE_PROFILE ?? 'read-only').trim();
|
|
7
30
|
if (raw && !PROFILES.includes(raw)) {
|
|
8
31
|
// Fail-closed to read-only, but say so — a typo'd profile otherwise looks
|
|
@@ -14,6 +37,8 @@ export function resolvePolicy(env = process.env) {
|
|
|
14
37
|
readOnly: /^(1|true|yes)$/i.test(env.GOOGLE_READ_ONLY ?? ''),
|
|
15
38
|
allow: parseGlobs(env.GOOGLE_WRITE_ALLOW),
|
|
16
39
|
deny: parseGlobs(env.GOOGLE_WRITE_DENY),
|
|
40
|
+
// Reserved seam only (see Policy.transport): does not affect the verdict.
|
|
41
|
+
transport: opts.transport ?? 'stdio',
|
|
17
42
|
};
|
|
18
43
|
}
|
|
19
44
|
function globToRegExp(glob) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-google-multi",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0-alpha.2",
|
|
4
4
|
"description": "Local MCP server for Google Workspace (Gmail, Drive, Calendar, Sheets, Docs, Contacts, Tasks, Meet, Search Console, +Forms/Chat/Admin) across multiple accounts — OAuth-only, encrypted token storage, deny-by-default writes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"dist"
|
|
13
13
|
],
|
|
14
14
|
"engines": {
|
|
15
|
-
"node": ">=
|
|
15
|
+
"node": ">=22"
|
|
16
16
|
},
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
@@ -57,7 +57,8 @@
|
|
|
57
57
|
"test:watch": "vitest",
|
|
58
58
|
"gen:discovery": "tsx scripts/fetch-discovery.ts",
|
|
59
59
|
"gen:tools": "tsx scripts/gen-tools.ts",
|
|
60
|
-
"gen:coverage": "tsx scripts/gen-coverage.ts"
|
|
60
|
+
"gen:coverage": "tsx scripts/gen-coverage.ts",
|
|
61
|
+
"pack:mcpb": "mcpb pack . mcp-google-multi.mcpb"
|
|
61
62
|
},
|
|
62
63
|
"dependencies": {
|
|
63
64
|
"@googleapis/admin": "^33.0.0",
|
|
@@ -74,22 +75,40 @@
|
|
|
74
75
|
"@googleapis/slides": "^6.0.0",
|
|
75
76
|
"@googleapis/tasks": "^13.0.0",
|
|
76
77
|
"@googleapis/webmasters": "^4.0.0",
|
|
77
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
78
|
-
"dotenv": "^17.4.0",
|
|
78
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
79
79
|
"googleapis-common": "^8.0.3",
|
|
80
|
+
"jose": "^6.2.8",
|
|
81
|
+
"markdown-it": "15.0.0",
|
|
80
82
|
"mime-types": "^3.0.2",
|
|
81
|
-
"
|
|
83
|
+
"nodemailer": "9.1.1",
|
|
84
|
+
"turndown": "7.2.4",
|
|
85
|
+
"turndown-plugin-gfm": "1.0.2",
|
|
82
86
|
"zod": "^4.3.6"
|
|
83
87
|
},
|
|
84
88
|
"devDependencies": {
|
|
89
|
+
"@anthropic-ai/mcpb": "^2.1.2",
|
|
85
90
|
"@eslint/js": "^10.0.1",
|
|
91
|
+
"@types/js-yaml": "^4.0.9",
|
|
92
|
+
"@types/markdown-it": "^14.1.2",
|
|
86
93
|
"@types/mime-types": "^3.0.1",
|
|
87
|
-
"@types/node": "^
|
|
94
|
+
"@types/node": "^22.20.1",
|
|
95
|
+
"@types/nodemailer": "^8.0.1",
|
|
96
|
+
"@types/turndown": "^5.0.6",
|
|
88
97
|
"eslint": "^10.2.1",
|
|
98
|
+
"js-yaml": "^4.3.2",
|
|
89
99
|
"semantic-release": "^25.0.3",
|
|
90
100
|
"tsx": "^4.23.1",
|
|
91
101
|
"typescript": "^6.0.3",
|
|
92
102
|
"typescript-eslint": "^8.59.1",
|
|
93
103
|
"vitest": "^3.2.6"
|
|
104
|
+
},
|
|
105
|
+
"optionalDependencies": {
|
|
106
|
+
"@napi-rs/keyring": "1.3.0"
|
|
107
|
+
},
|
|
108
|
+
"overrides": {
|
|
109
|
+
"tmp": "^0.2.4",
|
|
110
|
+
"fast-uri": "^3.1.6",
|
|
111
|
+
"hono": "^4.13.5",
|
|
112
|
+
"qs": "^6.16.0"
|
|
94
113
|
}
|
|
95
114
|
}
|