Skip to content

Commit 3a43b74

Browse files
committed
no-mistakes(review): Fix docs-only prompt gate, ui.md opt-out, shared-exclude unlink
1 parent 72dd249 commit 3a43b74

16 files changed

Lines changed: 218 additions & 61 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,12 @@ database does not have.
8080
writes code, and it says the value objects were emitted only when `entityFile()` (or another
8181
entity-module generator) ran. Found by an adopter on 1.1.0-rc.4.
8282
- **`agentDocsFile()` says when it skips `agent/ui.md`.** The page is written only when the run
83-
lists a client UI generator or the generator is given `includeUiTier: true`, and before this
84-
a project whose UI is generated by a separate config lost the page with no message. `meta
85-
gen` now warns `agent/ui.md not written: no client UI generator in this run; set
86-
includeUiTier: true if another config generates the UI.`, and the option is documented in
83+
lists a client UI generator or the config sets `includeUiTier: true`, and before this a
84+
project whose UI is generated by a separate config lost the page with no message. When the
85+
config leaves `includeUiTier` unset, `meta gen` now warns `agent/ui.md not written: no client
86+
UI generator in this run; set includeUiTier: true if another config generates the UI, or
87+
includeUiTier: false if there is no UI.` A project with no UI anywhere sets `includeUiTier:
88+
false`, which skips the page without the warning. Both settings are documented in
8789
`docs/features/migrations/docs-are-generators.md`. Found by an adopter on 1.1.0-rc.4.
8890
- **A pre-release CLI's version in `.metaobjects/.agent-context.json` is caught.** `meta init`
8991
stamps the running CLI's version into that committed file's `generatedBy`; run with a release
@@ -100,7 +102,9 @@ database does not have.
100102
- **`prerelease-link unlink` removes the git exclude lines `link` added.** `link` appended its
101103
ignore rules as bare lines to the clone's shared `info/exclude`, and `unlink` left them there.
102104
They now sit in one managed block, which `unlink` removes without touching a line the user
103-
wrote, and a repeated `link` does not add them twice.
105+
wrote, and a repeated `link` does not add them twice. The file is shared by every worktree
106+
of the clone, so an entry another linked worktree still needs stays until that worktree is
107+
unlinked.
104108
- `verify --codegen` (Python, C#) says when the committed output was generated with another
105109
column rule, another table rule, or both, and names the `naming` setting that reproduces it,
106110
instead of advising a regeneration that would commit the wrong column or table names.

‎agent-context/skills/metaobjects-codegen/references/typescript-docs.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ generate, docs included). Each factory is an ordinary entry in `generators`, fro
2121
| `docsFile()` | `docs` | the neutral model surface — one page per entity and per template (`<Entity>.md`, `<Template>.md`), plus an overview with the whole-model ER diagram. Options: `apiSurfaces`, `templates`. |
2222
| `apiDocsFile()` | `api-docs` | the api reference — `api/<Entity>.md`, `api/README.md`, `api/AGENT-API.md`: the concrete imports, signatures, payload field shapes and runnable examples for THIS project's generated code. Options: `subDir` (default `api`), `modelBaseUrl`. |
2323
| `requirementsFile()` | `requirements` | the declared `requirement.*` ledger, each entry headed by its dotted path and `title`. Writes nothing for a model with no `requirement.*` node. |
24-
| `agentDocsFile()` | `agent-docs` | `agent/schema.md`, `agent/ui.md` (only when the run also lists a client-tier generator, OR the config sets `includeUiTier: true` — the escape hatch for a docs-only config whose UI is generated by a separate config; skipping it with a UI surface in the model prints an advisory naming `includeUiTier`) and `agent/requirements.md` — the three `agent/` pages the always-on pointer reads before touching a tier. |
24+
| `agentDocsFile()` | `agent-docs` | `agent/schema.md`, `agent/ui.md` (only when the run also lists a client-tier generator, OR the config sets `includeUiTier: true` — the escape hatch for a docs-only config whose UI is generated by a separate config; skipping it with a UI surface in the model and `includeUiTier` unset prints an advisory naming `includeUiTier`; `includeUiTier: false` says there is no UI anywhere and skips it without one) and `agent/requirements.md` — the three `agent/` pages the always-on pointer reads before touching a tier. |
2525
| `metamodelDocsFile()` | `metamodel-docs` | the built-in vocabulary reference, under `metamodel/` (was `meta docs --metamodel`). |
2626
| `docsSiteFile()` | `docs-site` | an HTML site under `site/` (was `meta docs --site`). Option: `prompts`. `meta eject docs-site` copies its templates and assets to `codegen/docs-site/` (was `meta docs --scaffold-site`). |
2727

‎docs/features/migrations/docs-are-generators.md‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ them only if you ran those flags.
145145
|---|---|
146146
| `docs.outDir`, `--out` (default `./docs/generated`) | `targets.docs.outDir` |
147147
| `docs.layout`, `--layout` | `targets.docs.outputLayout` (falls back to the top-level `outputLayout`, as 1.0 did) |
148-
| `docs.surfaces`, `--model` / `--api` / `--requirements` / `--agent` | which factories you list: `docsFile()`, `apiDocsFile()`, `requirementsFile()`, `agentDocsFile()`. `--agent` wrote all three agent pages unconditionally; `agentDocsFile()` writes `agent/ui.md` only when the run also lists a client UI generator (a form, a hook, a grid or its columns) or the config sets `includeUiTier: true` — see "Things that are different in 1.1.0" |
148+
| `docs.surfaces`, `--model` / `--api` / `--requirements` / `--agent` | which factories you list: `docsFile()`, `apiDocsFile()`, `requirementsFile()`, `agentDocsFile()`. `--agent` wrote all three agent pages unconditionally; `agentDocsFile()` writes `agent/ui.md` only when the run also lists a client UI generator (a form, a hook, a grid or its columns) or the config sets `includeUiTier: true`; with `includeUiTier` unset it warns when it skips the page, and `includeUiTier: false` (no UI anywhere) skips it quietly — see "Things that are different in 1.1.0" |
149149
| `docs.apiSurfaces` | `docsFile({ apiSurfaces })`, same shape. Leave it out when the only api pages are this project's own: the model pages then link to whatever `apiDocsFile()` writes to the same target |
150150
| the `subDir` of the `ts` entry in `docs.apiSurfaces` (default `api`) | `apiDocsFile({ subDir })`, same default |
151151
| `docs.baseUrl`, `--base-url` | none: 1.0 read it nowhere. To link each api page to model pages hosted elsewhere, use `apiDocsFile({ modelBaseUrl })` |
@@ -178,8 +178,10 @@ them only if you ran those flags.
178178
whether a UI is emitted is a generator fact, not a metadata one. A **docs-only** config
179179
— one whose own `generators` lists no UI generator because a separate config generates
180180
the UI — never sees that generator, so set `includeUiTier: true` to write the page
181-
anyway. When the model has a UI surface but the page is skipped, `meta gen` prints an
182-
advisory naming `includeUiTier: true` rather than exiting silently.
181+
anyway. When the model has a UI surface, the page is skipped and the config leaves
182+
`includeUiTier` unset, `meta gen` prints an advisory naming `includeUiTier: true` rather
183+
than exiting silently. A project with no UI anywhere (a server-only backend) sets
184+
`includeUiTier: false`, which skips the page without the advisory.
183185

184186
**Scripts and CI.** Replace `meta docs` with `meta gen`, and `meta verify --docs` with
185187
`meta verify --codegen`. To write only the documentation, name the docs entries:

‎docs/features/prerelease.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,9 @@ the project's `.git/info/exclude`, which is local and not committed — in a lin
171171
worktree this is the *shared* exclude file in the clone's common dir (git has no
172172
per-worktree exclude), so the paths `link` adds there live inside their own managed block
173173
too: `unlink` removes exactly that block, never a line a user added to the file by hand,
174-
and a repeated `link` does not duplicate it. Files that *are* tracked by definition
174+
and a repeated `link` does not duplicate it. An entry that another worktree of the same
175+
clone still needs, because its own managed file is still linked, stays until that worktree
176+
is unlinked too. Files that *are* tracked by definition
175177
(`pyproject.toml`, `pom.xml`) get a loud warning instead — there is no way to make an edit
176178
to a tracked file uncommittable, which is precisely why the detector in §5 exists.
177179

‎fixtures/agent-context-conformance/ts-react-tanstack/expected/.claude/skills/metaobjects-codegen/references/typescript-docs.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ generate, docs included). Each factory is an ordinary entry in `generators`, fro
2121
| `docsFile()` | `docs` | the neutral model surface — one page per entity and per template (`<Entity>.md`, `<Template>.md`), plus an overview with the whole-model ER diagram. Options: `apiSurfaces`, `templates`. |
2222
| `apiDocsFile()` | `api-docs` | the api reference — `api/<Entity>.md`, `api/README.md`, `api/AGENT-API.md`: the concrete imports, signatures, payload field shapes and runnable examples for THIS project's generated code. Options: `subDir` (default `api`), `modelBaseUrl`. |
2323
| `requirementsFile()` | `requirements` | the declared `requirement.*` ledger, each entry headed by its dotted path and `title`. Writes nothing for a model with no `requirement.*` node. |
24-
| `agentDocsFile()` | `agent-docs` | `agent/schema.md`, `agent/ui.md` (only when the run also lists a client-tier generator, OR the config sets `includeUiTier: true` — the escape hatch for a docs-only config whose UI is generated by a separate config; skipping it with a UI surface in the model prints an advisory naming `includeUiTier`) and `agent/requirements.md` — the three `agent/` pages the always-on pointer reads before touching a tier. |
24+
| `agentDocsFile()` | `agent-docs` | `agent/schema.md`, `agent/ui.md` (only when the run also lists a client-tier generator, OR the config sets `includeUiTier: true` — the escape hatch for a docs-only config whose UI is generated by a separate config; skipping it with a UI surface in the model and `includeUiTier` unset prints an advisory naming `includeUiTier`; `includeUiTier: false` says there is no UI anywhere and skips it without one) and `agent/requirements.md` — the three `agent/` pages the always-on pointer reads before touching a tier. |
2525
| `metamodelDocsFile()` | `metamodel-docs` | the built-in vocabulary reference, under `metamodel/` (was `meta docs --metamodel`). |
2626
| `docsSiteFile()` | `docs-site` | an HTML site under `site/` (was `meta docs --site`). Option: `prompts`. `meta eject docs-site` copies its templates and assets to `codegen/docs-site/` (was `meta docs --scaffold-site`). |
2727

‎fixtures/agent-context-conformance/ts-requirements/expected/.claude/skills/metaobjects-codegen/references/typescript-docs.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ generate, docs included). Each factory is an ordinary entry in `generators`, fro
2121
| `docsFile()` | `docs` | the neutral model surface — one page per entity and per template (`<Entity>.md`, `<Template>.md`), plus an overview with the whole-model ER diagram. Options: `apiSurfaces`, `templates`. |
2222
| `apiDocsFile()` | `api-docs` | the api reference — `api/<Entity>.md`, `api/README.md`, `api/AGENT-API.md`: the concrete imports, signatures, payload field shapes and runnable examples for THIS project's generated code. Options: `subDir` (default `api`), `modelBaseUrl`. |
2323
| `requirementsFile()` | `requirements` | the declared `requirement.*` ledger, each entry headed by its dotted path and `title`. Writes nothing for a model with no `requirement.*` node. |
24-
| `agentDocsFile()` | `agent-docs` | `agent/schema.md`, `agent/ui.md` (only when the run also lists a client-tier generator, OR the config sets `includeUiTier: true` — the escape hatch for a docs-only config whose UI is generated by a separate config; skipping it with a UI surface in the model prints an advisory naming `includeUiTier`) and `agent/requirements.md` — the three `agent/` pages the always-on pointer reads before touching a tier. |
24+
| `agentDocsFile()` | `agent-docs` | `agent/schema.md`, `agent/ui.md` (only when the run also lists a client-tier generator, OR the config sets `includeUiTier: true` — the escape hatch for a docs-only config whose UI is generated by a separate config; skipping it with a UI surface in the model and `includeUiTier` unset prints an advisory naming `includeUiTier`; `includeUiTier: false` says there is no UI anywhere and skips it without one) and `agent/requirements.md` — the three `agent/` pages the always-on pointer reads before touching a tier. |
2525
| `metamodelDocsFile()` | `metamodel-docs` | the built-in vocabulary reference, under `metamodel/` (was `meta docs --metamodel`). |
2626
| `docsSiteFile()` | `docs-site` | an HTML site under `site/` (was `meta docs --site`). Option: `prompts`. `meta eject docs-site` copies its templates and assets to `codegen/docs-site/` (was `meta docs --scaffold-site`). |
2727

‎server/typescript/packages/codegen-ts/src/generators/agent-docs-file.ts‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -314,14 +314,16 @@ export const agentDocsFile = function agentDocsFile(opts?: AgentDocsFileOpts): G
314314
if (ui !== "") {
315315
if (ctx.config.includeUiTier === true) {
316316
files.push({ path: `${dir}/ui.md`, content: ui });
317-
} else {
317+
} else if (ctx.config.includeUiTierExplicit !== true) {
318318
// The model HAS a UI surface (renderAgentUiPage returned content) but this
319-
// run has no client UI generator and no `includeUiTier: true` override, so the
320-
// page is skipped. Before this, that was silent: `meta gen` exited 0 and listed
321-
// only the pages it wrote, and a docs-only project (its own config generates no
322-
// UI; a SEPARATE config does) lost `agent/ui.md` with no signal at all.
319+
// run has no client UI generator and the config left `includeUiTier` unset, so
320+
// the page is skipped. Before this, that was silent: `meta gen` exited 0 and
321+
// listed only the pages it wrote, and a docs-only project (its own config
322+
// generates no UI; a SEPARATE config does) lost `agent/ui.md` with no signal at
323+
// all. An explicit `includeUiTier: false` says there is no UI anywhere, so a
324+
// server-only project has a way to say so and is not advised on every run.
323325
ctx.warn(
324-
`${dir}/ui.md not written: no client UI generator in this run; set includeUiTier: true if another config generates the UI.`,
326+
`${dir}/ui.md not written: no client UI generator in this run; set includeUiTier: true if another config generates the UI, or includeUiTier: false if there is no UI.`,
325327
);
326328
}
327329
}

‎server/typescript/packages/codegen-ts/src/metaobjects-config.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ export interface ResolvedGenConfig {
7777
* `agent/ui.md` reads this to decide whether a UI tier exists to describe;
7878
* a metadata predicate can only say a UI *could* be generated. Undefined ⇒ false. */
7979
includeUiTier?: boolean;
80+
/** Whether `includeUiTier` came from the config rather than from the marker
81+
* aggregation. An explicit `false` means "no UI anywhere", so `agent/ui.md` skips the
82+
* page without advising; an unset key that resolved to `false` still advises.
83+
* Set by the runner only. Undefined ⇒ false. */
84+
includeUiTierExplicit?: boolean;
8085
/**
8186
* FR-019 / ADR-0026: the module specifier from which an externally-PROVIDED
8287
* shared enum (`@provided: true` on an abstract package-level `field.enum`) is
@@ -104,7 +109,7 @@ export const DEFAULT_EXT_STYLE: ExtStyle = "js";
104109
* fills inert defaults when they are absent AND the model emits no DB artifacts, and
105110
* throws a clear error when they are absent but the model DOES emit DB code (#194).
106111
*/
107-
export interface MetaobjectsGenConfig extends Omit<ResolvedGenConfig, "dbImport" | "dialect" | "extStyle" | "routesExpose"> {
112+
export interface MetaobjectsGenConfig extends Omit<ResolvedGenConfig, "dbImport" | "dialect" | "extStyle" | "routesExpose" | "includeUiTierExplicit"> {
108113
dbImport?: string;
109114
dialect?: Dialect;
110115
/** Import-specifier suffix in generated code. Defaults to `"js"` (`./x.js`), which is

‎server/typescript/packages/codegen-ts/src/prompt-generator-gate.ts‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,16 @@ const PROMPT_GENERATOR_NAMES: ReadonlySet<string> = new Set([
4040
export function warnMissingPromptGenerators(
4141
root: MetaData,
4242
generators: readonly Generator[],
43-
isDocsTarget: (g: Generator) => boolean,
43+
writesDocs: (g: Generator) => boolean,
4444
warn: (msg: string) => void,
4545
): void {
4646
// A run that lists no generator at all, or where every listed generator writes
47-
// documentation (its RESOLVED output target — the same per-generator signal
48-
// runner.ts's targetOf() uses to place output, not a name match), emitted no code of
49-
// any kind. There is nothing for a prompt generator to be missing FROM: telling such a
50-
// run to add promptRender() is wrong advice (it would add TypeScript render code to a
51-
// project that only writes documentation), so the gate does not fire.
52-
if (generators.length === 0 || generators.every(isDocsTarget)) return;
47+
// documentation (runner.ts decides that from the generator's registry layer, so a docs
48+
// generator on a custom target still counts), emitted no code of any kind. There is
49+
// nothing for a prompt generator to be missing FROM: telling such a run to add
50+
// promptRender() is wrong advice (it would add TypeScript render code to a project that
51+
// only writes documentation), so the gate does not fire.
52+
if (generators.length === 0 || generators.every(writesDocs)) return;
5353
if (generators.some((g) => PROMPT_GENERATOR_NAMES.has(g.name))) return;
5454

5555
// ADR-0039: resolving children — a template may arrive through an overlay or extends.

‎server/typescript/packages/codegen-ts/src/reference/agent-docs.ts‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -325,14 +325,16 @@ export const agentDocsFile = function agentDocsFile(opts?: AgentDocsFileOpts): G
325325
if (ui !== "") {
326326
if (ctx.config.includeUiTier === true) {
327327
files.push({ path: `${dir}/ui.md`, content: ui });
328-
} else {
328+
} else if (ctx.config.includeUiTierExplicit !== true) {
329329
// The model HAS a UI surface (renderAgentUiPage returned content) but this
330-
// run has no client UI generator and no `includeUiTier: true` override, so the
331-
// page is skipped. Before this, that was silent: `meta gen` exited 0 and listed
332-
// only the pages it wrote, and a docs-only project (its own config generates no
333-
// UI; a SEPARATE config does) lost `agent/ui.md` with no signal at all.
330+
// run has no client UI generator and the config left `includeUiTier` unset, so
331+
// the page is skipped. Before this, that was silent: `meta gen` exited 0 and
332+
// listed only the pages it wrote, and a docs-only project (its own config
333+
// generates no UI; a SEPARATE config does) lost `agent/ui.md` with no signal at
334+
// all. An explicit `includeUiTier: false` says there is no UI anywhere, so a
335+
// server-only project has a way to say so and is not advised on every run.
334336
ctx.warn(
335-
`${dir}/ui.md not written: no client UI generator in this run; set includeUiTier: true if another config generates the UI.`,
337+
`${dir}/ui.md not written: no client UI generator in this run; set includeUiTier: true if another config generates the UI, or includeUiTier: false if there is no UI.`,
336338
);
337339
}
338340
}

0 commit comments

Comments
 (0)