@volter/twin-standard 1.0.32 → 1.0.33

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/README.md CHANGED
@@ -6,11 +6,15 @@ workflow, a release, and the twin catalog's check of a submitted version all run
6
6
  place a pack is judged judges it by the same standard.
7
7
 
8
8
  ```bash
9
+ twin-standard create <dir> --init <vendor> --package <@scope/name> # fixed files, in your repository
10
+ twin-standard create <unit> --index # fixed handler map and fetch after derivation
9
11
  twin-standard gate <pack repository> [<pack or lane dir>…] # every unit passes the form section, or exit 1
10
12
  twin-standard gate-published <name>@<version>… [--registry <url>] # a published version, as the catalog grades a submission
11
13
  twin-standard grade <pack or lane dir>… [--static] [--form] # each criterion's result
12
14
  twin-standard derive <pack or lane dir> [--out <dir>] # write src/generated/ from the vendored spec
13
15
  twin-standard check-sources <pack or lane dir> [--recheck] # fetch and record the sources the unit cites
16
+ twin-standard facts <pack dir> [--out <file>] # package-local facts from its descriptor
17
+ twin-standard assess <pack dir> [--browser] [--out <file>] # inside a World
14
18
  twin-standard --version # this package's version and each standard's
15
19
  ```
16
20
 
@@ -18,3 +22,8 @@ What each criterion asks, and the rules for changing one, are twin-world's
18
22
  [architecture, "The grade"](https://github.com/volter-ai/twin-world/blob/main/docs/contributing/architecture.md#the-grade).
19
23
  A changed criterion is a release of this package: a criterion's id never changes meaning; a changed criterion takes a
20
24
  new id and a new standard version, and a tightened check names what newly fails.
25
+
26
+ The public `assessPack(packDir, { browser: true })` API runs inside a World, reports actual operation coverage from
27
+ kernel dispatch and replays journeys through Chromium when their wire is HTTP. Install Playwright and Chromium for
28
+ that target. Its report distinguishes API support, operations exercised, journey failures and replay, and does not
29
+ claim DOM interaction coverage. Catalog controllers own provenance, admission and publication.
@@ -0,0 +1,49 @@
1
+ export type AssessmentOptions = {
2
+ browser?: boolean;
3
+ conformance?: boolean;
4
+ };
5
+ /** Surface coverage counts actual kernel dispatch, and retains every declared gap in the denominator. */
6
+ export declare function assessPack(packDir: string, options?: AssessmentOptions): Promise<{
7
+ schemaVersion: number;
8
+ vendor: string;
9
+ package: any;
10
+ version: any;
11
+ ready: boolean;
12
+ gates: {
13
+ unit: string;
14
+ failures: string[];
15
+ }[];
16
+ quick: {
17
+ scope: string;
18
+ steps: number;
19
+ answered: number;
20
+ failures: {
21
+ step: string;
22
+ beat: string;
23
+ detail: string;
24
+ }[];
25
+ replay: {
26
+ equal: boolean;
27
+ runs: number;
28
+ firstSha256: string;
29
+ secondSha256: string;
30
+ };
31
+ operationCoverage: {
32
+ total: number;
33
+ exercised: number;
34
+ percent: number;
35
+ operations: string[];
36
+ missing: string[];
37
+ } | null;
38
+ servedOperations: string[];
39
+ surface: {
40
+ total: number;
41
+ served: number;
42
+ gap: number;
43
+ } | null;
44
+ codeCoverage: null;
45
+ stateTransitionCoverage: null;
46
+ };
47
+ browser: Record<string, unknown>;
48
+ conformance: import("./conformance.js").ConformanceResult[] | null;
49
+ }>;
@@ -0,0 +1,124 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ // Published assessment API. The standard owns journeys and checks; catalog controllers own admission authority.
10
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
11
+ import { join } from 'node:path';
12
+ import { createHash } from 'node:crypto';
13
+ import { observeDerivedDispatch } from '@volter/world-core/runtime';
14
+ import { p3Gate } from "./gate.js";
15
+ import { conformance } from "./conformance.js";
16
+ import { inMemoryWorld, walk, withPinnedWorldDraws, usePacks } from "./walk/behavior-journey.js";
17
+ import { compilePackFacts } from "./pack-facts.js";
18
+ import { expandFills } from "./walk/journey-kit.js";
19
+ const canonical = (value) => value && typeof value === 'object' ? Array.isArray(value) ? value.map(canonical) : Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, item]) => [key, canonical(item)])) : value;
20
+ const json = (value) => JSON.stringify(canonical(value));
21
+ const hash = (value) => createHash('sha256').update(json(value)).digest('hex');
22
+ const read = (file) => JSON.parse(readFileSync(file, 'utf8'));
23
+ /** Surface coverage counts actual kernel dispatch, and retains every declared gap in the denominator. */
24
+ export async function assessPack(packDir, options = {}) {
25
+ if (!process.env.VOLTER_WORLD)
26
+ throw new Error('Assessment must run inside a World');
27
+ const facts = read(join(packDir, 'generated/pack-facts.json'));
28
+ const vendor = Object.keys(facts.packs ?? {})[0];
29
+ if (!vendor || Object.keys(facts.packs).length !== 1)
30
+ throw new Error('Assessment needs one published vendor identity');
31
+ const manifest = read(join(packDir, 'package.json'));
32
+ const compiled = await compilePackFacts([{ vendor, dir: packDir }]);
33
+ if (json(compiled.packs) !== json(facts.packs) || compiled.undeclared.length)
34
+ throw new Error('Published facts differ from the pack descriptor');
35
+ const lanes = readdirSync(packDir).filter((name) => existsSync(join(packDir, name, 'src/manifest.ts')) && !existsSync(join(packDir, name, 'package.json')));
36
+ const units = [packDir, ...lanes.map((name) => join(packDir, name))];
37
+ if (packDir.split(/[\\/]/).at(-1) !== vendor)
38
+ throw new Error('Place the artifact in a directory named for its vendor before assessment');
39
+ usePacks(join(packDir, '..'));
40
+ const gates = await p3Gate(units);
41
+ const life = expandFills(read(join(packDir, 'journeys/customer-life.json')));
42
+ if (!Array.isArray(life.steps) || !life.steps.length)
43
+ throw new Error('Assessment needs a nonempty customer journey');
44
+ const surfaceRows = [];
45
+ for (const unit of units) {
46
+ const file = join(unit, 'src/generated/surface.gen.json');
47
+ if (!existsSync(file))
48
+ continue;
49
+ const surface = read(file);
50
+ if (!Array.isArray(surface.operations) || !surface.operations.length)
51
+ continue;
52
+ surfaceRows.push({ unit: unit === packDir ? vendor : `${vendor}/${unit.slice(packDir.length + 1)}`, signature: hash(surface.operations), ids: surface.operations.map((operation) => operation.id) });
53
+ }
54
+ const declaredHttp = [...new Set(surfaceRows.flatMap((row) => row.ids.map((id) => `${row.unit}:${id}`)))].sort();
55
+ const mod = await import(__rewriteRelativeImportExtension(join(packDir, 'src/index.ts')));
56
+ const factory = Object.entries(mod).find(([name, value]) => /^create\w+Fetch$/.test(name) && !/TwinFetch$/.test(name) && typeof value === 'function')?.[1];
57
+ const surfaceWorld = inMemoryWorld('catalog-surface');
58
+ let owners = null;
59
+ try {
60
+ const wire = factory?.({ root: surfaceWorld.root() });
61
+ if (wire?.ownersByUnit)
62
+ owners = Object.fromEntries(Object.entries(wire.ownersByUnit()).flatMap(([unit, operations]) => Object.entries(operations).map(([id, owner]) => [`${vendor}${unit ? `/${unit}` : ''}:${id}`, owner])));
63
+ else if (wire?.owners)
64
+ owners = Object.fromEntries(Object.entries(wire.owners()).map(([id, owner]) => [`${vendor}:${id}`, owner]));
65
+ }
66
+ finally {
67
+ surfaceWorld.restore();
68
+ }
69
+ const declared = owners ? Object.keys(owners).sort() : [];
70
+ const servedOperations = owners ? declared.filter((id) => owners[id] !== 'gap') : [];
71
+ const instrumented = declared.length > 0 && json(declared) === json(declaredHttp);
72
+ const coverageOf = (result) => !instrumented || result.ambiguous ? null : { total: declared.length, exercised: result.exercised.length, percent: 100 * result.exercised.length / declared.length, operations: result.exercised, missing: declared.filter((id) => !result.exercised.includes(id)) };
73
+ async function replay(served) {
74
+ const world = inMemoryWorld('catalog-replay');
75
+ const failures = [], trace = [];
76
+ const exercised = new Set();
77
+ const signatures = new WeakMap();
78
+ let ambiguous = false;
79
+ const stop = observeDerivedDispatch(({ surface, operation }) => {
80
+ let signature = signatures.get(surface.operations);
81
+ if (!signature) {
82
+ signature = hash(surface.operations);
83
+ signatures.set(surface.operations, signature);
84
+ }
85
+ const candidates = surfaceRows.filter((row) => row.signature === signature);
86
+ if (!candidates.length)
87
+ return; // Companion dispatch is outside this pack's denominator.
88
+ if (candidates.length !== 1) {
89
+ ambiguous = true;
90
+ return;
91
+ }
92
+ const id = `${candidates[0].unit}:${operation.id}`;
93
+ exercised.add(id);
94
+ });
95
+ try {
96
+ await withPinnedWorldDraws(() => walk(structuredClone(life), world.root(), failures, { beats: true, ...(served ? { served } : {}), hooks: { after: (step, path, answer) => trace.push({ name: step.name ?? '', path, status: answer.status, body: answer.body }) } }));
97
+ return { failures, trace, exercised: [...exercised].sort(), ambiguous };
98
+ }
99
+ finally {
100
+ stop();
101
+ world.restore();
102
+ }
103
+ }
104
+ const first = await replay(), second = await replay();
105
+ const replayEqual = first.trace.length > 0 && json(first.trace) === json(second.trace);
106
+ const coverage = coverageOf(first);
107
+ const quick = { scope: 'packaged-customer-journey; in-process', steps: life.steps.length, answered: first.trace.length, failures: [...first.failures, ...second.failures], replay: { equal: replayEqual, runs: 2, firstSha256: hash(first.trace), secondSha256: hash(second.trace) }, operationCoverage: coverage, servedOperations, surface: owners ? { total: declared.length, served: servedOperations.length, gap: declared.length - servedOperations.length } : null, codeCoverage: null, stateTransitionCoverage: null };
108
+ let browser = { measured: false, reason: options.browser ? 'Journey has a wire Chromium fetch cannot exercise' : 'Browser target not requested' };
109
+ const httpOnly = life.steps.every((step) => 'method' in step || 'wait' in step);
110
+ if (options.browser && httpOnly) {
111
+ const { chromiumServed } = await import("./browser-assessment.js");
112
+ const transport = await chromiumServed(packDir, life.host ?? 'twin.local');
113
+ try {
114
+ const a = await replay(transport.served), b = await replay(transport.served);
115
+ browser = { measured: true, target: 'Chromium fetch, cookie jar and HTTP response behavior; no DOM interaction coverage', version: transport.version, answered: a.trace.length, failures: [...a.failures, ...b.failures], replay: { equal: a.trace.length > 0 && json(a.trace) === json(b.trace), firstSha256: hash(a.trace), secondSha256: hash(b.trace), runs: 2 }, operationCoverage: coverageOf(a), domCoverage: null, clock: 'World and page JavaScript clocks frozen; native cookie expiration uses Chromium wall time' };
116
+ }
117
+ finally {
118
+ await transport.stop();
119
+ }
120
+ }
121
+ const conform = options.conformance === false ? null : await conformance(packDir);
122
+ const ready = gates.length > 0 && gates.every((gate) => !gate.failures.length) && !quick.failures.length && replayEqual && conform !== null && conform.length > 0 && conform.every((result) => !result.failures.length) && (!options.browser || !httpOnly || browser.measured === true && browser.failures.length === 0 && browser.replay.equal);
123
+ return { schemaVersion: 1, vendor, package: manifest.name, version: manifest.version, ready, gates: gates.map((gate) => ({ ...gate, unit: gate.unit === packDir ? vendor : `${vendor}/${gate.unit.slice(packDir.length + 1)}` })), quick, browser, conformance: conform };
124
+ }
@@ -0,0 +1,6 @@
1
+ import type { ServedTwin } from './walk/behavior-journey.js';
2
+ export declare function chromiumServed(packDir: string, host: string): Promise<{
3
+ served: ServedTwin;
4
+ version: string;
5
+ stop: () => Promise<void>;
6
+ }>;
@@ -0,0 +1,69 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ // Browser transport for the existing journey engine. A container supplies network isolation in catalog execution.
10
+ import { join } from 'node:path';
11
+ export async function chromiumServed(packDir, host) {
12
+ const { chromium } = await import('playwright');
13
+ const browser = await chromium.launch({ args: ['--no-sandbox'] });
14
+ const mod = await import(__rewriteRelativeImportExtension(join(packDir, 'src/index.ts')));
15
+ const factory = Object.entries(mod).find(([name, value]) => /^create\w+Fetch$/.test(name) && !/TwinFetch$/.test(name) && typeof value === 'function')?.[1];
16
+ if (!factory) {
17
+ await browser.close();
18
+ throw new Error('Browser assessment needs the pack HTTP fetch factory');
19
+ }
20
+ const served = async (root, options) => {
21
+ const fetchPack = factory({ root, ...options });
22
+ const context = await browser.newContext({ serviceWorkers: 'block', locale: 'en-US', timezoneId: 'UTC' });
23
+ const page = await context.newPage();
24
+ const harness = `https://${host}/__catalog_assessment__`;
25
+ await context.route('**/*', async (route) => {
26
+ const request = route.request();
27
+ if (request.url() === harness) {
28
+ await route.fulfill({ status: 200, contentType: 'text/html', body: '<!doctype html><title>Catalog assessment</title>' });
29
+ return;
30
+ }
31
+ if (!['xhr', 'fetch'].includes(request.resourceType())) {
32
+ await route.abort('blockedbyclient');
33
+ return;
34
+ }
35
+ try {
36
+ const response = await fetchPack(new Request(request.url(), { method: request.method(), headers: request.headers(), ...(request.postDataBuffer() ? { body: new Uint8Array(request.postDataBuffer()).buffer } : {}) }));
37
+ const headers = Object.fromEntries(response.headers);
38
+ const cookies = response.headers.getSetCookie();
39
+ if (cookies.length)
40
+ headers['set-cookie'] = cookies.join('\n');
41
+ await route.fulfill({ status: response.status, headers, body: Buffer.from(await response.arrayBuffer()) });
42
+ }
43
+ catch {
44
+ await route.abort('failed');
45
+ }
46
+ });
47
+ await page.goto(harness);
48
+ await page.clock.setFixedTime(new Date('2026-01-01T00:00:00.000Z'));
49
+ return {
50
+ fetch: async (request) => {
51
+ const body = request.body ? Buffer.from(await request.arrayBuffer()).toString('base64') : null;
52
+ const result = await page.evaluate(async ({ url, method, headers, body }) => {
53
+ const bytes = body === null ? undefined : Uint8Array.from(atob(body), (char) => char.charCodeAt(0));
54
+ const response = await fetch(url, { method, headers, body: bytes, redirect: 'manual', credentials: 'include' });
55
+ const data = new Uint8Array(await response.arrayBuffer());
56
+ let text = '';
57
+ for (let i = 0; i < data.length; i += 32768)
58
+ text += String.fromCharCode(...data.subarray(i, i + 32768));
59
+ return { status: response.status, headers: [...response.headers], body: btoa(text) };
60
+ }, { url: request.url, method: request.method, headers: Object.fromEntries(request.headers), body });
61
+ if (!result.status)
62
+ throw new Error('Chromium returned an opaque response; this journey needs browser-specific navigation assertions');
63
+ return new Response([101, 204, 205, 304].includes(result.status) || request.method === 'HEAD' ? null : Buffer.from(result.body, 'base64'), { status: result.status, headers: result.headers });
64
+ },
65
+ stop: () => { void context.close(); },
66
+ };
67
+ };
68
+ return { served, version: browser.version(), stop: () => browser.close() };
69
+ }
package/dist/src/cli.js CHANGED
@@ -1,4 +1,12 @@
1
1
  #!/usr/bin/env bun
2
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
3
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
4
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
5
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
6
+ });
7
+ }
8
+ return path;
9
+ };
2
10
  // twin-standard — the Protocol 3 standard's commands, the same wherever they run (a pack repository's hook and workflow,
3
11
  // a release, the catalog's check of a submission, an author's machine):
4
12
  //
@@ -22,7 +30,7 @@ import { withCheckoutFiles } from "./protocol-3.js";
22
30
  import { gatePublished } from "./published.js";
23
31
  const [command, ...args] = process.argv.slice(2);
24
32
  const usage = () => {
25
- console.error('usage: twin-standard gate <repo> [units…] | gate-published <name>@<version>… [--registry <url>] | grade <unit>… [--static] [--form] | derive <unit> [--out <dir>] | read-page <url> [--raw] | check-sources <unit> [--recheck] | conform <pack dir> | <name>@<version> [--registry <url>] | --version');
33
+ console.error('usage: twin-standard gate <repo> [units…] | gate-published <name>@<version>… [--registry <url>] | grade <unit>… [--static] [--form] | derive <unit> [--out <dir>] | read-page <url> [--raw] | check-sources <unit> [--recheck] | conform <pack dir> | <name>@<version> [--registry <url>] | create <dir> --init <vendor> --package <@scope/name> | create <unit> --index | facts <pack dir> [--out <file>] | assess <pack dir> [--browser] [--out <file>] | --version');
26
34
  process.exit(2);
27
35
  };
28
36
  if (command === '--version') {
@@ -95,6 +103,46 @@ else if (command === 'grade') {
95
103
  }
96
104
  });
97
105
  }
106
+ else if (command === 'create') {
107
+ if (args.includes('--init') && !args.includes('--package'))
108
+ throw new Error('Name your scoped package with --package');
109
+ await (await import("./create-pack.js")).createPack(args);
110
+ }
111
+ else if (command === 'assess') {
112
+ if (!args[0])
113
+ usage();
114
+ const { assessPack } = await import("./assessment.js");
115
+ const report = await assessPack(resolve(args[0]), { browser: args.includes('--browser') });
116
+ const at = args.indexOf('--out');
117
+ if (at >= 0) {
118
+ if (!args[at + 1])
119
+ usage();
120
+ const { writeFileSync } = await import('node:fs');
121
+ writeFileSync(resolve(args[at + 1]), `${JSON.stringify(report, null, 2)}\n`);
122
+ }
123
+ else
124
+ console.log(JSON.stringify(report, null, 2));
125
+ process.exit(report.ready ? 0 : 1);
126
+ }
127
+ else if (command === 'facts') {
128
+ if (!args[0])
129
+ usage();
130
+ const { compilePackFacts, renderPackFacts } = await import("./pack-facts.js");
131
+ const { mkdirSync, writeFileSync } = await import('node:fs');
132
+ const { join, dirname } = await import('node:path');
133
+ const dir = resolve(args[0]);
134
+ const vendor = String((await import(__rewriteRelativeImportExtension(join(dir, 'src/index.ts')))).pack?.vendor ?? '');
135
+ const at = args.indexOf('--out');
136
+ if (at >= 0 && !args[at + 1])
137
+ usage();
138
+ const out = at >= 0 ? resolve(args[at + 1]) : join(dir, 'generated/pack-facts.json');
139
+ const facts = await compilePackFacts([{ vendor, dir }]);
140
+ if (facts.undeclared.length)
141
+ throw new Error('Pack descriptor is missing');
142
+ mkdirSync(dirname(out), { recursive: true });
143
+ writeFileSync(out, renderPackFacts(facts));
144
+ console.log(out);
145
+ }
98
146
  else if (command === 'derive') {
99
147
  if (!args[0])
100
148
  usage();
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bun
2
+ /** src/semantics/index.ts: the handler map by operationId, keeping the name the unit's fetch imports it by. Each
3
+ * operation of the generated surface whose handler (named as `handlerName` names it) a family's file exports is an
4
+ * entry: an id no JavaScript name can hold (`storage.object.get`, `pulls/create`) is keyed as it is. */
5
+ export declare function handlerIndex(dir: string): string;
6
+ /** What a unit serves, checked against its decision table and its demand (the P3 procedure: demand, then the decision
7
+ * table, then the code). `journeys/decisions.json` (the vendor's, beside its lanes) names, for each operation the unit
8
+ * serves, the demand it answers and the mechanism that serves it (`handler` or `core`); an operation it does not serve
9
+ * is `unmodeled` in the manifest. The unit's owners are the vendor's dispatch's for that unit. A problem stops the index:
10
+ * six packs once shipped answering 404 to everything, and scope once grew past demand, both unseen by the tools. */
11
+ export declare function decisionProblems(dir: string): Promise<string[]>;
12
+ /** A unit's fetch.ts, a fixed file: `createPackFetch` over its parts as they stand (the manifest, the surface, the handler
13
+ * map, and its doors, clock and screens where it has them). `--init` writes it, and `--index` again when a door file,
14
+ * the clock or a screen is added. `name` is the fetch's export (`createClerkFetch`, a lane's `createFapiLaneFetch`). */
15
+ /** A unit's fetch export: a pack's `create<Vendor>Fetch`, a lane's (a unit with no package.json of its own) `create<Lane>LaneFetch`. */
16
+ export declare const fetchName: (dir: string) => string;
17
+ export declare function packFetchFile(dir: string, name: string): string;
18
+ /** The author's brief: the operations left to write, by family, each with the spec's words. */
19
+ export declare function brief(unit: string): Promise<string>;
20
+ /** A pack's `src/index.ts` (a fixed file): the descriptor registered with what the kernel derives from the pack's
21
+ * generated surface (the real-system adapters), or, for a vendor whose every API is a lane, each lane's manifest and
22
+ * surface. A lane's own index is not a pack's and is not written here. */
23
+ export declare function packIndexFile(dir: string, vendor: string): string;
24
+ /** A pack's `src/server.ts` (a fixed file), the kernel's serve seam around its fetch, naming only what its unit has so
25
+ * it typechecks and a bundler follows every import: the plain seam (serveHttp, which takes the sockets a fetch carries
26
+ * itself: "Other wires"), or, for a unit whose spec is a proto, the gRPC seam over the schema derive-pack generated
27
+ * (src/generated/proto.gen.json, imported by its literal path). `--init` writes the plain one, `--index` the gRPC one once
28
+ * the unit's proto is derived. */
29
+ export declare function serverFile(vendor: string, grpc: boolean): string;
30
+ /** A pack's tsconfig.json, a fixed file: what the grade's typecheck (soundness) compiles, the pack and its lanes. */
31
+ export declare const TSCONFIG: string;
32
+ /** The fixed files of a new pack, by path, for a vendor: what nobody should write by hand. */
33
+ export declare function initFiles(vendor: string): Record<string, string>;
34
+ /** The fixed files of a pack of lanes (Cloudflare's API and R2, Sigstore's Fulcio and Rekor): each lane a derived
35
+ * surface of its own under `<lane>/src`, keeping the vendor's one store and sharing its `src/semantics/shared.ts`, and the
36
+ * pack's server routing each lane's host to it. */
37
+ export declare function laneInitFiles(vendor: string, lanes: string[]): Record<string, string>;
38
+ export declare function createPack(args: string[]): Promise<void>;