/** * n8n Node Registry — PRODUCTION GRADE * Real node definitions: type, version, parameters schema, credentials, I/O structure * ZERO hallucinated nodes. ZERO placeholder types. ZERO unknown nodes. * Source: n8n official node definitions (github.com/n8n-io/n8n) */ export interface NodeRegistryEntry { type: string; displayName: string; typeVersion: number; group: string[]; description: string; isTrigger: boolean; credentialType?: string; credentialDisplayName?: string; inputs: string[]; outputs: string[]; outputNames?: string[]; requiredParameters: string[]; optionalParameters: string[]; defaultParameters: Record; executionBehavior: 'once' | 'perItem' | 'trigger' | 'webhook'; supportsRetry: boolean; layer: 'trigger' | 'transform' | 'ai' | 'integration' | 'control' | 'database' | 'utility'; tags: string[]; } export const N8N_NODE_REGISTRY: Record = { // ─── TRIGGER NODES ────────────────────────────────────────────────────────── 'n8n-nodes-base.webhook': { type: 'n8n-nodes-base.webhook', displayName: 'Webhook', typeVersion: 2, group: ['trigger'], description: 'Starts the workflow when a webhook is received', isTrigger: true, inputs: [], outputs: ['main'], requiredParameters: ['httpMethod', 'path'], optionalParameters: ['responseMode', 'responseData', 'responseCode', 'responseHeaders', 'rawBody', 'options'], defaultParameters: { httpMethod: 'POST', path: '={{$runIndex === 0 ? "auto-webhook-" + $workflow.id : ""}}', responseMode: 'onReceived', responseData: 'allEntries', }, executionBehavior: 'webhook', supportsRetry: false, layer: 'trigger', tags: ['trigger', 'http', 'webhook'], }, 'n8n-nodes-base.scheduleTrigger': { type: 'n8n-nodes-base.scheduleTrigger', displayName: 'Schedule Trigger', typeVersion: 1, group: ['trigger'], description: 'Triggers workflow on a schedule (cron or interval)', isTrigger: true, inputs: [], outputs: ['main'], requiredParameters: ['rule'], optionalParameters: [], defaultParameters: { rule: { interval: [{ field: 'hours', hoursInterval: 1 }], }, }, executionBehavior: 'trigger', supportsRetry: false, layer: 'trigger', tags: ['trigger', 'cron', 'schedule'], }, 'n8n-nodes-base.manualTrigger': { type: 'n8n-nodes-base.manualTrigger', displayName: 'Manual Trigger', typeVersion: 1, group: ['trigger'], description: 'Starts workflow execution manually via the UI', isTrigger: true, inputs: [], outputs: ['main'], requiredParameters: [], optionalParameters: [], defaultParameters: {}, executionBehavior: 'trigger', supportsRetry: false, layer: 'trigger', tags: ['trigger', 'manual'], }, 'n8n-nodes-base.telegramTrigger': { type: 'n8n-nodes-base.telegramTrigger', displayName: 'Telegram Trigger', typeVersion: 1, group: ['trigger'], description: 'Starts workflow when a Telegram message or event is received', isTrigger: true, credentialType: 'telegramApi', credentialDisplayName: 'Telegram API', inputs: [], outputs: ['main'], requiredParameters: ['updates'], optionalParameters: ['additionalFields'], defaultParameters: { updates: ['message'], }, executionBehavior: 'webhook', supportsRetry: false, layer: 'trigger', tags: ['trigger', 'telegram', 'messaging'], }, 'n8n-nodes-base.emailReadImap': { type: 'n8n-nodes-base.emailReadImap', displayName: 'Email Trigger (IMAP)', typeVersion: 2, group: ['trigger'], description: 'Triggers workflow when a new email is received via IMAP', isTrigger: true, credentialType: 'imap', credentialDisplayName: 'IMAP', inputs: [], outputs: ['main'], requiredParameters: ['mailbox', 'action'], optionalParameters: ['downloadAttachments', 'format', 'options'], defaultParameters: { mailbox: 'INBOX', action: 'read', }, executionBehavior: 'trigger', supportsRetry: false, layer: 'trigger', tags: ['trigger', 'email', 'imap'], }, 'n8n-nodes-base.githubTrigger': { type: 'n8n-nodes-base.githubTrigger', displayName: 'GitHub Trigger', typeVersion: 1, group: ['trigger'], description: 'Triggers on GitHub events (push, PR, issue, etc.)', isTrigger: true, credentialType: 'githubApi', credentialDisplayName: 'GitHub API', inputs: [], outputs: ['main'], requiredParameters: ['owner', 'repository', 'events'], optionalParameters: [], defaultParameters: { events: ['push'], }, executionBehavior: 'webhook', supportsRetry: false, layer: 'trigger', tags: ['trigger', 'github', 'devops'], }, 'n8n-nodes-base.slackTrigger': { type: 'n8n-nodes-base.slackTrigger', displayName: 'Slack Trigger', typeVersion: 1, group: ['trigger'], description: 'Triggers on Slack events (messages, reactions, etc.)', isTrigger: true, credentialType: 'slackOAuth2Api', credentialDisplayName: 'Slack OAuth2 API', inputs: [], outputs: ['main'], requiredParameters: ['trigger'], optionalParameters: ['channelId', 'watchedEvent'], defaultParameters: { trigger: 'any_message', }, executionBehavior: 'webhook', supportsRetry: false, layer: 'trigger', tags: ['trigger', 'slack', 'messaging'], }, 'n8n-nodes-base.notionTrigger': { type: 'n8n-nodes-base.notionTrigger', displayName: 'Notion Trigger', typeVersion: 1, group: ['trigger'], description: 'Triggers when a Notion database page is created or updated', isTrigger: true, credentialType: 'notionApi', credentialDisplayName: 'Notion API', inputs: [], outputs: ['main'], requiredParameters: ['databaseId', 'event'], optionalParameters: ['simple'], defaultParameters: { event: 'page_added', }, executionBehavior: 'trigger', supportsRetry: false, layer: 'trigger', tags: ['trigger', 'notion', 'productivity'], }, // ─── AI / LLM NODES ───────────────────────────────────────────────────────── '@n8n/n8n-nodes-langchain.agent': { type: '@n8n/n8n-nodes-langchain.agent', displayName: 'AI Agent', typeVersion: 1, group: ['transform'], description: 'AI Agent powered by LangChain with tools and memory', isTrigger: false, inputs: ['main', 'ai_tool', 'ai_memory', 'ai_languageModel'], outputs: ['main'], requiredParameters: ['text', 'options'], optionalParameters: ['systemMessage', 'promptType'], defaultParameters: { text: '={{ $json?.message ?? $json?.text ?? $json?.body?.message ?? "" }}', options: { systemMessage: 'You are a helpful AI assistant. Be concise and accurate.', }, }, executionBehavior: 'perItem', supportsRetry: true, layer: 'ai', tags: ['ai', 'agent', 'langchain', 'llm'], }, '@n8n/n8n-nodes-langchain.openAi': { type: '@n8n/n8n-nodes-langchain.openAi', displayName: 'OpenAI Chat Model', typeVersion: 1, group: ['transform'], description: 'OpenAI Chat Model for use with AI Agent or Chain nodes', isTrigger: false, credentialType: 'openAiApi', credentialDisplayName: 'OpenAI API', inputs: ['ai_languageModel'], outputs: ['ai_languageModel'], requiredParameters: ['model'], optionalParameters: ['options'], defaultParameters: { model: { __rl: true, value: 'gpt-4o', mode: 'list', cachedResultName: 'GPT-4o' }, options: { maxTokens: 2048, temperature: 0.7, }, }, executionBehavior: 'once', supportsRetry: true, layer: 'ai', tags: ['ai', 'openai', 'llm', 'langchain'], }, '@n8n/n8n-nodes-langchain.lmChatAnthropic': { type: '@n8n/n8n-nodes-langchain.lmChatAnthropic', displayName: 'Anthropic Chat Model', typeVersion: 1, group: ['transform'], description: 'Anthropic Claude model for use with AI Agent or Chain nodes', isTrigger: false, credentialType: 'anthropicApi', credentialDisplayName: 'Anthropic API', inputs: ['ai_languageModel'], outputs: ['ai_languageModel'], requiredParameters: ['model'], optionalParameters: ['options'], defaultParameters: { model: 'claude-3-5-sonnet-20241022', options: { maxTokens: 2048, temperature: 0.7, }, }, executionBehavior: 'once', supportsRetry: true, layer: 'ai', tags: ['ai', 'anthropic', 'claude', 'llm', 'langchain'], }, '@n8n/n8n-nodes-langchain.memoryBufferWindow': { type: '@n8n/n8n-nodes-langchain.memoryBufferWindow', displayName: 'Window Buffer Memory', typeVersion: 1, group: ['transform'], description: 'Keeps last N messages in memory for AI Agent context', isTrigger: false, inputs: ['ai_memory'], outputs: ['ai_memory'], requiredParameters: [], optionalParameters: ['sessionKey', 'sessionIdType', 'contextWindowLength'], defaultParameters: { contextWindowLength: 10, }, executionBehavior: 'once', supportsRetry: false, layer: 'ai', tags: ['ai', 'memory', 'langchain'], }, '@n8n/n8n-nodes-langchain.toolCode': { type: '@n8n/n8n-nodes-langchain.toolCode', displayName: 'Code Tool', typeVersion: 1, group: ['transform'], description: 'Custom JavaScript tool for AI Agent', isTrigger: false, inputs: ['ai_tool'], outputs: ['ai_tool'], requiredParameters: ['name', 'description', 'jsCode'], optionalParameters: [], defaultParameters: { name: 'custom_tool', description: 'Describe what this tool does so the AI agent knows when to use it', jsCode: '// Tool logic here\nreturn { result: "success" };', }, executionBehavior: 'once', supportsRetry: false, layer: 'ai', tags: ['ai', 'tool', 'langchain', 'code'], }, 'n8n-nodes-base.openAi': { type: 'n8n-nodes-base.openAi', displayName: 'OpenAI', typeVersion: 1, group: ['transform'], description: 'Use the OpenAI API (Chat, Image, Audio, etc.)', isTrigger: false, credentialType: 'openAiApi', credentialDisplayName: 'OpenAI API', inputs: ['main'], outputs: ['main'], requiredParameters: ['resource', 'operation'], optionalParameters: ['model', 'messages', 'options'], defaultParameters: { resource: 'chat', operation: 'complete', model: { __rl: true, value: 'gpt-4o', mode: 'list', cachedResultName: 'GPT-4o' }, }, executionBehavior: 'perItem', supportsRetry: true, layer: 'ai', tags: ['ai', 'openai', 'llm'], }, // ─── TRANSFORM / LOGIC NODES ───────────────────────────────────────────────── 'n8n-nodes-base.code': { type: 'n8n-nodes-base.code', displayName: 'Code', typeVersion: 2, group: ['transform'], description: 'Run custom JavaScript or Python code on items', isTrigger: false, inputs: ['main'], outputs: ['main'], requiredParameters: ['jsCode'], optionalParameters: ['mode', 'language', 'pythonCode'], defaultParameters: { mode: 'runOnceForAllItems', language: 'javaScript', jsCode: `// Available: $input, $json, $items(), $env const items = $input.all(); return items.map(item => { const data = item.json; return { json: { ...data, processed: true, processedAt: new Date().toISOString(), } }; });`, }, executionBehavior: 'once', supportsRetry: false, layer: 'transform', tags: ['code', 'javascript', 'transform'], }, 'n8n-nodes-base.set': { type: 'n8n-nodes-base.set', displayName: 'Edit Fields (Set)', typeVersion: 3, group: ['transform'], description: 'Set, add, or remove fields on items', isTrigger: false, inputs: ['main'], outputs: ['main'], requiredParameters: ['fields'], optionalParameters: ['options', 'include'], defaultParameters: { mode: 'manual', fields: { values: [ { name: 'outputField', value: '={{ $json?.inputField ?? "" }}', }, ], }, }, executionBehavior: 'perItem', supportsRetry: false, layer: 'transform', tags: ['transform', 'set', 'fields'], }, 'n8n-nodes-base.if': { type: 'n8n-nodes-base.if', displayName: 'IF', typeVersion: 2, group: ['transform'], description: 'Split items into two branches based on conditions', isTrigger: false, inputs: ['main'], outputs: ['main', 'main'], outputNames: ['true', 'false'], requiredParameters: ['conditions'], optionalParameters: ['combinator'], defaultParameters: { conditions: { options: { caseSensitive: true, leftValue: '', typeValidation: 'strict', }, conditions: [ { id: 'condition-1', leftValue: '={{ $json?.status ?? "" }}', rightValue: 'success', operator: { type: 'string', operation: 'equals', }, }, ], combinator: 'and', }, }, executionBehavior: 'perItem', supportsRetry: false, layer: 'control', tags: ['control', 'condition', 'branch'], }, 'n8n-nodes-base.switch': { type: 'n8n-nodes-base.switch', displayName: 'Switch', typeVersion: 3, group: ['transform'], description: 'Route items to different outputs based on rules', isTrigger: false, inputs: ['main'], outputs: ['main'], requiredParameters: ['rules'], optionalParameters: ['mode', 'fallbackOutput'], defaultParameters: { mode: 'rules', rules: { values: [ { conditions: { conditions: [ { leftValue: '={{ $json?.type ?? "" }}', rightValue: 'typeA', operator: { type: 'string', operation: 'equals' }, }, ], combinator: 'and', }, renameOutput: false, }, ], }, fallbackOutput: 'none', }, executionBehavior: 'perItem', supportsRetry: false, layer: 'control', tags: ['control', 'switch', 'routing'], }, 'n8n-nodes-base.merge': { type: 'n8n-nodes-base.merge', displayName: 'Merge', typeVersion: 3, group: ['transform'], description: 'Merge data from multiple branches', isTrigger: false, inputs: ['main', 'main'], outputs: ['main'], requiredParameters: ['mode'], optionalParameters: ['joinMode', 'clashHandling', 'options'], defaultParameters: { mode: 'append', }, executionBehavior: 'once', supportsRetry: false, layer: 'control', tags: ['control', 'merge', 'combine'], }, 'n8n-nodes-base.splitInBatches': { type: 'n8n-nodes-base.splitInBatches', displayName: 'Split In Batches', typeVersion: 3, group: ['transform'], description: 'Split large arrays into smaller batches for processing', isTrigger: false, inputs: ['main'], outputs: ['main', 'main'], outputNames: ['loop', 'done'], requiredParameters: ['batchSize'], optionalParameters: ['options'], defaultParameters: { batchSize: 10, options: {}, }, executionBehavior: 'once', supportsRetry: false, layer: 'control', tags: ['control', 'batch', 'loop', 'array'], }, 'n8n-nodes-base.itemLists': { type: 'n8n-nodes-base.itemLists', displayName: 'Item Lists', typeVersion: 3, group: ['transform'], description: 'Manipulate arrays: split, aggregate, deduplicate, sort', isTrigger: false, inputs: ['main'], outputs: ['main'], requiredParameters: ['operation'], optionalParameters: ['fieldToSplitOut', 'fieldToAggregate', 'sortFieldsUi', 'options'], defaultParameters: { operation: 'splitOutItems', fieldToSplitOut: 'items', include: 'noOtherFields', }, executionBehavior: 'once', supportsRetry: false, layer: 'transform', tags: ['transform', 'array', 'list'], }, 'n8n-nodes-base.filter': { type: 'n8n-nodes-base.filter', displayName: 'Filter', typeVersion: 1, group: ['transform'], description: 'Filter items based on conditions, keeping only matching items', isTrigger: false, inputs: ['main'], outputs: ['main'], requiredParameters: ['conditions'], optionalParameters: [], defaultParameters: { conditions: { options: { caseSensitive: true, typeValidation: 'strict' }, conditions: [ { id: 'filter-1', leftValue: '={{ $json?.active ?? false }}', rightValue: true, operator: { type: 'boolean', operation: 'equals' }, }, ], combinator: 'and', }, }, executionBehavior: 'perItem', supportsRetry: false, layer: 'transform', tags: ['transform', 'filter', 'condition'], }, // ─── HTTP / EXTERNAL API ───────────────────────────────────────────────────── 'n8n-nodes-base.httpRequest': { type: 'n8n-nodes-base.httpRequest', displayName: 'HTTP Request', typeVersion: 4, group: ['output'], description: 'Make HTTP requests to any API endpoint', isTrigger: false, inputs: ['main'], outputs: ['main'], requiredParameters: ['method', 'url'], optionalParameters: ['authentication', 'sendHeaders', 'sendQuery', 'sendBody', 'options'], defaultParameters: { method: 'GET', url: '', options: { timeout: 10000, redirect: { redirect: { followRedirects: true, maxRedirects: 3 }, }, }, }, executionBehavior: 'perItem', supportsRetry: true, layer: 'integration', tags: ['http', 'api', 'rest', 'integration'], }, // ─── MESSAGING ─────────────────────────────────────────────────────────────── 'n8n-nodes-base.telegram': { type: 'n8n-nodes-base.telegram', displayName: 'Telegram', typeVersion: 1, group: ['output'], description: 'Send messages, photos, documents via Telegram Bot API', isTrigger: false, credentialType: 'telegramApi', credentialDisplayName: 'Telegram API', inputs: ['main'], outputs: ['main'], requiredParameters: ['operation', 'chatId'], optionalParameters: ['text', 'photo', 'document', 'additionalFields'], defaultParameters: { operation: 'sendMessage', chatId: '={{ $json?.message?.chat?.id ?? $json?.chatId ?? "" }}', text: '={{ $json?.responseText ?? $json?.output ?? "" }}', additionalFields: { parse_mode: 'HTML', }, }, executionBehavior: 'perItem', supportsRetry: true, layer: 'integration', tags: ['telegram', 'messaging', 'bot'], }, 'n8n-nodes-base.slack': { type: 'n8n-nodes-base.slack', displayName: 'Slack', typeVersion: 2, group: ['output'], description: 'Send messages and interact with Slack', isTrigger: false, credentialType: 'slackApi', credentialDisplayName: 'Slack API', inputs: ['main'], outputs: ['main'], requiredParameters: ['resource', 'operation', 'channel'], optionalParameters: ['text', 'blocksUi', 'attachments', 'otherOptions'], defaultParameters: { resource: 'message', operation: 'post', channel: '', text: '={{ $json?.message ?? $json?.text ?? "" }}', }, executionBehavior: 'perItem', supportsRetry: true, layer: 'integration', tags: ['slack', 'messaging', 'notification'], }, 'n8n-nodes-base.gmail': { type: 'n8n-nodes-base.gmail', displayName: 'Gmail', typeVersion: 2, group: ['output'], description: 'Send and manage emails via Gmail', isTrigger: false, credentialType: 'googleOAuth2Api', credentialDisplayName: 'Google OAuth2 API', inputs: ['main'], outputs: ['main'], requiredParameters: ['operation', 'sendTo', 'subject'], optionalParameters: ['message', 'attachmentsUi', 'options'], defaultParameters: { operation: 'send', sendTo: '', subject: '', message: '', options: {}, }, executionBehavior: 'perItem', supportsRetry: true, layer: 'integration', tags: ['email', 'gmail', 'google'], }, // ─── PRODUCTIVITY / STORAGE ────────────────────────────────────────────────── 'n8n-nodes-base.googleSheets': { type: 'n8n-nodes-base.googleSheets', displayName: 'Google Sheets', typeVersion: 4, group: ['output'], description: 'Read, write, and manage Google Sheets data', isTrigger: false, credentialType: 'googleSheetsOAuth2Api', credentialDisplayName: 'Google Sheets OAuth2 API', inputs: ['main'], outputs: ['main'], requiredParameters: ['operation', 'documentId', 'sheetName'], optionalParameters: ['columns', 'filtersUI', 'options'], defaultParameters: { operation: 'appendOrUpdate', documentId: { __rl: true, value: '', mode: 'id' }, sheetName: { __rl: true, value: 'Sheet1', mode: 'name' }, }, executionBehavior: 'perItem', supportsRetry: true, layer: 'integration', tags: ['google', 'sheets', 'spreadsheet', 'storage'], }, 'n8n-nodes-base.airtable': { type: 'n8n-nodes-base.airtable', displayName: 'Airtable', typeVersion: 2, group: ['output'], description: 'Read, write, update, and delete Airtable records', isTrigger: false, credentialType: 'airtableTokenApi', credentialDisplayName: 'Airtable Token API', inputs: ['main'], outputs: ['main'], requiredParameters: ['operation', 'base', 'table'], optionalParameters: ['fields', 'filterByFormula', 'sort', 'options'], defaultParameters: { operation: 'create', base: { __rl: true, value: '', mode: 'id' }, table: { __rl: true, value: '', mode: 'id' }, }, executionBehavior: 'perItem', supportsRetry: true, layer: 'integration', tags: ['airtable', 'database', 'storage'], }, 'n8n-nodes-base.notion': { type: 'n8n-nodes-base.notion', displayName: 'Notion', typeVersion: 2, group: ['output'], description: 'Create, read, and update Notion pages and databases', isTrigger: false, credentialType: 'notionApi', credentialDisplayName: 'Notion API', inputs: ['main'], outputs: ['main'], requiredParameters: ['resource', 'operation'], optionalParameters: ['pageId', 'databaseId', 'title', 'properties', 'blockUi'], defaultParameters: { resource: 'page', operation: 'create', }, executionBehavior: 'perItem', supportsRetry: true, layer: 'integration', tags: ['notion', 'productivity', 'database'], }, // ─── DATABASE ──────────────────────────────────────────────────────────────── 'n8n-nodes-base.postgres': { type: 'n8n-nodes-base.postgres', displayName: 'Postgres', typeVersion: 2, group: ['output'], description: 'Execute SQL queries and interact with PostgreSQL databases', isTrigger: false, credentialType: 'postgres', credentialDisplayName: 'Postgres', inputs: ['main'], outputs: ['main'], requiredParameters: ['operation'], optionalParameters: ['table', 'query', 'columns', 'additionalFields', 'options'], defaultParameters: { operation: 'insert', table: { __rl: true, value: '', mode: 'name' }, }, executionBehavior: 'perItem', supportsRetry: true, layer: 'database', tags: ['database', 'sql', 'postgres'], }, 'n8n-nodes-base.mysql': { type: 'n8n-nodes-base.mysql', displayName: 'MySQL', typeVersion: 2, group: ['output'], description: 'Execute queries and interact with MySQL databases', isTrigger: false, credentialType: 'mySql', credentialDisplayName: 'MySQL', inputs: ['main'], outputs: ['main'], requiredParameters: ['operation'], optionalParameters: ['table', 'query', 'columns', 'options'], defaultParameters: { operation: 'insert', table: '', }, executionBehavior: 'perItem', supportsRetry: true, layer: 'database', tags: ['database', 'sql', 'mysql'], }, 'n8n-nodes-base.redis': { type: 'n8n-nodes-base.redis', displayName: 'Redis', typeVersion: 1, group: ['output'], description: 'Get, set, and manage Redis key-value data', isTrigger: false, credentialType: 'redis', credentialDisplayName: 'Redis', inputs: ['main'], outputs: ['main'], requiredParameters: ['operation'], optionalParameters: ['key', 'value', 'expire', 'keyType'], defaultParameters: { operation: 'get', key: '', }, executionBehavior: 'perItem', supportsRetry: true, layer: 'database', tags: ['database', 'cache', 'redis'], }, // ─── CRM / BUSINESS ────────────────────────────────────────────────────────── 'n8n-nodes-base.hubspot': { type: 'n8n-nodes-base.hubspot', displayName: 'HubSpot', typeVersion: 2, group: ['output'], description: 'Manage contacts, deals, companies, and tickets in HubSpot CRM', isTrigger: false, credentialType: 'hubspotApi', credentialDisplayName: 'HubSpot API', inputs: ['main'], outputs: ['main'], requiredParameters: ['resource', 'operation'], optionalParameters: ['contactId', 'dealId', 'additionalFields'], defaultParameters: { resource: 'contact', operation: 'create', }, executionBehavior: 'perItem', supportsRetry: true, layer: 'integration', tags: ['crm', 'hubspot', 'sales'], }, 'n8n-nodes-base.stripe': { type: 'n8n-nodes-base.stripe', displayName: 'Stripe', typeVersion: 1, group: ['output'], description: 'Manage customers, charges, subscriptions via Stripe', isTrigger: false, credentialType: 'stripeApi', credentialDisplayName: 'Stripe API', inputs: ['main'], outputs: ['main'], requiredParameters: ['resource', 'operation'], optionalParameters: ['customerId', 'amount', 'currency', 'additionalFields'], defaultParameters: { resource: 'customer', operation: 'get', }, executionBehavior: 'perItem', supportsRetry: true, layer: 'integration', tags: ['payment', 'stripe', 'ecommerce'], }, 'n8n-nodes-base.github': { type: 'n8n-nodes-base.github', displayName: 'GitHub', typeVersion: 1, group: ['output'], description: 'Interact with GitHub repositories, issues, PRs', isTrigger: false, credentialType: 'githubApi', credentialDisplayName: 'GitHub API', inputs: ['main'], outputs: ['main'], requiredParameters: ['resource', 'operation', 'owner', 'repository'], optionalParameters: ['title', 'body', 'labels', 'additionalParameters'], defaultParameters: { resource: 'issue', operation: 'create', owner: '', repository: '', }, executionBehavior: 'perItem', supportsRetry: true, layer: 'integration', tags: ['github', 'devops', 'git'], }, // ─── UTILITY NODES ─────────────────────────────────────────────────────────── 'n8n-nodes-base.noOp': { type: 'n8n-nodes-base.noOp', displayName: 'No Operation, do nothing', typeVersion: 1, group: ['utility'], description: 'Passes items through without modification (useful as placeholders)', isTrigger: false, inputs: ['main'], outputs: ['main'], requiredParameters: [], optionalParameters: [], defaultParameters: {}, executionBehavior: 'perItem', supportsRetry: false, layer: 'utility', tags: ['utility', 'passthrough'], }, 'n8n-nodes-base.stopAndError': { type: 'n8n-nodes-base.stopAndError', displayName: 'Stop and Error', typeVersion: 1, group: ['utility'], description: 'Stop workflow execution and throw a custom error', isTrigger: false, inputs: ['main'], outputs: [], requiredParameters: ['errorType'], optionalParameters: ['errorMessage', 'errorObject'], defaultParameters: { errorType: 'errorMessage', errorMessage: '={{ "Workflow stopped: " + ($json?.reason ?? "unknown error") }}', }, executionBehavior: 'perItem', supportsRetry: false, layer: 'utility', tags: ['utility', 'error', 'stop'], }, 'n8n-nodes-base.wait': { type: 'n8n-nodes-base.wait', displayName: 'Wait', typeVersion: 1, group: ['utility'], description: 'Pause workflow execution for a specified time', isTrigger: false, inputs: ['main'], outputs: ['main'], requiredParameters: ['amount', 'unit'], optionalParameters: [], defaultParameters: { amount: 1, unit: 'seconds', }, executionBehavior: 'once', supportsRetry: false, layer: 'utility', tags: ['utility', 'wait', 'delay'], }, 'n8n-nodes-base.respondToWebhook': { type: 'n8n-nodes-base.respondToWebhook', displayName: 'Respond to Webhook', typeVersion: 1, group: ['utility'], description: 'Send a custom response back to the webhook caller', isTrigger: false, inputs: ['main'], outputs: ['main'], requiredParameters: ['respondWith'], optionalParameters: ['responseBody', 'responseCode', 'responseHeaders', 'options'], defaultParameters: { respondWith: 'json', responseBody: '={{ JSON.stringify({ success: true, data: $json }) }}', responseCode: 200, }, executionBehavior: 'once', supportsRetry: false, layer: 'utility', tags: ['webhook', 'response', 'utility'], }, 'n8n-nodes-base.stickyNote': { type: 'n8n-nodes-base.stickyNote', displayName: 'Sticky Note', typeVersion: 1, group: ['annotation'], description: 'Add documentation notes to the workflow canvas', isTrigger: false, inputs: [], outputs: [], requiredParameters: ['content'], optionalParameters: ['height', 'width', 'color'], defaultParameters: { content: '## Workflow Documentation\n\nDescribe this section here.', height: 200, width: 300, color: 4, }, executionBehavior: 'once', supportsRetry: false, layer: 'utility', tags: ['documentation', 'annotation'], }, }; // ─── Registry Lookup Helpers ────────────────────────────────────────────────── /** * Get a node definition. Returns undefined if node type is not in registry. * NEVER return a fallback for unknown types — callers must handle undefined. */ export function getNodeDef(nodeType: string): NodeRegistryEntry | undefined { return N8N_NODE_REGISTRY[nodeType]; } /** * Validate that a node type exists in the registry */ export function isValidNodeType(nodeType: string): boolean { return nodeType in N8N_NODE_REGISTRY; } /** * Get all trigger node types */ export function getTriggerNodeTypes(): string[] { return Object.entries(N8N_NODE_REGISTRY) .filter(([, def]) => def.isTrigger) .map(([type]) => type); } /** * Get all node types for a given tag */ export function getNodeTypesByTag(tag: string): string[] { return Object.entries(N8N_NODE_REGISTRY) .filter(([, def]) => def.tags.includes(tag)) .map(([type]) => type); } /** * Get credential type required for a node type */ export function getRequiredCredential(nodeType: string): string | undefined { return N8N_NODE_REGISTRY[nodeType]?.credentialType; } /** * Get all registered node types as a list (for LLM context injection) */ export function getRegistryNodeList(): string { return Object.entries(N8N_NODE_REGISTRY) .map(([type, def]) => `- ${type} (v${def.typeVersion}): ${def.description}`) .join('\n'); } /** * Get all trigger node types as formatted string for prompts */ export function getTriggerNodeList(): string { return Object.entries(N8N_NODE_REGISTRY) .filter(([, def]) => def.isTrigger) .map(([type, def]) => `- ${type}: ${def.description}`) .join('\n'); }