Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Do not hand-edit `COMMAND_CATALOG`, `OPERATION_MEMBER_PATH_MAP`, `OPERATION_REFE
- `pnpm check:types` - raw TS compile across all referenced projects (`tsc -b tsconfig.references.json`). Does NOT run the public-interface chain. Legacy alias: `pnpm run type-check`.
- `pnpm check:public` - **canonical pre-merge command for typed public surfaces.** Validates both `superdoc` (tier discipline + jsdoc ratchet + vite build + postbuild chain + consumer typecheck matrix + deep-type audit + package-shape + snapshots + classification closure) and Document API (contract parity + output staleness + examples + overview). ~5 min. Non-mutating. Combines `check:public:superdoc` + `check:public:docapi`.
- `pnpm check:public:superdoc` - SuperDoc public package surface only. Wraps nine stages in cheap-to-expensive order: `contract-tiers-test`, `contract-tiers`, `jsdoc-ratchet`, `build`, `consumer-typecheck-matrix`, `deep-type-audit-supported-root`, `package-shape`, `export-snapshots`, `root-classification-closure`. Legacy alias: `pnpm run check:public-contract`.
- `pnpm check:public:docapi` - Document API public surface only. Clean-checkout safe: gitignored generated artifacts are built in memory; tracked outputs (reference docs, overview block) are compared byte-for-byte. No mutation. Legacy alias: `pnpm run docapi:check`.
- `pnpm check:public:docapi` - Document API public surface only. Wraps four stages: `contract-parity`, `contract-outputs`, `examples`, `overview-alignment`. Clean-checkout safe: gitignored generated artifacts are built in memory; tracked outputs (reference docs, overview block) are compared byte-for-byte. No mutation. Legacy alias: `pnpm run docapi:check`.
- `pnpm generate:docapi` - regenerate Document API outputs after editing the contract (alias of `docapi:sync`). Writes gitignored Document API generated artifacts. Run only when you need the artifacts materialized locally (SDK builds, publishing); `check:public:docapi` does not require it.
- `pnpm generate:all` - regenerate schemas, SDK clients, tool catalogs, reference docs.
- `pnpm report:public:superdoc` - print public-contract tier metadata (supported / legacy / legacy-raw / asset / deprecated). Read-only, not a gate. Use `check:public:superdoc` (or its `contract-tiers` stage) to enforce. Source of truth: `packages/superdoc/scripts/type-surface.config.cjs`.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"docapi:sync:check": "pnpm run generate:docapi && pnpm run check:public:docapi",
"check:types": "tsc -b tsconfig.references.json",
"check:public:superdoc": "node scripts/check-public-contract.mjs",
"check:public:docapi": "pnpm exec tsx packages/document-api/scripts/check-contract-parity.ts && pnpm exec tsx packages/document-api/scripts/check-contract-outputs.ts && pnpm exec tsx packages/document-api/scripts/check-examples.ts && pnpm exec tsx packages/document-api/scripts/check-overview-alignment.ts",
"check:public:docapi": "node scripts/check-public-docapi.mjs",
"check:public": "pnpm run check:public:superdoc && pnpm run check:public:docapi",
"generate:docapi": "pnpm exec tsx packages/document-api/scripts/generate-contract-outputs.ts",
"report:public:superdoc": "node scripts/report-public-contract.mjs",
Expand Down
17 changes: 11 additions & 6 deletions packages/superdoc/scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,17 @@ canonical source, and several artifacts are generated from it.
| `check-examples.ts` | check | Asserts contract examples compile. |
| `check-overview-alignment.ts` | check | Asserts the documentation overview reflects the current operation set. |

The four `check-*` scripts run together via `check:public:docapi` and
are **clean-checkout safe**: a fresh `git clone` followed by
`pnpm install && pnpm check:public` succeeds without `generate:docapi`
having run first. `generate:docapi` remains the explicit way to
materialize the gitignored artifacts when you need them locally (SDK
builds, publishing).
The four `check-*` scripts run together via `check:public:docapi`,
which invokes the staged wrapper at `scripts/check-public-docapi.mjs`.
Same shape as `check:public:superdoc`: cheap-to-expensive ordering,
named stages (`contract-parity`, `contract-outputs`, `examples`,
`overview-alignment`), stage headers + final elapsed time, and a
re-run hint on failure.

**Clean-checkout safe**: a fresh `git clone` followed by `pnpm install
&& pnpm check:public` succeeds without `generate:docapi` having run
first. `generate:docapi` remains the explicit way to materialize the
gitignored artifacts when you need them locally (SDK builds, publishing).

---

Expand Down
109 changes: 109 additions & 0 deletions scripts/check-public-docapi.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env node
/**
* Document API public-surface gate. Sibling of `check-public-contract.mjs`
* (SuperDoc); same staged shape, same failure UX.
*
* Non-mutating, clean-checkout safe: stage 2 builds gitignored
* artifacts in memory so `generate:docapi` is not a prerequisite.
* Cheap-to-expensive ordering — contract drift fails in seconds.
*
* Stages:
* 1. contract-parity - operation IDs, member maps, runtime API
* shape must agree.
* 2. contract-outputs - tracked outputs (reference docs, overview
* block) match the contract; gitignored
* outputs (schemas, agent artifacts) are
* built in memory so builder errors still
* surface. The longest stage.
* 3. examples - required workflow example headings exist
* in `packages/document-api/src/README.md`.
* 4. overview-alignment - `apps/docs/document-api/available-
* operations.mdx` structural correctness:
* reference link, section markers, every
* `editor.doc.*` path references a known
* member.
*
* Local usage:
* pnpm check:public (umbrella, runs SuperDoc + Document API)
* pnpm check:public:docapi (Document API only, this script)
*
* Legacy alias preserved: `pnpm run docapi:check`.
*/

import { spawnSync } from 'node:child_process';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';

const REPO_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');

const stages = [
{
name: 'contract-parity',
cwd: REPO_ROOT,
cmd: 'pnpm',
args: ['exec', 'tsx', 'packages/document-api/scripts/check-contract-parity.ts'],
blurb:
'Operation IDs, operation/member maps, and runtime API shape must agree. ' +
'Fast; runs first so contract drift fails before slower stages.',
},
{
name: 'contract-outputs',
cwd: REPO_ROOT,
cmd: 'pnpm',
args: ['exec', 'tsx', 'packages/document-api/scripts/check-contract-outputs.ts'],
blurb:
'Tracked outputs (reference docs, overview block) compared byte-for-byte. ' +
'Gitignored outputs (schemas, agent artifacts) built in memory; no need to ' +
'run `pnpm run generate:docapi` first.',
},
{
name: 'examples',
cwd: REPO_ROOT,
cmd: 'pnpm',
args: ['exec', 'tsx', 'packages/document-api/scripts/check-examples.ts'],
blurb:
'Required workflow example headings exist in ' +
'packages/document-api/src/README.md.',
},
{
name: 'overview-alignment',
cwd: REPO_ROOT,
cmd: 'pnpm',
args: ['exec', 'tsx', 'packages/document-api/scripts/check-overview-alignment.ts'],
blurb:
'Overview page structure: reference link, section markers, no stale ' +
'placeholders, every `editor.doc.*` path references a known member.',
},
];

const HR = '='.repeat(72);
const start = Date.now();

let failed = null;
for (const [i, s] of stages.entries()) {
console.log('');
console.log(HR);
console.log(`[${i + 1}/${stages.length}] ${s.name}`);
console.log(s.blurb);
console.log(HR);
const result = spawnSync(s.cmd, s.args, { cwd: s.cwd, stdio: 'inherit' });
if (result.status !== 0) {
failed = { stage: s.name, status: result.status ?? 1 };
break;
}
}

const elapsed = ((Date.now() - start) / 1000).toFixed(1);
console.log('');
console.log(HR);
if (failed) {
console.log(`FAIL: stage "${failed.stage}" exited ${failed.status} (after ${elapsed}s)`);
console.log('');
console.log('Re-run the failing stage directly to iterate:');
const failedStage = stages.find((s) => s.name === failed.stage);
console.log(` cd ${failedStage.cwd}`);
console.log(` ${failedStage.cmd} ${failedStage.args.join(' ')}`);
process.exit(failed.status);
} else {
console.log(`PASS: ${stages.length} stages, ${elapsed}s`);
}
Loading