Guidance for constructing code generators in the ZIO Golem project using AST nodes instead of strings.
Install
mkdir -p .claude/skills/zio-golem-code-generation && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14688" && unzip -o skill.zip -d .claude/skills/zio-golem-code-generation && rm skill.zipInstalls to .claude/skills/zio-golem-code-generation
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Generating Scala code in the golem subproject. Use when adding code generation steps, build-time source generators, scalameta AST construction, or sbt/Mill sourceGenerators to the golem/ subtree.Key capabilities
- →Construct generated code as Scalameta AST nodes using quasiquotes
- →Cross-compile code generation logic to Scala 2.12 and Scala 3.3.7
- →Parse dotted strings into Scalameta AST nodes for type and term references
- →Expose a pure, effect-free API for code generators
- →Integrate code generation with sbt and Mill build tools
How it works
The skill mandates constructing generated code as Scalameta AST nodes using quasiquotes, cross-compiling the logic to Scala 2.12 and Scala 3.3.7. It defines a pure API for generators and integrates them into sbt via `sourceGenerators` and Mill via `generatedSources`.
Inputs & outputs
When to use zio-golem-code-generation
- →Build source generators
- →Construct Scala code via AST
- →Implement sbt/Mill sourceGenerators
About this skill
ZIO Golem Code Generation
Guidelines for writing Scala code generators in the golem subproject.
Core Principle: Scalameta AST, Never String Templates
Always construct generated code as scalameta AST nodes using quasiquotes (q"...", t"...", source"...", param"..."). Never use string interpolation or text templates to produce Scala source files.
// ✅ Correct — typed AST
val tree = q"""
object $name {
def register(): Unit = {
..$registrations
()
}
}
"""
// ❌ Wrong — string interpolation
val code = s"""object $name {
def register(): Unit = { ... }
}"""
Shared Codegen Library (golem/codegen/)
All build-time code generation logic lives in golem/codegen/, a pure (no ZIO, no sbt, no Mill) Scala library that cross-compiles to Scala 2.12 (for sbt) and Scala 3.3.7 (for Mill). Both plugins depend on this shared library.
Cross-compilation constraints
Because the library must compile under Scala 2.12:
- Use
import scala.meta.dialects.Scala213for the implicit dialect needed by quasiquotes and.parse[T]calls. - For parsing with a specific dialect, use
dialects.Scala3(code).parse[Source](explicit dialect application) rather thanimplicit val d: Dialect = ...which causes ambiguity. - Use
parseMeta[T](code)(implicit parse: Parse[T])helper pattern for snippet parsing. - Avoid Scala 3-only syntax in shared code.
Type and term references
Parse dotted strings into scalameta AST nodes for use in quasiquotes:
private def parseMeta[T](code: String)(implicit parse: Parse[T]): T =
Scala213(code).parse[T].get
private def parseTermRef(dotted: String): Term.Ref =
parseMeta[Term](dotted).asInstanceOf[Term.Ref]
private def parseType(tpe: String): Type =
parseMeta[Type](tpe)
private def parseImporter(dotted: String): List[Importer] =
parseMeta[Stat](s"import $dotted").asInstanceOf[Import].importers
API pattern
Generators should expose a pure, effect-free API that accepts source text and returns generated outputs + diagnostics:
object MyCodegen {
final case class GeneratedFile(relativePath: String, content: String)
final case class Warning(path: Option[String], message: String)
final case class Result(files: Seq[GeneratedFile], warnings: Seq[Warning])
def generate(inputs: ...): Result = {
// 1. Parse/scan inputs
// 2. Build scalameta AST via quasiquotes
// 3. Pretty-print via .syntax
// 4. Return GeneratedFile with relative path + content
}
}
The plugin wrappers (sbt/Mill) handle file I/O, logging, and build-tool integration.
Build Integration Pattern
sbt Plugin (golem/sbt/)
The sbt plugin GolemPlugin is an AutoPlugin compiled as part of the meta-build via ProjectRef in project/plugins.sbt. It hooks into sourceGenerators:
Compile / sourceGenerators += Def.task {
val inputs = scalaSources.map { f =>
MyCodegen.SourceInput(f.getAbsolutePath, IO.read(f))
}
val result = MyCodegen.generate(inputs)
result.warnings.foreach(w => log.warn(s"[golem] ${w.message}"))
result.files.map { gf =>
val out = managedRoot / gf.relativePath
IO.write(out, gf.content)
out
}
}.taskValue
For new generators:
- Add the pure generation logic to
golem/codegen/src/main/scala/golem/codegen/. - Add sbt integration in
golem/sbt/src/main/scala/golem/sbt/. - Hook into
Compile / sourceGeneratorsas a.taskValue. - Use
FileFunction.cachedwithFileInfo.hashif the generation has an input file (schema, WIT, etc.) to avoid unnecessary regeneration.
Mill Plugin (golem/mill/)
The Mill plugin GolemAutoRegister is a trait mixed into ScalaJSModule. It uses generatedSources and T { ... } tasks. Follow the same pattern as golemGeneratedAutoRegisterSources.
Shared logic, not duplicated
All generation logic lives in golem/codegen/. The sbt and Mill plugins are thin wrappers that:
- Collect source files and read their contents
- Call the shared
generate(...)function - Log warnings
- Write returned files under managed/generated roots
- Configure build-tool-specific hooks (module initializers, compile dependencies)
When adding a new generation step, implement the logic once in golem/codegen/, then add thin wrappers in both GolemPlugin.scala and GolemAutoRegister.scala.
Existing Code Generation in Golem
1. Auto-Registration (shared codegen + sbt/Mill wrappers)
Scans sources for @agentImplementation classes using scalameta's parser, then generates RegisterAgents.scala and per-package __GolemAutoRegister_*.scala files using scalameta quasiquotes.
Files:
golem/codegen/src/main/scala/golem/codegen/autoregister/AutoRegisterCodegen.scala— shared logicgolem/sbt/src/main/scala/golem/sbt/GolemPlugin.scala— sbt wrappergolem/mill/src/golem/mill/GolemAutoRegister.scala— Mill wrapper
2. Scala 3 Macros (compile-time, not build-time)
Macros generate code at compile time, not as a build step. They live in golem/macros/ and use scala.quoted.*:
AgentDefinitionMacro— extractsAgentMetadatafrom@agentDefinitiontraitsAgentImplementationMacro— generates implementation wrappers from@agentImplementationclassesAgentClientMacro— generates RPC client typesAgentCompanionMacro— generates companion object boilerplate (get,getPhantom, etc.)
These are not build-time code generators. Do not confuse them with sourceGenerators.
Generation Pipeline Shape
Follow this pipeline for new generators:
1. Load schema/input (WIT file, annotation scan, external spec)
2. Parse into models (typed case classes, not raw strings)
3. Classify/transform (determine what code to emit)
4. Build AST (scalameta quasiquotes)
5. Pretty-print (.syntax on the AST root)
6. Return (GeneratedFile with relativePath + content)
The plugin wrappers handle file writing, formatting, and incremental build integration.
Conventions
- Pure functions — all generator methods are pure. No ZIO, no sbt/Mill types, no file I/O in the shared library.
- Trait mixin composition — split generators into traits (
ModelGenerator,ClientGenerator, etc.) and mix them into the main codegen class if complexity warrants it. - Dialect-aware — use
dialects.Scala3for parsing user sources (withScala213fallback). UseScala213for quasiquote construction (compatible with both 2.12 and 3.x codegen host). - Generated file header — include
/** Generated. Do not edit. */as a comment in generated objects/classes. - Output location — write to
sourceManaged(sbt) orT.dest(Mill), never to source directories.
When not to use it
- →When generating Scala code using string interpolation or text templates
- →When the code generation logic is not for the `golem` subproject
- →When implementing Scala 3 macros (compile-time, not build-time code generation)
Limitations
- →The skill is specific to the `golem` subproject.
- →It requires cross-compilation to Scala 2.12 and Scala 3.3.7.
- →It explicitly forbids string interpolation or text templates for code generation.
How it compares
This skill enforces a specific, type-safe approach to Scala code generation within the `golem` subproject by using Scalameta ASTs and cross-compilation, preventing common errors associated with string templates and providing a standardized
Compared to similar skills
zio-golem-code-generation side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| zio-golem-code-generation (this skill) | 0 | 4mo | No flags | Advanced |
| godot | 1,044 | 5mo | Review | Intermediate |
| software-architecture | 333 | 6mo | No flags | Intermediate |
| drizzle | 238 | 2mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
software-architecture
davila7
Guide for quality focused software architecture. This skill should be used when users want to write code, design architecture, analyze code, in any case that relates to software development.
drizzle
lobehub
Drizzle ORM schema and database guide. Use when working with database schemas (src/database/schemas/*), defining tables, creating migrations, or database model code. Triggers on Drizzle schema definition, database migrations, or ORM usage questions.
screenshot-to-code
OneWave-AI
Convert UI screenshots into working HTML/CSS/React/Vue code. Detects design patterns, components, and generates responsive layouts. Use this when users provide screenshots of websites, apps, or UI designs and want code implementation.
zustand
lobehub
Zustand state management guide. Use when working with store code (src/store/**), implementing actions, managing state, or creating slices. Triggers on Zustand store development, state management questions, or action implementation.
codex
Lucklyric
Invoke Codex CLI for complex coding tasks requiring high reasoning capabilities. This skill should be invoked when users explicitly mention "Codex", request complex implementation challenges, advanced reasoning, or need high-reasoning model assistance. Automatically triggers on codex-related requests and supports session continuation for iterative development.