export declare const CANDIDATE_MANIFEST_FILENAME = "world-build-manifest.json"; export declare const CANDIDATE_RECEIPT_FILENAME = "world-build-manifest.sha256"; export declare const CANDIDATE_COOK_PLAN_FILENAME = "cook-plan.json"; export declare const CANDIDATE_SCOPE_REPORT_FILENAME = "cook-scope-report.json"; export declare const CANDIDATE_MANIFEST_SCHEMA = "helix.world-build/v1"; export declare const CANDIDATE_SDK_CONTRACT = "helix.unreal.sdk/v1"; export declare const CANDIDATE_SCOPE_REPORT_SCHEMA = "helix.cook-scope-report/v1"; /** The exact string the backend signs into every artifact PUT ticket. */ export declare const PRIVATE_IMMUTABLE = "private, max-age=31536000, immutable"; /** Cook-output role → backend Shared-Runtime artifact role. */ export declare const CANDIDATE_ROLE_TO_BACKEND: { readonly clientContent: "windows_client_content"; readonly serverContent: "linux_server_content"; readonly clientLua: "lua_client"; readonly sharedLua: "lua_shared"; readonly serverLua: "lua_server"; readonly clientWebUI: "webui"; readonly sharedWebUI: "webui"; }; /** Cook-output role → the path prefix its files take inside the Build. */ export declare const CANDIDATE_ROLE_PATH_PREFIX: { readonly clientContent: "client"; readonly serverContent: "server"; readonly clientLua: "lua/client"; readonly sharedLua: "lua/shared"; readonly serverLua: "lua/server"; readonly clientWebUI: "webui/client"; readonly sharedWebUI: "webui/shared"; }; /** Cook-output role → the build target it must declare. */ export declare const CANDIDATE_ROLE_TARGET: { readonly clientContent: "windowsClient"; readonly serverContent: "linuxServer"; readonly clientLua: "windowsClient"; readonly sharedLua: "portable"; readonly serverLua: "linuxServer"; readonly clientWebUI: "windowsClient"; readonly sharedWebUI: "portable"; }; /** Unreal hosting profile → the backend's network mode. */ export declare const HOST_PROFILE_TO_NETWORK_MODE: { readonly offline: "single_player"; readonly listen: "listen"; readonly managedOnDemand: "managed"; readonly managedPersistent: "managed"; }; export type CandidateRole = keyof typeof CANDIDATE_ROLE_TO_BACKEND; export type BackendArtifactRole = (typeof CANDIDATE_ROLE_TO_BACKEND)[CandidateRole]; export type SharedRuntimeNetworkMode = (typeof HOST_PROFILE_TO_NETWORK_MODE)[keyof typeof HOST_PROFILE_TO_NETWORK_MODE]; export declare const MAX_ARTIFACTS = 96; export declare const MAX_ARTIFACT_BYTES: number; export declare const MAX_TOTAL_BYTES: number; export type CandidateFileReceipt = { path: string; sha256: string; sizeBytes: number; mediaType: string; }; export type CandidateArtifactGroup = { role: CandidateRole; target: string; mountPoint: string; digest: string; sizeBytes: number; files: CandidateFileReceipt[]; }; export type CandidateManifest = { schemaVersion: string; runtime: { unrealEngineVersion: string; helixRuntimeVersion: string; helixSdkVersion: string; helixSdkContract: string; }; entry: { map: string; gameMode?: string; }; profiles: { host: string; network?: string; authority?: string; }; capabilities: { required: string[]; optional: string[]; }; provenance: { cookPlanSha256: string; }; artifacts: CandidateArtifactGroup[]; }; /** * The cook's own account of what it actually pulled in. * * `-CookDir` SEEDS the cook; it does not BOUND the reference walk, so a `/Game` * asset hard-referenced from a map inside the cook root is cooked into the DLC. * The commandlet fails closed on a dirty report, but this is the check that * matters most: it sits at the boundary where bytes actually leave the machine. */ export type CookScopeReport = { schemaVersion: string; clean: boolean; totalPackages: number; declaredRoots: string[]; cookedPackages: string[]; outOfScopePackages: string[]; }; export type VerifiedCandidate = { directory: string; manifest: CandidateManifest; /** sha256 of world-build-manifest.json, as recorded in its .sha256 receipt. */ manifestSha256: string; cookPlan: { digest: string; packages: string[]; }; cookScope: CookScopeReport; roles: CandidateRole[]; totalBytes: number; }; /** A single artifact intent plus the local file that must be PUT for it. */ export type PlannedUpload = { role: BackendArtifactRole; path: string; sizeBytes: number; sha256: string; mediaType: string; mountPath: string; /** Candidate-relative source, e.g. `artifacts/clientContent/Content/Paks/x.utoc`. */ source: string; }; export type SharedRuntimeCreateRequest = { idempotencyKey: string; manifest: { version: 1; runtimeAdapter: 'unreal'; networkMode: SharedRuntimeNetworkMode; runtime: { engineVersion: string; runtimeVersion: string; sdkVersion: string; }; activities: Array<{ id: string; map: string; gameMode?: string; maxPlayers: number; }>; capabilities: string[]; artifacts: Array>; }; }; export type SharedRuntimePublishPlan = { worldId: string; candidateManifestSha256: string; networkMode: SharedRuntimeNetworkMode; create: SharedRuntimeCreateRequest; uploads: PlannedUpload[]; totalBytes: number; }; /** * Every candidate/plan rejection. A distinct class so the command layer can * print the creator-facing list without swallowing genuine bugs, and so a * caller can tell "your build is not publishable" from "the network failed". */ export declare class UnrealCandidateError extends Error { readonly problems: string[]; constructor(message: string, problems?: string[]); render(): string; } export declare function sha256File(path: string): Promise; /** * The cook's own per-group digest: a receipt over every file's path, digest, * size, and media type. Recomputing it is what makes a hand-edited manifest — * one whose files were swapped after the cook signed off — fail closed. */ export declare function candidateArtifactDigest(files: CandidateFileReceipt[]): string; /** * Fail-closed audit of the cook scope report. * * The report is a CLAIM, exactly like the manifest, so the out-of-scope set is * RECOMPUTED from `cookedPackages` against `declaredRoots` and the two must * agree. A report that disagrees with itself is refused rather than believed — * otherwise a build could declare `clean: true` beside offenders it also lists. * * Every uncertain state refuses. An absent report is "cannot tell", and * cannot-tell must not publish: treating absent as clean is precisely the * silent-no-op failure this gate exists to stop. */ export declare function auditCookScope(report: CookScopeReport, problems: string[]): void; export declare function verifyUnrealCandidate(input: string, options?: { engineVersion?: string; }): Promise; export type PlanOptions = { worldId: string; idempotencyKey: string; activityId?: string; maxPlayers: number; }; /** * Turns a verified candidate into the exact backend create request plus the * upload list. Every bound the backend enforces is re-checked here so a build * that cannot possibly be accepted is refused before the first byte moves. */ export declare function planSharedRuntimePublish(candidate: VerifiedCandidate, options: PlanOptions): SharedRuntimePublishPlan; /** * The default idempotency key. Derived from the candidate's own manifest * digest, so re-running a publish after a network failure REPLAYS the same * Build instead of minting a second one, while a genuinely re-cooked world * (different bytes → different digest) gets its own. */ export declare function defaultIdempotencyKey(candidate: VerifiedCandidate): string;