Commit 15c85f8
feat(codegen-ts): declarative Mustache template-codegen scopes (#88)
* docs(codegen): SP-1 design — declarative Mustache template-generator parity
First sub-project of the codegen authoring-parity program (follow-on to ADR-0034).
Every port already ships the Mustache TemplateGenerator primitive (render engine is
byte-equivalent), but only TS lets a consumer wire their own template generator
declaratively — the others need a code walk the declarative surfaces (Maven XML,
--generators) can't express. SP-1 makes the common walks built-in + named
(perEntity/perPackage/wholeModel), so a consumer declares {template, scope,
outputPattern} with no code on any port. Lands the perPackage scope helper the
concepts guide §10 calls for; Kotlin gains a template generator for the first time.
Neutral, byte-gated contract: scope names + per-scope data dict + output-pattern
grammar + template resolution (new fixtures/template-codegen-conformance/). Wiring
stays idiomatic per port (no shared config format). Increments: TS reference → JVM
→ Python → C#. Native-generator registration parity is SP-2; the agent-context docs
rewrite is SP-3.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
* docs(codegen): SP-1 — resolve scope-naming + CLI-spec open points
Fold the two researched decisions into the SP-1 design:
- Scope names perEntity/perPackage/perModel (one vocabulary for code helpers +
declarative scope value); oncePerRun → soft-deprecated alias. Grounded in
Telosys / EF Core T4 / Prisma / OpenAPI Generator; "run" rejected as ambiguous
under multi-target output.
- C#/Python declarative surface: a JSON spec file (--template-spec + auto-discovered
default + JSON Schema), identical on both ports. Grounded in Smithy / OpenAPI
`files` / Buf / .config/dotnet-ef.json; YAML/TOML/inline-flags rejected for
stdlib-parity + the protoc cautionary tale.
§7 reframed as Decisions + remaining risks.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
* docs(codegen): SP-1a implementation plan — TS declarative template-codegen
8-task TDD plan for the TS reference increment: perPackage helper + perModel
rename; neutral structural data-dict builder; output-pattern expander; scope
walks wired into templateGenerator; JSON template-spec + schema (the CLI-port
contract); the template-codegen-conformance corpus + TS gate. Grounded in the
real metadata accessors; self-reviewed against the spec.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
* feat(codegen-ts): add perPackage scope helper + perModel (alias oncePerRun)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
* feat(codegen-ts): output-pattern expander for template codegen
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
* feat(codegen-ts): neutral structural template data-dict builder
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
* feat(codegen-ts): built-in scope walks (perEntity/perPackage/perModel) in templateGenerator
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
* feat(codegen-ts): JSON template-spec shape + parser + schema (CLI-port contract)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
* feat(codegen-ts): export template-codegen public API
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
* fix(codegen-ts): resolve effective package in template data dict + scope walks
entity.package is undefined for objects (object fqn() stays bare); read the
effective package via effectivePackage(resolutionKey()) so {package} and the
per-package grouping reflect the declared file package. Strengthen the data-dict
test to assert the real package (the prior assertion was tautological).
* test(codegen-ts): template-codegen conformance corpus + TS gate
Cross-port corpus: spec.json (perEntity/perPackage/perModel) over metadata/
resolving templates/ → byte-identical expected/. The TS gate runs it in a
hermetic tmp projectRoot (copies templates/) so runGen's .gen-state merge base
never lands in the committed corpus; a corpus .gitignore guards .metaobjects/.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
* no-mistakes(review): fix perPackage effective-package grouping and validate template-spec format
* no-mistakes(document): sync docs for declarative template-codegen scopes (SP-1a)
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>1 parent 47d3e47 commit 15c85f8
31 files changed
Lines changed: 2149 additions & 13 deletions
File tree
- docs
- features
- superpowers
- plans
- specs
- fixtures/template-codegen-conformance
- expected
- shop
- metadata
- templates
- server/typescript/packages/codegen-ts
- src
- generators
- template-codegen
- test/template-codegen
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
11 | 28 | | |
12 | 29 | | |
13 | 30 | | |
| |||
34 | 51 | | |
35 | 52 | | |
36 | 53 | | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
37 | 58 | | |
38 | 59 | | |
39 | 60 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
150 | 150 | | |
151 | 151 | | |
152 | 152 | | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
159 | 160 | | |
160 | 161 | | |
161 | | - | |
| 162 | + | |
162 | 163 | | |
163 | 164 | | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
71 | 109 | | |
72 | 110 | | |
73 | 111 | | |
| |||
0 commit comments