{
  "version": "act 1.0.17",
  "slug": "code-generation",
  "name": "code-generation",
  "description": "Generate boilerplate code from existing types using AST-aware code generation. Use when creating constructors, getters/setters, builders, equals/hash methods, JSON serialization, toString, interface implementations, test stubs, or any repetitive code derived from existing class/struct definitions. Supports batch generation for maximum efficiency.",
  "url": "https://act101.ai/docs/skills/code-generation",
  "body_md": "# Code Generation with act\n\nGenerate boilerplate from existing type definitions. All generation operations are CLI-based \u2014 invoke via shell commands. This skill is the authoritative reference for code generation patterns. Other skills (`code_porting`, `architectural_refactoring`, `code_refactoring`) delegate here for boilerplate generation.\n\n## Rules\n\n1. **Classify before acting.** Before writing boilerplate by hand, determine if a generator can produce it. Data types (DTOs, models, value objects) \u2192 generators. Business logic \u2192 manual/LLM. Interface stubs \u2192 `generate-impl`. If a generator exists for the task, use it \u2014 it produces correct, language-appropriate code without consuming LLM tokens.\n\n2. **Discover structure first.** Before generating, use `skeleton` and `symbols` to understand the target type's fields and structure. Don't guess field names \u2014 read them from the AST. The generator needs an existing type with fields defined to work from.\n\n3. **Batch independent generators.** All generators targeting the same type are independent \u2014 run them in parallel. A batch of 8 generators completes in wall-clock time of the slowest single operation instead of 8 sequential calls with round-trip overhead.\n\n4. **Order: type \u2192 generate \u2192 logic.** The base type with fields must exist first (generators need field definitions to work from). Run generators after the type exists. Write business logic last. For porting workflows: scaffold \u2192 batch generate \u2192 translate logic.\n\n5. **Preview before commit.** Always preview generated code before applying, especially when running generators for the first time on a language you haven't verified.\n\n6. **Validate after generation.** Run `diagnostics` after committing a generation batch to catch any issues. Follow with `import_organize` to clean up any new imports.\n\n7. **Don't generate what the language provides natively.** Rust has derive macros (`#[derive(PartialEq, Hash, Debug)]`). Python has dataclasses. C# has records. When the language has a native mechanism that provides the same functionality, prefer it. The generator is for languages that require explicit boilerplate.\n\n8. **Generate tests last.** `generate-tests` should run after all other boilerplate is in place \u2014 it needs to see the full API to produce useful stubs.\n\n## Available Generators\n\n| Generator | What it Creates | Input |\n|-----------|----------------|-------|\n| `generate-constructor` | Constructor from fields | Class/struct name |\n| `generate-impl` | Interface/trait implementation stubs | Class + interface name |\n| `generate-accessors` | Getters and setters | Class + field names |\n| `generate-builder` | Builder pattern | Class/struct name |\n| `generate-equals` | Equality comparison method | Class/struct name |\n| `generate-hash` | Hash code method | Class/struct name |\n| `generate-to-string` | String representation | Class/struct name |\n| `generate-from-json` | JSON deserialization | Class/struct name |\n| `generate-to-json` | JSON serialization | Class/struct name |\n| `generate-tests` | Test stubs for methods | Class/function name |\n| `generate-docstring` | Documentation comments | Symbol name |\n| `generate-init` | `__init__` method (Python) | Class name |\n| `generate-repr` | `__repr__` method (Python) | Class name |\n| `generate-mapped-type` | Mapped type utilities (TypeScript) | Type name |\n| `generate-type-guard` | Type guard function (TypeScript) | Type name |\n| `generate-operator-overloads` | Operator overloads (C++, C#, Python) | Class name |\n| `generate-rule-of-five` | Rule-of-five methods (C++) | Class name |\n\n## Batch Generation Pattern\n\nWhen creating a new data model with full boilerplate, **invoke generators in parallel** for maximum speed. Each generator is independent \u2014 they can all run concurrently.\n\n### Example: Full data model boilerplate\n\nGiven a class file with fields already defined:\n\n```bash\n# These are independent \u2014 run in parallel (all at once)\nact refactor generate-constructor User --file src/models/user.ts\nact refactor generate-accessors User --file src/models/user.ts --fields name,email,age\nact refactor generate-equals User --file src/models/user.ts\nact refactor generate-hash User --file src/models/user.ts\nact refactor generate-to-string User --file src/models/user.ts\nact refactor generate-to-json User --file src/models/user.ts\nact refactor generate-from-json User --file src/models/user.ts\nact refactor generate-builder User --file src/models/user.ts\n```\n\nThen sequentially:\n```bash\n# After all generators complete, organize imports\nact refactor import-organize --file src/models/user.ts\n# Generate test stubs last (depends on generated methods)\nact refactor generate-tests User --file src/models/user.ts\n```\n\n### Why batch?\n\nEach `act` invocation is fast (~50ms). But when called from an AI agent via MCP/shell, each invocation has overhead (tool call round-trip). Running 8 generators in parallel completes in wall-clock time of the slowest single operation (~100ms) instead of 8 sequential calls (~800ms + round-trip overhead).\n\n**For agents:** When you need to generate multiple boilerplate methods for a class, invoke all independent generators in a single batch of parallel tool calls.\n\n## Common Recipes\n\n### New Service Class\n\n1. Write the minimal class with method signatures (the base type must exist for generators to target)\n2. Batch in parallel: `generate-impl ServiceClass IServiceInterface`, `generate-constructor ServiceClass`\n3. `generate-tests ServiceClass` \u2014 create test stubs\n4. `import-organize` on the file\n\n### New DTO / Data Transfer Object\n\n1. Write the class with fields only (generators need the field definitions to work from)\n2. Batch in parallel: `generate-constructor`, `generate-accessors`, `generate-equals`, `generate-hash`, `generate-to-json`, `generate-from-json`, `generate-to-string`\n3. `generate-builder` if the DTO has many fields\n4. `generate-tests`\n\n### New API Response Type\n\n1. Write the type with fields (generators need the field definitions)\n2. Batch in parallel: `generate-from-json`, `generate-to-json`, `generate-equals`\n3. `generate-tests`\n\n### Post-Scaffold Boilerplate (Porting Integration)\n\nWhen porting data types from another language (see `code_porting` skill):\n\n1. Scaffold the target-language type using `port scaffold` (or write the type with fields manually)\n2. Classify: data type \u2192 generators, business logic \u2192 LLM translation\n3. Batch in parallel: all applicable generators for the data type\n4. Validate with `diagnostics`\n5. Move on to business logic translation\n\nThis step produces 80\u2013150 lines of correct, language-appropriate code per data type without consuming any LLM tokens.\n\n## When Other Skills Call This Skill\n\n- **`code_porting`:** After scaffolding a target file, classify each symbol. Data types get batch-generated here. Business logic gets LLM-translated.\n- **`architectural_refactoring`:** After extracting interfaces at seams, use `generate-impl` for implementation stubs.\n- **`code_refactoring`:** After `extract-class` creates a new type, use generators to add boilerplate.\n\n## Language-Specific Recipes\n\nSee [language-recipes.md](references/language-recipes.md) for Python dataclass generation, Rust derive macros, Go struct methods, C# record patterns, and more.\n\n> **Note:** Language support is actively expanding. If a generator fails for a language, it may not yet be supported. Run `scripts/language-operation-matrix.sh` to check current status per language."
}