Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
62d908d
feat(agent-context): deploy all language references; agent picks (rob…
dmealing Jun 23, 2026
5c2e933
docs(agent-context): add Python codegen reference (closes the python.…
dmealing Jun 23, 2026
e26840e
docs(spec): record deploy-all references override (supersedes stack-s…
dmealing Jun 23, 2026
e47d54c
docs(plan): Node meta CLI -> axi + TOON implementation plan (Plan 2 o…
dmealing Jun 23, 2026
25a1cd9
feat(cli): add output-format selector (TTY-aware) + TOON encode wrapper
dmealing Jun 23, 2026
a11ab3e
feat(cli): TOON+JSON gen formatters with axi aggregates + next-step help
dmealing Jun 23, 2026
7a4ce16
feat(cli): TOON+JSON migrate formatters with axi aggregates + next-st…
dmealing Jun 23, 2026
6e6de30
feat(cli): --format flag (TTY-aware) routes gen/migrate through TOON/…
dmealing Jun 23, 2026
81055cb
test(cli): update init-scaffold tests for deploy-all references (Plan…
dmealing Jun 23, 2026
261e61e
fix(cli): axi-conformant meta migrate (--help, idempotent, declared l…
dmealing Jun 23, 2026
1593c16
fix(cli): format-aware structured migrate errors on stdout (+ yarn pm…
dmealing Jun 23, 2026
154253c
feat(cli): per-subcommand --help, content-first no-args, 0/1/2 exit c…
dmealing Jun 23, 2026
6a340e1
docs(agent-context): document --format + discoverable migrate baseline
dmealing Jun 23, 2026
a5c6b1c
fix(cli): restore text-mode baseline hint + drop help[] refs to non-e…
dmealing Jun 23, 2026
7002ac1
no-mistakes(review): emit migrate branch errors on stdout; reject inv…
dmealing Jun 23, 2026
f8fd2d5
no-mistakes(review): make migrate structured summary reflect written-…
dmealing Jun 23, 2026
1eee75a
no-mistakes(review): surface applied ledger files in migrate summary …
dmealing Jun 23, 2026
a924956
no-mistakes(review): make postgres missing-dep hint package-manager-a…
dmealing Jun 23, 2026
eb9c2da
no-mistakes(document): sync CLI README with --format flag, per-comman…
dmealing Jun 23, 2026
0c80883
fix(agent-context): deploy-all references in the C# + Python assemble…
dmealing Jun 23, 2026
9a30089
docs(spec): single agent-context assembler (collapse per-port re-impl…
dmealing Jun 24, 2026
d4bd6e6
docs(plan): single agent-context assembler implementation plan (delet…
dmealing Jun 24, 2026
ee48807
feat(cli): add 'meta agent-docs --server <lang>' alias (canonical sca…
dmealing Jun 24, 2026
d9a9cc9
refactor(python): drop native agent-context assembler + embedding; ag…
dmealing Jun 24, 2026
b2a0e72
refactor(java): drop native agent-context assembler + classpath embed…
dmealing Jun 24, 2026
0a04544
fix(java): delete dead agent-context scaffold-write path (plan/Assemb…
dmealing Jun 24, 2026
c27036f
refactor(csharp): drop native agent-context assembler + embedded reso…
dmealing Jun 24, 2026
c70a982
docs(adr): ADR-0033 single agent-context assembler; redirect non-Node…
dmealing Jun 24, 2026
fa92f4d
fix(agent-context): ADR stub stream stdout→stderr; Python staleness n…
dmealing Jun 24, 2026
25ee235
no-mistakes(document): sync docs to single agent-context assembler (A…
dmealing Jun 24, 2026
c67e80a
no-mistakes(lint): remove orphaned Manifest import in Python CLI
dmealing Jun 24, 2026
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
76 changes: 76 additions & 0 deletions agent-context/skills/metaobjects-codegen/references/python.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Python codegen specifics

The Python port targets FastAPI consumers. Codegen runs through the **`metaobjects`
console-script** (`pip install metaobjects`). As on every port, schema migrations
are **Node-`meta`-owned** (ADR-0015): `meta migrate` / `meta verify --db` run
through the Node `meta` tool — the Python CLI has **no `migrate` subcommand** and
`metaobjects verify --db` is rejected. Everything below is `metaobjects`.

## Install

```bash
pip install metaobjects # provides the `metaobjects` console-script
# consumer runtime deps (you provide these — codegen does not pin them):
pip install "pydantic>=2" fastapi
```

## Run

```bash
metaobjects gen ./metadata --out ./generated [--package <pkg>]
metaobjects gen ./metadata --out ./generated --generators entity,routes,filter-allowlist
metaobjects verify ./metadata --codegen # codegen-drift gate (regenerate into a
# temp dir + diff vs the committed --out tree)
```

`metaobjects verify` defaults to `--codegen` (the codegen-output drift gate; it shares
the exact `gen` code path so the two can't diverge). `--templates` is the prompt/template
drift gate (see the prompts reference). Schema migration + live-DB drift are **not**
`metaobjects` — they run through the Node `meta` tool (see the migration reference).

## Generators

Wire generators by their stable name (`--generators <names>`), or run the default set.
Output lands under `--out` (with the `@generated` guard header). Metadata is the same
canonical JSON every port reads (fused-key form, `source.rdb` + `@table`, `@column` for
a renamed physical column).

| Stable name | Output |
|---|---|
| `entity` | one **Pydantic model** per `object.entity` / projection (the `entity-model` generator): typed fields from the metadata, nullability from `@required`, `@maxLength`/validators, enum fields → a Python `Enum`. This is the typed data model. |
| `routes` | a **FastAPI `APIRouter`** per writable entity (`source.rdb @kind="table"`) on the cross-port REST contract (`?filter[field][op]=`, `?sort=field:asc`, `?limit`/`?offset`, `?withCount=1` envelope, 400/404 envelopes). The router declares a repository **`Protocol`** you implement and inject. |
| `filter-allowlist` | per-entity filter allowlist (FR-009 — the server-side field+operator allowlist the routes validate against). |
| `payload` / `output-parser` / `output-prompt` / `extractor` / `render-helper` / `trace-helper` | the `template.output` prompt-pillar artifacts — see the **prompts** reference. |
| `template` | the generic Mustache `template` primitive. |

## No ORM — you own persistence (unlike the C# port)

Python codegen emits the **Pydantic models + the FastAPI routers**, but **no ORM /
persistence layer and no runnable server**. Two things you hand-write:

1. **The repository** — each generated router depends on a repository `Protocol`;
implement it against your datastore (SQLAlchemy / asyncpg) and inject it.
2. **The app entrypoint** — there is no generated `main.py`. Create one and mount the
routers:
```python
from fastapi import FastAPI
from generated.author_router import router as author_router
app = FastAPI()
app.include_router(author_router)
```

## Known gaps (current — may require a hand-edit)

- **Single-field, `int` PKs only.** The generated router/repository assume a single
`int` primary key (`id: int`). Non-`int` single-field PKs and composite PKs need a
hand-edit until specified.
- **DTO = `dict[str, Any]`.** Request bodies for `POST`/`PATCH`/`PUT` are typed
`dto: dict[str, Any]` and responses return `Any`; the repository `Protocol` uses
`Any` for the row type. The typed Pydantic model from the `entity` generator exists —
you can tighten the router signatures to it by hand.

## Re-scaffold this context

`metaobjects agent-docs --server python [--out <dir>]` (re)scaffolds the slim always-on
Markdown + these `metaobjects-*` skills into the project — the Python tool bundles the
agent-context tree, so a Python consumer needs no Node `meta`.
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ Generated files carry an `@generated by @metaobjectsdev/codegen-ts` header; the
runner overwrites those and refuses to touch files without it. Hand-customizations
that metadata can't express live in sibling `<Entity>.extra.ts` files.

**Output format:** `meta gen` (and the CLI generally) is TTY-aware — human-readable
text on a terminal, TOON on a pipe or agent. Override with `--format toon|json|text`.
TOON is the structured default for agents; `--format json` is also available.

## Multiple output targets

A `targets: { web: { outDir }, api: { outDir } }` registry plus a per-generator
Expand Down
37 changes: 37 additions & 0 deletions agent-context/skills/metaobjects-verify/references/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,45 @@ npm install --save-dev @metaobjectsdev/cli @metaobjectsdev/migrate-ts
You point the tool at the **same database your server connects to** — its
connection is independent of your runtime tier.

## Output format

`meta migrate` (and the CLI generally) is TTY-aware: when stdout is a terminal it
emits human-readable text; when piped to an agent or CI system it defaults to TOON
(a compact, unambiguous machine-readable format). Override with `--format`:

```bash
meta migrate ... --format toon # TOON (machine-readable, the pipe/agent default)
meta migrate ... --format json # JSON
meta migrate ... --format text # human-readable text (the TTY default)
```

Structured errors and next-step hints are also emitted on stdout (not stderr) in the
active format, so callers can parse them without scraping stderr.

## The workflow

### Fresh database: baseline first

The default `meta migrate` path is **offline** — it diffs metadata against a
committed schema snapshot rather than the live DB. On a fresh database there is no
snapshot yet; run the `baseline` step once before the first migration generate:

```bash
meta migrate baseline --dialect sqlite # seed snapshot from metadata (no DB needed)
meta migrate baseline --dialect postgres # same for Postgres
meta migrate baseline --from-db --db postgresql://... --dialect postgres
# alternative: seed from live DB (for existing schemas)
```

`baseline` writes a reference snapshot to `.metaobjects/migrations/` and exits
without emitting any SQL. After this, `meta migrate --dialect <d> --slug <name>`
operates offline against that snapshot.

If you run `meta migrate` before baselining, the CLI surfaces a structured
next-step hint pointing to the exact `baseline` command.

### Generating a migration

1. **Generate a migration** by diffing metadata vs the prior state (the live DB or a
committed snapshot). The engine emits paired `up.sql` + `down.sql`:

Expand Down
7 changes: 4 additions & 3 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 11 additions & 17 deletions docs/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ Four packages, version-locked at the C# port version (currently `0.11.1`):
| `MetaObjects` | Loader + canonical serializer |
| `MetaObjects.Render` | Mustache render + payload-VO + `verify` |
| `MetaObjects.Codegen` | EF Core + ASP.NET codegen + the runtime filter/dispatch helpers generated code references |
| `MetaObjects.Cli` | The `dotnet meta` .NET tool (`gen` / `verify` / `agent-docs`) |
| `MetaObjects.Cli` | The `dotnet meta` .NET tool (`gen` / `verify`; `agent-docs` is a redirect stub to the Node `meta` CLI) |

Shared package metadata lives in [`server/csharp/Directory.Build.props`](../server/csharp/Directory.Build.props);
per-package `PackageId`/`Title`/`Description` live in each `.csproj`. Test/integration projects set
Expand Down Expand Up @@ -220,15 +220,11 @@ lock the repo/owner IDs against resurrection attacks.)
*deprecate*. So validate the packed `.nupkg` locally before triggering the workflow.
3. **Bump the version in `Directory.Build.props`** (`<Version>`), not per-project. The
workflow can also override per-run via the `version` dispatch input (`-p:Version=`).
4. **Don't re-add `Pack`/`PackagePath` to the CLI's `agent-context/` Content item.** `PackAsTool`
already bundles build output (the files arrive via `CopyToOutputDirectory`) into
`tools/net8.0/any/`; an explicit `PackagePath` double-adds every file → **NU5118**, which is
fatal under this repo's `TreatWarningsAsErrors`. The item is deliberately `Pack=false`.
5. **The temp key is single-use and ~1 h.** The workflow requests it immediately before push — don't
4. **The temp key is single-use and ~1 h.** The workflow requests it immediately before push — don't
move the `NuGet/login` step earlier.
6. **The policy is bound to the org + repo + workflow *filename*.** Renaming `publish-csharp.yml`, or
5. **The policy is bound to the org + repo + workflow *filename*.** Renaming `publish-csharp.yml`, or
the policy owner leaving/locking the `metaobjects` org, makes the policy inactive until fixed.
7. **Source Link + symbols are on** (`PublishRepositoryUrl`, `EmbedUntrackedSources`, `snupkg`); CI
6. **Source Link + symbols are on** (`PublishRepositoryUrl`, `EmbedUntrackedSources`, `snupkg`); CI
sets `ContinuousIntegrationBuild` for deterministic builds. No action needed — just don't strip them.

## Procedure
Expand Down Expand Up @@ -283,16 +279,14 @@ subsequent releases keyless.)

## Gotchas (the non-obvious ones)

1. **The `agent-context/` bundle is vendored by a build hook, not a parent-path include.**
`hatch_build.py` copies the repo-root `agent-context/` into
`src/metaobjects/agent_context/_content` at build time, and `[tool.hatch.build]
artifacts` forces it into **both** sdist and wheel. Do **not** revert to a
`force-include` of `../../agent-context` — that builds a direct wheel but breaks
`uv build` (sdist → wheel), because the parent path is absent when building from the sdist.
2. **PyPI versions are immutable** (like npm/NuGet). You can't re-upload a version — only
1. **PyPI versions are immutable** (like npm/NuGet). You can't re-upload a version — only
yank. Validate locally first (below).
3. **Bump the version in `pyproject.toml`** (`[project].version`).
4. **The wheel is pure-Python/universal** (`py3-none-any`) — one wheel serves every platform.
2. **Bump the version in `pyproject.toml`** (`[project].version`).
3. **The wheel is pure-Python/universal** (`py3-none-any`) — one wheel serves every platform.

(No agent-context content is vendored into the wheel anymore — scaffolding moved to the
Node `meta agent-docs` CLI, so `hatch_build.py` is a no-op. Don't re-add a
`force-include` of `../../agent-context`.)

## Procedure

Expand Down
20 changes: 20 additions & 0 deletions docs/features/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ command surface splits in two:
| Capability | Tool | Invocation | Notes |
|---|---|---|---|
| Project scaffold (`init`) | Node `meta` | `meta init` | TS projects |
| **Agent-context scaffold** (`agent-docs`) | **Node `meta`** | `npx meta agent-docs --server <lang>` | **any backend** — single assembler (ADR-0033); non-Node CLIs redirect here |
| **Schema migrate** | **Node `meta`** | `meta migrate` | **any backend** — schema is Node-only (ADR-0015) |
| **Schema drift** (`verify --db`) | **Node `meta`** | `meta verify --db` | **any backend** — live-DB drift, Node-only |
| **Codegen drift** (`verify --codegen`) | **Node `meta`** | `meta verify --codegen` | TS reference (ADR-0021 D2) — regen-to-temp + diff committed output |
Expand Down Expand Up @@ -90,6 +91,25 @@ Java, Python, and Kotlin command surfaces are **codegen only** (`gen` + codegen
goals and the C#/Python migrate surfaces were removed in the schema-authority
consolidation; the only schema entry point anywhere is the Node `meta`.

## Agent-context scaffold is Node-only — by design

The `.metaobjects/AGENTS.md`/`CLAUDE.md` always-on files and the
`.claude/skills/metaobjects-*/` reference tree are assembled by **one** tool: the
Node `meta agent-docs` command. Per [ADR-0033](../../spec/decisions/ADR-0033-single-agent-context-assembler.md)
the per-port native assemblers (Python/Java/C#) and their byte-identity conformance
gates were removed — that content is effectively one static artifact, and every port
already needs the Node `meta` CLI or its binary for schema ops (ADR-0015).

```bash
npx meta agent-docs --server <lang> # csharp | java | kotlin | python | node
```

The C#, Java/Kotlin, and Python CLIs keep a **non-executing `agent-docs` pointer
stub** that prints `agent-context scaffolding moved to the meta CLI — run: npx meta
agent-docs --server <lang>` to stderr and exits non-zero. The **live staleness check**
in `gen`/`verify` stays per-port (it only *reads* the scaffold to nudge when it drifts);
its message now points at `npx meta agent-docs --server <lang>`.

## Running Kotlin codegen via Maven

`codegen-kotlin`'s generators extend `MultiFileDirectGeneratorBase` — the same
Expand Down
2 changes: 1 addition & 1 deletion docs/llms/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ If you are an AI assistant helping someone adopt MetaObjects, do this **first**
- 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 `7.4.1`.
- 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 five `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. (Native per-port scaffold commands for JVM/Python/C#-only projects are forthcoming; today, run the Node `meta init` regardless of backend.)
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 five `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>`.)
3. **Load `.metaobjects/AGENTS.md` and the `.claude/skills/metaobjects-*` skills.** They teach metadata authoring, codegen, runtime/UI, prompt construction, and `verify` — for this project's exact stack and version.

This file is the short corpus; the deep, version-matched how-to is the scaffolded local context.
Expand Down
2 changes: 1 addition & 1 deletion docs/llms/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ If you are an AI assistant helping someone adopt MetaObjects in their project, d
- a slim always-on `.metaobjects/AGENTS.md` + `.metaobjects/CLAUDE.md` agent context, **auto-wired into the project's root `CLAUDE.md`/`AGENTS.md`** (an `@.metaobjects/AGENTS.md` import line) so it loads automatically; and
- five `metaobjects-*` Claude Code skills under `.claude/skills/`, carrying only the language reference fragments for the project's stack.

Re-run `meta init --refresh-docs` to update the scaffolded agent docs after a CLI upgrade. (Native per-port scaffold commands for JVM/Python/C#-only projects are forthcoming; today, run the Node `meta init` regardless of backend language.)
Re-run `meta init --refresh-docs` to update the scaffolded 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. Run `meta init` regardless of backend language, or `npx meta agent-docs --server <lang>` to scaffold just the agent context.)

3. **After scaffolding, load `.metaobjects/AGENTS.md` and the `.claude/skills/metaobjects-*` skills.** They teach metadata authoring, codegen, runtime/UI, prompt construction, and `verify` — for this project's exact stack and version.

Expand Down
Loading
Loading