Skip to content

Commit b8b8a21

Browse files
committed
site: a first user hit a throwing stub, a source tree, and three wrong numbers
Four things, all found by walking the pages as a first-time reader. **Getting started stalled at step 6.** The page went from `meta gen` straight to "import the generated code and listen on 3000" — but `meta init` scaffolds `src/db.ts` as a THROWING stub (it will not choose between better-sqlite3, @libsql/client, pg and postgres.js on your behalf), so following the page start to finish gives you a server that throws on the first request. There is now a step 6, "Wire your database", between Generate and Use; the old 6 and 7 shift to 7 and 8. Its driver example is lifted from `DB_STUB_BODY` in the CLI's `init.ts` rather than written from memory, as this repo's AGENTS.md requires. **And it never said to install.** `meta init` DECLARES the packages the scaffolded generators and the generated code import — into devDependencies and dependencies — and then deliberately runs no package manager; its own warning says "Run your package manager's install before `meta gen`", twice. The page never repeated that, so the first `meta gen` reports TS2307 on files that are perfectly correct. `npm install` is now the third line of step 1. **The quickstart cards pointed at GitHub directory listings** — five languages, five file trees to read past. Each now points at that port's guide under `docs/ports/`, which opens Install → Configure → Generate → Use. The two client cards land on `typescript-client.md` at their own anchors. All six verified 200. **Three counts were wrong**, and the scaffold tree contradicted itself: it announced "seven skills" directly above a list of six. Six is right — `metaobjects-fit-assessment` carries `scaffold: false` because it is a PRE-adoption tool. Corpus fixtures 253 → 313 and corpora 19 → 21 (both measured upstream, see metaobjects 5f20e905d); base types 13 → 14, counted from `expected-registry.json`. Also: `requirements.html` opened with the sentence the homepage section linking to it had just delivered, near-verbatim — "the columns are there, the types line up, the tests pass — and no code path ever writes the value." Clicking "How capability requirements work →" landed you on what you had just read. It now opens a beat later, on why a test suite structurally cannot catch this: a test exercises code that exists, so the absence has no address. (`story.html` was checked for the same defect and does NOT have it — it shares the homepage's heading, which is the link's promise, but its first paragraph is a different beat. Left alone.) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NTcEKXTQMYt84fAjuw5A2M
1 parent 66f9cfe commit b8b8a21

3 files changed

Lines changed: 48 additions & 17 deletions

File tree

www/getting-started.html

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,13 @@ <h2 class="section-label">1 · Install &amp; scaffold</h2>
7676
<h3>Set up the project and the agent context</h3>
7777
<p>Add the TypeScript CLI and scaffold the workspace. <code>meta init</code> also teaches your coding agent how to use MetaObjects:</p>
7878
<pre class="gs-code">npm i <span class="s">@metaobjectsdev/cli</span>
79-
npx meta init</pre>
79+
npx meta init
80+
npm install <span class="c"># init DECLARES what it scaffolds against; it does not install</span></pre>
81+
<p class="gs-note">That third line is not optional. <code>meta init</code> adds the packages the
82+
scaffolded generators and the generated code import — to <code>devDependencies</code> and
83+
<code>dependencies</code> — but it deliberately never runs your package manager. Skip it and
84+
<code>meta gen</code> and <code>npx tsc</code> both report <code>TS2307</code> on files that are
85+
perfectly correct.</p>
8086
<p>That writes a small, legible tree — <strong>your models go in <code>metaobjects/</code></strong>,
8187
and the code generators land in your repo too:</p>
8288
<pre class="gs-code"><span class="c">your-project/</span>
@@ -92,7 +98,7 @@ <h3>Set up the project and the agent context</h3>
9298
├── src/db.ts <span class="c"># throwing stub — swap in your DB connection</span>
9399
├── CLAUDE.md <span class="c"># wired to auto-load the context below</span>
94100
├── .metaobjects/ <span class="c"># tool state + agent docs (AGENTS.md, CLAUDE.md)</span>
95-
└── .claude/skills/ <span class="c"># seven skills your agent now has:</span>
101+
└── .claude/skills/ <span class="c"># six skills your agent now has:</span>
96102
├── metaobjects-authoring/ <span class="c"># write &amp; edit models</span>
97103
├── metaobjects-codegen/ <span class="c"># run codegen</span>
98104
├── metaobjects-runtime-ui/ <span class="c"># wire up runtime + UI</span>
@@ -239,7 +245,29 @@ <h2 class="section-label">5 · Generate</h2>
239245
</section>
240246

241247
<section>
242-
<h2 class="section-label">6 · Use it — and add your own logic</h2>
248+
<h2 class="section-label">6 · Wire your database</h2>
249+
<p class="gs-note"><code>meta init</code> scaffolded <code>src/db.ts</code> as a <strong>throwing
250+
stub</strong>, on purpose: the generated routes have to import a <code>db</code> from somewhere for
251+
<code>meta gen</code> and your first <code>tsc</code> to succeed, and MetaObjects will not pick a driver
252+
for you — <code>better-sqlite3</code>, <code>@libsql/client</code>, <code>pg</code> and
253+
<code>postgres.js</code> are your call, not a dependency it adds behind your back. It type-checks
254+
everywhere and throws the first time anything actually touches it, with instructions. Replace it:</p>
255+
<pre class="gs-code">$ npm i <span class="s">better-sqlite3</span>
256+
257+
<span class="c">// src/db.ts — replace the scaffolded stub</span>
258+
import { drizzle } from <span class="s">"drizzle-orm/better-sqlite3"</span>;
259+
import Database from <span class="s">"better-sqlite3"</span>;
260+
261+
export const db = drizzle(new Database(<span class="s">"dev.sqlite"</span>));</pre>
262+
<p class="gs-note">Swap the driver import for your dialect. For libsql, Cloudflare D1, Postgres and
263+
multi-tenant setups, see
264+
<a href="https://github.com/metaobjectsdev/metaobjects/blob/main/docs/recipes/wiring-generated-queries.md">wiring
265+
generated queries</a>. Create the tables themselves with
266+
<code>meta migrate --from-db --db file:dev.sqlite --dialect sqlite --slug init --apply</code>.</p>
267+
</section>
268+
269+
<section>
270+
<h2 class="section-label">7 · Use it — and add your own logic</h2>
243271
<p class="gs-note">Import the generated code into your app. <strong>It runs with no MetaObjects dependency</strong>
244272
Drizzle, Zod, and Fastify only:</p>
245273
<pre class="gs-code">import Fastify from <span class="s">"fastify"</span>;
@@ -255,7 +283,7 @@ <h2 class="section-label">6 · Use it — and add your own logic</h2>
255283
</section>
256284

257285
<section>
258-
<h2 class="section-label">7 · Keep it honest</h2>
286+
<h2 class="section-label">8 · Keep it honest</h2>
259287
<p class="gs-note">As the model evolves, <code>meta verify</code> fails the build the moment generated code,
260288
schema, or prompt templates drift from it:</p>
261289
<pre class="gs-code">npx meta verify <span class="c"># --templates (default): prompt-template drift</span>

www/index.html

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ <h2 class="section-label">Five ports. All installable today.</h2>
294294
</tbody>
295295
</table>
296296
<p class="impl-note">
297-
Nineteen shared conformance corpora at <a href="https://github.com/metaobjectsdev/metaobjects/tree/main/fixtures"><code>fixtures/</code></a> — metamodel (253 fixtures), render, verify, extract, persistence (24 query scenarios against Testcontainers Postgres), API contract (cross-port, reference <em>and</em> generated lanes), YAML and more — validate every implementation against the same expectations. All ports implement <code>metamodelVersion</code> <code data-registry="metamodel">0.13</code> — the metadata contract, versioned separately from the package lines.
297+
Twenty-one shared conformance corpora at <a href="https://github.com/metaobjectsdev/metaobjects/tree/main/fixtures"><code>fixtures/</code></a> — metamodel (313 fixtures), render, verify, extract, persistence (24 query scenarios against Testcontainers Postgres), API contract (cross-port, reference <em>and</em> generated lanes), YAML and more — validate every implementation against the same expectations. All ports implement <code>metamodelVersion</code> <code data-registry="metamodel">0.13</code> — the metadata contract, versioned separately from the package lines.
298298
</p>
299299
</section>
300300

@@ -440,7 +440,7 @@ <h3 class="compare-subhead">Capability matrix — including AI-agent suitability
440440
<tr class="ai-row"><td>Machine-readable metadata (grep-friendly)</td> <td class="yes">YAML/JSON, named constants</td> <td class="partial">DSL or schema.prisma</td> <td class="no">annotations / decorators</td> <td class="yes">YAML/JSON</td></tr>
441441
<tr class="ai-row"><td>Generated code is plain (no proxy/decorator magic)</td> <td class="yes">idiomatic native</td> <td class="yes">idiomatic</td> <td class="no">proxy/runtime magic</td><td class="yes">type stubs</td></tr>
442442
<tr class="ai-row"><td>Deterministic regen (same in → same out)</td> <td class="yes">conformance-gated</td><td class="yes">yes</td> <td class="yes">yes</td> <td class="yes">yes</td></tr>
443-
<tr class="ai-row"><td>Small surface area for agent context window</td><td class="yes">13 base types + extensions</td> <td class="partial">single-lang ORM API</td> <td class="no">large framework surface</td><td class="yes">small spec</td></tr>
443+
<tr class="ai-row"><td>Small surface area for agent context window</td><td class="yes">14 base types + extensions</td> <td class="partial">single-lang ORM API</td> <td class="no">large framework surface</td><td class="yes">small spec</td></tr>
444444
</tbody>
445445
</table>
446446

@@ -474,23 +474,23 @@ <h2 class="section-label">Quickstart</h2>
474474
<div class="qs-group">
475475
<h3 class="qs-group-title">Server-side</h3>
476476
<div class="quickstart-grid">
477-
<a href="https://github.com/metaobjectsdev/metaobjects/tree/main/server/typescript" class="quickstart-card">
477+
<a href="https://github.com/metaobjectsdev/metaobjects/blob/main/docs/ports/typescript.md" class="quickstart-card">
478478
<span class="qs-lang">TypeScript</span>
479479
<span class="qs-arrow"></span>
480480
</a>
481-
<a href="https://github.com/metaobjectsdev/metaobjects/tree/main/server/java" class="quickstart-card">
481+
<a href="https://github.com/metaobjectsdev/metaobjects/blob/main/docs/ports/java.md" class="quickstart-card">
482482
<span class="qs-lang">Java</span>
483483
<span class="qs-arrow"></span>
484484
</a>
485-
<a href="https://github.com/metaobjectsdev/metaobjects/tree/main/server/java/codegen-kotlin" class="quickstart-card">
485+
<a href="https://github.com/metaobjectsdev/metaobjects/blob/main/docs/ports/kotlin.md" class="quickstart-card">
486486
<span class="qs-lang">Kotlin</span>
487487
<span class="qs-arrow"></span>
488488
</a>
489-
<a href="https://github.com/metaobjectsdev/metaobjects/tree/main/server/csharp" class="quickstart-card">
489+
<a href="https://github.com/metaobjectsdev/metaobjects/blob/main/docs/ports/csharp.md" class="quickstart-card">
490490
<span class="qs-lang">C#.NET</span>
491491
<span class="qs-arrow"></span>
492492
</a>
493-
<a href="https://github.com/metaobjectsdev/metaobjects/tree/main/server/python" class="quickstart-card">
493+
<a href="https://github.com/metaobjectsdev/metaobjects/blob/main/docs/ports/python.md" class="quickstart-card">
494494
<span class="qs-lang">Python</span>
495495
<span class="qs-arrow"></span>
496496
</a>
@@ -500,11 +500,11 @@ <h3 class="qs-group-title">Server-side</h3>
500500
<div class="qs-group">
501501
<h3 class="qs-group-title">Client-side</h3>
502502
<div class="quickstart-grid quickstart-grid--client">
503-
<a href="https://github.com/metaobjectsdev/metaobjects/tree/main/client/web/packages/runtime-web" class="quickstart-card">
503+
<a href="https://github.com/metaobjectsdev/metaobjects/blob/main/docs/ports/typescript-client.md#browser-runtime-packages" class="quickstart-card">
504504
<span class="qs-lang">Runtime Web</span>
505505
<span class="qs-arrow"></span>
506506
</a>
507-
<a href="https://github.com/metaobjectsdev/metaobjects/tree/main/client/web/packages/react" class="quickstart-card">
507+
<a href="https://github.com/metaobjectsdev/metaobjects/blob/main/docs/ports/typescript-client.md#generated-react-forms" class="quickstart-card">
508508
<span class="qs-lang">React</span>
509509
<span class="qs-arrow"></span>
510510
</a>

www/requirements.html

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,13 @@
100100
<p class="page-eyebrow">Capability requirements · ships in all five language ports</p>
101101
<h1>Check what your AI actually built.</h1>
102102
<p class="page-lede">
103-
Your agent reports the feature done. The columns are there, the types line up, the tests
104-
pass — and no code path ever writes the value. Nothing is broken, so nothing fails.
105-
MetaObjects makes a capability a node in your model, so the distance between what your
106-
software <em>claims</em> to do and what it does becomes something a build can check.
103+
A test exercises code that exists. That is the whole reason a passing suite can sit on
104+
top of a feature nobody finished: there is no test that fails because a column nobody
105+
writes was never wired to anything, and no linter that flags the handler you meant to
106+
add. The absence has no address — so give it one. A capability declared in MetaObjects
107+
is a node in the same model as your entities, and its link to the code is
108+
<strong>resolved, not trusted</strong>: name something that isn't there and the build
109+
stops.
107110
</p>
108111

109112
<h2>The failure that comes after drift</h2>

0 commit comments

Comments
 (0)