@hostwebhook/node-types 1.69.0 → 1.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/bucket-operations.d.ts +88 -0
  2. package/dist/bucket-operations.js +140 -0
  3. package/dist/calendar-toolkit.d.ts +1 -1
  4. package/dist/connections.d.ts +1 -1
  5. package/dist/connections.js +1 -0
  6. package/dist/discord-operations.d.ts +1 -1
  7. package/dist/discord-operations.js +4 -4
  8. package/dist/discord-toolkit.d.ts +1 -1
  9. package/dist/discord-toolkit.js +3 -3
  10. package/dist/dispatch.d.ts +1 -1
  11. package/dist/dispatch.js +1 -0
  12. package/dist/docs-toolkit.d.ts +1 -1
  13. package/dist/drive-toolkit.d.ts +1 -1
  14. package/dist/esm/bucket-operations.d.ts +88 -0
  15. package/dist/esm/bucket-operations.js +136 -0
  16. package/dist/esm/calendar-operations.d.ts +67 -0
  17. package/dist/esm/calendar-operations.js +176 -0
  18. package/dist/esm/calendar-toolkit.d.ts +50 -0
  19. package/dist/esm/calendar-toolkit.js +152 -0
  20. package/dist/esm/capacidad-de-credencial.d.ts +75 -0
  21. package/dist/esm/capacidad-de-credencial.js +68 -0
  22. package/dist/esm/connections.d.ts +17 -0
  23. package/dist/esm/connections.js +107 -0
  24. package/dist/esm/credentials.d.ts +144 -0
  25. package/dist/esm/credentials.js +199 -0
  26. package/dist/esm/discord-operations.d.ts +104 -0
  27. package/dist/esm/discord-operations.js +407 -0
  28. package/dist/esm/discord-toolkit.d.ts +64 -0
  29. package/dist/esm/discord-toolkit.js +260 -0
  30. package/dist/esm/dispatch.d.ts +16 -0
  31. package/dist/esm/dispatch.js +77 -0
  32. package/dist/esm/docs-operations.d.ts +99 -0
  33. package/dist/esm/docs-operations.js +127 -0
  34. package/dist/esm/docs-toolkit.d.ts +42 -0
  35. package/dist/esm/docs-toolkit.js +97 -0
  36. package/dist/esm/drive-operations.d.ts +103 -0
  37. package/dist/esm/drive-operations.js +319 -0
  38. package/dist/esm/drive-toolkit.d.ts +54 -0
  39. package/dist/esm/drive-toolkit.js +177 -0
  40. package/dist/esm/github-operations.d.ts +147 -0
  41. package/dist/esm/github-operations.js +551 -0
  42. package/dist/esm/gmail-operations.d.ts +190 -0
  43. package/dist/esm/gmail-operations.js +560 -0
  44. package/dist/esm/google-analytics-operations.d.ts +99 -0
  45. package/dist/esm/google-analytics-operations.js +222 -0
  46. package/dist/esm/google-contacts-operations.d.ts +93 -0
  47. package/dist/esm/google-contacts-operations.js +363 -0
  48. package/dist/esm/index.d.ts +68 -0
  49. package/dist/esm/index.js +51 -0
  50. package/dist/esm/jira-operations.d.ts +164 -0
  51. package/dist/esm/jira-operations.js +470 -0
  52. package/dist/esm/llm-models.d.ts +101 -0
  53. package/dist/esm/llm-models.js +230 -0
  54. package/dist/esm/mailchimp-operations.d.ts +56 -0
  55. package/dist/esm/mailchimp-operations.js +155 -0
  56. package/dist/esm/mongo-operations.d.ts +61 -0
  57. package/dist/esm/mongo-operations.js +120 -0
  58. package/dist/esm/notion-operations.d.ts +125 -0
  59. package/dist/esm/notion-operations.js +511 -0
  60. package/dist/esm/openrouter.d.ts +142 -0
  61. package/dist/esm/openrouter.js +99 -0
  62. package/dist/esm/package.json +4 -0
  63. package/dist/esm/postgres-operations.d.ts +60 -0
  64. package/dist/esm/postgres-operations.js +75 -0
  65. package/dist/esm/registry.d.ts +160 -0
  66. package/dist/esm/registry.js +885 -0
  67. package/dist/esm/sheets-operations.d.ts +78 -0
  68. package/dist/esm/sheets-operations.js +150 -0
  69. package/dist/esm/sheets-toolkit.d.ts +49 -0
  70. package/dist/esm/sheets-toolkit.js +127 -0
  71. package/dist/esm/shopify-operations.d.ts +95 -0
  72. package/dist/esm/shopify-operations.js +259 -0
  73. package/dist/esm/slack-operations.d.ts +81 -0
  74. package/dist/esm/slack-operations.js +244 -0
  75. package/dist/esm/slack-toolkit.d.ts +60 -0
  76. package/dist/esm/slack-toolkit.js +235 -0
  77. package/dist/esm/telegram-operations.d.ts +104 -0
  78. package/dist/esm/telegram-operations.js +351 -0
  79. package/dist/esm/telegram-toolkit.d.ts +52 -0
  80. package/dist/esm/telegram-toolkit.js +183 -0
  81. package/dist/esm/types.d.ts +149 -0
  82. package/dist/esm/types.js +8 -0
  83. package/dist/esm/ui.d.ts +13 -0
  84. package/dist/esm/ui.js +152 -0
  85. package/dist/esm/whatsapp-operations.d.ts +23 -0
  86. package/dist/esm/whatsapp-operations.js +36 -0
  87. package/dist/index.d.ts +68 -66
  88. package/dist/index.js +193 -187
  89. package/dist/openrouter.d.ts +1 -1
  90. package/dist/registry.d.ts +4 -4
  91. package/dist/registry.js +540 -210
  92. package/dist/sheets-toolkit.d.ts +1 -1
  93. package/dist/slack-operations.d.ts +1 -1
  94. package/dist/slack-operations.js +4 -4
  95. package/dist/slack-toolkit.d.ts +1 -1
  96. package/dist/slack-toolkit.js +3 -3
  97. package/dist/telegram-toolkit.d.ts +1 -1
  98. package/dist/types.d.ts +1 -1
  99. package/dist/ui.d.ts +1 -1
  100. package/dist/ui.js +2 -0
  101. package/package.json +21 -3
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Slack AI Toolkit — las herramientas que un slackAction expone cuando
3
+ * `aiEnabled` está encendido.
4
+ *
5
+ * **Se escribe una sola vez.** Antes vivía dos veces: una copia en
6
+ * `dashboard/components/slack-actions/slack-operations-schemas.ts` y otra en
7
+ * `api/src/mcp-servers/toolkit-specs.ts`, las dos a mano y en repos distintos,
8
+ * así que ningún test podía compararlas. Es la octava y novena mudanza de esta
9
+ * serie; de las siete anteriores, la de Contacts salió de que una copia
10
+ * anunciara 15 herramientas y expusiera una.
11
+ *
12
+ * La deriva aquí era gorda: **14 de las 16 descripciones** diferían. Gana la de
13
+ * la api en todas —es sistemáticamente la más completa y es la que sirve el MCP
14
+ * hoy—, y una no era cosmética: en `deleteMessage` la api nombra el permiso que
15
+ * hace falta (`chat:write.public` + admin) y el dashboard sólo decía «admin
16
+ * perms». Operaciones, nombres de herramienta y parámetros sí coincidían.
17
+ *
18
+ * Los nombres llevan `_slack_` para no chocar con los de Telegram y Discord
19
+ * cuando un mismo AI Node tiene varios toolkits encendidos.
20
+ *
21
+ * La forma es la que ya consume `toolkitSpecToMcpTool` en la api, para que
22
+ * pueda usarse sin adaptador. Los textos van en inglés porque los lee el modelo
23
+ * y quien mire la lista de herramientas del servidor MCP.
24
+ */
25
+ import { camposDeSlackNoDisponibles, operacionesDeSlackPara, } from './slack-operations.js';
26
+ const p = (name, description, required = true, type = 'string') => ({ name, type, description, required });
27
+ export const SLACK_TOOLKIT_SPECS = [
28
+ // ── Messages ─────────────────────────────────────────────────────
29
+ {
30
+ operation: 'sendMessage',
31
+ label: 'Send message',
32
+ toolName: 'send_slack_message',
33
+ description: 'Post a message to a Slack channel, group, or DM. ' +
34
+ 'USAGE RULES: ' +
35
+ '(1) `channel` is a Slack channel id (C…), group id (G…), or DM id (D…). Get it from the trigger payload, listChannels, or the user. Never invent one. ' +
36
+ '(2) For a thread reply, set `threadTs` to the parent message timestamp. ' +
37
+ '(3) Either `text` or `blocks` is required. Use blocks for rich layouts.',
38
+ parameters: [
39
+ p('channel', 'Channel/group/DM id where the message will be posted.'),
40
+ p('text', 'Message text. Slack mrkdwn supported. Required when blocks is empty.', false),
41
+ p('blocks', 'Block Kit JSON for rich layouts. Stringified JSON or JSON array.', false),
42
+ p('threadTs', 'Parent message timestamp to reply inside an existing thread.', false),
43
+ ],
44
+ },
45
+ {
46
+ operation: 'updateMessage',
47
+ label: 'Update message',
48
+ toolName: 'update_slack_message',
49
+ description: 'Edit a message previously posted by the bot. The bot can only edit its own messages — editing another user/bot message returns cant_update_message.',
50
+ parameters: [
51
+ p('channel', 'Channel where the original message lives.'),
52
+ p('ts', 'Timestamp of the message to edit (returned by sendMessage).'),
53
+ p('text', 'New message text. Required when blocks is empty.', false),
54
+ p('blocks', 'New Block Kit JSON. Replaces the existing layout.', false),
55
+ ],
56
+ },
57
+ {
58
+ operation: 'deleteMessage',
59
+ label: 'Delete message',
60
+ toolName: 'delete_slack_message',
61
+ description: "Delete a message the bot posted. Other users' messages need chat:write.public + admin perms — usually fails for AI-driven calls. Confirm before destructive use.",
62
+ parameters: [
63
+ p('channel', 'Channel where the message lives.'),
64
+ p('ts', 'Timestamp of the message to delete.'),
65
+ ],
66
+ destructive: true,
67
+ },
68
+ {
69
+ operation: 'sendEphemeral',
70
+ label: 'Send ephemeral',
71
+ toolName: 'send_slack_ephemeral',
72
+ description: 'Post a message visible only to a specific user — the rest of the channel does not see it. Useful for per-user prompts, errors, or warnings.',
73
+ parameters: [
74
+ p('channel', 'Channel where the ephemeral message will appear.'),
75
+ p('user', 'User id (U…) — the only viewer of the message.'),
76
+ p('text', 'Message text. Required when blocks is empty.', false),
77
+ p('blocks', 'Block Kit JSON for rich layouts.', false),
78
+ ],
79
+ },
80
+ {
81
+ operation: 'scheduleMessage',
82
+ label: 'Schedule message',
83
+ toolName: 'schedule_slack_message',
84
+ description: 'Schedule a Slack message to be posted at a future time. Returns a scheduled_message_id useful for cancellation later.',
85
+ parameters: [
86
+ p('channel', 'Channel where the message will be posted.'),
87
+ p('postAt', 'When to post — unix timestamp in SECONDS, not milliseconds.', true, 'number'),
88
+ p('text', 'Message text. Required when blocks is empty.', false),
89
+ p('blocks', 'Block Kit JSON for rich layouts.', false),
90
+ ],
91
+ },
92
+ {
93
+ operation: 'getMessage',
94
+ label: 'Get message',
95
+ toolName: 'get_slack_message',
96
+ description: 'Fetch a single message by its timestamp. Returns the message text + author + reactions + attachments. Use BEFORE editing or reacting to verify state.',
97
+ parameters: [
98
+ p('channel', 'Channel where the message lives.'),
99
+ p('ts', 'Timestamp of the message to fetch.'),
100
+ ],
101
+ },
102
+ // ── Channels ─────────────────────────────────────────────────────
103
+ {
104
+ operation: 'listChannels',
105
+ label: 'List channels',
106
+ toolName: 'list_slack_channels',
107
+ description: 'List public + private channels the bot can see in the workspace. Returns id, name, isMember, memberCount per channel. Pre-pick a channel before sendMessage.',
108
+ parameters: [
109
+ p('limit', 'Max channels to return (1-1000). Default 200.', false, 'number'),
110
+ p('excludeArchived', 'Hide archived channels. Default true.', false, 'boolean'),
111
+ ],
112
+ },
113
+ {
114
+ operation: 'getChannelHistory',
115
+ label: 'Get channel history',
116
+ toolName: 'get_slack_channel_history',
117
+ description: 'Read recent messages from a Slack channel. Useful for summarization, context retrieval, or finding a message by content before editing/reacting.',
118
+ parameters: [
119
+ p('channel', 'Channel id to read from.'),
120
+ p('limit', 'Max messages to return (1-200). Default 50.', false, 'number'),
121
+ p('oldest', 'Only messages newer than this timestamp.', false),
122
+ p('latest', 'Only messages older than this timestamp.', false),
123
+ ],
124
+ },
125
+ {
126
+ operation: 'getThreadReplies',
127
+ label: 'Get thread replies',
128
+ toolName: 'get_slack_thread_replies',
129
+ description: 'Fetch the replies inside a Slack thread, given the parent message timestamp. Use for summarizing or continuing a thread.',
130
+ parameters: [
131
+ p('channel', 'Channel where the thread lives.'),
132
+ p('ts', 'Timestamp of the thread parent message.'),
133
+ p('limit', 'Max replies to return (1-1000). Default 100.', false, 'number'),
134
+ ],
135
+ },
136
+ {
137
+ operation: 'createChannel',
138
+ label: 'Create channel',
139
+ toolName: 'create_slack_channel',
140
+ description: 'Create a new public or private Slack channel. Names must be lowercase, no spaces, max 80 chars. Confirm with the user before creating channels — they are usually long-lived org artifacts.',
141
+ parameters: [
142
+ p('name', 'Channel name — lowercase, no spaces, max 80 chars.'),
143
+ p('isPrivate', 'Create a private channel instead of public. Default false.', false, 'boolean'),
144
+ ],
145
+ destructive: true,
146
+ },
147
+ {
148
+ operation: 'inviteToChannel',
149
+ label: 'Invite to channel',
150
+ toolName: 'invite_to_slack_channel',
151
+ description: 'Invite one or more users to a Slack channel by user id. Comma-separated `users` argument.',
152
+ parameters: [
153
+ p('channel', 'Channel id to invite users to.'),
154
+ p('users', 'Comma-separated user ids (U…) to invite.'),
155
+ ],
156
+ },
157
+ // ── Reactions ────────────────────────────────────────────────────
158
+ {
159
+ operation: 'addReaction',
160
+ label: 'Add reaction',
161
+ toolName: 'add_slack_reaction',
162
+ description: 'Add an emoji reaction to a Slack message as the bot. Use the emoji NAME without colons (e.g. `thumbsup`, `white_check_mark`, `eyes`).',
163
+ parameters: [
164
+ p('channel', 'Channel where the message lives.'),
165
+ p('ts', 'Timestamp of the message to react to.'),
166
+ p('name', 'Emoji name without colons.'),
167
+ ],
168
+ },
169
+ {
170
+ operation: 'removeReaction',
171
+ label: 'Remove reaction',
172
+ toolName: 'remove_slack_reaction',
173
+ description: "Remove the bot's own emoji reaction from a Slack message. Cannot remove other users' reactions.",
174
+ parameters: [
175
+ p('channel', 'Channel where the message lives.'),
176
+ p('ts', 'Timestamp of the message.'),
177
+ p('name', 'Emoji name without colons.'),
178
+ ],
179
+ },
180
+ // ── Users ────────────────────────────────────────────────────────
181
+ {
182
+ operation: 'listUsers',
183
+ label: 'List users',
184
+ toolName: 'list_slack_users',
185
+ description: 'List human members of the Slack workspace. Returns id, name, real_name, email, avatarUrl. Excludes deleted users + bots by default.',
186
+ parameters: [
187
+ p('limit', 'Max users to return (1-1000). Default 200.', false, 'number'),
188
+ p('includeDeleted', 'Include deactivated users. Default false.', false, 'boolean'),
189
+ p('includeBots', 'Include bot users + app users. Default false.', false, 'boolean'),
190
+ ],
191
+ },
192
+ {
193
+ operation: 'getUserInfo',
194
+ label: 'Get user info',
195
+ toolName: 'get_slack_user_info',
196
+ description: 'Fetch a Slack user profile (real_name, email, timezone, status, avatar). Use BEFORE sendEphemeral to confirm the user id is valid.',
197
+ parameters: [p('user', 'User id (U…) to look up.')],
198
+ },
199
+ // ── Files ────────────────────────────────────────────────────────
200
+ {
201
+ operation: 'uploadFile',
202
+ label: 'Upload file',
203
+ toolName: 'upload_slack_file',
204
+ description: 'Upload a file to Slack and optionally share it in a channel. Provide either a public `url` to fetch or inline `contentBase64` for small payloads. Optionally attach to a thread via `threadTs`.',
205
+ parameters: [
206
+ p('url', 'Public URL or HW _file.downloadUrl that HW will fetch and re-upload.', false),
207
+ p('contentBase64', 'Inline base64 file content (alternative to url).', false),
208
+ p('filename', 'Display name in Slack. Auto-derived from URL when omitted.', false),
209
+ p('channel', 'Channel id to share the uploaded file in.', false),
210
+ p('title', 'Title shown above the file.', false),
211
+ p('initialComment', 'Message Slack posts together with the file.', false),
212
+ p('threadTs', 'Thread to attach the file to.', false),
213
+ ],
214
+ },
215
+ ];
216
+ export const SLACK_TOOLKIT_BY_TOOL_NAME = Object.fromEntries(SLACK_TOOLKIT_SPECS.map((s) => [s.toolName, s]));
217
+ /**
218
+ * Las herramientas que ofrecerle al modelo con ESTA credencial.
219
+ *
220
+ * Gemelo de `herramientasDeDiscordPara`, y por la misma razón: los dos
221
+ * consumidores —la expansión MCP de la api y el selector del AI Node del
222
+ * dashboard— filtrarían por su cuenta y acabarían discrepando.
223
+ *
224
+ * En Slack el recorte es brutal y conviene verlo escrito: con un webhook el
225
+ * modelo pasa de **16 herramientas a una**, y esa una pierde el `channel`,
226
+ * porque el destino lo fijó quien instaló la credencial. Dejarle el campo sería
227
+ * invitarle a elegir un canal que Slack va a ignorar sin decir nada.
228
+ */
229
+ export function herramientasDeSlackPara(tipoDeCredencial) {
230
+ const permitidas = new Set(operacionesDeSlackPara(tipoDeCredencial));
231
+ const fuera = camposDeSlackNoDisponibles(tipoDeCredencial);
232
+ return SLACK_TOOLKIT_SPECS.filter((s) => permitidas.has(s.operation)).map((s) => fuera.size === 0
233
+ ? s
234
+ : { ...s, parameters: s.parameters.filter((p) => !fuera.has(p.name)) });
235
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Telegram Bot API operation enum — single source of truth across the API,
3
+ * Dashboard, and any future consumers (Message Broker, MCP server). Used by:
4
+ * - telegramAction entity / DTO (api): operation field + validation
5
+ * - dashboard TelegramAction operation picker
6
+ * - MCP toolkit-specs expansion (one aiEnabled telegramAction → N tools)
7
+ *
8
+ * Phase 1 covers the eight ops that handle ~95% of bot send use cases.
9
+ * Phase 2 candidates (sendMediaGroup, voice/video uploads, chat admin,
10
+ * setMyCommands, message reactions, inline-mode answers) get added by
11
+ * extending this list, bumping the package, and re-installing in
12
+ * consumers — same pattern as Gmail / Calendar / Drive.
13
+ */
14
+ export declare const TELEGRAM_OPERATIONS: readonly ["sendMessage", "replyToMessage", "sendPhoto", "sendDocument", "sendVoice", "sendAndWaitForResponse", "editMessageText", "deleteMessage", "answerCallbackQuery", "forwardMessage", "sendPoll"];
15
+ export type TelegramOperation = (typeof TELEGRAM_OPERATIONS)[number];
16
+ /** Type guard — useful when validating untrusted input (DTOs, tool calls). */
17
+ export declare function isTelegramOperation(value: unknown): value is TelegramOperation;
18
+ /**
19
+ * Per-operation form schema, same idea as SLACK_OPERATION_SPECS and
20
+ * DISCORD_OPERATION_SPECS: the detail page renders it with one loop instead of
21
+ * a branch per operation. It replaces 12 branches and a local `OPERATIONS`
22
+ * array of 11 entries whose count had already drifted from the truth — the
23
+ * mode chip read "Choose 1 of 10 ops" while the page painted 11 cards.
24
+ *
25
+ * Two things about this node's schema are worth knowing before writing a
26
+ * renderer for it:
27
+ *
28
+ * 1. **`chatId` is per-operation, not global.** The page used to hoist one
29
+ * shared field to the top of every form, but `answerCallbackQuery` has no
30
+ * chat at all (it answers a callback id) and `forwardMessage` needs two
31
+ * chats with their own labels — "Destination" and "Source". So it is
32
+ * declared op by op, and where it repeats it repeats on purpose.
33
+ * 2. **Three booleans default to ON.** See the note on `default` below; a
34
+ * renderer that coerces with `!!config[name]` silently turns them off.
35
+ */
36
+ export interface TelegramParamSpec {
37
+ /** Field key — the property name inside `operationConfig`. */
38
+ name: string;
39
+ /** UI label shown above the control. */
40
+ label: string;
41
+ /**
42
+ * Param type for form rendering.
43
+ *
44
+ * - `string` — one-line input with `{{payload.x}}` templating.
45
+ * - `text` — the same input, multiline; `rows` sets its height.
46
+ * - `select` — fixed option list (only `parseMode` today).
47
+ * - `boolean` — a Switch. Read it as `config[name] ?? default`, never as
48
+ * `!!config[name]`: see `default`.
49
+ * - `number` — numeric input clamped to `min`/`max` as it is typed.
50
+ * - `linesList` — **stored as an array of strings, edited as one per
51
+ * line.** Telegram's poll options. The cousin of Contacts' `csvList`,
52
+ * split on newlines instead of commas. A renderer that treats it as text
53
+ * turns the array into a string on the first save and `sendPoll` starts
54
+ * failing.
55
+ */
56
+ type: 'string' | 'text' | 'select' | 'boolean' | 'number' | 'linesList';
57
+ /** Required by the operation. Metadata — the form does not gate on it. */
58
+ required?: boolean;
59
+ /** Help text under the control. Absent where the form shows none. */
60
+ description?: string;
61
+ /** Hint shown inside the input. May contain newlines for `linesList`. */
62
+ placeholder?: string;
63
+ /**
64
+ * Value to show when the stored one is `undefined`.
65
+ *
66
+ * `includeDisapprove`, `isAnonymous` and `parseMode` all have one, and the
67
+ * first two default to **true**: the stored config only ever holds `false`
68
+ * when the user turned them off. `config[name] ?? default` reproduces that
69
+ * exactly; `!!config[name]` does not, and getting it wrong strips the
70
+ * Disapprove button off every approval flow that already exists.
71
+ */
72
+ default?: string | number | boolean;
73
+ /** `select` only — the fixed option list, in display order. */
74
+ options?: string[];
75
+ /** `number` only — the input clamps to these while typing. */
76
+ min?: number;
77
+ max?: number;
78
+ /** `text` only — height of the textarea. */
79
+ rows?: number;
80
+ /**
81
+ * Renders side by side with the next field in a two-column row. Only the
82
+ * Approve / Disapprove button labels use it — they are one decision split
83
+ * in two, and stacking them reads as two unrelated fields.
84
+ */
85
+ pairedWithNext?: boolean;
86
+ }
87
+ export interface TelegramOperationSpec {
88
+ /** UI label for the operation picker card. */
89
+ label: string;
90
+ /** Sub-line under the label in the picker. */
91
+ description: string;
92
+ /** Bot API method the operation maps to (core.telegram.org/bots/api). */
93
+ apiMethod: string;
94
+ /**
95
+ * The op accepts `reply_markup`, so the page offers the inline-keyboard
96
+ * builder for it. Used to live as a hardcoded array of five strings in the
97
+ * detail page. `sendAndWaitForResponse` is deliberately absent: it builds
98
+ * its own Approve / Disapprove keyboard and a second one would collide.
99
+ */
100
+ supportsInlineKeyboard?: boolean;
101
+ /** Parameter schema. Order matters for form rendering. */
102
+ params: TelegramParamSpec[];
103
+ }
104
+ export declare const TELEGRAM_OPERATION_SPECS: Record<TelegramOperation, TelegramOperationSpec>;