@hostwebhook/node-types 1.52.11 → 1.52.12

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.
@@ -20,3 +20,84 @@ export declare const DRIVE_OPERATIONS: readonly ["upload", "download", "copy", "
20
20
  export type DriveOperation = (typeof DRIVE_OPERATIONS)[number];
21
21
  /** Type guard — useful when validating untrusted input (DTOs, tool calls). */
22
22
  export declare function isDriveOperation(value: unknown): value is DriveOperation;
23
+ export type DriveParamType =
24
+ /** Live file picker (needs a credential) + templated paste. */
25
+ 'driveFile'
26
+ /** Text input with `{{payload.*}}` autocomplete. */
27
+ | 'template'
28
+ /** Plain `<select>`; the labels are not the values, so `options` is required. */
29
+ | 'select'
30
+ /**
31
+ * Searchable mime-type dropdown. The option list is long and shared with
32
+ * other screens, so it stays in the dashboard (`lib/drive-mime-options`)
33
+ * and the schema only says "this field is a mime picker".
34
+ */
35
+ | 'mimeSelect' | 'number'
36
+ /**
37
+ * A `<select>` whose values are `''` / `'true'` / `'false'` but which is
38
+ * stored as a BOOLEAN, or omitted entirely when `''`.
39
+ *
40
+ * This is the shape that keeps `starred` honest: the api applies it with
41
+ * `typeof config.starred === 'boolean'`, so "— don't change —" has to mean
42
+ * *no key at all*. A plain Switch cannot express that third state, and
43
+ * storing `''` or `'false'` would silently stop the star from ever changing.
44
+ */
45
+ | 'booleanSelect'
46
+ /**
47
+ * Full-width explainer card that toggles: icon, title, prose and bullets,
48
+ * with the switch on the right. The card's rich body is JSX, so it lives in
49
+ * the page keyed by param name — the schema only declares the field.
50
+ */
51
+ | 'switchCard'
52
+ /** Live multi-select of the starting folder's immediate children. */
53
+ | 'driveSubfolders';
54
+ export interface DriveParamSpec {
55
+ /** The `operationConfig` key. This is what the api reads — not a UI name. */
56
+ name: string;
57
+ label: string;
58
+ type: DriveParamType;
59
+ required?: boolean;
60
+ /**
61
+ * Help text under the field. Plain text on purpose: the package holds no
62
+ * React, so the `<code>` spans the page used to have are gone. Deliberate.
63
+ */
64
+ description?: string;
65
+ placeholder?: string;
66
+ /** Prefilled when the saved config has no value for this key. */
67
+ default?: string | number;
68
+ /** Required for `select` and `booleanSelect` — label and value differ. */
69
+ options?: ReadonlyArray<{
70
+ value: string;
71
+ label: string;
72
+ }>;
73
+ min?: number;
74
+ max?: number;
75
+ /**
76
+ * Renders in the "Advanced" tab instead of "Config". The page used to keep
77
+ * a two-name `ADVANCED_FIELDS` array while the advanced *tab* actually held
78
+ * four fields, so `recursive` and `subfolderIds` only showed up because
79
+ * `list` happened to also carry one of the two named fields. Marking all
80
+ * four here removes that coincidence.
81
+ */
82
+ advanced?: boolean;
83
+ /**
84
+ * Only shown when a sibling field holds one of these values. No other node's
85
+ * schema needed this yet; Drive has three cases (the two share targets and
86
+ * the subfolder scope).
87
+ */
88
+ showWhen?: {
89
+ field: string;
90
+ in: ReadonlyArray<string>;
91
+ };
92
+ }
93
+ export interface DriveOperationSpec {
94
+ /** UI label for the operation dropdown row. */
95
+ label: string;
96
+ /** Sub-line under the label in the dropdown. */
97
+ description: string;
98
+ /** Drive API method it maps to (developers.google.com/drive/api/reference). */
99
+ apiMethod: string;
100
+ /** Parameter schema. Order matters: it is the on-screen order. */
101
+ params: DriveParamSpec[];
102
+ }
103
+ export declare const DRIVE_OPERATION_SPECS: Record<DriveOperation, DriveOperationSpec>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DRIVE_OPERATIONS = void 0;
3
+ exports.DRIVE_OPERATION_SPECS = exports.DRIVE_OPERATIONS = void 0;
4
4
  exports.isDriveOperation = isDriveOperation;
5
5
  /**
6
6
  * Google Drive operation enum — single source of truth across the API,
@@ -38,3 +38,286 @@ exports.DRIVE_OPERATIONS = [
38
38
  function isDriveOperation(value) {
39
39
  return typeof value === 'string' && exports.DRIVE_OPERATIONS.includes(value);
40
40
  }
41
+ /* Fábricas de los campos que se repiten, para que un cambio de copy no haya
42
+ que perseguirlo por doce operaciones. */
43
+ const fileId = () => ({
44
+ name: 'fileId',
45
+ label: 'Drive File',
46
+ type: 'driveFile',
47
+ required: true,
48
+ description: 'Pick a file from Drive or paste a templated value like {{payload.driveFileId}}.',
49
+ });
50
+ const parentFolderId = () => ({
51
+ name: 'parentFolderId',
52
+ label: 'Parent Folder ID (override)',
53
+ type: 'template',
54
+ advanced: true,
55
+ placeholder: 'Empty = use Default Folder above',
56
+ description: "Folder id used for this operation only. Leave empty to use the action's Default Folder. Templates work — e.g. {{payload.folderId}}.",
57
+ });
58
+ /** El filtro por tipo de upload/list. En `export` el mismo `mimeType` es otra
59
+ cosa y se declara aparte. */
60
+ const mimeTypeFilter = () => ({
61
+ name: 'mimeType',
62
+ label: 'File type filter (optional)',
63
+ type: 'mimeSelect',
64
+ description: 'Restrict the operation to files of this type. Leave as "Any" to match every file.',
65
+ });
66
+ const ORDER_BY_OPTIONS = [
67
+ { value: 'modifiedTime desc', label: 'Modified time (newest first)' },
68
+ { value: 'modifiedTime', label: 'Modified time (oldest first)' },
69
+ { value: 'createdTime desc', label: 'Created time (newest first)' },
70
+ { value: 'createdTime', label: 'Created time (oldest first)' },
71
+ { value: 'name', label: 'Name (A→Z)' },
72
+ { value: 'name desc', label: 'Name (Z→A)' },
73
+ ];
74
+ const EXPORT_FORMAT_OPTIONS = [
75
+ { value: 'application/pdf', label: 'PDF (.pdf)' },
76
+ {
77
+ value: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
78
+ label: 'Word (.docx) — for Google Docs',
79
+ },
80
+ {
81
+ value: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
82
+ label: 'Excel (.xlsx) — for Google Sheets',
83
+ },
84
+ {
85
+ value: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
86
+ label: 'PowerPoint (.pptx) — for Google Slides',
87
+ },
88
+ { value: 'text/plain', label: 'Plain text (.txt)' },
89
+ { value: 'text/csv', label: 'CSV (.csv) — for Google Sheets' },
90
+ { value: 'text/html', label: 'HTML (.html)' },
91
+ ];
92
+ exports.DRIVE_OPERATION_SPECS = {
93
+ upload: {
94
+ label: 'Upload File',
95
+ description: 'Stream a file from a payload _file ref into Drive',
96
+ apiMethod: 'files.create',
97
+ params: [
98
+ {
99
+ name: 'fileName',
100
+ label: 'Destination File Name',
101
+ type: 'template',
102
+ placeholder: '{{payload.name}} — leave blank to use _file.originalName',
103
+ },
104
+ {
105
+ name: 'sourceField',
106
+ label: 'Source Field (payload path)',
107
+ type: 'template',
108
+ placeholder: '_file',
109
+ default: '_file',
110
+ description: 'Where the _file ref lives in the incoming payload. Default _file. For nested refs use a dotted path (e.g. doc if upstream is { doc: { _file: ... } }).',
111
+ },
112
+ mimeTypeFilter(),
113
+ parentFolderId(),
114
+ ],
115
+ },
116
+ download: {
117
+ label: 'Download File',
118
+ description: 'Fetch a Drive file → payload _file ref for downstream nodes',
119
+ apiMethod: 'files.get (alt=media)',
120
+ params: [fileId()],
121
+ },
122
+ list: {
123
+ label: 'List / Search',
124
+ description: 'List or search files (iterable output)',
125
+ apiMethod: 'files.list',
126
+ params: [
127
+ {
128
+ name: 'query',
129
+ label: 'Search Query',
130
+ type: 'template',
131
+ placeholder: 'Substring to match against file names — empty = list all',
132
+ },
133
+ mimeTypeFilter(),
134
+ {
135
+ name: 'pageSize',
136
+ label: 'Max Results',
137
+ type: 'number',
138
+ min: 1,
139
+ max: 100,
140
+ default: 50,
141
+ description: 'Up to 100 per call. Output is iterable — downstream nodes process each file independently.',
142
+ },
143
+ {
144
+ name: 'orderBy',
145
+ label: 'Order By',
146
+ type: 'select',
147
+ default: 'modifiedTime desc',
148
+ options: ORDER_BY_OPTIONS,
149
+ },
150
+ parentFolderId(),
151
+ { name: 'recursive', label: 'Search subfolders too', type: 'switchCard', advanced: true },
152
+ {
153
+ name: 'subfolderIds',
154
+ label: 'Limit to specific subfolders',
155
+ type: 'driveSubfolders',
156
+ advanced: true,
157
+ showWhen: { field: 'recursive', in: ['true'] },
158
+ },
159
+ {
160
+ name: 'downloadResults',
161
+ label: 'Auto-download matching files',
162
+ type: 'switchCard',
163
+ advanced: true,
164
+ },
165
+ ],
166
+ },
167
+ get: {
168
+ label: 'Get Metadata',
169
+ description: 'Read metadata for one file (no bytes)',
170
+ apiMethod: 'files.get',
171
+ params: [fileId()],
172
+ },
173
+ copy: {
174
+ label: 'Copy File',
175
+ description: 'Duplicate a file, optionally rename and/or move',
176
+ apiMethod: 'files.copy',
177
+ params: [
178
+ fileId(),
179
+ {
180
+ name: 'newName',
181
+ label: 'New File Name',
182
+ type: 'template',
183
+ placeholder: "Optional — defaults to 'Copy of <original>'",
184
+ },
185
+ parentFolderId(),
186
+ ],
187
+ },
188
+ move: {
189
+ label: 'Move File',
190
+ description: 'Move a file to a different folder',
191
+ apiMethod: 'files.update (addParents / removeParents)',
192
+ params: [fileId(), parentFolderId()],
193
+ },
194
+ delete: {
195
+ label: 'Delete (Trash)',
196
+ description: 'Move to trash — recoverable for 30 days',
197
+ apiMethod: 'files.update (trashed) / files.delete when permanent',
198
+ params: [
199
+ fileId(),
200
+ {
201
+ name: 'permanent',
202
+ label: 'Delete Permanently?',
203
+ type: 'booleanSelect',
204
+ options: [
205
+ { value: '', label: 'No — move to trash (recoverable)' },
206
+ { value: 'true', label: '⚠️ Yes — erase forever (irreversible)' },
207
+ ],
208
+ },
209
+ ],
210
+ },
211
+ share: {
212
+ label: 'Share File',
213
+ description: 'Grant viewer / commenter / editor permission',
214
+ apiMethod: 'permissions.create',
215
+ params: [
216
+ fileId(),
217
+ {
218
+ name: 'type',
219
+ label: 'Share With',
220
+ type: 'select',
221
+ default: 'user',
222
+ options: [
223
+ { value: 'user', label: 'Specific user (email)' },
224
+ { value: 'group', label: 'Group (email)' },
225
+ { value: 'domain', label: 'Entire domain' },
226
+ { value: 'anyone', label: '⚠️ Anyone with the link (public)' },
227
+ ],
228
+ },
229
+ {
230
+ name: 'role',
231
+ label: 'Permission Role',
232
+ type: 'select',
233
+ default: 'reader',
234
+ options: [
235
+ { value: 'reader', label: 'Viewer (read-only)' },
236
+ { value: 'commenter', label: 'Commenter' },
237
+ { value: 'writer', label: 'Editor' },
238
+ ],
239
+ },
240
+ {
241
+ name: 'emailAddress',
242
+ label: 'Email Address',
243
+ type: 'template',
244
+ placeholder: 'user@example.com or {{payload.email}}',
245
+ showWhen: { field: 'type', in: ['user', 'group'] },
246
+ },
247
+ {
248
+ name: 'domain',
249
+ label: 'Domain',
250
+ type: 'template',
251
+ placeholder: 'example.com',
252
+ showWhen: { field: 'type', in: ['domain'] },
253
+ },
254
+ {
255
+ name: 'sendNotificationEmail',
256
+ label: 'Notify Recipient',
257
+ type: 'booleanSelect',
258
+ options: [
259
+ { value: '', label: "No — don't send email" },
260
+ { value: 'true', label: 'Yes — send share notification email' },
261
+ ],
262
+ },
263
+ ],
264
+ },
265
+ update: {
266
+ label: 'Update Metadata',
267
+ description: 'Rename, set description, or star/unstar',
268
+ apiMethod: 'files.update',
269
+ params: [
270
+ fileId(),
271
+ { name: 'name', label: 'New Name', type: 'template', placeholder: '{{payload.title}}' },
272
+ {
273
+ name: 'description',
274
+ label: 'Description (optional)',
275
+ type: 'template',
276
+ placeholder: '{{payload.description}}',
277
+ },
278
+ {
279
+ name: 'starred',
280
+ label: 'Starred (optional)',
281
+ type: 'booleanSelect',
282
+ options: [
283
+ { value: '', label: "— don't change —" },
284
+ { value: 'true', label: '⭐ Star' },
285
+ { value: 'false', label: 'Un-star' },
286
+ ],
287
+ },
288
+ ],
289
+ },
290
+ createFolder: {
291
+ label: 'Create Folder',
292
+ description: 'Create a new folder, optionally inside a parent',
293
+ apiMethod: 'files.create (folder mimeType)',
294
+ params: [
295
+ /* Mismo `name` que en update, con otra etiqueta y otro placeholder: por
296
+ eso los params son por operación y no un registro global de campos. */
297
+ { name: 'name', label: 'Folder Name', type: 'template', placeholder: 'Reports' },
298
+ parentFolderId(),
299
+ ],
300
+ },
301
+ export: {
302
+ label: 'Export Google Doc',
303
+ description: 'Export a Doc / Sheet / Slide to PDF / DOCX / XLSX',
304
+ apiMethod: 'files.export',
305
+ params: [
306
+ fileId(),
307
+ {
308
+ name: 'mimeType',
309
+ label: 'Export Format',
310
+ type: 'select',
311
+ default: 'application/pdf',
312
+ options: EXPORT_FORMAT_OPTIONS,
313
+ description: 'Export only works on Google native docs (Docs, Sheets, Slides, Drawings). For regular files use Download instead.',
314
+ },
315
+ ],
316
+ },
317
+ getPermissions: {
318
+ label: 'List Permissions',
319
+ description: 'List who has access (audit before changing)',
320
+ apiMethod: 'permissions.list',
321
+ params: [fileId()],
322
+ },
323
+ };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Drive AI Toolkit — las herramientas que un driveAction expone cuando
3
+ * `aiEnabled` está encendido.
4
+ *
5
+ * **Se escribe una sola vez**, como el de Sheets y el de Telegram. Antes vivía
6
+ * TRES veces, y las tres a mano:
7
+ *
8
+ * 1. `dashboard/components/drive-actions/drive-operations-schemas.ts`
9
+ * 2. `api/src/mcp-servers/toolkit-specs.ts`
10
+ * 3. la página de detalle, que pintaba las doce herramientas como doce
11
+ * `<li>` escritos a mano, con el número `12` también a mano en tres sitios
12
+ *
13
+ * La 1 y la 2 no habían derivado todavía (medido el 2026-08-10: cero
14
+ * diferencias, al contrario que Slack con 13 y WhatsApp con 4). Esto es lo que
15
+ * hace que sigan sin derivar.
16
+ *
17
+ * El ORDEN de este array importa: `AiToolkitPreview` pinta el encabezado de
18
+ * grupo sólo cuando cambia respecto a la fila anterior, así que las
19
+ * herramientas del mismo grupo tienen que ir seguidas. Los tres grupos son los
20
+ * que ya inventaba el JSX que sustituye.
21
+ */
22
+ import type { DriveOperation } from './drive-operations';
23
+ export interface DriveToolkitParameter {
24
+ name: string;
25
+ type: 'string' | 'number' | 'boolean';
26
+ description: string;
27
+ required: boolean;
28
+ }
29
+ export interface DriveToolkitSpec {
30
+ operation: DriveOperation;
31
+ /** Etiqueta corta de la fila en la lista de herramientas. */
32
+ label: string;
33
+ /**
34
+ * Nombre con el que el LLM llama a la herramienta. Todas llevan `_drive_` o
35
+ * `_to_drive` para no chocar con las de Gmail, Sheets o Calendar cuando un
36
+ * mismo AI Node tiene varios toolkits encendidos.
37
+ */
38
+ toolName: string;
39
+ /** Descripción (más reglas de uso) que ve el LLM. */
40
+ description: string;
41
+ parameters: DriveToolkitParameter[];
42
+ /** Encabezado de grupo de la página de detalle. El orden es el que agrupa. */
43
+ group?: string;
44
+ /**
45
+ * Marca que la herramienta cambia algo difícil de deshacer, para que la página
46
+ * lo enseñe y el AI Node pida confirmación. Son **dos**, las mismas que ya
47
+ * estaban marcadas: `delete_drive_file` y `share_drive_file`. `move` no lo
48
+ * lleva, y es defendible — deshacerlo es otro move.
49
+ */
50
+ destructive?: boolean;
51
+ }
52
+ export declare const DRIVE_TOOLKIT_SPECS: DriveToolkitSpec[];
53
+ /** Índice por nombre de herramienta, para enrutar un `tools/call` sin recorrer. */
54
+ export declare const DRIVE_TOOLKIT_BY_TOOL_NAME: Record<string, DriveToolkitSpec>;
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ /**
3
+ * Drive AI Toolkit — las herramientas que un driveAction expone cuando
4
+ * `aiEnabled` está encendido.
5
+ *
6
+ * **Se escribe una sola vez**, como el de Sheets y el de Telegram. Antes vivía
7
+ * TRES veces, y las tres a mano:
8
+ *
9
+ * 1. `dashboard/components/drive-actions/drive-operations-schemas.ts`
10
+ * 2. `api/src/mcp-servers/toolkit-specs.ts`
11
+ * 3. la página de detalle, que pintaba las doce herramientas como doce
12
+ * `<li>` escritos a mano, con el número `12` también a mano en tres sitios
13
+ *
14
+ * La 1 y la 2 no habían derivado todavía (medido el 2026-08-10: cero
15
+ * diferencias, al contrario que Slack con 13 y WhatsApp con 4). Esto es lo que
16
+ * hace que sigan sin derivar.
17
+ *
18
+ * El ORDEN de este array importa: `AiToolkitPreview` pinta el encabezado de
19
+ * grupo sólo cuando cambia respecto a la fila anterior, así que las
20
+ * herramientas del mismo grupo tienen que ir seguidas. Los tres grupos son los
21
+ * que ya inventaba el JSX que sustituye.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.DRIVE_TOOLKIT_BY_TOOL_NAME = exports.DRIVE_TOOLKIT_SPECS = void 0;
25
+ const p = (name, description, required = true, type = 'string') => ({ name, type, description, required });
26
+ const ENTRAN_Y_SALEN = 'Files in / out';
27
+ const DESCUBRIR = 'Discovery';
28
+ const MUTACIONES = 'Mutations (LLM confirms first)';
29
+ exports.DRIVE_TOOLKIT_SPECS = [
30
+ /* ── Files in / out ─────────────────────────────────────────────────── */
31
+ {
32
+ operation: 'upload',
33
+ label: 'Upload file',
34
+ toolName: 'upload_to_drive',
35
+ group: ENTRAN_Y_SALEN,
36
+ description: 'Upload a file from the current event payload into Google Drive. Requires an `_file` ref in the payload (created by an upstream node — multipart ingress, File Transform, or another Drive download). Streams from R2; never holds the full file in memory.',
37
+ parameters: [
38
+ p('fileName', 'Optional. Override the destination file name. Defaults to the _file ref originalName.', false),
39
+ p('sourceField', 'Optional. Payload field path holding the _file ref. Defaults to "_file".', false),
40
+ p('parentFolderId', 'Optional. Drive folder ID to upload into. Empty = root.', false),
41
+ p('mimeType', 'Optional. Override the MIME type. Defaults to the _file ref mimeType.', false),
42
+ ],
43
+ },
44
+ {
45
+ operation: 'download',
46
+ label: 'Download file',
47
+ toolName: 'download_from_drive',
48
+ group: ENTRAN_Y_SALEN,
49
+ description: 'Download a Drive file to HostWebhook storage and return a `_file` ref the next pipeline node can consume (FileTransform, AI vision, HTTP body). Use the file ID from list_drive_files / search.',
50
+ parameters: [p('fileId', 'The Drive file ID to download.')],
51
+ },
52
+ {
53
+ operation: 'export',
54
+ label: 'Export Google doc',
55
+ toolName: 'export_drive_file',
56
+ group: ENTRAN_Y_SALEN,
57
+ description: 'Export a Google native document (Doc / Sheet / Slide / Drawing) to a downloadable format like PDF or DOCX, returning a `_file` ref the next pipeline node can consume. Does NOT work on regular files (those use download_from_drive).',
58
+ parameters: [
59
+ p('fileId', 'The Drive file ID (must be a Google native doc).'),
60
+ /* De las dos copias me quedo con la de la api, que es la que dice qué
61
+ formato de origen va a cada destino. La del dashboard se había quedado
62
+ sin esa parte. Es la única deriva que tenían Drive y, como estaba en la
63
+ descripción de un PARÁMETRO, ningún conteo la miraba. */
64
+ p('mimeType', 'Target MIME type. Common: "application/pdf" (Doc/Slide → PDF), "application/vnd.openxmlformats-officedocument.wordprocessingml.document" (Doc → DOCX), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" (Sheet → XLSX), "text/plain", "text/csv".'),
65
+ ],
66
+ },
67
+ /* ── Discovery ──────────────────────────────────────────────────────── */
68
+ {
69
+ operation: 'list',
70
+ label: 'List / search files',
71
+ toolName: 'list_drive_files',
72
+ group: DESCUBRIR,
73
+ description: "Search the user's Drive (or shared drive). Returns up to N matching files with id, name, mimeType, size, modifiedTime. Use this BEFORE any operation that needs a fileId — never invent IDs.",
74
+ parameters: [
75
+ p('query', 'Optional. Substring to match against file names.', false),
76
+ p('parentFolderId', 'Optional. Restrict search to a single folder.', false),
77
+ p('mimeType', 'Optional. Filter by MIME type (e.g. "application/pdf", "application/vnd.google-apps.folder").', false),
78
+ p('pageSize', 'Optional. Max results (default 50, max 100).', false, 'number'),
79
+ p('orderBy', 'Optional. Drive ordering string (default "modifiedTime desc").', false),
80
+ ],
81
+ },
82
+ {
83
+ operation: 'get',
84
+ label: 'Get file metadata',
85
+ toolName: 'get_drive_file',
86
+ group: DESCUBRIR,
87
+ description: 'Read full metadata for one Drive file (name, mimeType, size, parents, owners, starred, trashed). Does NOT download the bytes — use download_from_drive for that.',
88
+ parameters: [p('fileId', 'The Drive file ID.')],
89
+ },
90
+ {
91
+ operation: 'getPermissions',
92
+ label: 'List file permissions',
93
+ toolName: 'get_drive_permissions',
94
+ group: DESCUBRIR,
95
+ description: 'List who has access to a Drive file (id, type, role, emailAddress/domain, displayName). Use to audit sharing before changing permissions.',
96
+ parameters: [p('fileId', 'The Drive file ID.')],
97
+ },
98
+ /* ── Mutations ──────────────────────────────────────────────────────── */
99
+ {
100
+ operation: 'copy',
101
+ label: 'Copy file',
102
+ toolName: 'copy_drive_file',
103
+ group: MUTACIONES,
104
+ description: 'Duplicate a Drive file. Optionally rename and/or move into a different folder in one step.',
105
+ parameters: [
106
+ p('fileId', 'The source Drive file ID.'),
107
+ p('newName', 'Optional. Name for the copy. Defaults to "Copy of <original>".', false),
108
+ p('parentFolderId', 'Optional. Folder ID to place the copy into. Defaults to the source folder.', false),
109
+ ],
110
+ },
111
+ {
112
+ operation: 'move',
113
+ label: 'Move file',
114
+ toolName: 'move_drive_file',
115
+ group: MUTACIONES,
116
+ description: 'Move a Drive file to a different folder. The current parents are removed; the file is added to the new parent.',
117
+ parameters: [
118
+ p('fileId', 'The Drive file ID to move.'),
119
+ p('parentFolderId', 'Destination folder ID.'),
120
+ ],
121
+ },
122
+ {
123
+ operation: 'update',
124
+ label: 'Update file metadata',
125
+ toolName: 'update_drive_file',
126
+ group: MUTACIONES,
127
+ description: 'Rename a Drive file or change its description / starred status. Use list_drive_files first to find the fileId.',
128
+ parameters: [
129
+ p('fileId', 'The Drive file ID.'),
130
+ p('name', 'Optional. New name.', false),
131
+ p('description', 'Optional. New description.', false),
132
+ p('starred', 'Optional. Star/unstar.', false, 'boolean'),
133
+ ],
134
+ },
135
+ {
136
+ operation: 'createFolder',
137
+ label: 'Create folder',
138
+ toolName: 'create_drive_folder',
139
+ group: MUTACIONES,
140
+ description: 'Create a new folder in Drive. Use this BEFORE upload_to_drive when the user asks to put a file in a specific named folder that does not yet exist.',
141
+ parameters: [
142
+ p('name', 'Folder name.'),
143
+ p('parentFolderId', 'Optional. Parent folder ID. Empty = root.', false),
144
+ ],
145
+ },
146
+ {
147
+ operation: 'delete',
148
+ label: 'Delete file (trash)',
149
+ toolName: 'delete_drive_file',
150
+ group: MUTACIONES,
151
+ description: 'Move a Drive file to trash (recoverable for 30 days). Set permanent=true ONLY when the user explicitly confirms a permanent delete — irreversible. ALWAYS confirm with the user before calling this with permanent=true.',
152
+ parameters: [
153
+ p('fileId', 'The Drive file ID to delete.'),
154
+ p('permanent', 'Optional. true = bypass trash and erase forever (irreversible). Default false.', false, 'boolean'),
155
+ ],
156
+ destructive: true,
157
+ },
158
+ {
159
+ operation: 'share',
160
+ label: 'Share file',
161
+ toolName: 'share_drive_file',
162
+ group: MUTACIONES,
163
+ description: 'Grant a permission on a Drive file. CONFIRM with the user before calling this — sharing externally is sensitive. Public sharing (type="anyone") is especially dangerous; only use when the user explicitly says "make it public" or similar.',
164
+ parameters: [
165
+ p('fileId', 'The Drive file ID to share.'),
166
+ p('type', 'One of: "user" | "group" | "domain" | "anyone". Use "anyone" only with explicit user confirmation.'),
167
+ p('role', 'One of: "reader" | "commenter" | "writer".'),
168
+ p('emailAddress', 'Required when type=user|group.', false),
169
+ p('domain', 'Required when type=domain.', false),
170
+ p('sendNotificationEmail', 'Optional. true = email the recipient about the share.', false, 'boolean'),
171
+ ],
172
+ destructive: true,
173
+ },
174
+ ];
175
+ /** Índice por nombre de herramienta, para enrutar un `tools/call` sin recorrer. */
176
+ exports.DRIVE_TOOLKIT_BY_TOOL_NAME = Object.fromEntries(exports.DRIVE_TOOLKIT_SPECS.map((s) => [s.toolName, s]));
package/dist/index.d.ts CHANGED
@@ -9,8 +9,10 @@ export { GMAIL_OPERATIONS, isGmailOperation, } from './gmail-operations';
9
9
  export type { GmailOperation } from './gmail-operations';
10
10
  export { GOOGLE_CALENDAR_OPERATIONS, isGoogleCalendarOperation, } from './calendar-operations';
11
11
  export type { GoogleCalendarOperation } from './calendar-operations';
12
- export { DRIVE_OPERATIONS, isDriveOperation, } from './drive-operations';
13
- export type { DriveOperation } from './drive-operations';
12
+ export { DRIVE_OPERATIONS, DRIVE_OPERATION_SPECS, isDriveOperation, } from './drive-operations';
13
+ export type { DriveOperation, DriveParamType, DriveParamSpec, DriveOperationSpec, } from './drive-operations';
14
+ export { DRIVE_TOOLKIT_SPECS, DRIVE_TOOLKIT_BY_TOOL_NAME, } from './drive-toolkit';
15
+ export type { DriveToolkitSpec, DriveToolkitParameter, } from './drive-toolkit';
14
16
  export { TELEGRAM_OPERATIONS, TELEGRAM_OPERATION_SPECS, isTelegramOperation, } from './telegram-operations';
15
17
  export type { TelegramOperation, TelegramParamSpec, TelegramOperationSpec, } from './telegram-operations';
16
18
  export { TELEGRAM_TOOLKIT_SPECS, TELEGRAM_TOOLKIT_BY_TOOL_NAME, } from './telegram-toolkit';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GOOGLE_CONTACTS_OPERATIONS_V2 = exports.GOOGLE_CONTACTS_OPERATIONS_V1 = exports.GOOGLE_CONTACTS_OPERATIONS = exports.SHEETS_TOOLKIT_DEFAULTABLE = exports.SHEETS_TOOLKIT_BY_TOOL_NAME = exports.SHEETS_TOOLKIT_SPECS = exports.isSheetsOperation = exports.SHEETS_OPERATION_SPECS = exports.SHEETS_OPERATIONS = exports.isSlackOperation = exports.SLACK_OPERATION_SPECS = exports.SLACK_OPERATIONS = exports.isDiscordOperation = exports.DISCORD_OPERATION_SPECS = exports.DISCORD_OPERATIONS = exports.isWhatsAppOperation = exports.WHATSAPP_OPERATIONS = exports.TELEGRAM_TOOLKIT_BY_TOOL_NAME = exports.TELEGRAM_TOOLKIT_SPECS = exports.isTelegramOperation = exports.TELEGRAM_OPERATION_SPECS = exports.TELEGRAM_OPERATIONS = exports.isDriveOperation = exports.DRIVE_OPERATIONS = exports.isGoogleCalendarOperation = exports.GOOGLE_CALENDAR_OPERATIONS = exports.isGmailOperation = exports.GMAIL_OPERATIONS = exports.NODE_TYPE_TO_PREFIX = exports.PREFIX_TO_NODE_TYPE = exports.NODE_STATE_KEYS = exports.NODE_COLORS = exports.NODE_DETAIL_PATHS = exports.getNodeRegistryEntry = exports.NODE_REGISTRY = exports.getNodeDispatchConfig = exports.getAllNodeCollections = exports.NODE_DISPATCH = exports.resolveNodeId = exports.PREFIX_TO_TYPE = exports.NODE_UI = exports.ALL_NODE_TYPES = exports.isNodeType = exports.isTerminal = exports.canSendToNodes = exports.canReceiveFromNodes = exports.canReceiveFrom = exports.NODE_CONNECTIONS = exports.iterableMeta = exports.singleMeta = void 0;
4
- exports.isCredentialType = exports.getCredentialType = exports.credentialTypeValues = exports.CREDENTIAL_TYPE_VALUES = exports.CREDENTIAL_TYPES = exports.isGoogleContactsOperation = exports.GOOGLE_CONTACTS_DEFAULT_PERSON_FIELDS = exports.GOOGLE_CONTACTS_OPERATION_GROUPS = exports.GOOGLE_CONTACTS_OPERATION_SPECS = void 0;
3
+ exports.SHEETS_TOOLKIT_DEFAULTABLE = exports.SHEETS_TOOLKIT_BY_TOOL_NAME = exports.SHEETS_TOOLKIT_SPECS = exports.isSheetsOperation = exports.SHEETS_OPERATION_SPECS = exports.SHEETS_OPERATIONS = exports.isSlackOperation = exports.SLACK_OPERATION_SPECS = exports.SLACK_OPERATIONS = exports.isDiscordOperation = exports.DISCORD_OPERATION_SPECS = exports.DISCORD_OPERATIONS = exports.isWhatsAppOperation = exports.WHATSAPP_OPERATIONS = exports.TELEGRAM_TOOLKIT_BY_TOOL_NAME = exports.TELEGRAM_TOOLKIT_SPECS = exports.isTelegramOperation = exports.TELEGRAM_OPERATION_SPECS = exports.TELEGRAM_OPERATIONS = exports.DRIVE_TOOLKIT_BY_TOOL_NAME = exports.DRIVE_TOOLKIT_SPECS = exports.isDriveOperation = exports.DRIVE_OPERATION_SPECS = exports.DRIVE_OPERATIONS = exports.isGoogleCalendarOperation = exports.GOOGLE_CALENDAR_OPERATIONS = exports.isGmailOperation = exports.GMAIL_OPERATIONS = exports.NODE_TYPE_TO_PREFIX = exports.PREFIX_TO_NODE_TYPE = exports.NODE_STATE_KEYS = exports.NODE_COLORS = exports.NODE_DETAIL_PATHS = exports.getNodeRegistryEntry = exports.NODE_REGISTRY = exports.getNodeDispatchConfig = exports.getAllNodeCollections = exports.NODE_DISPATCH = exports.resolveNodeId = exports.PREFIX_TO_TYPE = exports.NODE_UI = exports.ALL_NODE_TYPES = exports.isNodeType = exports.isTerminal = exports.canSendToNodes = exports.canReceiveFromNodes = exports.canReceiveFrom = exports.NODE_CONNECTIONS = exports.iterableMeta = exports.singleMeta = void 0;
4
+ exports.isCredentialType = exports.getCredentialType = exports.credentialTypeValues = exports.CREDENTIAL_TYPE_VALUES = exports.CREDENTIAL_TYPES = exports.isGoogleContactsOperation = exports.GOOGLE_CONTACTS_DEFAULT_PERSON_FIELDS = exports.GOOGLE_CONTACTS_OPERATION_GROUPS = exports.GOOGLE_CONTACTS_OPERATION_SPECS = exports.GOOGLE_CONTACTS_OPERATIONS_V2 = exports.GOOGLE_CONTACTS_OPERATIONS_V1 = exports.GOOGLE_CONTACTS_OPERATIONS = void 0;
5
5
  var types_1 = require("./types");
6
6
  Object.defineProperty(exports, "singleMeta", { enumerable: true, get: function () { return types_1.singleMeta; } });
7
7
  Object.defineProperty(exports, "iterableMeta", { enumerable: true, get: function () { return types_1.iterableMeta; } });
@@ -41,7 +41,11 @@ Object.defineProperty(exports, "GOOGLE_CALENDAR_OPERATIONS", { enumerable: true,
41
41
  Object.defineProperty(exports, "isGoogleCalendarOperation", { enumerable: true, get: function () { return calendar_operations_1.isGoogleCalendarOperation; } });
42
42
  var drive_operations_1 = require("./drive-operations");
43
43
  Object.defineProperty(exports, "DRIVE_OPERATIONS", { enumerable: true, get: function () { return drive_operations_1.DRIVE_OPERATIONS; } });
44
+ Object.defineProperty(exports, "DRIVE_OPERATION_SPECS", { enumerable: true, get: function () { return drive_operations_1.DRIVE_OPERATION_SPECS; } });
44
45
  Object.defineProperty(exports, "isDriveOperation", { enumerable: true, get: function () { return drive_operations_1.isDriveOperation; } });
46
+ var drive_toolkit_1 = require("./drive-toolkit");
47
+ Object.defineProperty(exports, "DRIVE_TOOLKIT_SPECS", { enumerable: true, get: function () { return drive_toolkit_1.DRIVE_TOOLKIT_SPECS; } });
48
+ Object.defineProperty(exports, "DRIVE_TOOLKIT_BY_TOOL_NAME", { enumerable: true, get: function () { return drive_toolkit_1.DRIVE_TOOLKIT_BY_TOOL_NAME; } });
45
49
  var telegram_operations_1 = require("./telegram-operations");
46
50
  Object.defineProperty(exports, "TELEGRAM_OPERATIONS", { enumerable: true, get: function () { return telegram_operations_1.TELEGRAM_OPERATIONS; } });
47
51
  Object.defineProperty(exports, "TELEGRAM_OPERATION_SPECS", { enumerable: true, get: function () { return telegram_operations_1.TELEGRAM_OPERATION_SPECS; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostwebhook/node-types",
3
- "version": "1.52.11",
3
+ "version": "1.52.12",
4
4
  "description": "Shared node type definitions, connection rules, and dispatch config for HostWebhook",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",