From f8cde9ad95c37a9c92b5affe5f00337471f91272 Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Sun, 24 May 2026 08:04:35 -0300 Subject: [PATCH 1/2] refactor(typecheck): stage check:public:docapi behind a wrapper script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DocAPI parity with SuperDoc. The four check-* scripts previously ran as a single `&&` chain in root package.json: cmd1 && cmd2 && cmd3 && cmd4 That gave no per-stage timing, no progress markers, no failure-rerun hint, and no place to document why each stage exists. scripts/check-public-docapi.mjs adopts the same shape as scripts/check-public-contract.mjs: 1. contract-parity - operation IDs / member maps / runtime shape agree 2. contract-outputs - tracked outputs match the contract; gitignored outputs built in memory 3. examples - required workflow example headings exist 4. overview-alignment - overview MDX structural correctness Same display-name convention as the SuperDoc wrapper: plain kebab, scope-only, no `check-` prefix, no flags-in-names. Cheap-to-expensive ordering. Re-run hint on failure prints the actual command. Root package.json change is a one-liner: check:public:docapi now invokes `node scripts/check-public-docapi.mjs`. `docapi:check` legacy alias preserved. Verified: - pnpm check:public:docapi → PASS, 4 stages, 2.0s - pnpm check:public → PASS (both wrappers, end-to-end) - pnpm check:types → PASS --- AGENTS.md | 2 +- package.json | 2 +- packages/superdoc/scripts/README.md | 16 ++-- scripts/check-public-docapi.mjs | 109 ++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 8 deletions(-) create mode 100644 scripts/check-public-docapi.mjs diff --git a/AGENTS.md b/AGENTS.md index 444e912221..eb59352d55 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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`. diff --git a/package.json b/package.json index d206948dfe..ac9a86ab93 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/packages/superdoc/scripts/README.md b/packages/superdoc/scripts/README.md index aabe3dc2c1..ca89c464e6 100644 --- a/packages/superdoc/scripts/README.md +++ b/packages/superdoc/scripts/README.md @@ -178,12 +178,16 @@ 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`), per-stage timing, 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). --- diff --git a/scripts/check-public-docapi.mjs b/scripts/check-public-docapi.mjs new file mode 100644 index 0000000000..19b51cbf8c --- /dev/null +++ b/scripts/check-public-docapi.mjs @@ -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`); +} From 351cf49c3ccfd97e6306a4aa50ba98864400c736 Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Sun, 24 May 2026 08:08:17 -0300 Subject: [PATCH 2/2] docs(typecheck): correct README wording on docapi wrapper timing The wrapper reports total elapsed time at the end, not per-stage timing. Match what the script actually prints. --- packages/superdoc/scripts/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/superdoc/scripts/README.md b/packages/superdoc/scripts/README.md index ca89c464e6..a4a51636d3 100644 --- a/packages/superdoc/scripts/README.md +++ b/packages/superdoc/scripts/README.md @@ -182,7 +182,8 @@ 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`), per-stage timing, and a re-run hint on failure. +`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