@orkestrel/scaffold 0.0.77 → 0.0.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/skills/orkestrel-dispatch/scripts/bench.js +204 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/brief.js +102 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/cite.js +95 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/helpers.js +207 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/launch.js +108 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/login.js +114 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/result.js +108 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/sweep.js +156 -0
- package/dist/agents/skills/orkestrel-harden/scripts/discovery.js +196 -0
- package/dist/agents/skills/orkestrel-publish/scripts/compare.js +206 -0
- package/dist/agents/skills/orkestrel-publish/scripts/pins.js +93 -0
- package/dist/agents/skills/orkestrel-publish/scripts/wave.js +458 -0
- package/dist/agents/skills/orkestrel-publish/scripts/window.js +188 -0
- package/dist/agents/skills/orkestrel-scout/scripts/map.js +300 -0
- package/dist/agents/templates/brief.md +55 -0
- package/dist/bin/main.js +4 -2
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +77 -135
- package/dist/host/agents/orchestration.md +147 -998
- package/dist/host/agents/skills/enterprise-bootstrap/SKILL.md +2 -2
- package/dist/host/agents/skills/enterprise-bootstrap/references/inspection.md +1 -1
- package/dist/host/agents/skills/{orkestrel-align-packages → orkestrel-align}/SKILL.md +6 -13
- package/dist/host/agents/skills/{orkestrel-align-packages → orkestrel-align}/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/{orkestrel-align-packages → orkestrel-align}/references/fleet.md +5 -7
- package/dist/host/agents/skills/{orkestrel-build-application → orkestrel-build}/SKILL.md +11 -22
- package/dist/host/agents/skills/{orkestrel-build-application → orkestrel-build}/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +8 -16
- package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +3 -3
- package/dist/host/agents/skills/orkestrel-debrief/references/retention.md +13 -13
- package/dist/host/agents/skills/orkestrel-dispatch/SKILL.md +61 -0
- package/dist/host/agents/skills/orkestrel-dispatch/agents/openai.yaml +4 -0
- package/dist/host/agents/skills/orkestrel-dispatch/references/bench.md +25 -0
- package/dist/host/agents/skills/orkestrel-dispatch/references/launch.md +32 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/bench.ts +259 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/brief.ts +110 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/cite.ts +115 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/helpers.ts +239 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/launch.ts +124 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/login.ts +123 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/result.ts +129 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/sweep.ts +157 -0
- package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +42 -193
- package/dist/host/agents/skills/orkestrel-falsify/references/brief.md +38 -108
- package/dist/host/agents/skills/orkestrel-falsify/references/reconcile.md +35 -134
- package/dist/host/agents/skills/{orkestrel-harden-package → orkestrel-harden}/SKILL.md +10 -14
- package/dist/host/agents/skills/{orkestrel-harden-package → orkestrel-harden}/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/{orkestrel-harden-package → orkestrel-harden}/references/hardening.md +3 -4
- package/dist/host/agents/skills/orkestrel-harden/scripts/discovery.ts +228 -0
- package/dist/host/agents/skills/{orkestrel-prove-journey → orkestrel-journey}/SKILL.md +15 -23
- package/dist/host/agents/skills/orkestrel-journey/agents/openai.yaml +4 -0
- package/dist/host/agents/skills/{orkestrel-prove-journey → orkestrel-journey}/references/captures.md +1 -1
- package/dist/host/agents/skills/{orkestrel-polish-surface → orkestrel-polish}/SKILL.md +25 -33
- package/dist/host/agents/skills/{orkestrel-polish-surface → orkestrel-polish}/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/{orkestrel-polish-surface → orkestrel-polish}/references/capture-harness.md +3 -3
- package/dist/host/agents/skills/orkestrel-publish/SKILL.md +33 -20
- package/dist/host/agents/skills/orkestrel-publish/references/release.md +39 -0
- package/dist/host/agents/skills/orkestrel-publish/references/wave.md +22 -21
- package/dist/host/agents/skills/orkestrel-publish/references/window.md +27 -14
- package/dist/host/agents/skills/orkestrel-publish/scripts/compare.ts +220 -0
- package/dist/host/agents/skills/orkestrel-publish/scripts/pins.ts +114 -0
- package/dist/host/agents/skills/orkestrel-publish/scripts/wave.ts +629 -0
- package/dist/host/agents/skills/orkestrel-publish/scripts/window.ts +242 -0
- package/dist/host/agents/skills/orkestrel-scout/SKILL.md +28 -0
- package/dist/host/agents/skills/orkestrel-scout/agents/openai.yaml +4 -0
- package/dist/host/agents/skills/orkestrel-scout/scripts/map.ts +352 -0
- package/dist/host/agents/templates/brief.md +21 -142
- package/dist/host/agents/transports/claude-cli.md +21 -0
- package/dist/host/agents/transports/codex.md +38 -159
- package/dist/host/agents/transports/cursor.md +16 -65
- package/dist/host/claude/AGENTS.md +38 -0
- package/dist/host/claude/agents/analyst.md +14 -53
- package/dist/host/claude/agents/astra.md +26 -0
- package/dist/host/claude/agents/builder.md +14 -30
- package/dist/host/claude/agents/checker.md +13 -57
- package/dist/host/claude/agents/distiller.md +11 -26
- package/dist/host/claude/agents/grok.md +12 -35
- package/dist/host/claude/agents/opus.md +14 -30
- package/dist/host/claude/agents/planner.md +10 -44
- package/dist/host/claude/agents/researcher.md +11 -30
- package/dist/host/claude/agents/reviewer.md +11 -95
- package/dist/host/claude/agents/scout.md +9 -23
- package/dist/host/claude/agents/verifier.md +15 -33
- package/dist/host/claude/rules/documentation.md +8 -2
- package/dist/host/claude/rules/portability.md +7 -1
- package/dist/host/claude/rules/quality.md +36 -96
- package/dist/host/claude/rules/styles.md +3 -0
- package/dist/host/claude/rules/tests.md +6 -3
- package/dist/host/claude/rules/workspace.md +19 -15
- package/dist/host/claude/rules/writing.md +57 -108
- package/dist/host/claude/settings.json +5 -3
- package/dist/host/claude/skills/enterprise-bootstrap/SKILL.md +1 -1
- package/dist/host/claude/skills/{orkestrel-align-packages → orkestrel-align}/SKILL.md +2 -2
- package/dist/host/claude/skills/{orkestrel-build-application → orkestrel-build}/SKILL.md +2 -2
- package/dist/host/claude/skills/orkestrel-dispatch/SKILL.md +11 -0
- package/dist/host/claude/skills/orkestrel-falsify/SKILL.md +2 -1
- package/dist/host/claude/skills/{orkestrel-harden-package → orkestrel-harden}/SKILL.md +2 -2
- package/dist/host/claude/skills/{orkestrel-prove-journey → orkestrel-journey}/SKILL.md +2 -2
- package/dist/host/claude/skills/orkestrel-polish/SKILL.md +12 -0
- package/dist/host/claude/skills/orkestrel-scout/SKILL.md +11 -0
- package/dist/host/codex/agents/analyst.toml +14 -31
- package/dist/host/codex/agents/astra.toml +25 -0
- package/dist/host/codex/agents/builder.toml +13 -20
- package/dist/host/codex/agents/checker.toml +13 -27
- package/dist/host/codex/agents/distiller.toml +9 -22
- package/dist/host/codex/agents/grok.toml +11 -30
- package/dist/host/codex/agents/opus.toml +14 -22
- package/dist/host/codex/agents/orkestrel.toml +1 -1
- package/dist/host/codex/agents/planner.toml +11 -28
- package/dist/host/codex/agents/researcher.toml +10 -22
- package/dist/host/codex/agents/reviewer.toml +11 -27
- package/dist/host/codex/agents/scout.toml +11 -17
- package/dist/host/codex/agents/verifier.toml +16 -12
- package/dist/host/codex/config.toml +18 -21
- package/dist/host/cursor/mcp.json +0 -4
- package/dist/host/cursor/rules/orchestration.mdc +12 -20
- package/dist/host/dotfiles/mcp.json +0 -4
- package/dist/host/dotfiles/oxlintrc.json +7 -0
- package/dist/host/guides/probe.md +9 -9
- package/dist/host/guides/scaffold.md +117 -71
- package/dist/host/guides/test.md +1 -1
- package/dist/host/manifest.json +321 -184
- package/dist/host/scripts/codex.sh +0 -0
- package/dist/host/scripts/cursor.sh +0 -0
- package/dist/host/scripts/deps.sh +0 -0
- package/dist/host/scripts/ollama.sh +0 -0
- package/dist/host/tests/config.test.ts +68 -46
- package/dist/host/tests/policy.test.ts +1 -5
- package/dist/host/tests/setupPolicy.ts +179 -4
- package/dist/src/core/index.cjs +255 -84
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +94 -29
- package/dist/src/core/index.d.ts +94 -29
- package/dist/src/core/index.js +253 -85
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +55 -9
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +29 -4
- package/dist/src/server/index.d.ts +29 -4
- package/dist/src/server/index.js +56 -11
- package/dist/src/server/index.js.map +1 -1
- package/package.json +15 -11
- package/dist/host/CLAUDE.md +0 -61
- package/dist/host/agents/skills/orkestrel-prove-journey/agents/openai.yaml +0 -4
- package/dist/host/agents/transports/claude.md +0 -49
- package/dist/host/claude/agents/application.md +0 -36
- package/dist/host/claude/agents/sol.md +0 -61
- package/dist/host/claude/skills/orkestrel-polish-surface/SKILL.md +0 -12
- package/dist/host/codex/agents/application.toml +0 -25
- package/dist/host/codex/agents/sol.toml +0 -19
- /package/dist/host/agents/skills/{orkestrel-align-packages → orkestrel-align}/references/integration.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-harden-package → orkestrel-harden}/references/centralization.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-harden-package → orkestrel-harden}/references/contract.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-harden-package → orkestrel-harden}/references/research.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-prove-journey → orkestrel-journey}/references/decide.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-prove-journey → orkestrel-journey}/references/layer.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-prove-journey → orkestrel-journey}/references/statechart.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-prove-journey → orkestrel-journey}/references/styles.md +0 -0
|
@@ -101,7 +101,7 @@ export declare const ARTIFACT_TEMPLATES: Readonly<{
|
|
|
101
101
|
entry: "import * as entry from {{specifier}}\nimport { describe, expect, it } from 'vitest'\n\ndescribe({{label}}, () => {\n\tit('has no starter exports', () => {\n\t\texpect(Object.keys(entry)).toStrictEqual([])\n\t})\n})\n";
|
|
102
102
|
bin: "import { describe, expect, it } from 'vitest'\n\ndescribe('bin entry', () => {\n\tit('has no starter exports', async () => {\n{{import}}\n\t\texpect(Object.keys(entry)).toStrictEqual([])\n\t})\n})\n";
|
|
103
103
|
distribution: Readonly<{
|
|
104
|
-
proof: "// The artifact a consumer installs, measured rather than described. This workspace\n// is packed and installed into a throwaway consumer, and every following claim is read\n// off that installed tree: the exports map it publishes, the declarations it ships,\n// and the module objects a real runtime hands a consumer. Nothing here names this\n// package, one of its exports, or how many there are, so the proof stays true as\n// the published surface moves.\n{{types}}import type { SpawnSyncReturns } from 'node:child_process'\nimport type { TestContext } from 'vitest'\nimport { spawnSync } from 'node:child_process'\nimport {\n\texistsSync,\n\tmkdirSync,\n\tmkdtempSync,\n\treaddirSync,\n\treadFileSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from 'node:fs'\n{{transport}}import { createRequire } from 'node:module'\nimport { tmpdir } from 'node:os'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n{{launcher}}import { afterAll, describe, expect, it } from 'vitest'\n\nconst ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')\nconst NPM = process.platform === 'win32' ? 'npm.cmd' : 'npm'\n// The compiler this workspace installs, run as a command rather than called in\n// process: the command and its plain-text diagnostics are the same across the\n// compiler majors this toolchain supports, and its in-process API is not. It is\n// resolved from the workspace under proof, so a consumer of the packed artifact is\n// checked by the same compiler that workspace's own `check` script runs.\nconst TSC = createRequire(join(ROOT, 'package.json')).resolve('typescript/bin/tsc')\n// Windows needs a shell to launch a `.cmd`: Node refuses one directly since the\n// batch-argument hardening, and `spawnSync` returns `EINVAL` with a null status\n// rather than an exit code a caller can read. Every following argument is a literal or\n// a path this file built, so the shell has nothing to escape.\nconst SHELL = process.platform === 'win32'\n// `prepublishOnly` runs this proof as `npm run test:distribution -- --mode release`.\n// Release is the publish gate, so evidence it cannot obtain fails there and skips\n// everywhere else: a gate that passes on missing evidence proves nothing.\nconst RELEASE = import.meta.env.MODE === 'release'\n// The built output directory convention a browser face may publish from. Every\n// selection reads this prefix off the export target and never off the subpath name. A\n// workspace whose only published face is the browser one publishes that face at the\n// root subpath, so a rule keyed on the subpath name drives a browser bundle through\n// Node and the miss is silent.\nconst BROWSER_OUTPUT = './dist/src/browser/'\nconst ABSENT_SUBPATH = '/no-subpath-is-published-under-this-name'\n// A compiler diagnostic that says where it is: the path relative to the directory\n// the compiler ran in, the 1-based line and column, the code, and the message. The\n// diagnostics are the verdict rather than the exit code, which differs between the\n// compiler majors this toolchain supports, so a reported line matching nothing here\n// came from something other than a check of a consumer module.\nconst DIAGNOSTIC_PATTERN = /^(.+?)\\(\\d+,\\d+\\): error TS\\d+: /u\nconst PING = ['ping', '--fetch-retries=0', '--fetch-timeout=5000', '--loglevel=silent']\nconst ESM_DRIVER = 'drive.mjs'\nconst CJS_DRIVER = 'drive.cjs'\nconst CONSUMER_MANIFEST = `{ \"name\": \"distribution-consumer\", \"private\": true, \"type\": \"module\" }\\n`\nconst ESM_DRIVER_SOURCE = `const entry = await import(process.argv[2])\nprocess.stdout.write(JSON.stringify(Object.keys(entry).sort()))\n`\nconst CJS_DRIVER_SOURCE = `const entry = require(process.argv[2])\nprocess.stdout.write(JSON.stringify(Object.keys(entry).sort()))\n`\n\n// The extensions a JavaScript handler loads as modules. Node loads a native addon\n// through its addon handler instead, so that extension is named separately.\nconst MODULE_EXTENSIONS = ['.js', '.mjs', '.cjs']\nconst ADDON_EXTENSION = '.node'\n// The extensions a declaration file carries. A `require` condition declares\n// `.d.cts` and an ESM-only one `.d.mts`, so the `.d.ts` spelling alone does not\n// name them.\nconst DECLARATION_EXTENSIONS = ['.d.ts', '.d.cts', '.d.mts']\ntype Format = 'module' | 'commonjs'\n\n// The Node import target is resolved with the conditions that driver supplies. The\n// CommonJS compile probe is selected from its declaration's format, and its runtime\n// drive loads the same subpath through Node's require resolver. Vite's production\n// client build enables its module and browser conditions.\nconst RUNTIME_CONDITIONS = Object.freeze({\n\tmodule: Object.freeze(['node-addons', 'node', 'import', 'module-sync']),\n\tcommonjs: Object.freeze(['node-addons', 'node', 'require', 'module-sync']),\n\tbrowser: Object.freeze(['module', 'browser', 'production', 'import']),\n})\n// TypeScript's Node resolutions add `node` to the format condition. Its bundler\n// resolution does not, so a browser drive compares against the declaration a bundler\n// consumer reads rather than borrowing the Node declaration.\nconst BUNDLER_CONDITIONS = Object.freeze({\n\tmodule: ['types', 'import'],\n\tcommonjs: ['types', 'require'],\n})\nconst DECLARATION_CONDITIONS = Object.freeze({\n\tmodule: ['types', 'node', 'import'],\n\tcommonjs: ['types', 'node', 'require'],\n\tbrowser: BUNDLER_CONDITIONS.module,\n})\n\ninterface Resolution {\n\treadonly label: string\n\treadonly resolution: string\n\treadonly module: string\n\treadonly conditions: Readonly<Record<Format, readonly string[]>>\n}\n\ninterface TargetResolution {\n\treadonly target: string\n}\n\n// Each compile driver carries the compiler options its scratch project sets and\n// the conditions TypeScript applies for that resolution and importing format. A\n// `require`-only subpath therefore stays in each CommonJS probe that can resolve it.\n// The option values are the spellings the project file takes, so nothing here needs\n// the compiler's own API to name them.\nconst RESOLUTIONS: readonly Resolution[] = [\n\t{\n\t\tlabel: 'node16',\n\t\tresolution: 'node16',\n\t\tmodule: 'node16',\n\t\tconditions: DECLARATION_CONDITIONS,\n\t},\n\t{\n\t\tlabel: 'nodenext',\n\t\tresolution: 'nodenext',\n\t\tmodule: 'nodenext',\n\t\tconditions: DECLARATION_CONDITIONS,\n\t},\n\t{\n\t\tlabel: 'bundler',\n\t\tresolution: 'bundler',\n\t\tmodule: 'esnext',\n\t\tconditions: BUNDLER_CONDITIONS,\n\t},\n]\n\n// The driver a bundled consumer reads declarations under. A browser application\n// compiles through a bundler, so the browser drive answers under this one alone,\n// and naming it here is what keeps that selection tied to the driver it selects.\nconst BROWSER_DRIVER = RESOLUTIONS.find((candidate) => candidate.label === 'bundler')\nif (BROWSER_DRIVER === undefined) throw new Error(\"RESOLUTIONS carries no 'bundler' row\")\n\nconst FORMATS: ReadonlyArray<readonly [extension: string, format: Format]> = [\n\t['ts', 'module'],\n\t['cts', 'commonjs'],\n]\n\n// One published subpath, resolved to what this proof can drive: the specifier a\n// consumer writes, whether the declarations its consumer formats resolve at all,\n// whether the exports map answers the browser condition with a target of its own,\n// whether it answers `import` and `require` at all, and whether the target that\n// `require` answers with is one that a CommonJS consumer loads.\ninterface Entry {\n\treadonly subpath: string\n\treadonly specifier: string\n\treadonly mapping: unknown\n\treadonly declaration: {\n\t\treadonly importable: boolean\n\t\treadonly requirable: boolean\n\t\treadonly browsable: boolean\n\t}\n\treadonly browsable: boolean\n\treadonly importable: boolean\n\treadonly requirable: boolean\n\treadonly loadable: boolean\n}\n\n// The installed tree every claim is read from. Every subpath the exports map names\n// lands in exactly one of `entries`, `undeclared`, and `excluded`, so a subpath this\n// proof cannot drive is reported rather than dropped.\ninterface Stage {\n\treadonly consumer: string\n\treadonly installed: string\n\treadonly archives: readonly string[]\n\treadonly entries: readonly Entry[]\n\treadonly subpaths: readonly string[]\n\treadonly undeclared: readonly string[]\n\treadonly excluded: readonly string[]\n\treadonly targets: readonly string[]\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction isNames(value: unknown): value is readonly string[] {\n\treturn Array.isArray(value) && value.every((name) => typeof name === 'string')\n}\n\n// A fallback list, which is what Node reads an array in an exports entry as. The\n// narrowing is what the following walkers need: `Array.isArray` widens an `unknown`\n// member to `any`, and an entry read that way is not read at all.\nfunction isList(value: unknown): value is readonly unknown[] {\n\treturn Array.isArray(value)\n}\n\n// Whether a string is a valid package target. Node rejects a target outside the\n// package and a target containing a dot, parent, or node_modules segment during\n// package-target resolution. A later module-resolution failure is not the same\n// thing: an array falls through the former and keeps the latter.\nfunction isPackageTarget(target: string): boolean {\n\tif (!target.startsWith('./')) return false\n\tfor (const segment of target.slice(2).split(/[\\\\/]/u)) {\n\t\tlet decoded = segment\n\t\ttry {\n\t\t\tdecoded = decodeURIComponent(segment)\n\t\t} catch {}\n\t\tconst normalized = decoded.toLowerCase()\n\t\tif (normalized === '.' || normalized === '..' || normalized === 'node_modules') return false\n\t}\n\treturn true\n}\n\nfunction readJson(path: string): unknown {\n\tconst parsed: unknown = JSON.parse(readFileSync(path, 'utf8'))\n\treturn parsed\n}\n\nfunction readManifestName(path: string): string {\n\tconst manifest = readJson(path)\n\tif (!isRecord(manifest) || typeof manifest.name !== 'string') {\n\t\tthrow new Error(`The manifest at ${path} declares no package name`)\n\t}\n\treturn manifest.name\n}\n\nfunction writeFile(path: string, content: string): void {\n\tmkdirSync(dirname(path), { recursive: true })\n\twriteFileSync(path, content)\n}\n\nfunction readOutput(result: SpawnSyncReturns<string>): string {\n\treturn `${result.stdout ?? ''}${result.stderr ?? ''}`.trim()\n}\n\nfunction runNpm(args: readonly string[], cwd: string): SpawnSyncReturns<string> {\n\treturn spawnSync(NPM, [...args], {\n\t\tcwd,\n\t\tencoding: 'utf8',\n\t\tenv: { ...process.env, npm_config_cache: CACHE },\n\t\tshell: SHELL,\n\t\twindowsHide: true,\n\t})\n}\n\nfunction runNode(args: readonly string[], cwd: string): SpawnSyncReturns<string> {\n\treturn spawnSync(process.execPath, [...args], { cwd, encoding: 'utf8', windowsHide: true })\n}\n\n// Node's own condition matching, read in declaration order.\nfunction resolvePackageTarget(\n\tentry: unknown,\n\tconditions: readonly string[],\n): TargetResolution | undefined {\n\tif (typeof entry === 'string') return { target: entry }\n\tif (isList(entry)) {\n\t\tfor (const member of entry) {\n\t\t\tconst resolved = resolvePackageTarget(member, conditions)\n\t\t\tif (resolved !== undefined && isPackageTarget(resolved.target)) return resolved\n\t\t}\n\t\treturn undefined\n\t}\n\tif (!isRecord(entry)) return undefined\n\tfor (const [condition, nested] of Object.entries(entry)) {\n\t\tif (condition !== 'default' && !conditions.includes(condition)) continue\n\t\tconst resolved = resolvePackageTarget(nested, conditions)\n\t\tif (resolved !== undefined) return resolved\n\t}\n\treturn undefined\n}\n\n// A flat entry, a condition-nested entry, and a fallback list all resolve through\n// one walker. An entry may declare `types` beside `default` at its top level\n// rather than inside `import`, so a fixed `entry.import.types` lookup is not\n// equivalent to condition resolution.\nfunction resolveTarget(entry: unknown, conditions: readonly string[]): string | undefined {\n\treturn resolvePackageTarget(entry, conditions)?.target\n}\n\n// Whether a path is a physical file. TypeScript's file-existence check refuses a\n// directory at the same spelling and continues to the outer package scope.\nfunction matchesFile(path: string): boolean {\n\ttry {\n\t\treturn statSync(path).isFile()\n\t} catch {\n\t\treturn false\n\t}\n}\n\n// TypeScript resolves a declaration target by accepting an existing declaration\n// directly or by substituting beside a JavaScript target. A missing target leaves\n// the containing condition or fallback list unresolved, so the walk continues.\nfunction targetToDeclaration(target: string, installed: string): string | undefined {\n\tif (!isPackageTarget(target)) return undefined\n\tlet declaration = target\n\tif (target.endsWith('.cjs')) declaration = `${target.slice(0, -4)}.d.cts`\n\telse if (target.endsWith('.mjs')) declaration = `${target.slice(0, -4)}.d.mts`\n\telse if (target.endsWith('.js')) declaration = `${target.slice(0, -3)}.d.ts`\n\telse if (!isDeclaration(target)) return undefined\n\treturn matchesFile(join(installed, declaration)) ? declaration : undefined\n}\n\n// The declaration TypeScript resolves through one importing format's conditions.\n// Condition objects keep manifest order, and arrays keep fallback order.\nfunction resolveDeclaration(\n\tentry: unknown,\n\tconditions: readonly string[],\n\tinstalled: string,\n): string | undefined {\n\tif (typeof entry === 'string') return targetToDeclaration(entry, installed)\n\tif (isList(entry)) {\n\t\tfor (const member of entry) {\n\t\t\tconst resolved = resolveDeclaration(member, conditions, installed)\n\t\t\tif (resolved !== undefined) return resolved\n\t\t}\n\t\treturn undefined\n\t}\n\tif (!isRecord(entry)) return undefined\n\tfor (const [condition, nested] of Object.entries(entry)) {\n\t\tif (condition !== 'default' && !conditions.includes(condition)) continue\n\t\tconst resolved = resolveDeclaration(nested, conditions, installed)\n\t\tif (resolved !== undefined) return resolved\n\t}\n\treturn undefined\n}\n\n// The nearest package scope that decides a `.d.ts` declaration's module format. A\n// physical nested manifest starts a scope even when it omits `type` or cannot be\n// parsed. A directory at that spelling is not a manifest, so the walk continues.\nfunction readPackageType(installed: string, target: string): unknown {\n\tlet directory = dirname(join(installed, target))\n\twhile (true) {\n\t\tconst path = join(directory, 'package.json')\n\t\tif (matchesFile(path)) {\n\t\t\ttry {\n\t\t\t\tconst manifest = readJson(path)\n\t\t\t\treturn isRecord(manifest) ? manifest.type : undefined\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t}\n\t\tif (directory === installed) return undefined\n\t\tconst parent = dirname(directory)\n\t\tif (parent === directory) return undefined\n\t\tdirectory = parent\n\t}\n}\n\nfunction resolvesBrowser(entry: unknown): boolean {\n\tconst module = resolveTarget(entry, RUNTIME_CONDITIONS.browser)\n\tif (module !== undefined && module.startsWith(BROWSER_OUTPUT)) return true\n\tif (module === undefined) return false\n\tconst imported = resolveTarget(entry, RUNTIME_CONDITIONS.module)\n\tconst required = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)\n\treturn module !== imported && module !== required\n}\n\n// Whether the target selected by Node's CommonJS conditions is a module require can\n// load. A JavaScript target takes its own nearest package scope. Native addons and\n// extensionless targets have their own CommonJS handlers.\nfunction resolvesCommonJS(entry: unknown, installed: string): boolean {\n\tconst target = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)\n\tif (target === undefined) return false\n\tconst name = target.slice(target.lastIndexOf('/') + 1)\n\tif (name.endsWith('.cjs')) return true\n\tif (name.endsWith('.mjs')) return false\n\tif (name.endsWith('.node')) return true\n\tif (!name.includes('.')) return true\n\treturn name.endsWith('.js') && readPackageType(installed, target) !== 'module'\n}\n\n// Whether the declaration selected by a typed CommonJS consumer admits that entry.\n// A `.d.cts` declaration admits and a `.d.mts` declaration refuses. A `.d.ts`\n// declaration takes its own nearest package scope.\nfunction declaresCommonJS(entry: unknown, installed: string): boolean {\n\tconst declaration = resolveDeclaration(entry, DECLARATION_CONDITIONS.commonjs, installed)\n\tif (declaration === undefined) return false\n\tif (declaration.endsWith('.d.cts')) return true\n\tif (declaration.endsWith('.d.mts')) return false\n\treturn declaration.endsWith('.d.ts') && readPackageType(installed, declaration) !== 'module'\n}\n\n// Every target an entry names under any condition. A fallback list omits members\n// Node rejects during package-target validation, because no reader can take them.\nfunction collectTargets(entry: unknown): readonly string[] {\n\tif (typeof entry === 'string') return [entry]\n\tif (isList(entry)) return entry.flatMap(collectTargets).filter(isPackageTarget)\n\tif (!isRecord(entry)) return []\n\treturn Object.values(entry).flatMap((nested) => collectTargets(nested))\n}\n\n// Whether a target is a file a runtime loads for its names, which is what a\n// declaration is owed for. The extension on the target's own file name decides it,\n// and a name carrying no extension is code: `require` reads such a file through its\n// JavaScript handler, so an extensionless target loads and publishes names. Node\n// loads `.node` through its native-addon handler. Every other extension is an asset\n// a consumer reads rather than imports — a stylesheet, a WebAssembly binary, the\n// `\"./package.json\"` manifest pointer, and a declaration alike.\n// The cost is an extensionless file published for a reader, such as a `LICENSE`:\n// that target reports undeclared until it is given an extension or a declaration.\nfunction isModule(target: string): boolean {\n\tconst name = target.slice(target.lastIndexOf('/') + 1)\n\tconst dot = name.lastIndexOf('.')\n\tif (name.endsWith(ADDON_EXTENSION)) return true\n\treturn dot === -1 || MODULE_EXTENSIONS.includes(name.slice(dot))\n}\n\n// Whether a resolved target is a declaration rather than the JavaScript a\n// `default` branch answers with when the entry declares no `types` condition.\nfunction isDeclaration(target: string): boolean {\n\treturn DECLARATION_EXTENSIONS.some((extension) => target.endsWith(extension))\n}\n\n// The declarations the Node module, Node CommonJS, and browser drives compare\n// against. Each field uses the conditions of the TypeScript consumer paired with\n// that runtime. A JavaScript target resolves through TypeScript's adjacent\n// declaration substitution rather than standing in for the declaration itself.\nfunction readDeclaration(\n\tentry: unknown,\n\tinstalled: string,\n): {\n\treadonly module: string | undefined\n\treadonly commonjs: string | undefined\n\treadonly browser: string | undefined\n} {\n\treturn {\n\t\tmodule: resolveDeclaration(entry, DECLARATION_CONDITIONS.module, installed),\n\t\tcommonjs: resolveDeclaration(entry, DECLARATION_CONDITIONS.commonjs, installed),\n\t\tbrowser: resolveDeclaration(entry, DECLARATION_CONDITIONS.browser, installed),\n\t}\n}\n\n// The entries one compile driver can resolve under its own conditions.\nfunction selectEntries(entries: readonly Entry[], conditions: readonly string[]): readonly Entry[] {\n\treturn entries.filter(\n\t\t(entry) =>\n\t\t\tresolveTarget(entry.mapping, conditions) !== undefined &&\n\t\t\t(!conditions.includes('require') || entry.loadable),\n\t)\n}\n\n// The compile drivers whose conditions reach one entry under one importing format.\n// A driver that resolves no target for that entry compiles nothing, so a consumer\n// written under it would report a resolution failure this package never made.\nfunction selectDrivers(entry: Entry, format: Format): readonly Resolution[] {\n\treturn RESOLUTIONS.filter(\n\t\t(driver) => selectEntries([entry], driver.conditions[format]).length > 0,\n\t)\n}\n\n// Requirable entries that declare CommonJS support but a typed CommonJS consumer\n// cannot compile against. A default branch resolving under the require condition\n// set makes no CommonJS claim.\nfunction selectUntypable(entries: readonly Entry[], installed: string): readonly Entry[] {\n\treturn entries.filter(\n\t\t(entry) =>\n\t\t\tentry.requirable &&\n\t\t\tisRecord(entry.mapping) &&\n\t\t\tObject.hasOwn(entry.mapping, 'require') &&\n\t\t\t!declaresCommonJS(entry.mapping, installed),\n\t)\n}\n\n// One surface comparison, written as the consumer module that proves it: the\n// installed entry that consumer imports, the file extension fixing its importing\n// format, the names a real runtime published off it, and the driver whose scratch\n// project compiles it.\ninterface Surface {\n\treadonly entry: Entry\n\treadonly extension: string\n\treadonly published: readonly string[]\n\treadonly driver: Resolution\n}\n\n// A scratch project over named consumer modules, written beside them so their own\n// resolution reaches the installed package. Nothing is emitted and no ambient types\n// are pulled in, so what the check reads is the installed declarations alone.\nfunction writeProject(\n\tstage: Stage,\n\tname: string,\n\tdriver: Resolution,\n\tfiles: readonly string[],\n): string {\n\tconst path = join(stage.consumer, `tsconfig.${name}.json`)\n\tconst project = {\n\t\tcompilerOptions: {\n\t\t\tmodule: driver.module,\n\t\t\tmoduleResolution: driver.resolution,\n\t\t\tnoEmit: true,\n\t\t\tskipLibCheck: true,\n\t\t\tstrict: true,\n\t\t\ttarget: 'esnext',\n\t\t\ttypes: [],\n\t\t},\n\t\tfiles: [...files],\n\t}\n\twriteFile(path, `${JSON.stringify(project, undefined, '\\t')}\\n`)\n\treturn path\n}\n\n// The diagnostics the compiler this workspace installs reports for one scratch\n// project. The compiler runs as a command, so nothing here reaches an API that\n// moves between its majors, and the located lines it prints are the verdict rather\n// than the exit code, which moves between them. A line carrying no location, a line\n// naming the scratch project rather than a consumer module, and anything at all on\n// the error stream are faults of this proof rather than of the package under proof,\n// so each is raised where it happens instead of counted against the package.\nfunction checkProject(stage: Stage, project: string): readonly string[] {\n\tconst result = runNode([TSC, '--noEmit', '--pretty', 'false', '-p', project], stage.consumer)\n\tconst refused = `${result.stderr ?? ''}`.trim()\n\tif (refused.length > 0) {\n\t\tthrow new Error(`The consumer compiler wrote ${refused} to its error stream`)\n\t}\n\tconst reported: string[] = []\n\tfor (const line of `${result.stdout ?? ''}`.split(/\\r\\n|\\n/u)) {\n\t\tif (line.trim().length === 0) continue\n\t\tconst last = reported.at(-1)\n\t\t// An elaborated diagnostic prints its detail on indented lines under its own\n\t\t// first line, so each of those joins the diagnostic it elaborates.\n\t\tif (/^\\s/u.test(line) && last !== undefined) {\n\t\t\treported[reported.length - 1] = `${last} ${line.trim()}`\n\t\t\tcontinue\n\t\t}\n\t\tconst located = DIAGNOSTIC_PATTERN.exec(line)?.[1]\n\t\tif (located === undefined) {\n\t\t\tthrow new Error(`The consumer compiler reported ${line}, which names no location`)\n\t\t}\n\t\tif (resolve(stage.consumer, located) === project) {\n\t\t\tthrow new Error(`The scratch project is itself at fault: ${line}`)\n\t\t}\n\t\treported.push(line)\n\t}\n\tif (reported.length === 0 && result.status !== 0) {\n\t\tthrow new Error(`The consumer compiler refused the project: ${readOutput(result)}`)\n\t}\n\treturn reported\n}\n\n// One installed entry's published names checked against its own declarations by\n// the compiler this workspace installs, in the direction each divergence surfaces\n// under. The runtime's key list is written into the consumer as a literal, so the\n// published side comes from a real process and the declared side from the\n// declarations that process's package ships, and the two can disagree. A name the\n// declarations carry and the runtime does not lands on `declared`. A name the\n// runtime carries and the declarations do not, and a name the declarations publish\n// as a type alone, land on `surfaced`: a variable widens into the type\n// `declared` annotates, and only `surfaced` reads the literal's own keys back.\n// Each names the member it is about, so the failure says which export moved.\nfunction checkSurface(stage: Stage, surface: Surface): readonly string[] {\n\tconst slug = surface.entry.subpath.replaceAll(/[^\\w]+/gu, '-')\n\tconst name = `surface.${surface.driver.label}${slug}.${surface.extension}`\n\tconst module = `${name}`\n\tconst keys = surface.published.map((key) => `${JSON.stringify(key)}: true`).join(', ')\n\twriteFile(\n\t\tjoin(stage.consumer, module),\n\t\t`import * as entry from ${JSON.stringify(surface.entry.specifier)}\nconst published = {${keys.length === 0 ? '' : ` ${keys} `}} as const\nconst declared: Record<keyof typeof entry, true> = published\nconst surfaced: Record<keyof typeof published, true> = declared\n`,\n\t)\n\tconst project = writeProject(stage, name, surface.driver, [`./${module}`])\n\treturn checkProject(stage, project).map((line) => `${surface.driver.label}: ${line}`)\n}\n\n// One consumer module importing every installed entry, written where its own\n// resolution finds the installed package.\nfunction writeConsumerProbe(stage: Stage, path: string, specifiers: readonly string[]): void {\n\tconst names: string[] = []\n\tconst bindings: string[] = []\n\tfor (const [index, specifier] of specifiers.entries()) {\n\t\tconst binding = `entry${String(index)}`\n\t\tnames.push(binding)\n\t\tbindings.push(`import * as ${binding} from ${JSON.stringify(specifier)}`)\n\t}\n\tconst source = `${bindings.join('\\n')}\\nexport const surface = [${names.join(', ')}]\\n`\n\twriteFile(join(stage.consumer, path), source)\n}\n\n// The runtime key set a real process reads off one installed entry under one\n// condition. The driver is a file rather than an `--eval` string, so the specifier\n// travels as an argument and nothing needs escaping.\nfunction driveRuntime(stage: Stage, specifier: string, driver: string): readonly string[] {\n\tconst result = runNode([join(stage.consumer, driver), specifier], stage.consumer)\n\tif (result.status !== 0) {\n\t\tthrow new Error(`Loading ${specifier} from the consumer failed: ${readOutput(result)}`)\n\t}\n\tconst published: unknown = JSON.parse(result.stdout)\n\tif (!isNames(published)) throw new Error(`The driver printed no name list for ${specifier}`)\n\treturn published\n}\n{{helpers}}\n// Pack this workspace, install the archive into an isolated consumer, and read the\n// published surface back off the installed tree. Every later claim reads this\n// result, so a failure here is raised where it happens rather than once per entry.\nfunction buildStage(): Stage {\n\tconst packed = join(SCRATCH, 'packed')\n\tconst consumer = join(SCRATCH, 'consumer')\n\tmkdirSync(packed, { recursive: true })\n\tconst pack = runNpm(['pack', '--ignore-scripts', '--pack-destination', packed], ROOT)\n\tif (pack.status !== 0) throw new Error(`npm pack refused this workspace: ${readOutput(pack)}`)\n\tconst archives = readdirSync(packed).filter((name) => name.endsWith('.tgz'))\n\tconst archive = archives[0]\n\tif (archives.length !== 1 || archive === undefined) {\n\t\tthrow new Error(`npm pack wrote no single archive: ${archives.join(', ')}`)\n\t}\n\twriteFile(join(consumer, 'package.json'), CONSUMER_MANIFEST)\n\twriteFile(join(consumer, ESM_DRIVER), ESM_DRIVER_SOURCE)\n\twriteFile(join(consumer, CJS_DRIVER), CJS_DRIVER_SOURCE)\n\tconst install = runNpm(\n\t\t['install', '--ignore-scripts', '--no-audit', '--no-fund', join(packed, archive)],\n\t\tconsumer,\n\t)\n\tif (install.status !== 0) {\n\t\tthrow new Error(`Installing the packed archive failed: ${readOutput(install)}`)\n\t}\n\tconst name = readManifestName(join(ROOT, 'package.json'))\n\tconst installed = join(consumer, 'node_modules', ...name.split('/'))\n\tconst manifest = readJson(join(installed, 'package.json'))\n\tif (!isRecord(manifest) || !isRecord(manifest.exports)) {\n\t\tthrow new Error('The installed manifest publishes no exports map')\n\t}\n\tconst entries: Entry[] = []\n\tconst targets: string[] = []\n\tconst subpaths: string[] = []\n\tconst undeclared: string[] = []\n\tconst excluded: string[] = []\n\tfor (const [subpath, entry] of Object.entries(manifest.exports)) {\n\t\tconst files = collectTargets(entry)\n\t\ttargets.push(...files)\n\t\tsubpaths.push(subpath)\n\t\tconst declaration = readDeclaration(entry, installed)\n\t\t// A subpath resolving no declaration is partitioned rather than dropped. It is a\n\t\t// defect when a runtime loads one of its targets for names, because a consumer\n\t\t// importing it compiles against nothing under `node16`. It is an excluded\n\t\t// publication otherwise: the `\"./package.json\"` manifest pointer and a stylesheet\n\t\t// are published for a reader rather than an importer.\n\t\tif (\n\t\t\tdeclaration.module === undefined &&\n\t\t\tdeclaration.commonjs === undefined &&\n\t\t\tdeclaration.browser === undefined\n\t\t) {\n\t\t\tif (files.some(isModule)) undeclared.push(subpath)\n\t\t\telse excluded.push(subpath)\n\t\t\tcontinue\n\t\t}\n\t\tconst importTarget = resolveTarget(entry, RUNTIME_CONDITIONS.module)\n\t\tconst requireTarget = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)\n\t\tconst browserTarget = resolveTarget(entry, RUNTIME_CONDITIONS.browser)\n\t\tconst browsable = resolvesBrowser(entry)\n\t\tconst shadowed = browsable && requireTarget === browserTarget\n\t\tconst requirable = requireTarget !== undefined && !shadowed\n\t\tconst loadable = requirable && resolvesCommonJS(entry, installed)\n\t\tentries.push({\n\t\t\tsubpath,\n\t\t\tspecifier: subpath === '.' ? name : `${name}${subpath.slice(1)}`,\n\t\t\tmapping: entry,\n\t\t\tdeclaration: {\n\t\t\t\timportable: declaration.module !== undefined,\n\t\t\t\trequirable: declaration.commonjs !== undefined,\n\t\t\t\tbrowsable: declaration.browser !== undefined,\n\t\t\t},\n\t\t\tbrowsable,\n\t\t\timportable: importTarget !== undefined && !(browsable && importTarget === browserTarget),\n\t\t\trequirable,\n\t\t\tloadable,\n\t\t})\n\t}\n\treturn { consumer, installed, archives, entries, subpaths, undeclared, excluded, targets }\n}\n\nconst SCRATCH = mkdtempSync(join(tmpdir(), 'distribution-'))\nconst CACHE = join(SCRATCH, 'cache')\nmkdirSync(CACHE, { recursive: true })\n// The scratch tree holds the npm cache, the packed archive, and the installed\n// consumer, so its removal is registered before the first thing that can throw.\nafterAll(() => {\n\trmSync(SCRATCH, { force: true, recursive: true })\n})\n\n// Installing the packed archive resolves its own runtime dependencies, so an\n// unreachable registry leaves nothing to measure. Under release that is the gate\n// failing; anywhere else the suite skips and names the mechanism it wanted.\n//\n// A module that throws while loading never reaches the `afterAll` it registered,\n// so every throw here removes the scratch tree on its way out.\nfunction openStage(): Stage | undefined {\n\ttry {\n\t\tif (runNpm(PING, ROOT).status !== 0) {\n\t\t\tif (!RELEASE) return undefined\n\t\t\tthrow new Error(\n\t\t\t\t'The release gate requires a reachable npm registry, and npm ping did not answer',\n\t\t\t)\n\t\t}\n\t\treturn buildStage()\n\t} catch (error) {\n\t\trmSync(SCRATCH, { force: true, recursive: true })\n\t\tthrow error\n\t}\n}\n\nconst STAGE = openStage()\nconst STAGED = STAGE !== undefined\n\ndescribe('distribution classifiers', () => {\n\tit('classifies synthetic export mappings without a registry stage', () => {\n\t\tconst root = join(SCRATCH, 'classifiers')\n\t\twriteFile(\n\t\t\tjoin(root, 'package.json'),\n\t\t\tJSON.stringify({\n\t\t\t\ttype: 'commonjs',\n\t\t\t\texports: {\n\t\t\t\t\tcondition: { browser: './b.js', default: './n.js' },\n\t\t\t\t\tconvention: { default: './dist/src/browser/index.js' },\n\t\t\t\t\tuniversal: { default: './shared.js' },\n\t\t\t\t\t'import-shared': {\n\t\t\t\t\t\tbrowser: './shared.mjs',\n\t\t\t\t\t\timport: './shared.mjs',\n\t\t\t\t\t\tdefault: './node.js',\n\t\t\t\t\t},\n\t\t\t\t\t'require-shared': {\n\t\t\t\t\t\tbrowser: './shared.cjs',\n\t\t\t\t\t\trequire: './shared.cjs',\n\t\t\t\t\t\tdefault: './node.js',\n\t\t\t\t\t},\n\t\t\t\t\tnode: { node: './node.js', default: './node.js' },\n\t\t\t\t\tsilent: { 'module-sync': './x.cjs', import: './x.mjs' },\n\t\t\t\t\tmodule: { require: './x.mjs' },\n\t\t\t\t\t'nested-module': { require: './module/x.js' },\n\t\t\t\t\t'nested-commonjs': { require: './commonjs/x.js' },\n\t\t\t\t\tesm: { import: './x.mjs' },\n\t\t\t\t},\n\t\t\t}),\n\t\t)\n\t\twriteFile(join(root, 'module/package.json'), '{ \"type\": \"module\" }\\n')\n\t\twriteFile(join(root, 'commonjs/package.json'), '{ \"type\": \"commonjs\" }\\n')\n\t\tconst manifest = readJson(join(root, 'package.json'))\n\t\tif (!isRecord(manifest) || !isRecord(manifest.exports)) {\n\t\t\tthrow new Error('The classifier fixture declares no exports map')\n\t\t}\n\t\tconst mappings = manifest.exports\n\t\texpect({\n\t\t\tcondition: resolvesBrowser(mappings.condition),\n\t\t\tconvention: resolvesBrowser(mappings.convention),\n\t\t\tuniversal: resolvesBrowser(mappings.universal),\n\t\t\timport: resolvesBrowser(mappings['import-shared']),\n\t\t\trequire: resolvesBrowser(mappings['require-shared']),\n\t\t\tnode: resolvesBrowser(mappings.node),\n\t\t}).toStrictEqual({\n\t\t\tcondition: true,\n\t\t\tconvention: true,\n\t\t\tuniversal: false,\n\t\t\timport: false,\n\t\t\trequire: false,\n\t\t\tnode: false,\n\t\t})\n\t\texpect({\n\t\t\tsilent: resolvesCommonJS(mappings.silent, root),\n\t\t\tmodule: resolvesCommonJS(mappings.module, root),\n\t\t\tnestedModule: resolvesCommonJS(mappings['nested-module'], root),\n\t\t\tnestedCommonJS: resolvesCommonJS(mappings['nested-commonjs'], root),\n\t\t\tesm: resolvesCommonJS(mappings.esm, root),\n\t\t}).toStrictEqual({\n\t\t\tsilent: true,\n\t\t\tmodule: false,\n\t\t\tnestedModule: false,\n\t\t\tnestedCommonJS: true,\n\t\t\tesm: false,\n\t\t})\n\t})\n})\n\n// The staged consumer, or a skip naming what the run could not reach. `it.skipIf`\n// carries no reason, so the gate sits here where the test context can state one.\nfunction requireStage(context: TestContext): Stage {\n\tif (!STAGED) {\n\t\treturn context.skip('`npm ping` did not answer, so nothing was packed or installed')\n\t}\n\treturn STAGE\n}\n\ndescribe('installed package consumer', () => {\n\tit('packs one archive and installs it in isolation [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\texpect(stage.archives).toHaveLength(1)\n\t\texpect(existsSync(join(stage.installed, 'package.json'))).toBe(true)\n\t\texpect(stage.entries.length).toBeGreaterThan(0)\n\t})\n\n\tit('ships every relative target its exports map names [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst relative = stage.targets.filter((target) => target.startsWith('./'))\n\t\texpect(relative).not.toStrictEqual([])\n\t\texpect(relative.filter((target) => !existsSync(join(stage.installed, target)))).toStrictEqual(\n\t\t\t[],\n\t\t)\n\t})\n\n\t// Every published subpath is driven, excluded by name, or reported here. A dropped\n\t// one leaves no trace: no runtime test, no declaration comparison, and no place in\n\t// the resolution compile, so the run reports success for a subpath it never\n\t// measured.\n\tit('declares types for every module it publishes [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst partitioned = [\n\t\t\t...stage.entries.map((entry) => entry.subpath),\n\t\t\t...stage.undeclared,\n\t\t\t...stage.excluded,\n\t\t]\n\t\texpect(stage.undeclared).toStrictEqual([])\n\t\texpect(partitioned.sort()).toStrictEqual([...stage.subpaths].sort())\n\t\t// A driven subpath answers a runtime condition. One resolving a declaration and\n\t\t// no Node or browser target compiles for a consumer and throws when that consumer\n\t\t// loads it. Each later drive retires itself for that entry, so this assertion names\n\t\t// the subpath rather than counting it as driven.\n\t\tconst unreachable = stage.entries.filter(\n\t\t\t(entry) => !entry.importable && !entry.requirable && !entry.browsable,\n\t\t)\n\t\texpect(unreachable.map((entry) => entry.subpath)).toStrictEqual([])\n\t\tconst untypable = selectUntypable(stage.entries, stage.installed)\n\t\texpect(untypable.map((entry) => entry.subpath)).toStrictEqual([])\n\t})\n\n\tit('refuses a subpath its exports map does not name [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst name = readManifestName(join(stage.installed, 'package.json'))\n\t\tconst driver = join(stage.consumer, ESM_DRIVER)\n\t\tconst result = runNode([driver, `${name}${ABSENT_SUBPATH}`], stage.consumer)\n\t\texpect(result.status).not.toBe(0)\n\t\texpect(readOutput(result)).toContain('ERR_PACKAGE_PATH_NOT_EXPORTED')\n\t})\n\n\t// The absent subpath is the firing control: a resolution that reports nothing\n\t// for every published entry has not been shown to resolve anything at all. Each\n\t// module format carries its own control, because a format that resolves nothing\n\t// is silent for the same reason a resolution that resolves nothing is.\n\tit('compiles a consumer under every module resolution [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst name = readManifestName(join(stage.installed, 'package.json'))\n\t\tconst reported: string[] = []\n\t\tconst silent: string[] = []\n\t\tfor (const driver of RESOLUTIONS) {\n\t\t\tfor (const [extension, format] of FORMATS) {\n\t\t\t\tconst written = selectEntries(stage.entries, driver.conditions[format])\n\t\t\t\tif (written.length === 0) continue\n\t\t\t\tconst label = `${driver.label}.${extension}`\n\t\t\t\tconst probe = `probe.${label}`\n\t\t\t\tconst specifiers = written.map((entry) => entry.specifier)\n\t\t\t\twriteConsumerProbe(stage, probe, specifiers)\n\t\t\t\tconst project = writeProject(stage, probe, driver, [`./${probe}`])\n\t\t\t\tfor (const message of checkProject(stage, project)) {\n\t\t\t\t\treported.push(`${label}: ${message}`)\n\t\t\t\t}\n\t\t\t\tconst control = `control.${label}`\n\t\t\t\twriteConsumerProbe(stage, control, [`${name}${ABSENT_SUBPATH}`])\n\t\t\t\tconst refused = writeProject(stage, control, driver, [`./${control}`])\n\t\t\t\tif (checkProject(stage, refused).length === 0) silent.push(label)\n\t\t\t}\n\t\t}\n\t\texpect(reported).toStrictEqual([])\n\t\texpect(silent).toStrictEqual([])\n\t})\n{{guard}}})\n\nfor (const entry of STAGE?.entries ?? []) {\n\tdescribe(`installed entry ${entry.subpath}`, () => {\n\t\tit.runIf(entry.importable)(\n\t\t\t'publishes what it declares to a Node import, and no more',\n\t\t\t(context) => {\n\t\t\t\tconst stage = requireStage(context)\n\t\t\t\t// The exports-map walk resolved a declaration a typed importer reads, so an\n\t\t\t\t// entry reaching this drive without one is reported for that rather than for\n\t\t\t\t// what a consumer of a missing declaration goes on to say.\n\t\t\t\tif (!entry.declaration.importable) {\n\t\t\t\t\tthrow new Error(`${entry.subpath} publishes no import declaration`)\n\t\t\t\t}\n\t\t\t\tconst published = driveRuntime(stage, entry.specifier, ESM_DRIVER)\n\t\t\t\tconst drivers = selectDrivers(entry, 'module')\n\t\t\t\texpect(drivers).not.toStrictEqual([])\n\t\t\t\tconst reported = drivers.flatMap((driver) =>\n\t\t\t\t\tcheckSurface(stage, { entry, extension: 'ts', published, driver }),\n\t\t\t\t)\n\t\t\t\texpect(reported).toStrictEqual([])\n\t\t\t},\n\t\t)\n\n\t\tit.runIf(entry.requirable)(\n\t\t\t'publishes what it declares to a Node require, and no more',\n\t\t\t(context) => {\n\t\t\t\tconst stage = requireStage(context)\n\t\t\t\tif (!entry.declaration.requirable) {\n\t\t\t\t\tthrow new Error(`${entry.subpath} publishes no require declaration`)\n\t\t\t\t}\n\t\t\t\tconst published = driveRuntime(stage, entry.specifier, CJS_DRIVER)\n\t\t\t\t// A subpath whose `require` resolves to a module that no typed CommonJS\n\t\t\t\t// consumer can compile against carries no declared side to compare here, and\n\t\t\t\t// whether it may publish one at all is the untypable set's question rather\n\t\t\t\t// than this drive's. The preceding runtime drive ran either way.\n\t\t\t\tconst drivers = selectDrivers(entry, 'commonjs')\n\t\t\t\texpect(drivers).not.toStrictEqual([])\n\t\t\t\tconst reported = drivers.flatMap((driver) =>\n\t\t\t\t\tcheckSurface(stage, { entry, extension: 'cts', published, driver }),\n\t\t\t\t)\n\t\t\t\texpect(reported).toStrictEqual([])\n\t\t\t},\n\t\t)\n{{drive}}\t})\n}\n";
|
|
104
|
+
proof: "// The artifact a consumer installs, measured rather than described. This workspace\n// is packed and installed into a throwaway consumer, and every following claim is read\n// off that installed tree: the exports map it publishes, the declarations it ships,\n// and the module objects a real runtime hands a consumer. Nothing here names this\n// package, one of its exports, or how many there are, so the proof stays true as\n// the published surface moves.\n{{types}}import type { SpawnSyncReturns } from 'node:child_process'\nimport type { TestContext } from 'vitest'\nimport { spawnSync } from 'node:child_process'\nimport {\n\texistsSync,\n\tmkdirSync,\n\tmkdtempSync,\n\treaddirSync,\n\treadFileSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from 'node:fs'\n{{transport}}import { createRequire } from 'node:module'\nimport { tmpdir } from 'node:os'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n{{launcher}}import { afterAll, describe, expect, it } from 'vitest'\n\nconst ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')\nconst NPM = process.platform === 'win32' ? 'npm.cmd' : 'npm'\n// The compiler this workspace installs, run as a command rather than called in\n// process: the command and its plain-text diagnostics are the same across the\n// compiler majors this toolchain supports, and its in-process API is not. It is\n// resolved from the workspace under proof, so a consumer of the packed artifact is\n// checked by the same compiler that workspace's own `check` script runs.\nconst TSC = createRequire(join(ROOT, 'package.json')).resolve('typescript/bin/tsc')\n// Windows needs a shell to launch a `.cmd`: Node refuses one directly since the\n// batch-argument hardening, and `spawnSync` returns `EINVAL` with a null status\n// rather than an exit code a caller can read. Every following argument is a literal or\n// a path this file built, so the shell has nothing to escape.\nconst SHELL = process.platform === 'win32'\n// `prepublishOnly` runs this proof as `npm run test:distribution -- --mode release`,\n// and the root configuration's project factories carry that mode into this project.\n// Release is the publish gate, so evidence it cannot obtain fails there and skips\n// everywhere else: a gate that passes on missing evidence proves nothing.\nconst RELEASE = import.meta.env.MODE === 'release'\n// The built output directory convention a browser face may publish from. Every\n// selection reads this prefix off the export target and never off the subpath name. A\n// workspace whose only published face is the browser one publishes that face at the\n// root subpath, so a rule keyed on the subpath name drives a browser bundle through\n// Node and the miss is silent.\nconst BROWSER_OUTPUT = './dist/src/browser/'\nconst ABSENT_SUBPATH = '/no-subpath-is-published-under-this-name'\n// A compiler diagnostic that says where it is: the path relative to the directory\n// the compiler ran in, the 1-based line and column, the code, and the message. The\n// diagnostics are the verdict rather than the exit code, which differs between the\n// compiler majors this toolchain supports, so a reported line matching nothing here\n// came from something other than a check of a consumer module.\nconst DIAGNOSTIC_PATTERN = /^(.+?)\\(\\d+,\\d+\\): error TS\\d+: /u\nconst PING = ['ping', '--fetch-retries=0', '--fetch-timeout=5000', '--loglevel=silent']\nconst ESM_DRIVER = 'drive.mjs'\nconst CJS_DRIVER = 'drive.cjs'\nconst CONSUMER_MANIFEST = `{ \"name\": \"distribution-consumer\", \"private\": true, \"type\": \"module\" }\\n`\nconst ESM_DRIVER_SOURCE = `const entry = await import(process.argv[2])\nprocess.stdout.write(JSON.stringify(Object.keys(entry).sort()))\n`\nconst CJS_DRIVER_SOURCE = `const entry = require(process.argv[2])\nprocess.stdout.write(JSON.stringify(Object.keys(entry).sort()))\n`\n\n// The extensions a JavaScript handler loads as modules. Node loads a native addon\n// through its addon handler instead, so that extension is named separately.\nconst MODULE_EXTENSIONS = ['.js', '.mjs', '.cjs']\nconst ADDON_EXTENSION = '.node'\n// The extensions a declaration file carries. A `require` condition declares\n// `.d.cts` and an ESM-only one `.d.mts`, so the `.d.ts` spelling alone does not\n// name them.\nconst DECLARATION_EXTENSIONS = ['.d.ts', '.d.cts', '.d.mts']\ntype Format = 'module' | 'commonjs'\n\n// The Node import target is resolved with the conditions that driver supplies. The\n// CommonJS compile probe is selected from its declaration's format, and its runtime\n// drive loads the same subpath through Node's require resolver. Vite's production\n// client build enables its module and browser conditions.\nconst RUNTIME_CONDITIONS = Object.freeze({\n\tmodule: Object.freeze(['node-addons', 'node', 'import', 'module-sync']),\n\tcommonjs: Object.freeze(['node-addons', 'node', 'require', 'module-sync']),\n\tbrowser: Object.freeze(['module', 'browser', 'production', 'import']),\n})\n// TypeScript's Node resolutions add `node` to the format condition. Its bundler\n// resolution does not, so a browser drive compares against the declaration a bundler\n// consumer reads rather than borrowing the Node declaration.\nconst BUNDLER_CONDITIONS = Object.freeze({\n\tmodule: ['types', 'import'],\n\tcommonjs: ['types', 'require'],\n})\nconst DECLARATION_CONDITIONS = Object.freeze({\n\tmodule: ['types', 'node', 'import'],\n\tcommonjs: ['types', 'node', 'require'],\n\tbrowser: BUNDLER_CONDITIONS.module,\n})\n\ninterface Resolution {\n\treadonly label: string\n\treadonly resolution: string\n\treadonly module: string\n\treadonly conditions: Readonly<Record<Format, readonly string[]>>\n}\n\ninterface TargetResolution {\n\treadonly target: string\n}\n\n// Each compile driver carries the compiler options its scratch project sets and\n// the conditions TypeScript applies for that resolution and importing format. A\n// `require`-only subpath therefore stays in each CommonJS probe that can resolve it.\n// The option values are the spellings the project file takes, so nothing here needs\n// the compiler's own API to name them.\nconst RESOLUTIONS: readonly Resolution[] = [\n\t{\n\t\tlabel: 'node16',\n\t\tresolution: 'node16',\n\t\tmodule: 'node16',\n\t\tconditions: DECLARATION_CONDITIONS,\n\t},\n\t{\n\t\tlabel: 'nodenext',\n\t\tresolution: 'nodenext',\n\t\tmodule: 'nodenext',\n\t\tconditions: DECLARATION_CONDITIONS,\n\t},\n\t{\n\t\tlabel: 'bundler',\n\t\tresolution: 'bundler',\n\t\tmodule: 'esnext',\n\t\tconditions: BUNDLER_CONDITIONS,\n\t},\n]\n\n// The driver a bundled consumer reads declarations under. A browser application\n// compiles through a bundler, so the browser drive answers under this one alone,\n// and naming it here is what keeps that selection tied to the driver it selects.\nconst BROWSER_DRIVER = RESOLUTIONS.find((candidate) => candidate.label === 'bundler')\nif (BROWSER_DRIVER === undefined) throw new Error(\"RESOLUTIONS carries no 'bundler' row\")\n\nconst FORMATS: ReadonlyArray<readonly [extension: string, format: Format]> = [\n\t['ts', 'module'],\n\t['cts', 'commonjs'],\n]\n\n// One published subpath, resolved to what this proof can drive: the specifier a\n// consumer writes, whether the declarations its consumer formats resolve at all,\n// whether the exports map answers the browser condition with a target of its own,\n// whether it answers `import` and `require` at all, and whether the target that\n// `require` answers with is one that a CommonJS consumer loads.\ninterface Entry {\n\treadonly subpath: string\n\treadonly specifier: string\n\treadonly mapping: unknown\n\treadonly declaration: {\n\t\treadonly importable: boolean\n\t\treadonly requirable: boolean\n\t\treadonly browsable: boolean\n\t}\n\treadonly browsable: boolean\n\treadonly importable: boolean\n\treadonly requirable: boolean\n\treadonly loadable: boolean\n}\n\n// The installed tree every claim is read from. Every subpath the exports map names\n// lands in exactly one of `entries`, `undeclared`, and `excluded`, so a subpath this\n// proof cannot drive is reported rather than dropped.\ninterface Stage {\n\treadonly consumer: string\n\treadonly installed: string\n\treadonly archives: readonly string[]\n\treadonly entries: readonly Entry[]\n\treadonly subpaths: readonly string[]\n\treadonly undeclared: readonly string[]\n\treadonly excluded: readonly string[]\n\treadonly targets: readonly string[]\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction isNames(value: unknown): value is readonly string[] {\n\treturn Array.isArray(value) && value.every((name) => typeof name === 'string')\n}\n\n// A fallback list, which is what Node reads an array in an exports entry as. The\n// narrowing is what the following walkers need: `Array.isArray` widens an `unknown`\n// member to `any`, and an entry read that way is not read at all.\nfunction isList(value: unknown): value is readonly unknown[] {\n\treturn Array.isArray(value)\n}\n\n// Whether a string is a valid package target. Node rejects a target outside the\n// package and a target containing a dot, parent, or node_modules segment during\n// package-target resolution. A later module-resolution failure is not the same\n// thing: an array falls through the former and keeps the latter.\nfunction isPackageTarget(target: string): boolean {\n\tif (!target.startsWith('./')) return false\n\tfor (const segment of target.slice(2).split(/[\\\\/]/u)) {\n\t\tlet decoded = segment\n\t\ttry {\n\t\t\tdecoded = decodeURIComponent(segment)\n\t\t} catch {}\n\t\tconst normalized = decoded.toLowerCase()\n\t\tif (normalized === '.' || normalized === '..' || normalized === 'node_modules') return false\n\t}\n\treturn true\n}\n\nfunction readJson(path: string): unknown {\n\tconst parsed: unknown = JSON.parse(readFileSync(path, 'utf8'))\n\treturn parsed\n}\n\nfunction readManifestName(path: string): string {\n\tconst manifest = readJson(path)\n\tif (!isRecord(manifest) || typeof manifest.name !== 'string') {\n\t\tthrow new Error(`The manifest at ${path} declares no package name`)\n\t}\n\treturn manifest.name\n}\n\nfunction writeFile(path: string, content: string): void {\n\tmkdirSync(dirname(path), { recursive: true })\n\twriteFileSync(path, content)\n}\n\nfunction readOutput(result: SpawnSyncReturns<string>): string {\n\treturn `${result.stdout ?? ''}${result.stderr ?? ''}`.trim()\n}\n\nfunction runNpm(args: readonly string[], cwd: string): SpawnSyncReturns<string> {\n\treturn spawnSync(NPM, [...args], {\n\t\tcwd,\n\t\tencoding: 'utf8',\n\t\tenv: { ...process.env, npm_config_cache: CACHE },\n\t\tshell: SHELL,\n\t\twindowsHide: true,\n\t})\n}\n\nfunction runNode(args: readonly string[], cwd: string): SpawnSyncReturns<string> {\n\treturn spawnSync(process.execPath, [...args], { cwd, encoding: 'utf8', windowsHide: true })\n}\n\n// Node's own condition matching, read in declaration order.\nfunction resolvePackageTarget(\n\tentry: unknown,\n\tconditions: readonly string[],\n): TargetResolution | undefined {\n\tif (typeof entry === 'string') return { target: entry }\n\tif (isList(entry)) {\n\t\tfor (const member of entry) {\n\t\t\tconst resolved = resolvePackageTarget(member, conditions)\n\t\t\tif (resolved !== undefined && isPackageTarget(resolved.target)) return resolved\n\t\t}\n\t\treturn undefined\n\t}\n\tif (!isRecord(entry)) return undefined\n\tfor (const [condition, nested] of Object.entries(entry)) {\n\t\tif (condition !== 'default' && !conditions.includes(condition)) continue\n\t\tconst resolved = resolvePackageTarget(nested, conditions)\n\t\tif (resolved !== undefined) return resolved\n\t}\n\treturn undefined\n}\n\n// A flat entry, a condition-nested entry, and a fallback list all resolve through\n// one walker. An entry may declare `types` beside `default` at its top level\n// rather than inside `import`, so a fixed `entry.import.types` lookup is not\n// equivalent to condition resolution.\nfunction resolveTarget(entry: unknown, conditions: readonly string[]): string | undefined {\n\treturn resolvePackageTarget(entry, conditions)?.target\n}\n\n// Whether a path is a physical file. TypeScript's file-existence check refuses a\n// directory at the same spelling and continues to the outer package scope.\nfunction matchesFile(path: string): boolean {\n\ttry {\n\t\treturn statSync(path).isFile()\n\t} catch {\n\t\treturn false\n\t}\n}\n\n// TypeScript resolves a declaration target by accepting an existing declaration\n// directly or by substituting beside a JavaScript target. A missing target leaves\n// the containing condition or fallback list unresolved, so the walk continues.\nfunction targetToDeclaration(target: string, installed: string): string | undefined {\n\tif (!isPackageTarget(target)) return undefined\n\tlet declaration = target\n\tif (target.endsWith('.cjs')) declaration = `${target.slice(0, -4)}.d.cts`\n\telse if (target.endsWith('.mjs')) declaration = `${target.slice(0, -4)}.d.mts`\n\telse if (target.endsWith('.js')) declaration = `${target.slice(0, -3)}.d.ts`\n\telse if (!isDeclaration(target)) return undefined\n\treturn matchesFile(join(installed, declaration)) ? declaration : undefined\n}\n\n// The declaration TypeScript resolves through one importing format's conditions.\n// Condition objects keep manifest order, and arrays keep fallback order.\nfunction resolveDeclaration(\n\tentry: unknown,\n\tconditions: readonly string[],\n\tinstalled: string,\n): string | undefined {\n\tif (typeof entry === 'string') return targetToDeclaration(entry, installed)\n\tif (isList(entry)) {\n\t\tfor (const member of entry) {\n\t\t\tconst resolved = resolveDeclaration(member, conditions, installed)\n\t\t\tif (resolved !== undefined) return resolved\n\t\t}\n\t\treturn undefined\n\t}\n\tif (!isRecord(entry)) return undefined\n\tfor (const [condition, nested] of Object.entries(entry)) {\n\t\tif (condition !== 'default' && !conditions.includes(condition)) continue\n\t\tconst resolved = resolveDeclaration(nested, conditions, installed)\n\t\tif (resolved !== undefined) return resolved\n\t}\n\treturn undefined\n}\n\n// The nearest package scope that decides a `.d.ts` declaration's module format. A\n// physical nested manifest starts a scope even when it omits `type` or cannot be\n// parsed. A directory at that spelling is not a manifest, so the walk continues.\nfunction readPackageType(installed: string, target: string): unknown {\n\tlet directory = dirname(join(installed, target))\n\twhile (true) {\n\t\tconst path = join(directory, 'package.json')\n\t\tif (matchesFile(path)) {\n\t\t\ttry {\n\t\t\t\tconst manifest = readJson(path)\n\t\t\t\treturn isRecord(manifest) ? manifest.type : undefined\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t}\n\t\tif (directory === installed) return undefined\n\t\tconst parent = dirname(directory)\n\t\tif (parent === directory) return undefined\n\t\tdirectory = parent\n\t}\n}\n\nfunction resolvesBrowser(entry: unknown): boolean {\n\tconst module = resolveTarget(entry, RUNTIME_CONDITIONS.browser)\n\tif (module !== undefined && module.startsWith(BROWSER_OUTPUT)) return true\n\tif (module === undefined) return false\n\tconst imported = resolveTarget(entry, RUNTIME_CONDITIONS.module)\n\tconst required = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)\n\treturn module !== imported && module !== required\n}\n\n// Whether the target selected by Node's CommonJS conditions is a module require can\n// load. A JavaScript target takes its own nearest package scope. Native addons and\n// extensionless targets have their own CommonJS handlers.\nfunction resolvesCommonJS(entry: unknown, installed: string): boolean {\n\tconst target = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)\n\tif (target === undefined) return false\n\tconst name = target.slice(target.lastIndexOf('/') + 1)\n\tif (name.endsWith('.cjs')) return true\n\tif (name.endsWith('.mjs')) return false\n\tif (name.endsWith('.node')) return true\n\tif (!name.includes('.')) return true\n\treturn name.endsWith('.js') && readPackageType(installed, target) !== 'module'\n}\n\n// Whether the declaration selected by a typed CommonJS consumer admits that entry.\n// A `.d.cts` declaration admits and a `.d.mts` declaration refuses. A `.d.ts`\n// declaration takes its own nearest package scope.\nfunction declaresCommonJS(entry: unknown, installed: string): boolean {\n\tconst declaration = resolveDeclaration(entry, DECLARATION_CONDITIONS.commonjs, installed)\n\tif (declaration === undefined) return false\n\tif (declaration.endsWith('.d.cts')) return true\n\tif (declaration.endsWith('.d.mts')) return false\n\treturn declaration.endsWith('.d.ts') && readPackageType(installed, declaration) !== 'module'\n}\n\n// Every target an entry names under any condition. A fallback list omits members\n// Node rejects during package-target validation, because no reader can take them.\nfunction collectTargets(entry: unknown): readonly string[] {\n\tif (typeof entry === 'string') return [entry]\n\tif (isList(entry)) return entry.flatMap(collectTargets).filter(isPackageTarget)\n\tif (!isRecord(entry)) return []\n\treturn Object.values(entry).flatMap((nested) => collectTargets(nested))\n}\n\n// Whether a target is a file a runtime loads for its names, which is what a\n// declaration is owed for. The extension on the target's own file name decides it,\n// and a name carrying no extension is code: `require` reads such a file through its\n// JavaScript handler, so an extensionless target loads and publishes names. Node\n// loads `.node` through its native-addon handler. Every other extension is an asset\n// a consumer reads rather than imports — a stylesheet, a WebAssembly binary, the\n// `\"./package.json\"` manifest pointer, and a declaration alike.\n// The cost is an extensionless file published for a reader, such as a `LICENSE`:\n// that target reports undeclared until it is given an extension or a declaration.\nfunction isModule(target: string): boolean {\n\tconst name = target.slice(target.lastIndexOf('/') + 1)\n\tconst dot = name.lastIndexOf('.')\n\tif (name.endsWith(ADDON_EXTENSION)) return true\n\treturn dot === -1 || MODULE_EXTENSIONS.includes(name.slice(dot))\n}\n\n// Whether a resolved target is a declaration rather than the JavaScript a\n// `default` branch answers with when the entry declares no `types` condition.\nfunction isDeclaration(target: string): boolean {\n\treturn DECLARATION_EXTENSIONS.some((extension) => target.endsWith(extension))\n}\n\n// The declarations the Node module, Node CommonJS, and browser drives compare\n// against. Each field uses the conditions of the TypeScript consumer paired with\n// that runtime. A JavaScript target resolves through TypeScript's adjacent\n// declaration substitution rather than standing in for the declaration itself.\nfunction readDeclaration(\n\tentry: unknown,\n\tinstalled: string,\n): {\n\treadonly module: string | undefined\n\treadonly commonjs: string | undefined\n\treadonly browser: string | undefined\n} {\n\treturn {\n\t\tmodule: resolveDeclaration(entry, DECLARATION_CONDITIONS.module, installed),\n\t\tcommonjs: resolveDeclaration(entry, DECLARATION_CONDITIONS.commonjs, installed),\n\t\tbrowser: resolveDeclaration(entry, DECLARATION_CONDITIONS.browser, installed),\n\t}\n}\n\n// The entries one compile driver can resolve under its own conditions.\nfunction selectEntries(entries: readonly Entry[], conditions: readonly string[]): readonly Entry[] {\n\treturn entries.filter(\n\t\t(entry) =>\n\t\t\tresolveTarget(entry.mapping, conditions) !== undefined &&\n\t\t\t(!conditions.includes('require') || entry.loadable),\n\t)\n}\n\n// The compile drivers whose conditions reach one entry under one importing format.\n// A driver that resolves no target for that entry compiles nothing, so a consumer\n// written under it would report a resolution failure this package never made.\nfunction selectDrivers(entry: Entry, format: Format): readonly Resolution[] {\n\treturn RESOLUTIONS.filter(\n\t\t(driver) => selectEntries([entry], driver.conditions[format]).length > 0,\n\t)\n}\n\n// Requirable entries that declare CommonJS support but a typed CommonJS consumer\n// cannot compile against. A default branch resolving under the require condition\n// set makes no CommonJS claim.\nfunction selectUntypable(entries: readonly Entry[], installed: string): readonly Entry[] {\n\treturn entries.filter(\n\t\t(entry) =>\n\t\t\tentry.requirable &&\n\t\t\tisRecord(entry.mapping) &&\n\t\t\tObject.hasOwn(entry.mapping, 'require') &&\n\t\t\t!declaresCommonJS(entry.mapping, installed),\n\t)\n}\n\n// One surface comparison, written as the consumer module that proves it: the\n// installed entry that consumer imports, the file extension fixing its importing\n// format, the names a real runtime published off it, and the driver whose scratch\n// project compiles it.\ninterface Surface {\n\treadonly entry: Entry\n\treadonly extension: string\n\treadonly published: readonly string[]\n\treadonly driver: Resolution\n}\n\n// A scratch project over named consumer modules, written beside them so their own\n// resolution reaches the installed package. Nothing is emitted and no ambient types\n// are pulled in, so what the check reads is the installed declarations alone.\nfunction writeProject(\n\tstage: Stage,\n\tname: string,\n\tdriver: Resolution,\n\tfiles: readonly string[],\n): string {\n\tconst path = join(stage.consumer, `tsconfig.${name}.json`)\n\tconst project = {\n\t\tcompilerOptions: {\n\t\t\tmodule: driver.module,\n\t\t\tmoduleResolution: driver.resolution,\n\t\t\tnoEmit: true,\n\t\t\tskipLibCheck: true,\n\t\t\tstrict: true,\n\t\t\ttarget: 'esnext',\n\t\t\ttypes: [],\n\t\t},\n\t\tfiles: [...files],\n\t}\n\twriteFile(path, `${JSON.stringify(project, undefined, '\\t')}\\n`)\n\treturn path\n}\n\n// The diagnostics the compiler this workspace installs reports for one scratch\n// project. The compiler runs as a command, so nothing here reaches an API that\n// moves between its majors, and the located lines it prints are the verdict rather\n// than the exit code, which moves between them. A line carrying no location, a line\n// naming the scratch project rather than a consumer module, and anything at all on\n// the error stream are faults of this proof rather than of the package under proof,\n// so each is raised where it happens instead of counted against the package.\nfunction checkProject(stage: Stage, project: string): readonly string[] {\n\tconst result = runNode([TSC, '--noEmit', '--pretty', 'false', '-p', project], stage.consumer)\n\tconst refused = `${result.stderr ?? ''}`.trim()\n\tif (refused.length > 0) {\n\t\tthrow new Error(`The consumer compiler wrote ${refused} to its error stream`)\n\t}\n\tconst reported: string[] = []\n\tfor (const line of `${result.stdout ?? ''}`.split(/\\r\\n|\\n/u)) {\n\t\tif (line.trim().length === 0) continue\n\t\tconst last = reported.at(-1)\n\t\t// An elaborated diagnostic prints its detail on indented lines under its own\n\t\t// first line, so each of those joins the diagnostic it elaborates.\n\t\tif (/^\\s/u.test(line) && last !== undefined) {\n\t\t\treported[reported.length - 1] = `${last} ${line.trim()}`\n\t\t\tcontinue\n\t\t}\n\t\tconst located = DIAGNOSTIC_PATTERN.exec(line)?.[1]\n\t\tif (located === undefined) {\n\t\t\tthrow new Error(`The consumer compiler reported ${line}, which names no location`)\n\t\t}\n\t\tif (resolve(stage.consumer, located) === project) {\n\t\t\tthrow new Error(`The scratch project is itself at fault: ${line}`)\n\t\t}\n\t\treported.push(line)\n\t}\n\tif (reported.length === 0 && result.status !== 0) {\n\t\tthrow new Error(`The consumer compiler refused the project: ${readOutput(result)}`)\n\t}\n\treturn reported\n}\n\n// One installed entry's published names checked against its own declarations by\n// the compiler this workspace installs, in the direction each divergence surfaces\n// under. The runtime's key list is written into the consumer as a literal, so the\n// published side comes from a real process and the declared side from the\n// declarations that process's package ships, and the two can disagree. A name the\n// declarations carry and the runtime does not lands on `declared`. A name the\n// runtime carries and the declarations do not, and a name the declarations publish\n// as a type alone, land on `surfaced`: a variable widens into the type\n// `declared` annotates, and only `surfaced` reads the literal's own keys back.\n// Each names the member it is about, so the failure says which export moved.\nfunction checkSurface(stage: Stage, surface: Surface): readonly string[] {\n\tconst slug = surface.entry.subpath.replaceAll(/[^\\w]+/gu, '-')\n\tconst name = `surface.${surface.driver.label}${slug}.${surface.extension}`\n\tconst module = `${name}`\n\tconst keys = surface.published.map((key) => `${JSON.stringify(key)}: true`).join(', ')\n\twriteFile(\n\t\tjoin(stage.consumer, module),\n\t\t`import * as entry from ${JSON.stringify(surface.entry.specifier)}\nconst published = {${keys.length === 0 ? '' : ` ${keys} `}} as const\nconst declared: Record<keyof typeof entry, true> = published\nconst surfaced: Record<keyof typeof published, true> = declared\n`,\n\t)\n\tconst project = writeProject(stage, name, surface.driver, [`./${module}`])\n\treturn checkProject(stage, project).map((line) => `${surface.driver.label}: ${line}`)\n}\n\n// One consumer module importing every installed entry, written where its own\n// resolution finds the installed package.\nfunction writeConsumerProbe(stage: Stage, path: string, specifiers: readonly string[]): void {\n\tconst names: string[] = []\n\tconst bindings: string[] = []\n\tfor (const [index, specifier] of specifiers.entries()) {\n\t\tconst binding = `entry${String(index)}`\n\t\tnames.push(binding)\n\t\tbindings.push(`import * as ${binding} from ${JSON.stringify(specifier)}`)\n\t}\n\tconst source = `${bindings.join('\\n')}\\nexport const surface = [${names.join(', ')}]\\n`\n\twriteFile(join(stage.consumer, path), source)\n}\n\n// The runtime key set a real process reads off one installed entry under one\n// condition. The driver is a file rather than an `--eval` string, so the specifier\n// travels as an argument and nothing needs escaping.\nfunction driveRuntime(stage: Stage, specifier: string, driver: string): readonly string[] {\n\tconst result = runNode([join(stage.consumer, driver), specifier], stage.consumer)\n\tif (result.status !== 0) {\n\t\tthrow new Error(`Loading ${specifier} from the consumer failed: ${readOutput(result)}`)\n\t}\n\tconst published: unknown = JSON.parse(result.stdout)\n\tif (!isNames(published)) throw new Error(`The driver printed no name list for ${specifier}`)\n\treturn published\n}\n{{helpers}}\n// Pack this workspace, install the archive into an isolated consumer, and read the\n// published surface back off the installed tree. Every later claim reads this\n// result, so a failure here is raised where it happens rather than once per entry.\nfunction buildStage(): Stage {\n\tconst packed = join(SCRATCH, 'packed')\n\tconst consumer = join(SCRATCH, 'consumer')\n\tmkdirSync(packed, { recursive: true })\n\tconst pack = runNpm(['pack', '--ignore-scripts', '--pack-destination', packed], ROOT)\n\tif (pack.status !== 0) throw new Error(`npm pack refused this workspace: ${readOutput(pack)}`)\n\tconst archives = readdirSync(packed).filter((name) => name.endsWith('.tgz'))\n\tconst archive = archives[0]\n\tif (archives.length !== 1 || archive === undefined) {\n\t\tthrow new Error(`npm pack wrote no single archive: ${archives.join(', ')}`)\n\t}\n\twriteFile(join(consumer, 'package.json'), CONSUMER_MANIFEST)\n\twriteFile(join(consumer, ESM_DRIVER), ESM_DRIVER_SOURCE)\n\twriteFile(join(consumer, CJS_DRIVER), CJS_DRIVER_SOURCE)\n\tconst install = runNpm(\n\t\t['install', '--ignore-scripts', '--no-audit', '--no-fund', join(packed, archive)],\n\t\tconsumer,\n\t)\n\tif (install.status !== 0) {\n\t\tthrow new Error(`Installing the packed archive failed: ${readOutput(install)}`)\n\t}\n\tconst name = readManifestName(join(ROOT, 'package.json'))\n\tconst installed = join(consumer, 'node_modules', ...name.split('/'))\n\tconst manifest = readJson(join(installed, 'package.json'))\n\tif (!isRecord(manifest) || !isRecord(manifest.exports)) {\n\t\tthrow new Error('The installed manifest publishes no exports map')\n\t}\n\tconst entries: Entry[] = []\n\tconst targets: string[] = []\n\tconst subpaths: string[] = []\n\tconst undeclared: string[] = []\n\tconst excluded: string[] = []\n\tfor (const [subpath, entry] of Object.entries(manifest.exports)) {\n\t\tconst files = collectTargets(entry)\n\t\ttargets.push(...files)\n\t\tsubpaths.push(subpath)\n\t\tconst declaration = readDeclaration(entry, installed)\n\t\t// A subpath resolving no declaration is partitioned rather than dropped. It is a\n\t\t// defect when a runtime loads one of its targets for names, because a consumer\n\t\t// importing it compiles against nothing under `node16`. It is an excluded\n\t\t// publication otherwise: the `\"./package.json\"` manifest pointer and a stylesheet\n\t\t// are published for a reader rather than an importer.\n\t\tif (\n\t\t\tdeclaration.module === undefined &&\n\t\t\tdeclaration.commonjs === undefined &&\n\t\t\tdeclaration.browser === undefined\n\t\t) {\n\t\t\tif (files.some(isModule)) undeclared.push(subpath)\n\t\t\telse excluded.push(subpath)\n\t\t\tcontinue\n\t\t}\n\t\tconst importTarget = resolveTarget(entry, RUNTIME_CONDITIONS.module)\n\t\tconst requireTarget = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)\n\t\tconst browserTarget = resolveTarget(entry, RUNTIME_CONDITIONS.browser)\n\t\tconst browsable = resolvesBrowser(entry)\n\t\tconst shadowed = browsable && requireTarget === browserTarget\n\t\tconst requirable = requireTarget !== undefined && !shadowed\n\t\tconst loadable = requirable && resolvesCommonJS(entry, installed)\n\t\tentries.push({\n\t\t\tsubpath,\n\t\t\tspecifier: subpath === '.' ? name : `${name}${subpath.slice(1)}`,\n\t\t\tmapping: entry,\n\t\t\tdeclaration: {\n\t\t\t\timportable: declaration.module !== undefined,\n\t\t\t\trequirable: declaration.commonjs !== undefined,\n\t\t\t\tbrowsable: declaration.browser !== undefined,\n\t\t\t},\n\t\t\tbrowsable,\n\t\t\timportable: importTarget !== undefined && !(browsable && importTarget === browserTarget),\n\t\t\trequirable,\n\t\t\tloadable,\n\t\t})\n\t}\n\treturn { consumer, installed, archives, entries, subpaths, undeclared, excluded, targets }\n}\n\nconst SCRATCH = mkdtempSync(join(tmpdir(), 'distribution-'))\nconst CACHE = join(SCRATCH, 'cache')\nmkdirSync(CACHE, { recursive: true })\n// The scratch tree holds the npm cache, the packed archive, and the installed\n// consumer, so its removal is registered before the first thing that can throw.\nafterAll(() => {\n\trmSync(SCRATCH, { force: true, recursive: true })\n})\n\n// Installing the packed archive resolves its own runtime dependencies, so an\n// unreachable registry leaves nothing to measure. Under release that is the gate\n// failing; anywhere else the suite skips and names the mechanism it wanted.\n//\n// A module that throws while loading never reaches the `afterAll` it registered,\n// so every throw here removes the scratch tree on its way out.\nfunction openStage(): Stage | undefined {\n\ttry {\n\t\tif (runNpm(PING, ROOT).status !== 0) {\n\t\t\tif (!RELEASE) return undefined\n\t\t\tthrow new Error(\n\t\t\t\t'The release gate requires a reachable npm registry, and npm ping did not answer',\n\t\t\t)\n\t\t}\n\t\treturn buildStage()\n\t} catch (error) {\n\t\trmSync(SCRATCH, { force: true, recursive: true })\n\t\tthrow error\n\t}\n}\n\nconst STAGE = openStage()\nconst STAGED = STAGE !== undefined\n\ndescribe('distribution classifiers', () => {\n\tit('classifies synthetic export mappings without a registry stage', () => {\n\t\tconst root = join(SCRATCH, 'classifiers')\n\t\twriteFile(\n\t\t\tjoin(root, 'package.json'),\n\t\t\tJSON.stringify({\n\t\t\t\ttype: 'commonjs',\n\t\t\t\texports: {\n\t\t\t\t\tcondition: { browser: './b.js', default: './n.js' },\n\t\t\t\t\tconvention: { default: './dist/src/browser/index.js' },\n\t\t\t\t\tuniversal: { default: './shared.js' },\n\t\t\t\t\t'import-shared': {\n\t\t\t\t\t\tbrowser: './shared.mjs',\n\t\t\t\t\t\timport: './shared.mjs',\n\t\t\t\t\t\tdefault: './node.js',\n\t\t\t\t\t},\n\t\t\t\t\t'require-shared': {\n\t\t\t\t\t\tbrowser: './shared.cjs',\n\t\t\t\t\t\trequire: './shared.cjs',\n\t\t\t\t\t\tdefault: './node.js',\n\t\t\t\t\t},\n\t\t\t\t\tnode: { node: './node.js', default: './node.js' },\n\t\t\t\t\tsilent: { 'module-sync': './x.cjs', import: './x.mjs' },\n\t\t\t\t\tmodule: { require: './x.mjs' },\n\t\t\t\t\t'nested-module': { require: './module/x.js' },\n\t\t\t\t\t'nested-commonjs': { require: './commonjs/x.js' },\n\t\t\t\t\tesm: { import: './x.mjs' },\n\t\t\t\t},\n\t\t\t}),\n\t\t)\n\t\twriteFile(join(root, 'module/package.json'), '{ \"type\": \"module\" }\\n')\n\t\twriteFile(join(root, 'commonjs/package.json'), '{ \"type\": \"commonjs\" }\\n')\n\t\tconst manifest = readJson(join(root, 'package.json'))\n\t\tif (!isRecord(manifest) || !isRecord(manifest.exports)) {\n\t\t\tthrow new Error('The classifier fixture declares no exports map')\n\t\t}\n\t\tconst mappings = manifest.exports\n\t\texpect({\n\t\t\tcondition: resolvesBrowser(mappings.condition),\n\t\t\tconvention: resolvesBrowser(mappings.convention),\n\t\t\tuniversal: resolvesBrowser(mappings.universal),\n\t\t\timport: resolvesBrowser(mappings['import-shared']),\n\t\t\trequire: resolvesBrowser(mappings['require-shared']),\n\t\t\tnode: resolvesBrowser(mappings.node),\n\t\t}).toStrictEqual({\n\t\t\tcondition: true,\n\t\t\tconvention: true,\n\t\t\tuniversal: false,\n\t\t\timport: false,\n\t\t\trequire: false,\n\t\t\tnode: false,\n\t\t})\n\t\texpect({\n\t\t\tsilent: resolvesCommonJS(mappings.silent, root),\n\t\t\tmodule: resolvesCommonJS(mappings.module, root),\n\t\t\tnestedModule: resolvesCommonJS(mappings['nested-module'], root),\n\t\t\tnestedCommonJS: resolvesCommonJS(mappings['nested-commonjs'], root),\n\t\t\tesm: resolvesCommonJS(mappings.esm, root),\n\t\t}).toStrictEqual({\n\t\t\tsilent: true,\n\t\t\tmodule: false,\n\t\t\tnestedModule: false,\n\t\t\tnestedCommonJS: true,\n\t\t\tesm: false,\n\t\t})\n\t})\n})\n\n// The staged consumer, or a skip naming what the run could not reach. `it.skipIf`\n// carries no reason, so the gate sits here where the test context can state one.\nfunction requireStage(context: TestContext): Stage {\n\tif (!STAGED) {\n\t\treturn context.skip('`npm ping` did not answer, so nothing was packed or installed')\n\t}\n\treturn STAGE\n}\n\ndescribe('installed package consumer', () => {\n\tit('packs one archive and installs it in isolation [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\texpect(stage.archives).toHaveLength(1)\n\t\texpect(existsSync(join(stage.installed, 'package.json'))).toBe(true)\n\t\texpect(stage.entries.length).toBeGreaterThan(0)\n\t})\n\n\tit('ships every relative target its exports map names [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst relative = stage.targets.filter((target) => target.startsWith('./'))\n\t\texpect(relative).not.toStrictEqual([])\n\t\texpect(relative.filter((target) => !existsSync(join(stage.installed, target)))).toStrictEqual(\n\t\t\t[],\n\t\t)\n\t})\n\n\t// Every published subpath is driven, excluded by name, or reported here. A dropped\n\t// one leaves no trace: no runtime test, no declaration comparison, and no place in\n\t// the resolution compile, so the run reports success for a subpath it never\n\t// measured.\n\tit('declares types for every module it publishes [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst partitioned = [\n\t\t\t...stage.entries.map((entry) => entry.subpath),\n\t\t\t...stage.undeclared,\n\t\t\t...stage.excluded,\n\t\t]\n\t\texpect(stage.undeclared).toStrictEqual([])\n\t\texpect(partitioned.sort()).toStrictEqual([...stage.subpaths].sort())\n\t\t// A driven subpath answers a runtime condition. One resolving a declaration and\n\t\t// no Node or browser target compiles for a consumer and throws when that consumer\n\t\t// loads it. Each later drive retires itself for that entry, so this assertion names\n\t\t// the subpath rather than counting it as driven.\n\t\tconst unreachable = stage.entries.filter(\n\t\t\t(entry) => !entry.importable && !entry.requirable && !entry.browsable,\n\t\t)\n\t\texpect(unreachable.map((entry) => entry.subpath)).toStrictEqual([])\n\t\tconst untypable = selectUntypable(stage.entries, stage.installed)\n\t\texpect(untypable.map((entry) => entry.subpath)).toStrictEqual([])\n\t})\n\n\tit('refuses a subpath its exports map does not name [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst name = readManifestName(join(stage.installed, 'package.json'))\n\t\tconst driver = join(stage.consumer, ESM_DRIVER)\n\t\tconst result = runNode([driver, `${name}${ABSENT_SUBPATH}`], stage.consumer)\n\t\texpect(result.status).not.toBe(0)\n\t\texpect(readOutput(result)).toContain('ERR_PACKAGE_PATH_NOT_EXPORTED')\n\t})\n\n\t// The absent subpath is the firing control: a resolution that reports nothing\n\t// for every published entry has not been shown to resolve anything at all. Each\n\t// module format carries its own control, because a format that resolves nothing\n\t// is silent for the same reason a resolution that resolves nothing is.\n\tit('compiles a consumer under every module resolution [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst name = readManifestName(join(stage.installed, 'package.json'))\n\t\tconst reported: string[] = []\n\t\tconst silent: string[] = []\n\t\tfor (const driver of RESOLUTIONS) {\n\t\t\tfor (const [extension, format] of FORMATS) {\n\t\t\t\tconst written = selectEntries(stage.entries, driver.conditions[format])\n\t\t\t\tif (written.length === 0) continue\n\t\t\t\tconst label = `${driver.label}.${extension}`\n\t\t\t\tconst probe = `probe.${label}`\n\t\t\t\tconst specifiers = written.map((entry) => entry.specifier)\n\t\t\t\twriteConsumerProbe(stage, probe, specifiers)\n\t\t\t\tconst project = writeProject(stage, probe, driver, [`./${probe}`])\n\t\t\t\tfor (const message of checkProject(stage, project)) {\n\t\t\t\t\treported.push(`${label}: ${message}`)\n\t\t\t\t}\n\t\t\t\tconst control = `control.${label}`\n\t\t\t\twriteConsumerProbe(stage, control, [`${name}${ABSENT_SUBPATH}`])\n\t\t\t\tconst refused = writeProject(stage, control, driver, [`./${control}`])\n\t\t\t\tif (checkProject(stage, refused).length === 0) silent.push(label)\n\t\t\t}\n\t\t}\n\t\texpect(reported).toStrictEqual([])\n\t\texpect(silent).toStrictEqual([])\n\t})\n{{guard}}})\n\nfor (const entry of STAGE?.entries ?? []) {\n\tdescribe(`installed entry ${entry.subpath}`, () => {\n\t\tit.runIf(entry.importable)(\n\t\t\t'publishes what it declares to a Node import, and no more',\n\t\t\t(context) => {\n\t\t\t\tconst stage = requireStage(context)\n\t\t\t\t// The exports-map walk resolved a declaration a typed importer reads, so an\n\t\t\t\t// entry reaching this drive without one is reported for that rather than for\n\t\t\t\t// what a consumer of a missing declaration goes on to say.\n\t\t\t\tif (!entry.declaration.importable) {\n\t\t\t\t\tthrow new Error(`${entry.subpath} publishes no import declaration`)\n\t\t\t\t}\n\t\t\t\tconst published = driveRuntime(stage, entry.specifier, ESM_DRIVER)\n\t\t\t\tconst drivers = selectDrivers(entry, 'module')\n\t\t\t\texpect(drivers).not.toStrictEqual([])\n\t\t\t\tconst reported = drivers.flatMap((driver) =>\n\t\t\t\t\tcheckSurface(stage, { entry, extension: 'ts', published, driver }),\n\t\t\t\t)\n\t\t\t\texpect(reported).toStrictEqual([])\n\t\t\t},\n\t\t)\n\n\t\tit.runIf(entry.requirable)(\n\t\t\t'publishes what it declares to a Node require, and no more',\n\t\t\t(context) => {\n\t\t\t\tconst stage = requireStage(context)\n\t\t\t\tif (!entry.declaration.requirable) {\n\t\t\t\t\tthrow new Error(`${entry.subpath} publishes no require declaration`)\n\t\t\t\t}\n\t\t\t\tconst published = driveRuntime(stage, entry.specifier, CJS_DRIVER)\n\t\t\t\t// A subpath whose `require` resolves to a module that no typed CommonJS\n\t\t\t\t// consumer can compile against carries no declared side to compare here, and\n\t\t\t\t// whether it may publish one at all is the untypable set's question rather\n\t\t\t\t// than this drive's. The preceding runtime drive ran either way.\n\t\t\t\tconst drivers = selectDrivers(entry, 'commonjs')\n\t\t\t\texpect(drivers).not.toStrictEqual([])\n\t\t\t\tconst reported = drivers.flatMap((driver) =>\n\t\t\t\t\tcheckSurface(stage, { entry, extension: 'cts', published, driver }),\n\t\t\t\t)\n\t\t\t\texpect(reported).toStrictEqual([])\n\t\t\t},\n\t\t)\n{{drive}}\t})\n}\n";
|
|
105
105
|
transport: "import { createServer } from 'node:http'\n";
|
|
106
106
|
types: "import type { PlaywrightProviderOptions } from '@vitest/browser-playwright'\nimport type { Browser } from 'playwright'\n";
|
|
107
107
|
launcher: "import { chromium } from 'playwright'\nimport { build } from 'vite'\nimport { resolveBrowser, resolvePinnedBrowser } from '../configs/browsers.js'\n";
|
|
@@ -113,13 +113,13 @@ export declare const ARTIFACT_TEMPLATES: Readonly<{
|
|
|
113
113
|
}>;
|
|
114
114
|
docs: Readonly<{
|
|
115
115
|
readme: "# {{package}}\n\n{{description}}\n\n## Development\n\n```sh\nnpm install\nnpm test\n```\n";
|
|
116
|
-
agents: "# AGENTS.md\n\nThe `@orkestrel/scaffold` package is this repository's coding and orchestration authority. This\nfile points at it and states no law of its own.\n\nRead these before working: the `AGENTS.md` coding contract, the `.agents/orchestration.md`\nagent-operation contract, every applicable rule the contract's rule map names under\n`.claude/rules/`, and the dispatch-named skill under `.agents/skills/` with the references it\nrequires.\n\nResolve every one of those paths against scaffold, never against this repository:\n\n- When a scaffold checkout sits beside this repository, read `../scaffold/AGENTS.md`, the\n `../scaffold/.agents/orchestration.md` file, the `../scaffold/.claude/rules/` directory, and\n the `../scaffold/.agents/skills/` directory.\n- Otherwise read the installed copy, whose paths drop the dot that opens each segment: the\n `node_modules/@orkestrel/scaffold/dist/host/AGENTS.md` file, the\n `node_modules/@orkestrel/scaffold/dist/host/agents/orchestration.md` file, the\n `node_modules/@orkestrel/scaffold/dist/host/claude/rules/` directory, and the\n `node_modules/@orkestrel/scaffold/dist/host/agents/skills/` directory.\n\nEvery path a scaffold-supplied file names resolves the same way. The files this repository carries\n— the `.claude/agents/orkestrel.md` catalog file, the `.claude/settings.json` permission file,\
|
|
117
|
-
claude: "# CLAUDE.md\n\nRead the `AGENTS.md` file in this repository first. It names the coding and orchestration\nauthority and where to read each contract.\n\nThis file imports nothing. An `@path` import inlines the imported file into every context that\nloads it, which is the cost this pointer removes.\n";
|
|
116
|
+
agents: "# AGENTS.md\n\nThe `@orkestrel/scaffold` package is this repository's coding and orchestration authority. This\nfile points at it and states no law of its own.\n\nRead these before working: the `AGENTS.md` coding contract, the `.agents/orchestration.md`\nagent-operation contract, every applicable rule the contract's rule map names under\n`.claude/rules/`, and the dispatch-named skill under `.agents/skills/` with the references it\nrequires.\n\nResolve every one of those paths against scaffold, never against this repository:\n\n- When a scaffold checkout sits beside this repository, read `../scaffold/AGENTS.md`, the\n `../scaffold/.agents/orchestration.md` file, the `../scaffold/.claude/rules/` directory, and\n the `../scaffold/.agents/skills/` directory.\n- Otherwise read the installed copy, whose paths drop the dot that opens each segment: the\n `node_modules/@orkestrel/scaffold/dist/host/AGENTS.md` file, the\n `node_modules/@orkestrel/scaffold/dist/host/agents/orchestration.md` file, the\n `node_modules/@orkestrel/scaffold/dist/host/claude/rules/` directory, and the\n `node_modules/@orkestrel/scaffold/dist/host/agents/skills/` directory.\n\nEvery path a scaffold-supplied file names resolves the same way. Run a script such a file names\nthrough its built twin: replace `node .agents/skills/` with\n`node node_modules/@orkestrel/scaffold/dist/agents/skills/` and the `.ts` extension with `.js`,\nbecause Node runs no `.ts` file under `node_modules`. The files this repository carries\n— the `.claude/agents/orkestrel.md` catalog file, the `.claude/settings.json` permission file,\nthe bench scripts under `scripts/`, and the skill pointers under `.agents/skills/` and\n`.claude/skills/`, which name the canonical skills and how to run their scripts — are this\nrepository's own copies and resolve here.\n\nIn Claude Code, also read the Claude bridge: `../scaffold/.claude/AGENTS.md` beside a checkout, or\n`node_modules/@orkestrel/scaffold/dist/host/claude/AGENTS.md` from the installed copy. Keep no\n`CLAUDE.md` in this repository; one stops Claude Code from reading this file.\n\nEdit none of the scaffold-owned files here. The `scaffold repair` command restores them, so a\nchange to one is a commit in the scaffold repository followed by a release.\n";
|
|
118
117
|
}>;
|
|
119
118
|
guides: Readonly<{
|
|
120
119
|
readme: "# Guides\n\n## By concept\n\n- Package\n - Spec: Not created. Create this file when the workspace has a public surface:\n `guides/{{guide}}.md`\n - Source:\n{{source}}\n - Tests:\n{{tests}}\n\n## By directory\n\n{{directories}}\n";
|
|
121
120
|
}>;
|
|
122
121
|
orchestration: Readonly<{
|
|
122
|
+
skill: "\n# Load the canonical skill\n\nThis file is a pointer the `@orkestrel/scaffold` package writes into every fleet workspace; the\nskill itself ships with that package. Read the canonical `SKILL.md` completely and follow it:\n\n- beside a scaffold checkout, `../scaffold/.agents/skills/{{name}}/SKILL.md`;\n- otherwise, `node_modules/@orkestrel/scaffold/dist/host/agents/skills/{{name}}/SKILL.md`.\n\nResolve every path the canonical skill names against the same root; under `node_modules` each\nsegment drops its opening dot. Run a script the skill names through its built twin, as this\nrepository's `AGENTS.md` states. This pointer carries no process of its own; `AGENTS.md`, the applicable\nrules, and the canonical skill remain authoritative in that order.\n";
|
|
123
123
|
service: "#!/usr/bin/env sh\nset -eu\n\nprintf '%s\\n' \\\n{{vendors}}\n";
|
|
124
124
|
}>;
|
|
125
125
|
}>;
|
|
@@ -253,13 +253,16 @@ export declare const BIN_ENTRY_PATH = "src/bin/main.ts";
|
|
|
253
253
|
* fleet pin; every other peer is a floor. `extras` are package-specific
|
|
254
254
|
* development dependencies and may carry any valid npm name.
|
|
255
255
|
* `bin`, `setup`, `guides`, `integration`, `conformance`, `service`,
|
|
256
|
-
* `vendors`, `global`, `showcase`, and `
|
|
256
|
+
* `vendors`, `global`, `showcase`, `journey`, and `skills` are structural facts: each is
|
|
257
257
|
* set only when the workspace physically ships the directory or exact-case file
|
|
258
258
|
* that defines it, never because of the workspace's name and never because a
|
|
259
259
|
* sibling fact is set.
|
|
260
260
|
* `setup` lists the runtimes required by root setup proofs: `node` for generic
|
|
261
261
|
* and server proofs, and `browser` for `tests/setupBrowser.test.ts`.
|
|
262
262
|
* `journey` selects the birth-owned variant wrapper for a browser application.
|
|
263
|
+
* `skills` registers the `skills` Vitest project over the mirrored proofs of the skill
|
|
264
|
+
* scripts a workspace ships under each `.agents/skills/<skill>/scripts/` directory, and adds their
|
|
265
|
+
* scoped typecheck.
|
|
263
266
|
* `showcase` projects only a browser `app`. The gate answers an absent browser
|
|
264
267
|
* axis with a non-blocking question, so a caller that set the flag learns it
|
|
265
268
|
* emitted nothing and the compile still completes.
|
|
@@ -293,6 +296,7 @@ export declare interface Blueprint {
|
|
|
293
296
|
readonly global: boolean;
|
|
294
297
|
readonly showcase: boolean;
|
|
295
298
|
readonly journey: boolean;
|
|
299
|
+
readonly skills: boolean;
|
|
296
300
|
}
|
|
297
301
|
|
|
298
302
|
/**
|
|
@@ -355,21 +359,23 @@ export declare function blueprintToDevDependencies(blueprint: Blueprint): Readon
|
|
|
355
359
|
*
|
|
356
360
|
* @param blueprint - The workspace specification.
|
|
357
361
|
* @returns The birth-owned package front page and the content-owned `AGENTS.md`
|
|
358
|
-
*
|
|
362
|
+
* pointer.
|
|
359
363
|
*
|
|
360
364
|
* @remarks
|
|
361
365
|
* The front page is the workspace's own prose, so it is written once and left
|
|
362
|
-
* alone from then on. The
|
|
363
|
-
* restored whenever
|
|
366
|
+
* alone from then on. The pointer is scaffold's, so it is content-owned and
|
|
367
|
+
* restored whenever it drifts.
|
|
364
368
|
*
|
|
365
|
-
*
|
|
366
|
-
* vendored paths at one storage name, and `AGENTS.md`
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
+
* The pointer is planned here rather than vendored because `stageHost` refuses two
|
|
370
|
+
* vendored paths at one storage name, and `AGENTS.md` already stores the canon a
|
|
371
|
+
* release ships. Planning it as this package's own content leaves the path with
|
|
372
|
+
* one claimant. No `CLAUDE.md` is planned: a target holding one stops Claude Code
|
|
373
|
+
* from reading `AGENTS.md`, so the path stays canon without a claimant, `audit`
|
|
374
|
+
* reports a copy `foreign`, and `overwrite` deletes it.
|
|
369
375
|
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
376
|
+
* The pointer carries no varying span, so it is not filled: a workspace's name
|
|
377
|
+
* never reaches the text, and the paths a reader follows are the same in every
|
|
378
|
+
* target.
|
|
373
379
|
*
|
|
374
380
|
* @example
|
|
375
381
|
* ```ts
|
|
@@ -377,7 +383,7 @@ export declare function blueprintToDevDependencies(blueprint: Blueprint): Readon
|
|
|
377
383
|
*
|
|
378
384
|
* const blueprint = createBlueprint('router', { src: ['core'] })
|
|
379
385
|
*
|
|
380
|
-
* blueprintToDocumentArtifacts(blueprint).map((artifact) => artifact.path) // ['README.md', 'AGENTS.md'
|
|
386
|
+
* blueprintToDocumentArtifacts(blueprint).map((artifact) => artifact.path) // ['README.md', 'AGENTS.md']
|
|
381
387
|
* ```
|
|
382
388
|
*/
|
|
383
389
|
export declare function blueprintToDocumentArtifacts(blueprint: Blueprint): readonly ContentArtifact[];
|
|
@@ -424,13 +430,20 @@ export declare function blueprintToGuideArtifacts(blueprint: Blueprint): readonl
|
|
|
424
430
|
* staged bytes; and the `.claude/agents` directory in `CANON_PATHS` is what
|
|
425
431
|
* stages those bytes, so listing the file in `HOST_PATHS` as well would claim one
|
|
426
432
|
* storage name twice and refuse the stage. The rest of the canon a target reads
|
|
427
|
-
* from the installed package, at the locations the `AGENTS.md`
|
|
428
|
-
*
|
|
433
|
+
* from the installed package, at the locations the `AGENTS.md` pointer
|
|
434
|
+
* {@link blueprintToDocumentArtifacts} emits names.
|
|
429
435
|
*
|
|
430
436
|
* The {@link SEED_GUIDE_PATHS} mirrors are claimed explicitly
|
|
431
437
|
* from `REFERENCE_PATHS`. The target's own guide is excluded by
|
|
432
438
|
* {@link selectHostPaths}; the remaining reference guides grant no target claim.
|
|
433
439
|
*
|
|
440
|
+
* The skill pointer set follows, for each name in {@link TARGET_SKILL_NAMES}:
|
|
441
|
+
* the `.claude/skills/<name>/SKILL.md` bridge and the
|
|
442
|
+
* `.agents/skills/<name>/agents/openai.yaml` sidecar as copies, then the
|
|
443
|
+
* `.agents/skills/<name>/SKILL.md` pointer with `pointer` set, whose bytes
|
|
444
|
+
* hydration derives from the canonical skill. A blueprint with `skills` set
|
|
445
|
+
* ships its own skill canon, so it plans no pointer set.
|
|
446
|
+
*
|
|
434
447
|
* @example
|
|
435
448
|
* ```ts
|
|
436
449
|
* import { blueprintToHostArtifacts, createBlueprint } from '@orkestrel/scaffold'
|
|
@@ -439,6 +452,7 @@ export declare function blueprintToGuideArtifacts(blueprint: Blueprint): readonl
|
|
|
439
452
|
*
|
|
440
453
|
* blueprintToHostArtifacts(blueprint).some((artifact) => artifact.path === 'tests/guides.test.ts') // false
|
|
441
454
|
* blueprintToHostArtifacts(blueprint).some((artifact) => artifact.path === 'guides/router.md') // false
|
|
455
|
+
* blueprintToHostArtifacts(blueprint).find((artifact) => artifact.path === '.agents/skills/orkestrel-harden/SKILL.md')?.pointer // true
|
|
442
456
|
* ```
|
|
443
457
|
*/
|
|
444
458
|
export declare function blueprintToHostArtifacts(blueprint: Blueprint): readonly Artifact[];
|
|
@@ -743,7 +757,7 @@ export declare function blueprintToTestArtifacts(blueprint: Blueprint): readonly
|
|
|
743
757
|
* Every direct `test:<project>` script is writable, together with the probe and
|
|
744
758
|
* benchmark workbench scripts. A workspace carrying guides adds `test:guides`,
|
|
745
759
|
* whose package-owned entry runs the guides project and handles explicit parity
|
|
746
|
-
* rewrites
|
|
760
|
+
* rewrites, and one carrying skills adds `test:skills`. Publishing adds the pack and publication lifecycle scripts.
|
|
747
761
|
* Aggregate test scripts and
|
|
748
762
|
* maintainer-owned gate chains stay outside the region.
|
|
749
763
|
*
|
|
@@ -804,8 +818,8 @@ export declare function bytesToHex(bytes: Uint8Array): string;
|
|
|
804
818
|
* Staging walks these beside {@link HOST_PATHS}, so a release ships them and a
|
|
805
819
|
* reader reaches them two ways: a scaffold checkout sitting beside the
|
|
806
820
|
* repository, or the `node_modules/@orkestrel/scaffold/dist/host/` root inside
|
|
807
|
-
* the installed package. The `AGENTS.md`
|
|
808
|
-
*
|
|
821
|
+
* the installed package. The `AGENTS.md` pointer scaffold plans is what names
|
|
822
|
+
* each location.
|
|
809
823
|
*
|
|
810
824
|
* This list, {@link HOST_PATHS}, and {@link REFERENCE_PATHS} are disjoint by
|
|
811
825
|
* prefix in every direction: no member equals or sits beneath another list's
|
|
@@ -814,14 +828,17 @@ export declare function bytesToHex(bytes: Uint8Array): string;
|
|
|
814
828
|
* name twice, which refuses the stage.
|
|
815
829
|
*
|
|
816
830
|
* The plan claims paths inside the canon deliberately, and each has a reason.
|
|
817
|
-
* `blueprintToDocumentArtifacts` claims `AGENTS.md`
|
|
818
|
-
*
|
|
831
|
+
* `blueprintToDocumentArtifacts` claims `AGENTS.md` as this package's own
|
|
832
|
+
* template pointer. `blueprintToHostArtifacts` claims
|
|
819
833
|
* {@link CATALOG_AGENT_PATH}, because the catalog verb refuses a target that
|
|
820
834
|
* lacks the file and repair restores its absence.
|
|
821
835
|
*
|
|
822
836
|
* A target therefore holds a file at a canon path only where the plan claims it.
|
|
823
837
|
* That is the rule every verb obeys, and it is what makes a copy found anywhere
|
|
824
|
-
* else superseded.
|
|
838
|
+
* else superseded. A member this checkout no longer holds, `CLAUDE.md` since
|
|
839
|
+
* Claude Code began reading `AGENTS.md` directly, stays listed for exactly that
|
|
840
|
+
* reason: the stager ships nothing for it, `audit` reports a target's copy
|
|
841
|
+
* `foreign`, and `overwrite` deletes it.
|
|
825
842
|
*/
|
|
826
843
|
export declare const CANON_PATHS: readonly string[];
|
|
827
844
|
|
|
@@ -1274,7 +1291,7 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1274
1291
|
export declare const CONFIG_TEMPLATES: Readonly<{
|
|
1275
1292
|
root: Readonly<{
|
|
1276
1293
|
tsconfig: "{\n\t\"compilerOptions\": {\n\t\t\"target\": \"ESNext\",\n\t\t\"module\": \"ESNext\",\n\t\t\"moduleResolution\": \"bundler\",\n\t\t\"allowImportingTsExtensions\": true,\n\t\t\"lib\": [\"ESNext\", \"DOM\", \"DOM.Iterable\"],\n\t\t\"types\": [\"node\", \"vite/client\", \"vitest/globals\"],\n\t\t\"moduleDetection\": \"force\",\n\t\t\"resolveJsonModule\": true,\n\t\t\"strict\": true,\n\t\t\"verbatimModuleSyntax\": true,\n\t\t\"noUncheckedIndexedAccess\": true,\n\t\t\"noUncheckedSideEffectImports\": true,\n\t\t\"exactOptionalPropertyTypes\": true,\n\t\t\"noUnusedLocals\": true,\n\t\t\"noUnusedParameters\": true,\n\t\t\"noImplicitOverride\": true,\n\t\t\"noFallthroughCasesInSwitch\": true,\n\t\t\"forceConsistentCasingInFileNames\": true,\n\t\t\"skipLibCheck\": true,\n\t\t\"noEmit\": true,\n\t\t\"paths\": {\n{{paths}}\n\t\t}\n\t},\n\t\"exclude\": [\"node_modules\", \"dist\", \"tmp\"]\n}\n";
|
|
1277
|
-
vite: "{{journey}}import type { PluginOption, UserConfig } from 'vite'\nimport { mergeConfig } from 'vite'\n{{imports}}import { defineConfig } from 'vitest/config'\nimport manifest from './package.json' with { type: 'json' }\nimport tsconfig from './tsconfig.json' with { type: 'json' }\n{{helpers}}{{browsers}}import { fileURLToPath, URL } from 'node:url'\n\n{{options}}export function resolveWorkspacePath(relativePath: string): string {\n\treturn fileURLToPath(new URL(relativePath, import.meta.url))\n}\n\nconst peerDependencies = 'peerDependencies' in manifest ? manifest.peerDependencies : undefined\nif (\n\tpeerDependencies !== undefined &&\n\t(typeof peerDependencies !== 'object' ||\n\t\tpeerDependencies === null ||\n\t\tArray.isArray(peerDependencies))\n) {\n\tthrow new Error('package peerDependencies must be an object')\n}\nexport const peers: readonly string[] =\n\tpeerDependencies === undefined ? [] : Object.keys(peerDependencies)\n\nconst resolve = {\n\talias: Object.entries(tsconfig.compilerOptions.paths).reduce((aliases, [key, values]) => {\n\t\tconst [path] = values\n\t\tif (path === undefined) throw new Error('tsconfig path alias ' + key + ' has no target')\n\t\treturn Object.assign(aliases, { [key]: resolveWorkspacePath(path) })\n\t}, {}),\n}\n\n// Merges a caller's override onto the configuration a factory declares, so a\n// package's own configuration reaches the factory through its parameter instead of\n// wrapping the call from outside.\n//\n// Vitest calls every registered project factory with its own invocation record —\n// `command`, `mode`, `isSsrBuild`, `isPreview` — so a factory that also takes an\n// override receives that record in the same position. A `UserConfig` declares `mode`\n// but not `command`, and the invocation record always carries both, so a value\n// carrying the pair is that record rather than an override. The merge returns the\n// base
|
|
1294
|
+
vite: "{{journey}}import type { PluginOption, UserConfig } from 'vite'\nimport { mergeConfig } from 'vite'\n{{imports}}import { defineConfig } from 'vitest/config'\nimport manifest from './package.json' with { type: 'json' }\nimport tsconfig from './tsconfig.json' with { type: 'json' }\n{{helpers}}{{browsers}}import { fileURLToPath, URL } from 'node:url'\n\n{{options}}export function resolveWorkspacePath(relativePath: string): string {\n\treturn fileURLToPath(new URL(relativePath, import.meta.url))\n}\n\nconst peerDependencies = 'peerDependencies' in manifest ? manifest.peerDependencies : undefined\nif (\n\tpeerDependencies !== undefined &&\n\t(typeof peerDependencies !== 'object' ||\n\t\tpeerDependencies === null ||\n\t\tArray.isArray(peerDependencies))\n) {\n\tthrow new Error('package peerDependencies must be an object')\n}\nexport const peers: readonly string[] =\n\tpeerDependencies === undefined ? [] : Object.keys(peerDependencies)\n\nconst resolve = {\n\talias: Object.entries(tsconfig.compilerOptions.paths).reduce((aliases, [key, values]) => {\n\t\tconst [path] = values\n\t\tif (path === undefined) throw new Error('tsconfig path alias ' + key + ' has no target')\n\t\treturn Object.assign(aliases, { [key]: resolveWorkspacePath(path) })\n\t}, {}),\n}\n\n// Merges a caller's override onto the configuration a factory declares, so a\n// package's own configuration reaches the factory through its parameter instead of\n// wrapping the call from outside.\n//\n// Vitest calls every registered project factory with its own invocation record —\n// `command`, `mode`, `isSsrBuild`, `isPreview` — so a factory that also takes an\n// override receives that record in the same position. A `UserConfig` declares `mode`\n// but not `command`, and the invocation record always carries both, so a value\n// carrying the pair is that record rather than an override. The merge returns the\n// base in the record's `mode` and carries none of the record's other fields. Vitest\n// runs a project that declares no `mode` in its own run mode, `test`, rather than in\n// the `--mode` value it was invoked with, so a distribution proof run with\n// `--mode release` would read `test` and skip where it must fail. A record whose\n// `mode` is not a string throws. The `tests/config.test.ts` file drives every\n// registered factory through it.\n//\n// `mergeConfig` concatenates arrays, so an override carrying `plugins` would otherwise\n// add a second copy of a plugin the base already declares. Only named top-level\n// objects replace a base plugin of the same name, in the base's position, and one\n// override entry is taken at most once. An entry no base position took appends in its\n// written order; the caller's own entries never merge with each other. Nested arrays,\n// promises, falsy entries, and anonymous objects pass through unchanged. An override\n// cannot remove a base plugin. Every key other than `plugins` merges as `mergeConfig`\n// merges it, so an override's arrays elsewhere concatenate with the base's rather than\n// replacing them.\nexport function mergeOverride(base: UserConfig, override?: UserConfig): UserConfig {\n\tif (override === undefined) return base\n\tif ('command' in override && 'mode' in override) {\n\t\tif (typeof override.mode !== 'string') {\n\t\t\tthrow new Error('The project invocation carries no string mode')\n\t\t}\n\t\treturn { ...base, mode: override.mode }\n\t}\n\tconst merged: UserConfig = mergeConfig(base, override)\n\tif (merged.plugins === undefined) return merged\n\tconst candidates = override.plugins ?? []\n\tconst taken = new Set<number>()\n\tconst selected: PluginOption[] = []\n\tfor (const plugin of base.plugins ?? []) {\n\t\tif (!isNamedPlugin(plugin)) {\n\t\t\tselected.push(plugin)\n\t\t\tcontinue\n\t\t}\n\t\tconst index = candidates.findIndex(\n\t\t\t(candidate, position) =>\n\t\t\t\t!taken.has(position) && isNamedPlugin(candidate) && candidate.name === plugin.name,\n\t\t)\n\t\tconst replacement = candidates[index]\n\t\tif (replacement === undefined) {\n\t\t\tselected.push(plugin)\n\t\t} else {\n\t\t\tselected.push(replacement)\n\t\t\ttaken.add(index)\n\t\t}\n\t}\n\tfor (const [index, plugin] of candidates.entries()) {\n\t\tif (!taken.has(index)) selected.push(plugin)\n\t}\n\treturn { ...merged, plugins: selected }\n}\n\nfunction isNamedPlugin(plugin: PluginOption): plugin is { name: string } {\n\treturn (\n\t\ttypeof plugin === 'object' &&\n\t\tplugin !== null &&\n\t\t!Array.isArray(plugin) &&\n\t\t!('then' in plugin && typeof plugin.then === 'function') &&\n\t\t'name' in plugin &&\n\t\ttypeof plugin.name === 'string'\n\t)\n}\n\n{{factories}}export default defineConfig({\n\tresolve,\n\ttest: {\n{{projects}}\n\t},\n})\n";
|
|
1278
1295
|
}>;
|
|
1279
1296
|
factories: Readonly<{
|
|
1280
1297
|
src: Readonly<{
|
|
@@ -1295,10 +1312,11 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1295
1312
|
setup: "export function setup(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'setup', color: 'white' },\n\t\t\tinclude: ['tests/setup*.test.ts'],\n\t\t\texclude: ['tests/setupBrowser.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1296
1313
|
browser: "export function setupBrowser(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n{{plugins}}\t\ttest: {\n\t\t\tname: { label: 'setup:browser', color: 'blue' },\n\t\t\tinclude: ['tests/setupBrowser.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1297
1314
|
guides: "export function guides(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'guides', color: 'green' },\n\t\t\tinclude: ['tests/guides.test.ts'],\n\t\t\texclude: ['tests/src/**/*.test.ts', 'tests/app/**/*.test.ts', 'tests/setup.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1315
|
+
skills: "// The skill scripts this package ships as canon, each driven as a child process against a\n// scratch fixture from its mirrored proof under `tests/agents/skills/<skill>/scripts/`. The\n// `configs/agents/tsconfig.skills.json` wrapper selects the project.\nexport function skills(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'skills', color: 'blue' },\n\t\t\tinclude: ['tests/agents/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\t// Each case spawns node on a script; a census case runs `vitest list` over this checkout.\n\t\t\ttestTimeout: 60_000,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1298
1316
|
conformance: "// Where this package drifts from the official tooling it stays compatible with.\n// The subject is this package, so the proof is hermetic and stays in `npm test`.\nexport function conformance(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'conformance', color: 'magenta' },\n\t\t\tinclude: ['tests/conformance.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1299
1317
|
service: "// The caller prepares the live external services before this project.\n// `tests/setupService.ts` verifies readiness, and the project stays out of `npm test`\n// because a real service answers it.\nexport function service(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'service', color: 'red' },\n\t\t\tinclude: ['tests/service/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupService.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\ttestTimeout: 120_000,\n\t\t\thookTimeout: 120_000,\n\t\t\tfileParallelism: false,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1300
1318
|
distribution: "export function distribution(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'distribution', color: 'cyan' },\n\t\t\tinclude: ['tests/distribution.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\ttestTimeout: 120_000,\n\t\t\thookTimeout: 120_000,\n\t\t\tfileParallelism: false,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1301
|
-
probe: "// A workbench, not a proof. No gate selects this project. Run in test mode by the\n// `test:probe` script, it collects `tmp/
|
|
1319
|
+
probe: "// A workbench, not a proof. No gate selects this project. Run in test mode by the\n// `test:probe` script, it collects `tmp/probes/**/*.test.ts`. Run in benchmark mode by the\n// `test:bench` script, the same workbench also collects `tests/**/*.test.ts` for a `bench` block,\n// so a suite may carry a bench beside its ordinary tests without a second project. The mode\n// guard around each `bench` call keeps it out of test mode, so it never executes there.\nexport function probe(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'probe', color: 'black' },\n\t\t\tinclude: ['tmp/probes/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\tfileParallelism: false,\n\t\t\tpool: 'threads',\n\t\t\tbenchmark: { include: ['tmp/probes/**/*.test.ts', 'tests/**/*.test.ts'] },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1302
1320
|
integration: "export function integration(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'integration', color: 'blue' },\n\t\t\tinclude: ['tests/integration.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n{{global}}\t\t\tenvironment: 'node',\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1303
1321
|
}>;
|
|
1304
1322
|
tsconfigs: Readonly<{
|
|
@@ -1313,6 +1331,7 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1313
1331
|
server: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\"],\n\t\t\"types\": [\"node\"]\n\t},\n\t\"include\": [\n{{include}}\n\t]\n}\n";
|
|
1314
1332
|
}>;
|
|
1315
1333
|
bin: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\"],\n\t\t\"types\": [\"node\"],\n\t\t\"noEmit\": false,\n\t\t\"declaration\": true,\n\t\t\"emitDeclarationOnly\": true,\n\t\t\"rootDir\": \"../../src\",\n\t\t\"outDir\": \"../../dist/bin\"\n\t},\n\t\"include\": [\n\t\t\"../../src/bin/**/*.cts\",\n\t\t\"../../src/bin/**/*.mts\",\n\t\t\"../../src/bin/**/*.ts\",\n\t\t\"../../src/bin/**/*.tsx\"\n\t]\n}\n";
|
|
1334
|
+
skills: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\"],\n\t\t\"types\": [\"node\"]\n\t},\n\t\"include\": [\"../../.agents/skills/*/scripts/*.ts\"],\n\t\"exclude\": [\"../../node_modules\"]\n}\n";
|
|
1316
1335
|
}>;
|
|
1317
1336
|
vites: Readonly<{
|
|
1318
1337
|
src: Readonly<{
|
|
@@ -1725,11 +1744,15 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1725
1744
|
* {@link HydratedArtifact}. Workspace-owned paths and paths whose bytes belong
|
|
1726
1745
|
* to another verb stay plain host artifacts, because this writer claims only
|
|
1727
1746
|
* their presence.
|
|
1747
|
+
*
|
|
1748
|
+
* `pointer`, when true, makes hydration derive the bytes from the vendored file
|
|
1749
|
+
* rather than copy them, by `renderSkillPointer`; absence means a copy.
|
|
1728
1750
|
*/
|
|
1729
1751
|
export declare interface HostArtifact extends ArtifactBase {
|
|
1730
1752
|
readonly origin: 'host';
|
|
1731
1753
|
readonly ownership: 'presence' | 'birth';
|
|
1732
1754
|
readonly source?: string;
|
|
1755
|
+
readonly pointer?: boolean;
|
|
1733
1756
|
readonly hex?: never;
|
|
1734
1757
|
readonly content?: never;
|
|
1735
1758
|
}
|
|
@@ -1915,10 +1938,11 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1915
1938
|
* boundary, so a sibling whose name opens with a member's name —
|
|
1916
1939
|
* `.claude/rulesets` beside `.claude/rules` — stays outside.
|
|
1917
1940
|
*
|
|
1918
|
-
* Membership answers
|
|
1919
|
-
* it. A plan claims `AGENTS.md
|
|
1920
|
-
*
|
|
1921
|
-
*
|
|
1941
|
+
* Membership answers whether scaffold owns the path, not whether a plan claims
|
|
1942
|
+
* it. A plan claims `AGENTS.md` and {@link CATALOG_AGENT_PATH} at canon paths
|
|
1943
|
+
* deliberately, so a consumer deciding whether to write, restore, or remove a
|
|
1944
|
+
* path reads the plan rather than this predicate. A member the checkout no
|
|
1945
|
+
* longer holds is still canon, so a copy a target keeps reports as foreign.
|
|
1922
1946
|
*
|
|
1923
1947
|
* @example
|
|
1924
1948
|
* ```ts
|
|
@@ -3056,6 +3080,31 @@ export declare class Compiler implements CompilerInterface {
|
|
|
3056
3080
|
*/
|
|
3057
3081
|
export declare const RELEASE_PROOF_COMMAND = "npm run test:distribution -- --mode release";
|
|
3058
3082
|
|
|
3083
|
+
/**
|
|
3084
|
+
* Renders the `SKILL.md` pointer a target carries in place of a canonical skill.
|
|
3085
|
+
*
|
|
3086
|
+
* @param canonical - The canonical `SKILL.md` text, which opens with a frontmatter block.
|
|
3087
|
+
* @param name - The skill directory name the pointer body names.
|
|
3088
|
+
* @returns The canonical frontmatter block copied line for line, from its opening `---` line through
|
|
3089
|
+
* its closing `---` line, then the filled `ARTIFACT_TEMPLATES.orchestration.skill` body, with `\n`
|
|
3090
|
+
* line endings; `undefined` when the canonical text does not open with a complete frontmatter block.
|
|
3091
|
+
*
|
|
3092
|
+
* @remarks
|
|
3093
|
+
* The frontmatter is copied rather than rewritten, so every harness that
|
|
3094
|
+
* discovers the pointer reads the canonical `name` and `description` and
|
|
3095
|
+
* triggers the skill exactly as the canonical file would. A CRLF canonical
|
|
3096
|
+
* text yields the same pointer as its LF form.
|
|
3097
|
+
*
|
|
3098
|
+
* @example
|
|
3099
|
+
* ```ts
|
|
3100
|
+
* import { renderSkillPointer } from '@orkestrel/scaffold'
|
|
3101
|
+
*
|
|
3102
|
+
* renderSkillPointer('---\nname: orkestrel-harden\ndescription: Hardens a package.\n---\n\n# Harden\n', 'orkestrel-harden')?.startsWith('---\nname: orkestrel-harden\ndescription: Hardens a package.\n---\n\n# Load the canonical skill\n') // true
|
|
3103
|
+
* renderSkillPointer('# Harden\n', 'orkestrel-harden') // undefined
|
|
3104
|
+
* ```
|
|
3105
|
+
*/
|
|
3106
|
+
export declare function renderSkillPointer(canonical: string, name: string): string | undefined;
|
|
3107
|
+
|
|
3059
3108
|
/**
|
|
3060
3109
|
* Replaces the runtime and development dependency ranges in package manifest text, and never a
|
|
3061
3110
|
* peer range.
|
|
@@ -3320,6 +3369,9 @@ export declare class Compiler implements CompilerInterface {
|
|
|
3320
3369
|
*/
|
|
3321
3370
|
export declare const SHOWCASE_DEV_DEPENDENCIES: Readonly<Record<string, string>>;
|
|
3322
3371
|
|
|
3372
|
+
/** Names the TypeScript wrapper whose presence makes a workspace `skills`. */
|
|
3373
|
+
export declare const SKILLS_CONFIG_PATH = "configs/agents/tsconfig.skills.json";
|
|
3374
|
+
|
|
3323
3375
|
/** Holds exact lowercase hexadecimal target bytes keyed by artifact-relative path. */
|
|
3324
3376
|
export declare type Snapshot = Readonly<Record<string, string>>;
|
|
3325
3377
|
|
|
@@ -3427,6 +3479,19 @@ export declare class Compiler implements CompilerInterface {
|
|
|
3427
3479
|
/** Sets the columns one tab occupies when the formatter measures a line, matching `tabWidth`. */
|
|
3428
3480
|
export declare const TAB_WIDTH = 2;
|
|
3429
3481
|
|
|
3482
|
+
/**
|
|
3483
|
+
* Lists the package-facing skills a target receives pointers for, frozen and alphabetical.
|
|
3484
|
+
*
|
|
3485
|
+
* @remarks
|
|
3486
|
+
* `blueprintToHostArtifacts` plans, for each name, the Claude bridge, the Codex
|
|
3487
|
+
* sidecar, and the derived `SKILL.md` pointer, so every harness discovers the
|
|
3488
|
+
* skill while its body, references, and scripts stay in the installed package.
|
|
3489
|
+
* `orkestrel-align`, `orkestrel-dispatch`, `orkestrel-publish`, and
|
|
3490
|
+
* `orkestrel-scout` are excluded because they run from the scaffold checkout
|
|
3491
|
+
* and a target is not an orchestration host.
|
|
3492
|
+
*/
|
|
3493
|
+
export declare const TARGET_SKILL_NAMES: readonly string[];
|
|
3494
|
+
|
|
3430
3495
|
/** Matches the exact `major.minor.patch` version syntax a blueprint declares. */
|
|
3431
3496
|
export declare const VERSION_PATTERN: RegExp;
|
|
3432
3497
|
|