Skip to main content
Glama

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
NameRequiredDescriptionDefault
projectPathNoPath to project directory (defaults to current directory)
includeDefaultsNoInclude [defaults] section with recommended settings (default: true)
autoDetectNoAuto-detect technologies and generate tasks (default: true)

Implementation Reference

  • 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)',
            },
          },
        },
      },
    ],
  • 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,
          },
        ],
      };
    }
  • 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)}`);
      }
    }
  • 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;
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/drewkhoury/devpipe-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server