create_config
Generate a config.toml file for Devpipe by auto-detecting project technologies and creating tasks automatically.
Instructions
Create a complete config.toml file from scratch with auto-detected tasks based on project technologies.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectPath | No | Path to project directory (defaults to current directory) | |
| includeDefaults | No | Include [defaults] section with recommended settings (default: true) | |
| autoDetect | No | Auto-detect technologies and generate tasks (default: true) |
Implementation Reference
- src/utils.ts:544-622 (handler)Core handler function that generates a complete devpipe config.toml from scratch, optionally including defaults and auto-detecting project technologies to suggest tasks using analyzeProject and generateTaskConfig.export async function createConfig(projectPath: string = process.cwd(), options?: { includeDefaults?: boolean; autoDetect?: boolean; }): Promise<string> { const includeDefaults = options?.includeDefaults !== false; const autoDetect = options?.autoDetect !== false; let config = ''; // Add defaults section if (includeDefaults) { config += `# Devpipe Configuration # https://github.com/drewkhoury/devpipe [defaults] outputRoot = ".devpipe" fastThreshold = 300 # Tasks over 300s are skipped with --fast uiMode = "basic" # Options: basic, full animationRefreshMs = 500 animatedGroupBy = "phase" # Options: phase, type [defaults.git] mode = "staged_unstaged" # Options: staged, staged_unstaged, ref # ref = "HEAD" # Uncomment to compare against a specific ref [task_defaults] enabled = true workdir = "." # fixType = "helper" # Options: auto, helper, none `; } // Auto-detect and add tasks if (autoDetect) { const analysis = await analyzeProject(projectPath); if (analysis.detectedTechnologies.length > 0) { config += `# Detected technologies: ${analysis.detectedTechnologies.join(', ')}\n\n`; // Group tasks by phase const phases = new Map<string, Array<{ technology: string; taskType: string; reason: string }>>(); for (const task of analysis.suggestedTasks) { let phase = 'validate'; if (task.taskType.includes('build')) phase = 'build'; else if (task.taskType.includes('test')) phase = 'test'; if (!phases.has(phase)) phases.set(phase, []); phases.get(phase)!.push(task); } // Add phase headers and tasks for (const [phase, tasks] of phases) { const phaseName = phase.charAt(0).toUpperCase() + phase.slice(1); config += `# ${phaseName} Phase\n`; config += `[tasks.phase-${phase}]\n`; config += `name = "${phaseName}"\n`; config += `desc = "Tasks for ${phase} stage"\n\n`; for (const task of tasks) { const taskId = `${task.technology.toLowerCase().replace(/\./g, '-')}-${task.taskType}`; const taskConfig = generateTaskConfig(task.technology, task.taskType, taskId); config += taskConfig + '\n'; } } } else { // No technologies detected, add example tasks config += `# Example tasks - customize for your project\n\n`; config += `[tasks.example-check]\n`; config += `name = "Example Check"\n`; config += `desc = "Replace with your actual check command"\n`; config += `type = "check"\n`; config += `command = "echo 'Add your check command here'"\n\n`; } } return config; }
- src/index.ts:294-314 (registration)Tool registration in the listTools handler, defining the tool name, description, and input schema.name: 'create_config', description: 'Create a complete config.toml file from scratch with auto-detected tasks based on project technologies.', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to project directory (defaults to current directory)', }, includeDefaults: { type: 'boolean', description: 'Include [defaults] section with recommended settings (default: true)', }, autoDetect: { type: 'boolean', description: 'Auto-detect technologies and generate tasks (default: true)', }, }, }, }, ],
- src/index.ts:620-638 (handler)MCP server request handler for callToolRequest that invokes the createConfig utility with parsed arguments and returns the generated config as text content.case 'create_config': { const projectPath = args?.projectPath || process.cwd(); const includeDefaults = args?.includeDefaults !== false; const autoDetect = args?.autoDetect !== false; const configContent = await createConfig(projectPath, { includeDefaults, autoDetect, }); return { content: [ { type: 'text', text: configContent, }, ], }; }
- src/utils.ts:286-375 (helper)Helper function used by createConfig to analyze the project directory and detect technologies/suggest tasks.export async function analyzeProject(projectPath: string = process.cwd()): Promise<{ detectedTechnologies: string[]; suggestedTasks: Array<{ technology: string; taskType: string; reason: string }>; existingFiles: { [key: string]: boolean }; }> { const detectedTechnologies: string[] = []; const suggestedTasks: Array<{ technology: string; taskType: string; reason: string }> = []; const existingFiles: { [key: string]: boolean } = {}; try { const files = await readdir(projectPath); // Check for various technology indicators for (const file of files) { existingFiles[file] = true; } // Go detection if (existingFiles['go.mod'] || existingFiles['go.sum']) { detectedTechnologies.push('Go'); suggestedTasks.push( { technology: 'Go', taskType: 'check-format', reason: 'go fmt for formatting' }, { technology: 'Go', taskType: 'check-lint', reason: 'golangci-lint for linting' }, { technology: 'Go', taskType: 'check-static', reason: 'go vet for static analysis' }, { technology: 'Go', taskType: 'test-unit', reason: 'go test for unit tests' }, { technology: 'Go', taskType: 'build', reason: 'go build for compilation' } ); } // Python detection if (existingFiles['requirements.txt'] || existingFiles['pyproject.toml'] || existingFiles['setup.py']) { detectedTechnologies.push('Python'); suggestedTasks.push( { technology: 'Python', taskType: 'check-format', reason: 'black or ruff for formatting' }, { technology: 'Python', taskType: 'check-lint', reason: 'pylint or ruff for linting' }, { technology: 'Python', taskType: 'check-types', reason: 'mypy for type checking' }, { technology: 'Python', taskType: 'test-unit', reason: 'pytest for unit tests' } ); } // Node.js/TypeScript detection if (existingFiles['package.json']) { detectedTechnologies.push('Node.js'); suggestedTasks.push( { technology: 'Node.js', taskType: 'check-lint', reason: 'eslint for linting' }, { technology: 'Node.js', taskType: 'test-unit', reason: 'npm test or jest' }, { technology: 'Node.js', taskType: 'build', reason: 'npm run build' } ); } if (existingFiles['tsconfig.json']) { detectedTechnologies.push('TypeScript'); suggestedTasks.push( { technology: 'TypeScript', taskType: 'check-types', reason: 'tsc for type checking' } ); } // Rust detection if (existingFiles['Cargo.toml']) { detectedTechnologies.push('Rust'); suggestedTasks.push( { technology: 'Rust', taskType: 'check-format', reason: 'cargo fmt for formatting' }, { technology: 'Rust', taskType: 'check-lint', reason: 'cargo clippy for linting' }, { technology: 'Rust', taskType: 'test-unit', reason: 'cargo test for tests' }, { technology: 'Rust', taskType: 'build', reason: 'cargo build' } ); } // Docker detection if (existingFiles['Dockerfile'] || existingFiles['docker-compose.yml']) { detectedTechnologies.push('Docker'); suggestedTasks.push( { technology: 'Docker', taskType: 'check-lint', reason: 'hadolint for Dockerfile linting' } ); } // Makefile detection if (existingFiles['Makefile']) { detectedTechnologies.push('Make'); } return { detectedTechnologies, suggestedTasks, existingFiles }; } catch (error) { throw new Error(`Failed to analyze project: ${error instanceof Error ? error.message : String(error)}`); } }
- src/utils.ts:397-539 (helper)Helper function used by createConfig to generate individual task TOML configurations from templates.export function generateTaskConfig(technology: string, taskType: string, taskId?: string): string { const id = taskId || `${technology.toLowerCase()}-${taskType}`; // Special handling for phase headers if (technology.toLowerCase() === 'phase') { return generatePhaseHeader(taskType, taskId); } const templates: { [key: string]: { [key: string]: any } } = { 'Go': { 'check-format': { name: 'Go Format', desc: 'Verifies that Go code is properly formatted', type: 'check', command: 'gofmt -l .', fixType: 'helper', fixCommand: 'gofmt -w .' }, 'check-lint': { name: 'Golang CI Lint', desc: 'Runs comprehensive linting on Go code', type: 'check', command: 'golangci-lint run', fixType: 'auto', fixCommand: 'golangci-lint run --fix' }, 'check-static': { name: 'Go Vet', desc: 'Examines Go code for suspicious constructs', type: 'check', command: 'go vet ./...' }, 'test-unit': { name: 'Unit Tests', desc: 'Run all unit tests', type: 'test', command: 'go test -v ./...', metricsFormat: 'junit', metricsPath: 'test-results.xml' }, 'build': { name: 'Build Binary', desc: 'Compile Go application', type: 'build', command: 'go build -o bin/app .' } }, 'Python': { 'check-format': { name: 'Python Format Check', desc: 'Check Python code formatting with black', type: 'check', command: 'black --check .', fixType: 'auto', fixCommand: 'black .' }, 'check-lint': { name: 'Python Lint', desc: 'Lint Python code with ruff', type: 'check', command: 'ruff check .', fixType: 'auto', fixCommand: 'ruff check --fix .' }, 'check-types': { name: 'Type Check', desc: 'Check types with mypy', type: 'check', command: 'mypy .' }, 'test-unit': { name: 'Unit Tests', desc: 'Run pytest unit tests', type: 'test', command: 'pytest', metricsFormat: 'junit', metricsPath: 'test-results.xml' } }, 'Node.js': { 'check-lint': { name: 'ESLint', desc: 'Lint JavaScript/TypeScript with ESLint', type: 'check', command: 'npm run lint', fixType: 'auto', fixCommand: 'npm run lint -- --fix' }, 'test-unit': { name: 'Unit Tests', desc: 'Run unit tests', type: 'test', command: 'npm test' }, 'build': { name: 'Build', desc: 'Build the project', type: 'build', command: 'npm run build' } }, 'TypeScript': { 'check-types': { name: 'Type Check', desc: 'Check TypeScript types', type: 'check', command: 'tsc --noEmit' } } }; const techTemplates = templates[technology]; if (!techTemplates) { return `# No template available for ${technology}\n# Please create a custom task`; } const template = techTemplates[taskType]; if (!template) { return `# No template available for ${technology} ${taskType}\n# Available types: ${Object.keys(techTemplates).join(', ')}`; } // Generate TOML let toml = `[tasks.${id}]\n`; toml += `name = "${template.name}"\n`; toml += `desc = "${template.desc}"\n`; toml += `type = "${template.type}"\n`; toml += `command = "${template.command}"\n`; if (template.fixType) { toml += `fixType = "${template.fixType}"\n`; } if (template.fixCommand) { toml += `fixCommand = "${template.fixCommand}"\n`; } if (template.metricsFormat) { toml += `metricsFormat = "${template.metricsFormat}"\n`; } if (template.metricsPath) { toml += `metricsPath = "${template.metricsPath}"\n`; } return toml; }