Template Engine
awa uses Eta as its template engine. Templates are plain files that can render conditionally based on feature flags, include partials, and declare stale files to delete.
Quick Overview
Section titled “Quick Overview”- Templates are rendered with context
{ features }and accessed viait.features - File and directory names are mirrored into the output (except underscore-prefixed paths)
- Whitespace-only output is skipped;
<!-- AWA:EMPTY_FILE -->creates an intentional empty file _delete.txtsupports post-generation cleanup, including feature-gated sections
Syntax
Section titled “Syntax”Templates receive a context object it with a features array containing the resolved feature flags.
Feature Flags
Section titled “Feature Flags”<% if (it.features.includes('copilot')) { %> <%~ include('_partials/copilot.instructions', it) %> <%} %>Feature names are treated as plain strings. awa does not enforce a fixed list at render time.
Conditionals
Section titled “Conditionals”<% if (it.features.includes('testing')) { %> ## Testing This section appears only when 'testing' isenabled. <% } %><% it.features.forEach(function(feature) { %> - <%= feature %> <% }) %>Output Tags
Section titled “Output Tags”| Tag | Behaviour |
|---|---|
<%= expr %> | Output, HTML-escaped |
<%~ expr %> | Output, raw (unescaped) |
<% code %> | Execute JavaScript, no output |
Partials
Section titled “Partials”Reusable content blocks live in _partials/. Include them with:
<%~ include('_partials/header', it) %>Partials receive the same context as the parent template. Use _partials/ so they are excluded from generated output.
File Handling
Section titled “File Handling”Naming
Section titled “Naming”Template filenames map directly to output filenames — there is no .eta extension stripping. The directory structure is mirrored as-is.
Underscore Convention
Section titled “Underscore Convention”Files and directories starting with _ are never written to the output directory:
_partials/— shared content blocks_delete.txt— delete list_README.md— template documentation (not output)
Empty Output
Section titled “Empty Output”- A template that renders to only whitespace → file is skipped (not created)
- A template that renders exactly
<!-- AWA:EMPTY_FILE -->(after trim) → an empty file is created intentionally
Delete Lists
Section titled “Delete Lists”Place a _delete.txt in the template root to declare files that should be removed from the output directory after generation.
# One path per line, relative to output directoryold-agent.mddeprecated/config.mdRules:
- Deletions are only applied when
--deleteis enabled (ordelete = truein config) - Deletions happen after file generation
- Files that don’t exist in output are silently skipped
- Files that conflict with generated files are skipped with a warning
--forcedeletes without prompting--dry-runlogs deletions without executing
Feature-Gated Delete Sections
Section titled “Feature-Gated Delete Sections”Use # @feature sections to delete stale files only when specific features are not active:
# @feature copilot.github/copilot-instructions.md
# @feature claude cursorCLAUDE.mdFor a # @feature section, each listed path is deleted only when none of the listed features are active.
Any non-@feature comment resets the current feature gate section.
Template Directory Layout
Section titled “Template Directory Layout”A typical template directory:
my-templates/├── _partials/│ ├── header.md│ └── workflow.md├── _delete.txt├── _README.md├── .github/│ ├── agents/│ │ └── awa.agent.md│ └── prompts/│ ├── awa.code.prompt.md│ └── awa.design.prompt.md└── .awa/ └── rules/ └── conventions.mdBest Practices
Section titled “Best Practices”- Keep templates deterministic: same inputs should produce same outputs
- Put reusable blocks in
_partials/instead of duplicating content - Keep
_delete.txtfocused on stale output paths and document intent with comments - Test template changes with
awa template diff . --template <path>before writing changes - Use
--dry-runand--deletetogether when validating cleanup behavior - Use
awa template testwith snapshot fixtures to catch template regressions in CI
Template Sources
Section titled “Template Sources”Templates can be loaded from local paths or remote Git repositories.
Local Path
Section titled “Local Path”awa init . --template ./my-templatesawa init . --template /absolute/path/to/templatesGitHub
Section titled “GitHub”# Shorthandawa init . --template owner/repo
# With subdirectoryawa init . --template owner/repo/templates
# With branch or tagawa init . --template owner/repo#mainawa init . --template owner/repo#v1.0.0
# Full URLawa init . --template https://github.com/owner/repoGitLab / Bitbucket
Section titled “GitLab / Bitbucket”awa init . --template gitlab:owner/repoawa init . --template bitbucket:owner/repoawa init . --template git@github.com:owner/repoRemote templates are fetched via degit and cached in ~/.cache/awa/templates/. Use --refresh to re-fetch cached sources.
Overlays
Section titled “Overlays”Overlays let you layer additional files on top of a base template without modifying it. Each overlay directory is merged over the base template (last overlay wins for conflicting paths).
awa template generate . --overlay ./overlays/company --overlay ./overlays/projectawa template diff . --overlay ./my-overridesOverlays are also configurable in .awa.toml:
template = "owner/repo"overlay = ["./overlays/company", "./overlays/project"]The merged result is passed to the template engine as if it were a single template directory. Overlay files take precedence over base template files with the same path.
Rendering Flow
Section titled “Rendering Flow”- Resolve template source (
--templateor bundled default) - Resolve features from CLI/config (
features,preset,remove-features) - Walk templates (excluding underscore-prefixed paths)
- Render each template with
{ features } - Create/overwrite/skip files based on conflicts and mode flags
- Process
_delete.txtentries (only when delete mode is enabled)