compile
Compile workflows by injecting external code and prompt files to prepare them for deployment in McFlow's n8n automation environment.
Instructions
Compile all workflows by injecting external code/prompt files
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| output | No | Save compiled workflows to dist folder (default: true) |
Implementation Reference
- src/tools/handler.ts:109-129 (handler)Handler function that executes the 'compile' tool by instantiating WorkflowCompiler and calling compileAll with the output flag.case 'compile': const outputToFiles = args?.output !== false; const compiler = new WorkflowCompiler(this.workflowsPath); try { const compiledWorkflows = await compiler.compileAll(outputToFiles); return { content: [{ type: 'text', text: `✅ Successfully compiled ${compiledWorkflows.size} workflows${outputToFiles ? ' to dist/' : ' (in memory)'}\n\n` + Array.from(compiledWorkflows.keys()).map(name => `• ${name}`).join('\n') }] }; } catch (error: any) { return { content: [{ type: 'text', text: `❌ Compilation failed: ${error.message}` }] }; }
- src/tools/registry.ts:206-217 (schema)Tool schema definition including name, description, and input schema for the 'compile' tool.name: 'compile', description: 'Compile all workflows by injecting external code/prompt files', inputSchema: { type: 'object', properties: { output: { type: 'boolean', description: 'Save compiled workflows to dist folder (default: true)', }, }, }, },
- src/tools/registry.ts:206-217 (registration)Registration of the 'compile' tool in the tool definitions array returned by getToolDefinitions().name: 'compile', description: 'Compile all workflows by injecting external code/prompt files', inputSchema: { type: 'object', properties: { output: { type: 'boolean', description: 'Save compiled workflows to dist folder (default: true)', }, }, }, },
- src/workflows/compiler.ts:378-404 (helper)The compileAll method in WorkflowCompiler class, which iterates over all workflow files, compiles them by injecting external code/prompt files, and optionally saves to dist/ directory.async compileAll(outputToFiles: boolean = false): Promise<Map<string, Workflow>> { const flowsDir = path.join(this.workflowsPath, 'flows'); const compiledWorkflows = new Map<string, Workflow>(); try { const files = await fs.readdir(flowsDir); const workflowFiles = files.filter(f => f.endsWith('.json')); for (const file of workflowFiles) { const workflowPath = path.join(flowsDir, file); const compiled = await this.compileWorkflow(workflowPath); compiledWorkflows.set(file, compiled); // Optionally save compiled version to dist/ if (outputToFiles) { await this.saveCompiledWorkflow(file, compiled); } } console.log(`\n✅ Compiled ${compiledWorkflows.size} workflows`); } catch (error) { console.error('Error compiling workflows:', error); throw error; } return compiledWorkflows; }
- src/workflows/compiler.ts:56-103 (helper)Core compileWorkflow method that processes each node in the workflow, injecting external code, prompts, SQL, JSON etc. from files in nodes/ directories.async compileWorkflow(workflowPath: string): Promise<Workflow> { // Read the workflow file const workflowContent = await fs.readFile(workflowPath, 'utf-8'); const workflow: Workflow = JSON.parse(workflowContent); // Generate a stable ID based on the workflow name if not present // This ensures the same workflow always gets the same ID if (!workflow.id) { // Create a stable ID from the workflow name (sanitized) const baseName = path.basename(workflowPath, '.json'); workflow.id = baseName.toLowerCase().replace(/[^a-z0-9-]/g, '-'); } // Ensure workflow has required fields for n8n if (workflow.active === undefined) { workflow.active = false; // Default to inactive } if (!workflow.settings) { workflow.settings = { executionOrder: 'v1' }; } if (!workflow.connections) { workflow.connections = {}; } // Add or update timestamp to force n8n to recognize the update workflow.updatedAt = new Date().toISOString(); if (!workflow.createdAt) { workflow.createdAt = workflow.updatedAt; } // Always process nodes to ensure external files are injected // This ensures any changes to external files are picked up console.log(` 🔧 Compiling workflow: ${path.basename(workflowPath)}`); let nodesProcessed = 0; for (const node of workflow.nodes) { const wasProcessed = await this.processNode(node); if (wasProcessed) nodesProcessed++; } if (nodesProcessed > 0) { console.log(` ✅ Processed ${nodesProcessed} nodes with external content`); } else { console.log(` ✓ No external content to inject`); } return workflow; }