Skip to content

feat(cli): agent-friendly meta CLI with --format/TOON output and deploy-all agent-context references#71

Merged
dmealing merged 31 commits into
mainfrom
metaobjects-cli-axi-and-deploys
Jun 24, 2026
Merged

feat(cli): agent-friendly meta CLI with --format/TOON output and deploy-all agent-context references#71
dmealing merged 31 commits into
mainfrom
metaobjects-cli-axi-and-deploys

Conversation

@dmealing

Copy link
Copy Markdown
Member

Intent

Two-part metaobjects product fix on this branch (Plan 1 + Plan 2 of a planned 5; Node CLI first, Python/C#/Maven CLIs are intentionally NOT touched yet). PLAN 1 — agent-context deploy-all: change the skill-reference assembler (sdk/src/agent-context/assemble.ts) to deploy ALL per-language references/.md fragments instead of only the detected stack's. This is a deliberate override of the prior stack-selective design: stack detection silently found nothing for monorepos (the metaobjects repo itself had servers:[]), starving agents of all language guidance; deploy-all is robust (the agent reads the reference matching its stack; SKILL.md points to them). Also authored the missing metaobjects-codegen/references/python.md (the only language without a codegen reference), added a regen script for the conformance goldens, and updated SDK + CLI init-scaffold tests to assert all-languages-present (not weakened). PLAN 2 — make the Node 'meta' CLI agent-friendly per the axi standard (axi.md) with TOON output: add --format <toon|json|text> with a deliberately TTY-aware default (human-readable text on a TTY, token-efficient TOON on a pipe/agent — intentionally NOT always-TOON, to avoid breaking humans); TOON+JSON formatters for gen and migrate sharing one data-shape function each, with axi aggregates/totals + next-step help[] lines; axi-conformant 'meta migrate' (promote @libsql/kysely-libsql from optional peer to a real dependency since sqlite migrate hard-requires it, per-subcommand --help, idempotent no-op-on-no-changes, a discoverable 'baseline' prerequisite hint, package-manager-aware missing-dep errors, and structured errors emitted on STDOUT in the active format — intentionally diverging from POSIX stderr convention because axi requires agent-parseable errors on stdout); per-subcommand --help for every command; a content-first no-args view; and 0/1/2 exit codes. Key deliberate decisions a diff-only reviewer would miss: TOON uses @toon-format/toon (the official package; the bare 'toon' is an unrelated squatter); drizzle-orm is pinned ^0.45.1 and zod ^4.4.3 to match what codegen-ts 0.11.5 actually emits (the wider peer ranges are misleading); a few migrate sub-function error paths (runBaseline/runD1Migrate) are intentionally left stderr-only with _fmt stubs as a documented follow-up; and several Minor review findings were triaged as acceptable follow-ups rather than fixed in this branch.

What Changed

  • Added an axi-conformant Node meta CLI surface: a TTY-aware --format <toon|json|text> flag (human text on a TTY, token-efficient TOON on a pipe) routing gen and migrate through shared data-shape formatters with axi aggregates/totals and next-step help[] lines, plus per-subcommand --help, a content-first no-args view, and 0/1/2 exit codes. New lib/format.ts, lib/output.ts, lib/output-json.ts, and lib/pm-detect.ts back this.
  • Hardened meta migrate for agents: idempotent no-op when nothing changed, a discoverable baseline prerequisite hint, package-manager-aware missing-dependency errors, structured errors emitted on stdout in the active format, and a structured summary that reflects written-vs-applied-vs-dry-run state (including applied ledger files with no fresh diff). Promoted @libsql/kysely-libsql from optional peer to a real dependency and pinned drizzle-orm/zod to the ranges codegen-ts emits.
  • Changed the agent-context assembler (sdk/src/agent-context/assemble.ts) to deploy all per-language references/<lang>.md fragments instead of only the detected stack's, authored the previously-missing metaobjects-codegen/references/python.md, added a conformance-goldens regen script, and updated SDK + CLI init-scaffold tests to assert all languages are present.

Risk Assessment

✅ Low: The change is well-bounded and its substantive concerns were already addressed across four prior review rounds and are covered by tests; only one minor cosmetic output glitch and a doc-staleness note remain, neither affecting correctness or parseability materially.

Testing

Ran the CLI test suite (331 pass) plus the eight new/updated axi + deploy-all test files (79 pass) and the SDK assembler test (6 pass), all green. Beyond unit tests, I drove the actual meta binary to produce reviewer-visible CLI transcripts: Plan 1 shows a fresh meta init in an empty directory deploying all five per-language reference fragments (incl. the new codegen python.md) — the monorepo case that previously starved agents; Plan 2 shows the TTY-aware --format toon|json|text output with axi summary/help[] lines, invalid-format rejection, the discoverable migrate baseline hint, idempotent no-op, structured errors on STDOUT, and a live-DB --apply that persisted real sqlite tables (verified by querying sqlite_master), exercising the @libsql/kysely-libsql dependency promotion. Exit codes 0/1/2 were all observed. This change is CLI/agent-facing (no rendered UI surface), so terminal transcripts and persisted DB state are the appropriate end-user evidence rather than screenshots. One scratch run hit an EEXIST on a duplicate same-second migration timestamp — a test-sequencing artifact, not a product defect — worked around with a single clean apply.

Evidence: Plan 2 — axi CLI transcript (no-args, gen text/toon/json, invalid format, migrate baseline/idempotent/structured-error)
================================================================
 PLAN 2 — Node 'meta' CLI made agent-friendly (axi + TOON)
================================================================

$ meta            # content-first no-args view (inside a project)
meta — MetaObjects CLI (v0.11.5)  ·  metaobjects/ found

  meta gen              Run codegen
  meta verify           Check for drift
  meta migrate          Diff vs DB and emit SQL
  meta --help           Full command reference

exit=0

$ meta gen --format text
meta gen — sqlite, src/generated

  NEW        src/generated/Widget.ts        
  NEW        src/generated/Widget.queries.ts
  NEW        src/generated/Widget.routes.ts 
  NEW        src/generated/index.ts         

  4 written

exit=0

$ meta gen --format toon     # TOON: tabular, token-efficient, axi summary+help[]
gen[4]{file,status}:
  src/generated/Widget.ts,unchanged
  src/generated/Widget.queries.ts,unchanged
  src/generated/Widget.routes.ts,unchanged
  src/generated/index.ts,unchanged
summary: 4 unchanged
help[2]: typecheck the generated code with `npx tsc`,run schema with `meta migrate --db <url> --slug <name>`
exit=0

$ meta gen --format json
{
  "gen": [
    {
      "file": "src/generated/Widget.ts",
      "status": "unchanged"
    },
    {
      "file": "src/generated/Widget.queries.ts",
      "status": "unchanged"
    },
    {
      "file": "src/generated/Widget.routes.ts",
      "status": "unchanged"
    },
    {
      "file": "src/generated/index.ts",
      "status": "unchanged"
    }
  ],
  "summary": "4 unchanged",
  "help": [
    "typecheck the generated code with `npx tsc`",
    "run schema with `meta migrate --db <url> --slug <name>`"
  ]
}
exit=0

$ meta gen --format yaml     # invalid format rejected
meta: --format must be one of: toon, json, text (got 'yaml')
exit=2 (2 = usage error)

$ meta migrate --dialect sqlite     # discoverable baseline prerequisite, exit 2
meta: migrate: no schema snapshot at /tmp/meta-eviA-43H5/.metaobjects/migrations/.schema.sqlite.json; run `meta migrate baseline --dialect sqlite` first
error: no schema snapshot
hint: first run `meta migrate baseline --dialect sqlite`
exit=2

$ meta migrate --dialect sqlite --format json    # SAME error, structured on STDOUT (axi divergence)
{
  "error": "no schema snapshot",
  "hint": "first run `meta migrate baseline --dialect sqlite`"
}
exit=2

$ meta migrate baseline --dialect sqlite
migrate: wrote schema snapshot /tmp/meta-eviA-43H5/.metaobjects/migrations/.schema.sqlite.json
exit=0

$ meta migrate --dialect sqlite     # idempotent no-op on no changes, exit 0
migrate: no changes
exit=0
Evidence: Plan 2 — live-DB migrate: structured JSON aggregates + persisted sqlite apply (widgets + ledger)
================================================================
 PLAN 2 — live-DB migrate: structured JSON + persisted apply
 (@libsql/kysely-libsql promoted optional-peer -> real dependency)
================================================================

$ meta migrate --db file:app.db --from-db --apply --slug init --format json
migrate: --from-db did not advance the committed snapshot; run 'meta migrate baseline --from-db' to re-sync
{
  "changes": [
    {
      "kind": "create-table",
      "count": 1
    }
  ],
  "written": [
    "/tmp/meta-eviC-xeX9/.metaobjects/migrations/20260623162626-init/up.sql",
    "/tmp/meta-eviC-xeX9/.metaobjects/migrations/20260623162626-init/down.sql"
  ],
  "summary": "1 create-table; applied 1 migration(s)",
  "help": [
    "roll back with `meta migrate --rollback <target>`"
  ]
}
migrate: applied 1 migration(s): 20260623162626-init
exit=0

# Persisted sqlite state after --apply (widgets + migration ledger created):
[
  {
    "name": "_metaobjects_migrations",
    "type": "table"
  },
  {
    "name": "sqlite_autoindex__metaobjects_migrations_1",
    "type": "index"
  },
  {
    "name": "widgets",
    "type": "table"
  }
]
Evidence: Plan 1 — deploy-all references: empty-dir init installs all 5 language refs incl. new python.md
================================================================
 PLAN 1 — deploy-ALL per-language references
 Scenario: empty dir => stack detection finds NOTHING
 (the exact monorepo-starvation case: servers:[] previously
  deployed ZERO references). Deploy-all installs them all;
  the agent reads the reference matching its stack.
================================================================

$ meta init

Initialized metaobjects/ + .metaobjects/ + metaobjects.config.ts


# All per-language reference fragments now deployed:
.claude/skills/metaobjects-codegen/references/csharp.md
.claude/skills/metaobjects-codegen/references/java.md
.claude/skills/metaobjects-codegen/references/kotlin.md
.claude/skills/metaobjects-codegen/references/python.md
.claude/skills/metaobjects-codegen/references/typescript.md
.claude/skills/metaobjects-prompts/references/csharp.md
.claude/skills/metaobjects-prompts/references/java.md
.claude/skills/metaobjects-prompts/references/kotlin.md
.claude/skills/metaobjects-prompts/references/python.md
.claude/skills/metaobjects-prompts/references/typescript.md
.claude/skills/metaobjects-runtime-ui/references/java.md
.claude/skills/metaobjects-runtime-ui/references/kotlin.md
.claude/skills/metaobjects-runtime-ui/references/react.md
.claude/skills/metaobjects-runtime-ui/references/tanstack.md
.claude/skills/metaobjects-runtime-ui/references/typescript.md
.claude/skills/metaobjects-verify/references/migration.md

# The previously-missing codegen Python reference is present:
.claude/skills/metaobjects-codegen/references/python.md

# Head of the newly-authored python.md:
# 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`.

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 2 infos
  • ℹ️ server/typescript/packages/cli/src/commands/migrate.ts:102 - AlreadyEmittedError (migrate.ts:102) is defined and handled in the top-level catch (line 440), but it is never thrown anywhere. The doc comments (lines 99-101, 438-440) describe sub-functions throwing it after calling emitStructuredError(), but runOfflineGenerate/runBaseline/runD1Migrate all return &lt;code&gt; instead. The catch branch is therefore unreachable dead code today. Consistent with the author's documented follow-up to wire structured errors into the migrate sub-functions; harmless as forward-looking scaffolding, but currently misleading.
  • ⚠️ server/typescript/packages/cli/src/commands/migrate.ts:186 - In json/toon format mode several migrate error paths emit only to stderr via log.error and return non-zero WITHOUT calling emitStructuredError, so an agent parsing stdout gets empty output plus a bare exit code and cannot see the failure reason: the d1 top-level checks (lines ~186/190/194), the --db &lt;url&gt; required path (~213), and the d1/baseline sub-functions (the _fmt stubs). The author explicitly scoped runBaseline/runD1Migrate as follow-ups, but the migrateCommand-level d1/db-required branches fall in the same gap and partially undercut the axi 'parseable errors on stdout' goal. The parse-args and offline-generate paths ARE covered, so this is a coverage gap, not a regression.
  • ℹ️ server/typescript/packages/cli/src/lib/format.ts:8 - resolveFormat silently ignores an invalid --format value (e.g. --format jsonn) and falls back to the TTY-aware default rather than erroring. On a pipe, an agent that mistypes the format would silently receive TOON instead of the JSON it requested, with no diagnostic. Consider rejecting unrecognized format values with a non-zero exit.

🔧 Fix: emit migrate branch errors on stdout; reject invalid --format
3 issues (1 warning, 2 infos) still open:

  • ⚠️ server/typescript/packages/cli/src/lib/output.ts:212 - migrateResultToData() derives summary purely from isBlocked, so it emits &#34;…; applied&#34; (and help &#34;roll back with meta migrate --rollback <target>&#34;) for runs that applied nothing to the DB: (1) --from-db without --apply only writes migration files; (2) --dry-run writes nothing yet still hits this formatter (migrate.ts:388 falls through to migrate.ts:434-446); (3) even with --apply, the output prints BEFORE applyPending runs (migrate.ts:448 precedes 449), so an apply failure that flips exitCode to 1 contradicts the already-printed applied. The text formatter intentionally avoids the word (it shows Written: + paths). Because the TOON/JSON output is the agent-facing contract, summary: applied can cause an agent to believe the DB is migrated and skip applying. The shape already carries dryRun, and apply-state is known at the call site — thread both in so the structured summary reflects written-vs-applied.
  • ℹ️ server/typescript/packages/cli/src/commands/gen.ts:30 - In json/toon mode genCommand still emits all error paths (arg-parse, config-load, metadata-load, runGen failure at lines 30/49/68/70/83) only to stderr via log.error with a bare non-zero exit — no structured payload on stdout. This is the same axi 'parseable errors on stdout' gap the migrate command-level branches were just fixed for; gen's success path is structured but its failures are not. Consistent with the author scoping structured errors to migrate, so flagging only as a parallel coverage gap, not a regression.
  • ℹ️ server/typescript/packages/cli/src/index.ts:238 - The content-first no-args view always emits human text and ignores the resolved fmt. An agent invoking bare meta on a pipe (where the TTY-aware default is toon) gets prose rather than structured output, a minor divergence from the axi pipe-gets-structured intent applied to gen/migrate.

🔧 Fix: make migrate structured summary reflect written-vs-applied-vs-dry-run state
1 warning still open:

  • ⚠️ server/typescript/packages/cli/src/lib/output.ts:220 - migrateResultToData checks !hasChanges first and ignores applied, but applyPending runs whenever config.apply &amp;&amp; exitCode===0 &amp;&amp; !dryRun (migrate.ts:413) — NOT gated on hasChanges. As the comment at migrate.ts:409-411 documents, --apply also applies previously-written-but-unapplied files via the ledger. So meta migrate --db &lt;url&gt; --apply with the schema already in sync but a committed-unapplied migration file in outDir applies that file (appliedNames non-empty) while the structured summary reports no schema changes / metadata and schema are in sync — nothing to do. This is the inverse of the round-2 bug: the agent-facing TOON/JSON summary under-reports a real apply (only the text-mode log at migrate.ts:456-457 surfaces it). Surface the applied state ahead of the !hasChanges branch (e.g. report applied N migration(s) when applied.length>0 even with no diff).

🔧 Fix: surface applied ledger files in migrate summary even with no fresh diff
2 issues (1 warning, 1 info) still open:

  • ⚠️ server/typescript/packages/cli/src/lib/kysely.ts:114 - The sqlite missing-dep path was upgraded to a package-manager-aware install hint via installCommand() (line 84), but the postgres path still hardcodes 'bun add pg'. This inverts the intended UX: @libsql/kysely-libsql is now a hard dependency (always present in a normal install, so its catch-branch hint is effectively dead), while pg remains the genuinely-optional peer (peerDependenciesMeta.pg.optional=true) — i.e. the actually-missing-dep case keeps the non-PM-aware 'bun add pg' message, undercutting the stated 'package-manager-aware missing-dep errors' goal exactly where it matters. Mirror the sqlite path: const cmd = await installCommand(&#39;pg&#39;, process.cwd()); and interpolate it.
  • ℹ️ server/typescript/packages/cli/src/commands/migrate.ts:425 - On --apply failure the structured stdout summary correctly reports apply failed (output.ts:236-238), but the actual DB error message is emitted only to stderr via log.error and never as a structured {error,hint} on stdout in json/toon mode. An agent parsing stdout learns the apply failed but not why. This is the same axi 'parseable errors on stdout' gap the command-level branches were fixed for, now in the mid-pipeline apply path; consistent with the documented sub-function follow-up scope, flagging as a parallel coverage gap, not a regression.

🔧 Fix: make postgres missing-dep hint package-manager-aware in CLI kysely builder
2 infos still open:

  • ℹ️ server/typescript/packages/cli/src/lib/output.ts:226 - In the isBlocked branch the summary is built as ${changeSummary}; not applied directly, NOT via the guarded prefix (line 215) that every other branch uses. The ambiguous-abort path in migrateCommand (migrate.ts:335-345) constructs the result with changeCounts: {} and a populated ambiguous list, so changeSummary is empty and the agent-facing TOON/JSON summary becomes a dangling &#34;; not applied&#34;. This path is reachable by a real meta migrate --db &lt;url&gt; run with an ambiguous rename under --on-ambiguous abort. The blocked-changes path always carries non-empty changeCounts (set before emit at migrate.ts:357), which is why the existing blocked test (output-toon.test.ts:91) didn't surface it. Use the same empty-guard as prefix: ${changeSummary ? ${changeSummary}; : &#34;&#34;}not applied.
  • ℹ️ server/typescript/packages/cli/src/index.ts:61 - The top-level HELP_TEXT migrate section still says --db &lt;url&gt; DB connection URL (required, or set DATABASE_URL or config), but migrate's default path is now offline snapshot generation (migrate.ts:223) and --db is only required for live-introspect / --apply / --rollback. The per-subcommand MIGRATE_HELP_TEXT (migrate.ts:61) already states this accurately; the top-level slice is now inconsistent and overstates the requirement.
✅ **Test** - passed

✅ No issues found.

  • cd server/typescript &amp;&amp; bun test packages/cli — 331 pass / 2 skip / 0 fail (baseline CLI suite)
  • bun test packages/cli/test/migrate-ux.test.ts packages/cli/test/index-format.test.ts packages/cli/test/help-and-exit.test.ts packages/cli/test/lib/output-toon.test.ts packages/cli/test/lib/format.test.ts packages/cli/test/unit/init-agent-context.test.ts packages/cli/test/unit/init-docs-only.test.ts packages/cli/test/unit/kysely-builder.test.ts — 79 pass / 0 fail (new axi + Plan-1 files)
  • bun test packages/sdk/test/agent-context/assemble.test.ts — 6 pass / 0 fail (deploy-all assembler)
  • Manual CLI: meta init in an empty dir, then find .claude/skills -path &#39;*references*&#39; -name &#39;*.md&#39; — all 5 language refs incl. new codegen python.md present (Plan 1)
  • Manual CLI: meta (no-args), meta gen --format text|toon|json, meta gen --format yaml (exit 2), meta gen|migrate --help (Plan 2)
  • Manual CLI: meta migrate --dialect sqlite (baseline hint, exit 2) → meta migrate --dialect sqlite --format json (structured error on stdout) → meta migrate baseline → re-run (idempotent no-op, exit 0)
  • Manual CLI: meta migrate --db file:app.db --from-db --apply --slug init --format json (structured TOON/JSON aggregates+help[]) then probed sqlite_master via bun:sqlite — widgets table + migration ledger persisted (exit 0)
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

dmealing and others added 30 commits June 24, 2026 13:41
…ust to stack-detection miss)

The reference filter (assemble.ts) only installed references whose token was in
the detected stack; when detection came up empty (as in this monorepo's own
init), agents got zero language guidance. Deploy all references instead and let
the agent read the one matching its stack (SKILL.md already points to them).
Update the assemble tests + regenerate the conformance goldens (each stack now
assembles the full 22-file set); add a regen script for the corpus.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018mjBXyYKk6tbQymzhgMmdB
…md gap)

metaobjects-codegen shipped references for ts/java/kotlin/csharp but not python,
so Python adopters got no codegen guidance. Add python.md (accurate to the actual
Python port: entity->Pydantic, routes->FastAPI, no ORM, int-PK/dict[str,Any]
gaps, Node-owned migrate). Regenerate conformance goldens (now 23 files/stack).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018mjBXyYKk6tbQymzhgMmdB
…elective)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018mjBXyYKk6tbQymzhgMmdB
…f 5)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018mjBXyYKk6tbQymzhgMmdB
…JSON/text

Extract --format globally in run() alongside --cwd; resolve once with
resolveFormat(flag, isTTY) and thread the OutputFormat into genCommand
and migrateCommand. Each command emits formatGenResultToon/Json or the
existing text formatter at the single log.info call site. Adds
--format <toon|json|text> to HELP_TEXT GLOBAL OPTIONS.

Tests: dispatch-level unit tests for resolveFormat selection + five
integration tests against the trainer-website-meta fixture asserting
TOON tabular shape, JSON parse, and text header; full suite 296 pass.
… 1 fallout)

Replace stack-selective assertions (typescript.md absent) with deploy-all
assertions (all language references present) in init-agent-context and
init-docs-only unit tests. Test names updated to reflect the new behavior.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018mjBXyYKk6tbQymzhgMmdB
…ibsql, PM-aware errors)

- Declare @libsql/kysely-libsql ^0.4.0 as a direct dep (was optional peer)
- Intercept --help/-h before strict parseMigrateArgs; print per-subcommand usage block
- Emit structured {error, hint} JSON/TOON on stdout for arg-parse failures
- Baseline discoverability: no-snapshot path emits JSON next-step hint on stdout
- PM-aware missing-dep error: detect lockfile (npm/pnpm/yarn/bun) and print matching install command
- 11 new tests in test/migrate-ux.test.ts; suite: 309 pass, 0 fail
…-detect, drop stale devDep)

Thread fmt into runOfflineGenerate so no-snapshot hint uses emitStructuredError(fmt) instead
of hardcoded log.info(JSON.stringify(...)). Add top-level try/catch in migrateCommand with
AlreadyEmittedError sentinel so any unhandled sub-function throw emits structured error on
stdout in the active format (exit 1) without double-emitting. Add yarn pm-detect test case.
Remove stale @libsql/kysely-libsql from devDependencies (already in dependencies).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018mjBXyYKk6tbQymzhgMmdB
…xistent migrate subcommands

- Append "; run \`meta migrate baseline --dialect <dialect>\` first" to the
  log.error() in the no-snapshot path so text/TTY users see the next step
  (emitStructuredError is a no-op for text format; the structured hint was
  already correct for json/toon).
- Replace the two fabricated help[] hints ("meta migrate status",
  "meta migrate down --slug <name>") with the real rollback surface:
  "roll back with \`meta migrate --rollback <target>\`".
- Extend captureCommand() in migrate-ux.test.ts to also capture stderr;
  add a text-mode no-snapshot test asserting stderr contains "baseline".
- Update output-toon.test.ts help[] assertion from "status" to "--rollback".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018mjBXyYKk6tbQymzhgMmdB
…rs (cross-port parity)

The TS assembler was updated to deploy-all (emit every references/*.md regardless
of stack); the C# and Python ports still had the per-stack token filter, so the
byte-identity conformance gate failed for those ports.

Changes:
- server/python: drop `p.stem in stack.tokens` guard in assemble(); emit every
  .md in references/ sorted, matching TS deploy-all semantics.
- server/csharp: drop `.Where(stack.Tokens.Contains)` from the LINQ chain in
  AgentContextAssembler.Assemble(); same effect.
- fixtures/: regenerate conformance goldens via regen-agent-context-conformance.ts
  to pick up the 03bd9b5b doc additions (typescript.md +4 lines, migration.md
  +37 lines) that were missed when the goldens were last committed.

All conformance gates pass: Python 305/305, C# 670/670, CLI 35/35.
…ementations)

Option A: Node meta is the sole assembler; Python/JVM/C# stop assembling +
embedding agent-context. Non-Node CLIs keep a non-executing pointer stub
redirecting to 'npx meta agent-docs --server <lang>'. Reconciles with ADR-0015
(Node/binary already required for migrate). Folded into this branch as deletions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018mjBXyYKk6tbQymzhgMmdB
…e per-port assemblers)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018mjBXyYKk6tbQymzhgMmdB
…ffolder for all ports)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ent-docs redirects to meta CLI

- Delete assemble.py, types.py, content_root.py (the Python-port assembler)
- Delete tests/conformance/test_agent_context_conformance.py (byte-identity test)
- Delete src/metaobjects/agent_context/_content/ (build-time vendored content tree)
- Stub _cmd_agent_docs in cli.py: prints redirect message to stderr, returns 1
- Keep scaffold.py (stripped to staleness-nudge symbols only: agent_context_staleness,
  Manifest, AGENT_CONTEXT_MANIFEST_PATH, installed_metaobjects_version) — used by gen/verify
- Fix agent_context/__init__.py: drop assembler re-exports, keep staleness symbols
- Fix cli.py imports: drop assemble/make_stack/plan_scaffold/resolve_agent_context_root
- Remove dead _detect_python_server/_wire_root_doc helpers and _ROOT_DOC_* constants
- Neutralise hatch_build.py: no-op hook (no more _content vendoring)
- Drop _content/ from .gitignore
- Remove test_agent_docs_stamps_generated_by from staleness tests (stamp is Node CLI's job now)

1288 passed (was 1294: 5 conformance fixtures + 1 stamp test removed).
…ding; agent-docs Mojo redirects to meta CLI

AssembledFile and Stack are retained — AgentContextScaffold.plan() takes both as
parameters and AgentContextScaffoldTest constructs them directly. Only
AgentContextAssembler and ContentRoot were assembly-only; they are deleted.
AgentContextConformanceTest (the byte-identity gate) is also deleted; it was
never in the CI -Dtest list (confirmed absent from conformance.yml).
…ledFile/Stack) + correct staleness nudge to npx meta

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…udge → npx meta agent-docs --server python

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018mjBXyYKk6tbQymzhgMmdB
@dmealing
dmealing force-pushed the metaobjects-cli-axi-and-deploys branch from d144ea5 to c67e80a Compare June 24, 2026 18:38
@dmealing
dmealing merged commit 934489d into main Jun 24, 2026
29 checks passed
@dmealing
dmealing deleted the metaobjects-cli-axi-and-deploys branch June 24, 2026 23:48
dmealing added a commit that referenced this pull request Jun 25, 2026
Lockstep npm release of the @metaobjectsdev/* packages (13 publish candidates).
Ships the agent-friendly meta CLI (--format/TOON output, deploy-all agent-context
references, #71) plus the agent-context scaffold fixes (#1, #73): the injected
AGENTS.md/CLAUDE.md now name the database schema + migrations as metadata-derived
and no longer guess the migration binding.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant