Skip to content

Commit 75a4465

Browse files
committed
site: propagate 0.20.0/0.19.5 + fix Python codegen accuracy (Pydantic+FastAPI, not SQLAlchemy)
- Version refs: npm 0.19.3 -> 0.20.0; PyPI 0.19.4 -> 0.19.5 (badge, port row, llms). NuGet 0.19.3 / Maven Central 7.11.3 untouched. - Python port accuracy: the site advertised the Python codegen as generating SQLAlchemy ORM models (with a fabricated `class Subscriber(Base)` / mapped_column example). The actual codegen emits Pydantic BaseModel + FastAPI routers only — replaced the example with the real generated output (Pydantic + `Literal[...]` enum + validated Create/Patch schemas) and corrected the five codegen-claim spots. The competitor-comparison table (SQLAlchemy as a Python ORM alternative) is accurate and unchanged. - Runtime description corrected: "SQLAlchemy Core" -> DB-API 2 ObjectManager (pg8000 / psycopg) in llms.txt + llms-full.txt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeGSV3StPCcJGZNNJ4ZfAb
1 parent 32a4aee commit 75a4465

3 files changed

Lines changed: 34 additions & 41 deletions

File tree

www/index.html

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ <h2 class="section-label">Four pillars. All shipping.</h2>
9696
<div class="pillars-grid">
9797
<article class="pillar">
9898
<h3>Codegen</h3>
99-
<p>One metadata model → idiomatic native code in five languages: <strong>Drizzle + Zod + Fastify/Hono</strong> (TS), <strong>Spring REST + DTO + JPA</strong> (Java), <strong>Exposed + KotlinPoet + Spring</strong> (Kotlin), <strong>EF Core + ASP.NET + Postgres DDL</strong> (C#), <strong>Pydantic + FastAPI + SQLAlchemy</strong> (Python). Hand-edit-preserving regen via three-way merge.</p>
99+
<p>One metadata model → idiomatic native code in five languages: <strong>Drizzle + Zod + Fastify/Hono</strong> (TS), <strong>Spring REST + DTO + JPA</strong> (Java), <strong>Exposed + KotlinPoet + Spring</strong> (Kotlin), <strong>EF Core + ASP.NET + Postgres DDL</strong> (C#), <strong>Pydantic + FastAPI</strong> (Python). Hand-edit-preserving regen via three-way merge.</p>
100100
</article>
101101
<article class="pillar">
102102
<h3>Runtime metadata</h3>
@@ -197,8 +197,8 @@ <h2 class="section-label">Five ports. All installable today.</h2>
197197
<tbody>
198198
<tr>
199199
<td><strong>TypeScript</strong></td>
200-
<td><span class="status status-stable">npm 0.19.3 · reference</span></td>
201-
<td>npm <code>@metaobjectsdev/*@0.19.3</code> (the reference implementation). Drizzle + Zod + Fastify + Hono codegen, Kysely runtime, and <code>meta migrate</code> for Postgres / SQLite / Cloudflare D1 — the TS toolchain owns schema migrations. 2,500+ tests across the workspace.</td>
200+
<td><span class="status status-stable">npm 0.20.0 · reference</span></td>
201+
<td>npm <code>@metaobjectsdev/*@0.20.0</code> (the reference implementation). Drizzle + Zod + Fastify + Hono codegen, Kysely runtime, and <code>meta migrate</code> for Postgres / SQLite / Cloudflare D1 — the TS toolchain owns schema migrations. 2,500+ tests across the workspace.</td>
202202
</tr>
203203
<tr>
204204
<td><strong>Java</strong></td>
@@ -217,8 +217,8 @@ <h2 class="section-label">Five ports. All installable today.</h2>
217217
</tr>
218218
<tr>
219219
<td><strong>Python</strong></td>
220-
<td><span class="status status-stable">PyPI 0.19.4</span></td>
221-
<td>PyPI <code>metaobjects</code> <code>0.19.4</code> + the <code>metaobjects</code> CLI. Loader + canonical serializer + render + verify + codegen (Pydantic + FastAPI + SQLAlchemy) + ObjectManager runtime. All five cross-port conformance corpora green.</td>
220+
<td><span class="status status-stable">PyPI 0.19.5</span></td>
221+
<td>PyPI <code>metaobjects</code> <code>0.19.5</code> + the <code>metaobjects</code> CLI. Loader + canonical serializer + render + verify + codegen (Pydantic + FastAPI) + ObjectManager runtime. All five cross-port conformance corpora green.</td>
222222
</tr>
223223
</tbody>
224224
</table>
@@ -230,7 +230,7 @@ <h2 class="section-label">Five ports. All installable today.</h2>
230230
<!-- Canonical example: one schema → five languages -->
231231
<section class="example" id="example">
232232
<h2 class="section-label">From one schema, five languages.</h2>
233-
<p class="example-intro">A typed entity in metadata, side-by-side with what every port actually generates. Each output is idiomatic for that language — Drizzle + Zod for TypeScript, JPA + Spring records for Java, Exposed + KotlinPoet data classes for Kotlin, EF Core + ASP.NET records for C#, SQLAlchemy + Pydantic for Python. Same metadata; five idiomatic outputs; conformance-gated to byte-identical canonical form.</p>
233+
<p class="example-intro">A typed entity in metadata, side-by-side with what every port actually generates. Each output is idiomatic for that language — Drizzle + Zod for TypeScript, JPA + Spring records for Java, Exposed + KotlinPoet data classes for Kotlin, EF Core + ASP.NET records for C#, Pydantic + FastAPI for Python. Same metadata; five idiomatic outputs; conformance-gated to byte-identical canonical form.</p>
234234

235235
<p class="example-section-label">The source: one YAML file in <code>metaobjects/</code></p>
236236
<pre class="example-code"><code><span class="comment"># metaobjects/meta.subscriber.yaml</span>
@@ -360,33 +360,26 @@ <h2 class="section-label">From one schema, five languages.</h2>
360360
}
361361
}</code></pre>
362362

363-
<p class="example-section-label">Python — SQLAlchemy + Pydantic + FastAPI from <code>metaobjects.codegen</code></p>
364-
<pre class="example-code"><code><span class="comment"># generated/subscriber.py</span>
365-
<span class="keyword">from</span> datetime <span class="keyword">import</span> datetime
366-
<span class="keyword">from</span> enum <span class="keyword">import</span> Enum
367-
<span class="keyword">from</span> typing <span class="keyword">import</span> Optional
363+
<p class="example-section-label">Python — Pydantic + FastAPI from <code>metaobjects gen</code></p>
364+
<pre class="example-code"><code><span class="comment"># generated/Subscriber.py</span>
365+
<span class="keyword">from</span> __future__ <span class="keyword">import</span> annotations
366+
<span class="keyword">from</span> typing <span class="keyword">import</span> Literal
367+
<span class="keyword">import</span> datetime
368368
<span class="keyword">from</span> pydantic <span class="keyword">import</span> BaseModel, Field
369-
<span class="keyword">from</span> sqlalchemy <span class="keyword">import</span> String
370-
<span class="keyword">from</span> sqlalchemy.orm <span class="keyword">import</span> Mapped, mapped_column
371-
<span class="keyword">from</span> .base <span class="keyword">import</span> Base
372-
373-
<span class="keyword">class</span> SubscriberStatus(str, Enum):
374-
ACTIVE = <span class="string">"active"</span>
375-
PAUSED = <span class="string">"paused"</span>
376-
CANCELLED = <span class="string">"cancelled"</span>
377-
378-
<span class="keyword">class</span> Subscriber(Base):
379-
__tablename__ = <span class="string">"subscribers"</span>
380-
id: Mapped[<span class="keyword">int</span>] = mapped_column(primary_key=<span class="keyword">True</span>, autoincrement=<span class="keyword">True</span>)
381-
email: Mapped[<span class="keyword">str</span>] = mapped_column(String(320))
382-
name: Mapped[Optional[<span class="keyword">str</span>]]
383-
status: Mapped[SubscriberStatus]
384-
created_at: Mapped[datetime]
385-
386-
<span class="keyword">class</span> SubscriberInsert(BaseModel):
387-
email: <span class="keyword">str</span> = Field(max_length=320)
388-
name: Optional[<span class="keyword">str</span>] = <span class="keyword">None</span>
389-
status: SubscriberStatus</code></pre>
369+
370+
371+
<span class="keyword">class</span> Subscriber(BaseModel):
372+
id: <span class="keyword">int</span> | <span class="keyword">None</span> = <span class="keyword">None</span>
373+
email: <span class="keyword">str</span> = Field(max_length=320)
374+
name: <span class="keyword">str</span> | <span class="keyword">None</span> = <span class="keyword">None</span>
375+
status: Literal[<span class="string">"active"</span>, <span class="string">"paused"</span>, <span class="string">"cancelled"</span>]
376+
createdAt: datetime.datetime | <span class="keyword">None</span> = <span class="keyword">None</span>
377+
378+
379+
<span class="keyword">class</span> SubscriberCreate(BaseModel): <span class="comment"># CREATE input — validated (FR-036)</span>
380+
email: <span class="keyword">str</span> = Field(min_length=1, max_length=320)
381+
name: <span class="keyword">str</span> | <span class="keyword">None</span> = <span class="keyword">None</span>
382+
status: Literal[<span class="string">"active"</span>, <span class="string">"paused"</span>, <span class="string">"cancelled"</span>]</code></pre>
390383

391384
<p class="example-section-label">Plus a migration — dialect-aware (Postgres / SQLite / Cloudflare D1)</p>
392385
<pre class="example-code"><code><span class="comment">-- migrations/0001_create_subscribers.up.sql (SQLite dialect)</span>
@@ -525,7 +518,7 @@ <h2 class="section-label">How MetaObjects compares.</h2>
525518
<td><strong>Python</strong></td>
526519
<td><a href="https://www.sqlalchemy.org/">SQLAlchemy</a>, <a href="https://docs.djangoproject.com/en/stable/topics/db/models/">Django ORM</a>, <a href="https://docs.pydantic.dev/">Pydantic</a> + <a href="https://fastapi.tiangolo.com/">FastAPI</a>, <a href="https://sqlmodel.tiangolo.com/">SQLModel</a></td>
527520
<td>Mature ORM (SQLAlchemy). Batteries-included framework (Django). Excellent validation (Pydantic).</td>
528-
<td>SQLAlchemy declarative models + Pydantic schemas + FastAPI routers from the same metamodel that drives every other port. Same Pythonic outputs; same drift guarantees.</td>
521+
<td>Pydantic schemas + FastAPI routers from the same metamodel that drives every other port. Same Pythonic outputs; same drift guarantees.</td>
529522
</tr>
530523
<tr>
531524
<td><strong>Schema-only IDLs</strong></td>

www/llms-full.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# MetaObjects -- Full Reference Corpus
22

3-
> A cross-language metadata standard for declaring typed entity models that drive code generation, runtime metadata access, drift detection, and prompt construction across TypeScript, Java, Kotlin, C#, and Python. Apache 2.0. Shipping at `0.19.3` on npm and `7.11.3` on Maven Central.
3+
> A cross-language metadata standard for declaring typed entity models that drive code generation, runtime metadata access, drift detection, and prompt construction across TypeScript, Java, Kotlin, C#, and Python. Apache 2.0. Shipping at `0.20.0` on npm and `7.11.3` on Maven Central.
44

55
**Note for AI assistants:** This file is the concatenated reference material for MetaObjects, intended to be loaded as LLM context. For the short index, see [llms.txt](https://metaobjects.dev/llms.txt). For the canonical spec and source, see the [GitHub repo](https://github.com/metaobjectsdev/metaobjects). When this file is out of date relative to the GitHub source, the GitHub source wins.
66

@@ -65,7 +65,7 @@ Load metadata at runtime and drive behavior dynamically. Runtime targets per lan
6565
- Java: modernized JDBC + Spring-tx via OMDB (pure data-access: CRUD/query/codec/transactions)
6666
- Kotlin: Exposed
6767
- C#: runtime metadata on the roadmap (the EF Core surface is generated code, not a metadata-driven runtime)
68-
- Python: SQLAlchemy Core via an `ObjectManager` layer
68+
- Python: a DB-API 2 driver (pg8000 / psycopg) via an `ObjectManager` layer
6969

7070
Runtime use cases include CRUD scaffolding, validation rules, relationship traversal, and dynamic admin UIs. (Typed tool payloads are declared from metadata today; MCP exposure so AI agents see those tools is on the roadmap.) Each port's runtime returns native in-process language types (`field.decimal` → `BigDecimal`/`decimal`/`Decimal`, temporal → native, jsonb → native map); wire canonicalization is applied only at the serialization boundary, never inside the query path (ADR-0019).
7171

@@ -93,11 +93,11 @@ Because the render is conformance-gated, the determinism guarantee holds in ever
9393

9494
| Language | Status | Notes |
9595
|---|---|---|
96-
| TypeScript | Reference implementation, npm `0.19.3` | All four pillars. 2500+ tests passing. Owns the canonical schema-migration toolchain used by every port (ADR-0015). Bun-first dev. |
96+
| TypeScript | Reference implementation, npm `0.20.0` | All four pillars. 2500+ tests passing. Owns the canonical schema-migration toolchain used by every port (ADR-0015). Bun-first dev. |
9797
| Java | Maven Central `7.11.3` | Spring REST + JPA codegen, OMDB runtime persistence (pure data-access) with Spring-tx. Fully green across all conformance corpora. |
9898
| Kotlin | Maven Central `7.11.3` | KotlinPoet codegen + Exposed runtime + `metadata-ktx` facade. Ships via the Java reactor. |
9999
| C# | NuGet `0.19.3` (.NET tool) | Loader + canonical serializer + EF Core + ASP.NET codegen + render/verify. `dotnet meta` tool. |
100-
| Python | PyPI `0.19.4` | Loader + serializer + render + verify + codegen + `ObjectManager` runtime. Fully green across all corpora. |
100+
| Python | PyPI `0.19.5` | Loader + serializer + render + verify + codegen + `ObjectManager` runtime. Fully green across all corpora. |
101101

102102
Conformance fixtures live at [`fixtures/`](https://github.com/metaobjectsdev/metaobjects/tree/main/fixtures). Every port runs the shared corpus byte-identically: metamodel (`conformance/`, ~90 fixtures), render, persistence (Testcontainers Postgres, with an `op: roundtrip` gate so every `field.*` subtype write+read round-trips on every port), api-contract (20 scenarios, two lanes — a reference server AND each port's generated API booted over HTTP), registry (byte-matched metamodel-vocabulary manifest, live + green in all five ports), and yaml/verify.
103103

www/llms.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# MetaObjects
22

3-
> A cross-language metadata standard for declaring typed entity models that drive code generation, runtime metadata access, drift detection, and prompt construction across TypeScript, Java, Kotlin, C#, and Python. Apache 2.0. Shipping at `0.19.3` on npm and `7.11.3` on Maven Central.
3+
> A cross-language metadata standard for declaring typed entity models that drive code generation, runtime metadata access, drift detection, and prompt construction across TypeScript, Java, Kotlin, C#, and Python. Apache 2.0. Shipping at `0.20.0` on npm and `7.11.3` on Maven Central.
44

55
The metamodel is the durable spine; generated code is the disposable artifact. Substrate is local-first: typed metadata lives in your repo, and the generated code is idiomatic per-language output with **no proprietary runtime** — the entity/model tier is dependency-free, and the optional client, prompt-render, and runtime tiers are ordinary Apache-2.0 packages you could vendor or fork. If `@metaobjectsdev/*` (npm) or `com.metaobjects:*` (Maven) disappears tomorrow, you keep working code in every language.
66

@@ -39,13 +39,13 @@ This `llms.txt` is the short index; the deep, version-matched how-to is the scaf
3939
MetaObjects pillars are capabilities of the same metadata spine, not separate products. **All four ship today across all five ports** (TS / Java / Kotlin / C# / Python) — though not uniformly deep: see the [capability matrix](https://github.com/metaobjectsdev/metaobjects#capability-matrix) for per-port coverage, and note the field ranking is drift > codegen > prompts > runtime metadata (the youngest pillar).
4040

4141
- **Codegen** — emit idiomatic per-language code from a single metadata model. Drizzle + Zod + Fastify (TypeScript), Spring REST + DTO + JPA repositories (Java via `codegen-spring`), KotlinPoet + Exposed + Spring (Kotlin via `codegen-kotlin`), EF Core + ASP.NET (C#), Pydantic + FastAPI (Python). Hand-edit-preserving regeneration via three-way merge. Includes M:N relationship codegen (FR-018) in all five ports — entity navigation, idiomatic ORM wiring, and REST traversal (`GET /<source-plural>/{id}/<relation>`).
42-
- **Runtime metadata** — load metadata at runtime and drive behavior dynamically: CRUD, validation, relationships, dynamic admin UIs. (Typed tool payloads are declared today; MCP exposure of tools is on the roadmap.) Kysely (TS), SQLAlchemy Core (Python), modernized JDBC + Spring-tx via OMDB (Java), Exposed (Kotlin); C# runtime metadata is on the roadmap (its EF Core output is generated code, not a metadata-driven runtime). Runtime queries return native in-process types (ADR-0019); wire canonicalization happens only at the serialization boundary.
42+
- **Runtime metadata** — load metadata at runtime and drive behavior dynamically: CRUD, validation, relationships, dynamic admin UIs. (Typed tool payloads are declared today; MCP exposure of tools is on the roadmap.) Kysely (TS), a DB-API 2 driver (pg8000 / psycopg) via ObjectManager (Python), modernized JDBC + Spring-tx via OMDB (Java), Exposed (Kotlin); C# runtime metadata is on the roadmap (its EF Core output is generated code, not a metadata-driven runtime). Runtime queries return native in-process types (ADR-0019); wire canonicalization happens only at the serialization boundary.
4343
- **Drift detection** — catch divergence between generated code and metadata before it ships. `verify` is one verb with explicit subverbs (ADR-0021): `verify --codegen` (regen-and-diff against committed output), `verify --templates` (prompt `{{field}}` ↔ payload-VO drift), and `verify --db` (live-DB schema drift, Node `meta` only). Surfaces drift as build-time breakage rather than a production incident.
4444
- **Prompt construction** — treat LLM prompts as governed metadata instead of strings scattered across services. A typed payload declared as a projection (so payload bloat and token cost are a diff, not a mystery), external provider-resolved prompt text, and a logic-less Mustache engine that renders deterministically: snapshot-testable in CI, byte-stable so an exact-prefix prompt-cache hit doesn't break on a stray whitespace, and drift-checked at build time so a renamed field can't silently degrade a prompt. Conformance-gated, so the guarantee holds in every language port. Render + payload-VO codegen + `verify` + `template.output` parser-on-receipt (FR-006) + the output-format prompt fragment & tolerant `extract` parser (FR-010/FR-011) ship in all five ports today.
4545

46-
## Implementations (npm `0.19.3` / Maven Central `7.11.3`)
46+
## Implementations (npm `0.20.0` / Maven Central `7.11.3`)
4747

48-
- [TypeScript](https://github.com/metaobjectsdev/metaobjects/tree/main/server/typescript): the reference implementation. Published to npm at `0.19.3` across 14 `@metaobjectsdev/*` packages on the `latest` tag. 2500+ tests passing across the workspace. Bun-first dev workflow. Owns the canonical schema-migration toolchain used by every port (ADR-0015).
48+
- [TypeScript](https://github.com/metaobjectsdev/metaobjects/tree/main/server/typescript): the reference implementation. Published to npm at `0.20.0` across 14 `@metaobjectsdev/*` packages on the `latest` tag. 2500+ tests passing across the workspace. Bun-first dev workflow. Owns the canonical schema-migration toolchain used by every port (ADR-0015).
4949
- [Java](https://github.com/metaobjectsdev/metaobjects/tree/main/server/java): 13 publishable Maven modules under `com.metaobjects:*` at `7.11.3` on Maven Central. Spring REST + JPA codegen, OMDB runtime persistence (pure data-access) with Spring-tx, full FR-003 + FR-006 + FR-010/011 + FR-018 + FR5 family. Fully green across all conformance corpora.
5050
- [Kotlin](https://github.com/metaobjectsdev/metaobjects/tree/main/server/java/codegen-kotlin): a Kotlin codegen pipeline on KotlinPoet plus `metadata-ktx` — a Kotlin facade over the Java MetaObjects core. Ships via the Java reactor (`metaobjects-metadata-ktx`, `metaobjects-codegen-kotlin`). Persistence-conformance runs against Testcontainers Postgres through Exposed.
5151
- [C#](https://github.com/metaobjectsdev/metaobjects/tree/main/server/csharp): loader + canonical serializer + EF Core + ASP.NET codegen + render/verify. The `dotnet meta` tool ships `gen` and the codegen-side `verify` subverbs (`--codegen`, `--templates`); schema migration is Node `meta` only (ADR-0015).

0 commit comments

Comments
 (0)