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
* feat(cli): lint ```metadata doc embeds — body shape + reference liveness (ADR-0051 P1)
Completes the ADR-0051 P1 publish lint. `collectAndLintDocs` (run by
`os compile` / `os lint`, which already pass the assembled stack) now
also validates every ```metadata fence:
- body shape: `type` ∈ {state_machine, flow, permission} (did-you-mean
on a typo'd type), `name` required, `object` required for
state_machine.
- reference liveness against the package's OWN metadata: the object +
named state_machine rule, the flow, or the permission set must exist
in this stack. A dead same-package reference is a build error (same
posture as docs/broken-link), with did-you-mean hints. Cross-package
embeds are out of v1 scope.
Note: scans share `stripCode()` which DELETES fenced blocks, so the
embed scan walks raw lines instead. The body parser mirrors the
objectui-side one so build-time and render-time agree.
Tests: 8 cases (valid trio, unknown type, missing name/object, dead
object/rule/flow/permission refs, non-metadata fences ignored, locale
variants). Verified the real app-showcase doc lints clean (no false
positives) with a typo'd-ref negative control.
No CLI build fix was needed: a clean dependency-ordered build
(`turbo run build --filter=@objectstack/cli`, 52/52) passes; the
previously-seen `validate-expressions.ts` / adr-0048-test errors were
stale/unbuilt local `dist`, not a code defect.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore(changeset): @objectstack/cli minor for ADR-0051 metadata-embed lint
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(cli): lint `metadata` doc embeds (ADR-0051 P1) — validate every `metadata` fence body shape (type ∈ state_machine | flow | permission with did-you-mean, required name, object required for state_machine) and its same-package reference liveness (the referenced object + state_machine rule / flow / permission set must exist in the stack). A dead same-package reference is a build error, matching `docs/broken-link`.
err('docs/metadata-embed',`metadata embed in "${docName}" has unknown type "${type}"${s ? ` — did you mean \`${s}\`?` : ` (expected ${METADATA_EMBED_TYPES.join(', ')})`}.`);
434
+
continue;
435
+
}
436
+
if(!f.name){
437
+
err('docs/metadata-embed',`metadata embed (${type}) in "${docName}" is missing \`name\`.`);
438
+
continue;
439
+
}
440
+
441
+
// ── reference liveness (same-package) ──
442
+
if(type==='state_machine'){
443
+
if(!f.object){
444
+
err('docs/metadata-embed',`state_machine embed "${f.name}" in "${docName}" is missing \`object\` (a state machine is a rule on an object).`);
445
+
continue;
446
+
}
447
+
constobj=objByName.get(f.object);
448
+
if(!obj){
449
+
consts=nearest(f.object,[...objByName.keys()]);
450
+
err('docs/metadata-embed-ref',`state_machine embed in "${docName}" references object "${f.object}", which does not exist in this package${s ? ` — did you mean \`${s}\`?` : ''}.`);
err('docs/metadata-embed-ref',`state_machine embed in "${docName}" references "${f.name}", but object "${f.object}" has no state_machine rule with that name${s ? ` — did you mean \`${s}\`?` : ''}.`);
460
+
}
461
+
}elseif(type==='flow'){
462
+
if(!flowNames.includes(f.name)){
463
+
consts=nearest(f.name,flowNames);
464
+
err('docs/metadata-embed-ref',`flow embed in "${docName}" references flow "${f.name}", which does not exist in this package${s ? ` — did you mean \`${s}\`?` : ''}.`);
465
+
}
466
+
}elseif(type==='permission'){
467
+
if(!permNames.includes(f.name)){
468
+
consts=nearest(f.name,permNames);
469
+
err('docs/metadata-embed-ref',`permission embed in "${docName}" references permission set "${f.name}", which does not exist in this package${s ? ` — did you mean \`${s}\`?` : ''}.`);
0 commit comments