Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ here.**

## [Unreleased]

## [1.3.0] — 2026-11-11

_npm `1.3.0` (full lockstep across all 14 `@metaobjectsdev/*` publish candidates)._

**`metamodelVersion` moves to `1.3`.** This release adds vocabulary (`field.duration`,
`validator.exactlyOne`, `@constraintName`, `@condition`, `@maxLength` on `field.enum`,
`@sequenceStart`, `@sequenceName`, `@flattenedColumnPrefix`, the `pascal` column rule, and
Expand All @@ -21,6 +25,33 @@ vocabulary only the named ports implement so far, e.g. the `view.*` controls, `[
set grows by the `implementedIn` rows that used to be carved out. A port that reports `1.2` does not
know that vocabulary; upgrade every port together.

### Upgrading from 1.2.0

Each item below is described in full under Added, Changed or Fixed; this list is where to start.

- **`validator.atLeastOne` takes no `@max`.** A model that carries `@max: 1` on an `atLeastOne`
fails to load; a rule meaning "exactly one of these fields" is the new `validator.exactlyOne`.
- **C# durations on the wire.** A `field.duration` is written in each language's standard form
by default (`TimeSpan`'s `"01:30:00"` in C#). A project that wants ISO-8601 (`"PT1H30M"`) in
every port sets `"wire": { "durations": "iso" }` in `.metaobjects/config.json`.
- **Breaking, C#: `ColumnNamingStrategy` and `TableNamingRule` are classes, not enums.** The
built-ins keep their names and `Pascal` is new; code that switched on them or used them as
constants needs the change described under Changed. The new `pascal` column rule is opt-in
(`"naming": { "columns": "pascal" }`).
- **Deprecated: `tsOnly` in `meta types --format json`.** It is still emitted through 1.3.x,
derived from the new `implementedIn`, and is removed in 1.4. Read `implementedIn` instead.
- **A template that names a variable not on its payload now raises at render time** instead of
rendering the variable as empty. Regenerate, and fix the name the error reports.
- **C#, EF Core migrations.** The first `dotnet ef migrations add` after upgrading scaffolds the
indexes and comments the context now declares, and a Postgres context that declares
`@sequenceStart` needs `UseIdentityStartMigrations()` registered after `UseNpgsql(...)`. A
self-hosted codegen runner sets `GenConfig.Dialect`. A nullable enum with `@default` now starts
at its default instead of NULL. See the four C# upgrade notes under Changed.
- **`@sequenceStart` records a start; in 1.3.0 it does not move an existing counter.** A later
release is planned to move a counter that sits below the declared start forward to it, never
backward.
- **`metamodelVersion` is `1.3`.** Upgrade every port together.

### Added

- **Cross-port vocabulary that only some ports implement so far (`implementedIn`).** A registry
Expand Down Expand Up @@ -301,10 +332,12 @@ know that vocabulary; upgrade every port together.
a table rename. On Postgres `meta migrate` creates
`GENERATED BY DEFAULT AS IDENTITY (SEQUENCE NAME "…" START WITH n)`, reads the live sequence
back from the catalog, and alters one whose declared start or name differs in place: a new
start is recorded (`ALTER SEQUENCE … START WITH n`) and the counter is never moved, because live
rows hold the ids it handed out; a new name is a rename. Every port gives `@sequenceStart` this
one meaning, the first value of a fresh sequence; the persistence migration scenario
`sequence-start-change-keeps-counter` pins it on live Postgres. Only what
start is recorded (`ALTER SEQUENCE … START WITH n`), and in 1.3.0 the existing counter is not
moved, because live rows hold the ids it handed out; a new name is a rename. Every port gives
`@sequenceStart` this one meaning, the first value of a fresh sequence; the persistence
migration scenario `sequence-start-change-keeps-counter` pins it on live Postgres. A later
release is planned to strengthen this to a forward-only move (a counter below the declared
start moves up to it, never down), so do not build on the counter staying where it is. Only what
the model declares is compared, on the live, shadow and snapshot paths alike, so a model that
declares neither sees no new change and writes the same SQL and snapshots. Every port
registers both attributes and refuses either without `@generation: increment`
Expand Down
164 changes: 87 additions & 77 deletions bun.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/web/packages/react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@metaobjectsdev/react",
"version": "1.2.0",
"version": "1.3.0",
"description": "React runtime for metaobjects: useEntityForm hook and CurrencyInput component.",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion client/web/packages/runtime-web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@metaobjectsdev/runtime-web",
"version": "1.2.0",
"version": "1.3.0",
"description": "Pure framework-agnostic browser core for metaobjects: currency, filter URL serialization, fetcher contract types.",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion client/web/packages/tanstack/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@metaobjectsdev/tanstack",
"version": "1.2.0",
"version": "1.3.0",
"description": "TanStack runtime for metaobjects: EntityFetcherProvider, EntityGrid, default cell renderers.",
"type": "module",
"main": "./dist/index.js",
Expand Down
5 changes: 3 additions & 2 deletions docs/CONFORMANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,9 @@ are recorded here instead.

**`identity.primary @sequenceStart`** (one semantic in every port): on a fresh
database the identity or sequence begins at `@sequenceStart`; when the start changes on an
existing database, the change sets `START WITH` only. It never `RESTART`s and never moves the
current value, because live rows already hold the ids it has handed out. The port TODOs below
existing database, the change sets `START WITH` only. It never `RESTART`s, and in 1.3 it does
not move the current value, because live rows already hold the ids it has handed out (a later
release is planned to move a counter below the start forward, never backward). The port TODOs below
are tracked in [#544](https://github.com/metaobjectsdev/metaobjects/issues/544).

- *Honoured and pinned:* C#. The generated context carries the start on Npgsql, and the generated
Expand Down
9 changes: 5 additions & 4 deletions docs/features/migrations-and-drift.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,11 @@ from the catalog. A live sequence whose start or name differs from the declarati
in place, never dropped:

- a different start records it (`ALTER SEQUENCE … START WITH n`) and nothing else. It never
restarts the sequence and never moves its current value, because live rows already hold the
ids it handed out: `@sequenceStart` is the first value of a fresh sequence, the same in
every port. The down migration restores the old start value, again without touching the
counter.
restarts the sequence, and in this release it does not move its current value, because live
rows already hold the ids it handed out: `@sequenceStart` is the first value of a fresh
sequence, the same in every port. The down migration restores the old start value, again
without touching the counter. A later release is planned to move a counter that sits below
the declared start forward to it (never backward), so do not rely on the counter staying put.
- a different name renames it (`ALTER SEQUENCE … RENAME TO …`); the down renames it back.

Only what the model declares is compared, on every path (a live database, a shadow database,
Expand Down
18 changes: 9 additions & 9 deletions docs/llms/llms-full.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MetaObjects -- Full Reference Corpus

> Coding agents get context — rules files, memories, MCP servers — and context is advisory: nothing fails when the code stops matching it. MetaObjects gives your agent one typed model of your application — data, API, UI, prompt payloads, and what the software is supposed to do — generates each layer's code from it in TypeScript, Java, Kotlin, C# and Python with no proprietary runtime in the output, and fails your build when generated code, a prompt, or a claimed capability drifts from that model. Your hand-written logic stays yours. Apache 2.0. Shipping at `1.2.0` on npm and `8.2.0` on Maven Central.
> Coding agents get context — rules files, memories, MCP servers — and context is advisory: nothing fails when the code stops matching it. MetaObjects gives your agent one typed model of your application — data, API, UI, prompt payloads, and what the software is supposed to do — generates each layer's code from it in TypeScript, Java, Kotlin, C# and Python with no proprietary runtime in the output, and fails your build when generated code, a prompt, or a claimed capability drifts from that model. Your hand-written logic stays yours. Apache 2.0. Shipping at `1.3.0` on npm and `8.3.0` on Maven Central.

**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.

Expand Down Expand Up @@ -39,7 +39,7 @@ If you are an AI assistant helping someone adopt MetaObjects, do this **first**

1. **Install the port's package:**
- TypeScript / Node: `npm i -D @metaobjectsdev/cli @metaobjectsdev/codegen-ts @metaobjectsdev/metadata typescript @types/better-sqlite3`, then `npm i @metaobjectsdev/runtime-ts drizzle-orm zod fastify better-sqlite3` (SQLite; use `pg` and `@types/pg` for Postgres). The generated files import `drizzle-orm`, `zod`, `fastify` and a driver, and `npm` does not add them for you.
- Java / Kotlin: add `com.metaobjects:metaobjects-metadata`, `com.metaobjects:metaobjects-codegen-spring` (Java) or `com.metaobjects:metaobjects-codegen-kotlin` (Kotlin), and `com.metaobjects:metaobjects-maven-plugin`, all at `8.2.0`.
- Java / Kotlin: add `com.metaobjects:metaobjects-metadata`, `com.metaobjects:metaobjects-codegen-spring` (Java) or `com.metaobjects:metaobjects-codegen-kotlin` (Kotlin), and `com.metaobjects:metaobjects-maven-plugin`, all at `8.3.0`.
- Python: `pip install metaobjects`
- C#: install the MetaObjects .NET tool (invoked as `dotnet meta`).
2. **Run `meta init`** (the Node `meta` CLI). It works in any project that has Node — including a JVM or Python project with a TypeScript frontend. It scaffolds a slim always-on `.metaobjects/AGENTS.md` + `.metaobjects/CLAUDE.md` (auto-wired via an `@.metaobjects/AGENTS.md` import line into the project's root `CLAUDE.md`/`AGENTS.md`, so it loads automatically) plus six `metaobjects-*` Claude Code skills under `.claude/skills/`, carrying only the project's language reference fragments. Re-run `meta init --refresh-docs` to update the agent docs after a CLI upgrade. (The Node `meta` CLI is the single agent-context scaffolder for every backend, by design — ADR-0033; the JVM/Python/C# CLIs deliberately redirect to it. For a non-Node project, scaffold just the agent context with `npx meta agent-docs --server <lang>`.)
Expand Down Expand Up @@ -125,11 +125,11 @@ TypeScript, Java, Kotlin and C# projects publish; TypeScript, Python, Java, Kotl

| Language | Status | Notes |
|---|---|---|
| TypeScript | Reference implementation, npm `1.2.0` | All six pillars, and the only port that prints the requirements authoring lint and publishes shared models. 2500+ tests passing. Owns the canonical schema-migration toolchain used by every port (ADR-0015). Bun-first dev. |
| Java | Maven Central `8.2.0` | Spring REST + DTO + repository-interface codegen, OMDB runtime persistence (pure data-access) with Spring-tx. Fully green across all conformance corpora. |
| Kotlin | Maven Central `8.2.0` | KotlinPoet codegen + Exposed runtime + `metadata-ktx` facade. Ships via the Java reactor. |
| C# | NuGet `1.2.0` (.NET tool) | Loader + canonical serializer + EF Core + ASP.NET codegen + render/verify. `dotnet meta` tool. |
| Python | PyPI `1.2.0` | Loader + serializer + render + verify + codegen + `ObjectManager` runtime. Fully green across all corpora. |
| TypeScript | Reference implementation, npm `1.3.0` | All six pillars, and the only port that prints the requirements authoring lint and publishes shared models. 2500+ tests passing. Owns the canonical schema-migration toolchain used by every port (ADR-0015). Bun-first dev. |
| Java | Maven Central `8.3.0` | Spring REST + DTO + repository-interface codegen, OMDB runtime persistence (pure data-access) with Spring-tx. Fully green across all conformance corpora. |
| Kotlin | Maven Central `8.3.0` | KotlinPoet codegen + Exposed runtime + `metadata-ktx` facade. Ships via the Java reactor. |
| C# | NuGet `1.3.0` (.NET tool) | Loader + canonical serializer + EF Core + ASP.NET codegen + render/verify. `dotnet meta` tool. |
| Python | PyPI `1.3.0` | Loader + serializer + render + verify + codegen + `ObjectManager` runtime. Fully green across all corpora. |

Conformance fixtures live at [`fixtures/`](https://github.com/metaobjectsdev/metaobjects/tree/main/fixtures). Every port runs the shared corpus byte-identically: metamodel (`conformance/`, 314 fixtures), render, persistence (Testcontainers Postgres, with an `op: roundtrip` gate so every `field.*` subtype write+read round-trips on every port), api-contract (41 scenarios — 26 core plus TPH / M:N / jsonb / write-through — 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.

Expand Down Expand Up @@ -182,7 +182,7 @@ Universal web client (`client/web/packages/`): `@metaobjectsdev/runtime-web`, `@

## Java / Kotlin Maven coordinates

All published to Maven Central under `com.metaobjects:*` at `8.2.0`:
All published to Maven Central under `com.metaobjects:*` at `8.3.0`:

- `metaobjects-metadata`, `metaobjects-metadata-ktx`
- `metaobjects-codegen-base`, `metaobjects-codegen-mustache`, `metaobjects-codegen-spring`, `metaobjects-codegen-kotlin`, `metaobjects-codegen-plantuml`
Expand Down Expand Up @@ -219,7 +219,7 @@ Project marker directory: `.metaobjects/`.

## Quickstart (Java / Kotlin)

Add the Maven coordinates above at `8.2.0`. Run codegen with `mvn metaobjects:generate` and codegen-drift checks with `mvn metaobjects:verify`. Configure generators (including Kotlin generators, which run through the same goal) on the `metaobjects-maven-plugin`. See [`server/java/`](https://github.com/metaobjectsdev/metaobjects/tree/main/server/java) and [`server/java/codegen-kotlin/README.md`](https://github.com/metaobjectsdev/metaobjects/tree/main/server/java/codegen-kotlin).
Add the Maven coordinates above at `8.3.0`. Run codegen with `mvn metaobjects:generate` and codegen-drift checks with `mvn metaobjects:verify`. Configure generators (including Kotlin generators, which run through the same goal) on the `metaobjects-maven-plugin`. See [`server/java/`](https://github.com/metaobjectsdev/metaobjects/tree/main/server/java) and [`server/java/codegen-kotlin/README.md`](https://github.com/metaobjectsdev/metaobjects/tree/main/server/java/codegen-kotlin).

---

Expand Down
Loading
Loading