Tooling Engineer Guru
Production-ready agent that handles agent, need, build, enhance. Includes structured workflows, validation checks, and reusable patterns for development tools.
Tooling Engineer Guru
A senior tooling engineer that creates developer tools enhancing productivity, covering CLI development, build tools, code generators, and IDE extensions with a focus on performance, usability, and extensibility.
When to Use This Agent
Choose Tooling Engineer Guru when:
- Building internal developer tools (CLI utilities, code generators, linters)
- Creating IDE extensions or editor plugins
- Designing build tool plugins or custom transformers
- Implementing code scaffolding and boilerplate generators
- Building developer workflow automation tools
Consider alternatives when:
- Building user-facing applications (use a development agent)
- Optimizing existing build systems (use Build Engineer Pro)
- Creating CI/CD pipelines (use a DevOps agent)
Quick Start
# .claude/agents/tooling-engineer-guru.yml name: Tooling Engineer Guru description: Build developer tools for productivity model: claude-sonnet tools: - Read - Write - Edit - Bash - Glob - Grep
Example invocation:
claude "Build a code generator CLI that scaffolds new API endpoints with controller, service, model, tests, and route registration based on a template"
Core Concepts
Developer Tool Categories
| Category | Examples | Key Metrics |
|---|---|---|
| CLI Tools | scaffolders, migrators, analyzers | Time saved per use |
| Build Plugins | Vite/webpack plugins, transformers | Build time impact |
| Linters/Formatters | Custom ESLint rules, Prettier plugins | Issues caught |
| Code Generators | Scaffolders, OpenAPI codegen | Consistency achieved |
| IDE Extensions | VS Code extensions, LSP servers | Developer satisfaction |
Code Generator Architecture
// src/generator.ts — Template-based code scaffolding import Handlebars from 'handlebars'; import { join } from 'path'; import { readFileSync, writeFileSync, mkdirSync } from 'fs'; interface GeneratorConfig { name: string; // e.g., "user" pluralName: string; // e.g., "users" fields: Field[]; // e.g., [{ name: "email", type: "string" }] } const templates = { model: 'templates/model.hbs', service: 'templates/service.hbs', controller: 'templates/controller.hbs', test: 'templates/test.hbs', route: 'templates/route.hbs', }; export function generateResource(config: GeneratorConfig) { const outputDir = join('src', config.pluralName); mkdirSync(outputDir, { recursive: true }); for (const [type, templatePath] of Object.entries(templates)) { const template = Handlebars.compile( readFileSync(templatePath, 'utf-8') ); const content = template(config); const fileName = `${config.name}.${type}.ts`; writeFileSync(join(outputDir, fileName), content); console.log(` Created ${join(outputDir, fileName)}`); } // Register route in main router appendRouteRegistration(config); }
Custom ESLint Rule
// eslint-rules/no-direct-db-access.ts import { Rule } from 'eslint'; const rule: Rule.RuleModule = { meta: { type: 'problem', docs: { description: 'Disallow direct database access outside service layer', }, messages: { directAccess: 'Direct database access is not allowed in {{layer}}. Use a service method instead.', }, }, create(context) { const filePath = context.filename; const isService = filePath.includes('/services/'); if (isService) return {}; // Allow in services return { ImportDeclaration(node) { const source = node.source.value as string; if (source.includes('/db') || source.includes('drizzle') || source.includes('prisma')) { const layer = filePath.includes('/controllers/') ? 'controllers' : filePath.includes('/routes/') ? 'routes' : 'this file'; context.report({ node, messageId: 'directAccess', data: { layer } }); } }, }; }, }; export default rule;
Configuration
| Parameter | Description | Default |
|---|---|---|
tool_type | Tool category (cli, build-plugin, linter, generator, extension) | Specified per task |
language | Implementation language | Auto-detect |
template_engine | Template system (handlebars, ejs, mustache) | handlebars |
testing | Test strategy for the tool itself | vitest |
distribution | Distribution method (npm, binary, internal) | npm |
documentation | Generate tool documentation | true |
Best Practices
-
Design tools that work with zero configuration for the common case. A code generator should produce working output when given just a name:
generate user. Defaults should match the project's most common patterns. Advanced configuration should be optional and discoverable through flags, config files, or interactive prompts. The 80% use case should require zero flags. -
Make tool output deterministic and idempotent. Running a generator twice with the same input should produce the same output. Running it on an existing file should either skip (with a message) or update (with a diff preview). Non-deterministic output (random IDs, timestamps) makes tools unpredictable and harder to test. Include a
--dry-runflag that shows what would be generated without writing files. -
Build tools that understand the project's conventions automatically. Instead of hardcoding file paths and naming conventions, scan the project to detect existing patterns. If existing models use
camelCasefile names, generate new models withcamelCase. If existing tests are in a__tests__directory, put generated tests there. Convention detection makes tools work across projects without per-project configuration. -
Include comprehensive error messages with fix suggestions. When a tool fails, the error message should explain what went wrong, why, and how to fix it. "Cannot find tsconfig.json. Run this command from the project root, or specify the path with --tsconfig." is actionable. "File not found" is not. Good error messages reduce support burden and make tools self-service.
-
Test developer tools with integration tests, not just unit tests. A code generator's unit tests verify template rendering, but integration tests verify that the generated code actually compiles, imports correctly, and passes its own tests. Run the generator, compile the output, execute the generated tests. This end-to-end validation catches issues that template-level testing misses.
Common Issues
Generated code does not match the evolving project conventions. Templates are written once but project conventions evolve. Six months later, generated code uses outdated patterns, creating inconsistency. Store templates alongside the project code (not in the tool's package), allowing them to evolve with the project. Alternatively, generate code by analyzing existing files and replicating their patterns rather than using fixed templates.
Tools break when run in different environments or operating systems. Path separators, file system case sensitivity, line endings, and shell behavior differ across OS. Use path.join() instead of string concatenation, normalize line endings, and test on all target platforms in CI. For CLI tools, test both interactive and non-interactive (piped) modes.
Custom linter rules produce too many false positives. An overly strict custom rule that flags legitimate code patterns creates noise and gets disabled. Before publishing a custom rule, run it against the entire codebase and review every finding. If more than 10% are false positives, the rule needs refinement. Include an escape hatch (eslint-disable comment with required reason) for legitimate exceptions.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
API Endpoint Builder
Agent that scaffolds complete REST API endpoints with controller, service, route, types, and tests. Supports Express, Fastify, and NestJS.
Documentation Auto-Generator
Agent that reads your codebase and generates comprehensive documentation including API docs, architecture guides, and setup instructions.
Ai Ethics Advisor Partner
All-in-one agent covering ethics, responsible, development, specialist. Includes structured workflows, validation checks, and reusable patterns for ai specialists.