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 bc2e9b1
Browse filesBrowse the repository at this point in the historyBrowse files
docs(agent-context): correct the migrate guidance shipped to adopters
The `metaobjects-verify` skill — scaffolded into every adopter repo by
`meta init` and mirrored into llms.txt — told agents to run
`meta migrate baseline --dialect sqlite` on a **fresh** database. That is the
exact greenfield trap 0.20.1 refused at the CLI: an offline baseline derives the
"existing" snapshot from the metadata, recording the target shape as already
applied, so no table is ever created, every later migrate reports `no changes`,
and the failure surfaces later at the API layer as `no such table`. An agent
following the shipped skill would have walked a newcomer straight into it.
Corrected to the working greenfield path (`--from-db … --slug init --apply`),
with `baseline --from-db` kept for its real use — adopting a database that
already has its schema. The skill also claimed the no-snapshot hint points at
`baseline`; it points at `--from-db … --apply`.
Also fixes a second inaccuracy in the same family across the skill, its
reference, and both llms files: `meta migrate --db <url> --slug <name>` was
described as "diff metadata vs the live DB", but without `--from-db`/`--apply`
that is the OFFLINE path and `--db` is ignored. Every example now passes
`--dialect` — which selects the diff pipeline, not just the SQL flavor — and
distinguishes the offline, live (`--from-db`) and replay (`apply-pending`) forms.
Edited at the canonical `agent-context/` source; the sdk bundle was reproduced
with `bundle-agent-context.mjs` and the four `agent-context-conformance`
goldens regenerated.
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 --db <url> --slug <name>` — diff metadata vs the live DB and emit migration SQL files under `.metaobjects/migrations`. 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` 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.
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
+10-3Lines changed: 10 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -147,11 +147,18 @@ What this means in practice:
147
147
it. You point it at the same database your server connects to:
148
148
149
149
```
150
-
meta migrate --db postgresql://... --slug initial # emit migration SQL
151
-
meta migrate --db postgresql://... --apply # apply pending migrations
152
-
meta migrate --dry-run # preview without writing
150
+
meta migrate --from-db --db postgresql://... --dialect postgres --slug init --apply
Copy file name to clipboardExpand all lines: fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.claude/skills/metaobjects-verify/references/migration.md
+34-15Lines changed: 34 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -40,37 +40,53 @@ active format, so callers can parse them without scraping stderr.
40
40
41
41
## The workflow
42
42
43
-
### Fresh database: baseline first
43
+
### Fresh database: create the tables with `--from-db … --apply`
44
44
45
45
The default `meta migrate` path is **offline** — it diffs metadata against a
46
46
committed schema snapshot rather than the live DB. On a fresh database there is no
47
-
snapshot yet; run the `baseline` step once before the first migration generate:
47
+
snapshot yet, so the first command introspects the (empty) database instead:
48
48
49
49
```bash
50
-
meta migrate baseline --dialect sqlite # seed snapshot from metadata (no DB needed)
51
-
meta migrate baseline --dialect postgres # same for Postgres
52
-
meta migrate baseline --from-db --db postgresql://... --dialect postgres
53
-
# alternative: seed from live DB (for existing schemas)
50
+
meta migrate --from-db --db file:dev.sqlite --dialect sqlite --slug init --apply
54
51
```
55
52
56
-
`baseline` writes a reference snapshot to `.metaobjects/migrations/` and exits
57
-
without emitting any SQL. After this, `meta migrate --dialect <d> --slug <name>`
58
-
operates offline against that snapshot.
53
+
That diffs metadata against what is *actually* in the database (nothing), emits the
54
+
full `CREATE TABLE` set, applies it, and records the resulting snapshot — so the
55
+
everyday offline flow works immediately afterwards, with no extra step.
56
+
57
+
**Do NOT reach for `meta migrate baseline` on a database that does not exist yet.**
58
+
An offline baseline derives the "existing" snapshot from your *metadata*, recording
59
+
your entities' target shape as already applied: no table is ever created, every
60
+
later `meta migrate` reports `no changes` (exit 0), and the failure only surfaces at
61
+
the API layer as `no such table`. The CLI now refuses an offline baseline when it can
62
+
prove the target `--db` is empty, and its no-snapshot hint routes to the `--from-db`
63
+
command above.
59
64
60
-
If you run `meta migrate` before baselining, the CLI surfaces a structured
61
-
next-step hint pointing to the exact `baseline` command.
65
+
`baseline` is for the other case — **adopting** metadata onto a database that already
66
+
has its schema (a pre-existing, non-MetaObjects setup), where you want to record
67
+
current state without emitting any DDL:
68
+
69
+
```bash
70
+
meta migrate baseline --from-db --db postgresql://... --dialect postgres
71
+
```
62
72
63
73
### Generating a migration
64
74
65
75
1.**Generate a migration** by diffing metadata vs the prior state (the live DB or a
66
76
committed snapshot). The engine emits paired `up.sql` + `down.sql`:
67
77
68
78
```bash
69
-
meta migrate --db postgresql://... # emit up.sql + down.sql
70
-
meta migrate --db postgresql://... --slug initial # name the migration
71
-
meta migrate --dry-run # preview without writing
79
+
meta migrate --dialect postgres --slug add-user-shipping # offline: diff vs the committed snapshot
80
+
meta migrate --dialect postgres --slug add-user-shipping --dry-run # preview without writing
81
+
meta migrate --from-db --db postgresql://... --dialect postgres --slug add-user-shipping
82
+
# diff vs the LIVE database instead
72
83
```
73
84
85
+
`--dialect` is always required and is load-bearing — it selects the diff
86
+
pipeline, not just the SQL flavor. The default path is offline (`--db` is
87
+
ignored without `--from-db` or `--apply`); pass `--from-db` when you want the
88
+
diff taken against the live database.
89
+
74
90
2.**Review the SQL.** Read the emitted `up.sql` (forward) and `down.sql`
75
91
(rollback) before applying. Destructive changes (drop column / drop table) are
76
92
opt-in — the engine blocks them unless explicitly allowed, and routes ambiguous
@@ -80,7 +96,10 @@ next-step hint pointing to the exact `baseline` command.
80
96
a ledger table:
81
97
82
98
```bash
83
-
meta migrate --db postgresql://... --apply # run pending up.sql
99
+
meta migrate --dialect postgres --slug add-user-shipping --db postgresql://... --apply
100
+
# generate ...and apply it
101
+
meta migrate apply-pending --db postgresql://... --dialect postgres
102
+
# replay committed migrations, no diff (fresh DB / CI)
84
103
meta migrate --db postgresql://... --rollback <target># run down.sql for migrations newer than <target>
85
104
meta migrate --db postgresql://... --rollback ""# roll back everything (empty target)
0 commit comments