You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 22c1296
Browse filesBrowse the repository at this point in the historyBrowse files
fix(migrate): only advance the snapshot when a migration was written
Independent review of the preceding three commits found the new guard
(`!dryRun && exitCode === 0 && !applyFailed`) also fires on the zero-change
branch, where the live path writes nothing. Reproduced on a real sqlite engine:
a database already matching its metadata but reached WITHOUT any committed
migration — a restored dump, hand-run DDL, an adopted DB — turned a plain
`meta migrate --from-db` drift check into an implicit baseline. It recorded the
target schema as already-applied with zero CREATE TABLE anywhere, so the offline
path reported `no changes` permanently and `apply-pending` provisioned an empty
database on CI. That is the 0.20.1 greenfield-baseline trap re-entered through a
different door.
The snapshot means "the schema the committed migrations land you in", so it now
advances exactly when this run wrote one — the rule runOfflineGenerate already
follows, returning on `no changes` before writing. Both motivating scenarios
(greenfield --from-db --apply, and --apply without --from-db) always write files,
so neither regresses; re-verified end to end in a cold project.
Also from the review:
- The snapshot carries the engine version introspection just captured. Writing
bare `expected` dropped `meta.sqliteVersion`, which `emit` reads to choose
native ALTER vs recreate-and-copy; on SQLite < 3.35 a later offline migration
would have been un-appliable.
- A writeSnapshot failure is reported as itself rather than surfacing as
"unexpected error" after the migration already applied.
- The post-write hint said "apply with `meta migrate --db <url> --apply`",
which re-runs the diff: it demands --slug again (exit 2) and, if given one,
emits a second migration with the same DDL. Now `meta migrate apply-pending
--db <url>` (#242), verified by running the hint verbatim.
- Two stale `258` fixture counts survived in the files the refresh targeted
(README.md, spec/roadmap.md); both are 260.
- "`--dialect` is always required" was false and contradicted the CLI's own
--help: it is required offline and on `baseline`, and auto-detected from the
URL scheme with `--db`. Corrected in the skill, its reference and both llms
files.
- CHANGELOG [Unreleased] now states its registry scope (npm · PyPI · NuGet;
Maven has no changed product file) and covers the agent-context fix, which
ships to adopters in three of those packages.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S3msoGxjRMwx94PhKSLDuE
Copy file name to clipboardExpand all lines: docs/llms/llms.txt
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -69,7 +69,7 @@ MetaObjects deliberately does **not** ship one universal binary. Schema operatio
69
69
- `meta init` — scaffold `metaobjects/`, `.metaobjects/`, and `metaobjects.config.ts`, **plus** the agent context: a slim `.metaobjects/AGENTS.md` + `CLAUDE.md` (auto-wired into the project's root `CLAUDE.md`/`AGENTS.md`) and six `metaobjects-*` Claude Code skills under `.claude/skills/` scoped to the project's stack. `meta init --refresh-docs` updates only the agent docs.
70
70
- `meta gen [<entity>...]` — TS codegen from entities defined under `metaobjects/`. Supports `--dry-run` and `--watch`. Generators (`entityFile()`, `queriesFile()`, `routesFile()`, `formFile()`, `tanstackQuery()`, `tanstackGrid()`, `barrel()`) come from `@metaobjectsdev/codegen-ts/generators` (and per-framework siblings) and are wired in `metaobjects.config.ts`. Per-port codegen runs in that port's own build tool: `mvn metaobjects:generate` (Java/Kotlin), `dotnet meta gen` (C#), `metaobjects gen` (Python).
- `meta migrate --dialect <d> --slug <name>` — diff metadata vs the committed schema snapshot and emit migration SQL files under `.metaobjects/migrations`; add `--db <url> --apply` to run them. `--dialect` is always required and selects the diff pipeline, not just the SQL flavor. On a brand-new database the first command is `meta migrate --from-db --db <url> --dialect <d> --slug init --apply` (diff against the empty database, emit `CREATE TABLE`, apply, record the snapshot) — **not** `meta migrate baseline`, which is for adopting a database that already has its schema. `meta migrate apply-pending --db <url> --dialect <d>` replays committed migrations with no diff (fresh DB / CI). Supports SQLite (`file:`, `libsql:`), Postgres (`postgres:`, `postgresql:`), and Cloudflare D1 (TS only). `--dry-run` prints SQL to stdout. **Schema migration is owned by the Node `meta` CLI (ADR-0015) and used by every port regardless of backend language** — it is shipped as a standalone binary, so a JVM/Python/C# project needs no per-language migrate engine. There is no Maven, .NET, or Python migrate command.
72
+
- `meta migrate --dialect <d> --slug <name>` — diff metadata vs the committed schema snapshot and emit migration SQL files under `.metaobjects/migrations`; add `--db <url> --apply` to run them. `--dialect` selects the diff pipeline, not just the SQL flavor — required offline and on `baseline`, auto-detected from the URL scheme when `--db` is given. On a brand-new database the first command is `meta migrate --from-db --db <url> --dialect <d> --slug init --apply` (diff against the empty database, emit `CREATE TABLE`, apply, record the snapshot) — **not** `meta migrate baseline`, which is for adopting a database that already has its schema. `meta migrate apply-pending --db <url> --dialect <d>` replays committed migrations with no diff (fresh DB / CI). Supports SQLite (`file:`, `libsql:`), Postgres (`postgres:`, `postgresql:`), and Cloudflare D1 (TS only). `--dry-run` prints SQL to stdout. **Schema migration is owned by the Node `meta` CLI (ADR-0015) and used by every port regardless of backend language** — it is shipped as a standalone binary, so a JVM/Python/C# project needs no per-language migrate engine. There is no Maven, .NET, or Python migrate command.
73
73
- `meta export [--out <file>]` — flatten loaded metadata to one canonical JSON artifact.
Copy file name to clipboardExpand all lines: fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.claude/skills/metaobjects-verify/SKILL.md
+5-3Lines changed: 5 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -155,9 +155,11 @@ What this means in practice:
155
155
meta migrate --dialect postgres --slug add-user-shipping --dry-run # preview without writing
156
156
```
157
157
158
-
`--dialect` is always required — it selects the diff pipeline, not just the SQL
159
-
flavor. Do **not** run `meta migrate baseline` on a database that does not exist
160
-
yet; see `references/migration.md`.
158
+
Always pass `--dialect` — it selects the diff pipeline, not just the SQL flavor.
159
+
It is *required* on the offline path and on `baseline`; with `--db` the CLI can
160
+
auto-detect it from the URL scheme, but being explicit keeps the two paths
161
+
reading the same. Do **not** run `meta migrate baseline` on a database that does
162
+
not exist yet; see `references/migration.md`.
161
163
162
164
- Dialects: `postgres` (default), `sqlite`, and `d1` (Cloudflare D1, TS-only).
163
165
- The JVM and Python ports have **no** migration command of their own — their
Copy file name to clipboardExpand all lines: fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.claude/skills/metaobjects-verify/references/migration.md
Copy file name to clipboardExpand all lines: fixtures/agent-context-conformance/java-react/expected/.claude/skills/metaobjects-verify/references/migration.md
0 commit comments