@hostwebhook/node-types 1.52.13 → 1.52.15

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.
@@ -16,3 +16,52 @@ export declare const GOOGLE_CALENDAR_OPERATIONS: readonly ["createEvent", "updat
16
16
  export type GoogleCalendarOperation = (typeof GOOGLE_CALENDAR_OPERATIONS)[number];
17
17
  /** Type guard — useful when validating untrusted input (DTOs, tool calls). */
18
18
  export declare function isGoogleCalendarOperation(value: unknown): value is GoogleCalendarOperation;
19
+ export type GoogleCalendarParamTarget = 'eventConfig' | 'listConfig' | 'root';
20
+ export type GoogleCalendarParamType =
21
+ /** Campo de texto con autocompletado de `{{payload.*}}`. */
22
+ 'template' | 'number' | 'select'
23
+ /** El `TimezonePicker` que ya existe en el dashboard. */
24
+ | 'timezone';
25
+ export interface GoogleCalendarParamSpec {
26
+ /** La clave DENTRO de `target`. Es la del cable, no un nombre de UI. */
27
+ name: string;
28
+ /** Dónde vive en la entidad. */
29
+ target: GoogleCalendarParamTarget;
30
+ label: string;
31
+ type: GoogleCalendarParamType;
32
+ required?: boolean;
33
+ /** Texto de ayuda. Llano: el paquete no lleva React. */
34
+ description?: string;
35
+ placeholder?: string;
36
+ default?: string | number;
37
+ options?: ReadonlyArray<{
38
+ value: string;
39
+ label: string;
40
+ }>;
41
+ min?: number;
42
+ max?: number;
43
+ /**
44
+ * Cómo se llama esta misma cosa en el `config` que espera el ejecutor
45
+ * compartido (`google-calendar-operations.service.ts`). El ejecutor está
46
+ * escrito para la ruta del toolkit, donde el LLM manda los nombres **sin**
47
+ * sufijo, así que `summaryTemplate` viaja como `summary`. Sólo lo llevan los
48
+ * params de las operaciones que van por ese despachador.
49
+ */
50
+ execKey?: string;
51
+ }
52
+ export interface GoogleCalendarOperationSpec {
53
+ /** Etiqueta del desplegable, y la misma que pinta el lienzo y el panel. */
54
+ label: string;
55
+ /** Sub-línea del desplegable. */
56
+ description: string;
57
+ /** Método de la API de Google al que corresponde. */
58
+ apiMethod: string;
59
+ /**
60
+ * Si se ejecuta por el despachador genérico (`calendarOps.run`) en vez de por
61
+ * un `case` escrito a mano. Son las cuatro que se abrieron el 2026-08-11.
62
+ */
63
+ viaExecutor?: boolean;
64
+ /** Orden de pantalla. */
65
+ params: GoogleCalendarParamSpec[];
66
+ }
67
+ export declare const GOOGLE_CALENDAR_OPERATION_SPECS: Record<GoogleCalendarOperation, GoogleCalendarOperationSpec>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GOOGLE_CALENDAR_OPERATIONS = void 0;
3
+ exports.GOOGLE_CALENDAR_OPERATION_SPECS = exports.GOOGLE_CALENDAR_OPERATIONS = void 0;
4
4
  exports.isGoogleCalendarOperation = isGoogleCalendarOperation;
5
5
  /**
6
6
  * Google Calendar operation enum — single source of truth across the API,
@@ -41,3 +41,140 @@ function isGoogleCalendarOperation(value) {
41
41
  return (typeof value === 'string' &&
42
42
  exports.GOOGLE_CALENDAR_OPERATIONS.includes(value));
43
43
  }
44
+ /* Fábricas de los campos que se repiten entre operaciones. */
45
+ const eventIdParam = (label, description) => ({
46
+ name: 'eventIdTemplate',
47
+ target: 'root',
48
+ label,
49
+ type: 'template',
50
+ required: true,
51
+ placeholder: '{{payload.eventId}}',
52
+ description,
53
+ execKey: 'eventId',
54
+ });
55
+ /** Los siete de `eventConfig`, que comparten `createEvent`, `updateEvent` y
56
+ `proposeEvent`. */
57
+ const eventConfigParams = () => [
58
+ { name: 'summaryTemplate', target: 'eventConfig', label: 'Summary', type: 'template', placeholder: '{{payload.title}}', execKey: 'summary' },
59
+ { name: 'descriptionTemplate', target: 'eventConfig', label: 'Description', type: 'template', placeholder: 'Event description... (supports {{templates}})', execKey: 'description' },
60
+ { name: 'locationTemplate', target: 'eventConfig', label: 'Location', type: 'template', placeholder: '{{payload.location}}', execKey: 'location' },
61
+ { name: 'startTemplate', target: 'eventConfig', label: 'Start Date', type: 'template', placeholder: '{{payload.startTime}}', execKey: 'start' },
62
+ { name: 'endTemplate', target: 'eventConfig', label: 'End Date', type: 'template', placeholder: '{{payload.endTime}}', execKey: 'end' },
63
+ {
64
+ name: 'attendeesTemplate',
65
+ target: 'eventConfig',
66
+ label: 'Attendees (comma-separated emails)',
67
+ type: 'template',
68
+ placeholder: '{{payload.attendees}}',
69
+ description: 'e.g. user@example.com, other@example.com',
70
+ execKey: 'attendees',
71
+ },
72
+ { name: 'timeZone', target: 'eventConfig', label: 'Time Zone', type: 'timezone', execKey: 'timeZone' },
73
+ ];
74
+ exports.GOOGLE_CALENDAR_OPERATION_SPECS = {
75
+ createEvent: {
76
+ label: 'Create Event',
77
+ description: 'Create a new calendar event',
78
+ apiMethod: 'events.insert',
79
+ params: eventConfigParams(),
80
+ },
81
+ updateEvent: {
82
+ label: 'Update Event',
83
+ description: 'Update an existing event by ID',
84
+ apiMethod: 'events.patch',
85
+ params: [
86
+ eventIdParam('Event ID', 'Template to resolve the Google Calendar event ID'),
87
+ ...eventConfigParams(),
88
+ ],
89
+ },
90
+ deleteEvent: {
91
+ label: 'Delete Event',
92
+ description: 'Delete an event by ID',
93
+ apiMethod: 'events.delete',
94
+ params: [eventIdParam('Event ID', 'Template to resolve the Google Calendar event ID')],
95
+ },
96
+ listEvents: {
97
+ label: 'List Events',
98
+ description: 'List events in a date range',
99
+ apiMethod: 'events.list',
100
+ params: [
101
+ { name: 'timeMinTemplate', target: 'listConfig', label: 'Start Date', type: 'template', placeholder: '{{payload.from}}', execKey: 'timeMin' },
102
+ { name: 'timeMaxTemplate', target: 'listConfig', label: 'End Date', type: 'template', placeholder: '{{payload.to}}', execKey: 'timeMax' },
103
+ { name: 'maxResults', target: 'listConfig', label: 'Max Results', type: 'number', min: 1, max: 2500, default: 10 },
104
+ { name: 'query', target: 'listConfig', label: 'Search Query', type: 'template', placeholder: 'meeting' },
105
+ ],
106
+ },
107
+ getEvent: {
108
+ label: 'Get Event',
109
+ description: 'Get a single event by ID',
110
+ apiMethod: 'events.get',
111
+ params: [eventIdParam('Event ID', 'Template to resolve the Google Calendar event ID')],
112
+ },
113
+ /* ── Las cuatro que se abrieron al modo directo el 2026-08-11 ── */
114
+ listCalendars: {
115
+ label: 'List Calendars',
116
+ description: 'List the calendars you can write to (iterable output)',
117
+ apiMethod: 'calendarList.list',
118
+ viaExecutor: true,
119
+ /* Sin campos: no toma nada. Es de descubrimiento, así que en un pipeline
120
+ determinista aporta poco; está por completitud del enum. */
121
+ params: [],
122
+ },
123
+ findFreeSlots: {
124
+ label: 'Find Free Slots',
125
+ description: 'Find open windows in a date range (iterable output)',
126
+ apiMethod: 'freebusy.query',
127
+ viaExecutor: true,
128
+ params: [
129
+ { name: 'timeMinTemplate', target: 'listConfig', label: 'Window Start', type: 'template', required: true, placeholder: '{{payload.from}}', description: 'ISO 8601. Start of the window to search.', execKey: 'timeMin' },
130
+ { name: 'timeMaxTemplate', target: 'listConfig', label: 'Window End', type: 'template', required: true, placeholder: '{{payload.to}}', description: 'ISO 8601. End of the window to search.', execKey: 'timeMax' },
131
+ { name: 'durationMinutes', target: 'listConfig', label: 'Slot Length (minutes)', type: 'number', min: 15, max: 480, default: 30, description: 'Only windows at least this long are returned.', execKey: 'durationMinutes' },
132
+ { name: 'calendarIds', target: 'listConfig', label: 'Extra Calendars (comma-separated ids)', type: 'template', placeholder: 'primary, team@example.com', description: 'Combine availability across these. Empty = just the calendar configured above.', execKey: 'calendarIds' },
133
+ { name: 'timeZone', target: 'listConfig', label: 'Time Zone', type: 'timezone', description: 'IANA zone used to read the window bounds.', execKey: 'timeZone' },
134
+ ],
135
+ },
136
+ proposeEvent: {
137
+ label: 'Propose Event (tentative)',
138
+ description: 'Create a tentative event — no invites sent',
139
+ apiMethod: 'events.insert (status: tentative)',
140
+ viaExecutor: true,
141
+ params: [
142
+ ...eventConfigParams(),
143
+ /* `recurrence` sólo entra aquí, que va por el ejecutor. `createEvent` y
144
+ `updateEvent` siguen sin él porque su ruta es el `buildEventBody`
145
+ escrito a mano del servicio: es una asimetría entre modos que ya
146
+ existía y que esto no crea ni arregla. */
147
+ {
148
+ name: 'recurrenceTemplate',
149
+ target: 'eventConfig',
150
+ label: 'Recurrence (RRULE)',
151
+ type: 'template',
152
+ placeholder: 'RRULE:FREQ=WEEKLY;BYDAY=MO',
153
+ description: 'One RFC 5545 rule. Empty = a one-off event.',
154
+ execKey: 'recurrence',
155
+ },
156
+ ],
157
+ },
158
+ confirmEvent: {
159
+ label: 'Confirm Proposed Event',
160
+ description: 'Promote a tentative event and send invites',
161
+ apiMethod: 'events.patch (status: confirmed)',
162
+ viaExecutor: true,
163
+ params: [
164
+ eventIdParam('Proposal ID', 'The proposalId a Propose Event run returned. Normally {{payload.proposalId}} from an upstream node — this op is meant to sit downstream of a Propose Event.'),
165
+ {
166
+ name: 'sendUpdates',
167
+ target: 'root',
168
+ label: 'Invite Policy',
169
+ type: 'select',
170
+ default: 'all',
171
+ options: [
172
+ { value: 'all', label: 'All attendees' },
173
+ { value: 'externalOnly', label: 'External attendees only' },
174
+ { value: 'none', label: "Don't send invites" },
175
+ ],
176
+ execKey: 'sendUpdates',
177
+ },
178
+ ],
179
+ },
180
+ };
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Calendar AI Toolkit — las nueve herramientas que un calendarAction expone
3
+ * cuando `aiEnabled` está encendido.
4
+ *
5
+ * **Se escribe una sola vez.** Antes vivía dos veces —aquí y en
6
+ * `api/src/mcp-servers/toolkit-specs.ts`— y las dos copias YA habían derivado:
7
+ * las **siete** operaciones que aceptan `calendarId` describían el parámetro de
8
+ * dos maneras distintas. Gana la de la api, que es la única que dice cuál es el
9
+ * defecto:
10
+ *
11
+ * api "Optional calendar id. Defaults to the configured calendar
12
+ * (usually 'primary'). Use list_my_calendars to discover ids."
13
+ * dashboard "Optional override of the configured calendar. Use
14
+ * list_my_calendars first to discover ids when the user
15
+ * mentions a non-default calendar."
16
+ *
17
+ * Esa deriva estaba en la descripción de un PARÁMETRO, así que el conteo de la
18
+ * auditoría del 2026-08-10 no la veía y daba Calendar por limpio. Con las
19
+ * descripciones de parámetro incluidas, la deriva real de los ocho toolkits
20
+ * duplicados eran 32 y no 18.
21
+ *
22
+ * Dos cosas que **no** se añaden, a propósito:
23
+ * - `group`: Calendar nunca tuvo cabeceras de grupo en su lista, y meterlas
24
+ * es estructura visible nueva.
25
+ * - `destructive` en `delete_calendar_event`: cambiaría el comportamiento de
26
+ * `requireConfirmationForDestructive`. Mismo criterio que en Telegram.
27
+ *
28
+ * El array se generó desde la copia de la api para que las descripciones largas
29
+ * salieran idénticas, no tecleadas.
30
+ */
31
+ import type { GoogleCalendarOperation } from './calendar-operations';
32
+ export interface GoogleCalendarToolkitParameter {
33
+ name: string;
34
+ type: 'string' | 'number' | 'boolean';
35
+ description: string;
36
+ required: boolean;
37
+ }
38
+ export interface GoogleCalendarToolkitSpec {
39
+ operation: GoogleCalendarOperation;
40
+ /** Etiqueta corta de la fila en la lista de herramientas. */
41
+ label: string;
42
+ /** El nombre con el que el LLM llama a la herramienta. */
43
+ toolName: string;
44
+ /** Descripción y reglas de uso que ve el LLM. */
45
+ description: string;
46
+ parameters: GoogleCalendarToolkitParameter[];
47
+ }
48
+ export declare const GOOGLE_CALENDAR_TOOLKIT_SPECS: GoogleCalendarToolkitSpec[];
49
+ /** Índice por nombre de herramienta, para enrutar un `tools/call` sin recorrer. */
50
+ export declare const GOOGLE_CALENDAR_TOOLKIT_BY_TOOL_NAME: Record<string, GoogleCalendarToolkitSpec>;
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ /**
3
+ * Calendar AI Toolkit — las nueve herramientas que un calendarAction expone
4
+ * cuando `aiEnabled` está encendido.
5
+ *
6
+ * **Se escribe una sola vez.** Antes vivía dos veces —aquí y en
7
+ * `api/src/mcp-servers/toolkit-specs.ts`— y las dos copias YA habían derivado:
8
+ * las **siete** operaciones que aceptan `calendarId` describían el parámetro de
9
+ * dos maneras distintas. Gana la de la api, que es la única que dice cuál es el
10
+ * defecto:
11
+ *
12
+ * api "Optional calendar id. Defaults to the configured calendar
13
+ * (usually 'primary'). Use list_my_calendars to discover ids."
14
+ * dashboard "Optional override of the configured calendar. Use
15
+ * list_my_calendars first to discover ids when the user
16
+ * mentions a non-default calendar."
17
+ *
18
+ * Esa deriva estaba en la descripción de un PARÁMETRO, así que el conteo de la
19
+ * auditoría del 2026-08-10 no la veía y daba Calendar por limpio. Con las
20
+ * descripciones de parámetro incluidas, la deriva real de los ocho toolkits
21
+ * duplicados eran 32 y no 18.
22
+ *
23
+ * Dos cosas que **no** se añaden, a propósito:
24
+ * - `group`: Calendar nunca tuvo cabeceras de grupo en su lista, y meterlas
25
+ * es estructura visible nueva.
26
+ * - `destructive` en `delete_calendar_event`: cambiaría el comportamiento de
27
+ * `requireConfirmationForDestructive`. Mismo criterio que en Telegram.
28
+ *
29
+ * El array se generó desde la copia de la api para que las descripciones largas
30
+ * salieran idénticas, no tecleadas.
31
+ */
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.GOOGLE_CALENDAR_TOOLKIT_BY_TOOL_NAME = exports.GOOGLE_CALENDAR_TOOLKIT_SPECS = void 0;
34
+ const p = (name, description, required = true, type = 'string') => ({ name, type, description, required });
35
+ exports.GOOGLE_CALENDAR_TOOLKIT_SPECS = [
36
+ {
37
+ operation: "createEvent",
38
+ label: "Create event",
39
+ toolName: "create_calendar_event",
40
+ description: "Create a new event on the user's calendar. USAGE RULES: (1) Always include start AND end (ISO 8601 datetime or YYYY-MM-DD for all-day). (2) For ALL-DAY events the `end` date is EXCLUSIVE — to cover Apr 19+20 send start=2026-04-19 end=2026-04-21. A single-day all-day event needs end = start + 1 day. (3) Confirm date + time + timezone in your reply (the user lives in Mexico City UTC-6 unless told otherwise). (4) Compose the summary fresh from the user's CURRENT request — never reuse content recalled from memory unless the user explicitly references it. (5) For events with external attendees or significant impact, prefer propose_calendar_event (tentative, no invites) so the user can preview before invites go out.",
41
+ parameters: [
42
+ p("summary", "Short event title.", true),
43
+ p("start", "Event start. ISO 8601 datetime (e.g. 2026-04-19T15:00:00) or date (YYYY-MM-DD) for all-day.", true),
44
+ p("end", "Event end. Same format as start. For all-day events this is EXCLUSIVE: an event that covers Apr 19+20 needs end=2026-04-21.", true),
45
+ p("description", "Optional longer description.", false),
46
+ p("location", "Optional physical or virtual location.", false),
47
+ p("attendees", "Comma-separated emails to invite.", false),
48
+ p("timeZone", "IANA timezone (e.g. America/Mexico_City). Defaults to UTC.", false),
49
+ p("recurrence", "Optional RFC 5545 RRULE string for repeating events (e.g. \"RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=10\"). Daily=\"RRULE:FREQ=DAILY\"; weekly Mon=\"RRULE:FREQ=WEEKLY;BYDAY=MO\"; monthly first=\"RRULE:FREQ=MONTHLY;BYDAY=1MO\". Confirm the recurrence pattern in your reply.", false),
50
+ p("calendarId", "Optional calendar id. Defaults to the configured calendar (usually 'primary'). Use list_my_calendars to discover ids.", false),
51
+ ],
52
+ },
53
+ {
54
+ operation: "updateEvent",
55
+ label: "Update event",
56
+ toolName: "update_calendar_event",
57
+ description: "Update an existing event by id. Only fields you provide are changed (PATCH semantics). USAGE RULES: (1) Use eventId from a getEvent / listEvents call earlier in THIS conversation, never from memory. (2) When changing time, confirm the new time + timezone in your reply. (3) EXTENDING an all-day event across more days: send the new `end` as the day AFTER the last day (Google's all-day end is EXCLUSIVE). To make an event cover Apr 19+20, set end=2026-04-21. (4) When you change one of start/end on an all-day event, send BOTH so the new range is unambiguous (otherwise PATCH may leave a stale boundary).",
58
+ parameters: [
59
+ p("eventId", "Event id from listEvents / getEvent in THIS conversation.", true),
60
+ p("summary", "Optional new title.", false),
61
+ p("start", "Optional new start. For all-day events use YYYY-MM-DD.", false),
62
+ p("end", "Optional new end. For all-day events this is EXCLUSIVE: to cover through Apr 20 send end=2026-04-21.", false),
63
+ p("description", "Optional new description.", false),
64
+ p("location", "Optional new location.", false),
65
+ p("attendees", "Optional new attendee list (REPLACES existing).", false),
66
+ p("timeZone", "Optional timezone.", false),
67
+ p("recurrence", "Optional RFC 5545 RRULE string for repeating events (e.g. \"RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=10\"). Daily=\"RRULE:FREQ=DAILY\"; weekly Mon=\"RRULE:FREQ=WEEKLY;BYDAY=MO\"; monthly first=\"RRULE:FREQ=MONTHLY;BYDAY=1MO\". Confirm the recurrence pattern in your reply.", false),
68
+ p("calendarId", "Optional calendar id. Defaults to the configured calendar (usually 'primary'). Use list_my_calendars to discover ids.", false),
69
+ ],
70
+ },
71
+ {
72
+ operation: "deleteEvent",
73
+ label: "Delete event",
74
+ toolName: "delete_calendar_event",
75
+ description: "Permanently delete an event. USAGE RULES: (1) ALWAYS confirm with the user before calling this — calendar deletes are silent and irreversible. (2) Use eventId from a tool call earlier in THIS conversation.",
76
+ parameters: [
77
+ p("eventId", "Event id to delete.", true),
78
+ p("calendarId", "Optional calendar id. Defaults to the configured calendar (usually 'primary'). Use list_my_calendars to discover ids.", false),
79
+ ],
80
+ },
81
+ {
82
+ operation: "listEvents",
83
+ label: "List events",
84
+ toolName: "list_calendar_events",
85
+ description: "Search the user's calendar. Returns headers (summary, start, end, attendees) per match. USAGE RULES: (1) Default to next 7 days when the user doesn't specify a window. (2) Use ISO datetimes for timeMin / timeMax. (3) For full event details (description, location), call getEvent with the specific id.",
86
+ parameters: [
87
+ p("timeMin", "Start of window (ISO 8601). Defaults to now.", false),
88
+ p("timeMax", "End of window (ISO 8601). Defaults to 7 days from now.", false),
89
+ p("maxResults", "Default 25, max 250.", false, "number"),
90
+ p("query", "Free-text search across summary/description/attendees.", false),
91
+ p("timeZone", "IANA timezone for parsing timeMin/timeMax.", false),
92
+ p("calendarId", "Optional calendar id. Defaults to the configured calendar (usually 'primary'). Use list_my_calendars to discover ids.", false),
93
+ ],
94
+ },
95
+ {
96
+ operation: "getEvent",
97
+ label: "Get event",
98
+ toolName: "get_calendar_event",
99
+ description: "Fetch a single event by id. Returns full details including description, attendees, organizer, recurrence.",
100
+ parameters: [
101
+ p("eventId", "Event id to fetch.", true),
102
+ p("calendarId", "Optional calendar id. Defaults to the configured calendar (usually 'primary'). Use list_my_calendars to discover ids.", false),
103
+ ],
104
+ },
105
+ {
106
+ operation: "listCalendars",
107
+ label: "List my calendars",
108
+ toolName: "list_my_calendars",
109
+ description: "Return all calendars the user can write to (primary + shared + secondary). USAGE RULES: (1) Call this when the user mentions a non-default calendar by name (e.g. 'add this to my Work calendar') and you don't yet know its id. (2) After listing, pass the matching `id` as `calendarId` on subsequent ops to target that calendar.",
110
+ parameters: [],
111
+ },
112
+ {
113
+ operation: "findFreeSlots",
114
+ label: "Find free slots",
115
+ toolName: "find_calendar_free_slots",
116
+ description: "Return open windows in a date range across one or more calendars. USAGE RULES: (1) Call this BEFORE proposing / creating an event when the user asks 'when am I free' or wants you to pick a time. (2) Default window: next 7 days, business hours 8am-6pm in the user's timezone. (3) Suggest the top 2-3 slots in your reply, then ask which they prefer.",
117
+ parameters: [
118
+ p("timeMin", "Start of window (ISO 8601).", true),
119
+ p("timeMax", "End of window (ISO 8601).", true),
120
+ p("durationMinutes", "Required slot length in minutes. Default 30, min 15, max 480.", false, "number"),
121
+ p("calendarIds", "Comma-separated calendar ids to combine availability across. Defaults to the configured calendar.", false),
122
+ p("timeZone", "IANA timezone for parsing timeMin/timeMax.", false),
123
+ ],
124
+ },
125
+ {
126
+ operation: "proposeEvent",
127
+ label: "Propose event (tentative)",
128
+ toolName: "propose_calendar_event",
129
+ description: "Create a TENTATIVE event (status: tentative, NO invites sent). The user sees it greyed out in their calendar. USAGE RULES: (1) Use this instead of create_calendar_event for events with external attendees or significant impact — the user previews before invites fire. (2) Show the proposalId in your reply ('I drafted: <details>. Confirm with proposalId X to send invites.'). (3) After the user confirms, call confirm_calendar_event with that proposalId. If they reject, call delete_calendar_event with it.",
130
+ parameters: [
131
+ p("summary", "Short event title.", true),
132
+ p("start", "Event start (ISO 8601 or YYYY-MM-DD for all-day).", true),
133
+ p("end", "Event end. For all-day events this is EXCLUSIVE: to cover through Apr 20 send end=2026-04-21.", true),
134
+ p("description", "Optional longer description.", false),
135
+ p("location", "Optional location.", false),
136
+ p("attendees", "Optional comma-separated emails (NOT invited yet — only saved on the tentative event).", false),
137
+ p("timeZone", "IANA timezone.", false),
138
+ p("recurrence", "Optional RFC 5545 RRULE string for repeating events (e.g. \"RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=10\"). Daily=\"RRULE:FREQ=DAILY\"; weekly Mon=\"RRULE:FREQ=WEEKLY;BYDAY=MO\"; monthly first=\"RRULE:FREQ=MONTHLY;BYDAY=1MO\". Confirm the recurrence pattern in your reply.", false),
139
+ p("calendarId", "Optional calendar id. Defaults to the configured calendar (usually 'primary'). Use list_my_calendars to discover ids.", false),
140
+ ],
141
+ },
142
+ {
143
+ operation: "confirmEvent",
144
+ label: "Confirm proposed event",
145
+ toolName: "confirm_calendar_event",
146
+ description: "Promote a tentative event to confirmed and (by default) send invites to attendees. Pairs with propose_calendar_event for the preview-then-commit flow. USAGE RULES: (1) Use the proposalId from your most recent propose_calendar_event call in THIS conversation — never from memory. (2) sendUpdates default 'all' fires invites; pass 'externalOnly' for just non-org attendees, or 'none' to silently confirm.",
147
+ parameters: [
148
+ p("eventId", "Proposal id (returned by propose_calendar_event as proposalId).", true),
149
+ p("sendUpdates", "Invite policy: 'all' (default), 'externalOnly', or 'none'.", false),
150
+ p("calendarId", "Optional calendar id. Defaults to the configured calendar (usually 'primary'). Use list_my_calendars to discover ids.", false),
151
+ ],
152
+ },
153
+ ];
154
+ /** Índice por nombre de herramienta, para enrutar un `tools/call` sin recorrer. */
155
+ exports.GOOGLE_CALENDAR_TOOLKIT_BY_TOOL_NAME = Object.fromEntries(exports.GOOGLE_CALENDAR_TOOLKIT_SPECS.map((s) => [s.toolName, s]));
package/dist/index.d.ts CHANGED
@@ -7,8 +7,10 @@ export type { NodeRegistryEntry, NodeGroup } from './registry';
7
7
  export { NODE_REGISTRY, getNodeRegistryEntry, NODE_DETAIL_PATHS, NODE_COLORS, NODE_STATE_KEYS, PREFIX_TO_NODE_TYPE, NODE_TYPE_TO_PREFIX, } from './registry';
8
8
  export { GMAIL_OPERATIONS, isGmailOperation, } from './gmail-operations';
9
9
  export type { GmailOperation } from './gmail-operations';
10
- export { GOOGLE_CALENDAR_OPERATIONS, isGoogleCalendarOperation, } from './calendar-operations';
11
- export type { GoogleCalendarOperation } from './calendar-operations';
10
+ export { GOOGLE_CALENDAR_OPERATIONS, GOOGLE_CALENDAR_OPERATION_SPECS, isGoogleCalendarOperation, } from './calendar-operations';
11
+ export type { GoogleCalendarOperation, GoogleCalendarParamTarget, GoogleCalendarParamType, GoogleCalendarParamSpec, GoogleCalendarOperationSpec, } from './calendar-operations';
12
+ export { GOOGLE_CALENDAR_TOOLKIT_SPECS, GOOGLE_CALENDAR_TOOLKIT_BY_TOOL_NAME, } from './calendar-toolkit';
13
+ export type { GoogleCalendarToolkitSpec, GoogleCalendarToolkitParameter, } from './calendar-toolkit';
12
14
  export { DRIVE_OPERATIONS, DRIVE_OPERATION_SPECS, isDriveOperation, } from './drive-operations';
13
15
  export type { DriveOperation, DriveParamType, DriveParamSpec, DriveOperationSpec, } from './drive-operations';
14
16
  export { DRIVE_TOOLKIT_SPECS, DRIVE_TOOLKIT_BY_TOOL_NAME, } from './drive-toolkit';
@@ -31,5 +33,7 @@ export { GOOGLE_CONTACTS_OPERATIONS, GOOGLE_CONTACTS_OPERATIONS_V1, GOOGLE_CONTA
31
33
  export type { GoogleContactsOperation, GoogleContactsParamSpec, GoogleContactsOperationSpec, GoogleContactsOperationGroup, } from './google-contacts-operations';
32
34
  export { POSTGRES_OPERATIONS, POSTGRES_MODES, POSTGRES_OPERATION_SPECS, isPostgresOperation, } from './postgres-operations';
33
35
  export type { PostgresOperation, PostgresMode, PostgresOperationSpec, } from './postgres-operations';
36
+ export { MONGO_OPERATIONS, MONGO_OPERATION_SPECS, isMongoOperation, } from './mongo-operations';
37
+ export type { MongoOperation, MongoParamType, MongoParamSpec, MongoOperationSpec, } from './mongo-operations';
34
38
  export type { CredentialTypeRegistration, CredentialType } from './credentials';
35
39
  export { CREDENTIAL_TYPES, CREDENTIAL_TYPE_VALUES, credentialTypeValues, getCredentialType, isCredentialType, } from './credentials';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
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.isPostgresOperation = exports.POSTGRES_OPERATION_SPECS = exports.POSTGRES_MODES = exports.POSTGRES_OPERATIONS = 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;
3
+ 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.GOOGLE_CALENDAR_TOOLKIT_BY_TOOL_NAME = exports.GOOGLE_CALENDAR_TOOLKIT_SPECS = exports.isGoogleCalendarOperation = exports.GOOGLE_CALENDAR_OPERATION_SPECS = 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.isMongoOperation = exports.MONGO_OPERATION_SPECS = exports.MONGO_OPERATIONS = exports.isPostgresOperation = exports.POSTGRES_OPERATION_SPECS = exports.POSTGRES_MODES = exports.POSTGRES_OPERATIONS = 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 = exports.SHEETS_TOOLKIT_DEFAULTABLE = exports.SHEETS_TOOLKIT_BY_TOOL_NAME = exports.SHEETS_TOOLKIT_SPECS = 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; } });
@@ -38,7 +38,11 @@ Object.defineProperty(exports, "GMAIL_OPERATIONS", { enumerable: true, get: func
38
38
  Object.defineProperty(exports, "isGmailOperation", { enumerable: true, get: function () { return gmail_operations_1.isGmailOperation; } });
39
39
  var calendar_operations_1 = require("./calendar-operations");
40
40
  Object.defineProperty(exports, "GOOGLE_CALENDAR_OPERATIONS", { enumerable: true, get: function () { return calendar_operations_1.GOOGLE_CALENDAR_OPERATIONS; } });
41
+ Object.defineProperty(exports, "GOOGLE_CALENDAR_OPERATION_SPECS", { enumerable: true, get: function () { return calendar_operations_1.GOOGLE_CALENDAR_OPERATION_SPECS; } });
41
42
  Object.defineProperty(exports, "isGoogleCalendarOperation", { enumerable: true, get: function () { return calendar_operations_1.isGoogleCalendarOperation; } });
43
+ var calendar_toolkit_1 = require("./calendar-toolkit");
44
+ Object.defineProperty(exports, "GOOGLE_CALENDAR_TOOLKIT_SPECS", { enumerable: true, get: function () { return calendar_toolkit_1.GOOGLE_CALENDAR_TOOLKIT_SPECS; } });
45
+ Object.defineProperty(exports, "GOOGLE_CALENDAR_TOOLKIT_BY_TOOL_NAME", { enumerable: true, get: function () { return calendar_toolkit_1.GOOGLE_CALENDAR_TOOLKIT_BY_TOOL_NAME; } });
42
46
  var drive_operations_1 = require("./drive-operations");
43
47
  Object.defineProperty(exports, "DRIVE_OPERATIONS", { enumerable: true, get: function () { return drive_operations_1.DRIVE_OPERATIONS; } });
44
48
  Object.defineProperty(exports, "DRIVE_OPERATION_SPECS", { enumerable: true, get: function () { return drive_operations_1.DRIVE_OPERATION_SPECS; } });
@@ -85,6 +89,10 @@ Object.defineProperty(exports, "POSTGRES_OPERATIONS", { enumerable: true, get: f
85
89
  Object.defineProperty(exports, "POSTGRES_MODES", { enumerable: true, get: function () { return postgres_operations_1.POSTGRES_MODES; } });
86
90
  Object.defineProperty(exports, "POSTGRES_OPERATION_SPECS", { enumerable: true, get: function () { return postgres_operations_1.POSTGRES_OPERATION_SPECS; } });
87
91
  Object.defineProperty(exports, "isPostgresOperation", { enumerable: true, get: function () { return postgres_operations_1.isPostgresOperation; } });
92
+ var mongo_operations_1 = require("./mongo-operations");
93
+ Object.defineProperty(exports, "MONGO_OPERATIONS", { enumerable: true, get: function () { return mongo_operations_1.MONGO_OPERATIONS; } });
94
+ Object.defineProperty(exports, "MONGO_OPERATION_SPECS", { enumerable: true, get: function () { return mongo_operations_1.MONGO_OPERATION_SPECS; } });
95
+ Object.defineProperty(exports, "isMongoOperation", { enumerable: true, get: function () { return mongo_operations_1.isMongoOperation; } });
88
96
  var credentials_1 = require("./credentials");
89
97
  Object.defineProperty(exports, "CREDENTIAL_TYPES", { enumerable: true, get: function () { return credentials_1.CREDENTIAL_TYPES; } });
90
98
  Object.defineProperty(exports, "CREDENTIAL_TYPE_VALUES", { enumerable: true, get: function () { return credentials_1.CREDENTIAL_TYPE_VALUES; } });
@@ -0,0 +1,61 @@
1
+ /**
2
+ * MongoDB operation enum + esquema del formulario — una sola copia para la api,
3
+ * el Dashboard y el broker.
4
+ *
5
+ * ── Lo que quita ──
6
+ * La lista estaba escrita a mano **cinco veces sólo en la api** (tres en el DTO,
7
+ * dos en la entidad) y otras tantas en el dashboard. Y de los siete valores,
8
+ * el lienzo sólo conocía **cinco**: `findAll` y `findOneAndUpdate` no estaban en
9
+ * sus mapas de etiqueta y color, así que se pintaban grises y con el nombre
10
+ * crudo en camelCase mientras el panel sí les daba azul y ámbar.
11
+ *
12
+ * ── Lo fácil de Mongo ──
13
+ * Al contrario que Drive o Calendar, aquí **no hay capa de renombrado**: el
14
+ * `name` de cada param es la prop de la entidad tal cual, y el `apiUpdate` de la
15
+ * página es un passthrough de una línea. Es la forma de guardado más simple de
16
+ * la tanda.
17
+ */
18
+ export declare const MONGO_OPERATIONS: readonly ["insertOne", "findOne", "findAll", "updateOne", "findOneAndUpdate", "deleteOne", "aggregate"];
19
+ export type MongoOperation = (typeof MONGO_OPERATIONS)[number];
20
+ /** Type guard — útil al validar entrada que no controlas (DTOs, tool calls). */
21
+ export declare function isMongoOperation(value: unknown): value is MongoOperation;
22
+ export type MongoParamType =
23
+ /** El `TemplateEditor` de JSON, con autocompletado de `{{payload.*}}`. */
24
+ 'jsonTemplate'
25
+ /** El componente `UpdateBuilder` (arma `$set`, `$inc`… sin escribir JSON). */
26
+ | 'updateBuilder'
27
+ /**
28
+ * Un `Switch` que se guarda **al instante** (`updateFieldInstant`) y se lee de
29
+ * la entidad, no de los locales. Se conserva así porque es como estaba.
30
+ */
31
+ | 'booleanInstant';
32
+ export interface MongoParamSpec {
33
+ /** La prop de la entidad. Sin renombrado: es también la clave del cable. */
34
+ name: string;
35
+ label: string;
36
+ type: MongoParamType;
37
+ /** Texto de ayuda. Llano: el paquete no lleva React. */
38
+ description?: string;
39
+ placeholder?: string;
40
+ /** Sólo para `jsonTemplate`: la altura del editor. */
41
+ minHeight?: number;
42
+ maxHeight?: number;
43
+ }
44
+ export interface MongoOperationSpec {
45
+ /** La del desplegable de la página de detalle: «Insert One». */
46
+ label: string;
47
+ /**
48
+ * La de la píldora estrecha del lienzo y del panel: «INSERT».
49
+ *
50
+ * **Son dos etiquetas a propósito**, como en Calendar: dos anchos distintos y
51
+ * las dos se ven. Antes había una TERCERA convención, porque el panel pintaba
52
+ * `operation.toUpperCase()` y decía «FINDONEANDUPDATE» donde el lienzo decía
53
+ * «UPDATE». Ahora los dos leen esta.
54
+ */
55
+ labelShort: string;
56
+ /** Sub-línea del desplegable. */
57
+ description: string;
58
+ /** Orden de pantalla. */
59
+ params: MongoParamSpec[];
60
+ }
61
+ export declare const MONGO_OPERATION_SPECS: Record<MongoOperation, MongoOperationSpec>;
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ /**
3
+ * MongoDB operation enum + esquema del formulario — una sola copia para la api,
4
+ * el Dashboard y el broker.
5
+ *
6
+ * ── Lo que quita ──
7
+ * La lista estaba escrita a mano **cinco veces sólo en la api** (tres en el DTO,
8
+ * dos en la entidad) y otras tantas en el dashboard. Y de los siete valores,
9
+ * el lienzo sólo conocía **cinco**: `findAll` y `findOneAndUpdate` no estaban en
10
+ * sus mapas de etiqueta y color, así que se pintaban grises y con el nombre
11
+ * crudo en camelCase mientras el panel sí les daba azul y ámbar.
12
+ *
13
+ * ── Lo fácil de Mongo ──
14
+ * Al contrario que Drive o Calendar, aquí **no hay capa de renombrado**: el
15
+ * `name` de cada param es la prop de la entidad tal cual, y el `apiUpdate` de la
16
+ * página es un passthrough de una línea. Es la forma de guardado más simple de
17
+ * la tanda.
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.MONGO_OPERATION_SPECS = exports.MONGO_OPERATIONS = void 0;
21
+ exports.isMongoOperation = isMongoOperation;
22
+ exports.MONGO_OPERATIONS = [
23
+ 'insertOne', // inserta un documento
24
+ 'findOne', // devuelve el primero que casa
25
+ 'findAll', // devuelve todos los que casan (tope 1000)
26
+ 'updateOne', // actualiza el primero que casa
27
+ 'findOneAndUpdate', // actualiza y devuelve el documento
28
+ 'deleteOne', // borra el primero que casa
29
+ 'aggregate', // pipeline de agregación
30
+ ];
31
+ /** Type guard — útil al validar entrada que no controlas (DTOs, tool calls). */
32
+ function isMongoOperation(value) {
33
+ return typeof value === 'string' && exports.MONGO_OPERATIONS.includes(value);
34
+ }
35
+ /* Los campos que comparten varias operaciones. */
36
+ const queryTemplate = () => ({
37
+ name: 'queryTemplate',
38
+ label: 'Query Template',
39
+ type: 'jsonTemplate',
40
+ placeholder: '{"email": "{{payload.email}}"}',
41
+ minHeight: 100,
42
+ maxHeight: 200,
43
+ });
44
+ const updateTemplate = () => ({
45
+ name: 'updateTemplate',
46
+ label: 'Update Operations',
47
+ type: 'updateBuilder',
48
+ });
49
+ exports.MONGO_OPERATION_SPECS = {
50
+ insertOne: {
51
+ label: 'Insert One',
52
+ labelShort: 'INSERT',
53
+ description: 'Insert a single document',
54
+ params: [
55
+ {
56
+ name: 'documentTemplate',
57
+ label: 'Document Template',
58
+ type: 'jsonTemplate',
59
+ placeholder: '{"name": "{{payload.name}}", "email": "{{payload.email}}"}',
60
+ minHeight: 100,
61
+ maxHeight: 200,
62
+ },
63
+ ],
64
+ },
65
+ findOne: {
66
+ label: 'Find One',
67
+ labelShort: 'FIND',
68
+ description: 'Find a single matching document',
69
+ params: [queryTemplate()],
70
+ },
71
+ findAll: {
72
+ label: 'Find All',
73
+ /* Antes no estaba en el mapa del lienzo y salía el crudo `findAll`. */
74
+ labelShort: 'FIND ALL',
75
+ description: 'Find all matching documents (limit 1000)',
76
+ params: [
77
+ /* El interruptor va ANTES del query, que es el orden en que se pintaba. */
78
+ {
79
+ name: 'includeCount',
80
+ label: 'Include Count',
81
+ type: 'booleanInstant',
82
+ description: 'Return total count of matching documents alongside results',
83
+ },
84
+ queryTemplate(),
85
+ ],
86
+ },
87
+ updateOne: {
88
+ label: 'Update One',
89
+ labelShort: 'UPDATE',
90
+ description: 'Update a single matching document',
91
+ params: [queryTemplate(), updateTemplate()],
92
+ },
93
+ findOneAndUpdate: {
94
+ label: 'Find & Update',
95
+ /* Tampoco estaba: salía el crudo `findOneAndUpdate` en el lienzo y
96
+ `FINDONEANDUPDATE` en el panel. */
97
+ labelShort: 'FIND & UPDATE',
98
+ description: 'Find, update, and return the document',
99
+ params: [queryTemplate(), updateTemplate()],
100
+ },
101
+ deleteOne: {
102
+ label: 'Delete One',
103
+ labelShort: 'DELETE',
104
+ description: 'Delete a single matching document',
105
+ params: [queryTemplate()],
106
+ },
107
+ aggregate: {
108
+ label: 'Aggregate',
109
+ labelShort: 'AGGREGATE',
110
+ description: 'Run aggregation pipeline ($match, $group, $sort...)',
111
+ params: [
112
+ {
113
+ /* Mismo campo que en las demás, con otro título y otro ejemplo: por eso
114
+ los params se declaran por operación y no en un registro global. */
115
+ name: 'queryTemplate',
116
+ label: 'Pipeline Template',
117
+ type: 'jsonTemplate',
118
+ placeholder: '[{"$match": {"status": "active"}}, {"$group": {"_id": "$category"}}]',
119
+ minHeight: 100,
120
+ maxHeight: 200,
121
+ },
122
+ ],
123
+ },
124
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostwebhook/node-types",
3
- "version": "1.52.13",
3
+ "version": "1.52.15",
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",