Skip to content

Commit 135b8ea

Browse files
committed
Merge branch 'worktree-agent-a75154ea111a2b638'
# Conflicts: # agent-context/skills/metaobjects-audit/references/csharp.md # docs/features/own-your-codegen.md
2 parents 956092b + 9733c87 commit 135b8ea

75 files changed

Lines changed: 4435 additions & 615 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.claude/rules/codegen-architecture.md‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@ interface Generator {
2424
}
2525
```
2626

27-
Helpers `perEntity()` and `oncePerRun()` cover the common "file per entity" / "one-shot" cases.
27+
Helpers `perEntity()`, `perPackage()` and `perModel()` cover the per-object / per-package /
28+
whole-model scopes (`oncePerRun()` is the deprecated alias of `perModel()`).
29+
30+
**Writing a generator of your own is the primary path** (ADR-0034 Amendment 4): `meta
31+
generator new <name> [--scope entity|package|model]` writes a working one into
32+
`codegen/generators/` and wires it into the config. Model reads an owned generator needs
33+
are exported from the package root (`objectRefTarget`, `enumValues`, `servedPath`, the case
34+
helpers); the guide and every port's shape are in `docs/recipes/write-your-own-generator.md`.
2835

2936
**Built-in factories**: `entityFile`, `queriesFile`, `routesFile`, `formFile`, `barrel`. Per ADR-0034 (scaffold-and-own) and its Amendment 2 (opt-in codegen), `meta init` scaffolds `codegen/generators/` EMPTY with `generators: []`; `meta gen --list --probe` is the catalog, and `meta eject <name>...` copies each chosen reference template into the consumer repo at `codegen/generators/*.ts` and prints the import and entry to wire. The owned copy is the ONLY import path for `entityFile`/`queriesFile`/`routesFile`/`barrel`: the deprecated `@metaobjectsdev/codegen-ts/generators` re-export of them was **removed at the 1.0 cut**.
3037

‎README.md‎

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ model. Your hand-written logic stays yours.
1717
supposed to do — that your agent reads and writes. Two things happen to it:
1818

1919
- **Generate.** The boring parts are derived from it, in TypeScript, Java, Kotlin, C#
20-
and Python — at build time by reference generators you copy into your repo and own,
20+
and Python — at build time by generators you write or copy into your repo and own,
2121
or at runtime from the live model. Nothing proprietary in the output.
2222
- **Verify.** The build fails when generated code drifts from the model and when a
2323
prompt's payload no longer matches what it's told — and it fails or warns when a
@@ -183,7 +183,7 @@ MetaObjects has two layers, and only the first is a promise
183183

184184
| | Core — guaranteed | Helpers — yours |
185185
|---|---|---|
186-
| **What** | The metamodel, loader, canonical format and registry; runtime metadata access (the `ObjectManager`, not the HTTP adapters that mount it); schema migrations (`meta migrate`); the drift gates (`meta verify`); prompt render and the reply parser | Every generator that writes application code into your repo: routes, controllers, ORM wiring, DTOs, forms, grids, hooks |
186+
| **What** | The metamodel, loader, canonical format and registry; runtime metadata access (the `ObjectManager`, not the HTTP adapters that mount it); schema migrations (`meta migrate`); the drift gates (`meta verify`); prompt render and the reply parser | Every generator that writes code into your repo — the ones you write for the outputs you need, and the reference routes, controllers, ORM wiring, DTOs, forms, grids and hooks you copy |
187187
| **Promise** | Conformance-gated, the same behaviour in every port that ships it, covered by the [compatibility policy](docs/compatibility-policy.md) | Reference starting points that compile and pass their reference fixtures. Copy one with `meta eject` and change it freely |
188188
| **A defect is** | A MetaObjects bug, fixed in a release | A bug in the reference, fixed there; your copy is yours |
189189

@@ -202,12 +202,17 @@ complete in all five ports; MCP exposure of declared prompts/tools is the one re
202202
roadmap item. The fifth has been dogfooded on maintainer-owned projects only, and the
203203
sixth ships two libraries at their own stability labels:
204204

205-
1. **Codegen** *(reference generators you own, ejectable in every port)* — starting points that emit per-language
206-
code (Drizzle/Zod + Fastify for TS, Spring REST + DTO + repository for Java,
207-
`data class` + Exposed for Kotlin, EF Core record + ASP.NET routes for C#, Pydantic +
208-
FastAPI for Python). Copy the ones you need, change them, and regenerate with
209-
hand-edit-preserving three-way merge. The engine that runs them is core; their output
210-
is yours.
205+
1. **Codegen** *(generators you write and own, in every port)* — on the core, you build
206+
the generators your application needs: OpenAPI, JSON Schema, Zod, DTOs, a client,
207+
docs — anything the model describes. A generator is a name plus a function from the
208+
model to files, and `verify` gates it with nothing to register; `meta generator new
209+
<name>` scaffolds a working one on TypeScript, and
210+
[Write your own generator](docs/recipes/write-your-own-generator.md) has every port's
211+
20-line shape plus JSON Schema and OpenAPI examples to copy. The reference generators
212+
(Drizzle/Zod + Fastify for TS, Spring REST + DTO + repository for Java, `data class` +
213+
Exposed for Kotlin, EF Core record + ASP.NET routes for C#, Pydantic + FastAPI for
214+
Python) are starting points: eject the one that is close, change it, and regenerate.
215+
The engine that runs generators is core; their output is yours.
211216
2. **Runtime metadata** — load metadata at runtime, drive behavior dynamically
212217
(CRUD, validation, relationships, dynamic admin UIs; typed tool payloads are
213218
declared today, with MCP exposure on the roadmap).

‎agent-context/skills/metaobjects-audit/references/csharp.md‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,14 @@ copies the helper runtime the generated routes call (`FilterParser`, `EfCoreFilt
6464
`ValueObjectValidator`, `ConstraintErrors`, `Iso8601TimestampConverter`) into
6565
`codegen/runtime/` under the namespace `Codegen.Runtime`. That folder is owned code, not a
6666
hand-rolled filter parser: do not flag it. `dotnet meta gen --list` marks each owned copy
67-
`identical` or `DIFFERS`.
68-
69-
A project that has not ejected is not a finding either: running the packaged generators by
70-
name is a supported choice. For a shape no built-in emits, the lighter path is a
71-
**declarative template**: `dotnet meta gen --template-spec <json> --template-root <dir>`,
72-
whose entries append to your `--generators` selection. Worked example with the full JSON:
73-
`docs/ports/csharp.md`.
67+
`identical` or `DIFFERS`. A generator the project WRITES is an `IGenerator` listed in
68+
`codegen/Program.cs` the same way.
69+
70+
**A finding of the form "the built-ins do not emit the shape this project needs", or a
71+
hand-written layer the model fully describes, resolves to a generator the project writes**
72+
(ADR-0034 Amendment 4), or to a declarative template (`dotnet meta gen --template-spec
73+
<json> --template-root <dir>`) where the shape is what matters. Recommend it; it is the
74+
primary path. Worked template example: `docs/ports/csharp.md`.
7475

7576
To re-scaffold the agent-context into a C# project, use the Node `meta` CLI (the
7677
single agent-docs assembler per ADR-0033):

‎agent-context/skills/metaobjects-audit/references/python.md‎

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,17 @@ regardless of server language — see the migration reference.
5959

6060
## Owned generators
6161

62-
Python does not scaffold-and-own generators — they are provided by the `metaobjects`
63-
package and selected by stable name via `--generators`, over a **closed built-in
64-
registry**. There is no analog to the TS `codegen/generators/*.ts` pattern here, and no
65-
seam to register a generator of your own. (`--provider module:symbol` registers
66-
**metamodel vocabulary**, not a generator — do not read it as one.)
67-
68-
**So do not score a Python project down for "not owning its generators", and do not
69-
recommend writing one.** The customization path here is the **declarative template**:
70-
`metaobjects gen --template-spec <json> --templates <dir>`, whose entries append to your
71-
`--generators` selection. A finding of the form "the built-ins do not emit the shape this project
72-
needs" resolves to a template-spec, not to generator code. Worked example with the full
73-
JSON: `docs/ports/python.md`.
62+
Python generators are owned the same way as on every port. `metaobjects eject <name>`
63+
copies a reference into `codegen/generators/`, and a generator the project WRITES is wired
64+
the same way — a `module:symbol` entry in `--generators` or in `metaobjects.config.yaml`,
65+
reading the model through `metaobjects.codegen.model_walk`. (`--provider module:symbol`
66+
registers **metamodel vocabulary**, not a generator — do not read it as one.)
67+
68+
**A finding of the form "the built-ins do not emit the shape this project needs", or a
69+
hand-written layer the model fully describes, resolves to a generator the project writes**
70+
(ADR-0034 Amendment 4), or to a declarative template (`metaobjects gen --template-spec
71+
<json> --templates <dir>`) where the shape is what matters. Recommend it; it is the
72+
primary path. Worked template example: `docs/ports/python.md`.
7473

7574
To re-scaffold the agent-context into a Python project, use the Node `meta` CLI (the
7675
single agent-docs assembler per ADR-0033):

0 commit comments

Comments
 (0)