treelay 0.1.0 → 0.2.0
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 +27 -4
- package/SPEC.md +40 -6
- package/dist/{chunk-QKQUPZVD.js → chunk-CP7GIVGA.js} +356 -16
- package/dist/chunk-CP7GIVGA.js.map +1 -0
- package/dist/cli.js +122 -41
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +174 -3
- package/dist/index.js +17 -1
- package/package.json +4 -2
- package/dist/chunk-QKQUPZVD.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/c3.ts","../src/manifest.ts","../src/render.ts","../src/variables.ts","../src/hash.ts","../src/refs.ts","../src/fetch/cache.ts","../src/fetch/git.ts","../src/fetch/npm.ts","../src/fetch/index.ts","../src/lockfile.ts","../src/resolve.ts","../src/merge/patch.ts","../src/sidecar.ts","../src/merge/deepMerge.ts","../src/merge/structured.ts","../src/merge/index.ts","../src/layer-files.ts","../src/state.ts","../src/compile.ts","../src/serde.ts","../src/drift.ts","../src/update.ts","../src/explain.ts","../src/blast-radius.ts","../src/verify.ts","../src/reflux.ts"],"sourcesContent":["/** Error types used across treelay. */\n\n/** A cycle was found in the parents/mixins graph (§3). */\nexport class CycleError extends Error {\n constructor(public readonly path: string[]) {\n super(`Inheritance cycle detected: ${path.join(\" → \")}`);\n this.name = \"CycleError\";\n }\n}\n\n/** C3 could not produce a consistent linearization (§3). */\nexport class InconsistentHierarchyError extends Error {\n constructor(message: string) {\n super(`Inconsistent hierarchy: ${message}`);\n this.name = \"InconsistentHierarchyError\";\n }\n}\n\n/** A patch/merge could not be applied cleanly (§5). */\nexport class MergeConflictError extends Error {\n constructor(\n public readonly file: string,\n message: string,\n ) {\n super(`Merge conflict in ${file}: ${message}`);\n this.name = \"MergeConflictError\";\n }\n}\n\n/** Placeholder for not-yet-built functionality during scaffolding. */\nexport class NotImplementedError extends Error {\n constructor(what: string) {\n super(`Not implemented yet: ${what}`);\n this.name = \"NotImplementedError\";\n }\n}\n","/**\n * C3 linearization (Python's MRO) over the `parents` graph — SPEC §3.\n *\n * This is the principled answer to multiple inheritance: it resolves diamonds\n * (a shared ancestor appears once, before its descendants), respects the local\n * order parents were declared in, and is monotonic. The naive alternative\n * (depth-first + last-wins dedupe) produces surprising orders in diamonds.\n *\n * Output is MRO order: most-derived first (root, then ancestors high → low\n * precedence). Callers that apply layers lowest-precedence-first should reverse\n * the ancestor portion. See `resolve.ts`.\n */\n\nimport { CycleError, InconsistentHierarchyError } from \"./errors.js\";\n\n/**\n * Linearize `root` over a parent graph.\n *\n * @param root the starting node\n * @param parentsOf returns the direct parents of a node, in declaration order\n * @param key stable identity for a node (defaults to String)\n * @returns MRO: `[root, ...ancestors]`, highest precedence first\n */\nexport function c3Linearize<T>(\n root: T,\n parentsOf: (node: T) => T[],\n key: (node: T) => string = (n) => String(n),\n): T[] {\n const lin = (node: T, path: string[]): T[] => {\n const k = key(node);\n if (path.includes(k)) {\n throw new CycleError([...path, k]);\n }\n const parents = parentsOf(node);\n if (parents.length === 0) return [node];\n\n const nextPath = [...path, k];\n const sequences = parents.map((p) => lin(p, nextPath));\n // The list of direct parents preserves the locally-declared order.\n sequences.push([...parents]);\n\n return [node, ...merge(sequences, key)];\n };\n\n return lin(root, []);\n}\n\n/**\n * The C3 merge: repeatedly take the head of some sequence that does not appear\n * in the *tail* of any sequence, append it, and remove it from all heads.\n */\nfunction merge<T>(sequences: T[][], key: (node: T) => string): T[] {\n const lists = sequences.map((s) => [...s]).filter((s) => s.length > 0);\n const result: T[] = [];\n\n while (lists.length > 0) {\n let candidate: T | undefined;\n\n for (const list of lists) {\n const head = list[0]!;\n const headKey = key(head);\n const inSomeTail = lists.some((other) =>\n other.slice(1).some((n) => key(n) === headKey),\n );\n if (!inSomeTail) {\n candidate = head;\n break;\n }\n }\n\n if (candidate === undefined) {\n const remaining = lists.map((l) => l.map(key).join(\", \")).join(\" | \");\n throw new InconsistentHierarchyError(\n `cannot linearize conflicting precedence among: ${remaining}`,\n );\n }\n\n result.push(candidate);\n const candidateKey = key(candidate);\n for (let i = lists.length - 1; i >= 0; i--) {\n const list = lists[i]!;\n if (list.length > 0 && key(list[0]!) === candidateKey) {\n list.shift();\n }\n if (list.length === 0) {\n lists.splice(i, 1);\n }\n }\n }\n\n return result;\n}\n","/** Manifest loading — SPEC §2. */\n\nimport { readFileSync, existsSync, accessSync, constants } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport type { Manifest } from \"./types.js\";\n\nconst MANIFEST_NAMES = [\"treelay.json\", \"treelay.yaml\", \"treelay.yml\"];\n\n/**\n * Load the manifest for a layer directory. Looks for a standalone\n * `treelay.{json,yaml,yml}`, then falls back to a `\"treelay\"` key in\n * `package.json`. Returns an empty manifest if none is found (a plain\n * directory is a valid, parent-less layer).\n */\nexport function loadManifest(dir: string): Manifest {\n for (const name of MANIFEST_NAMES) {\n const file = join(dir, name);\n if (existsSync(file)) {\n const raw = readFileSync(file, \"utf8\");\n return (name.endsWith(\".json\") ? JSON.parse(raw) : parseYaml(raw)) as Manifest;\n }\n }\n\n const pkgPath = join(dir, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as {\n treelay?: Manifest;\n name?: string;\n };\n if (pkg.treelay) {\n // package.json `name` is a fallback; an explicit treelay.name wins.\n return { ...(pkg.name !== undefined ? { name: pkg.name } : {}), ...pkg.treelay };\n }\n }\n\n return {};\n}\n\n/** Whether a directory is writable (false ⇒ promotion targets exclude it, §8). */\nexport function isWritable(dir: string): boolean {\n try {\n accessSync(dir, constants.W_OK);\n // node_modules installs are writable on disk but should be treated as\n // read-only sources; callers layer that policy on top of this check.\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * Template rendering via LiquidJS — SPEC §6.\n *\n * LiquidJS is chosen for safety: layers arrive as third-party npm packages, so\n * the engine must not allow arbitrary code execution or filesystem/network\n * access. We construct the engine with file-system access disabled; a template\n * can only read the resolved variable values.\n */\n\nimport { Liquid } from \"liquidjs\";\nimport type { Values } from \"./types.js\";\n\nexport const DEFAULT_TEMPLATE_SUFFIX = \".tmpl\";\n\n/** A sandboxed Liquid engine — no includes/layouts from disk. */\nexport function createEngine(): Liquid {\n return new Liquid({\n // No `root`/`fs` ⇒ `{% include %}`/`{% render %}` from disk is unavailable.\n strictVariables: true,\n strictFilters: true,\n });\n}\n\nconst engine = createEngine();\n\n/** Render a single template string with the given values. */\nexport async function renderString(\n template: string,\n values: Values,\n): Promise<string> {\n return engine.parseAndRender(template, values);\n}\n\n/**\n * Decide whether a file path should be rendered, and return its output name.\n * Suffix opt-in (default): only `*.tmpl` files render, with the suffix stripped.\n */\nexport function templateTarget(\n path: string,\n suffix: string = DEFAULT_TEMPLATE_SUFFIX,\n): { render: boolean; outPath: string } {\n if (path.endsWith(suffix)) {\n return { render: true, outPath: path.slice(0, -suffix.length) };\n }\n return { render: false, outPath: path };\n}\n","/**\n * Variable declaration merge + value resolution — SPEC §6.\n *\n * Declarations merge across the linearized stack (parents < mixins < self),\n * producing one merged questionnaire for the whole composition. Values are then\n * resolved lowest → highest: declared default → answers file → prompts → CLI/env.\n */\n\nimport { createInterface } from \"node:readline/promises\";\nimport { parse as parseYaml } from \"yaml\";\nimport { createEngine } from \"./render.js\";\nimport type { Layer, ResolvedGraph, VariableDecl, VariableType, Values } from \"./types.js\";\n\n/**\n * Merge variable declarations across layers (lowest → highest precedence).\n * Same-named declarations merge per-key, so a child can override just the\n * `default` while inheriting the parent's `prompt`/`type`.\n */\nexport function mergeVariableDecls(\n layers: Layer[],\n): Record<string, VariableDecl> {\n const merged: Record<string, VariableDecl> = {};\n for (const layer of layers) {\n const vars = layer.manifest.variables ?? {};\n for (const [name, decl] of Object.entries(vars)) {\n merged[name] = { ...merged[name], ...decl };\n }\n }\n return merged;\n}\n\n/** Options controlling how values are sourced. */\nexport interface ResolveValuesOptions {\n /** Pre-supplied answers (e.g. loaded from `.treelay/answers.json`). */\n answers?: Values;\n /** CLI `--set k=v` overrides (highest precedence before computed). */\n set?: Values;\n /** Whether to prompt interactively for missing, prompt-able variables. */\n prompt?: boolean;\n}\n\n/** Sentinel: a render that referenced a not-yet-resolved variable. */\nconst DEFER = Symbol(\"defer\");\n\n/** Coerce a raw value (often a string from `--set` or a render) to its type. */\nfunction coerce(type: VariableType, raw: unknown): unknown {\n if (raw === undefined || raw === null) return raw;\n switch (type) {\n case \"string\":\n case \"path\":\n return String(raw);\n case \"number\": {\n if (typeof raw === \"number\") return raw;\n const n = Number(raw);\n if (Number.isNaN(n)) throw new Error(`expected a number, got \"${raw}\"`);\n return n;\n }\n case \"boolean\":\n if (typeof raw === \"boolean\") return raw;\n return raw === \"true\" || raw === \"1\" || raw === \"yes\";\n case \"json\":\n return typeof raw === \"string\" ? JSON.parse(raw) : raw;\n case \"yaml\":\n return typeof raw === \"string\" ? parseYaml(raw) : raw;\n }\n}\n\n/** A render result is falsy when it's empty or an explicit false-ish literal. */\nfunction isFalsy(rendered: string): boolean {\n const t = rendered.trim();\n return t === \"\" || t === \"false\";\n}\n\n/**\n * Resolve final variable values for a graph (§6 steps 3–4): collect from\n * defaults/answers/overrides, prompt for the rest, then evaluate computed and\n * templated defaults in dependency order via a fixpoint over the declarations.\n */\nexport async function resolveValues(\n graph: ResolvedGraph,\n options: ResolveValuesOptions = {},\n): Promise<Values> {\n const engine = createEngine();\n const decls = graph.variables;\n const values: Values = {};\n\n // Strictly render a template against the values resolved so far; a reference to\n // a not-yet-resolved variable throws under strictVariables → treat as DEFER so\n // the fixpoint retries it on a later pass.\n const tryRender = async (tmpl: string): Promise<string | typeof DEFER> => {\n try {\n return await engine.parseAndRender(tmpl, values);\n } catch {\n return DEFER;\n }\n };\n\n // Render a declaration's default (templated when a string, literal otherwise).\n const evalDefault = async (\n decl: VariableDecl,\n ): Promise<unknown | typeof DEFER> => {\n if (typeof decl.default !== \"string\") return decl.default;\n const r = await tryRender(decl.default);\n if (r === DEFER) return DEFER;\n return coerce(decl.type, r);\n };\n\n // Provided values: answers (low) then --set (high). Coerce declared ones.\n const provided: Values = { ...options.answers, ...options.set };\n for (const [name, raw] of Object.entries(provided)) {\n values[name] = decls[name] ? coerce(decls[name]!.type, raw) : raw;\n }\n\n const resolved = new Set(Object.keys(provided).filter((n) => decls[n]));\n let pending = Object.keys(decls).filter((n) => !resolved.has(n));\n\n // Set up prompting lazily so non-interactive runs never touch stdin.\n let rl: ReturnType<typeof createInterface> | undefined;\n const promptVar = async (\n name: string,\n decl: VariableDecl,\n fallback: unknown,\n ): Promise<unknown> => {\n rl ??= createInterface({ input: process.stdin, output: process.stdout });\n const hint = decl.choices ? ` ${JSON.stringify(decl.choices)}` : \"\";\n const def = fallback !== undefined ? ` [${String(fallback)}]` : \"\";\n // TODO(§6): mask `secret` input; readline echoes it for now.\n const answer = (await rl.question(`${decl.prompt}${hint}${def} `)).trim();\n return answer === \"\" ? fallback : coerce(decl.type, answer);\n };\n\n try {\n let guard = pending.length + 1;\n while (pending.length && guard-- > 0) {\n const next: string[] = [];\n let progressed = false;\n\n for (const name of pending) {\n const decl = decls[name]!;\n\n // `when` falsy ⇒ the variable is skipped entirely (left undefined).\n if (decl.when !== undefined) {\n const w = await tryRender(decl.when);\n if (w === DEFER) { next.push(name); continue; }\n if (isFalsy(w)) { resolved.add(name); progressed = true; continue; }\n }\n\n // Computed: always derived from its (templated) default, never prompted.\n if (decl.computed) {\n if (decl.default === undefined) {\n throw new Error(`computed variable \"${name}\" has no default`);\n }\n const r = await evalDefault(decl);\n if (r === DEFER) { next.push(name); continue; }\n values[name] = r; resolved.add(name); progressed = true; continue;\n }\n\n const fallback =\n decl.default !== undefined ? await evalDefault(decl) : undefined;\n if (fallback === DEFER) { next.push(name); continue; }\n\n if (decl.prompt !== undefined && options.prompt) {\n values[name] = await promptVar(name, decl, fallback);\n } else if (fallback !== undefined) {\n values[name] = fallback;\n } else {\n // No default and either no prompt or prompting disabled: unresolved.\n next.push(name);\n continue;\n }\n resolved.add(name); progressed = true;\n }\n\n pending = next;\n if (!progressed) break;\n }\n } finally {\n rl?.close();\n }\n\n if (pending.length) {\n throw new Error(\n `Cannot resolve variables: ${pending.join(\", \")} ` +\n `(no value/default, or a dependency cycle among defaults)`,\n );\n }\n\n // Validation: enum membership + `validate` expressions (render \"\" when valid).\n for (const [name, decl] of Object.entries(decls)) {\n if (!(name in values)) continue;\n if (decl.choices && !decl.choices.includes(values[name])) {\n throw new Error(\n `Invalid ${name}: ${JSON.stringify(values[name])} not in ` +\n JSON.stringify(decl.choices),\n );\n }\n if (decl.validate) {\n const msg = (await engine.parseAndRender(decl.validate, values)).trim();\n if (msg) throw new Error(`Invalid ${name}: ${msg}`);\n }\n }\n\n return values;\n}\n","/**\n * Content hashing — the single source of truth for the `sha256:…` format used\n * by `.treelay` sidecar `base:` fields (§5) and the destination baseline (§7).\n */\n\nimport { createHash } from \"node:crypto\";\nimport { readdirSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/** Hash content into the canonical `sha256:<hex>` form. */\nexport function hashContent(data: Buffer | string): string {\n return \"sha256:\" + createHash(\"sha256\").update(data).digest(\"hex\");\n}\n\n/** Whether `data` matches a recorded `sha256:…` hash. */\nexport function matchesHash(data: Buffer | string, recorded: string): boolean {\n return hashContent(data) === recorded.trim();\n}\n\n/**\n * Hash a whole directory tree into one `sha256:…` — the lockfile's `integrity`.\n *\n * Deliberately independent of any VCS: it digests the *materialized content*,\n * which is the thing a build actually consumes. A git commit SHA already says\n * which revision was asked for; this says the bytes on disk still are that\n * revision, so a corrupted or hand-edited cache entry is caught rather than\n * silently compiled in.\n *\n * Paths are sorted and mixed into the digest alongside their content, so\n * renaming a file changes the hash even when the bytes are identical.\n */\nexport function hashTree(dir: string): string {\n const digest = createHash(\"sha256\");\n for (const rel of listTreeFiles(dir)) {\n digest.update(rel);\n digest.update(\"\\0\");\n digest.update(createHash(\"sha256\").update(readFileSync(join(dir, rel))).digest());\n digest.update(\"\\n\");\n }\n return \"sha256:\" + digest.digest(\"hex\");\n}\n\n/**\n * Every file under `dir`, relative and sorted, with `.git` and `node_modules`\n * pruned.\n *\n * `.git` is excluded so the integrity of a checkout depends only on its\n * content — otherwise two materializations of the same commit would hash\n * differently because their object stores were packed differently.\n * `node_modules` is excluded because an installed package's dependencies are\n * the package manager's business, not part of the layer's identity, and hashing\n * them would make integrity depend on hoisting decisions.\n */\nconst TREE_HASH_PRUNE = new Set([\".git\", \"node_modules\"]);\n\nfunction listTreeFiles(dir: string, prefix = \"\"): string[] {\n const out: string[] = [];\n for (const e of readdirSync(dir, { withFileTypes: true }).sort((a, b) =>\n a.name < b.name ? -1 : a.name > b.name ? 1 : 0,\n )) {\n if (TREE_HASH_PRUNE.has(e.name)) continue;\n const rel = prefix === \"\" ? e.name : `${prefix}/${e.name}`;\n if (e.isDirectory()) out.push(...listTreeFiles(join(dir, e.name), rel));\n else if (e.isFile()) out.push(rel);\n }\n return out;\n}\n","/**\n * Layer reference syntax — SPEC §2 (\"Referencing layers\") and §3.\n *\n * A ref names where a layer's content comes from. Three origins, distinguished\n * purely by shape so nothing has to be declared twice:\n *\n * ```\n * ../base local path (relative or absolute)\n * file:./base local path, explicit\n * git+https://host/o/r.git#v1.2.0 git at a commit-ish\n * git+ssh://git@host/o/r.git#main git over ssh\n * git+file:///srv/repos/pkgs.git#v1 git with a local remote (offline/tests)\n * github:acme/base#v2 shorthand for git+https://github.com/acme/base.git\n * @acme/base@^2 npm package, resolved through node_modules\n * npm:@acme/base@^2 npm, explicit\n * ```\n *\n * Any non-local form may carry `?path=<subdir>` to use a subdirectory of the\n * fetched tree as the layer root — the monorepo-of-layers case (`?path=core/_layer`).\n *\n * Parsing is pure and total: it never touches the network or the filesystem.\n * {@link canonicalRef} is the single normalized string used as a lockfile key,\n * so two spellings of the same thing cannot occupy two lock entries.\n */\n\nimport { isAbsolute } from \"node:path\";\n\n/** Where a layer's bytes come from. */\nexport type RefKind = \"local\" | \"git\" | \"npm\";\n\n/** A ref that is fetched and pinned — everything except a local path. */\nexport type RemoteRefKind = Exclude<RefKind, \"local\">;\n\ninterface BaseRef {\n /** The ref exactly as written in the manifest. */\n raw: string;\n}\n\n/** A path on this machine; never locked, never cached. */\nexport interface LocalRef extends BaseRef {\n kind: \"local\";\n /** The path portion, with any `file:` scheme stripped. */\n path: string;\n}\n\n/** A git repository at a commit-ish (branch, tag, or full SHA). */\nexport interface GitRef extends BaseRef {\n kind: \"git\";\n /** Clone URL, scheme included, `git+` prefix stripped. */\n url: string;\n /** Branch / tag / SHA as written. Defaults to `HEAD`. */\n committish: string;\n /** Subdirectory of the repo that forms the layer root. */\n subdir?: string;\n}\n\n/** An npm package, resolved through the installed `node_modules` tree. */\nexport interface NpmRef extends BaseRef {\n kind: \"npm\";\n /** Package name, scope included. */\n name: string;\n /** Semver range as written. Defaults to `*`. */\n range: string;\n /** Subdirectory of the package that forms the layer root. */\n subdir?: string;\n}\n\nexport type ParsedRef = LocalRef | GitRef | NpmRef;\n\n/** Refs that are fetched, cached and pinned in `treelay.lock`. */\nexport type RemoteRef = GitRef | NpmRef;\n\n/** Raised when a ref cannot be parsed at all. */\nexport class InvalidRefError extends Error {\n constructor(\n public readonly ref: string,\n reason: string,\n ) {\n super(`Invalid layer reference \"${ref}\": ${reason}`);\n this.name = \"InvalidRefError\";\n }\n}\n\nconst GITHUB_SHORTHAND = /^github:([^/#?]+)\\/([^/#?]+?)(?:\\.git)?(?=[#?]|$)/;\nconst WINDOWS_DRIVE = /^[A-Za-z]:[\\\\/]/;\n\n/** Split a trailing `?path=…` and `#committish` off a ref body. */\nfunction splitSuffixes(rest: string): {\n body: string;\n subdir?: string;\n committish?: string;\n} {\n let body = rest;\n let committish: string | undefined;\n let subdir: string | undefined;\n\n const hash = body.indexOf(\"#\");\n if (hash !== -1) {\n committish = body.slice(hash + 1);\n body = body.slice(0, hash);\n }\n const q = body.indexOf(\"?\");\n if (q !== -1) {\n const params = new URLSearchParams(body.slice(q + 1));\n const p = params.get(\"path\");\n if (p) subdir = normalizeSubdir(p);\n body = body.slice(0, q);\n }\n return {\n body,\n ...(subdir !== undefined ? { subdir } : {}),\n ...(committish !== undefined && committish !== \"\" ? { committish } : {}),\n };\n}\n\n/** Normalize a `?path=` value: posix, no leading/trailing slash, no escapes. */\nfunction normalizeSubdir(p: string): string {\n const clean = p.split(\"\\\\\").join(\"/\").replace(/^\\/+|\\/+$/g, \"\");\n if (clean.split(\"/\").includes(\"..\")) {\n throw new InvalidRefError(p, \"`path=` may not escape the fetched tree with `..`\");\n }\n return clean;\n}\n\n/** Is this ref a local path (the only kind that is never fetched)? */\nexport function isLocalRef(ref: string): boolean {\n return parseRef(ref).kind === \"local\";\n}\n\n/** Parse a layer reference. Pure: no network, no filesystem. */\nexport function parseRef(ref: string): ParsedRef {\n const raw = ref.trim();\n if (raw === \"\") throw new InvalidRefError(ref, \"empty reference\");\n\n if (raw.startsWith(\"file:\")) {\n return { kind: \"local\", raw, path: raw.slice(\"file:\".length) };\n }\n if (raw.startsWith(\".\") || isAbsolute(raw) || WINDOWS_DRIVE.test(raw)) {\n return { kind: \"local\", raw, path: raw };\n }\n\n const gh = GITHUB_SHORTHAND.exec(raw);\n if (gh) {\n const { subdir, committish } = splitSuffixes(raw.slice(gh[0].length));\n return git(raw, `https://github.com/${gh[1]}/${gh[2]}.git`, committish, subdir);\n }\n\n if (raw.startsWith(\"git+\")) {\n const { body, subdir, committish } = splitSuffixes(raw.slice(\"git+\".length));\n if (body === \"\") throw new InvalidRefError(ref, \"git ref has no URL\");\n return git(raw, body, committish, subdir);\n }\n\n // A bare URL is git only when it is unambiguously a repository.\n if (raw.includes(\"://\")) {\n const { body, subdir, committish } = splitSuffixes(raw);\n if (body.endsWith(\".git\")) return git(raw, body, committish, subdir);\n throw new InvalidRefError(\n ref,\n \"URLs must be prefixed with `git+` (or end in `.git`) so the transport is explicit\",\n );\n }\n\n const npmBody = raw.startsWith(\"npm:\") ? raw.slice(\"npm:\".length) : raw;\n const { body, subdir } = splitSuffixes(npmBody);\n return npm(raw, body, subdir);\n}\n\nfunction git(\n raw: string,\n url: string,\n committish: string | undefined,\n subdir: string | undefined,\n): GitRef {\n return {\n kind: \"git\",\n raw,\n url,\n committish: committish ?? \"HEAD\",\n ...(subdir !== undefined ? { subdir } : {}),\n };\n}\n\nfunction npm(raw: string, body: string, subdir: string | undefined): NpmRef {\n // Scoped names carry a leading `@`, so look for the version separator after it.\n const at = body.indexOf(\"@\", body.startsWith(\"@\") ? 1 : 0);\n const name = at === -1 ? body : body.slice(0, at);\n const range = at === -1 ? \"*\" : body.slice(at + 1);\n if (name === \"\") throw new InvalidRefError(raw, \"npm ref has no package name\");\n return {\n kind: \"npm\",\n raw,\n name,\n range: range === \"\" ? \"*\" : range,\n ...(subdir !== undefined ? { subdir } : {}),\n };\n}\n\n/**\n * The normalized spelling of a ref — the lockfile key.\n *\n * Two manifests writing `github:acme/base#v2` and\n * `git+https://github.com/acme/base.git#v2` mean the same layer and must share\n * one lock entry, so the key is derived from the parsed shape rather than the\n * text. Local refs canonicalize to themselves; they are never locked.\n */\nexport function canonicalRef(ref: ParsedRef | string): string {\n const parsed = typeof ref === \"string\" ? parseRef(ref) : ref;\n const query = parsed.kind !== \"local\" && parsed.subdir ? `?path=${parsed.subdir}` : \"\";\n switch (parsed.kind) {\n case \"local\":\n return parsed.raw;\n case \"git\":\n return `git+${parsed.url}${query}#${parsed.committish}`;\n case \"npm\":\n return `npm:${parsed.name}@${parsed.range}${query}`;\n }\n}\n\n/**\n * The immutable spelling of a ref once resolved — what the lock pins to.\n *\n * `git+…#main` resolves to `git+…#<sha>`; `npm:pkg@^2` to `npm:pkg@2.3.1`.\n * Recording this (alongside the requested form) is what lets drift detection\n * say precisely *what moved*.\n */\nexport function pinnedRef(ref: RemoteRef, revision: string): string {\n const query = ref.subdir ? `?path=${ref.subdir}` : \"\";\n return ref.kind === \"git\"\n ? `git+${ref.url}${query}#${revision}`\n : `npm:${ref.name}@${revision}${query}`;\n}\n\n/** A 40-hex git object name — already immutable, so nothing to re-resolve. */\nexport function isCommitSha(committish: string): boolean {\n return /^[0-9a-f]{40}$/i.test(committish);\n}\n","/**\n * Content-addressed cache for fetched layers (SPEC §3).\n *\n * Every fetched tree lands at a path derived from *what it is*, never from who\n * asked for it: `<root>/git/<repo-key>/rev/<commit>/`. Two layers pinning the\n * same commit share one checkout, a held-back pin coexists with a floating one\n * instead of fighting over a working directory, and the cache is safe to delete\n * at any time — worst case the next resolve re-fetches.\n *\n * `TREELAY_CACHE_DIR` overrides the location, which is how tests stay hermetic.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, rmSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\n/** Root of the cache: `$TREELAY_CACHE_DIR`, else `~/.cache/treelay`. */\nexport function cacheRoot(override?: string): string {\n return (\n override ??\n process.env[\"TREELAY_CACHE_DIR\"] ??\n join(homedir(), \".cache\", \"treelay\")\n );\n}\n\n/**\n * A filesystem-safe, collision-resistant key for a remote location.\n *\n * The readable slug is there for humans poking at the cache; the hash suffix is\n * what actually guarantees uniqueness, since sanitizing a URL is lossy.\n */\nexport function locationKey(location: string): string {\n const slug =\n location\n .replace(/^[a-z+]+:\\/\\//i, \"\")\n .replace(/[^A-Za-z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 48) || \"layer\";\n const digest = createHash(\"sha256\").update(location).digest(\"hex\").slice(0, 16);\n return `${slug}-${digest}`;\n}\n\n/** Directory holding everything cached for one git remote. */\nexport function gitRepoDir(location: string, root?: string): string {\n return join(cacheRoot(root), \"git\", locationKey(location));\n}\n\n/** The bare mirror clone for a git remote — the fetch-once, read-many store. */\nexport function gitMirrorDir(location: string, root?: string): string {\n return join(gitRepoDir(location, root), \"repo.git\");\n}\n\n/** Extracted checkout of one exact commit. */\nexport function gitRevisionDir(\n location: string,\n revision: string,\n root?: string,\n): string {\n return join(gitRepoDir(location, root), \"rev\", revision);\n}\n\n/** Create a directory, replacing any partial contents from a failed fetch. */\nexport function freshDir(dir: string): string {\n rmSync(dir, { recursive: true, force: true });\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\n/** Ensure a directory exists without disturbing what is already in it. */\nexport function ensureCacheDir(dir: string): string {\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n return dir;\n}\n","/**\n * Git-backed layers (SPEC §3).\n *\n * Two operations, deliberately separated because they have very different\n * costs and failure modes:\n *\n * - **resolve** — what commit does `#main` mean *right now*? Needs the remote.\n * - **materialize** — give me the tree at commit `abc123`. Needs only the cache\n * once that commit has been fetched, and is what a locked build does.\n *\n * That split is the whole of \"compile honours the lock\": a locked build never\n * asks the first question, so a moved branch cannot change what it produces.\n *\n * Everything shells out to the user's `git`. Reimplementing the wire protocol\n * to save a process spawn would trade a well-tested dependency every developer\n * already has for a novel one that has to learn about proxies, credential\n * helpers, SSH agents and partial clones.\n */\n\nimport { execFileSync } from \"node:child_process\";\nimport { existsSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport { hashTree } from \"../hash.js\";\nimport type { GitRef } from \"../refs.js\";\nimport { isCommitSha } from \"../refs.js\";\nimport {\n ensureCacheDir,\n freshDir,\n gitMirrorDir,\n gitRepoDir,\n gitRevisionDir,\n} from \"./cache.js\";\n\n/** Raised when a git operation fails, carrying git's own message. */\nexport class GitFetchError extends Error {\n constructor(\n public readonly url: string,\n message: string,\n ) {\n super(`git layer ${url}: ${message}`);\n this.name = \"GitFetchError\";\n }\n}\n\n/** Run git, returning trimmed stdout; stderr is folded into the thrown error. */\nfunction git(args: string[], cwd?: string): string {\n try {\n return execFileSync(\"git\", args, {\n encoding: \"utf8\",\n ...(cwd ? { cwd } : {}),\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: {\n ...process.env,\n // Never stop for credentials: a hung prompt inside a build is worse\n // than a clear \"authentication failed\".\n GIT_TERMINAL_PROMPT: \"0\",\n GIT_ADVICE: \"0\",\n },\n }).trim();\n } catch (err) {\n const e = err as { stderr?: Buffer | string; message?: string };\n const detail = (e.stderr?.toString() ?? e.message ?? \"\").trim();\n throw new Error(detail || `git ${args.join(\" \")} failed`);\n }\n}\n\n/** Ensure the bare mirror for a remote exists; returns its path. */\nfunction ensureMirror(url: string, cacheDir?: string): string {\n const mirror = gitMirrorDir(url, cacheDir);\n if (existsSync(join(mirror, \"HEAD\"))) return mirror;\n ensureCacheDir(gitRepoDir(url, cacheDir));\n try {\n git([\"clone\", \"--mirror\", \"--quiet\", url, mirror]);\n } catch (err) {\n // A half-written mirror would poison every later resolve.\n rmSync(mirror, { recursive: true, force: true });\n throw new GitFetchError(url, `clone failed — ${(err as Error).message}`);\n }\n return mirror;\n}\n\n/** Refresh a mirror from its remote (network). */\nfunction updateMirror(url: string, mirror: string): void {\n try {\n git([\"--git-dir\", mirror, \"fetch\", \"--prune\", \"--quiet\", \"origin\", \"+refs/*:refs/*\"]);\n } catch (err) {\n throw new GitFetchError(url, `fetch failed — ${(err as Error).message}`);\n }\n}\n\n/** Does the mirror already contain this object? */\nfunction hasCommit(mirror: string, committish: string): boolean {\n try {\n git([\"--git-dir\", mirror, \"rev-parse\", \"--verify\", \"--quiet\", `${committish}^{commit}`]);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve a commit-ish to an exact commit SHA, fetching if needed.\n *\n * A full SHA is returned untouched only once we know the mirror has it — a\n * pinned build must still fail loudly if the commit has been garbage-collected\n * upstream, rather than materializing nothing.\n */\nexport function resolveGitRevision(ref: GitRef, cacheDir?: string): string {\n const mirror = ensureMirror(ref.url, cacheDir);\n\n // Tags and branches move; re-fetch before trusting a local answer. An\n // immutable SHA only needs a fetch when we don't already have the object.\n if (!isCommitSha(ref.committish) || !hasCommit(mirror, ref.committish)) {\n updateMirror(ref.url, mirror);\n }\n try {\n return git([\"--git-dir\", mirror, \"rev-parse\", `${ref.committish}^{commit}`]);\n } catch {\n throw new GitFetchError(\n ref.url,\n `no such revision \"${ref.committish}\". It may have been deleted, ` +\n `renamed, or never pushed.`,\n );\n }\n}\n\n/**\n * The revision a moving ref points to on the remote *right now*.\n *\n * Returns undefined when the remote cannot be reached — drift detection is an\n * advisory read, and being offline must degrade to \"unknown\" rather than fail a\n * build that is otherwise fully pinned.\n */\nexport function liveGitRevision(ref: GitRef): string | undefined {\n if (isCommitSha(ref.committish)) return ref.committish;\n try {\n // An *annotated* tag has two ids: the tag object, and the commit it points\n // at. `ls-remote` only advertises the peeled form when the `^{}` pattern is\n // asked for by name — and without it, comparing a tag object's id against\n // the locked *commit* id reports drift on every annotated tag, forever.\n const lines = git([\"ls-remote\", ref.url, ref.committish, `${ref.committish}^{}`])\n .split(\"\\n\")\n .filter((l) => l.trim() !== \"\");\n const peeled = lines.find((l) => l.split(/\\s+/)[1]?.endsWith(\"^{}\"));\n return (peeled ?? lines[0])?.split(/\\s+/)[0];\n } catch {\n return undefined;\n }\n}\n\n/**\n * Materialize an exact commit into the cache and return the layer root.\n *\n * The tree is extracted via `git archive`, so the result carries no `.git` at\n * all — a checkout that cannot leak a gitlink into a composed tree, and one\n * whose integrity hash depends only on content (§4's `.git` exclusion covers\n * the same hazard from the other side).\n */\nexport function materializeGit(\n ref: GitRef,\n revision: string,\n cacheDir?: string,\n): { dir: string; integrity: string } {\n const dest = gitRevisionDir(ref.url, revision, cacheDir);\n const root = ref.subdir ? join(dest, ref.subdir) : dest;\n\n if (!existsSync(dest)) {\n const mirror = ensureMirror(ref.url, cacheDir);\n if (!hasCommit(mirror, revision)) updateMirror(ref.url, mirror);\n freshDir(dest);\n const tar = join(dest, \".treelay-archive.tar\");\n try {\n git([\"--git-dir\", mirror, \"archive\", \"--format=tar\", \"-o\", tar, revision]);\n execFileSync(\"tar\", [\"-xf\", tar, \"-C\", dest], { stdio: \"ignore\" });\n } catch (err) {\n rmSync(dest, { recursive: true, force: true });\n throw new GitFetchError(\n ref.url,\n `could not extract ${revision.slice(0, 12)} — ${(err as Error).message}`,\n );\n } finally {\n rmSync(tar, { force: true });\n }\n }\n\n if (!existsSync(root)) {\n throw new GitFetchError(\n ref.url,\n `subdirectory \"${ref.subdir}\" does not exist at ${revision.slice(0, 12)}`,\n );\n }\n return { dir: root, integrity: hashTree(root) };\n}\n","/**\n * npm-backed layers (SPEC §3).\n *\n * An overlay *is* a normal npm package (§2), so treelay resolves npm refs the\n * way any Node program resolves a dependency: through the installed\n * `node_modules` tree, starting at the layer that declared the ref.\n *\n * **treelay deliberately does not install anything.** Package installation is\n * already owned by a tool with a lockfile, an integrity model, a registry\n * configuration and an offline cache; shipping a second, worse copy of that\n * inside a composition engine would mean two lockfiles disagreeing about the\n * same tree. treelay's job is to record *which* version composition consumed,\n * and to fail clearly when the package is not installed at all.\n *\n * The consequence worth naming: an npm layer's exact version is whatever the\n * package manager put on disk. `treelay.lock` pins what was used and\n * {@link liveNpmVersion} reports when the installed tree has since moved, but\n * reproducing an old pin is `npm ci`'s job, not treelay's.\n */\n\nimport { createRequire } from \"node:module\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { satisfies, validRange } from \"semver\";\n\nimport { hashTree } from \"../hash.js\";\nimport type { NpmRef } from \"../refs.js\";\n\n/** Raised when an npm layer cannot be resolved from the installed tree. */\nexport class NpmResolveError extends Error {\n constructor(\n public readonly packageName: string,\n message: string,\n ) {\n super(`npm layer ${packageName}: ${message}`);\n this.name = \"NpmResolveError\";\n }\n}\n\n/**\n * Locate an installed package's root directory, searching up from `fromDir`.\n *\n * Node's own resolver is only the *fallback* here, because it returns the\n * realpath of what it finds. Layer directories are compared as strings all over\n * treelay — nested-destination pruning (§7), promotion targets (§8) — and a\n * resolver that silently canonicalizes symlinks would hand back a path in a\n * different shape from every local layer beside it. Walking `node_modules`\n * ourselves keeps the path in the caller's frame of reference, and as a bonus\n * sidesteps packages whose `exports` map hides `./package.json`.\n */\nfunction packageDir(ref: NpmRef, fromDir: string): string {\n for (let dir = fromDir; ; dir = dirname(dir)) {\n const candidate = join(dir, \"node_modules\", ref.name);\n if (existsSync(join(candidate, \"package.json\"))) return candidate;\n if (dirname(dir) === dir) break;\n }\n\n // Not in any plain node_modules — defer to Node (workspaces, PnP shims).\n try {\n const require = createRequire(join(fromDir, \"package.json\"));\n return dirname(require.resolve(`${ref.name}/package.json`));\n } catch {\n throw new NpmResolveError(\n ref.name,\n `not installed under ${fromDir}. treelay resolves npm layers from ` +\n `node_modules rather than installing them — run your package manager ` +\n `first (e.g. \\`npm install ${ref.name}\\`).`,\n );\n }\n}\n\n/** The version currently installed for an npm ref, or undefined if absent. */\nexport function liveNpmVersion(ref: NpmRef, fromDir: string): string | undefined {\n try {\n const pkg = JSON.parse(\n readFileSync(join(packageDir(ref, fromDir), \"package.json\"), \"utf8\"),\n ) as { version?: string };\n return pkg.version;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resolve and materialize an npm layer.\n *\n * \"Materialize\" is a no-op copy here — the installed package already *is* the\n * tree, and duplicating it into the cache would only create a second thing to\n * keep in sync. The integrity hash is taken over the installed content, so a\n * reinstall that changes the bytes still shows up as drift.\n */\nexport function materializeNpm(\n ref: NpmRef,\n fromDir: string,\n): { dir: string; revision: string; integrity: string } {\n const pkgRoot = packageDir(ref, fromDir);\n const pkg = JSON.parse(readFileSync(join(pkgRoot, \"package.json\"), \"utf8\")) as {\n version?: string;\n };\n const version = pkg.version ?? \"0.0.0\";\n\n if (ref.range !== \"*\" && validRange(ref.range) && !satisfies(version, ref.range)) {\n throw new NpmResolveError(\n ref.name,\n `installed version ${version} does not satisfy \"${ref.range}\". ` +\n `Update the dependency, or relax the ref in treelay.json.`,\n );\n }\n\n const root = ref.subdir ? join(pkgRoot, ref.subdir) : pkgRoot;\n if (!existsSync(root)) {\n throw new NpmResolveError(\n ref.name,\n `subdirectory \"${ref.subdir}\" does not exist in ${pkgRoot}`,\n );\n }\n return { dir: root, revision: version, integrity: hashTree(root) };\n}\n","/**\n * Fetching a remote layer, lock-aware (SPEC §3).\n *\n * One entry point sits between resolution and the per-transport fetchers, and\n * it is where the lockfile earns its keep:\n *\n * - **locked** — the lock already pins this ref → materialize *that* revision.\n * No remote query, so a branch that has since moved cannot change the build.\n * - **unlocked** — resolve the ref live, materialize, and hand back an entry for\n * the caller to record.\n * - **frozen** — an unlocked ref is an error, not a silent lock update. This is\n * the CI posture: builds reproduce or they fail.\n *\n * Everything here is synchronous by design. Layer resolution is called from\n * `resolve()`, which the entire library and CLI treat as a plain function; making\n * it async to accommodate a subprocess would ripple through every caller for no\n * behavioural gain, since a build cannot proceed without its layers anyway.\n */\n\nimport { existsSync } from \"node:fs\";\n\nimport { hashTree } from \"../hash.js\";\nimport type { LockEntry, TreelayLock } from \"../lockfile.js\";\nimport type { RemoteRef } from \"../refs.js\";\nimport { canonicalRef } from \"../refs.js\";\nimport { liveGitRevision, materializeGit, resolveGitRevision } from \"./git.js\";\nimport { liveNpmVersion, materializeNpm } from \"./npm.js\";\n\nexport { GitFetchError, liveGitRevision } from \"./git.js\";\nexport { NpmResolveError, liveNpmVersion } from \"./npm.js\";\nexport { cacheRoot, locationKey } from \"./cache.js\";\n\n/** Raised when a frozen resolve meets a ref the lockfile does not pin. */\nexport class LockMissingError extends Error {\n constructor(public readonly ref: string) {\n super(\n `${ref} is not in treelay.lock, and resolution is frozen. ` +\n `Run \\`treelay lock\\` and commit the result, or drop --frozen-lockfile.`,\n );\n this.name = \"LockMissingError\";\n }\n}\n\n/** Raised when cached content no longer matches the integrity the lock records. */\nexport class IntegrityError extends Error {\n constructor(ref: string, expected: string, actual: string) {\n super(\n `${ref}: cached content does not match treelay.lock.\\n` +\n ` expected ${expected}\\n actual ${actual}\\n` +\n `The cache entry has been modified or corrupted. Delete it (or the whole ` +\n `cache) and re-resolve.`,\n );\n this.name = \"IntegrityError\";\n }\n}\n\nexport interface FetchOptions {\n /** Directory the ref was declared in — the anchor for npm resolution. */\n fromDir: string;\n /** Existing pins; consulted before any remote is contacted. */\n lock: TreelayLock;\n /** Refuse to resolve refs the lock does not already pin (CI). */\n frozen?: boolean;\n /** Re-resolve moving refs to their current revision, advancing the lock. */\n updateRefs?: boolean;\n /** Override the cache root (tests). */\n cacheDir?: string;\n}\n\n/** A materialized remote layer plus the lock entry describing it. */\nexport interface FetchedLayer {\n /** Canonical ref — the lockfile key. */\n ref: string;\n /** Absolute path of the layer root on disk. */\n dir: string;\n revision: string;\n integrity: string;\n entry: LockEntry;\n /** True when the lock gained or changed an entry because of this fetch. */\n changed: boolean;\n}\n\n/** Fetch (or reuse) a remote layer, honouring the lock. */\nexport function fetchLayer(ref: RemoteRef, options: FetchOptions): FetchedLayer {\n const key = canonicalRef(ref);\n const locked = options.updateRefs ? undefined : options.lock.refs[key];\n\n if (!locked && options.frozen) throw new LockMissingError(key);\n\n const { dir, revision, integrity } =\n ref.kind === \"git\"\n ? fetchGit(ref, locked?.resolved, options)\n : materializeNpm(ref, options.fromDir);\n\n // Integrity is only a corruption signal when both sides claim the *same*\n // revision. A different revision is drift — legitimate for npm, where the\n // installed tree is the package manager's to change — and is reported as\n // such rather than mistaken for a tampered cache.\n if (locked && locked.resolved === revision && locked.integrity !== integrity) {\n throw new IntegrityError(key, locked.integrity, integrity);\n }\n\n const entry: LockEntry = {\n kind: ref.kind,\n source: ref.kind === \"git\" ? ref.url : ref.name,\n requested: ref.kind === \"git\" ? ref.committish : ref.range,\n resolved: revision,\n integrity,\n ...(ref.subdir !== undefined ? { path: ref.subdir } : {}),\n };\n\n const changed =\n locked === undefined ||\n locked.resolved !== entry.resolved ||\n locked.integrity !== entry.integrity;\n\n return { ref: key, dir, revision, integrity, entry, changed };\n}\n\n/** Git: reuse a cached checkout when the lock already pins the revision. */\nfunction fetchGit(\n ref: RemoteRef & { kind: \"git\" },\n lockedRevision: string | undefined,\n options: FetchOptions,\n): { dir: string; revision: string; integrity: string } {\n const revision = lockedRevision ?? resolveGitRevision(ref, options.cacheDir);\n const { dir, integrity } = materializeGit(ref, revision, options.cacheDir);\n return { dir, revision, integrity };\n}\n\n/**\n * Re-hash a materialized layer. Used by `treelay lock --check` to notice a\n * cache that has been edited in place without re-fetching anything.\n */\nexport function verifyIntegrity(dir: string, expected: string): boolean {\n return existsSync(dir) && hashTree(dir) === expected;\n}\n\n/**\n * What a ref points at on the remote right now — the drift probe.\n *\n * Undefined means \"could not tell\" (offline, no credentials, package not\n * installed), never \"unchanged\": an advisory check that silently reports\n * in-sync when it could not look would be worse than saying nothing.\n */\nexport function liveRevision(ref: RemoteRef, fromDir: string): string | undefined {\n return ref.kind === \"git\" ? liveGitRevision(ref) : liveNpmVersion(ref, fromDir);\n}\n","/**\n * `treelay.lock` — resolved lineage and pinned revisions (SPEC §3, §9).\n *\n * The lockfile sits beside the **leaf layer's manifest** and is committed to\n * version control. It answers one question: *what exactly was materialized?* A\n * manifest says `#main`; the lock says which commit `main` was when the tree was\n * last resolved, plus an integrity hash of the content that produced.\n *\n * Note the division of labour with `<dest>/.treelay/lock.json` (§7): that file\n * records what a *destination* was built from, and is regenerated on every\n * compile. `treelay.lock` records what the *source composition* pins to, and\n * changes only when a ref is added or deliberately advanced.\n *\n * Serialization is deterministic — sorted keys throughout, fixed field order,\n * two-space indent, trailing newline — so re-running `treelay lock` on an\n * unchanged tree produces a byte-identical file and never shows up in a diff.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { RemoteRefKind } from \"./refs.js\";\n\n/** Filename of the source-side lockfile, beside the leaf manifest. */\nexport const LOCKFILE_NAME = \"treelay.lock\";\n\n/** Bumped when the on-disk shape changes incompatibly. */\nexport const LOCKFILE_VERSION = 1;\n\n/** One pinned layer reference. */\nexport interface LockEntry {\n kind: RemoteRefKind;\n /** Clone URL (git) or package name (npm). */\n source: string;\n /** The mutable thing that was asked for: branch, tag, or semver range. */\n requested: string;\n /** The immutable revision it resolved to: commit SHA, or exact version. */\n resolved: string;\n /** `sha256:…` over the materialized tree — detects a tampered cache. */\n integrity: string;\n /** Subdirectory of the fetched tree used as the layer root, if any. */\n path?: string;\n /**\n * Which layers asked for this ref, as paths relative to the lockfile (local\n * layers) or canonical refs (remote ones). Sorted. Purely informational, but\n * it is what makes a held-back pin explainable months later.\n */\n requestedBy?: string[];\n}\n\n/** The parsed lockfile. */\nexport interface TreelayLock {\n lockfileVersion: number;\n /** Canonical ref → what it pinned to. */\n refs: Record<string, LockEntry>;\n}\n\n/** An empty, valid lock — what a tree with no remote refs serializes to. */\nexport function emptyLock(): TreelayLock {\n return { lockfileVersion: LOCKFILE_VERSION, refs: {} };\n}\n\n/** Absolute path of the lockfile for a leaf layer directory. */\nexport function lockfilePath(leafDir: string): string {\n return join(leafDir, LOCKFILE_NAME);\n}\n\n/** Raised when a lockfile exists but cannot be used. */\nexport class LockfileError extends Error {\n constructor(file: string, reason: string) {\n super(`${file}: ${reason}`);\n this.name = \"LockfileError\";\n }\n}\n\n/** Read the lockfile beside a leaf layer, or an empty lock when there is none. */\nexport function readLock(leafDir: string): TreelayLock {\n const file = lockfilePath(leafDir);\n if (!existsSync(file)) return emptyLock();\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(readFileSync(file, \"utf8\"));\n } catch (err) {\n throw new LockfileError(file, `not valid JSON (${(err as Error).message})`);\n }\n if (typeof parsed !== \"object\" || parsed === null) {\n throw new LockfileError(file, \"expected a JSON object\");\n }\n\n const lock = parsed as Partial<TreelayLock>;\n if (lock.lockfileVersion !== LOCKFILE_VERSION) {\n throw new LockfileError(\n file,\n `lockfileVersion ${String(lock.lockfileVersion)} was written by a different ` +\n `version of treelay (this one writes ${LOCKFILE_VERSION}). Delete it and ` +\n `re-run \\`treelay lock\\` to regenerate.`,\n );\n }\n return { lockfileVersion: LOCKFILE_VERSION, refs: lock.refs ?? {} };\n}\n\n/**\n * Render a lock to its canonical text.\n *\n * Field order is fixed rather than alphabetical because these files are read by\n * humans during incident review: what was asked for, then what it became.\n */\nexport function serializeLock(lock: TreelayLock): string {\n const refs: Record<string, LockEntry> = {};\n for (const key of Object.keys(lock.refs).sort()) {\n const e = lock.refs[key]!;\n refs[key] = {\n kind: e.kind,\n source: e.source,\n requested: e.requested,\n resolved: e.resolved,\n integrity: e.integrity,\n ...(e.path !== undefined ? { path: e.path } : {}),\n ...(e.requestedBy?.length ? { requestedBy: [...e.requestedBy].sort() } : {}),\n };\n }\n return JSON.stringify({ lockfileVersion: lock.lockfileVersion, refs }, null, 2) + \"\\n\";\n}\n\n/** Write the lock beside a leaf layer. Returns true when the bytes changed. */\nexport function writeLock(leafDir: string, lock: TreelayLock): boolean {\n const file = lockfilePath(leafDir);\n const text = serializeLock(lock);\n if (existsSync(file) && readFileSync(file, \"utf8\") === text) return false;\n writeFileSync(file, text);\n return true;\n}\n\n/** Do two locks pin the same things to the same revisions? */\nexport function locksEqual(a: TreelayLock, b: TreelayLock): boolean {\n return serializeLock(a) === serializeLock(b);\n}\n","/**\n * Resolve a leaf overlay directory into an ordered, linearized layer stack\n * plus the merged variable schema — SPEC §3, §6.\n *\n * Precedence, lowest → highest: mounts < parents (C3-linearized) < mixins < self.\n *\n * Resolution is synchronous even though it may clone repositories. Every caller\n * in the library and CLI treats `resolve` as a plain function, and a build\n * cannot proceed without its layers anyway, so there is nothing to overlap with\n * — the cost of going async would be paid by every consumer for no gain.\n */\n\nimport { isAbsolute, relative, resolve as resolvePath } from \"node:path\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { c3Linearize } from \"./c3.js\";\nimport { loadManifest, isWritable } from \"./manifest.js\";\nimport { mergeVariableDecls } from \"./variables.js\";\nimport { fetchLayer } from \"./fetch/index.js\";\nimport { emptyLock, locksEqual, readLock, type TreelayLock } from \"./lockfile.js\";\nimport { canonicalRef, parseRef, type RemoteRef } from \"./refs.js\";\nimport type { Layer, LayerRef, ResolvedGraph } from \"./types.js\";\n\nexport interface ResolveOptions {\n /**\n * Refuse to resolve any ref the lockfile does not already pin. The CI\n * posture: a build either reproduces from what was committed, or it fails.\n */\n frozen?: boolean;\n /** Re-resolve moving refs to their current upstream revision. */\n updateRefs?: boolean;\n /** Ignore the lockfile entirely — resolve everything live, pin nothing. */\n noLock?: boolean;\n /** Override the fetch cache root (tests). */\n cacheDir?: string;\n}\n\n/** Raised when a `mounts` declaration cannot be materialized coherently. */\nexport class MountError extends Error {\n constructor(mountPath: string, reason: string) {\n super(`Invalid mount \"${mountPath}\": ${reason}`);\n this.name = \"MountError\";\n }\n}\n\n/** Mutable state threaded through one resolution. */\ninterface Context {\n root: string;\n options: ResolveOptions;\n cache: Map<string, Layer>;\n /** The lock as it stands on disk — what pinned revisions to honour. */\n existing: TreelayLock;\n /** The lock this resolution produces; only refs actually used appear. */\n next: TreelayLock;\n}\n\n/** Resolve a leaf directory into its full composition. */\nexport function resolve(srcDir: string, options: ResolveOptions = {}): ResolvedGraph {\n const root = isAbsolute(srcDir) ? srcDir : resolvePath(process.cwd(), srcDir);\n const existing = options.noLock ? emptyLock() : readLock(root);\n const ctx: Context = {\n root,\n options,\n cache: new Map(),\n existing,\n next: emptyLock(),\n };\n\n const self = loadLocal(ctx, root);\n\n // C3 over the parents graph. `parentsOf` resolves each layer's declared\n // parents — local or fetched — as it walks.\n const parentsOf = (layer: Layer): Layer[] =>\n (layer.manifest.parents ?? []).map((ref) => loadRef(ctx, ref, layer));\n\n const mro = c3Linearize(self, parentsOf, (l) => l.id); // [self, ...ancestorsHighToLow]\n const parentsLowToHigh = mro.slice(1).reverse();\n\n // Mixins sit strictly above all parents, in declaration order (last = highest).\n // NOTE: a mixin's own parents are not yet flattened into the stack — TODO once\n // nested-mixin composition is specced out.\n const mixins = (self.manifest.mixins ?? []).map((ref) => loadRef(ctx, ref, self));\n\n const declared = [...parentsLowToHigh, ...mixins, self];\n const mounts = resolveMounts(ctx, declared);\n\n const layers = [...mounts, ...declared];\n const variables = mergeVariableDecls(layers);\n\n return {\n layers,\n variables,\n lock: ctx.next,\n lockDirty: !options.noLock && !locksEqual(existing, ctx.next),\n lockDir: root,\n };\n}\n\n/**\n * Resolve the `mounts` declared across the stack into re-rooted layers (§3).\n *\n * Mount *paths* merge by ordinary layer precedence — the highest layer that\n * names `packages` decides which ref is used — which is what lets a leaf hold a\n * vendored tree back at an older pin while its parents float. There is nothing\n * package-specific about it: it is the same override rule as everything else.\n *\n * The resulting layers sit at the **bottom** of the stack, below every declared\n * layer. Vendored content is substrate: any layer, including the one that\n * declared the mount, must be able to patch or tombstone a file inside it, and\n * that only works if the mount is beneath them all. Placing a mount next to its\n * declaring layer would instead make an intermediate layer's patch depend on\n * which ancestor happened to win the ref.\n */\nfunction resolveMounts(ctx: Context, declared: readonly Layer[]): Layer[] {\n // Lowest → highest, last writer wins, remembering who won so the ref resolves\n // relative to the right directory.\n const winners = new Map<string, { ref: LayerRef; from: Layer }>();\n for (const layer of declared) {\n for (const [path, ref] of Object.entries(layer.manifest.mounts ?? {})) {\n winners.set(normalizeMount(path), { ref, from: layer });\n }\n }\n if (!winners.size) return [];\n\n const paths = [...winners.keys()].sort();\n for (let i = 1; i < paths.length; i++) {\n const prev = paths[i - 1]!;\n if (paths[i]!.startsWith(prev + \"/\")) {\n throw new MountError(\n paths[i]!,\n `it nests inside mount \"${prev}\". Overlapping mounts have no ` +\n `unambiguous owner — give them disjoint paths.`,\n );\n }\n }\n\n return paths.map((path) => {\n const { ref, from } = winners.get(path)!;\n const base = loadRef(ctx, ref, from);\n return {\n ...base,\n // A mount is a distinct stack position, so it needs a distinct identity:\n // the same ref may legitimately be mounted at two paths.\n id: `mount:${path}`,\n mountPath: path,\n // Vendored trees are never promotion targets. Reflux maps output paths\n // back to layer paths, and a mounted layer's output paths carry a prefix\n // its sources do not — so it is read-only until that mapping exists (§8).\n writable: false,\n };\n });\n}\n\n/** Validate and normalize a mount path into a relative posix subpath. */\nfunction normalizeMount(path: string): string {\n const clean = path.split(\"\\\\\").join(\"/\").replace(/^\\.\\//, \"\").replace(/\\/+$/, \"\");\n if (clean === \"\" || clean === \".\") {\n throw new MountError(path, \"a mount needs a non-empty subpath\");\n }\n if (isAbsolute(clean) || clean.startsWith(\"/\")) {\n throw new MountError(path, \"mount paths are relative to the composed tree root\");\n }\n if (clean.split(\"/\").includes(\"..\")) {\n throw new MountError(path, \"mount paths may not escape the composed tree\");\n }\n return clean;\n}\n\n/** Load a local layer directory, memoized by absolute path. */\nfunction loadLocal(ctx: Context, dir: string): Layer {\n const cached = ctx.cache.get(dir);\n if (cached) return cached;\n const layer: Layer = {\n id: dir,\n dir,\n manifest: loadManifest(dir),\n writable: isWritable(dir),\n origin: { kind: \"local\" },\n };\n ctx.cache.set(dir, layer);\n return layer;\n}\n\n/** Resolve one declared reference from `from` into a loaded layer. */\nfunction loadRef(ctx: Context, ref: LayerRef, from: Layer): Layer {\n const parsed = parseRef(ref);\n if (parsed.kind === \"local\") return loadLocal(ctx, resolveLocalRef(ref, from.dir));\n\n const key = canonicalRef(parsed);\n const cached = ctx.cache.get(key);\n if (cached) {\n recordRequester(ctx, key, from);\n return cached;\n }\n\n const fetched = fetchLayer(parsed as RemoteRef, {\n fromDir: from.dir,\n lock: ctx.existing,\n ...(ctx.options.frozen ? { frozen: true } : {}),\n ...(ctx.options.updateRefs ? { updateRefs: true } : {}),\n ...(ctx.options.cacheDir ? { cacheDir: ctx.options.cacheDir } : {}),\n });\n\n ctx.next.refs[key] = fetched.entry;\n recordRequester(ctx, key, from);\n\n const layer: Layer = {\n id: key,\n dir: fetched.dir,\n manifest: loadManifest(fetched.dir),\n // A cache checkout is shared by every project on the machine and is keyed\n // by an immutable revision. Editing it would silently change other builds,\n // so fetched layers are never promotion targets (§8).\n writable: false,\n origin: {\n kind: parsed.kind,\n ref: key,\n revision: fetched.revision,\n integrity: fetched.integrity,\n },\n };\n ctx.cache.set(key, layer);\n return layer;\n}\n\n/** Note which layer asked for a ref, for the lockfile's `requestedBy`. */\nfunction recordRequester(ctx: Context, key: string, from: Layer): void {\n const entry = ctx.next.refs[key];\n if (!entry) return;\n // Local layers are recorded relative to the lockfile so the file stays\n // machine-independent and reviewable in a diff.\n const who =\n from.origin?.kind === \"local\" || from.origin === undefined\n ? relative(ctx.root, from.dir).split(\"\\\\\").join(\"/\") || \".\"\n : from.id;\n const list = new Set(entry.requestedBy ?? []);\n list.add(who);\n entry.requestedBy = [...list].sort();\n}\n\n/** Resolve a local path reference to an absolute directory. */\nfunction resolveLocalRef(ref: LayerRef, fromDir: string): string {\n const parsed = parseRef(ref);\n const dir = resolvePath(fromDir, parsed.kind === \"local\" ? parsed.path : ref);\n if (!existsSync(dir) || !statSync(dir).isDirectory()) {\n throw new Error(`Layer not found: \"${ref}\" (resolved to ${dir})`);\n }\n return dir;\n}\n\n/**\n * Resolve a layer reference to an absolute directory on disk.\n *\n * Retained as the low-level entry point: local paths resolve directly, and\n * fetched refs are materialized into the cache and their root returned.\n */\nexport function resolveRef(\n ref: LayerRef,\n fromDir: string,\n options: ResolveOptions & { lock?: TreelayLock } = {},\n): string {\n const parsed = parseRef(ref);\n if (parsed.kind === \"local\") return resolveLocalRef(ref, fromDir);\n return fetchLayer(parsed as RemoteRef, {\n fromDir,\n lock: options.lock ?? emptyLock(),\n ...(options.frozen ? { frozen: true } : {}),\n ...(options.updateRefs ? { updateRefs: true } : {}),\n ...(options.cacheDir ? { cacheDir: options.cacheDir } : {}),\n }).dir;\n}\n","/**\n * Unified-diff 3-way merge — SPEC §5.\n *\n * Two paths, chosen by whether the caller can supply the base *content* the\n * patch was authored against:\n *\n * - **base known** → reconstruct the author's intent (`base` → `patched`), then\n * reconcile it against the drift the inherited file actually took\n * (`base` → `current`) with a real diff3. This resolves cleanly far more\n * often than a flat apply and produces honest conflicts when it can't.\n * - **base unknown** → best-effort apply onto `current`. jsdiff searches for\n * each hunk's location, so hunks that merely *moved* still land; changed\n * context is rejected rather than guessed at.\n *\n * Either way the function is all-or-nothing: it returns fully merged text or\n * throws `MergeConflictError`. It never returns partially-patched content.\n */\n\nimport { applyPatch, parsePatch } from \"diff\";\nimport { merge as diff3, mergeDiff3 } from \"node-diff3\";\nimport { MergeConflictError } from \"../errors.js\";\n\n/** Default conflict-marker labels, phrased for the `update` direction (§7). */\nexport const MERGE_LABELS = {\n ours: \"ours (your edits)\",\n base: \"base (last template output)\",\n theirs: \"theirs (new template)\",\n} as const;\n\nexport interface TextMerge3Args {\n /** Common ancestor both sides diverged from. */\n base: string;\n /** The local side — kept first in conflict markers, as git does. */\n ours: string;\n /** The incoming side. */\n theirs: string;\n labels?: { ours: string; base: string; theirs: string };\n}\n\nexport interface TextMerge3Result {\n /** False when the two sides edited the same region. */\n clean: boolean;\n /** Merged text; carries diff3-style conflict markers when `clean` is false. */\n text: string;\n}\n\n/**\n * Three-way merge of raw text — the same diff3 engine `applyPatch3Way` uses,\n * exposed directly for `update`, which already holds all three versions and has\n * no patch to apply.\n *\n * Conflicts are *returned*, not thrown: unlike compile, `update` has to write\n * something (markers or a `.rej`) so the user can resolve it in place.\n * Markers include the base section, so you can see what the template previously\n * produced rather than guessing why the two sides disagree.\n */\nexport function mergeText3(args: TextMerge3Args): TextMerge3Result {\n const { base, ours, theirs, labels = MERGE_LABELS } = args;\n if (ours === theirs) return { clean: true, text: ours };\n if (ours === base) return { clean: true, text: theirs };\n if (theirs === base) return { clean: true, text: ours };\n\n const merged = mergeDiff3(toLines(ours), toLines(base), toLines(theirs), {\n label: { a: labels.ours, o: labels.base, b: labels.theirs },\n });\n return {\n clean: !merged.conflict,\n text: fromLines(merged.result as string[]),\n };\n}\n\nexport interface Patch3WayArgs {\n /** Relative path, for error messages. */\n file: string;\n /** The inherited content the patch should land on. */\n current: string;\n /** Unified diff. Bare `@@` hunks are accepted (no `---`/`+++` headers). */\n patch: string;\n /**\n * The exact content the patch was authored against. When supplied, enables a\n * true 3-way merge; omit it for best-effort apply.\n */\n base?: string;\n}\n\n/**\n * Split text into lines losslessly — `fromLines(toLines(t)) === t` for all `t`,\n * including the trailing-newline case (which yields a final `\"\"` element).\n */\nfunction toLines(text: string): string[] {\n return text.split(\"\\n\");\n}\n\nfunction fromLines(lines: string[]): string {\n return lines.join(\"\\n\");\n}\n\n/** Reject an unparseable payload up front, with a clearer message than jsdiff's. */\nfunction assertParseable(file: string, patch: string): void {\n let hunks = 0;\n try {\n hunks = parsePatch(patch).reduce((n, p) => n + p.hunks.length, 0);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n // jsdiff reports a header/body length mismatch as \"contained invalid line\",\n // which sends people hunting for a bad character instead of miscounted\n // hunk headers — the usual mistake when a patch is written by hand.\n const hint = /invalid line/i.test(message)\n ? \"\\nCheck the `@@ -old,COUNT +new,COUNT @@` header: the counts must match \" +\n \"the number of lines in the hunk body (context + removals for the first, \" +\n \"context + additions for the second).\"\n : \"\";\n throw new MergeConflictError(\n file,\n `patch payload is not a valid unified diff — ${message}${hint}`,\n );\n }\n if (hunks === 0) {\n throw new MergeConflictError(\n file,\n \"patch payload contains no hunks (expected unified-diff `@@` sections)\",\n );\n }\n}\n\n/** A short preview of text, for error messages. */\nfunction preview(text: string, maxLines = 20): string {\n const lines = toLines(text);\n return lines.length <= maxLines\n ? text\n : fromLines(lines.slice(0, maxLines)) + `\\n… (${lines.length - maxLines} more lines)`;\n}\n\n/**\n * Apply a unified diff onto `current`, reconciling against `base` when known.\n *\n * Returns the merged text, or throws MergeConflictError — never half-applies.\n */\nexport function applyPatch3Way(args: Patch3WayArgs): string {\n const { file, current, patch, base } = args;\n assertParseable(file, patch);\n\n // No recorded base: best-effort apply. jsdiff relocates moved hunks; anything\n // it can't place is a rejection, and rejections are fatal (§5 \"fail loud\").\n if (base === undefined) {\n const applied = applyPatch(current, patch);\n if (applied === false) {\n throw new MergeConflictError(\n file,\n \"patch does not apply to the inherited content and no base was recorded, \" +\n \"so it cannot be reconciled.\\n\" +\n \"Record a `base:`/`baseContent:` in the sidecar to enable a three-way merge.\\n\" +\n `--- patch ---\\n${preview(patch)}`,\n );\n }\n return applied;\n }\n\n // The patch is defined as a delta *from* `base`, so it must apply there. If it\n // doesn't, the sidecar itself is inconsistent — say so rather than blaming the\n // inherited file.\n const patched = applyPatch(base, patch);\n if (patched === false) {\n throw new MergeConflictError(\n file,\n \"patch does not apply to its own recorded base — the sidecar is inconsistent \" +\n \"(`base`/`baseContent` does not match the patch payload).\\n\" +\n `--- patch ---\\n${preview(patch)}`,\n );\n }\n\n // No drift: the inherited content is exactly what the patch was authored\n // against, so the author's intent is the answer.\n if (current === base) return patched;\n\n // Drift: reconcile (base → current) against (base → patched).\n const merged = diff3(toLines(current), toLines(base), toLines(patched));\n if (merged.conflict) {\n throw new MergeConflictError(\n file,\n \"three-way merge conflict — the inherited file changed in the same region \" +\n \"the patch edits.\\n\" +\n \"Re-author the patch against the current content, or resolve by hand.\\n\" +\n `--- conflict ---\\n${preview(fromLines(merged.result as string[]))}`,\n );\n }\n return fromLines(merged.result as string[]);\n}\n","/**\n * `.treelay` sidecar parsing & detection — SPEC §4.\n *\n * A `<targetPath>.treelay` file describes an operation on the inherited file:\n * the strategy, an optional base hash (enabling true 3-way merge, §5), an\n * optional `when:` guard, and the payload. This is the canonical, full-power\n * form; the filename suffixes (`.patch`/`.append`/`.delete`) are sugar that\n * desugar to one of these ops.\n */\n\nimport { parse as parseYaml } from \"yaml\";\nimport type { SidecarOp, SidecarOpKind } from \"./types.js\";\n\nexport const SIDECAR_SUFFIX = \".treelay\";\n\n/** Is this path a sidecar? (Distinct from the `.treelay/` state dir, §7.) */\nexport function isSidecar(path: string): boolean {\n return path.endsWith(SIDECAR_SUFFIX) && path !== SIDECAR_SUFFIX;\n}\n\n/** Map a sidecar path to the inherited file it operates on. */\nexport function sidecarTarget(path: string): string {\n return path.slice(0, -SIDECAR_SUFFIX.length);\n}\n\n/** Parse sidecar YAML into a validated op. */\nexport function parseSidecar(yaml: string): SidecarOp {\n const op = parseYaml(yaml) as SidecarOp;\n if (!op || typeof op.op !== \"string\") {\n throw new Error(`Invalid .treelay sidecar: missing \"op\"`);\n }\n return op;\n}\n\n/** Desugar a filename suffix convention into an equivalent sidecar op (§4). */\nconst SUFFIX_OPS: Record<string, SidecarOpKind> = {\n \".patch\": \"patch\",\n \".append\": \"append\",\n \".prepend\": \"prepend\",\n \".delete\": \"delete\",\n};\n\n/**\n * If `path` ends in a known merge suffix, return the desugared op and the\n * target path it applies to. A bare `.patch` has no recorded `base`, so it is\n * best-effort apply rather than true 3-way (§5).\n */\nexport function desugarSuffix(\n path: string,\n): { op: SidecarOpKind; target: string } | undefined {\n for (const [suffix, op] of Object.entries(SUFFIX_OPS)) {\n if (path.endsWith(suffix)) {\n return { op, target: path.slice(0, -suffix.length) };\n }\n }\n return undefined;\n}\n","/** Recursive deep merge for structured files — SPEC §4. */\n\nimport type { ArrayPolicy } from \"../types.js\";\n\ntype Json = unknown;\n\nfunction isObject(v: Json): v is Record<string, Json> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/**\n * Deep-merge `over` onto `base`. Objects merge recursively; arrays follow the\n * `arrays` policy. Default `replace` because concat surprises people (§4).\n */\nexport function deepMerge(\n base: Json,\n over: Json,\n arrays: ArrayPolicy = \"replace\",\n): Json {\n if (Array.isArray(base) && Array.isArray(over)) {\n switch (arrays) {\n case \"concat\":\n return [...base, ...over];\n case \"replace\":\n return over;\n case \"by-key\":\n // TODO(§4): merge array elements by a key field once the key is specced.\n return over;\n }\n }\n\n if (isObject(base) && isObject(over)) {\n const result: Record<string, Json> = { ...base };\n for (const [k, v] of Object.entries(over)) {\n result[k] = k in base ? deepMerge(base[k], v, arrays) : v;\n }\n return result;\n }\n\n // Scalars, or mismatched shapes: the higher layer wins.\n return over;\n}\n","/** Structured patches for config files — SPEC §5. */\n\nimport { createRequire } from \"node:module\";\nimport type { Operation } from \"fast-json-patch\";\n\n// Both libraries are CommonJS; Node's ESM named-import interop can't see their\n// exports, so load them through createRequire (works at runtime and under test).\nconst require = createRequire(import.meta.url);\nconst { applyPatch: applyJsonPatchLib } =\n require(\"fast-json-patch\") as typeof import(\"fast-json-patch\");\nconst jsonMergePatch =\n require(\"json-merge-patch\") as typeof import(\"json-merge-patch\");\n\n/**\n * Apply an RFC 7386 JSON Merge Patch. `null` values in the patch delete keys;\n * everything else recurses. The target is deep-cloned first so the caller's\n * value is never mutated (the underlying library mutates in place).\n */\nexport function applyMergePatch(target: unknown, patch: unknown): unknown {\n const clone = target === undefined ? undefined : structuredClone(target);\n return jsonMergePatch.apply(clone, patch);\n}\n\n/**\n * Produce the RFC 7386 merge patch turning `before` into `after` — the inverse\n * of {@link applyMergePatch}. Reflux (§8) uses it to record a promoted edit to a\n * structured file as a delta rather than a whole-file copy.\n */\nexport function generateMergePatch(before: unknown, after: unknown): unknown {\n return jsonMergePatch.generate(before, after);\n}\n\n/**\n * Apply an RFC 6902 JSON Patch (precise array/path ops). Non-mutating: returns\n * the new document and leaves the input untouched.\n */\nexport function applyJsonPatch(target: unknown, ops: unknown[]): unknown {\n const { newDocument } = applyJsonPatchLib(\n structuredClone(target),\n ops as Operation[],\n /* validateOperation */ true,\n /* mutateDocument */ false,\n );\n return newDocument;\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/**\n * Do two RFC 7386 merge patches disagree? They conflict only where both touch\n * the *same* key with a different outcome; keys only one side changed compose\n * freely, which is exactly what makes structured merging beat line diffing for\n * config files.\n */\nfunction patchesConflict(a: unknown, b: unknown): boolean {\n if (isObject(a) && isObject(b)) {\n for (const key of Object.keys(a)) {\n if (key in b && patchesConflict(a[key], b[key])) return true;\n }\n return false;\n }\n return JSON.stringify(a) !== JSON.stringify(b);\n}\n\nexport interface StructuredMerge3Result {\n clean: boolean;\n /** The merged document; only meaningful when `clean`. */\n value: unknown;\n}\n\n/**\n * Three-way merge two structured documents by reconciling their *changes*\n * rather than their lines (§7).\n *\n * Line-based merging conflicts on edits that happen to sit near each other;\n * comparing `base → ours` and `base → theirs` as merge patches instead means\n * two sides adding different keys — the common case for `package.json` — merges\n * cleanly no matter where those keys landed in the file.\n */\nexport function mergeStructured3(\n base: unknown,\n ours: unknown,\n theirs: unknown,\n): StructuredMerge3Result {\n const ourPatch = generateMergePatch(base, ours);\n const theirPatch = generateMergePatch(base, theirs);\n\n if (ourPatch === undefined) return { clean: true, value: theirs };\n if (theirPatch === undefined) return { clean: true, value: ours };\n if (patchesConflict(ourPatch, theirPatch)) return { clean: false, value: undefined };\n\n // Non-conflicting, so order is irrelevant; apply theirs then ours.\n return {\n clean: true,\n value: applyMergePatch(applyMergePatch(base, theirPatch), ourPatch),\n };\n}\n","/** Per-file merge strategy dispatch — SPEC §4. */\n\nimport picomatch from \"picomatch\";\nimport type { MergeStrategy } from \"../types.js\";\n\nexport { deepMerge } from \"./deepMerge.js\";\nexport { applyPatch3Way } from \"./patch.js\";\nexport { applyMergePatch, applyJsonPatch } from \"./structured.js\";\n\nconst STRUCTURED = /\\.(json|ya?ml|toml)$/i;\nconst BINARY = /\\.(png|jpe?g|gif|webp|ico|pdf|woff2?|ttf|zip|gz)$/i;\n\n/**\n * Default strategy for a path when no manifest glob or sidecar specifies one:\n * structured files deep-merge, binaries replace, everything else replaces (text\n * gets patch/append only via explicit sidecar/suffix).\n */\nexport function defaultStrategy(path: string): MergeStrategy {\n if (STRUCTURED.test(path)) return \"deep-merge\";\n if (BINARY.test(path)) return \"replace\";\n return \"replace\";\n}\n\n/** Resolve the strategy for a path given the manifest `merge` globs (§4). */\nexport function strategyFor(\n path: string,\n globs: Record<string, MergeStrategy> = {},\n): MergeStrategy {\n for (const [glob, strategy] of Object.entries(globs)) {\n if (picomatch.isMatch(path, glob)) return strategy;\n }\n return defaultStrategy(path);\n}\n","/**\n * Layer file enumeration & classification — the shared walk beneath both\n * `compile` (§6/§7) and `explain` (§9).\n *\n * Everything that decides *which* files in a layer participate in composition,\n * and *what kind* of contribution each one makes, lives here. Compile turns\n * those entries into bytes; explain turns them into provenance. Keeping the\n * walk in one place is what stops the two from disagreeing about what a layer\n * contains.\n */\n\nimport { relative, resolve as resolvePath } from \"node:path\";\nimport fg from \"fast-glob\";\n\nimport { isSidecar, sidecarTarget, desugarSuffix } from \"./sidecar.js\";\nimport { templateTarget, DEFAULT_TEMPLATE_SUFFIX } from \"./render.js\";\nimport type { Layer, SidecarOpKind } from \"./types.js\";\n\n/**\n * Globs never materialized into the output.\n *\n * `.git` is excluded in **both** forms deliberately (§4, \"built-in tombstone\"):\n * `**\\/.git/**` covers a normal repository directory's contents, while\n * `**\\/.git` covers the *gitlink file* that a git **submodule** checkout carries\n * in place of a directory. A layer vendored as a submodule would otherwise\n * publish its gitlink into every compiled tree, producing output that git reads\n * as a broken submodule. `.gitignore`/`.gitmodules` are ordinary files and are\n * intentionally **not** matched by the exact-name `.git` glob.\n */\nexport const ALWAYS_IGNORE = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/.git\",\n \".treelay/**\",\n \"**/.treelay/**\",\n \"**/treelay.json\",\n \"**/treelay.yaml\",\n \"**/treelay.yml\",\n // The lockfile is manifest metadata, not content. Composing it would publish\n // a layer's pins into every tree built from it — and, worse, make the leaf's\n // own lockfile a *generated* file that `update` then reports as a change.\n \"**/treelay.lock\",\n];\n\n/** What sort of contribution a source file in a layer makes. */\nexport type EntryKind = \"file\" | \"sidecar\" | \"suffix\";\n\n/** One classified source file within a layer. */\nexport interface LayerEntry {\n /** Path of the source file relative to the layer dir. */\n source: string;\n /** The path after stripping the template suffix (may still carry an op suffix). */\n inner: string;\n /** True when the source carried the template suffix (content renders, §6). */\n isTemplate: boolean;\n kind: EntryKind;\n /** For sidecar/suffix entries, the operation being performed. */\n op?: SidecarOpKind;\n /**\n * The output path this entry targets, *before* Liquid path rendering.\n * For ops this is the inherited file the op applies to.\n */\n rawTarget: string;\n}\n\n/**\n * Raised when a destination directory is a layer root itself — compiling a\n * layer on top of itself is degenerate, not merely awkward, so it fails loud\n * rather than half-consuming its own output.\n */\nexport class SelfCompileError extends Error {\n constructor(dir: string) {\n super(\n `Destination is a layer root: ${dir}\\n` +\n `Compiling a layer into itself would overwrite the sources being read. ` +\n `Choose a destination outside the layer, or a subdirectory of it (e.g. ${dir}/build).`,\n );\n this.name = \"SelfCompileError\";\n }\n}\n\n/**\n * Extra ignore globs so a destination nested *inside* a layer never feeds its\n * own prior output back into the composition (§7).\n *\n * The autom-lake shape — compiling into a gitignored `build/` inside the source\n * repo — is explicitly supported: a destination that is a strict descendant of\n * a layer is pruned from that layer's walk. A destination that *is* the layer\n * root is rejected via {@link SelfCompileError}.\n */\nexport function destExclusions(layerDir: string, destDir?: string): string[] {\n if (!destDir) return [];\n const layerAbs = resolvePath(layerDir);\n const destAbs = resolvePath(destDir);\n if (destAbs === layerAbs) throw new SelfCompileError(layerAbs);\n\n const rel = relative(layerAbs, destAbs);\n // Outside the layer (or on another drive) ⇒ nothing to prune.\n if (rel === \"\" || rel.startsWith(\"..\") || resolvePath(layerAbs, rel) !== destAbs) {\n return [];\n }\n const posix = rel.split(\"\\\\\").join(\"/\");\n return [posix, `${posix}/**`];\n}\n\n/**\n * Re-root an output path under a layer's mount point (§3).\n *\n * A mounted layer composes exactly like any other — same strategies, same\n * sidecars — except that every path it produces or operates on is prefixed.\n * Keeping that in one function is what stops `compile` and `explain` from\n * disagreeing about where a mounted file lands.\n */\nexport function mountTarget(layer: Layer, target: string): string {\n return layer.mountPath ? `${layer.mountPath}/${target}` : target;\n}\n\n/** List the composable source files of a layer, lowest-level primitive. */\nexport function listLayerFiles(layer: Layer, destDir?: string): string[] {\n return fg\n .sync(\"**/*\", {\n cwd: layer.dir,\n dot: true,\n onlyFiles: true,\n ignore: [\n ...ALWAYS_IGNORE,\n ...(layer.manifest.ignore ?? []),\n ...destExclusions(layer.dir, destDir),\n ],\n })\n .sort();\n}\n\n/**\n * Classify one source path into the contribution it makes.\n *\n * The template suffix is outermost (§6): strip and render first, then the inner\n * name decides whether this is a sidecar, suffix sugar, or a plain file.\n */\nexport function classifyEntry(source: string, templateSuffix: string): LayerEntry {\n const { render: isTemplate, outPath: inner } = templateTarget(source, templateSuffix);\n\n if (isSidecar(inner)) {\n return {\n source,\n inner,\n isTemplate,\n kind: \"sidecar\",\n rawTarget: sidecarTarget(inner),\n };\n }\n\n const sugar = desugarSuffix(inner);\n if (sugar) {\n return {\n source,\n inner,\n isTemplate,\n kind: \"suffix\",\n op: sugar.op,\n rawTarget: sugar.target,\n };\n }\n\n return { source, inner, isTemplate, kind: \"file\", rawTarget: inner };\n}\n\n/** Enumerate a layer's classified entries, in stable (sorted) order. */\nexport function enumerateLayer(layer: Layer, destDir?: string): LayerEntry[] {\n const suffix = layer.manifest.templateSuffix ?? DEFAULT_TEMPLATE_SUFFIX;\n return listLayerFiles(layer, destDir).map((rel) => classifyEntry(rel, suffix));\n}\n","/**\n * Destination `.treelay/` state — SPEC §7.\n *\n * Written into the compiled destination so the template link survives: the\n * lockfile (resolved lineage), persisted answers (deterministic re-render),\n * the baseline (merge base for update & reflux), and the generated/owned map.\n */\n\nimport {\n mkdirSync,\n readFileSync,\n writeFileSync,\n existsSync,\n rmSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { hashContent } from \"./hash.js\";\nimport type { ResolvedGraph, VariableDecl, Values } from \"./types.js\";\n\nexport const STATE_DIR = \".treelay\";\n\nexport interface TreelayState {\n lock: LockFile;\n answers: Values;\n /** relative path → content hash of what the template last produced. */\n baseline: Record<string, string>;\n /** relative path → whether the template owns it (vs user-created). */\n manifest: Record<string, { owned: boolean; fromLayer: string }>;\n}\n\nexport interface LockFile {\n /**\n * Layer ids/refs lowest → highest precedence at last compile. The last entry\n * is the leaf — this is how `update <dest>` rediscovers its source template\n * without being told where it came from.\n */\n lineage: string[];\n /** Resolved version refs per layer (npm/git), for drift detection. */\n versions: Record<string, string>;\n}\n\nexport const statePaths = (destDir: string) => ({\n dir: join(destDir, STATE_DIR),\n lock: join(destDir, STATE_DIR, \"lock.json\"),\n answers: join(destDir, STATE_DIR, \"answers.json\"),\n baseline: join(destDir, STATE_DIR, \"baseline.json\"),\n /** Content snapshot of the last template output — the diff3 merge base (§7). */\n baselineDir: join(destDir, STATE_DIR, \"baseline\"),\n manifest: join(destDir, STATE_DIR, \"manifest.json\"),\n});\n\n/**\n * The leaf template a destination was compiled from, recovered from the lock.\n * Returns undefined for a lockfile with no lineage (nothing to update against).\n */\nexport function sourceOf(state: TreelayState): string | undefined {\n return state.lock.lineage[state.lock.lineage.length - 1];\n}\n\n/** Whether a destination already carries treelay state (⇒ `update`, not compile). */\nexport function hasState(destDir: string): boolean {\n return existsSync(statePaths(destDir).lock);\n}\n\n/**\n * Drop `secret` variables from the answers before persisting (§6/§7): secrets\n * are masked input and must never be written to disk.\n */\nfunction stripSecrets(\n values: Values,\n decls: Record<string, VariableDecl>,\n): Values {\n const out: Values = {};\n for (const [k, v] of Object.entries(values)) {\n if (decls[k]?.secret) continue;\n out[k] = v;\n }\n return out;\n}\n\n/**\n * Persist the state artifacts into `<destDir>/.treelay/`.\n *\n * `snapshot` is the exact content the template just produced. It is stored\n * alongside the hash index because the two answer different questions: the hash\n * cheaply decides *whether* a file changed, but only the content can serve as\n * the merge base when both the template and the user changed it (§7). Passing\n * it replaces any previous snapshot wholesale, so files the template no longer\n * produces don't linger as stale merge bases.\n */\nexport function writeState(\n destDir: string,\n state: TreelayState,\n decls: Record<string, VariableDecl>,\n snapshot?: ReadonlyMap<string, Buffer>,\n): void {\n const paths = statePaths(destDir);\n mkdirSync(paths.dir, { recursive: true });\n const json = (v: unknown) => JSON.stringify(v, null, 2) + \"\\n\";\n writeFileSync(paths.lock, json(state.lock));\n writeFileSync(paths.answers, json(stripSecrets(state.answers, decls)));\n writeFileSync(paths.baseline, json(state.baseline));\n writeFileSync(paths.manifest, json(state.manifest));\n\n if (snapshot) {\n rmSync(paths.baselineDir, { recursive: true, force: true });\n for (const [rel, data] of snapshot) {\n const abs = join(paths.baselineDir, rel);\n ensureDir(abs);\n writeFileSync(abs, data);\n }\n }\n}\n\n/**\n * Read one file's baseline content — the merge base for `update` (§7).\n *\n * Undefined when the destination predates snapshotting, never had the file, or\n * the snapshot has gone stale. `expectedHash` is what makes the last case safe:\n * any writer that advances `baseline.json` without passing a fresh `snapshot` to\n * {@link writeState} leaves content that no longer matches, and merging against\n * a wrong base corrupts silently. Verifying here turns that into a plain\n * \"no base available\", which callers surface as a conflict instead.\n */\nexport function readBaselineFile(\n destDir: string,\n rel: string,\n expectedHash?: string,\n): Buffer | undefined {\n const abs = join(statePaths(destDir).baselineDir, rel);\n if (!existsSync(abs)) return undefined;\n const data = readFileSync(abs);\n if (expectedHash !== undefined && hashContent(data) !== expectedHash) {\n return undefined;\n }\n return data;\n}\n\n/** Read back persisted state (used by update/status/reflux). */\nexport function readState(destDir: string): TreelayState {\n const paths = statePaths(destDir);\n const read = (p: string) => JSON.parse(readFileSync(p, \"utf8\"));\n return {\n lock: read(paths.lock),\n answers: read(paths.answers),\n baseline: read(paths.baseline),\n manifest: read(paths.manifest),\n };\n}\n\n/**\n * Build a destination lockfile from a resolved graph.\n *\n * `versions` is the record of *what was actually materialized* — canonical ref\n * → exact revision — copied from the source `treelay.lock` at compile time. The\n * two files are deliberately distinct: `treelay.lock` is the pin a repository\n * commits and reviews, while this one is forensic, saying what a particular\n * destination on a particular day was built from.\n */\nexport function lockFromGraph(graph: ResolvedGraph): LockFile {\n const versions: Record<string, string> = {};\n for (const ref of Object.keys(graph.lock?.refs ?? {}).sort()) {\n versions[ref] = graph.lock!.refs[ref]!.resolved;\n }\n return {\n lineage: graph.layers.map((l) => l.id),\n versions,\n };\n}\n\n/** Ensure a file's parent directory exists before writing it. */\nexport function ensureDir(filePath: string): void {\n mkdirSync(dirname(filePath), { recursive: true });\n}\n","/**\n * Compile pipeline — SPEC §6 (the eight steps) and §7 (state).\n *\n * resolve graph → merge var decls → resolve values → eval computed →\n * render each layer → merge rendered layers per-file → drop empty-named\n * files → materialize + persist state.\n *\n * Render-then-merge: a child's op is authored against the parent's *rendered*\n * output, so each layer is rendered before the merge step.\n */\n\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport fg from \"fast-glob\";\n\nimport { MergeConflictError } from \"./errors.js\";\nimport { hashContent } from \"./hash.js\";\nimport { applyPatch3Way } from \"./merge/patch.js\";\nimport { renderString, templateTarget, DEFAULT_TEMPLATE_SUFFIX } from \"./render.js\";\nimport {\n isSidecar,\n sidecarTarget,\n parseSidecar,\n desugarSuffix,\n SIDECAR_SUFFIX,\n} from \"./sidecar.js\";\nimport { strategyFor, deepMerge, applyMergePatch, applyJsonPatch } from \"./merge/index.js\";\nimport { ALWAYS_IGNORE, destExclusions, mountTarget } from \"./layer-files.js\";\nimport { parseStructured, stringifyStructured } from \"./serde.js\";\nimport { writeLock } from \"./lockfile.js\";\nimport {\n writeState,\n lockFromGraph,\n ensureDir,\n type TreelayState,\n} from \"./state.js\";\nimport type {\n CompileResult,\n Layer,\n MergeStrategy,\n ResolvedGraph,\n SidecarOp,\n SidecarOpKind,\n Values,\n} from \"./types.js\";\n\nexport interface CompileOptions {\n destDir: string;\n /** Final variable values (from `resolveValues`). */\n values?: Values;\n /**\n * Persist newly-resolved pins back into the source `treelay.lock` (§3).\n *\n * Defaults to true, following every package manager: the first build after a\n * ref is added records what it resolved to, so the *next* build reproduces it.\n * A frozen resolve never gets here — it fails on the unpinned ref instead.\n */\n writeLockfile?: boolean;\n}\n\n\n/**\n * One accumulated output file as it builds up across the layer stack. Also the\n * public shape of an in-memory composition (see {@link composeFiles}).\n */\nexport interface FileEntry {\n data: Buffer;\n strategy: MergeStrategy;\n fromLayer: string;\n patchedFrom: string[];\n}\n\n/** A normalized operation on an inherited file (from a sidecar or suffix sugar). */\ninterface Op {\n kind: SidecarOpKind;\n target: string;\n when?: string;\n render: boolean;\n content?: string;\n merge?: unknown;\n jsonPatch?: unknown[];\n /** Recorded base hash — drift detector for `patch` ops (§5). */\n base?: string;\n /** Recorded base content — enables true diff3 under drift (§5). */\n baseContent?: string;\n}\n\n/** Does this string contain Liquid markup worth rendering? */\nfunction needsRender(s: string): boolean {\n return s.includes(\"{{\") || s.includes(\"{%\");\n}\n\n/**\n * Compose a graph into an in-memory file map, writing nothing.\n *\n * This is the whole pipeline minus materialization, split out because `update`\n * (§7) needs the *would-be* output to merge against a project that already\n * exists — recompiling straight onto disk would destroy the very edits it is\n * trying to preserve.\n *\n * `destDir` is only used to prune a destination nested inside the source tree,\n * so a compose is safe to run with the real destination path.\n */\nexport async function composeFiles(\n graph: ResolvedGraph,\n values: Values = {},\n destDir?: string,\n): Promise<Map<string, FileEntry>> {\n const acc = new Map<string, FileEntry>();\n for (const layer of graph.layers) {\n await applyLayer(layer, acc, values, destDir);\n }\n return acc;\n}\n\n/** Provenance + baseline bookkeeping derived from a composition. */\nexport function summarize(acc: ReadonlyMap<string, FileEntry>): {\n result: CompileResult;\n baseline: Record<string, string>;\n manifest: TreelayState[\"manifest\"];\n} {\n const result: CompileResult = { files: {} };\n const baseline: Record<string, string> = {};\n const manifest: TreelayState[\"manifest\"] = {};\n\n for (const [rel, entry] of acc) {\n result.files[rel] = {\n fromLayer: entry.fromLayer,\n strategy: entry.strategy,\n owned: false,\n ...(entry.patchedFrom.length ? { patchedFrom: entry.patchedFrom } : {}),\n };\n baseline[rel] = hashContent(entry.data);\n manifest[rel] = { owned: false, fromLayer: entry.fromLayer };\n }\n return { result, baseline, manifest };\n}\n\n/** Materialize a resolved graph into a destination directory. */\nexport async function compile(\n graph: ResolvedGraph,\n options: CompileOptions,\n): Promise<CompileResult> {\n const values = options.values ?? {};\n const acc = await composeFiles(graph, values, options.destDir);\n\n // Compose fully before writing anything: a conflict partway through must not\n // leave a half-built destination behind (§5).\n const { result, baseline, manifest } = summarize(acc);\n const snapshot = new Map<string, Buffer>();\n\n for (const [rel, entry] of acc) {\n const abs = join(options.destDir, rel);\n ensureDir(abs);\n writeFileSync(abs, entry.data);\n snapshot.set(rel, entry.data);\n }\n\n const state: TreelayState = {\n lock: lockFromGraph(graph),\n answers: values,\n baseline,\n manifest,\n };\n writeState(options.destDir, state, graph.variables, snapshot);\n\n // Record any pins this build discovered, so the next one reproduces it.\n if (options.writeLockfile !== false && graph.lockDirty && graph.lockDir && graph.lock) {\n writeLock(graph.lockDir, graph.lock);\n }\n\n return result;\n}\n\n/** Apply a single layer's files, then its ops, onto the accumulator. */\nasync function applyLayer(\n layer: Layer,\n acc: Map<string, FileEntry>,\n values: Values,\n destDir?: string,\n): Promise<void> {\n const suffix = layer.manifest.templateSuffix ?? DEFAULT_TEMPLATE_SUFFIX;\n const renderAllText = layer.manifest.render === \"all-text\";\n const arrays = layer.manifest.arrays ?? \"replace\";\n\n const entries = fg.sync(\"**/*\", {\n cwd: layer.dir,\n dot: true,\n onlyFiles: true,\n // A destination nested inside this layer is pruned so a recompile never\n // folds its own prior output back in (§7).\n ignore: [\n ...ALWAYS_IGNORE,\n ...(layer.manifest.ignore ?? []),\n ...destExclusions(layer.dir, destDir),\n ],\n });\n\n const ops: Op[] = [];\n\n for (const rel of entries.sort()) {\n const raw = readFileSync(join(layer.dir, rel));\n // The template suffix is outermost: strip-and-render first, then look at the\n // inner name to see whether it's a sidecar / suffix-op / plain file.\n const { render: isTmpl, outPath: inner } = templateTarget(rel, suffix);\n\n if (isSidecar(inner)) {\n const op = sidecarToOp(raw.toString(\"utf8\"), inner, isTmpl, values);\n op.target = mountTarget(layer, op.target);\n ops.push(op);\n continue;\n }\n\n const sugar = desugarSuffix(inner);\n if (sugar) {\n ops.push({\n kind: sugar.op,\n target: mountTarget(layer, await renderPath(sugar.target, values)),\n render: isTmpl,\n content: raw.toString(\"utf8\"),\n });\n continue;\n }\n\n // Plain file. Render the path always (when it has markup), the content only\n // when it opted in via the suffix (or the layer is render: all-text).\n // Emptiness is decided before the mount prefix goes on: a conditional file\n // that rendered away is still dropped when the layer is mounted (§6 step 7).\n const rendered = await renderPath(inner, values);\n if (rendered.trim() === \"\") continue;\n const target = mountTarget(layer, rendered);\n\n const doRenderContent = isTmpl || (renderAllText && looksTextual(inner));\n const data = doRenderContent\n ? Buffer.from(await renderString(raw.toString(\"utf8\"), values), \"utf8\")\n : raw;\n\n mergeFile(acc, target, data, layer, arrays);\n }\n\n for (const op of ops) await applyOp(acc, op, values);\n}\n\n/** Render a relative path through Liquid when it carries markup. */\nasync function renderPath(path: string, values: Values): Promise<string> {\n return needsRender(path) ? renderString(path, values) : path;\n}\n\n/** Parse a sidecar's YAML (optionally rendered) into a normalized Op. */\nfunction sidecarToOp(\n yamlText: string,\n innerPath: string,\n isTmpl: boolean,\n _values: Values,\n): Op {\n const sc: SidecarOp = parseSidecar(yamlText);\n const op: Op = {\n kind: sc.op,\n target: sidecarTarget(innerPath),\n render: sc.render ?? false,\n };\n if (sc.when !== undefined) op.when = sc.when;\n if (sc.base !== undefined) op.base = sc.base;\n if (sc.baseContent !== undefined) op.baseContent = sc.baseContent;\n if (sc.content !== undefined) op.content = sc.content;\n if (sc.merge !== undefined) op.merge = sc.merge;\n if (sc.jsonPatch !== undefined) op.jsonPatch = sc.jsonPatch;\n if (sc.patch !== undefined) op.content = sc.patch; // unified-diff payload (§5)\n // `isTmpl` (the sidecar file itself was *.tmpl) is reserved for rendering the\n // YAML before parse; sidecars are rarely templated, so we keep it simple.\n void isTmpl;\n return op;\n}\n\n/** Merge a plain file's data into the accumulator under its target path. */\nfunction mergeFile(\n acc: Map<string, FileEntry>,\n target: string,\n data: Buffer,\n layer: Layer,\n arrays: Layer[\"manifest\"][\"arrays\"],\n): void {\n const strategy = strategyFor(target, layer.manifest.merge);\n const existing = acc.get(target);\n\n if (!existing) {\n acc.set(target, { data, strategy, fromLayer: layer.id, patchedFrom: [] });\n return;\n }\n\n switch (strategy) {\n case \"replace\":\n existing.data = data;\n existing.fromLayer = layer.id;\n existing.strategy = strategy;\n break;\n case \"deep-merge\": {\n const merged = deepMerge(\n parseStructured(target, existing.data.toString(\"utf8\")),\n parseStructured(target, data.toString(\"utf8\")),\n arrays ?? \"replace\",\n );\n existing.data = Buffer.from(stringifyStructured(target, merged), \"utf8\");\n existing.patchedFrom.push(existing.fromLayer);\n existing.fromLayer = layer.id;\n existing.strategy = strategy;\n break;\n }\n case \"append\":\n existing.data = Buffer.concat([existing.data, data]);\n existing.patchedFrom.push(layer.id);\n break;\n case \"prepend\":\n existing.data = Buffer.concat([data, existing.data]);\n existing.patchedFrom.push(layer.id);\n break;\n case \"delete\":\n acc.delete(target);\n break;\n case \"patch\":\n // The glob declared this path's files to *be* unified diffs, so the\n // higher layer's content is a patch onto the inherited file. No recorded\n // base is possible here (a plain file carries no metadata), so this is\n // best-effort apply — the sidecar form exists for when that matters.\n existing.data = Buffer.from(\n applyPatch3Way({\n file: target,\n current: existing.data.toString(\"utf8\"),\n patch: data.toString(\"utf8\"),\n }),\n \"utf8\",\n );\n existing.strategy = \"patch\";\n existing.patchedFrom.push(layer.id);\n break;\n }\n}\n\n/** Apply a sidecar/suffix operation onto the accumulator (§4). */\nasync function applyOp(\n acc: Map<string, FileEntry>,\n op: Op,\n values: Values,\n): Promise<void> {\n if (op.when !== undefined) {\n const w = (await renderString(op.when, values)).trim();\n if (w === \"\" || w === \"false\") return; // conditional op skipped\n }\n\n const existing = acc.get(op.target);\n const content =\n op.content !== undefined && op.render\n ? await renderString(op.content, values)\n : op.content;\n\n switch (op.kind) {\n case \"delete\":\n acc.delete(op.target);\n return;\n\n case \"replace\": {\n const data = Buffer.from(content ?? \"\", \"utf8\");\n if (existing) {\n existing.data = data;\n existing.patchedFrom.push(\"sidecar\");\n } else {\n acc.set(op.target, {\n data,\n strategy: \"replace\",\n fromLayer: \"sidecar\",\n patchedFrom: [],\n });\n }\n return;\n }\n\n case \"append\":\n case \"prepend\": {\n const add = Buffer.from(content ?? \"\", \"utf8\");\n const base = existing?.data ?? Buffer.alloc(0);\n const data =\n op.kind === \"append\"\n ? Buffer.concat([base, add])\n : Buffer.concat([add, base]);\n if (existing) {\n existing.data = data;\n existing.patchedFrom.push(\"sidecar\");\n } else {\n acc.set(op.target, {\n data,\n strategy: op.kind,\n fromLayer: \"sidecar\",\n patchedFrom: [],\n });\n }\n return;\n }\n\n case \"merge\": {\n // Structured patch (RFC 7386 merge / RFC 6902 json-patch) onto the file.\n const baseData = existing\n ? parseStructured(op.target, existing.data.toString(\"utf8\"))\n : {};\n const result = op.jsonPatch\n ? applyJsonPatch(baseData, op.jsonPatch)\n : applyMergePatch(baseData, op.merge ?? {});\n setStructured(acc, op, existing, result);\n return;\n }\n\n case \"patch\": {\n // A patch edits an inherited file; with nothing to inherit there is no\n // \"super()\" to call, so this is an authoring error, not a silent create.\n if (!existing) {\n throw new MergeConflictError(\n op.target,\n \"patch has nothing to apply to — the file is not produced by any \" +\n \"lower layer (never created, or removed by a tombstone). \" +\n \"Ship the full file instead of a patch, or drop the tombstone.\",\n );\n }\n const current = existing.data.toString(\"utf8\");\n existing.data = Buffer.from(\n applyPatch3Way({\n file: op.target,\n current,\n patch: content ?? \"\",\n ...resolvePatchBase(op, current),\n }),\n \"utf8\",\n );\n existing.strategy = \"patch\";\n existing.patchedFrom.push(\"sidecar\");\n return;\n }\n }\n}\n\n/**\n * Decide what base content (if any) a patch can be reconciled against (§5).\n *\n * - Explicit `baseContent` wins, and its hash is verified when `base` is also\n * recorded — a mismatch means the sidecar contradicts itself.\n * - Otherwise a recorded `base` hash that still matches the inherited file\n * proves the file has not drifted, so the file *is* the base and the patch is\n * guaranteed to apply.\n * - A recorded hash that no longer matches means drift with no way to\n * reconstruct the original, so we hand back no base: `applyPatch3Way` then\n * relocates what it can and fails loud on the rest, rather than blindly\n * applying a patch we know was authored against different content.\n */\nfunction resolvePatchBase(op: Op, current: string): { base?: string } {\n if (op.baseContent !== undefined) {\n if (op.base !== undefined && hashContent(op.baseContent) !== op.base.trim()) {\n throw new MergeConflictError(\n op.target,\n `sidecar is inconsistent: \\`baseContent\\` hashes to ` +\n `${hashContent(op.baseContent)} but \\`base\\` records ${op.base}.`,\n );\n }\n return { base: op.baseContent };\n }\n if (op.base !== undefined && hashContent(current) === op.base.trim()) {\n return { base: current };\n }\n return {};\n}\n\n/** Write a structured (parsed) value back into the accumulator. */\nfunction setStructured(\n acc: Map<string, FileEntry>,\n op: Op,\n existing: FileEntry | undefined,\n value: unknown,\n): void {\n const data = Buffer.from(stringifyStructured(op.target, value), \"utf8\");\n if (existing) {\n existing.data = data;\n existing.patchedFrom.push(\"sidecar\");\n } else {\n acc.set(op.target, {\n data,\n strategy: \"deep-merge\",\n fromLayer: \"sidecar\",\n patchedFrom: [],\n });\n }\n}\n\n/** Coarse text/binary guess by extension, for `render: all-text` mode. */\nfunction looksTextual(path: string): boolean {\n return !/\\.(png|jpe?g|gif|webp|ico|pdf|woff2?|ttf|zip|gz|tar|exe|bin)$/i.test(\n path,\n );\n}\n\n// Re-exported for callers that need the sidecar suffix constant alongside compile.\nexport { SIDECAR_SUFFIX };\n","/**\n * Structured-file (de)serialization by extension — SPEC §4.\n *\n * Deep-merge and the sidecar `merge`/`jsonPatch` ops operate on parsed data, but\n * files live on disk as text. These helpers round-trip JSON and YAML while\n * preserving the source's indentation flavor as best as is reasonable.\n */\n\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\n\nexport type StructuredFormat = \"json\" | \"yaml\";\n\n/** Detect the structured format of a path, or `undefined` if it isn't one. */\nexport function structuredFormat(path: string): StructuredFormat | undefined {\n if (/\\.json$/i.test(path)) return \"json\";\n if (/\\.ya?ml$/i.test(path)) return \"yaml\";\n return undefined;\n}\n\n/** Parse structured text into data, per the path's format. */\nexport function parseStructured(path: string, text: string): unknown {\n const fmt = structuredFormat(path);\n if (fmt === \"json\") return text.trim() === \"\" ? {} : JSON.parse(text);\n if (fmt === \"yaml\") return parseYaml(text) ?? {};\n throw new Error(`Not a structured file: ${path}`);\n}\n\n/** Serialize data back to text, per the path's format (JSON keeps 2-space indent). */\nexport function stringifyStructured(path: string, data: unknown): string {\n const fmt = structuredFormat(path);\n if (fmt === \"json\") return JSON.stringify(data, null, 2) + \"\\n\";\n if (fmt === \"yaml\") return stringifyYaml(data);\n throw new Error(`Not a structured file: ${path}`);\n}\n","/**\n * Upstream drift — has a ref moved since the lock pinned it? (SPEC §3, §9)\n *\n * Drift is *reported*, never acted on. A build whose lock says `abc123` keeps\n * producing `abc123` even after `main` advances; that is the entire point of\n * pinning. What treelay owes the user is that the divergence is visible —\n * `explain` annotates the layer, `update` says so before merging, and\n * `treelay lock --update` is the one command that advances a pin.\n *\n * The probe is best-effort by construction. Being offline, lacking credentials,\n * or having deleted the package makes the current revision *unknown*, which is\n * a distinct answer from \"unchanged\" and is presented as one.\n */\n\nimport { liveRevision } from \"./fetch/index.js\";\nimport type { TreelayLock } from \"./lockfile.js\";\nimport { parseRef, type RemoteRef } from \"./refs.js\";\nimport type { Layer, ResolvedGraph } from \"./types.js\";\n\n/** Whether a pinned ref still matches its upstream. */\nexport type DriftStatus = \"in-sync\" | \"moved\" | \"unknown\" | \"immutable\";\n\n/** One ref's drift verdict. */\nexport interface DriftReport {\n /** Canonical ref (the lockfile key). */\n ref: string;\n /** What was asked for — branch, tag, or semver range. */\n requested: string;\n /** The revision the lock pins, and what any build here materializes. */\n locked: string;\n /** What the ref points at now; undefined when it could not be determined. */\n current?: string;\n status: DriftStatus;\n /** Layers composed from this ref, for a message that names names. */\n layers: string[];\n}\n\n/** Has anything actually moved? (unknown is not drift — it is ignorance). */\nexport function hasDrift(reports: readonly DriftReport[]): boolean {\n return reports.some((r) => r.status === \"moved\");\n}\n\n/**\n * Check every pinned ref in a resolved graph against its upstream.\n *\n * Contacts the network once per distinct ref, so callers should treat it as an\n * explicit action rather than something to fold into a hot path.\n */\nexport function checkDrift(graph: ResolvedGraph, fromDir?: string): DriftReport[] {\n const lock = graph.lock;\n if (!lock) return [];\n\n const anchor = fromDir ?? graph.lockDir ?? process.cwd();\n const reports: DriftReport[] = [];\n\n for (const key of Object.keys(lock.refs).sort()) {\n const entry = lock.refs[key]!;\n const layers = graph.layers\n .filter((l: Layer) => l.origin?.ref === key)\n .map((l) => l.manifest.name ?? l.id);\n\n const parsed = parseRef(key) as RemoteRef;\n // A ref written as an exact commit or exact version cannot move; saying\n // \"in sync\" would imply we checked something that has no upstream question.\n const immutable =\n (parsed.kind === \"git\" && parsed.committish === entry.resolved) ||\n (parsed.kind === \"npm\" && parsed.range === entry.resolved);\n\n const current = immutable ? entry.resolved : liveRevision(parsed, anchor);\n const status: DriftStatus = immutable\n ? \"immutable\"\n : current === undefined\n ? \"unknown\"\n : current === entry.resolved\n ? \"in-sync\"\n : \"moved\";\n\n reports.push({\n ref: key,\n requested: entry.requested,\n locked: entry.resolved,\n ...(current !== undefined ? { current } : {}),\n status,\n layers,\n });\n }\n return reports;\n}\n\n/** Short revision for display; npm versions are already short. */\nfunction short(rev: string): string {\n return /^[0-9a-f]{40}$/i.test(rev) ? rev.slice(0, 12) : rev;\n}\n\n/** Human-readable drift summary. Empty string when nothing has moved. */\nexport function formatDrift(reports: readonly DriftReport[]): string {\n const moved = reports.filter((r) => r.status === \"moved\");\n if (!moved.length) return \"\";\n\n const lines = moved.map((r) => {\n const who = r.layers.length ? ` (${r.layers.join(\", \")})` : \"\";\n return (\n ` ${r.ref}\\n` +\n ` pinned ${short(r.locked)}\\n` +\n ` ${r.requested} is now ${short(r.current!)}${who}`\n );\n });\n return (\n `${moved.length} ref(s) have moved upstream since treelay.lock was written:\\n` +\n lines.join(\"\\n\") +\n `\\nThis build used the pinned revisions. Run \\`treelay lock --update\\` to advance them.`\n );\n}\n","/**\n * Living-template update — SPEC §7.\n *\n * Reloads saved answers (prompting only for newly-introduced variables),\n * recompiles `theirs`, and three-way merges against the baseline (`base`) and\n * the working copy (`ours`), then rewrites the baseline.\n *\n * The whole resolution is computed before anything is written. `update` touches\n * a project the user has been working in, so a failure partway through must\n * leave that project exactly as it was rather than half-updated.\n */\n\nimport {\n existsSync,\n readFileSync,\n rmSync,\n writeFileSync,\n statSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport { composeFiles, summarize, type FileEntry } from \"./compile.js\";\nimport { checkDrift, type DriftReport } from \"./drift.js\";\nimport { hashContent } from \"./hash.js\";\nimport { mergeText3 } from \"./merge/patch.js\";\nimport { mergeStructured3 } from \"./merge/structured.js\";\nimport { resolve } from \"./resolve.js\";\nimport { parseStructured, stringifyStructured, structuredFormat } from \"./serde.js\";\nimport {\n readState,\n readBaselineFile,\n writeState,\n lockFromGraph,\n ensureDir,\n sourceOf,\n type LockFile,\n type TreelayState,\n} from \"./state.js\";\nimport { resolveValues } from \"./variables.js\";\nimport type { Values, VariableDecl } from \"./types.js\";\n\n/** How each file was resolved. */\nexport type Resolution =\n | \"take-theirs\"\n | \"keep-ours\"\n | \"merged\"\n | \"conflict\"\n | \"delete\"\n /** All three sides agree — nothing to do. Lets a no-op update say so. */\n | \"unchanged\";\n\nexport interface UpdateOptions {\n /**\n * How conflicts are surfaced:\n * - `markers` (default) — write the merged file with diff3 conflict markers.\n * - `rej` — leave the working file untouched and drop the incoming version\n * beside it as `<file>.rej`, for projects where a file must stay parseable.\n */\n onConflict?: \"markers\" | \"rej\";\n /** CLI `--set k=v` overrides applied over saved answers. */\n set?: Record<string, unknown>;\n /** Prompt for variables the new template version introduced (default true). */\n prompt?: boolean;\n /** Refuse to resolve refs `treelay.lock` does not pin (§3). */\n frozen?: boolean;\n}\n\nexport interface UpdatePlan {\n /** Per file: the resolution that update would apply. */\n files: Record<string, Resolution>;\n /** Paths that could not be merged cleanly. */\n conflicts: string[];\n /** Variables the new template version introduced and now has answers for. */\n newVariables: string[];\n /**\n * Pinned refs whose upstream has moved since `treelay.lock` was written (§3).\n *\n * Reported, never followed. An update that silently recomposed at a newer\n * revision because a branch advanced would make \"pull my template's changes\n * down\" mean two different things depending on the day.\n */\n drift: DriftReport[];\n}\n\n/** One file's decided outcome, held in memory until the whole plan is known. */\ninterface Decision {\n path: string;\n resolution: Resolution;\n /** Content to write at `path`, when the resolution produces one. */\n write?: Buffer;\n /** Content to write at `path.rej` (conflict, `rej` mode). */\n rej?: Buffer;\n /** Remove the file from the working tree. */\n remove?: boolean;\n}\n\n/** A NUL byte is the usual signal that text merging would be meaningless. */\nfunction isBinary(data: Buffer): boolean {\n return data.includes(0);\n}\n\n/**\n * Merge one file's three versions.\n *\n * Text merging runs first even for JSON/YAML, because it preserves the file's\n * formatting and comments. Only when it conflicts do we retry structurally,\n * where two sides editing unrelated keys merge cleanly regardless of how close\n * those keys sit in the file — at the cost of reserializing (§7).\n */\nfunction mergeOne(\n path: string,\n base: string,\n ours: string,\n theirs: string,\n): { clean: boolean; text: string } {\n const text = mergeText3({ base, ours, theirs });\n if (text.clean) return text;\n\n if (structuredFormat(path)) {\n try {\n const merged = mergeStructured3(\n parseStructured(path, base),\n parseStructured(path, ours),\n parseStructured(path, theirs),\n );\n if (merged.clean) {\n return { clean: true, text: stringifyStructured(path, merged.value) };\n }\n } catch {\n // Unparseable on some side (often because a previous update left markers\n // in it) — the text merge's conflict output stands.\n }\n }\n return text;\n}\n\n/** Compute every file's outcome without touching the working tree. */\nasync function planFrom(\n destDir: string,\n options: UpdateOptions,\n): Promise<{\n decisions: Decision[];\n plan: UpdatePlan;\n theirs: Map<string, FileEntry>;\n values: Values;\n state: TreelayState;\n destLock: LockFile;\n variables: Record<string, VariableDecl>;\n}> {\n const state = readState(destDir);\n const src = sourceOf(state);\n if (!src) {\n throw new Error(\n `${destDir}: .treelay/lock.json records no lineage, so there is no ` +\n `template to update from. Recompile with \\`treelay compile <src> ${destDir}\\`.`,\n );\n }\n if (!existsSync(src) || !statSync(src).isDirectory()) {\n throw new Error(\n `${destDir}: the template it was compiled from is gone (${src}). ` +\n `Restore it, or recompile from its new location.`,\n );\n }\n\n const graph = resolve(src, options.frozen ? { frozen: true } : {});\n\n // Saved answers are pre-supplied, so `resolveValues` only prompts for\n // variables the new template version added (§7).\n const newVariables = Object.keys(graph.variables).filter(\n (name) => !(name in state.answers),\n );\n const values = await resolveValues(graph, {\n answers: state.answers,\n ...(options.set ? { set: options.set } : {}),\n prompt: options.prompt !== false,\n });\n\n const theirs = await composeFiles(graph, values, destDir);\n\n const decisions: Decision[] = [];\n const files: Record<string, Resolution> = {};\n const conflicts: string[] = [];\n\n const paths = [\n ...new Set([...Object.keys(state.baseline), ...theirs.keys()]),\n ].sort();\n\n for (const path of paths) {\n const decision = decide(destDir, path, state, theirs, options);\n decisions.push(decision);\n files[path] = decision.resolution;\n if (decision.resolution === \"conflict\") conflicts.push(path);\n }\n\n return {\n decisions,\n plan: { files, conflicts, newVariables, drift: checkDrift(graph) },\n theirs,\n values,\n state,\n destLock: lockFromGraph(graph),\n variables: graph.variables,\n };\n}\n\n/** Resolve a single path against base / ours / theirs (§7's case table). */\nfunction decide(\n destDir: string,\n path: string,\n state: TreelayState,\n theirsMap: Map<string, FileEntry>,\n options: UpdateOptions,\n): Decision {\n const baseHash = state.baseline[path];\n const theirsEntry = theirsMap.get(path);\n const abs = join(destDir, path);\n const ours = existsSync(abs) ? readFileSync(abs) : undefined;\n\n // The template no longer produces this file.\n if (!theirsEntry) {\n if (!ours) return { path, resolution: \"unchanged\" };\n if (baseHash !== undefined && hashContent(ours) === baseHash) {\n return { path, resolution: \"delete\", remove: true };\n }\n // Edited locally and removed upstream — dropping it would discard the\n // user's work silently, so make them decide.\n return conflictOver(path, ours, undefined, options);\n }\n\n const theirs = theirsEntry.data;\n\n // Newly introduced by the template.\n if (baseHash === undefined) {\n if (!ours) return { path, resolution: \"take-theirs\", write: theirs };\n if (ours.equals(theirs)) return { path, resolution: \"unchanged\" };\n // The user already had a file where the template now wants to put one.\n return conflictOver(path, ours, theirs, options);\n }\n\n if (!ours) {\n // Deleted locally. If the template didn't change it, respect the deletion.\n if (hashContent(theirs) === baseHash) return { path, resolution: \"keep-ours\" };\n return conflictOver(path, undefined, theirs, options);\n }\n\n const oursUnchanged = hashContent(ours) === baseHash;\n const theirsUnchanged = hashContent(theirs) === baseHash;\n\n if (oursUnchanged && theirsUnchanged) return { path, resolution: \"unchanged\" };\n if (oursUnchanged) return { path, resolution: \"take-theirs\", write: theirs };\n if (theirsUnchanged) return { path, resolution: \"keep-ours\" };\n if (ours.equals(theirs)) return { path, resolution: \"unchanged\" };\n\n // Both sides changed. Merge if we can read all three as text — and only if\n // the snapshot still matches the recorded hash, so a stale base becomes a\n // conflict rather than a silently wrong merge.\n const base = readBaselineFile(destDir, path, baseHash);\n if (!base || isBinary(base) || isBinary(ours) || isBinary(theirs)) {\n return conflictOver(path, ours, theirs, options);\n }\n\n const merged = mergeOne(\n path,\n base.toString(\"utf8\"),\n ours.toString(\"utf8\"),\n theirs.toString(\"utf8\"),\n );\n if (merged.clean) {\n return { path, resolution: \"merged\", write: Buffer.from(merged.text, \"utf8\") };\n }\n return conflictOver(path, ours, theirs, options, Buffer.from(merged.text, \"utf8\"));\n}\n\n/**\n * Build a conflict decision honouring `onConflict`. In `markers` mode the\n * merged-with-markers text is written in place; in `rej` mode the working file\n * is left exactly as it is and the incoming version lands at `<path>.rej`.\n */\nfunction conflictOver(\n path: string,\n ours: Buffer | undefined,\n theirs: Buffer | undefined,\n options: UpdateOptions,\n markers?: Buffer,\n): Decision {\n if ((options.onConflict ?? \"markers\") === \"rej\") {\n return {\n path,\n resolution: \"conflict\",\n ...(ours ? {} : { write: Buffer.alloc(0) }),\n ...(theirs ? { rej: theirs } : { rej: Buffer.alloc(0) }),\n };\n }\n // Markers mode needs something to write; without a mergeable pair (a delete\n // conflict, or binary) fall back to the incoming version so the change is at\n // least visible, or keep ours when there is no incoming content.\n const write = markers ?? theirs ?? ours;\n return { path, resolution: \"conflict\", ...(write ? { write } : {}) };\n}\n\n/** Dry-run: compute the per-file 3-way resolution without writing (§10). */\nexport async function planUpdate(\n destDir: string,\n options: UpdateOptions = {},\n): Promise<UpdatePlan> {\n // Never prompt on a dry run — a plan should not have side effects.\n const { plan } = await planFrom(destDir, { ...options, prompt: false });\n return plan;\n}\n\n/** Apply a template update into an existing destination. */\nexport async function update(\n destDir: string,\n options: UpdateOptions = {},\n): Promise<UpdatePlan> {\n const { decisions, plan, theirs, values, variables, destLock } = await planFrom(\n destDir,\n options,\n );\n\n // Everything above is pure. Only now do we touch the project.\n for (const d of decisions) {\n const abs = join(destDir, d.path);\n if (d.remove) {\n rmSync(abs, { force: true });\n continue;\n }\n if (d.write) {\n ensureDir(abs);\n writeFileSync(abs, d.write);\n }\n if (d.rej) {\n ensureDir(abs);\n writeFileSync(abs + \".rej\", d.rej);\n }\n }\n\n // The baseline records what the template last produced, which is `theirs`\n // regardless of how each merge landed. Advancing it unconditionally is what\n // makes a repeated update a no-op, and stops a conflict from being re-offered\n // every single time.\n const { baseline, manifest } = summarize(theirs);\n const snapshot = new Map<string, Buffer>();\n for (const [rel, entry] of theirs) snapshot.set(rel, entry.data);\n\n writeState(\n destDir,\n { lock: destLock, answers: values, baseline, manifest },\n variables,\n snapshot,\n );\n\n return plan;\n}\n","/**\n * `explain` — per-file provenance across the layer stack (SPEC §9, §12 step 7).\n *\n * The debugging story for a system whose whole job is \"this file came from\n * somewhere non-obvious\": for every output path, which layers contributed, via\n * which strategy, in what precedence order, and which one won.\n *\n * Read-only. It walks the same enumeration as `compile` (see `layer-files.ts`)\n * and mirrors its accumulation bookkeeping — `winner`/`strategy`/`patchedFrom`\n * are defined to match `CompileResult.files[path]` exactly, and a test asserts\n * that equivalence so the two cannot drift apart silently.\n *\n * Unlike compile, explain never throws on a not-yet-implemented strategy: a\n * unified-diff patch is *described* rather than applied, so `explain` stays\n * useful precisely where a build is failing.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { basename, join, resolve as resolvePath } from \"node:path\";\n\nimport { enumerateLayer, mountTarget, type LayerEntry } from \"./layer-files.js\";\nimport { parseSidecar } from \"./sidecar.js\";\nimport { renderString } from \"./render.js\";\nimport { strategyFor } from \"./merge/index.js\";\nimport { resolve as resolveGraph } from \"./resolve.js\";\nimport { canonicalRef, parseRef } from \"./refs.js\";\nimport { readState, hasState } from \"./state.js\";\nimport type {\n Layer,\n MergeStrategy,\n ResolvedGraph,\n SidecarOpKind,\n Values,\n} from \"./types.js\";\n\n/** Why a layer is in the stack (§1, §3). */\nexport type LayerRole = \"parent\" | \"mixin\" | \"self\" | \"mount\";\n\n/** What a contribution did to the accumulating file. */\nexport type ContributionAction =\n | \"create\"\n | \"replace\"\n | \"deep-merge\"\n | \"append\"\n | \"prepend\"\n | \"delete\"\n | \"merge\"\n | \"patch\";\n\n/** A layer's position and identity within the resolved stack. */\nexport interface LayerSummary {\n id: string;\n name: string;\n role: LayerRole;\n /** 1-based position, lowest precedence first. */\n position: number;\n writable: boolean;\n /** Canonical ref this layer was fetched from (§3); absent for local layers. */\n ref?: string;\n /** Exact revision materialized — commit SHA or package version. */\n revision?: string;\n /** Subpath a mounted layer's files are re-rooted under (§3). */\n mountPath?: string;\n}\n\n/** One layer's contribution to one output path. */\nexport interface Contribution {\n layer: string;\n name: string;\n role: LayerRole;\n position: number;\n /** Source file within the layer that produced this contribution. */\n source: string;\n action: ContributionAction;\n /** How the file would be combined at this step (§4). */\n strategy: MergeStrategy;\n kind: LayerEntry[\"kind\"];\n /** Recorded base hash from a sidecar, enabling true 3-way merge (§5). */\n base?: string;\n /** True when a `when:` guard evaluated falsy and the op was skipped (§4). */\n skipped?: boolean;\n /** Human note (unsupported strategy, unrendered path, …). */\n note?: string;\n}\n\n/** The full provenance of one output path. */\nexport interface FileExplanation {\n path: string;\n /** In precedence order, lowest → highest. */\n contributions: Contribution[];\n /** Whether the file survives to the output (false ⇒ tombstoned). */\n present: boolean;\n /** Layer id whose content won — mirrors `CompileResult.files[path].fromLayer`. */\n winner?: string;\n /** Winning strategy — mirrors `CompileResult.files[path].strategy`. */\n strategy?: MergeStrategy;\n /** Layers whose patches/merges were folded in — mirrors `patchedFrom`. */\n patchedFrom: string[];\n /** True for a destination file with no template origin (user-owned, §7). */\n owned?: boolean;\n}\n\n/** The whole composition, explained. */\nexport interface ExplainResult {\n layers: LayerSummary[];\n /** Keyed by output path, insertion-ordered by path. */\n files: Record<string, FileExplanation>;\n}\n\nexport interface ExplainOptions {\n /** Variable values used to render templated paths and `when:` guards (§6). */\n values?: Values;\n /** A destination nested inside a layer, pruned from the walk (§7). */\n destDir?: string;\n}\n\n/** Mutable per-path state while walking the stack — mirrors compile's FileEntry. */\ninterface Live {\n strategy: MergeStrategy;\n fromLayer: string;\n patchedFrom: string[];\n}\n\n/** Classify each layer by why it is in the stack. */\nexport function summarizeLayers(graph: ResolvedGraph): LayerSummary[] {\n const self = graph.layers[graph.layers.length - 1];\n\n // Classification is done by *identity*, never by re-resolving. A remote ref\n // resolved a second time here could land on a different commit than the graph\n // was built from — and would hit the network to do it, in a read-only\n // command. A layer's id already is its absolute dir (local) or its canonical\n // ref (fetched), so matching against that is both exact and free.\n const mixinIds = new Set<string>();\n if (self) {\n for (const ref of self.manifest.mixins ?? []) {\n try {\n const parsed = parseRef(ref);\n mixinIds.add(\n parsed.kind === \"local\"\n ? resolvePath(self.dir, parsed.path)\n : canonicalRef(parsed),\n );\n } catch {\n // An unparseable ref simply stays unclassified; explain never throws.\n }\n }\n }\n\n return graph.layers.map((layer, i) => ({\n id: layer.id,\n name: displayName(layer),\n role: layer.mountPath\n ? \"mount\"\n : layer === self\n ? \"self\"\n : mixinIds.has(layer.id)\n ? \"mixin\"\n : \"parent\",\n position: i + 1,\n writable: layer.writable,\n ...(layer.origin?.ref ? { ref: layer.origin.ref } : {}),\n ...(layer.origin?.revision ? { revision: layer.origin.revision } : {}),\n ...(layer.mountPath ? { mountPath: layer.mountPath } : {}),\n }));\n}\n\nfunction displayName(layer: Layer): string {\n // A fetched layer's directory is a cache path, which says nothing useful; its\n // manifest name, or failing that its ref, is what a reader recognizes.\n if (layer.manifest.name) return layer.manifest.name;\n if (layer.mountPath) return `${layer.mountPath}/`;\n return layer.origin?.ref ?? basename(layer.dir);\n}\n\n/** Render a path through Liquid, tolerating missing values (explain is read-only). */\nasync function tryRenderPath(\n path: string,\n values: Values,\n): Promise<{ path: string; note?: string }> {\n if (!path.includes(\"{{\") && !path.includes(\"{%\")) return { path };\n try {\n return { path: await renderString(path, values) };\n } catch {\n // `plan`-style usage without answers: describe the template, don't fail.\n return { path, note: \"path left unrendered (no value for its variables)\" };\n }\n}\n\n/** Explain every output path produced by a resolved graph. */\nexport async function explain(\n graph: ResolvedGraph,\n options: ExplainOptions = {},\n): Promise<ExplainResult> {\n const values = options.values ?? {};\n const summaries = summarizeLayers(graph);\n const live = new Map<string, Live>();\n const history = new Map<string, Contribution[]>();\n const deleted = new Set<string>();\n\n const record = (target: string, c: Contribution) => {\n const list = history.get(target);\n if (list) list.push(c);\n else history.set(target, [c]);\n };\n\n for (const [i, layer] of graph.layers.entries()) {\n const summary = summaries[i]!;\n const arrays = layer.manifest.arrays ?? \"replace\";\n void arrays; // array policy affects bytes, not provenance\n const entries = enumerateLayer(layer, options.destDir);\n\n // Two passes per layer, matching compile: plain files first, then ops.\n const ops: LayerEntry[] = [];\n\n for (const entry of entries) {\n if (entry.kind !== \"file\") {\n ops.push(entry);\n continue;\n }\n\n const rendered = await tryRenderPath(entry.rawTarget, values);\n if (rendered.path.trim() === \"\") continue; // conditional file dropped (§6 step 7)\n const target = mountTarget(layer, rendered.path);\n\n const strategy = strategyFor(target, layer.manifest.merge);\n const existing = live.get(target);\n const base: Omit<Contribution, \"action\"> = {\n layer: layer.id,\n name: summary.name,\n role: summary.role,\n position: summary.position,\n source: entry.source,\n strategy,\n kind: entry.kind,\n ...(rendered.note ? { note: rendered.note } : {}),\n };\n\n if (!existing) {\n live.set(target, { strategy, fromLayer: layer.id, patchedFrom: [] });\n deleted.delete(target);\n record(target, { ...base, action: \"create\" });\n continue;\n }\n\n switch (strategy) {\n case \"replace\":\n existing.fromLayer = layer.id;\n existing.strategy = strategy;\n record(target, { ...base, action: \"replace\" });\n break;\n case \"deep-merge\":\n existing.patchedFrom.push(existing.fromLayer);\n existing.fromLayer = layer.id;\n existing.strategy = strategy;\n record(target, { ...base, action: \"deep-merge\" });\n break;\n case \"append\":\n case \"prepend\":\n existing.patchedFrom.push(layer.id);\n record(target, { ...base, action: strategy });\n break;\n case \"delete\":\n live.delete(target);\n deleted.add(target);\n record(target, { ...base, action: \"delete\" });\n break;\n case \"patch\":\n record(target, {\n ...base,\n action: \"patch\",\n note: \"unified-diff patch via merge glob (§5) — described, not applied\",\n });\n break;\n }\n }\n\n for (const entry of ops) {\n await explainOp(entry, layer, summary, values, live, deleted, record);\n }\n }\n\n // Assemble, sorted by path for stable output.\n const files: Record<string, FileExplanation> = {};\n for (const path of [...history.keys()].sort()) {\n const state = live.get(path);\n files[path] = {\n path,\n contributions: history.get(path)!,\n present: state !== undefined,\n patchedFrom: state?.patchedFrom ?? [],\n ...(state ? { winner: state.fromLayer, strategy: state.strategy } : {}),\n };\n }\n\n return { layers: summaries, files };\n}\n\n/** Explain one sidecar/suffix op, mirroring compile's `applyOp` bookkeeping. */\nasync function explainOp(\n entry: LayerEntry,\n layer: Layer,\n summary: LayerSummary,\n values: Values,\n live: Map<string, Live>,\n deleted: Set<string>,\n record: (target: string, c: Contribution) => void,\n): Promise<void> {\n let op: SidecarOpKind | undefined = entry.op;\n let baseHash: string | undefined;\n let when: string | undefined;\n\n if (entry.kind === \"sidecar\") {\n try {\n const sc = parseSidecar(readFileSync(join(layer.dir, entry.source), \"utf8\"));\n op = sc.op;\n baseHash = sc.base;\n when = sc.when;\n } catch (err) {\n record(mountTarget(layer, entry.rawTarget), {\n layer: layer.id,\n name: summary.name,\n role: summary.role,\n position: summary.position,\n source: entry.source,\n action: \"replace\",\n strategy: \"replace\",\n kind: entry.kind,\n skipped: true,\n note: `unreadable sidecar: ${err instanceof Error ? err.message : String(err)}`,\n });\n return;\n }\n }\n if (!op) return;\n\n const rendered = await tryRenderPath(entry.rawTarget, values);\n const target = mountTarget(layer, rendered.path);\n\n const contribution: Contribution = {\n layer: layer.id,\n name: summary.name,\n role: summary.role,\n position: summary.position,\n source: entry.source,\n action: op as ContributionAction,\n strategy: op === \"merge\" ? \"deep-merge\" : (op as MergeStrategy),\n kind: entry.kind,\n ...(baseHash ? { base: baseHash } : {}),\n ...(rendered.note ? { note: rendered.note } : {}),\n };\n\n if (when !== undefined) {\n let truthy = true;\n try {\n const w = (await renderString(when, values)).trim();\n truthy = !(w === \"\" || w === \"false\");\n } catch {\n truthy = false;\n }\n if (!truthy) {\n record(target, {\n ...contribution,\n skipped: true,\n note: `skipped: \\`when: ${when}\\` evaluated falsy`,\n });\n return;\n }\n }\n\n const existing = live.get(target);\n\n switch (op) {\n case \"delete\":\n live.delete(target);\n deleted.add(target);\n break;\n case \"replace\":\n case \"append\":\n case \"prepend\":\n if (existing) existing.patchedFrom.push(\"sidecar\");\n else\n live.set(target, {\n strategy: op === \"replace\" ? \"replace\" : op,\n fromLayer: \"sidecar\",\n patchedFrom: [],\n });\n break;\n case \"merge\":\n if (existing) existing.patchedFrom.push(\"sidecar\");\n else\n live.set(target, {\n strategy: \"deep-merge\",\n fromLayer: \"sidecar\",\n patchedFrom: [],\n });\n break;\n case \"patch\":\n contribution.note =\n \"unified-diff 3-way patch (§5) — described, not applied\" +\n (baseHash ? \"\" : \"; no recorded base ⇒ best-effort apply\");\n break;\n }\n\n record(target, contribution);\n}\n\n/** Explain a single output path; undefined when no layer touches it. */\nexport async function explainFile(\n graph: ResolvedGraph,\n path: string,\n options: ExplainOptions = {},\n): Promise<FileExplanation | undefined> {\n const result = await explain(graph, options);\n return result.files[path];\n}\n\n/**\n * Explain a compiled destination (§7).\n *\n * The lockfile's lineage records absolute layer dirs lowest → highest, so its\n * last entry *is* the source root: a destination can reconstruct its own graph\n * and re-explain itself with the answers it was built from. Files the template\n * does not own are reported as user-owned rather than omitted.\n */\nexport async function explainDest(destDir: string): Promise<ExplainResult> {\n if (!hasState(destDir)) {\n throw new Error(\n `No .treelay state in ${destDir} — not a compiled destination. ` +\n `Point \\`explain\\` at a source layer directory instead.`,\n );\n }\n const state = readState(destDir);\n const src = state.lock.lineage[state.lock.lineage.length - 1];\n if (!src) throw new Error(`Corrupt lockfile in ${destDir}: empty lineage.`);\n\n const result = await explain(resolveGraph(src), {\n values: state.answers,\n destDir,\n });\n\n for (const [path, entry] of Object.entries(state.manifest)) {\n const file = result.files[path];\n if (file) file.owned = entry.owned;\n }\n return result;\n}\n\n/** Render an explanation as aligned, human-readable text. */\nexport function formatExplanation(\n result: ExplainResult,\n only?: string,\n): string {\n const lines: string[] = [];\n\n lines.push(\"Layers (lowest → highest precedence):\");\n for (const l of result.layers) {\n const marks = [\n l.mountPath ? `mounted at ${l.mountPath}/` : undefined,\n l.revision ? `pinned ${shortRevision(l.revision)}` : undefined,\n l.writable ? undefined : \"read-only\",\n ].filter(Boolean);\n const flags = marks.length ? ` [${marks.join(\", \")}]` : \"\";\n lines.push(` ${l.position}. ${l.name} (${l.role})${flags}`);\n }\n lines.push(\"\");\n\n const paths = only ? [only] : Object.keys(result.files);\n if (only && !result.files[only]) {\n lines.push(`No layer contributes to \"${only}\".`);\n return lines.join(\"\\n\");\n }\n\n for (const path of paths) {\n const file = result.files[path]!;\n const status = file.present\n ? `← ${nameOf(result, file.winner)} (${file.strategy})`\n : \"← removed (tombstoned)\";\n lines.push(`${path} ${status}`);\n\n for (const c of file.contributions) {\n const marks = [\n c.skipped ? \"skipped\" : undefined,\n c.kind === \"sidecar\" ? \"sidecar\" : c.kind === \"suffix\" ? \"suffix\" : undefined,\n c.base ? `base ${c.base.slice(0, 14)}…` : undefined,\n ].filter(Boolean);\n const suffix = marks.length ? ` [${marks.join(\", \")}]` : \"\";\n lines.push(\n ` ${c.position}. ${pad(c.name, 18)} ${pad(c.role, 7)} ${pad(c.action, 11)} ${c.source}${suffix}`,\n );\n if (c.note) lines.push(` note: ${c.note}`);\n }\n\n if (file.patchedFrom.length) {\n const names = file.patchedFrom.map((id) => nameOf(result, id));\n lines.push(` folded in: ${names.join(\", \")}`);\n }\n if (file.owned) lines.push(\" user-owned (not produced by the template)\");\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\").trimEnd();\n}\n\n/** Commit SHAs are abbreviated for display; package versions are already short. */\nfunction shortRevision(rev: string): string {\n return /^[0-9a-f]{40}$/i.test(rev) ? rev.slice(0, 12) : rev;\n}\n\nfunction nameOf(result: ExplainResult, id?: string): string {\n if (!id) return \"—\";\n return result.layers.find((l) => l.id === id)?.name ?? id;\n}\n\nfunction pad(s: string, n: number): string {\n return s.length >= n ? s : s + \" \".repeat(n - s.length);\n}\n","/**\n * Blast radius — SPEC §8 guard 3.\n *\n * \"Promoting up reaches *every sibling* inheriting that layer — the intent, but\n * a footgun.\" Before a promote lands, report who else is downstream of the\n * target so the reach is a stated fact rather than a surprise on someone else's\n * next `update`.\n *\n * Two populations, found two different ways:\n *\n * - **dependents** — other *layers* declaring the target as a parent or mixin.\n * Found by reading manifests. These inherit the change by composition.\n * - **destinations** — already-compiled *projects* whose lockfile lineage\n * includes the target. Found by reading `.treelay/lock.json`. These are live\n * deployments that will absorb the change when they next update.\n *\n * The search is bounded: reflux passes a root (normally the common ancestor of\n * the composition) rather than letting this wander the filesystem.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join, resolve as resolvePath, sep } from \"node:path\";\nimport fg from \"fast-glob\";\n\nimport { loadManifest } from \"./manifest.js\";\nimport { resolveRef } from \"./resolve.js\";\nimport { STATE_DIR } from \"./state.js\";\nimport type { LockFile } from \"./state.js\";\n\nexport interface BlastRadius {\n /** The layer being promoted into. */\n layer: string;\n searchRoot: string;\n /** Other layer dirs that declare the target as a parent or mixin. */\n dependents: string[];\n /** Compiled destination dirs whose lineage includes the target. */\n destinations: string[];\n /**\n * True when the scan may be incomplete — consumers can live outside the\n * search root, so \"none found\" is never proof of \"none exist\".\n */\n bounded: boolean;\n}\n\nexport interface BlastRadiusOptions {\n /** Directory to scan. Consumers outside it are invisible to this scan. */\n searchRoot: string;\n /** Destination doing the promoting; excluded from `destinations`. */\n excludeDest?: string;\n /** Layer doing the promoting; excluded from `dependents`. */\n excludeLayer?: string;\n /** Directory depth to scan. Deep enough for a monorepo, bounded for sanity. */\n depth?: number;\n}\n\nconst MANIFEST_GLOBS = [\n \"**/treelay.json\",\n \"**/treelay.yaml\",\n \"**/treelay.yml\",\n \"**/package.json\",\n];\n\nconst SCAN_IGNORE = [\"**/node_modules/**\", \"**/.git/**\"];\n\n/** Find every layer and compiled destination downstream of `layerDir`. */\nexport function blastRadius(\n layerDir: string,\n options: BlastRadiusOptions,\n): BlastRadius {\n const target = resolvePath(layerDir);\n const searchRoot = resolvePath(options.searchRoot);\n const depth = options.depth ?? 8;\n\n const dependents = new Set<string>();\n const destinations = new Set<string>();\n\n for (const rel of fg.sync(MANIFEST_GLOBS, {\n cwd: searchRoot,\n dot: true,\n onlyFiles: true,\n deep: depth,\n ignore: SCAN_IGNORE,\n })) {\n const dir = resolvePath(searchRoot, dirname(rel));\n if (dir === target) continue;\n if (options.excludeLayer && dir === resolvePath(options.excludeLayer)) continue;\n\n const manifest = loadManifest(dir);\n const refs = [...(manifest.parents ?? []), ...(manifest.mixins ?? [])];\n for (const ref of refs) {\n let resolved: string;\n try {\n resolved = resolveRef(ref, dir);\n } catch {\n continue; // unresolvable (npm/git pending §2) — cannot be scored\n }\n if (resolved === target) dependents.add(dir);\n }\n }\n\n for (const rel of fg.sync(`**/${STATE_DIR}/lock.json`, {\n cwd: searchRoot,\n dot: true,\n onlyFiles: true,\n deep: depth + 1,\n ignore: SCAN_IGNORE,\n })) {\n const destDir = resolvePath(searchRoot, dirname(dirname(rel)));\n if (options.excludeDest && destDir === resolvePath(options.excludeDest)) continue;\n try {\n const lock = JSON.parse(readFileSync(join(searchRoot, rel), \"utf8\")) as LockFile;\n if (lock.lineage?.includes(target)) destinations.add(destDir);\n } catch {\n continue; // unreadable lockfile is not evidence of a consumer\n }\n }\n\n return {\n layer: target,\n searchRoot,\n dependents: [...dependents].sort(),\n destinations: [...destinations].sort(),\n bounded: true,\n };\n}\n\n/** A one-line warning in the shape SPEC §8 guard 3 asks for. */\nexport function describeBlastRadius(radius: BlastRadius, layerName: string): string {\n const n = radius.dependents.length;\n const d = radius.destinations.length;\n if (n === 0 && d === 0) {\n return `${layerName} has no other known consumers under ${radius.searchRoot}.`;\n }\n const parts: string[] = [];\n if (n) parts.push(`${n} other layer${n === 1 ? \"\" : \"s\"} inherit${n === 1 ? \"s\" : \"\"} it`);\n if (d) parts.push(`${d} compiled destination${d === 1 ? \"\" : \"s\"} include${d === 1 ? \"s\" : \"\"} it`);\n return (\n `${layerName} is consumed beyond this project — ${parts.join(\", \")}. ` +\n `This edit reaches all of them on their next update.`\n );\n}\n\n/** The deepest directory containing every given path — a natural search root. */\nexport function commonAncestor(paths: string[]): string {\n if (paths.length === 0) return resolvePath(\".\");\n const split = paths.map((p) => resolvePath(p).split(sep));\n const first = split[0]!;\n let i = 0;\n while (i < first.length && split.every((parts) => parts[i] === first[i])) i++;\n return split[0]!.slice(0, i).join(sep) || sep;\n}\n","/**\n * Round-trip verification — SPEC §8 guard 2.\n *\n * \"After any promote/extract, recompile and assert the working copy is\n * byte-identical.\" This is the guard that makes reflux trustworthy: a promoted\n * edit is only accepted once the graph provably reproduces it, so merge-order\n * interactions surface as a loud failure instead of silent drift.\n *\n * The comparison is deliberately one-directional. Every path the template\n * produces must match the destination exactly; files the destination has but\n * the template does not are *user-owned* (§7) and are none of verification's\n * business. Without that asymmetry every unpromoted local file would read as a\n * failure.\n */\n\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport { composeFiles } from \"./compile.js\";\nimport type { ResolvedGraph, Values } from \"./types.js\";\n\n/**\n * Compose a graph and return its output in memory, without touching any real\n * destination — verification must not be able to disturb what it is checking.\n */\nexport async function composeToMemory(\n graph: ResolvedGraph,\n values: Values,\n destDir?: string,\n): Promise<Map<string, Buffer>> {\n const composed = await composeFiles(graph, values, destDir);\n const files = new Map<string, Buffer>();\n for (const [rel, entry] of composed) files.set(rel, entry.data);\n return files;\n}\n\nexport type MismatchKind =\n | \"content-differs\"\n | \"missing-in-dest\"\n | \"should-have-been-removed\";\n\nexport interface VerifyMismatch {\n path: string;\n kind: MismatchKind;\n detail: string;\n}\n\nexport interface VerifyResult {\n ok: boolean;\n mismatches: VerifyMismatch[];\n /** The recomposed output, reusable as the new baseline on success. */\n composed: Map<string, Buffer>;\n}\n\nexport interface VerifyOptions {\n /**\n * Paths a promotion intended to remove. Verification asserts the recompiled\n * template no longer produces them — otherwise a promoted tombstone that\n * failed to take would pass unnoticed, since the file is already gone from\n * the destination either way.\n */\n expectAbsent?: string[];\n}\n\n/** Recompile `graph` and assert `destDir` reproduces it byte-for-byte. */\nexport async function roundTripVerify(\n destDir: string,\n graph: ResolvedGraph,\n values: Values,\n options: VerifyOptions = {},\n): Promise<VerifyResult> {\n const composed = await composeToMemory(graph, values, destDir);\n const mismatches: VerifyMismatch[] = [];\n\n for (const [rel, expected] of composed) {\n const abs = join(destDir, rel);\n if (!existsSync(abs)) {\n mismatches.push({\n path: rel,\n kind: \"missing-in-dest\",\n detail: \"the template produces this file but the destination lacks it\",\n });\n continue;\n }\n const actual = readFileSync(abs);\n if (!actual.equals(expected)) {\n mismatches.push({\n path: rel,\n kind: \"content-differs\",\n detail:\n `recompiled output differs from the working copy ` +\n `(${expected.length} vs ${actual.length} bytes)`,\n });\n }\n }\n\n for (const rel of options.expectAbsent ?? []) {\n if (composed.has(rel)) {\n mismatches.push({\n path: rel,\n kind: \"should-have-been-removed\",\n detail: \"the template still produces this file after the promotion\",\n });\n }\n }\n\n return { ok: mismatches.length === 0, mismatches, composed };\n}\n\n/** Render mismatches into a message suitable for a thrown error. */\nexport function describeMismatches(mismatches: VerifyMismatch[]): string {\n return mismatches\n .map((m) => ` ${m.path} — ${m.kind}: ${m.detail}`)\n .join(\"\\n\");\n}\n","/**\n * Reflux — pushing instance edits back up the graph — SPEC §8.\n *\n * `compile` is instantiation; reflux is \"pull member up\". `status` lists what\n * diverged from the baseline and blames the layer that produced it, `promote`\n * pushes a change into an existing ancestor, and `extract` factors it into a\n * brand-new overlay.\n *\n * Every write-back runs the three guards of §8:\n *\n * 1. **Precedence shadowing** — refuse a target a higher layer would override,\n * because the change would silently vanish on the next recompile.\n * 2. **Round-trip verification** — recompile and assert the destination\n * reproduces byte-for-byte, rolling back the layer writes if it doesn't.\n * 3. **Blast radius** — report which other layers and compiled destinations\n * the target feeds before the change reaches them.\n *\n * Guards 1 and 2 divide the work: guard 1 catches the cases that provably\n * cannot work (a wholesale override sits above the target) with a precise,\n * actionable message; guard 2 catches everything subtler — partial merges,\n * append ordering, re-render losses — by simply checking whether the graph\n * reproduces reality.\n */\n\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join, relative, resolve as resolvePath } from \"node:path\";\nimport { createPatch } from \"diff\";\nimport fg from \"fast-glob\";\nimport { stringify as stringifyYaml } from \"yaml\";\n\nimport { hashContent } from \"./hash.js\";\nimport { explain, type Contribution, type ExplainResult } from \"./explain.js\";\nimport { resolve as resolveGraph, resolveRef } from \"./resolve.js\";\nimport { STATE_DIR, readState, writeState, lockFromGraph, sourceOf } from \"./state.js\";\nimport { SIDECAR_SUFFIX } from \"./sidecar.js\";\nimport { parseStructured } from \"./serde.js\";\nimport { generateMergePatch } from \"./merge/structured.js\";\nimport { blastRadius, commonAncestor, describeBlastRadius } from \"./blast-radius.js\";\nimport { roundTripVerify, composeToMemory, describeMismatches } from \"./verify.js\";\nimport type { BlastRadius } from \"./blast-radius.js\";\nimport type {\n Change,\n Layer,\n LayerRef,\n ResolvedGraph,\n Values,\n} from \"./types.js\";\n\n/**\n * Actions that set a file's whole content. A contribution of this kind sitting\n * *above* a promotion target means the promoted bytes can never survive — the\n * definition of precedence shadowing (§8 guard 1).\n *\n * Partial actions (deep-merge, append, prepend, patch, merge) are deliberately\n * absent: they transform rather than discard, so whether the promotion survives\n * is a question only a real recompile can answer. Guard 2 answers it.\n */\nconst WHOLESALE_ACTIONS = new Set([\"create\", \"replace\", \"delete\"]);\n\n/** Structured formats get a merge patch; everything else a unified diff (§5). */\nconst STRUCTURED = /\\.(json|ya?ml|toml)$/i;\n\n/** Everything reflux needs about a destination, loaded once. */\ninterface Context {\n destDir: string;\n srcDir: string;\n graph: ResolvedGraph;\n values: Values;\n explanation: ExplainResult;\n baseline: Record<string, string>;\n manifest: Record<string, { owned: boolean; fromLayer: string }>;\n}\n\nasync function loadContext(destDir: string): Promise<Context> {\n const state = readState(destDir);\n const srcDir = sourceOf(state);\n if (!srcDir) throw new Error(`Corrupt lockfile in ${destDir}: empty lineage.`);\n\n const graph = resolveGraph(srcDir);\n const explanation = await explain(graph, { values: state.answers, destDir });\n return {\n destDir,\n srcDir,\n graph,\n values: state.answers,\n explanation,\n baseline: state.baseline,\n manifest: state.manifest,\n };\n}\n\n/** Files currently in the destination, ignoring its `.treelay/` state dir. */\nfunction destFiles(destDir: string): string[] {\n return fg\n .sync(\"**/*\", {\n cwd: destDir,\n dot: true,\n onlyFiles: true,\n ignore: [`${STATE_DIR}/**`],\n })\n .sort();\n}\n\nconst layerName = (layer: Layer) => layer.manifest.name ?? relative(dirname(layer.dir), layer.dir);\n\nfunction layerById(graph: ResolvedGraph, id: string): Layer | undefined {\n return graph.layers.find((l) => l.id === id);\n}\n\nfunction nameOf(graph: ResolvedGraph, id: string): string {\n const layer = layerById(graph, id);\n return layer ? layerName(layer) : id;\n}\n\n/** Stack position of a layer, 1-based; 0 when it is not in the graph. */\nfunction positionOf(graph: ResolvedGraph, id: string): number {\n return graph.layers.findIndex((l) => l.id === id) + 1;\n}\n\n/**\n * Contributions above `position` that would wholly override the file.\n * Empty means a promotion to that position is not *provably* futile.\n */\nfunction shadowers(\n explanation: ExplainResult,\n path: string,\n position: number,\n): Contribution[] {\n const file = explanation.files[path];\n if (!file) return [];\n return file.contributions.filter(\n (c) => c.position > position && !c.skipped && WHOLESALE_ACTIONS.has(c.action),\n );\n}\n\n// ---------------------------------------------------------------- status\n\n/** List changes in a destination vs its baseline, with provenance (§8). */\nexport async function status(destDir: string): Promise<Change[]> {\n const ctx = await loadContext(destDir);\n const present = new Set(destFiles(destDir));\n const changes: Change[] = [];\n\n for (const [path, recorded] of Object.entries(ctx.baseline)) {\n if (!present.has(path)) {\n changes.push(annotate(ctx, { path, kind: \"deleted\" }));\n continue;\n }\n const actual = hashContent(readFileSync(join(destDir, path)));\n if (actual !== recorded) {\n changes.push(annotate(ctx, { path, kind: \"modified\" }));\n }\n }\n\n for (const path of present) {\n if (path in ctx.baseline) continue;\n changes.push(annotate(ctx, { path, kind: \"added\" }));\n }\n\n return changes.sort((a, b) => a.path.localeCompare(b.path));\n}\n\n/** Attach producing layer, patch chain, and viable promotion targets. */\nfunction annotate(ctx: Context, change: Change): Change {\n const file = ctx.explanation.files[change.path];\n const producing = file?.winner ?? ctx.manifest[change.path]?.fromLayer;\n\n // A target is viable when it is writable and nothing above it would\n // wholesale-override the file (§8 guard 1) — the \"where could this go\"\n // question `status` exists to answer.\n const targets = ctx.graph.layers\n .filter((l) => l.writable)\n .filter((l) => shadowers(ctx.explanation, change.path, positionOf(ctx.graph, l.id)).length === 0)\n .map((l) => l.id);\n\n return {\n ...change,\n ...(producing ? { producingLayer: producing } : {}),\n ...(file?.patchedFrom.length ? { patchedBy: file.patchedFrom } : {}),\n ...(file ? {} : { owned: true }),\n targets,\n };\n}\n\n/** Render `status` output in the annotated form of SPEC §8. */\nexport function formatStatus(changes: Change[], graph: ResolvedGraph): string {\n if (changes.length === 0) return \"No changes vs baseline.\";\n const mark = { modified: \"M\", added: \"A\", deleted: \"D\" } as const;\n const width = Math.max(...changes.map((c) => c.path.length));\n\n return changes\n .map((c) => {\n const path = c.path.padEnd(width);\n if (!c.producingLayer) return ` A ${path} ← local-only (no template origin)`;\n const patched = c.patchedBy?.length\n ? ` (+ patched by ${c.patchedBy.map((id) => nameOf(graph, id)).join(\", \")})`\n : \"\";\n return ` ${mark[c.kind]} ${path} ← produced by ${nameOf(graph, c.producingLayer)}${patched}`;\n })\n .join(\"\\n\");\n}\n\n// --------------------------------------------------------------- promote\n\n/** How a promoted change was written into its target layer. */\nexport type LandingMode = \"rewrite\" | \"patch\" | \"create\" | \"tombstone\";\n\nexport interface LandedChange {\n path: string;\n mode: LandingMode;\n /** File written inside the target layer, relative to the layer root. */\n wrote: string;\n}\n\nexport interface PromoteResult {\n /** Layer id promoted into. */\n target: string;\n targetName: string;\n landed: LandedChange[];\n verified: boolean;\n blastRadius: BlastRadius;\n /** Human-readable §8 guard 3 warning. */\n blastRadiusWarning: string;\n}\n\nexport interface PromoteOptions {\n /** Target layer to promote into; if omitted, auto-suggest from provenance. */\n to?: LayerRef;\n /** Recompile and assert byte-identity after promoting (default true). */\n verify?: boolean;\n /** Root for the blast-radius scan (default: common ancestor of the graph). */\n searchRoot?: string;\n}\n\n/**\n * Promote changes up into a target layer. Throws on precedence-shadowing,\n * read-only targets, or a failed round-trip verification (§8 guards). Generates\n * a `.treelay` sidecar recording both `base` and `baseContent` when the change\n * lands as a patch rather than a rewrite (§5).\n */\nexport async function promote(\n destDir: string,\n changes: Change[],\n options: PromoteOptions = {},\n): Promise<PromoteResult> {\n if (changes.length === 0) throw new Error(\"promote: no changes given.\");\n const ctx = await loadContext(destDir);\n\n const target = resolveTarget(ctx, changes, options.to);\n const position = positionOf(ctx.graph, target.id);\n\n if (!target.writable) {\n throw new Error(\n `Cannot promote into ${layerName(target)}: the layer is read-only.\\n` +\n `Promote into a writable layer above it, or capture the change as a patch there (§8).`,\n );\n }\n\n // Guard 1 — precedence shadowing, checked for every path before writing any.\n for (const change of changes) {\n const blocked = shadowers(ctx.explanation, change.path, position);\n if (blocked.length) {\n const names = [...new Set(blocked.map((c) => c.name))].join(\", \");\n throw new Error(\n `Promoting ${change.path} to ${layerName(target)} has no effect; ` +\n `${names} overrides this file at a higher precedence.\\n` +\n `Promote to ${names} or to the leaf instead (§8 guard 1).`,\n );\n }\n }\n\n const tx = new LayerTransaction();\n let landed: LandedChange[];\n try {\n landed = [];\n for (const change of changes) {\n landed.push(await landChange(ctx, change, target, position, tx));\n }\n } catch (err) {\n tx.rollback();\n throw err;\n }\n\n // Guard 2 — round-trip verification against a freshly resolved graph, since\n // the layer we just wrote to may have changed what resolution produces.\n const verify = options.verify !== false;\n if (verify) {\n const regraph = resolveGraph(ctx.srcDir);\n const removed = changes.filter((c) => c.kind === \"deleted\").map((c) => c.path);\n const result = await roundTripVerify(destDir, regraph, ctx.values, {\n expectAbsent: removed,\n });\n if (!result.ok) {\n tx.rollback();\n throw new Error(\n `Round-trip verification failed after promoting to ${layerName(target)} — ` +\n `the recompiled template does not reproduce the working copy, so the ` +\n `promotion was rolled back (§8 guard 2):\\n${describeMismatches(result.mismatches)}`,\n );\n }\n rebaseline(ctx, regraph, result.composed);\n }\n\n // Guard 3 — blast radius, reported (not enforced) once the change has landed.\n const searchRoot =\n options.searchRoot ?? commonAncestor([...ctx.graph.layers.map((l) => l.dir), destDir]);\n const radius = blastRadius(target.dir, {\n searchRoot,\n excludeDest: destDir,\n excludeLayer: ctx.srcDir,\n });\n\n return {\n target: target.id,\n targetName: layerName(target),\n landed,\n verified: verify,\n blastRadius: radius,\n blastRadiusWarning: describeBlastRadius(radius, layerName(target)),\n };\n}\n\n/** Pick the target layer: explicit `--to`, else the provenance suggestion. */\nfunction resolveTarget(ctx: Context, changes: Change[], to?: LayerRef): Layer {\n if (to) {\n const dir = to.startsWith(\".\") || to.startsWith(\"/\") ? resolveRef(to, ctx.srcDir) : to;\n const layer = ctx.graph.layers.find((l) => l.id === dir || layerName(l) === to);\n if (!layer) {\n const known = ctx.graph.layers.map((l) => layerName(l)).join(\", \");\n throw new Error(`Unknown promotion target \"${to}\". Layers in this composition: ${known}.`);\n }\n return layer;\n }\n\n const suggestions = new Set(\n changes.map((c) => c.producingLayer ?? ctx.explanation.files[c.path]?.winner ?? ctx.srcDir),\n );\n if (suggestions.size > 1) {\n const names = [...suggestions].map((id) => nameOf(ctx.graph, id)).join(\", \");\n throw new Error(\n `These changes come from different layers (${names}), so there is no single ` +\n `suggested target. Promote them separately, or pass an explicit target.`,\n );\n }\n const [only] = [...suggestions];\n const layer = layerById(ctx.graph, only!);\n if (!layer) throw new Error(`Suggested target ${only} is not part of the composition.`);\n return layer;\n}\n\n/** Write one change into the target layer, recording undo in `tx`. */\nasync function landChange(\n ctx: Context,\n change: Change,\n target: Layer,\n position: number,\n tx: LayerTransaction,\n): Promise<LandedChange> {\n const file = ctx.explanation.files[change.path];\n\n if (change.kind === \"deleted\") {\n // When the target itself is the sole producer, removing its source file is\n // cleaner than layering a tombstone on top of the layer's own content.\n const own = file?.contributions.find((c) => c.layer === target.id);\n if (own && file!.contributions.length === 1) {\n tx.remove(join(target.dir, own.source));\n return { path: change.path, mode: \"tombstone\", wrote: own.source };\n }\n const sidecar = change.path + SIDECAR_SUFFIX;\n tx.write(join(target.dir, sidecar), stringifyYaml({ op: \"delete\" }));\n return { path: change.path, mode: \"tombstone\", wrote: sidecar };\n }\n\n const desired = readFileSync(join(ctx.destDir, change.path), \"utf8\");\n\n // The target already produces this file: rewrite its own source in place,\n // reusing the exact source path so a templated source does not gain a\n // duplicate plain-file sibling.\n const own = file?.contributions.find((c) => c.layer === target.id && c.kind === \"file\");\n if (own) {\n tx.write(join(target.dir, own.source), desired);\n return { path: change.path, mode: \"rewrite\", wrote: own.source };\n }\n\n // A lower layer produces it and the target does not: record only the delta,\n // so the target stays a focused overlay rather than a full copy.\n const inherited = await inheritedBelow(ctx, position, change.path);\n if (inherited !== undefined) {\n const sidecar = change.path + SIDECAR_SUFFIX;\n tx.write(\n join(target.dir, sidecar),\n buildPatchSidecar(change.path, inherited, desired),\n );\n return { path: change.path, mode: \"patch\", wrote: sidecar };\n }\n\n // Nothing below produces it — a genuinely new file for this layer.\n tx.write(join(target.dir, change.path), desired);\n return { path: change.path, mode: \"create\", wrote: change.path };\n}\n\n/**\n * The content a file has just *below* a given stack position — the base a\n * promoted patch is authored against.\n *\n * Composing the sub-stack through the real compiler is what keeps this honest:\n * it accounts for every merge, op and render that produced the inherited text,\n * rather than re-deriving it with a second implementation that could disagree.\n */\nasync function inheritedBelow(\n ctx: Context,\n position: number,\n path: string,\n): Promise<string | undefined> {\n if (position <= 1) return undefined;\n const below: ResolvedGraph = {\n layers: ctx.graph.layers.slice(0, position - 1),\n variables: ctx.graph.variables,\n };\n const composed = await composeToMemory(below, ctx.values);\n return composed.get(path)?.toString(\"utf8\");\n}\n\n/**\n * Build the sidecar for a patch-mode promotion.\n *\n * Both `base` and `baseContent` are recorded (§5): the hash detects that the\n * inherited file drifted, and the content is what lets diff3 actually reconcile\n * once it has. Reflux has the base text in hand, so there is no reason to emit\n * the weaker hash-only form that hand-authored sidecars are limited to.\n */\nfunction buildPatchSidecar(path: string, base: string, desired: string): string {\n if (STRUCTURED.test(path)) {\n // Structured formats have no line drift, so a merge patch is strictly\n // better than a diff — but the hash still buys drift detection.\n return stringifyYaml({\n op: \"merge\",\n base: hashContent(base),\n merge: generateMergePatch(parseStructured(path, base), parseStructured(path, desired)),\n });\n }\n\n return stringifyYaml({\n op: \"patch\",\n base: hashContent(base),\n baseContent: base,\n patch: createPatch(path, base, desired, undefined, undefined, { context: 3 }),\n });\n}\n\n/**\n * Rewrite the baseline so a verified promotion counts as \"from template\" and\n * drops off the local-changes list (§8) — it now flows down by inheritance.\n *\n * The content snapshot is rewritten alongside the hashes, not just the hashes:\n * `update` merges against the baseline *content* (§7), so leaving that stale\n * would make the next update reconcile against a base the template no longer\n * produces.\n */\nfunction rebaseline(\n ctx: Context,\n graph: ResolvedGraph,\n composed: Map<string, Buffer>,\n): void {\n const baseline: Record<string, string> = {};\n const manifest: Record<string, { owned: boolean; fromLayer: string }> = {};\n for (const [path, data] of composed) {\n baseline[path] = hashContent(data);\n manifest[path] = {\n owned: false,\n fromLayer: ctx.manifest[path]?.fromLayer ?? ctx.srcDir,\n };\n }\n writeState(\n ctx.destDir,\n { lock: lockFromGraph(graph), answers: ctx.values, baseline, manifest },\n graph.variables,\n composed,\n );\n}\n\n// --------------------------------------------------------------- extract\n\nexport interface ExtractOptions {\n /** Path for the new overlay layer. */\n as: string;\n /** Wire it into the leaf's `mixins` (vs leaving it free-standing). */\n asMixin?: boolean;\n /** Name for the new layer's manifest (default: its directory name). */\n name?: string;\n /** Recompile and assert byte-identity afterwards (default true when wired). */\n verify?: boolean;\n}\n\nexport interface ExtractResult {\n /** Absolute path of the new layer. */\n layer: string;\n name: string;\n files: string[];\n /** Whether the leaf was rewired to consume the new layer. */\n wired: boolean;\n verified: boolean;\n}\n\n/**\n * Capture changes as a new overlay layer (§8).\n *\n * A free-standing extraction (`asMixin: false`) deliberately skips round-trip\n * verification and leaves the baseline alone: the new layer is not in the graph\n * yet, so the destination provably *cannot* reproduce from it. Verifying would\n * fail by construction, and rewriting the baseline would falsely mark the edits\n * as inherited.\n */\nexport async function extract(\n destDir: string,\n changes: Change[],\n options: ExtractOptions,\n): Promise<ExtractResult> {\n if (changes.length === 0) throw new Error(\"extract: no changes given.\");\n const ctx = await loadContext(destDir);\n\n const layerDir = resolvePath(ctx.srcDir, options.as);\n if (existsSync(join(layerDir, \"treelay.json\"))) {\n throw new Error(`A layer already exists at ${layerDir}. Choose another path.`);\n }\n const name = options.name ?? layerDir.split(\"/\").filter(Boolean).pop()!;\n\n const tx = new LayerTransaction();\n const written: string[] = [];\n try {\n tx.write(join(layerDir, \"treelay.json\"), JSON.stringify({ name }, null, 2) + \"\\n\");\n\n for (const change of changes) {\n if (change.kind === \"deleted\") {\n const sidecar = change.path + SIDECAR_SUFFIX;\n tx.write(join(layerDir, sidecar), stringifyYaml({ op: \"delete\" }));\n written.push(sidecar);\n continue;\n }\n tx.write(\n join(layerDir, change.path),\n readFileSync(join(destDir, change.path), \"utf8\"),\n );\n written.push(change.path);\n }\n\n if (options.asMixin) wireMixin(ctx, options.as, tx);\n } catch (err) {\n tx.rollback();\n throw err;\n }\n\n const wired = options.asMixin === true;\n const shouldVerify = wired && options.verify !== false;\n let verified = false;\n\n if (shouldVerify) {\n const regraph = resolveGraph(ctx.srcDir);\n const removed = changes.filter((c) => c.kind === \"deleted\").map((c) => c.path);\n const result = await roundTripVerify(destDir, regraph, ctx.values, {\n expectAbsent: removed,\n });\n if (!result.ok) {\n tx.rollback();\n throw new Error(\n `Round-trip verification failed after extracting ${name} — rolled back ` +\n `(§8 guard 2):\\n${describeMismatches(result.mismatches)}`,\n );\n }\n rebaseline(ctx, regraph, result.composed);\n verified = true;\n }\n\n return { layer: layerDir, name, files: written.sort(), wired, verified };\n}\n\n/** Append the new layer to the leaf manifest's `mixins`, highest precedence. */\nfunction wireMixin(ctx: Context, ref: string, tx: LayerTransaction): void {\n const manifestPath = join(ctx.srcDir, \"treelay.json\");\n if (!existsSync(manifestPath)) {\n throw new Error(\n `Cannot wire the extracted layer in: ${ctx.srcDir} has no treelay.json. ` +\n `Extract without --mixin and add it by hand.`,\n );\n }\n const raw = readFileSync(manifestPath, \"utf8\");\n const manifest = JSON.parse(raw) as { mixins?: string[] };\n const mixins = [...(manifest.mixins ?? []), ref];\n tx.write(manifestPath, JSON.stringify({ ...manifest, mixins }, null, 2) + \"\\n\");\n}\n\n// ----------------------------------------------------------- transaction\n\n/**\n * A minimal undo log for layer writes.\n *\n * Round-trip verification is only meaningful if a failure leaves nothing\n * behind — a half-written layer would be worse than no promotion at all, since\n * the next compile would pick it up.\n */\nclass LayerTransaction {\n private undo: Array<() => void> = [];\n\n write(path: string, content: string): void {\n const existed = existsSync(path);\n const previous = existed ? readFileSync(path) : undefined;\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, content);\n this.undo.push(() => {\n if (previous !== undefined) writeFileSync(path, previous);\n else rmSync(path, { force: true });\n });\n }\n\n remove(path: string): void {\n if (!existsSync(path)) return;\n const previous = readFileSync(path);\n rmSync(path, { force: true });\n this.undo.push(() => {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, previous);\n });\n }\n\n rollback(): void {\n for (const step of this.undo.reverse()) step();\n this.undo = [];\n }\n}\n"],"mappings":"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","names":["parseYaml","parseYaml","engine","readFileSync","join","subdir","body","createHash","existsSync","join","existsSync","rmSync","join","git","existsSync","join","rmSync","existsSync","readFileSync","join","join","existsSync","require","readFileSync","existsSync","existsSync","existsSync","readFileSync","join","isAbsolute","existsSync","isAbsolute","existsSync","parseYaml","createRequire","require","isObject","relative","resolvePath","resolvePath","relative","mkdirSync","readFileSync","writeFileSync","existsSync","rmSync","dirname","join","join","existsSync","mkdirSync","writeFileSync","rmSync","readFileSync","dirname","readFileSync","writeFileSync","join","fg","parseYaml","join","writeFileSync","fg","readFileSync","status","existsSync","readFileSync","rmSync","writeFileSync","statSync","join","existsSync","statSync","join","readFileSync","rmSync","writeFileSync","readFileSync","join","resolvePath","resolvePath","readFileSync","join","status","readFileSync","dirname","join","resolvePath","fg","resolvePath","fg","dirname","readFileSync","join","layerName","readFileSync","existsSync","join","join","existsSync","readFileSync","existsSync","mkdirSync","readFileSync","rmSync","writeFileSync","dirname","join","relative","resolvePath","fg","stringifyYaml","STRUCTURED","fg","relative","dirname","nameOf","readFileSync","join","layer","own","stringifyYaml","resolvePath","existsSync","mkdirSync","writeFileSync","rmSync"]}
|