/** * Directory/file names dropped no matter what any `.gitignore` says. * * This is deliberately the SAME list the Dreamer checkpoint uses * (`dreamer-worker:src/runtime/CloudflareSandboxRuntime.ts` → `excludes`), so a * world whose source arrives from the CLI and a world whose source arrives from * a sandbox backup produce the same workspace shape. Edit mode restores both * through one code path; if the two origins disagreed about what a workspace * contains, that path would need to know where the source came from. * * Not overridable by a `.gitignore` negation. A creator who writes * `!node_modules` has not thought about a 400 MB upload, and "hard" that a * config file can switch off is not hard. */ export declare const SOURCE_HARD_EXCLUDES: readonly string[]; /** * Client-side size cap, mirroring the server's `SOURCE_MAX_BYTES` * (`helix-backend-api:src/instant-worlds/constants/world-source.ts`). Duplicated * rather than imported because it lives in a different repo behind an authed * endpoint; the point of holding it here is to refuse an over-cap archive * BEFORE any network call, so the creator gets one readable sentence instead of * a 400 after a long upload. */ export declare const SOURCE_MAX_BYTES: number; /** The IANA registration. The server also accepts `application/x-gzip`; we only ever send this one. */ export declare const SOURCE_CONTENT_TYPE = "application/gzip"; /** What the archive is called in creator-facing messages. */ export declare const SOURCE_ARCHIVE_FILENAME = "helix-source.tar.gz"; export type IgnoreRule = { /** Directory the rule was declared in, relative to the source root ('' for the root file). */ readonly base: string; /** A `!` rule: a later match re-includes. */ readonly negated: boolean; /** A trailing-slash rule: matches directories only. */ readonly dirOnly: boolean; /** True when the pattern contains a slash, so it is anchored to `base` rather than matching a basename at any depth. */ readonly anchored: boolean; readonly source: string; readonly re: RegExp; }; /** * Parse one `.gitignore` into rules. PURE — takes the text, not a path — so * every pattern form is testable without a filesystem. * * @param base directory the file was found in, relative to the source root. */ export declare function parseGitignore(text: string, base?: string): IgnoreRule[]; /** * Should this entry be left out of the archive? * * PURE, and the whole selection policy: the walker below decides nothing on its * own. Rules are applied in order and the LAST match wins, which is what makes * `!keep-me` work. Hard excludes are checked first and are not negotiable. * * @param relPath slash-separated path relative to the source root. */ export declare function isSourceExcluded(relPath: string, isDirectory: boolean, rules: readonly IgnoreRule[]): boolean; export type SourceEntry = { /** Slash-separated path inside the archive. */ readonly path: string; readonly absolutePath: string; readonly size: number; /** True when the file carries the owner-execute bit, so scripts stay runnable after extraction. */ readonly executable: boolean; }; /** Every file that belongs in the source archive, sorted, `.gitignore` and hard excludes applied. */ export declare function collectSourceFiles(root: string): SourceEntry[]; /** Build an uncompressed tar from in-memory entries. Pure. */ export declare function tarBytes(entries: ReadonlyArray<{ path: string; content: Buffer; executable?: boolean; }>): Buffer; export type SourceArchive = { readonly bytes: Buffer; readonly files: readonly string[]; readonly uncompressedBytes: number; }; /** * Build the archive for `root`, or throw a sentence a creator can act on. * * `maxBytes` is a parameter rather than a constant read so a test can pin BOTH * sides of the bound with a small fixture: a cap-sized archive must be accepted * and a cap-plus-one archive must be refused. A test that only checks the * refusal passes for every smaller cap too, which is not a bound. */ export declare function createSourceArchive(root: string, options?: { maxBytes?: number; }): SourceArchive; /** Creator-facing size, e.g. `2.1 MB`. SI units, one decimal; sub-megabyte reads in KB. */ export declare function formatArchiveSize(bytes: number): string;