@penvhq/cli 0.16.0 → 0.16.1

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/artifact.ts","../src/install.ts","../src/child.ts","../src/project.ts","../src/env-flags.ts","../src/registry.ts","../src/ui.ts","../src/style.ts","../src/commands/run.ts","../src/dotenv-files.ts","../src/commands/pull.ts","../src/commands/validate.ts","../src/schema.ts","../src/commands/cleanup.ts","../src/cutover.ts","../src/commands/doctor.ts","../src/commands/push.ts","../src/input.ts","../src/commands/encrypt.ts","../src/commands/set.ts","../src/commands/fill.ts","../src/commands/generate.ts","../src/commands/get.ts","../src/commands/import.ts","../src/adopt.ts","../src/detect.ts","../src/draft-schema.ts","../src/commands/init.ts","../src/scaffold-undo.ts","../src/seams.ts","../src/commands/key.ts","../src/keychain.ts","../src/commands/list.ts","../src/commands/migrate.ts","../src/commands/mv.ts","../src/commands/remove.ts","../src/commands/rotate.ts","../src/commands/watch.ts"],"sourcesContent":["/**\n * penv's command line.\n *\n * The wiring here is deliberately thin: every command's real work is a plain\n * exported function that takes a `cwd` and returns a result, and citty only\n * parses arguments, calls it, and prints what it returned. That is what lets the\n * tests call the commands rather than spawn them.\n */\n\nimport { setKeychain } from \"@penvhq/core\";\nimport { runMain as cittyRunMain, defineCommand } from \"citty\";\nimport { artifactCommand } from \"./commands/artifact.js\";\nimport { cleanupCommand } from \"./commands/cleanup.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\nimport { decryptCommand, encryptCommand } from \"./commands/encrypt.js\";\nimport { fillCommand } from \"./commands/fill.js\";\nimport { generateCommand } from \"./commands/generate.js\";\nimport { getCommand } from \"./commands/get.js\";\nimport { importCommand } from \"./commands/import.js\";\nimport { initCommand } from \"./commands/init.js\";\nimport { keyCommand } from \"./commands/key.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { migrateCommand } from \"./commands/migrate.js\";\nimport { mvCommand } from \"./commands/mv.js\";\nimport { pullCommand } from \"./commands/pull.js\";\nimport { pushCommand } from \"./commands/push.js\";\nimport { removeCommand } from \"./commands/remove.js\";\nimport { rotateCommand } from \"./commands/rotate.js\";\nimport { runCommand } from \"./commands/run.js\";\nimport { setCommand } from \"./commands/set.js\";\nimport { validateCommand } from \"./commands/validate.js\";\nimport { watchCommand } from \"./commands/watch.js\";\nimport { engineVersion } from \"./install.js\";\nimport { defaultKeychain } from \"./keychain.js\";\n\nexport const main = defineCommand({\n // Lazy, so reading the engine's own version off disk is something `--version`\n // does rather than something importing this module does.\n meta: () => ({\n name: \"penv\",\n description: \"Configuration that shares a data model with your production secret manager\",\n version: engineVersion(),\n }),\n subCommands: {\n init: initCommand,\n import: importCommand,\n generate: generateCommand,\n get: getCommand,\n set: setCommand,\n fill: fillCommand,\n mv: mvCommand,\n pull: pullCommand,\n push: pushCommand,\n rotate: rotateCommand,\n run: runCommand,\n remove: removeCommand,\n list: listCommand,\n cleanup: cleanupCommand,\n migrate: migrateCommand,\n encrypt: encryptCommand,\n decrypt: decryptCommand,\n key: keyCommand,\n validate: validateCommand,\n doctor: doctorCommand,\n watch: watchCommand,\n artifact: artifactCommand,\n },\n});\n\nexport function runMain(): Promise<void> {\n // The CLI is where the keychain is read and written; core stays native-free and\n // the runtime never registers a binding. Idempotent, and the binding is lazy —\n // the native module loads only if a keychain key is actually touched.\n setKeychain(defaultKeychain);\n return cittyRunMain(main);\n}\n\nexport type { ArtifactBuildOptions, ArtifactBuildResult } from \"./commands/artifact.js\";\nexport { renderArtifactBuild, runArtifactBuild } from \"./commands/artifact.js\";\nexport type {\n DoctorCheck,\n DoctorFinding,\n DoctorReport,\n DoctorSeverity,\n} from \"./commands/doctor.js\";\nexport { renderDoctor, runDoctor } from \"./commands/doctor.js\";\nexport type { ResealResult } from \"./commands/encrypt.js\";\nexport { runDecrypt, runEncrypt } from \"./commands/encrypt.js\";\nexport type { FillOptions, FillPrompt, FillResult } from \"./commands/fill.js\";\nexport { renderFill, runFill } from \"./commands/fill.js\";\nexport type { GenerateResult } from \"./commands/generate.js\";\nexport { generateDotenv, runGenerate } from \"./commands/generate.js\";\nexport type { GetExplanation } from \"./commands/get.js\";\nexport { runExplain, runGet } from \"./commands/get.js\";\nexport type { ImportReport } from \"./commands/import.js\";\nexport { importDotenv } from \"./commands/import.js\";\nexport type {\n AdoptionPlan,\n CutoverPlan,\n CutoverResult,\n InitResult,\n InitStep,\n} from \"./commands/init.js\";\nexport {\n applyCutover,\n insertEnvAlias,\n planAdoption,\n planCutover,\n runInit,\n} from \"./commands/init.js\";\nexport type { ListResult } from \"./commands/list.js\";\nexport { runList } from \"./commands/list.js\";\nexport type { MigrateMove, MigratePlan, MigrateResult, MigrateStatus } from \"./commands/migrate.js\";\nexport { applyMigrate, planMigrate, renderMigrate, runMigrate } from \"./commands/migrate.js\";\nexport type { MoveResult } from \"./commands/mv.js\";\nexport { renderMove, runMove } from \"./commands/mv.js\";\nexport type { PullOptions, PullResult } from \"./commands/pull.js\";\nexport { renderPull, runPull } from \"./commands/pull.js\";\nexport type { PushOptions, PushResult } from \"./commands/push.js\";\nexport { LAST_PUSHED_KEY, renderPush, runPush } from \"./commands/push.js\";\nexport type { RemoveResult } from \"./commands/remove.js\";\nexport { runRemove } from \"./commands/remove.js\";\nexport type { RotateOptions, RotatePhase, RotateResult } from \"./commands/rotate.js\";\nexport { renderRotate, runRotate } from \"./commands/rotate.js\";\nexport type { RunOptions, RunResult, RunSource } from \"./commands/run.js\";\nexport { runRun } from \"./commands/run.js\";\nexport type { SetResult } from \"./commands/set.js\";\nexport { runSet } from \"./commands/set.js\";\nexport type { EnvironmentCheck, ValidateIssue, ValidateResult } from \"./commands/validate.js\";\nexport { checkEnvironment, runValidate } from \"./commands/validate.js\";\nexport type { WatchHandle, WatchOptions } from \"./commands/watch.js\";\nexport { renderWatch, runWatch } from \"./commands/watch.js\";\nexport type { CleanupResult, Cutover, UndoResult } from \"./cutover.js\";\nexport { runCleanup, runUndo } from \"./cutover.js\";\n","/**\n * `penv artifact build` — the sealed deployment artifact CI hands a release.\n *\n * It is the third step of the sequence PRD §7 names: pull the target\n * environment, validate it, build the artifact, mount it. Each step is a command\n * with one job, and this one's is narrow on purpose — it does not re-reach a\n * verdict `penv validate` already reaches, because two implementations of \"is\n * this configuration good\" would eventually let a release be built that CI had\n * already rejected.\n *\n * Two properties are the whole design:\n *\n * **It never decrypts.** A sealed value is copied ciphertext-and-address into\n * the artifact exactly as the record holds it, so building needs no key at all —\n * CI can produce a production artifact without ever being able to read one. The\n * AAD is still the value file's full name, so the ciphertext stays bound to the\n * scope it was sealed at (invariant 17).\n *\n * **It refuses to guess the environment.** `--env` is named explicitly and never\n * defaulted, `--out` likewise. An artifact built for \"whatever the default was\"\n * is a release that ships the wrong environment's credentials, and the default\n * that made it is one config edit nobody reviewed.\n */\n\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, relative, resolve } from \"node:path\";\nimport type { Artifact, ArtifactEntry, ParameterRef, ValueFile } from \"@penvhq/core\";\nimport {\n ARTIFACT_FORMAT,\n candidatesFor,\n deliveryDigest,\n formatValueFile,\n isSecret,\n keySourceIdentifier,\n PenvError,\n parameterId,\n serializeArtifact,\n variableName,\n} from \"@penvhq/core\";\nimport { assertDeliverableNames, declaredRefs } from \"@penvhq/runtime\";\nimport { defineCommand } from \"citty\";\nimport { engineVersion } from \"../install.js\";\nimport type { Project } from \"../project.js\";\nimport { openProject } from \"../project.js\";\nimport { CHECK, formatRows, guard, WARN, write } from \"../ui.js\";\nimport { assertNoPublicSecret } from \"./run.js\";\nimport { loadSchema } from \"./validate.js\";\n\nexport interface ArtifactBuildOptions {\n readonly cwd: string;\n /** Named explicitly. There is no default, and none is invented. */\n readonly environment?: string;\n /** Named explicitly. Where the release will mount it from. */\n readonly out?: string;\n}\n\nexport interface ArtifactBuildResult {\n readonly file: string;\n readonly environment: string;\n readonly engineVersion: string;\n readonly keySource: string;\n /** Delivery mappings with a value. */\n readonly values: number;\n /** How many of those travelled as ciphertext. */\n readonly sealed: number;\n /** Declared mappings the environment has no non-local winner for. */\n readonly absent: number;\n /** True when the artifact was written inside the project — a `doctor` finding. */\n readonly insideRepo: boolean;\n}\n\n/** The invocation every refusal here points back at, with what is known filled in. */\nfunction buildCommand(environment: string | undefined, out: string | undefined): string {\n return `penv artifact build --env ${environment ?? \"<environment>\"} --out ${out ?? \"<path>\"}`;\n}\n\n/**\n * The environment, taken only from `--env`.\n *\n * Deliberately not `targetEnvironment`: `defaultEnvironment`, `PENV_ENV` and\n * `NODE_ENV` all answer for the machine the command runs on, and the machine a\n * release is built on has no opinion worth acting on about which environment the\n * release is for.\n */\nfunction targetOf(options: ArtifactBuildOptions): string {\n const environment = options.environment?.trim();\n if (environment === undefined || environment.length === 0) {\n throw new PenvError(\n \"ARTIFACT_ENV_REQUIRED\",\n \"`penv artifact build` names the environment it builds for, and `--env` was not given\",\n `Name it: \\`${buildCommand(undefined, options.out)}\\`. An artifact carries one environment, and penv will not pick which.`,\n );\n }\n return environment;\n}\n\n/** The path, taken only from `--out` — there is no default, and none is inside the repo. */\nfunction outputOf(options: ArtifactBuildOptions, environment: string): string {\n const out = options.out?.trim();\n if (out === undefined || out.length === 0) {\n throw new PenvError(\n \"ARTIFACT_OUT_REQUIRED\",\n \"`penv artifact build` writes where it is told, and `--out` was not given\",\n `Name the path: \\`${buildCommand(environment, undefined)}\\`. The artifact belongs outside the repository, so there is no default worth having.`,\n );\n }\n return isAbsolute(out) ? out : resolve(options.cwd, out);\n}\n\n/**\n * The winning value file for one parameter, unopened.\n *\n * `.local` scopes are skipped outright: a personal override is one developer's\n * machine, and shipping it to a release is the scope widening the cascade exists\n * to prevent. The precedence rule itself is not restated here — `candidatesFor`\n * owns the order and this only walks the list it returns.\n */\nasync function winnerOf(\n project: Project,\n ref: ParameterRef,\n environment: string,\n): Promise<{ readonly file: ValueFile; readonly stored: string } | undefined> {\n for (const file of candidatesFor(ref, environment, true)) {\n const stored = await project.provider.read(file);\n if (stored !== undefined) {\n return { file, stored };\n }\n }\n return undefined;\n}\n\n/**\n * A secret whose winner is a plaintext file, refused at the delivery boundary.\n *\n * `doctor` reports this and the artifact refuses it, and that is the difference\n * between a report and a release: an artifact is written once and read\n * unchanged, so a plaintext secret in one is a plaintext secret in every\n * container the release reaches, for as long as it runs. penv holds both halves\n * — meta says secret, the winning filename says plaintext — so this is where it\n * stops.\n */\nfunction plaintextSecret(parameter: string, location: string, environment: string): PenvError {\n return new PenvError(\n \"ARTIFACT_PLAINTEXT_SECRET\",\n `${parameter} is a secret for environment ${environment}, and its value comes from ${location}, which is not sealed`,\n `Seal it with \\`penv encrypt ${parameter} --env ${environment}\\` — an artifact carries ciphertext or nothing.`,\n );\n}\n\nexport async function runArtifactBuild(\n options: ArtifactBuildOptions,\n): Promise<ArtifactBuildResult> {\n const environment = targetOf(options);\n const file = outputOf(options, environment);\n const retry = buildCommand(environment, options.out);\n\n const project = openProject(options.cwd);\n const { schema, issues } = await loadSchema(project, environment);\n if (schema === undefined) {\n const lines = issues.map((issue) => ` ${issue.subject}: ${issue.message}`).join(\"\\n\");\n throw new PenvError(\n \"ARTIFACT_NO_SCHEMA\",\n `The schema did not load, so penv cannot tell what this artifact should deliver:\\n${lines}`,\n `Fix the error above, then run \\`${retry}\\` again.`,\n );\n }\n\n const refs = declaredRefs(schema);\n // The same check delivery makes, made here: an artifact whose entries collide\n // would deliver last-wins in a container, where nothing is left to notice.\n assertDeliverableNames(refs, project.config);\n await assertNoPublicSecret(project, environment, refs, retry);\n\n const values: Record<string, ArtifactEntry> = {};\n let sealed = 0;\n let present = 0;\n for (const ref of refs) {\n const parameter = parameterId(ref);\n const variable = variableName(ref, project.config);\n const winner = await winnerOf(project, ref, environment);\n if (winner === undefined) {\n values[parameter] = { kind: \"absent\", variable };\n continue;\n }\n present += 1;\n const location = formatValueFile(winner.file);\n if (winner.file.encrypted) {\n sealed += 1;\n values[parameter] = { kind: \"sealed\", variable, address: location, sealed: winner.stored };\n continue;\n }\n if (isSecret(await project.provider.readMeta(ref), environment)) {\n throw plaintextSecret(parameter, location, environment);\n }\n values[parameter] = { kind: \"plain\", variable, value: winner.stored };\n }\n\n const artifact: Artifact = {\n format: ARTIFACT_FORMAT,\n environment,\n engineVersion: engineVersion(),\n schemaDigest: deliveryDigest(values),\n keySource: keySourceIdentifier(project.config, environment),\n values,\n };\n\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, serializeArtifact(artifact), \"utf8\");\n\n const inside = relative(project.root, file);\n return {\n file,\n environment,\n engineVersion: artifact.engineVersion,\n keySource: artifact.keySource,\n values: present,\n sealed,\n absent: refs.length - present,\n insideRepo: inside !== \"\" && !inside.startsWith(\"..\") && !isAbsolute(inside),\n };\n}\n\n/** The artifact's path as the caller would type it, when it is below them. */\nfunction displayPath(cwd: string, file: string): string {\n const rel = relative(cwd, file);\n return rel === \"\" || rel.startsWith(\"..\") ? file : rel.split(\"\\\\\").join(\"/\");\n}\n\nexport function renderArtifactBuild(result: ArtifactBuildResult, cwd: string): string[] {\n const rows = [\n {\n glyph: CHECK,\n label: \"Built\",\n subject: displayPath(cwd, result.file),\n detail: `${result.values} values for environment ${result.environment}, ${result.sealed} sealed`,\n },\n ];\n // Said now, while the path can still be changed, and said again by `doctor`\n // for the artifact that was committed anyway.\n if (result.insideRepo) {\n rows.push({\n glyph: WARN,\n label: \"Inside the repository\",\n subject: displayPath(cwd, result.file),\n detail: \"a deployment artifact is stored outside git — write it somewhere else\",\n });\n }\n return formatRows(rows);\n}\n\nconst buildSubcommand = defineCommand({\n meta: {\n name: \"build\",\n description: \"Write the sealed deployment artifact for one environment\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to build for (required)\" },\n out: { type: \"string\", description: \"Where to write the artifact (required)\" },\n },\n run({ args }) {\n return guard(async () => {\n const cwd = process.cwd();\n const result = await runArtifactBuild({\n cwd,\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.out === undefined ? {} : { out: args.out }),\n });\n write(renderArtifactBuild(result, cwd));\n });\n },\n});\n\nexport const artifactCommand = defineCommand({\n meta: {\n name: \"artifact\",\n description: \"Build the sealed deployment artifact a release runs from\",\n },\n subCommands: { build: buildSubcommand },\n});\n","/**\n * The runtime dependencies an adopted project takes, and how they get there.\n *\n * PRD §3: an adopted project depends on `@penvhq/penv` at the engine's own\n * version — the typed `@env` surface, not a CLI distribution. It also depends on\n * zod, because the `penv.schema.ts` init scaffolds imports it: zod is a *peer* of\n * `@penvhq/penv`, and a peer is a package the project supplies. Under pnpm's\n * strict layout nothing hoists it to the project root, so an install that named\n * only `@penvhq/penv` left the very schema init had just written unable to\n * resolve `zod` — and adoption could never finish.\n *\n * Both are installed with the package manager the project already uses, and only\n * after showing the exact `package.json` and lockfile change: an install is the\n * one step of adoption that reaches outside the repository, so it is the one step\n * that is shown before it happens rather than reported after.\n *\n * The install itself is a seam. It shells out to a package manager, which the\n * tests must never do — and a fake here is not a weaker test, because what init\n * has to get right is the plan, the consent, and the refusal when the install\n * does not happen.\n *\n * A plan is a list of steps, because in a workspace \"the project's dependency\"\n * is plural. pnpm refuses a bare `add` at a workspace root (`-w` is how you say\n * you meant the root), and a workspace package that declares `@penvhq/penv`\n * itself is a second copy of the very version the manifest pins — one repository\n * ran the 0.8 bridge under a 0.11 pin for three releases because nothing looked\n * below the root, and the same repository then held two `@penvhq/core`s five\n * minor versions apart because the scan looked for only one name. So every\n * `package.json` that declares either moves, under one consent, and the commands\n * shown are the ones that run.\n *\n * Two commands write that dependency line: `penv init`, which is the engine's,\n * and `penv upgrade`, which is the launcher's. This module is published at\n * `@penvhq/cli/install` so the launcher reaches it without loading the command\n * surface — one answer to \"which package manager, which diff, which spawn\",\n * rather than a second copy on the other side of the launcher/engine split.\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join, relative, sep } from \"node:path\";\nimport { PenvError } from \"@penvhq/core\";\nimport { startChild } from \"./child.js\";\n\n/** The package an adopted project depends on. The CLI engine is not one of its dependencies. */\nexport const RUNTIME_PACKAGE = \"@penvhq/penv\";\n\n/** The peer `penv.schema.ts` imports, which the project supplies because a peer is not hoisted. */\nexport const SCHEMA_PACKAGE = \"zod\";\n\n/**\n * The module every committed provider declaration augments, which the project\n * declares for the same reason it declares zod: nothing hoists it.\n *\n * `penv add` commits a `declare module \"@penvhq/core\"` block, and TypeScript\n * resolves that specifier from the project's own files. Under pnpm's strict\n * layout a transitive dependency is not at the project root, so the specifier\n * resolves to nothing — and an augmentation whose module cannot be found is not\n * an error, it silently degrades to an *ambient* declaration. The map\n * `defineConfig` reads stays empty, a misspelled provider field compiles clean,\n * and no diagnostic anywhere says so. A hoisting package manager hides this; the\n * project declaring it is what makes the declaration bind under all of them.\n *\n * `devDependencies`, because that is the whole of what it is: a type-only\n * augmentation target. No application code imports it, and `@penvhq/penv`\n * carries its own copy of the runtime — so the PRD's one runtime dependency is\n * still one.\n */\nexport const TYPES_PACKAGE = \"@penvhq/core\";\n\nexport type PackageManager = \"pnpm\" | \"npm\" | \"yarn\" | \"bun\";\n\n/** The lockfile that names each manager, checked in this order. */\nconst LOCKFILES: readonly (readonly [PackageManager, string])[] = [\n [\"pnpm\", \"pnpm-lock.yaml\"],\n [\"yarn\", \"yarn.lock\"],\n [\"bun\", \"bun.lock\"],\n [\"bun\", \"bun.lockb\"],\n [\"npm\", \"package-lock.json\"],\n];\n\n/** How each manager is told to add a package. */\nconst ADD: Readonly<Record<PackageManager, readonly [string, string]>> = {\n pnpm: [\"pnpm\", \"add\"],\n npm: [\"npm\", \"install\"],\n yarn: [\"yarn\", \"add\"],\n bun: [\"bun\", \"add\"],\n};\n\n/** How each manager is told to write the version down exactly, with no range. */\nconst EXACT: Readonly<Record<PackageManager, string>> = {\n pnpm: \"--save-exact\",\n npm: \"--save-exact\",\n yarn: \"--exact\",\n bun: \"--exact\",\n};\n\n/** How each manager is told to keep the dependency in the block it is already in. */\nconst DEV: Readonly<Record<PackageManager, string>> = {\n pnpm: \"-D\",\n npm: \"--save-dev\",\n yarn: \"--dev\",\n bun: \"--dev\",\n};\n\n/** pnpm refuses an install at a workspace root without this — `ERR_PNPM_ADDING_TO_ROOT`. */\nconst WORKSPACE_ROOT_FLAG = \"-w\";\n\n/** pnpm's workspace file, which is both what declares the members and what makes the root refuse. */\nconst PNPM_WORKSPACE = \"pnpm-workspace.yaml\";\n\n/** One package the adopted project needs, and what its `package.json` says today. */\nexport interface InstallPackage {\n readonly name: string;\n readonly version: string;\n /** What `package.json` already says about it, when it says anything. */\n readonly declared?: string;\n /** True when this project already has it — nothing to install for this one. */\n readonly satisfied: boolean;\n}\n\n/** One `package.json` the install rewrites, and the command that rewrites it. */\nexport interface InstallStep {\n /** The file the diff names — `package.json`, or a workspace package's path to it. */\n readonly manifest: string;\n /** Everything this file needs, in the order the diff shows them. */\n readonly packages: readonly InstallPackage[];\n /** The command, argv-shaped — run from the project root, whichever file it writes. */\n readonly command: readonly string[];\n /** The block this step writes into, which is what the diff shows. */\n readonly dev: boolean;\n /**\n * True when that block is already in the file. The diff then shows it as the\n * context it is, without a `+`: claiming to create a `devDependencies` beside\n * fourteen entries is the one line in an otherwise literal diff that a reader\n * would go and check by hand.\n */\n readonly blockPresent: boolean;\n /** True when this file already declares every one of them. */\n readonly satisfied: boolean;\n}\n\nexport interface InstallPlan {\n readonly root: string;\n readonly manager: PackageManager;\n /**\n * The root's `package.json` — one step per block it writes, since one command\n * names one — then one per workspace package that declares the runtime package\n * or the types package itself.\n */\n readonly steps: readonly InstallStep[];\n /** The lockfile the manager will rewrite, when the project has one. */\n readonly lockfile?: string;\n /** True when every step is already satisfied — nothing to install. */\n readonly satisfied: boolean;\n}\n\n/** Runs an install plan, or throws. Replaced in tests; never spawns there. */\nexport type InstallRuntime = (plan: InstallPlan) => Promise<void>;\n\n/**\n * The engine's own version, read from its manifest rather than restated in the\n * source: `@penvhq/penv` must match the engine exactly, and a constant beside\n * the version a release bumps is a second answer waiting to drift.\n */\nexport function engineVersion(): string {\n const version = ownManifest()?.version;\n if (typeof version === \"string\" && version.length > 0) {\n return version;\n }\n throw new PenvError(\n \"ENGINE_VERSION_UNREADABLE\",\n \"penv could not read its own version, so it cannot say which `@penvhq/penv` this project needs\",\n `Reinstall penv, then run \\`penv init\\` again.`,\n );\n}\n\n/**\n * The zod an adopted project installs: the floor of the peer range the engine\n * and `@penvhq/penv` both declare, which is the version penv is built and tested\n * against.\n *\n * The floor rather than the range, because the diff shown before the install has\n * to be the line that actually lands — `--save-exact` on `^4.4.3` would write\n * whatever the registry resolved that day, which is not something a reader can\n * consent to in advance.\n */\nexport function schemaPackageVersion(): string {\n const peers = ownManifest()?.peerDependencies;\n const declared =\n peers !== null && typeof peers === \"object\" && !Array.isArray(peers)\n ? (peers as Record<string, unknown>)[SCHEMA_PACKAGE]\n : undefined;\n const floor = typeof declared === \"string\" ? declared.replace(/^[\\^~>=\\s]+/, \"\").trim() : \"\";\n if (floor.length > 0) {\n return floor;\n }\n throw new PenvError(\n \"ENGINE_PEER_UNREADABLE\",\n `penv could not read its own \\`${SCHEMA_PACKAGE}\\` peer range, so it cannot say which ${SCHEMA_PACKAGE} this project needs`,\n `Reinstall penv, then run \\`penv init\\` again.`,\n );\n}\n\n/** The engine's own manifest, or `undefined` when it cannot be read. */\nfunction ownManifest(): Record<string, unknown> | undefined {\n try {\n const parsed: unknown = JSON.parse(\n readFileSync(new URL(\"../package.json\", import.meta.url), \"utf8\"),\n );\n return parsed !== null && typeof parsed === \"object\" && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : undefined;\n } catch {\n // The callers refuse: a version penv guessed would pin a project's\n // dependency to something nobody chose.\n return undefined;\n }\n}\n\n/** The package manager this project already uses: its lockfile, then what it declares, then npm. */\nexport function detectPackageManager(root: string): PackageManager {\n for (const [manager, lockfile] of LOCKFILES) {\n if (existsSync(join(root, lockfile))) {\n return manager;\n }\n }\n return declaredManager(root) ?? \"npm\";\n}\n\n/** `\"packageManager\": \"pnpm@9.1.0\"` — corepack's field, and a project's own answer. */\nfunction declaredManager(root: string): PackageManager | undefined {\n const declared = manifestOf(root)?.packageManager;\n if (typeof declared !== \"string\") {\n return undefined;\n }\n const name = declared.split(\"@\")[0];\n return name === \"pnpm\" || name === \"npm\" || name === \"yarn\" || name === \"bun\" ? name : undefined;\n}\n\nfunction manifestOf(root: string): Record<string, unknown> | undefined {\n const file = join(root, \"package.json\");\n if (!existsSync(file)) {\n return undefined;\n }\n try {\n const manifest: unknown = JSON.parse(readFileSync(file, \"utf8\"));\n return manifest !== null && typeof manifest === \"object\" && !Array.isArray(manifest)\n ? (manifest as Record<string, unknown>)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** What one `package.json` says about a package today, and which block says it. */\ninterface Declaration {\n readonly version: string;\n /** True when it sits in `devDependencies` — where an install has to leave it. */\n readonly dev: boolean;\n}\n\nfunction declaredIn(dir: string, name: string): Declaration | undefined {\n const manifest = manifestOf(dir);\n for (const field of [\"dependencies\", \"devDependencies\"] as const) {\n const block: unknown = manifest?.[field];\n if (block !== null && typeof block === \"object\" && !Array.isArray(block)) {\n const version: unknown = (block as Record<string, unknown>)[name];\n if (typeof version === \"string\") {\n return { version, dev: field === \"devDependencies\" };\n }\n }\n }\n return undefined;\n}\n\n/** True when `package.json` already has the block a step writes into. */\nfunction blockPresentIn(dir: string, dev: boolean): boolean {\n const block: unknown = manifestOf(dir)?.[dev ? \"devDependencies\" : \"dependencies\"];\n return block !== null && typeof block === \"object\" && !Array.isArray(block);\n}\n\n/** True when `root` is the root of a pnpm workspace, which is what `-w` is for. */\nexport function isPnpmWorkspaceRoot(root: string): boolean {\n return existsSync(join(root, PNPM_WORKSPACE)) && existsSync(join(root, \"package.json\"));\n}\n\n/** The `packages:` list from `pnpm-workspace.yaml`, block or flow form. */\nfunction workspaceGlobs(root: string): string[] {\n let text: string;\n try {\n text = readFileSync(join(root, PNPM_WORKSPACE), \"utf8\");\n } catch {\n return [];\n }\n const unquote = (raw: string): string => raw.replace(/^['\"]|['\"]$/g, \"\").trim();\n const globs: string[] = [];\n let inside = false;\n for (const line of text.split(/\\r?\\n/)) {\n const flow = /^packages:\\s*\\[(.*)\\]\\s*$/.exec(line);\n if (flow?.[1] !== undefined) {\n return flow[1]\n .split(\",\")\n .map(unquote)\n .filter((glob) => glob !== \"\");\n }\n if (/^packages:\\s*$/.test(line)) {\n inside = true;\n continue;\n }\n if (!inside) {\n continue;\n }\n const item = /^\\s+-\\s*(.+?)\\s*$/.exec(line);\n if (item?.[1] !== undefined) {\n globs.push(unquote(item[1]));\n continue;\n }\n if (line.trim() !== \"\" && !line.trimStart().startsWith(\"#\")) {\n break;\n }\n }\n return globs;\n}\n\nfunction directoriesIn(dir: string): string[] {\n try {\n return readdirSync(dir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() && entry.name !== \"node_modules\")\n .map((entry) => join(dir, entry.name));\n } catch {\n return [];\n }\n}\n\nfunction isDirectory(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** `packages/*` and `apps/**` against the filesystem, one path segment at a time. */\nfunction expandGlob(root: string, glob: string): string[] {\n let dirs = [root];\n for (const segment of glob.split(\"/\").filter((part) => part !== \"\" && part !== \".\")) {\n const next: string[] = [];\n for (const dir of dirs) {\n if (segment === \"**\") {\n const stack = [dir];\n while (stack.length > 0) {\n const current = stack.pop() as string;\n next.push(current);\n stack.push(...directoriesIn(current));\n }\n continue;\n }\n if (segment.includes(\"*\")) {\n const pattern = new RegExp(\n `^${segment.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \"[^/]*\")}$`,\n );\n next.push(\n ...directoriesIn(dir).filter((child) => pattern.test(child.slice(dir.length + 1))),\n );\n continue;\n }\n const candidate = join(dir, segment);\n if (isDirectory(candidate)) {\n next.push(candidate);\n }\n }\n dirs = next;\n }\n return dirs;\n}\n\n/**\n * Every workspace package that declares `name` itself, root excluded — asked\n * once for `@penvhq/penv` and once for `@penvhq/core`, since a member holding\n * its own copy of either is a second version running under one pin.\n *\n * Only the ones that already declare it: penv moves a dependency a package\n * chose, and adding one to a package that never asked for it is a different\n * decision than the one being consented to.\n */\nfunction workspaceMembers(root: string, name: string): string[] {\n if (!isPnpmWorkspaceRoot(root)) {\n return [];\n }\n const globs = workspaceGlobs(root);\n const excluded = globs\n .filter((glob) => glob.startsWith(\"!\"))\n .flatMap((glob) => expandGlob(root, glob.slice(1)));\n const found = new Set<string>();\n for (const glob of globs.filter((entry) => !entry.startsWith(\"!\"))) {\n for (const dir of expandGlob(root, glob)) {\n if (dir !== root && !excluded.includes(dir) && declaredIn(dir, name) !== undefined) {\n found.add(dir);\n }\n }\n }\n return [...found].sort();\n}\n\n/** The path a diff shows for one of them, in the spelling every penv path uses. */\nfunction manifestPathOf(root: string, dir: string): string {\n const within = relative(root, dir)\n .split(sep)\n .filter((part) => part !== \"\");\n return [...within, \"package.json\"].join(\"/\");\n}\n\nfunction addCommand(\n manager: PackageManager,\n options: { readonly filter?: string; readonly workspaceRoot: boolean; readonly dev: boolean },\n specs: readonly string[],\n): string[] {\n const [bin, verb] = ADD[manager];\n return [\n bin,\n ...(options.filter === undefined ? [] : [\"--filter\", options.filter]),\n verb,\n ...(options.workspaceRoot ? [WORKSPACE_ROOT_FLAG] : []),\n EXACT[manager],\n ...(options.dev ? [DEV[manager]] : []),\n ...specs,\n ];\n}\n\nfunction stepFor(\n manager: PackageManager,\n manifest: string,\n packages: readonly InstallPackage[],\n options: {\n readonly filter?: string;\n readonly workspaceRoot: boolean;\n readonly dev: boolean;\n readonly dir: string;\n },\n): InstallStep {\n const pending = packages.filter((entry) => !entry.satisfied);\n const specs = (pending.length === 0 ? packages : pending).map(\n (entry) => `${entry.name}@${entry.version}`,\n );\n return {\n manifest,\n packages,\n command: addCommand(manager, options, specs),\n dev: options.dev,\n blockPresent: blockPresentIn(options.dir, options.dev),\n satisfied: pending.length === 0,\n };\n}\n\nexport function planInstall(root: string, version: string = engineVersion()): InstallPlan {\n const manager = detectPackageManager(root);\n const lockfile = LOCKFILES.find(\n ([name, file]) => name === manager && existsSync(join(root, file)),\n )?.[1];\n const workspaceRoot = manager === \"pnpm\" && isPnpmWorkspaceRoot(root);\n\n const runtime = declaredIn(root, RUNTIME_PACKAGE);\n const zod = declaredIn(root, SCHEMA_PACKAGE);\n const types = declaredIn(root, TYPES_PACKAGE);\n const packages: InstallPackage[] = [\n {\n name: RUNTIME_PACKAGE,\n version,\n ...(runtime === undefined ? {} : { declared: runtime.version }),\n satisfied: runtime?.version === version,\n },\n {\n name: SCHEMA_PACKAGE,\n version: schemaPackageVersion(),\n ...(zod === undefined ? {} : { declared: zod.version }),\n // Any declared zod counts: which zod a project uses is the project's\n // decision, and penv is here to make sure there is one, not to move it.\n satisfied: zod !== undefined,\n },\n ];\n const typesPackage: InstallPackage = {\n name: TYPES_PACKAGE,\n version,\n ...(types === undefined ? {} : { declared: types.version }),\n // Any declared version counts, for zod's reason: the augmentation binds on\n // the module resolving, not on which release of it a project pinned.\n satisfied: types !== undefined,\n };\n\n // The block a package chose is the block penv writes back to — but only when\n // every package this step installs lives there, since one command names one.\n // Which is also why the types package is its own step: it belongs in\n // `devDependencies` whatever the other two chose.\n const pending = packages.filter((entry) => !entry.satisfied);\n const steps: InstallStep[] = [\n stepFor(manager, \"package.json\", packages, {\n workspaceRoot,\n dir: root,\n dev:\n runtime?.dev === true &&\n pending.every((entry) => entry.name === RUNTIME_PACKAGE) &&\n pending.length > 0,\n }),\n stepFor(manager, \"package.json\", [typesPackage], { workspaceRoot, dir: root, dev: true }),\n ];\n // Both packages, because a member declaring either holds its own copy of it:\n // `@penvhq/penv` is a second bridge running under the pin, and `@penvhq/core`\n // is a second copy of the interfaces every committed declaration augments.\n for (const name of [RUNTIME_PACKAGE, TYPES_PACKAGE]) {\n for (const dir of workspaceMembers(root, name)) {\n const declared = declaredIn(dir, name) as Declaration;\n steps.push(\n stepFor(\n manager,\n manifestPathOf(root, dir),\n [\n {\n name,\n version,\n declared: declared.version,\n satisfied: declared.version === version,\n },\n ],\n {\n filter: `./${relative(root, dir).split(sep).join(\"/\")}`,\n workspaceRoot: false,\n dir,\n dev: declared.dev,\n },\n ),\n );\n }\n }\n\n return {\n root,\n manager,\n steps,\n ...(lockfile === undefined ? {} : { lockfile }),\n satisfied: steps.every((step) => step.satisfied),\n };\n}\n\nfunction describe(entry: InstallPackage): string {\n return `${entry.name} ${entry.version}`;\n}\n\n/** What this plan actually installs, once per package however many files declare it. */\nexport function installedPackages(plan: InstallPlan): readonly InstallPackage[] {\n const pending = plan.steps.flatMap((step) => step.packages).filter((entry) => !entry.satisfied);\n return [...new Map(pending.map((entry) => [entry.name, entry])).values()];\n}\n\n/** One file the plan wrote, and what landed in it. */\nexport interface InstalledManifest {\n readonly manifest: string;\n /** `@penvhq/penv 1.2.3 and @penvhq/core 1.2.3` — every package this file gained. */\n readonly packages: string;\n}\n\n/**\n * What the install landed, one entry per `package.json`.\n *\n * Per file rather than per step, because the root is two steps and a file is\n * what the reader recognises — and every package in it, because a caller\n * confirming only the one it happened to name leaves the release's own new\n * dependency unmentioned in the lines that say the upgrade worked.\n */\nexport function installedByManifest(plan: InstallPlan): readonly InstalledManifest[] {\n const byManifest = new Map<string, InstallPackage[]>();\n for (const step of plan.steps.filter((entry) => !entry.satisfied)) {\n const landed = byManifest.get(step.manifest) ?? [];\n landed.push(...step.packages.filter((entry) => !entry.satisfied));\n byManifest.set(step.manifest, landed);\n }\n return [...byManifest].map(([manifest, packages]) => ({\n manifest,\n packages: series(\n [...new Map(packages.map((entry) => [entry.name, entry])).values()].map(describe),\n ),\n }));\n}\n\n/** Every package the plan names, once each — the root's blocks are two steps now. */\nfunction plannedPackages(plan: InstallPlan): readonly InstallPackage[] {\n const all = plan.steps.flatMap((step) => step.packages);\n return [...new Map(all.map((entry) => [entry.name, entry])).values()];\n}\n\n/** `a`, `a and b`, `a, b and c`. */\nfunction series(values: readonly string[]): string {\n return values.length < 2\n ? (values[0] ?? \"\")\n : `${values.slice(0, -1).join(\", \")} and ${values.at(-1) as string}`;\n}\n\n/** The lines one `package.json` contributes to the diff. */\nfunction renderStep(step: InstallStep): string[] {\n const pending = step.packages.filter((entry) => !entry.satisfied);\n const added = pending.filter((entry) => entry.declared === undefined);\n const replaced = pending.filter((entry) => entry.declared !== undefined);\n const block = step.dev ? \"devDependencies\" : \"dependencies\";\n // The block's own lines are an insertion only when the block is not there yet.\n const edge = step.blockPresent ? \" \" : \" +\";\n return [\n step.manifest,\n ...(added.length === 0\n ? []\n : [\n `${edge} \"${block}\": {`,\n ...added.map((entry) => ` + \"${entry.name}\": \"${entry.version}\"`),\n `${edge} }`,\n ]),\n ...replaced.flatMap((entry) => [\n ` - \"${entry.name}\": \"${entry.declared}\"`,\n ` + \"${entry.name}\": \"${entry.version}\"`,\n ]),\n ];\n}\n\n/**\n * The change, as it will appear in the diff — the whole point of showing it is\n * that the reader recognises their own file, so these are the `package.json`\n * lines that land and the lockfile that gets rewritten, not a summary of both.\n *\n * In a workspace that is more than one file, and the commands underneath are the\n * ones that run: a \"Run with:\" line the reader cannot paste is worse than none.\n */\nexport function renderInstallPlan(plan: InstallPlan): string[] {\n if (plan.satisfied) {\n return [\n `package.json already has ${series(plannedPackages(plan).map(describe))} — nothing to install.`,\n ];\n }\n const pending = plan.steps.filter((step) => !step.satisfied);\n const [first, ...rest] = pending.map((step) => step.command.join(\" \"));\n const landing = installedPackages(plan).map((entry) => ` + ${entry.name}@${entry.version}`);\n return [\n ...pending.flatMap(renderStep),\n ...(plan.lockfile === undefined ? [] : [plan.lockfile, ...landing]),\n \"\",\n `Run with: ${first ?? \"\"}`,\n ...rest.map((command) => ` then ${command}`),\n ];\n}\n\n/**\n * The real install: the project's own package manager, started the way any other\n * child is (`.cmd` shims on Windows included), with its output the user's to see.\n *\n * Every step runs from the project root — `-w` and `--filter` are how a workspace\n * says which `package.json` it means, so the directory never changes.\n */\nexport const installWithPackageManager: InstallRuntime = async (plan) => {\n for (const step of plan.steps) {\n if (step.satisfied) {\n continue;\n }\n const child = startChild({\n command: step.command,\n env: process.env as Record<string, string>,\n cwd: plan.root,\n purpose: `install ${step.packages.map(describe).join(\" and \")} in ${step.manifest}`,\n });\n const ended = await child.ended;\n if (ended.exitCode !== 0 || ended.signal !== null) {\n throw installFailed(plan, step);\n }\n }\n};\n\n/**\n * What to do about a package manager that refused.\n *\n * Never the command that just failed: the one remediation guaranteed not to work\n * is the one the reader already ran. The manager said why, on their screen, and\n * nothing was migrated — so the answer is that line and a second `penv init`.\n */\nexport function installFailed(plan: InstallPlan, step: InstallStep): PenvError {\n return new PenvError(\n \"INIT_INSTALL_FAILED\",\n `${step.command.join(\" \")} did not finish, so penv migrated nothing`,\n `Read what ${plan.manager} printed above — it names what it refused. Fix that and run this ` +\n \"command again; your dotenv files are exactly where they were.\",\n );\n}\n","/**\n * Starting someone else's command, opaquely.\n *\n * `penv run -- <command>` starts exactly what follows `--`: the argument\n * boundaries the shell already worked out are handed to the operating system\n * untouched, stdio is the parent's, and the child's exit code and terminating\n * signal come back out. penv never parses the command, never rebuilds a command\n * line from it, never wraps it in a shell — a shell would re-split what the user\n * already split, and `penv run -- node -e \"console.log(1 > 2)\"` would redirect to\n * a file called `2`.\n *\n * Windows is the one place where \"hand it to the operating system\" needs help.\n * `pnpm`, `next` and every other node-installed tool are `.cmd` shims there, and\n * Node refuses to execute one without a shell. So a `.cmd`/`.bat` target — and\n * only that — is started through `cmd.exe /d /s /c` with\n * `windowsVerbatimArguments`, building the one command line cmd will accept and\n * escaping every argument so that cmd hands the child the same bytes penv was\n * given. Everything else spawns directly, on every platform.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { delimiter, isAbsolute, join, win32 } from \"node:path\";\nimport { PenvError } from \"@penvhq/core\";\n\n/** How a child ended. Exactly one of these is meaningful, and both are forwarded. */\nexport interface ChildResult {\n /** The child's own exit code, or 1 when a signal ended it. */\n readonly exitCode: number;\n /** The signal that ended the child, when one did. */\n readonly signal: NodeJS.Signals | null;\n}\n\nexport interface ChildInvocation {\n /** The command exactly as it followed `--`: the executable, then its arguments. */\n readonly command: readonly string[];\n readonly env: Record<string, string>;\n readonly cwd: string;\n /**\n * What penv is starting this on its own behalf to do — `init`'s dependency\n * install. Absent means the command is the user's, from after `--`, and the\n * two failures have opposite remedies: one is about what they typed, the other\n * about a program penv chose to run.\n */\n readonly purpose?: string;\n}\n\n/** A started child: how it ends, and the one thing a wrapper may do to it. */\nexport interface ChildHandle {\n /** Resolves when the child has ended, however it ended. */\n readonly ended: Promise<ChildResult>;\n /** Asks the child to stop — what `--watch` does before it starts the next one. */\n kill(signal?: NodeJS.Signals): void;\n}\n\n/** The seam `run` starts a child through — replaced in tests that assert what it was given. */\nexport type StartChild = (invocation: ChildInvocation) => ChildHandle;\n\n/** The signals a wrapper must pass through rather than absorb. */\nconst FORWARDED: readonly NodeJS.Signals[] = [\"SIGINT\", \"SIGTERM\", \"SIGHUP\", \"SIGBREAK\"];\n\nexport const startChild: StartChild = (invocation) => {\n const [executable, ...args] = invocation.command;\n if (executable === undefined) {\n throw noCommand();\n }\n\n const target = resolveTarget(executable, args, invocation.env);\n const child = spawn(target.file, target.args, {\n cwd: invocation.cwd,\n env: invocation.env,\n stdio: \"inherit\",\n ...(target.verbatim ? { windowsVerbatimArguments: true } : {}),\n });\n\n // Forwarded rather than handled: penv is a wrapper, and a Ctrl-C belongs to\n // the program the user is looking at. The child decides what to do with it,\n // and its answer comes back as the signal below.\n const forward = new Map<NodeJS.Signals, () => void>();\n for (const signal of FORWARDED) {\n const handler = (): void => {\n child.kill(signal);\n };\n forward.set(signal, handler);\n process.on(signal, handler);\n }\n const release = (): void => {\n for (const [signal, handler] of forward) {\n process.off(signal, handler);\n }\n };\n\n const ended = new Promise<ChildResult>((resolve, reject) => {\n child.on(\"error\", (cause) => {\n release();\n reject(cannotStart(executable, cause, invocation.purpose));\n });\n child.on(\"exit\", (code, signal) => {\n release();\n resolve({ exitCode: code ?? 1, signal });\n });\n });\n\n return {\n ended,\n kill(signal) {\n child.kill(signal);\n },\n };\n};\n\nexport function noCommand(): PenvError {\n return new PenvError(\n \"RUN_NO_COMMAND\",\n \"`penv run` was given no command to start\",\n \"Put the command after `--`, e.g. `penv run -- pnpm dev`.\",\n );\n}\n\nfunction cannotStart(executable: string, cause: unknown, purpose: string | undefined): PenvError {\n const detail = cause instanceof Error ? cause.message : String(cause);\n if (purpose !== undefined) {\n return new PenvError(\n \"PENV_COMMAND_NOT_STARTED\",\n `penv could not start \\`${executable}\\` to ${purpose}: ${detail}`,\n `Check that \\`${executable}\\` runs on its own — penv starts it the way your shell does, so it has to be on PATH. Nothing was changed.`,\n );\n }\n return new PenvError(\n \"RUN_COMMAND_NOT_STARTED\",\n `\\`${executable}\\` could not be started: ${detail}`,\n `Check the command after \\`--\\` runs on its own — \\`${executable}\\` has to be on PATH, exactly as it is spelled here.`,\n );\n}\n\ninterface SpawnTarget {\n readonly file: string;\n readonly args: readonly string[];\n /** True when the args are one pre-built command line rather than a list. */\n readonly verbatim: boolean;\n}\n\nfunction resolveTarget(\n executable: string,\n args: readonly string[],\n env: Readonly<Record<string, string | undefined>>,\n): SpawnTarget {\n if (process.platform !== \"win32\") {\n return { file: executable, args, verbatim: false };\n }\n const resolved = findExecutable(executable, env);\n if (resolved === undefined || !/\\.(cmd|bat)$/i.test(resolved)) {\n return { file: resolved ?? executable, args, verbatim: false };\n }\n return {\n file: env.ComSpec ?? \"cmd.exe\",\n args: [\"/d\", \"/s\", \"/c\", `\"${cmdCommandLine(resolved, args)}\"`],\n verbatim: true,\n };\n}\n\n/** A package-manager shim, which re-invokes cmd on its own way through. */\nconst SHIM = /(?:^|\\\\)node_modules\\\\\\.bin\\\\[^\\\\]+\\.cmd$/i;\n\n/**\n * The one command line cmd.exe is handed, escaped so the child receives the\n * bytes penv was given.\n *\n * The path is normalized first and *then* judged: `./node_modules/.bin/next.cmd`\n * and `.\\node_modules\\.bin\\next.cmd` are the same shim, and deciding on the\n * un-normalized spelling would escape a forward-slash invocation once while cmd\n * expands it twice — so an argument holding `&` would run as a command inside\n * the shim's second round. Windows' own separator, whatever this process runs\n * on, because this line is only ever read by cmd.exe.\n */\nexport function cmdCommandLine(resolved: string, args: readonly string[]): string {\n const command = win32.normalize(resolved);\n const shim = SHIM.test(command);\n return [escapeCommand(command), ...args.map((argument) => escapeArgument(argument, shim))].join(\n \" \",\n );\n}\n\n/**\n * The extensions a name is tried with, in the order the platform's own launcher\n * tries them.\n *\n * On Windows PATHEXT leads and the bare name comes last, because the bare name\n * is almost never what Windows would run: `pnpm`, `npx` and every\n * `node_modules/.bin` tool ship an extensionless POSIX shell script *beside*\n * their `.CMD` shim, in the same directory. Trying the empty extension first\n * matched that script, which is not executable by CreateProcess and is not a\n * `.cmd`, so the wrapper below was skipped and the spawn failed with ENOENT.\n * Everywhere else there are no extensions at all.\n */\nfunction extensions(\n env: Readonly<Record<string, string | undefined>>,\n platform: NodeJS.Platform,\n): string[] {\n if (platform !== \"win32\") {\n return [\"\"];\n }\n const declared = env.PATHEXT ?? \".COM;.EXE;.BAT;.CMD\";\n return [...declared.split(\";\").filter((extension) => extension.length > 0), \"\"];\n}\n\n/**\n * What the shell would have run, found the way the shell finds it: the name as\n * given if it carries a path, else each PATH directory, each with each\n * executable extension.\n *\n * `platform` is a parameter so the ordering above is testable on either kind of\n * machine — it is the whole behavior, and it differs by platform.\n */\nexport function findExecutable(\n executable: string,\n env: Readonly<Record<string, string | undefined>>,\n platform: NodeJS.Platform = process.platform,\n): string | undefined {\n const candidates = extensions(env, platform);\n const isFile = (path: string): boolean => existsSync(path) && statSync(path).isFile();\n\n if (executable.includes(\"/\") || executable.includes(\"\\\\\") || isAbsolute(executable)) {\n return candidates.map((extension) => executable + extension).find(isFile);\n }\n const path = env.PATH ?? env.Path ?? \"\";\n for (const directory of path.split(delimiter).filter((entry) => entry.length > 0)) {\n const hit = candidates.map((extension) => join(directory, executable + extension)).find(isFile);\n if (hit !== undefined) {\n return hit;\n }\n }\n return undefined;\n}\n\n/** The characters cmd.exe expands before the program ever sees them. */\nconst CMD_METACHARACTERS = /([()\\][%!^\"`<>&|;, *?])/g;\n\n/** The command's own path: cmd's metacharacters escaped, and no quotes to confuse it. */\nfunction escapeCommand(command: string): string {\n return command.replace(CMD_METACHARACTERS, \"^$1\");\n}\n\n/**\n * One argument, quoted so the child's runtime splits it exactly where penv was\n * given it, then escaped so cmd.exe passes those quotes through instead of\n * acting on them.\n */\nfunction escapeArgument(argument: string, doubleEscape: boolean): string {\n const quoted = `\"${argument.replace(/(\\\\*)\"/g, '$1$1\\\\\"').replace(/(\\\\*)$/, \"$1$1\")}\"`;\n const escaped = quoted.replace(CMD_METACHARACTERS, \"^$1\");\n return doubleEscape ? escaped.replace(CMD_METACHARACTERS, \"^$1\") : escaped;\n}\n","/**\n * Opening a penv project from a working directory, and the pieces every command\n * needs once it is open: the config, the environment to act on, the provider\n * rooted at the records tree, and the parameter a CLI key names.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type {\n AnyProvider,\n DecryptFailure,\n KeySource,\n ParameterRef,\n PenvConfig,\n Provider,\n ResolutionCandidate,\n} from \"@penvhq/core\";\nimport {\n assertMigrated,\n candidatesFor,\n environmentEntry,\n formatValueFile,\n isCanonicalSegment,\n isReservedToken,\n loadConfig,\n openValue,\n PenvError,\n parameterId,\n ReservedTokenError,\n recordsDir,\n refFromAccessPath,\n resolveEnvironment,\n resolveKeySource,\n SCHEMA_SHAPE_FILE,\n schemaFileOf,\n} from \"@penvhq/core\";\nimport { FilesystemProvider } from \"@penvhq/provider-filesystem\";\nimport { environmentFromShorthand } from \"./env-flags.js\";\nimport {\n assertProvidersRegistered,\n createProvider,\n createSourceProvider,\n LOCAL_TREE_TYPE,\n} from \"./registry.js\";\n\nexport interface Project {\n /** The directory holding `penv.config.ts`. */\n readonly root: string;\n readonly configFile: string;\n readonly config: PenvConfig;\n /** The parameter tree, absolute — `.penv/state/records/`. */\n readonly recordsDir: string;\n /**\n * The project's provider, as the contract — never the concrete\n * implementation. Shared commands speak the async interface and nothing more;\n * the sync twins a command genuinely needs are reached through `localTree`,\n * which is the one place the filesystem-only surface is named.\n */\n readonly provider: Provider;\n}\n\nexport function openProject(cwd: string): Project {\n const { config, file } = loadConfig(cwd);\n const root = dirname(file);\n // A project whose records still sit directly under `.penv/` is refused here,\n // once, rather than read as an empty tree by every command downstream.\n assertMigrated(root, config);\n // Refuse a config naming a provider this build cannot construct here, at open\n // time, rather than as a crash from whichever command first reached it. Plugin\n // types are resolved against the project (`root`), where the user installed them.\n assertProvidersRegistered(config, root);\n return {\n root,\n configFile: file,\n config,\n recordsDir: recordsDir(root),\n provider: createProvider(LOCAL_TREE_TYPE, { root, config }),\n };\n}\n\n/**\n * The project's provider as the concrete filesystem tree, for the sync reads and\n * writes a synchronous command cannot get from the async contract.\n *\n * `import`, `generate`, and `push` are synchronous — they are the adoption path\n * and the leaving guarantee — and they act on the local `.penv` tree, which is\n * always the filesystem provider (`penv pull` materialises it; the runtime reads\n * it). This narrows to that provider and names the reliance, so the type of\n * `Project.provider` stays the contract everywhere else. The refusal is a\n * belt-and-braces guard: `openProject` builds the tree as filesystem, so a\n * project in hand always narrows.\n */\nexport function localTree(project: Project): FilesystemProvider {\n if (!(project.provider instanceof FilesystemProvider)) {\n throw new PenvError(\n \"PROVIDER_NOT_LOCAL\",\n `This command reads the local .penv tree synchronously, which the \\`${project.provider.type}\\` provider is not`,\n \"Run this against a filesystem-backed project, or use a command that speaks the async provider contract.\",\n );\n }\n return project.provider;\n}\n\n/**\n * The module `schemaFile` names, when it carries the schema shape itself rather\n * than importing it — a project scaffolded before the shape/loader split, whose\n * `.penv/env.ts` (or wherever `schemaFile` points) defines its own `z.object`.\n * Returns that path; `undefined` when there is no such file, or when it is the\n * thin wrapper the current scaffold writes, which imports the shape and declares\n * no `z.object` of its own.\n *\n * Detection is by two markers, because the released layouts differ. penv 0.5+\n * scaffolded a `PenvSchemaShape` augmentation into the self-contained module;\n * penv <= 0.4 scaffolded `export const schema = z.object(...)` with no\n * augmentation at all. Either marker means the module declares its own shape; the\n * current wrapper (a re-export and a `load` call) carries neither.\n */\nexport function selfContainedSchemaModule(root: string, schemaFile: string): string | undefined {\n const file = join(root, ...schemaFile.split(\"/\"));\n if (!existsSync(file)) {\n return undefined;\n }\n const source = readFileSync(file, \"utf8\");\n return source.includes(\"PenvSchemaShape\") || source.includes(\"z.object\") ? schemaFile : undefined;\n}\n\n/**\n * The file that holds the editable schema shape, cohort-aware.\n *\n * A project scaffolded on the split keeps the `z.object` in `penv.schema.ts` and\n * a thin loader in `schemaFile`; one scaffolded before it keeps the shape\n * self-contained in `schemaFile` (invariant 2 — penv never rewrites either layout\n * into the other). Every message that tells the user where to edit the shape must\n * name the file that actually holds it, not a hard-coded path that is wrong for\n * whichever cohort it is not from — the same rule `writeSchemaShapeFile` follows\n * when it keeps an old-layout schema in place rather than standing a second one\n * beside it.\n */\nexport function schemaShapeFileOf(project: Project): string {\n const schemaFile = schemaFileOf(project.config);\n return selfContainedSchemaModule(project.root, schemaFile) ?? SCHEMA_SHAPE_FILE;\n}\n\n/**\n * The environment's DECLARED source-of-truth provider — the backend that holds\n * the truth, as opposed to `Project.provider`, which is always the local\n * filesystem tree every command edits.\n *\n * `pull` and cross-provider `doctor` read here: they compare or copy against what\n * the config says the environment's values live in. An undeclared environment has\n * no separate source of truth, so this falls back to the local tree — the two\n * coincide, and there is nothing to pull from elsewhere. `openProject` is\n * untouched: the working copy stays filesystem regardless.\n */\nexport async function sourceProviderFor(\n project: Project,\n environment: string,\n): Promise<AnyProvider> {\n const providerConfig = environmentEntry(project.config, environment);\n if (providerConfig === undefined) {\n return createProvider(LOCAL_TREE_TYPE, { root: project.root, config: project.config });\n }\n // A declared backend may be a plugin (`penv-cloud`, a third-party provider), so\n // this goes through the async, plugin-aware path rather than the built-in-only\n // `createProvider`. The local tree above is always a built-in and stays sync.\n // The result may hold records or a projection — callers narrow through\n // `holdsRecords`/`holdsProjection` and never call a method the capability\n // declaration did not promise.\n return createSourceProvider(providerConfig.provider, {\n root: project.root,\n config: project.config,\n providerConfig,\n environment,\n });\n}\n\n/**\n * The environment to act on: `--env` (or a whitelisted shorthand flag like\n * `--production`), then `PENV_ENV`, then `NODE_ENV`. `shorthand` carries the\n * bare flags the command did not declare, judged here against the whitelist —\n * the config interprets flags, it never parses them.\n */\nexport function targetEnvironment(\n project: Project,\n explicit?: string,\n shorthand?: readonly string[],\n): string {\n const fromFlags =\n shorthand === undefined\n ? undefined\n : environmentFromShorthand(project.config, shorthand, explicit);\n return resolveEnvironment(project.config, explicit ?? fromFlags);\n}\n\n/** A namespace separator on the command line, either spelling. */\nconst KEY_SEPARATOR = /[./\\\\]/;\n\n/**\n * The reserved set for a caller that has no config to hand: the static tokens\n * and nothing else. Environments are a config whitelist (invariant 10), so a\n * caller without a config cannot know which environment names are reserved.\n */\nconst NO_ENVIRONMENTS: PenvConfig = { environments: {} };\n\n/**\n * The parameter a CLI key names — `redis/password` and `redis.password` are one.\n *\n * `config` is optional because the reserved set is config-driven: given one,\n * a declared environment name is refused here too; without one, only the static\n * tokens are. Pass the open project's config whenever there is one — this is the\n * early, better-worded half of a check the filename grammar makes again when the\n * file is read, never the only half.\n */\nexport function refFromKey(key: string, config?: PenvConfig): ParameterRef {\n const segments = key.split(KEY_SEPARATOR).filter((segment) => segment.length > 0);\n const name = segments[segments.length - 1];\n if (name === undefined) {\n throw new PenvError(\n \"PARAMETER_KEY\",\n `\\`${key}\\` names no parameter`,\n \"A key is `<namespace>/<name>` or `<namespace>.<name>`, e.g. `redis/password`.\",\n );\n }\n if (isReservedToken(name, config ?? NO_ENVIRONMENTS)) {\n throw new ReservedTokenError(\"parameter\", name, key);\n }\n return { namespace: segments.slice(0, -1), name };\n}\n\n/**\n * Refuses a key that no canonical value file can back — the guard for the *write*\n * path only, `set` and the destination of `mv`.\n *\n * It lives apart from {@link refFromKey} deliberately. Read, remove and the\n * source of a rename address a file that already exists by its literal name, and\n * the filename grammar admits a non-canonical name (`dbHost`, `database_url`)\n * that the transform will never *produce* but a hand-written file or an older\n * penv may already have on disk. Guarding those paths would leave such a tree\n * repairable only by deleting the file by hand — the very lockout this function\n * is here to avoid. So only creation is refused: a `set` or a rename *into* a\n * name the schema cannot read is a file that would sit inert, and refusing it\n * early names the file that actually backs the key instead of writing a dead one.\n */\nexport function assertWritableKey(key: string): void {\n const segments = key.split(KEY_SEPARATOR).filter((s) => s.length > 0);\n if (segments.length === 0 || segments.every((s) => isCanonicalSegment(s))) {\n return;\n }\n const ref = refFromAccessPath(segments);\n if (ref !== undefined) {\n const suggestion = [...ref.namespace, ref.name].join(\"/\");\n throw new PenvError(\n \"PARAMETER_KEY_CASING\",\n `\\`${key}\\` is not a canonical parameter name`,\n `Parameter files are lower-case and hyphenated. Did you mean \\`${suggestion}\\`? That is the file that backs the \\`${key}\\` key in your schema.`,\n );\n }\n throw new PenvError(\n \"PARAMETER_KEY_UNREACHABLE\",\n `No value file can be named that reaches \\`${key}\\``,\n \"Parameter files are lower-case and hyphenated, and this key maps to no such file — a run of capitals like `apiURL` cannot be reached (use `api-url`, which the schema reads as `apiUrl`). Run `penv validate` or `penv fill` to see the names penv expects.\",\n );\n}\n\n/**\n * The key source for one environment, chosen by core.\n *\n * The CLI does not decide where keys live — it asks. Two choosers would be two\n * answers to one question, and the runtime is the other caller: a CLI that\n * sealed under a key the runtime could not find would make `penv set` and `load`\n * disagree about the same file.\n */\nexport function keySourceFor(project: Project, environment: string): KeySource {\n return resolveKeySource(project.config, environment);\n}\n\n/**\n * One parameter resolved against the filesystem, without reading it twice.\n *\n * The winner is a `ResolutionCandidate` rather than a bare `ValueFile` so this\n * satisfies core's `ResolvedValue`: the sync walk and the async one then hand the\n * same shape to the same `requireValue`, and there is one place that decides\n * what an unreadable value is.\n */\nexport interface SyncResolution {\n readonly ref: ParameterRef;\n readonly parameter: string;\n /** `undefined` when nothing is present, or when the winner did not open. */\n readonly value: string | undefined;\n readonly winner: ResolutionCandidate | undefined;\n /** Set only when the winner is `.enc` and did not decrypt. Mirrors `Resolution`. */\n readonly undecryptable?: DecryptFailure;\n}\n\n/**\n * The synchronous half of the cascade.\n *\n * `import` and `generate` are synchronous — they are the adoption path, and the\n * v0.1 gate exercises them as plain calls — while the provider contract is\n * async because a network-backed provider cannot be anything else. This walks\n * the filesystem provider's *additional* sync reads, exactly as the runtime\n * loader does for the same reason. It does not restate the precedence rule:\n * `candidatesFor` owns the order, and this only walks the list it returns.\n */\nexport function resolveSync(\n provider: FilesystemProvider,\n ref: ParameterRef,\n environment: string,\n keys: KeySource,\n skipPersonal?: boolean,\n): SyncResolution {\n for (const file of candidatesFor(ref, environment, skipPersonal)) {\n const read = provider.readSync(file);\n if (read === undefined) {\n continue;\n }\n // Unconditional, including for a plaintext file, which comes back verbatim:\n // a branch on `file.encrypted` here would be a second place deciding what\n // encryption means, and this walker is already the second walker.\n const opened = openValue(file, read, keys);\n return {\n ref,\n parameter: parameterId(ref),\n value: opened.kind === \"plaintext\" ? opened.value : undefined,\n ...(opened.kind === \"failed\" ? { undecryptable: opened.failure } : {}),\n winner: { file, location: formatValueFile(file), present: true },\n };\n }\n return { ref, parameter: parameterId(ref), value: undefined, winner: undefined };\n}\n\nexport function resolveAllSync(\n provider: FilesystemProvider,\n environment: string,\n keys: KeySource,\n skipPersonal?: boolean,\n): SyncResolution[] {\n return refsFrom(provider.listSync()).map((ref) =>\n resolveSync(provider, ref, environment, keys, skipPersonal),\n );\n}\n\n/**\n * The parameters a provider holds, scopes collapsed and ordered identically\n * everywhere.\n */\nexport function refsFrom(files: readonly ParameterRef[]): ParameterRef[] {\n const refs = new Map<string, ParameterRef>();\n for (const file of files) {\n const ref: ParameterRef = { namespace: file.namespace, name: file.name };\n const id = parameterId(ref);\n if (!refs.has(id)) {\n refs.set(id, ref);\n }\n }\n // Code-unit order, not locale order: a report must be identical on every machine.\n return [...refs.values()].sort((a, b) => {\n const left = parameterId(a);\n const right = parameterId(b);\n return left < right ? -1 : left > right ? 1 : 0;\n });\n}\n","/**\n * Environment shorthand flags: `penv pull --production` for any environment the\n * config whitelists.\n *\n * User-defined names land in penv's flag namespace under three rules that keep\n * the two from ever fighting:\n *\n * 1. **A real flag always wins.** Candidates are collected *after* every flag\n * the command declares (and penv's globals) is excluded, so an environment\n * named `yes` simply has no shorthand — `--env yes` still works, and config\n * can never rebind a flag penv defines.\n * 2. **Exactly one.** Two environment flags in one invocation is a hard error,\n * never first-wins; a shorthand that contradicts an explicit `--env` is the\n * same error.\n * 3. **`--env` stays canonical.** The shorthand is sugar; scripts and error\n * messages use the spelling that always works, including for names that\n * cannot be flags at all.\n *\n * Resolution happens post-parse against the loaded config's whitelist — the\n * parser knows nothing about environments, so the config cannot influence\n * parsing, only interpretation.\n */\n\nimport type { PenvConfig } from \"@penvhq/core\";\nimport { environmentNames, PenvError } from \"@penvhq/core\";\n\n/** Flags every penv invocation owns regardless of command. */\nconst BASE_RESERVED = [\"help\", \"version\", \"h\", \"v\", \"_\", \"--\"] as const;\n\n/**\n * Every flag name a penv command declares, across commands. An environment named\n * one of these loses its shorthand (rule 1) — `doctor` warns through\n * {@link shadowedEnvironments} so the user hears it once, calmly, rather than\n * discovering a flag that silently means something else.\n */\nconst COMMAND_FLAGS = [...BASE_RESERVED, \"env\", \"out\", \"allow-decrypt\", \"yes\", \"y\"] as const;\n\n/** The declared environments whose names a real flag shadows — no shorthand for these. */\nexport function shadowedEnvironments(config: PenvConfig): string[] {\n const flags = new Set<string>(COMMAND_FLAGS);\n return environmentNames(config).filter((environment) => flags.has(environment));\n}\n\n/**\n * The bare `--<flag>` switches this invocation carries that the command did not\n * declare — the only place an environment shorthand can live. Collected in the\n * command layer, where the declared flag names are known; judged later, where\n * the config is.\n */\nexport function shorthandCandidates(\n args: Readonly<Record<string, unknown>>,\n declared: readonly string[],\n): string[] {\n const reserved = new Set<string>([...BASE_RESERVED, ...declared]);\n return Object.keys(args).filter((key) => !reserved.has(key) && args[key] === true);\n}\n\nfunction quoteList(values: readonly string[]): string {\n return values.map((value) => `\\`--${value}\\``).join(\", \");\n}\n\n/**\n * The environment the shorthand flags name, judged against the whitelist. An\n * unknown bare flag is an error naming the environments that would have worked\n * — before this, a typo'd `--prodction` was silently ignored.\n */\nexport function environmentFromShorthand(\n config: PenvConfig,\n candidates: readonly string[],\n explicit: string | undefined,\n): string | undefined {\n if (candidates.length === 0) {\n return undefined;\n }\n const declared = environmentNames(config);\n const hits = candidates.filter((candidate) => declared.includes(candidate));\n const strangers = candidates.filter((candidate) => !declared.includes(candidate));\n\n if (strangers.length > 0) {\n throw new PenvError(\n \"UNKNOWN_FLAG\",\n `${quoteList(strangers)} ${strangers.length === 1 ? \"is not a flag\" : \"are not flags\"} this command takes, and ${strangers.length === 1 ? \"names\" : \"name\"} no declared environment`,\n `Declared environments work as bare flags: ${quoteList(declared)}. Anything else needs \\`--env <name>\\`.`,\n );\n }\n if (hits.length > 1) {\n throw new PenvError(\n \"ENVIRONMENT_FLAG_AMBIGUOUS\",\n `${quoteList(hits)} name two environments at once, and a command acts on exactly one`,\n \"Pass a single environment flag, or the canonical `--env <name>`.\",\n );\n }\n const hit = hits[0];\n if (hit !== undefined && explicit !== undefined && explicit !== hit) {\n throw new PenvError(\n \"ENVIRONMENT_FLAG_AMBIGUOUS\",\n `\\`--env ${explicit}\\` and \\`--${hit}\\` name two environments at once`,\n \"Drop one of them — `--env` is the canonical spelling.\",\n );\n }\n return hit;\n}\n","/**\n * The provider registry: the one place the CLI turns an environment entry's\n * `provider` into a concrete provider.\n *\n * It lives in the CLI, not in `@penvhq/core` and not in `@penvhq/runtime`. Core owns\n * the `Provider` *contract* and must not know which implementations exist —\n * knowing would make the interface answerable to its callers. The runtime never\n * selects a provider at all: it reads the local records tree whatever an\n * environment declares (see `runtime/src/resolve.ts`), so a registry there would\n * be the ability to dial a network provider at boot, which the design forbids.\n *\n * A provider is the package's fully-qualified name, and the name is the\n * import specifier. The registry pre-installs just two providers — the\n * filesystem tree every command edits and the mock used to rehearse rotation —\n * so \"built-in\" means only \"already installed\", not a different kind of\n * provider. Nothing else in the CLI names an implementation.\n *\n * Everything else is an extension, and {@link resolveExtension} owns the one\n * order every command finds one in: the local-extension list, then the project's\n * own `node_modules`, then `$PENV_HOME` at the version the manifest pins.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type {\n AnyProvider,\n Manifest,\n PenvConfig,\n Provider,\n ProviderFactoryContext,\n} from \"@penvhq/core\";\nimport {\n environmentEntry,\n environmentNames,\n holdsProjection,\n LOCAL_EXTENSIONS_PATH,\n localExtensionsFile,\n MANIFEST_PATH,\n PENV_DIR,\n PenvError,\n packageDir,\n packageEntry,\n parseLocalExtensions,\n parseManifest,\n penvHome,\n providerMissing,\n recordsDir,\n} from \"@penvhq/core\";\nimport { createFilesystemProvider } from \"@penvhq/provider-filesystem\";\nimport { createMockProvider } from \"@penvhq/provider-mock\";\n\n/**\n * What a factory needs to build a provider for one project. The shape is core's:\n * it is the seam provider packages build against, so the CLI consumes the same\n * declaration they do rather than restating it.\n */\nexport type ProviderContext = ProviderFactoryContext;\n\n/** Turns one project's context into a provider of one `type`. */\nexport type ProviderFactory = (context: ProviderContext) => Provider;\n\n/** The factory shape a provider package exports. May be async. */\ntype PluginProviderFactory = (context: ProviderContext) => AnyProvider | Promise<AnyProvider>;\n\n/** The symbol a provider package exports — the entry point this seam calls. */\nconst PLUGIN_FACTORY_EXPORT = \"penvProviderFactory\";\n\n/**\n * The local records tree is always served by the filesystem provider: it is the\n * working copy `penv pull` materialises and every command edits, whatever backend\n * an environment's source of truth lives in. Naming it here keeps the one string\n * literal that means \"the tree on disk\" out of `openProject`.\n */\nexport const LOCAL_TREE_TYPE = \"@penvhq/provider-filesystem\";\n\n/**\n * The providers that ship inside the CLI, so they resolve without the project\n * installing anything: the local tree itself, and the mock that rehearses\n * rotation. Every other provider is a package the project depends on.\n */\nconst REGISTRY = new Map<string, ProviderFactory>([\n [\n LOCAL_TREE_TYPE,\n ({ root, config }) => createFilesystemProvider({ root: recordsDir(root), config }),\n ],\n [\n \"@penvhq/provider-mock\",\n ({ root }) => createMockProvider({ storePath: resolve(root, PENV_DIR, \".penv-mock.json\") }),\n ],\n]);\n\n/** The record contract's methods — what a records-holding provider must carry before penv trusts it. */\nconst RECORD_CONTRACT_METHODS = [\n \"read\",\n \"write\",\n \"list\",\n \"remove\",\n \"readMeta\",\n \"writeMeta\",\n \"removeMeta\",\n] as const;\n\n/** The projection contract's required methods — the smaller surface a projection-holding provider carries. */\nconst PROJECTION_CONTRACT_METHODS = [\"verify\", \"push\", \"list\"] as const;\n\n/**\n * Loaded provider modules, memoized by resolved path, so a command touching\n * several environments backed by one package imports it once.\n */\nconst pluginModuleCache = new Map<string, Promise<Record<string, unknown>>>();\n\n/** Whether a package name is one the CLI ships pre-installed. */\nexport function isProviderRegistered(type: string): boolean {\n return REGISTRY.has(type);\n}\n\n/**\n * Builds a *pre-installed* provider of `type`, refusing any other loudly. This is\n * the synchronous path `openProject` uses for the local filesystem tree, which\n * always ships with the CLI — so it stays sync and never dials a package. A\n * declared source of truth, which may be any installed provider package, is\n * built through {@link createSourceProvider} instead.\n */\nexport function createProvider(type: string, context: ProviderContext): Provider {\n const factory = REGISTRY.get(type);\n if (factory === undefined) {\n throw unknownProvider(type);\n }\n return factory(context);\n}\n\n/**\n * Builds a provider of `type`. A pre-installed provider comes from the static map\n * (synchronously); anything else is imported from the package `type` names and\n * validated against the contract before it is trusted. The import is async,\n * which is why this is — a network provider cannot be constructed on a\n * synchronous path.\n */\nexport async function createSourceProvider(\n type: string,\n context: ProviderContext,\n): Promise<AnyProvider> {\n if (REGISTRY.has(type)) {\n return createProvider(type, context);\n }\n return loadPluginProvider(type, context);\n}\n\nasync function loadPluginProvider(type: string, context: ProviderContext): Promise<AnyProvider> {\n const path = resolveExtension(type, context.root, context.environment);\n\n let mod: Record<string, unknown>;\n try {\n mod = await importPlugin(path);\n } catch (cause) {\n throw providerLoadFailed(type, path, cause);\n }\n\n const factory = mod[PLUGIN_FACTORY_EXPORT];\n if (typeof factory !== \"function\") {\n throw new PenvError(\n \"PROVIDER_PLUGIN_INVALID\",\n `\\`${type}\\` does not export \\`${PLUGIN_FACTORY_EXPORT}\\``,\n `A penv provider package must export \\`${PLUGIN_FACTORY_EXPORT}(context) => Provider\\`.`,\n );\n }\n\n const provider = await (factory as PluginProviderFactory)(context);\n assertSatisfiesContract(provider, type);\n return provider;\n}\n\n/**\n * Refuses at open time every environment whose `provider` names a backend\n * this project cannot construct — the whole config in one pass, so a user with two\n * unknown providers hears about both, and never as a crash from the later command\n * that would have been the first to reach one.\n *\n * An entry naming no provider at all is refused here too, rather than skipped. A\n * half-migrated entry — one that kept `type:` — otherwise opens cleanly, and the\n * credential strip in `child-env.ts` cannot name the credentials of a provider\n * penv was never told about: `penv run` would hand the child `VAULT_TOKEN`.\n *\n * A pre-installed type passes on the map; any other passes only if\n * {@link resolveExtension} finds it — a *synchronous* existence check that runs\n * no provider code, so the open-time guarantee holds without `openProject`\n * turning async. The package's module is imported and its contract checked\n * later, when the environment's source is actually built.\n */\nexport function assertProvidersRegistered(\n config: PenvConfig,\n projectRoot: string,\n options?: { readonly ci?: boolean },\n): void {\n const local = localExtensions(projectRoot);\n const ci = options?.ci ?? isCi(process.env.CI);\n for (const environment of environmentNames(config)) {\n const provider = environmentEntry(config, environment)?.provider;\n if (typeof provider !== \"string\" || provider.trim().length === 0) {\n throw providerMissing(environment);\n }\n if (isProviderRegistered(provider)) {\n continue;\n }\n if (ci && local.includes(provider)) {\n throw localExtensionInCi(provider, environment);\n }\n resolveExtension(provider, projectRoot, environment, local);\n }\n}\n\n/**\n * The one place an extension is located, and the one order it is looked for in.\n * Every command resolves through here, so what `doctor` reports, what\n * `openProject` refuses, and what a provider operation imports are one answer.\n *\n * 1. **The local-extension list.** A package this checkout builds is read out of\n * the project and never out of the store: nothing pins it, so there are no\n * bytes in the store that could be it.\n * 2. **The project's own `node_modules`.** A package the project depends on wins\n * over anything the manifest pins — a repository editing a provider runs the\n * copy it is editing, not a release installed beside it.\n * 3. **`$PENV_HOME/extensions/<name>/<version>`, at the version the manifest\n * pins.** What `penv add` installed, `penv install` restores, and the\n * launcher verified before it passed `$PENV_HOME` to this process. This is\n * the path an extension added from a registry takes: `penv add` leaves\n * nothing in the project but a type declaration, so nothing about it resolves\n * from `node_modules`.\n *\n * Locating is not loading. This runs no provider code; the module is imported\n * only when a command actually performs a provider operation.\n */\nfunction resolveExtension(\n type: string,\n projectRoot: string,\n environment?: string,\n local: readonly string[] = localExtensions(projectRoot),\n): string {\n const fromProject = resolvePlugin(type, projectRoot);\n if (local.includes(type)) {\n if (fromProject === undefined) {\n throw localExtensionUnresolved(type, projectRoot, environment);\n }\n return fromProject;\n }\n if (fromProject !== undefined) {\n return fromProject;\n }\n\n const version = pinnedVersion(type, projectRoot);\n if (version === undefined) {\n throw unknownProvider(type, environment);\n }\n const stored = storedExtension(type, version);\n if (stored === undefined) {\n throw extensionNotInstalled(type, version, environment);\n }\n return stored;\n}\n\n/**\n * The version the manifest pins for `type`, or `undefined` when it pins none.\n *\n * A manifest penv cannot read is not this function's refusal: the launcher reads\n * it first on every run and owns every message about it, so a broken one here\n * means the type is simply not pinned — and the caller's own refusal, which\n * names the package rather than the file, is the better one to arrive.\n */\nfunction pinnedVersion(type: string, projectRoot: string): string | undefined {\n let manifest: Manifest;\n try {\n manifest = parseManifest(readFileSync(join(projectRoot, ...MANIFEST_PATH.split(\"/\")), \"utf8\"));\n } catch {\n return undefined;\n }\n return manifest.extensions[type]?.version;\n}\n\n/** The module of one pinned extension in `$PENV_HOME`, or `undefined` if it is not there. */\nfunction storedExtension(type: string, version: string): string | undefined {\n const entry = packageEntry(packageDir(penvHome(process.env), \"extensions\", type, version));\n return entry?.file;\n}\n\n/** The extensions this project develops, as `penv add --local` recorded them. */\nexport function localExtensions(projectRoot: string): string[] {\n let text: string;\n try {\n text = readFileSync(localExtensionsFile(projectRoot), \"utf8\");\n } catch {\n return [];\n }\n return parseLocalExtensions(text);\n}\n\nfunction isCi(value: string | undefined): boolean {\n return value !== undefined && value !== \"\" && value !== \"0\" && value.toLowerCase() !== \"false\";\n}\n\n/**\n * A local extension is the copy in this checkout, and nothing pins its bytes —\n * which is exactly what a pipeline may not run on. The remedy is the registry\n * path, because that is the one that produces something CI can verify.\n */\nfunction localExtensionInCi(type: string, environment: string): PenvError {\n return new PenvError(\n \"LOCAL_EXTENSION_IN_CI\",\n `The provider \\`${type}\\` for environment ${environment} is a local extension, and this is CI`,\n `${LOCAL_EXTENSIONS_PATH} records it as a package this project develops, so nothing pins ` +\n `the bytes CI would run. Publish it and run \\`penv add ${type}\\` to pin a release.`,\n );\n}\n\n/**\n * Resolves a provider package from the project, synchronously and without running\n * it. Returns the absolute module path, or `undefined` when the package is not\n * installed. `createRequire` is anchored at the project (not the CLI's own\n * install), so a globally-installed penv still finds a provider the project\n * depends on.\n */\nfunction resolvePlugin(specifier: string, fromDir: string): string | undefined {\n try {\n const require = createRequire(resolve(fromDir, \"noop.js\"));\n return require.resolve(specifier);\n } catch {\n return undefined;\n }\n}\n\n/** Imports the resolved module by path, memoized, working from both the ESM and CJS builds. */\nfunction importPlugin(resolvedPath: string): Promise<Record<string, unknown>> {\n const cached = pluginModuleCache.get(resolvedPath);\n if (cached !== undefined) {\n return cached;\n }\n const loading = import(pathToFileURL(resolvedPath).href) as Promise<Record<string, unknown>>;\n pluginModuleCache.set(resolvedPath, loading);\n return loading;\n}\n\n/**\n * Fails loudly if a loaded provider is missing a contract method — at load, not\n * mid-write. Which contract is the provider's own declaration: a\n * `holds: \"projection\"` capability selects the projection surface, anything\n * else the seven-method record contract the filesystem defines.\n */\nfunction assertSatisfiesContract(provider: AnyProvider, specifier: string): void {\n const projection = holdsProjection(provider);\n const methods: readonly string[] = projection\n ? PROJECTION_CONTRACT_METHODS\n : RECORD_CONTRACT_METHODS;\n const contract = projection\n ? \"the @penvhq/core ProjectionProvider contract its declared capabilities select\"\n : \"the @penvhq/core Provider contract that the filesystem provider defines\";\n for (const method of methods) {\n if (typeof (provider as unknown as Record<string, unknown>)[method] !== \"function\") {\n throw new PenvError(\n \"PROVIDER_PLUGIN_INVALID\",\n `The provider from \\`${specifier}\\` is missing \\`${method}()\\``,\n `It must satisfy ${contract}.`,\n );\n }\n }\n}\n\nfunction where(environment: string | undefined): string {\n return environment === undefined ? \"\" : ` for environment ${environment}`;\n}\n\nfunction unknownProvider(type: string, environment?: string): PenvError {\n const preinstalled = [...REGISTRY.keys()].map((name) => `\\`${name}\\``).join(\", \");\n return new PenvError(\n \"UNKNOWN_PROVIDER\",\n `The provider \\`${type}\\`${where(environment)} in penv.config.ts is nowhere penv looks for it`,\n `Run \\`penv add ${type}\\` to pin a release, or \\`penv add --local ${type}\\` if this ` +\n `repository is the one that builds it. penv looks in ${LOCAL_EXTENSIONS_PATH}, this ` +\n `project's node_modules, and then $PENV_HOME at the version ${MANIFEST_PATH} pins. The ` +\n `CLI ships ${preinstalled} pre-installed.`,\n );\n}\n\n/**\n * The manifest pins this extension and `$PENV_HOME` does not hold it — the one\n * unresolvable provider with a command behind it, so it names that command\n * rather than reporting the package as unknown.\n */\nfunction extensionNotInstalled(type: string, version: string, environment?: string): PenvError {\n return new PenvError(\n \"EXTENSION_NOT_INSTALLED\",\n `${MANIFEST_PATH} pins \\`${type}\\` ${version}${where(environment)}, and it is not installed ` +\n `in ${penvHome(process.env)}`,\n \"Run `penv install` — it downloads and verifies every version the manifest pins, extensions \" +\n \"included.\",\n );\n}\n\n/**\n * A local extension that stopped resolving. It is the copy this checkout builds,\n * so the store is not a second place to look — the project either has it or the\n * record is stale.\n */\nfunction localExtensionUnresolved(\n type: string,\n projectRoot: string,\n environment?: string,\n): PenvError {\n return new PenvError(\n \"LOCAL_EXTENSION_UNRESOLVED\",\n `${LOCAL_EXTENSIONS_PATH} records \\`${type}\\`${where(environment)} as a package this project ` +\n `develops, and it does not resolve from ${projectRoot}`,\n `Add it as a dependency of the root (a workspace link is one) and run \\`pnpm install\\`, or ` +\n `drop the name from ${LOCAL_EXTENSIONS_PATH} if this project no longer builds it.`,\n );\n}\n\n/**\n * A provider that resolved and would not import.\n *\n * The cause and the file are the message: `ERR_UNKNOWN_FILE_EXTENSION` on a\n * `src/index.ts` is the whole diagnosis, and a refusal that keeps neither sends\n * the reader to reproduce the import by hand outside penv.\n */\nfunction providerLoadFailed(type: string, path: string, cause: unknown): PenvError {\n const detail = cause instanceof Error ? cause.message : String(cause);\n return new PenvError(\n \"PROVIDER_PLUGIN_LOAD\",\n `The provider package \\`${type}\\` failed to load from ${path}: ${detail}`,\n \"penv imports that file exactly as it stands, with no transform, so it has to be built \" +\n \"JavaScript with its dependencies installed.\",\n );\n}\n","/**\n * The CLI's output voice.\n *\n * Reports are tables: a glyph, a label, and the parameter the line is about.\n * Columns are sized to the widest cell in one block so that a report reads down\n * the page as well as across it, and every command that reports uses this module\n * rather than assembling its own spacing.\n *\n * Color is applied here and nowhere lower: the glyph carries the verdict (green\n * pass, yellow warning, red failure, dim \"could not look\"), details and asides\n * are dimmed as metadata, and a remedy is a cyan-arrowed `tip` — the one shape a\n * reader learns once and then recognizes in every command. All of it degrades to\n * the exact plain bytes when the stream is not a terminal (see `style.ts`), so\n * pipes, CI logs, and tests never see an escape code.\n */\n\nimport { isPenvErrorLike } from \"@penvhq/core\";\nimport { err, out, padVisible, visibleWidth } from \"./style.js\";\n\nexport const CHECK = \"✓\";\nexport const WARN = \"⚠\";\nexport const CROSS = \"✗\";\n/** \"I could not look\" — a check that ran but could not reach a verdict. Never a pass. */\nexport const UNKNOWN = \"?\";\n\n/** The verdict each glyph carries, painted once here so every command agrees. */\nfunction paintGlyph(glyph: string): string {\n switch (glyph) {\n case CHECK:\n return out.green(glyph);\n case WARN:\n return out.yellow(glyph);\n case CROSS:\n return out.red(glyph);\n case UNKNOWN:\n return out.dim(glyph);\n default:\n return glyph;\n }\n}\n\n/** One reported line. `detail` is the last column and is never padded. */\nexport interface Row {\n readonly glyph: string;\n readonly label: string;\n readonly subject?: string;\n readonly detail?: string;\n}\n\n/** A step in a scaffolding run: what penv did, and an aligned aside. */\nexport interface Step {\n readonly glyph: string;\n readonly text: string;\n readonly note?: string;\n}\n\n/** Where a step's aside starts, measured from the glyph. */\nconst NOTE_COLUMN = 29;\n\nfunction widest(values: readonly string[]): number {\n return values.reduce((max, value) => Math.max(max, visibleWidth(value)), 0);\n}\n\nexport function formatRows(rows: readonly Row[]): string[] {\n const labelWidth = widest(rows.map((row) => row.label)) + 2;\n // Only rows that carry a detail need their subject padded; a row whose subject\n // is its last column must not widen the table for every other row.\n const detailed = rows.filter((row) => row.detail !== undefined);\n const subjectWidth = widest(detailed.map((row) => row.subject ?? \"\")) + 1;\n\n return rows.map((row) => {\n const head = `${paintGlyph(row.glyph)} ${padVisible(row.label, labelWidth)}`;\n if (row.detail === undefined) {\n return `${head}${row.subject ?? \"\"}`.trimEnd();\n }\n return `${head}${padVisible(row.subject ?? \"\", subjectWidth)}${out.dim(row.detail)}`.trimEnd();\n });\n}\n\n/**\n * Free-form aligned columns, for output that is a table rather than a report.\n * Every column but the last is padded to its widest cell. Cells may arrive\n * styled: widths are measured on what the terminal renders, not on the bytes.\n */\nexport function columns(rows: readonly (readonly string[])[], gap = 2): string[] {\n const count = rows.reduce((max, row) => Math.max(max, row.length), 0);\n const widths: number[] = [];\n for (let column = 0; column < count; column += 1) {\n widths.push(widest(rows.map((row) => row[column] ?? \"\")) + gap);\n }\n return rows.map((row) =>\n row\n .map((cell, index) =>\n index === row.length - 1 ? cell : padVisible(cell, widths[index] ?? 0),\n )\n .join(\"\")\n .trimEnd(),\n );\n}\n\nexport function formatSteps(steps: readonly Step[]): string[] {\n return steps.map((step) => {\n if (step.note === undefined) {\n return `${paintGlyph(step.glyph)} ${step.text}`;\n }\n // A text wider than the column gets a single space instead of alignment.\n // `padEnd` returns the string untouched when it is already too long, so the\n // aside ran straight into the last word — legible right up until the day a\n // step had something long to say, which is the day it mattered.\n const text =\n visibleWidth(step.text) >= NOTE_COLUMN ? `${step.text} ` : padVisible(step.text, NOTE_COLUMN);\n return `${paintGlyph(step.glyph)} ${text}${out.dim(step.note)}`;\n });\n}\n\n/**\n * A command's title line: what ran, and against which environment. The context\n * is dimmed so the eye lands on the report below, not the banner above it.\n */\nexport function heading(command: string, context?: string): string {\n return context === undefined\n ? out.bold(command)\n : `${out.bold(command)} ${out.dim(`· ${context}`)}`;\n}\n\n/**\n * A line the reader can act on — the `penv set` to paste, the rename to make.\n * One shape for every command: an arrow, then the remedy, indented under the\n * report it belongs to.\n */\nexport function tip(text: string): string {\n return ` ${out.cyan(\"→\")} ${text}`;\n}\n\n/**\n * A styled interactive question: `? parameter · context › `. Every prompt in the\n * CLI is this shape, so answering penv feels like one conversation.\n */\nexport function prompt(subject: string, context?: string): string {\n const head = `${out.cyan(\"?\")} ${out.bold(subject)}`;\n const tail = out.dim(\"› \");\n return context === undefined ? `${head} ${tail}` : `${head} ${out.dim(`· ${context}`)} ${tail}`;\n}\n\nexport function write(lines: readonly string[]): void {\n for (const line of lines) {\n process.stdout.write(`${line}\\n`);\n }\n}\n\n/**\n * The same lines, on stderr — for a command whose stdout belongs to something\n * else. `penv run` is the case: the child's output is the output, and penv's\n * own line must not land in a pipe the child is feeding.\n */\nexport function writeError(lines: readonly string[]): void {\n for (const line of lines) {\n process.stderr.write(`${line}\\n`);\n }\n}\n\n/**\n * A penv refusal already names the parameter, the environment, and the remedy,\n * so it is printed as written — the remedy re-shaped into the same arrowed tip\n * the reports use. Anything else is a bug in penv and keeps its stack.\n *\n * Recognised by shape, not by class: an extension is published self-contained\n * and throws refusals built from its own copy of core's error classes, so\n * `instanceof` would send every provider refusal down the bug path and print ten\n * frames of the provider's `dist` under an otherwise identical block.\n */\nexport function reportError(error: unknown): void {\n if (isPenvErrorLike(error)) {\n // `summary` is the message without the remedy the constructor folds into it,\n // so the remedy can wear the tip shape instead of a bare indent.\n process.stderr.write(`${err.red(CROSS)} ${error.summary}\\n`);\n if (error.remedy !== undefined) {\n process.stderr.write(` ${err.cyan(\"→\")} ${error.remedy}\\n`);\n }\n } else if (error instanceof Error) {\n process.stderr.write(`${err.red(CROSS)} ${error.message}\\n`);\n // The stack minus the message line it repeats, dimmed: it is for the bug\n // report, not the reader — but it must survive a copy-paste, so it is\n // printed rather than hidden.\n const stack = error.stack;\n const frames = stack?.startsWith(`${error.name}: ${error.message}`)\n ? stack.slice(`${error.name}: ${error.message}`.length).replace(/^\\n/, \"\")\n : stack;\n if (frames !== undefined && frames !== \"\") {\n process.stderr.write(`${err.dim(frames)}\\n`);\n }\n } else {\n process.stderr.write(`${err.red(CROSS)} ${String(error)}\\n`);\n }\n process.exitCode = 1;\n}\n\n/** Turns a thrown error into a printed one and a non-zero exit code. */\nexport async function guard(run: () => Promise<void>): Promise<void> {\n try {\n await run();\n } catch (error) {\n reportError(error);\n }\n}\n","/**\n * The CLI's palette.\n *\n * One restrained set of meanings, applied everywhere: green is a verdict that\n * passed, yellow one that warns, red one that failed; cyan marks the actionable —\n * a prompt, a command to paste; dim is metadata the eye should be able to skip.\n * Nothing else gets a color, so a colored word is always a signal.\n *\n * Styling is a property of the stream, not the text: a terminal gets color, a\n * pipe and a test get the exact bytes the plain renderer always produced. The\n * switch honors `NO_COLOR` and `FORCE_COLOR` (in that order — an explicit \"no\"\n * wins), then falls back to whether the stream is a TTY.\n */\n\ninterface ColorStream {\n readonly isTTY?: boolean;\n}\n\nfunction supportsColor(stream: ColorStream): boolean {\n const env = process.env;\n if (env.NO_COLOR !== undefined && env.NO_COLOR !== \"\") {\n return false;\n }\n if (env.FORCE_COLOR !== undefined && env.FORCE_COLOR !== \"\" && env.FORCE_COLOR !== \"0\") {\n return true;\n }\n if (env.TERM === \"dumb\") {\n return false;\n }\n return stream.isTTY === true;\n}\n\n/** Wraps text in one style. Identity when the palette's stream has no color. */\nexport type Paint = (text: string) => string;\n\nexport interface Palette {\n readonly enabled: boolean;\n readonly bold: Paint;\n readonly dim: Paint;\n readonly red: Paint;\n readonly green: Paint;\n readonly yellow: Paint;\n readonly cyan: Paint;\n readonly magenta: Paint;\n}\n\nconst ESC = `${String.fromCharCode(27)}[`;\nconst identity: Paint = (text) => text;\n\nfunction sgr(open: number, close: number, on: boolean): Paint {\n if (!on) {\n return identity;\n }\n const opener = `${ESC}${open}m`;\n const closer = `${ESC}${close}m`;\n return (text) => `${opener}${text}${closer}`;\n}\n\nfunction paletteFor(stream: ColorStream): Palette {\n const on = supportsColor(stream);\n return {\n enabled: on,\n bold: sgr(1, 22, on),\n dim: sgr(2, 22, on),\n red: sgr(31, 39, on),\n green: sgr(32, 39, on),\n yellow: sgr(33, 39, on),\n cyan: sgr(36, 39, on),\n magenta: sgr(35, 39, on),\n };\n}\n\n/** The report palette — everything written through `ui.write`. */\nexport const out: Palette = paletteFor(process.stdout);\n\n/** The error palette — `reportError` writes to stderr, whose TTY-ness is its own. */\nexport const err: Palette = paletteFor(process.stderr);\n\n/**\n * The width a terminal renders, with the style sequences that surround the text\n * counted at zero. Alignment must measure what the reader sees, or a styled cell\n * would push every column after it out of true.\n */\nconst STYLE_PATTERN = new RegExp(`${String.fromCharCode(27)}\\\\[[0-9;]*m`, \"g\");\n\n/**\n * The bytes a terminal actually shows. The one place that knows what a style\n * sequence looks like, so measuring a line and reading one back never disagree\n * — a test asserting a whole line uses this rather than a pattern of its own.\n */\nexport function visibleText(text: string): string {\n return text.replace(STYLE_PATTERN, \"\");\n}\n\nexport function visibleWidth(text: string): number {\n return visibleText(text).length;\n}\n\n/** `padEnd` measured on visible width, so styled and plain cells align in one table. */\nexport function padVisible(text: string, width: number): string {\n const missing = width - visibleWidth(text);\n return missing > 0 ? text + \" \".repeat(missing) : text;\n}\n","/**\n * `penv run` — how an adopted project starts.\n *\n * It resolves the cascade, checks it against the schema, builds a child\n * environment penv owns, and starts the exact command after `--`. Everything\n * after `--` belongs to the child: argument boundaries, pipes, shell syntax,\n * `pre*`/`post*` lifecycle hooks, exit code, signals. penv never rewrites a\n * script, detects an operator, or generates a backing script — the package\n * manager stays the child, and keeps everything that is its business.\n *\n * Two properties are worth stating because they are what the command is for:\n *\n * **It is network-forbidden.** `run` constructs no provider and contacts\n * nothing. It reads what is already materialised locally, and a missing\n * materialisation is a named failure with the `penv pull` line to run — a\n * provider being down is not a reason an application cannot start. `--watch` is\n * the single opt-in exception, and even there a failed sync leaves the running\n * child exactly where it was.\n *\n * **The verdict is `penv validate`'s.** The check runs once, here, and `run`\n * refuses precisely what `validate` refuses: two implementations of \"is this\n * configuration good\" would eventually let `run` start a process CI had already\n * rejected. `checkEnvironment` hands back the resolutions and the validated\n * object it reached that verdict on, so the child environment is built from the\n * same read rather than a second one.\n *\n * The daily form is `penv run -- pnpm dev`: `--source` defaults to `project`,\n * and `--env` falls back to the config's `defaultEnvironment`. CI names both.\n */\n\nimport type { FSWatcher } from \"node:fs\";\nimport { existsSync, readFileSync, watch } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport type { Artifact, ParameterRef, PenvConfig, Resolution } from \"@penvhq/core\";\nimport {\n ARTIFACT_BUILD_COMMAND,\n assertArtifactFor,\n environmentEntry,\n environmentNames,\n isPublicVariable,\n isSecret,\n keySourceFrom,\n MissingMaterializationError,\n openSealed,\n own,\n PenvError,\n parseArtifact,\n RECORDS_PATH,\n UndecryptableValueError,\n variableName,\n} from \"@penvhq/core\";\nimport type { DeclaredCredentials, DeliveredValue } from \"@penvhq/runtime\";\nimport {\n childEnvironment,\n declaredRefs,\n deliveredEnvironment,\n hasRemoteSource,\n RUN_MARKER,\n SNAPSHOT_VARIABLE,\n} from \"@penvhq/runtime\";\nimport { defineCommand } from \"citty\";\nimport type { z } from \"zod\";\nimport type { ChildHandle, ChildResult, StartChild } from \"../child.js\";\nimport { noCommand, startChild } from \"../child.js\";\nimport { activeDotenvFiles } from \"../dotenv-files.js\";\nimport { shorthandCandidates } from \"../env-flags.js\";\nimport { engineVersion } from \"../install.js\";\nimport type { Project } from \"../project.js\";\nimport { openProject, targetEnvironment } from \"../project.js\";\nimport { guard, heading, reportError, writeError } from \"../ui.js\";\nimport type { PullOptions, PullResult } from \"./pull.js\";\nimport { runPull } from \"./pull.js\";\nimport type { EnvironmentCheck, ValidateResult } from \"./validate.js\";\nimport { checkEnvironment } from \"./validate.js\";\n\n/** Where a run reads its values from. `snapshot` is the sealed artifact. */\nexport type RunSource = \"project\" | \"snapshot\";\n\nconst SOURCES: readonly RunSource[] = [\"project\", \"snapshot\"];\n\n/** How long a change waits for its neighbours before `--watch` acts on it. */\nconst DEBOUNCE_MS = 100;\n\n/** How long a child a restart is replacing has to leave before it is made to. */\nconst STOP_GRACE_MS = 5_000;\n\nexport interface RunOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n /** Defaults to `project`. */\n readonly source?: string;\n /** The one mode allowed to synchronise. Off by default. */\n readonly watch?: boolean;\n /** The command exactly as it followed `--`. */\n readonly command: readonly string[];\n /** The environment penv itself was started with. Defaults to `process.env`. */\n readonly host?: Readonly<Record<string, string | undefined>>;\n /** Injected in tests: how a child is started. */\n readonly start?: StartChild;\n /** Injected in tests: the sync `--watch` performs. */\n readonly pull?: (options: PullOptions) => Promise<PullResult>;\n /** Injected in tests: what tells `--watch` something changed. */\n readonly changes?: (onChange: () => void) => { close(): void };\n /** How long a replaced child has to leave before `--watch` insists. Defaults to 5s. */\n readonly stopGraceMs?: number;\n}\n\nexport interface RunResult {\n readonly environment: string;\n readonly source: RunSource;\n readonly command: readonly string[];\n /** Declared variables written into the child. */\n readonly written: number;\n /** Declared-but-valueless variables deleted from the child. */\n readonly deleted: number;\n /** penv's own variables removed before the child saw them. */\n readonly stripped: readonly string[];\n readonly exitCode: number;\n readonly signal: NodeJS.Signals | null;\n /** How many times `--watch` replaced the child. */\n readonly restarts: number;\n}\n\n/**\n * The command a run is, written the way the user would type it. It is what the\n * child carries in {@link RUN_MARKER}, so a nested `penv run` can name the\n * wrapper it found itself inside.\n */\nfunction invocationOf(\n environment: string | undefined,\n command: readonly string[],\n source?: RunSource,\n): string {\n const named = environment === undefined ? \"\" : ` --env ${environment}`;\n // Only `snapshot` is spelled out: `project` is the default, so writing it would\n // teach the reader a flag they never have to type.\n const flags = named + (source === \"snapshot\" ? \" --source snapshot\" : \"\");\n const parts = command.map((part) => (part.includes(\" \") ? JSON.stringify(part) : part));\n return `penv run${flags} -- ${parts.join(\" \")}`;\n}\n\n/**\n * An outer `penv run` meeting an in-script one.\n *\n * Both wrappers are named because neither is wrong on its own and the user\n * wrote them in different files — the outer one at a prompt, the inner one in a\n * `package.json` script they may have forgotten. Nesting is refused rather than\n * resolved: two owned environments over one process means the second silently\n * decides, and which one wins would depend on how the script was written.\n */\nfunction assertNotNested(host: Readonly<Record<string, string | undefined>>, inner: string): void {\n const outer = host[RUN_MARKER];\n if (outer === undefined) {\n return;\n }\n throw new PenvError(\n \"RUN_NESTED\",\n `\\`${inner}\\` is starting inside \\`${outer}\\`, and two penv environments cannot own one process`,\n `Drop one of the two wrappers — the inner one is in a package.json script — then run \\`${outer}\\` again.`,\n );\n}\n\n/** The two sources a run reads. Anything else is refused on what it says, not on what it finds. */\nfunction assertSource(source: string, inner: string): RunSource {\n if (source === \"project\" || source === \"snapshot\") {\n return source;\n }\n throw new PenvError(\n \"RUN_SOURCE_UNKNOWN\",\n `\\`--source ${source}\\` names no source penv reads`,\n `A run reads ${SOURCES.map((name) => `\\`${name}\\``).join(\" or \")}, and \\`project\\` is the default — so \\`${inner}\\` reads the local tree.`,\n );\n}\n\n/**\n * The public-prefix policy, checked before anything starts.\n *\n * `doctor` reports this and `run` refuses it, and that is the difference between\n * a report and a delivery: the variable is about to be written into a process\n * that will inline it into a browser bundle, permanently. penv is the only thing\n * holding both halves — meta says secret, the generated name says public — so it\n * is the only thing that can stop it.\n *\n * `penv artifact build` makes the same refusal for the same reason: the artifact\n * is the other delivery, and the container reading it has no meta to check.\n * `retry` is the command that was refused, so each caller names its own.\n */\nexport async function assertNoPublicSecret(\n project: Project,\n environment: string,\n refs: readonly ParameterRef[],\n retry: string,\n): Promise<void> {\n const prefixes = project.config.publicPrefixes ?? [];\n if (prefixes.length === 0) {\n return;\n }\n for (const ref of refs) {\n const variable = variableName(ref, project.config);\n if (!isPublicVariable(variable, project.config)) {\n continue;\n }\n if (!isSecret(await project.provider.readMeta(ref), environment)) {\n continue;\n }\n const parameter = [...ref.namespace, ref.name].join(\"/\");\n const prefix = prefixes.find((candidate) => variable.startsWith(candidate));\n throw new PenvError(\n \"RUN_PUBLIC_SECRET\",\n `The secret ${parameter} maps to ${variable}, which the \\`${prefix}\\` prefix publishes to the browser`,\n `Rename the parameter, or drop \\`secret\\` from its meta if it is not one — then \\`${retry}\\`.`,\n );\n }\n}\n\n/** A failed check, told to someone who was trying to start something. */\nfunction invalidConfiguration(result: ValidateResult, inner: string): PenvError {\n const lines = result.issues.map((issue) => ` ${issue.subject}: ${issue.message}`).join(\"\\n\");\n return new PenvError(\n \"RUN_INVALID_CONFIGURATION\",\n `Configuration for environment ${result.environment} is not valid, so nothing was started:\\n${lines}`,\n `Fix the values above, then run \\`${inner}\\` again.`,\n );\n}\n\n/** The tree's raw values, in the shape the child-environment assembly takes. */\nfunction valuesOf(\n resolutions: readonly Resolution[],\n): { readonly ref: ParameterRef; readonly value: string }[] {\n const values: { ref: ParameterRef; value: string }[] = [];\n for (const resolution of resolutions) {\n if (resolution.value !== undefined) {\n values.push({ ref: resolution.ref, value: resolution.value });\n }\n }\n return values;\n}\n\n/** What one check produced, once it is known to be startable. */\ninterface Prepared {\n readonly env: Record<string, string>;\n readonly written: number;\n readonly deleted: number;\n readonly stripped: readonly string[];\n}\n\n/**\n * A dotenv file that came back after the project adopted penv (PRD §6).\n *\n * The framework loads `.env`, `.env.local`, `.env.<environment>` and\n * `.env.<environment>.local` on its own, so one of them reappearing beside\n * penv's records is two live sources of configuration — the drift adoption\n * removed, recreated by an editor, a generator, or a teammate's paste. It is\n * refused rather than merged: which of the two is right is not penv's to decide,\n * and the environment the file serves is not always the one being started.\n *\n * `.env.example` and its kin are documentation and no framework loads them, so\n * they are not active files and are never checked. Neither is `.env.staging` in\n * a project that never declared `staging`: nothing loads it either.\n */\nfunction assertNoActiveDotenv(project: Project): void {\n const active = activeDotenvFiles(project.root, project.config);\n const first = active[0];\n if (first === undefined) {\n return;\n }\n throw new PenvError(\n \"RUN_DOTENV_ACTIVE\",\n `${first.name} is active configuration again, and your framework would read it beside penv's records`,\n `Adopt it with \\`penv init\\`, or delete ${first.name} — its values belong in ${RECORDS_PATH}/.`,\n );\n}\n\n/** A generated variable name — the only thing a credential declaration may hold. */\nconst VARIABLE = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The `package.json` of an installed package, found the way the project's own\n * code would find the package: resolved from the project root, then walked up to\n * the manifest that names it. Absent when the package is not installed — the\n * providers penv ships resolve from inside the CLI and have no manifest to read\n * here, which is why they are known rather than asked.\n */\nfunction packageManifest(specifier: string, root: string): Record<string, unknown> | undefined {\n let directory: string;\n try {\n directory = dirname(createRequire(resolve(root, \"noop.js\")).resolve(specifier));\n } catch {\n return undefined;\n }\n for (;;) {\n const file = join(directory, \"package.json\");\n if (existsSync(file)) {\n try {\n const parsed: unknown = JSON.parse(readFileSync(file, \"utf8\"));\n if (isPlainObject(parsed) && parsed.name === specifier) {\n return parsed;\n }\n } catch {\n return undefined;\n }\n }\n const parent = dirname(directory);\n if (parent === directory) {\n return undefined;\n }\n directory = parent;\n }\n}\n\n/**\n * What the providers this config names authenticate with, as each package\n * declares it.\n *\n * penv owns no credential of its own, so a provider's are ambient variables and\n * the only way to keep them out of the child is to name them. The four providers\n * penv ships are named in the runtime, which is where their delivery is decided;\n * every other extension names its own in `penv.credentials` in its package.json\n * — symmetric with `penv.types` — and this reads the declaration off the package\n * the project actually installed, for the providers the config actually names.\n *\n * A declaration that is not a list of variable names is refused rather than\n * skipped. Skipping it would hand that extension's credentials to the\n * application without saying so, which is the one outcome the declaration exists\n * to prevent.\n */\nexport function declaredCredentials(config: PenvConfig, root: string): DeclaredCredentials {\n const declared: Record<string, readonly string[]> = {};\n for (const environment of environmentNames(config)) {\n const provider = environmentEntry(config, environment)?.provider;\n if (provider === undefined || own(declared, provider) !== undefined) {\n continue;\n }\n const penv = packageManifest(provider, root)?.penv;\n const credentials = isPlainObject(penv) ? penv.credentials : undefined;\n if (credentials === undefined) {\n continue;\n }\n if (\n !Array.isArray(credentials) ||\n credentials.some((name) => typeof name !== \"string\" || !VARIABLE.test(name))\n ) {\n throw new PenvError(\n \"PROVIDER_CREDENTIALS_INVALID\",\n `\\`${provider}\\` declares \\`penv.credentials\\`, and it is not a list of variable names`,\n `Its package.json should read \\`\"penv\": { \"credentials\": [\"ACME_TOKEN\"] }\\` — penv strips ` +\n \"exactly what an extension declares, so it will not guess at a declaration it cannot read.\",\n );\n }\n declared[provider] = credentials;\n }\n return declared;\n}\n\nasync function prepare(\n project: Project,\n environment: string,\n host: Readonly<Record<string, string | undefined>>,\n inner: string,\n): Promise<Prepared> {\n assertNoActiveDotenv(project);\n const check: EnvironmentCheck = await checkEnvironment(project, environment);\n\n if (!check.result.ok || check.schema === undefined) {\n // Nothing at all resolved, for an environment whose values live in a\n // provider: this is the clone-and-run case, and the whole tree is what is\n // missing. The schema report below would be a wall of absences with the\n // wrong remedy under it.\n if (\n check.resolutions.every((resolution) => resolution.winner === undefined) &&\n hasRemoteSource(project.config, environment)\n ) {\n throw new MissingMaterializationError(environment);\n }\n throw invalidConfiguration(check.result, inner);\n }\n\n const schema: z.ZodType = check.schema;\n await assertNoPublicSecret(project, environment, declaredRefs(schema), inner);\n\n const { env, written, deleted, stripped } = childEnvironment({\n host,\n config: project.config,\n environment,\n schema,\n values: valuesOf(check.resolutions),\n ...(check.validated === undefined ? {} : { validated: check.validated }),\n credentials: declaredCredentials(project.config, project.root),\n invocation: inner,\n });\n return { env, written, deleted, stripped };\n}\n\n/**\n * The artifact a `--source snapshot` run reads, and only that.\n *\n * `PENV_SNAPSHOT` is the whole of the input. There is no search, no default\n * path, and no fall back to the project tree: a container that was supposed to\n * mount an artifact and did not must say so, not quietly start from whatever\n * happens to be on disk beside it.\n */\nfunction snapshotPath(host: Readonly<Record<string, string | undefined>>): string {\n const path = host[SNAPSHOT_VARIABLE]?.trim();\n if (path === undefined || path.length === 0) {\n throw new PenvError(\n \"RUN_SNAPSHOT_UNSET\",\n `\\`--source snapshot\\` reads the sealed artifact ${SNAPSHOT_VARIABLE} names, and ${SNAPSHOT_VARIABLE} is not set`,\n `Build one with \\`${ARTIFACT_BUILD_COMMAND}\\` and point ${SNAPSHOT_VARIABLE} at it.`,\n );\n }\n return path;\n}\n\nfunction readSnapshot(path: string): string {\n try {\n return readFileSync(path, \"utf8\");\n } catch {\n throw new PenvError(\n \"RUN_SNAPSHOT_MISSING\",\n `${SNAPSHOT_VARIABLE} names ${path}, and penv cannot read a sealed artifact there`,\n `Point ${SNAPSHOT_VARIABLE} at the artifact your release mounted — \\`${ARTIFACT_BUILD_COMMAND}\\` writes one.`,\n );\n }\n}\n\n/**\n * The artifact's values, opened in memory.\n *\n * The key source is the identifier the artifact carries and nothing else — the\n * environment's entry never travelled, because provider and key *configuration*\n * is exactly what an artifact must not hold. A ciphertext that will not open is a\n * refusal here, before the child exists: the alternative is starting an\n * application with a variable silently missing.\n */\nfunction openSnapshot(artifact: Artifact, path: string): DeliveredValue[] {\n const keys = keySourceFrom(artifact.keySource, artifact.environment);\n return Object.entries(artifact.values)\n .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))\n .map(([parameter, entry]): DeliveredValue => {\n if (entry.kind === \"absent\") {\n return { parameter, variable: entry.variable };\n }\n if (entry.kind === \"plain\") {\n return { parameter, variable: entry.variable, value: entry.value };\n }\n const opened = openSealed(entry.address, entry.sealed, keys);\n if (opened.kind === \"failed\") {\n throw new UndecryptableValueError(\n parameter,\n artifact.environment,\n `${entry.address} in ${path}`,\n opened.failure,\n );\n }\n return { parameter, variable: entry.variable, value: opened.value };\n });\n}\n\n/**\n * A run from a sealed artifact: read, verify, open, inject.\n *\n * No project is opened, and that is the point rather than an optimisation.\n * There is no `penv.config.ts`, no records tree and no provider package in a\n * release container, so this path reaches for none of them — and the artifact is\n * verified whole (format, engine, environment, delivery digest) before a single\n * ciphertext is opened.\n */\nfunction prepareFromSnapshot(\n host: Readonly<Record<string, string | undefined>>,\n environment: string | undefined,\n command: readonly string[],\n): { readonly environment: string; readonly prepared: Prepared } {\n const path = snapshotPath(host);\n const artifact = parseArtifact(readSnapshot(path), path);\n assertArtifactFor(\n artifact,\n { engineVersion: engineVersion(), ...(environment === undefined ? {} : { environment }) },\n path,\n );\n\n const { env, written, deleted, stripped } = deliveredEnvironment({\n host,\n environment: artifact.environment,\n values: openSnapshot(artifact, path),\n invocation: invocationOf(artifact.environment, command, \"snapshot\"),\n });\n return { environment: artifact.environment, prepared: { env, written, deleted, stripped } };\n}\n\n/**\n * `--watch`'s sync, and whether it worked.\n *\n * Reported and swallowed rather than thrown: a provider that will not answer\n * must not take a running child down with it. The caller uses the answer to\n * decide whether to go on — mid-session it does not, because restarting on a\n * sync that did not happen would swap a validated environment for the same one\n * and stop the child for nothing.\n */\nasync function sync(\n project: Project,\n environment: string,\n pull: (options: PullOptions) => Promise<PullResult>,\n): Promise<boolean> {\n if (!hasRemoteSource(project.config, environment)) {\n return true;\n }\n try {\n await pull({ cwd: project.root, environment });\n return true;\n } catch (error) {\n // The message is what is wanted here, not the verdict: a provider that would\n // not answer must not decide the exit code of a session the user ends later.\n const previous = process.exitCode;\n reportError(error);\n process.exitCode = previous;\n return false;\n }\n}\n\n/**\n * Stopping the child a restart is replacing: asked, then made to.\n *\n * SIGTERM is the ask, and a dev server that traps it and never leaves would hold\n * the restart open forever — waiting on a child that has decided not to end is a\n * developer watching nothing happen. So the ask is bounded and the escalation is\n * a signal the process cannot decline.\n */\nasync function stop(child: ChildHandle, graceMs: number): Promise<void> {\n child.kill(\"SIGTERM\");\n const escalation = setTimeout(() => child.kill(\"SIGKILL\"), graceMs);\n try {\n await child.ended;\n } finally {\n clearTimeout(escalation);\n }\n}\n\n/** The default change signal: the records tree and the config file, debounced. */\nfunction watchProject(project: Project, onChange: () => void): { close(): void } {\n const watchers = new Set<FSWatcher>();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const schedule = (): void => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n timer = setTimeout(onChange, DEBOUNCE_MS);\n };\n\n const add = (target: string, recursive: boolean, only?: string): void => {\n if (!existsSync(target)) {\n return;\n }\n try {\n const watcher = watch(target, { recursive }, (_event, filename) => {\n if (only !== undefined && (filename === null || basename(filename) !== only)) {\n return;\n }\n schedule();\n });\n watcher.on(\"error\", () => watchers.delete(watcher));\n watchers.add(watcher);\n } catch {\n // A platform that cannot watch this target is a weaker watch, never a\n // wrong run: the child already has the environment penv resolved.\n }\n };\n\n add(project.recordsDir, true);\n add(dirname(project.configFile), false, basename(project.configFile));\n\n return {\n close(): void {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n for (const watcher of watchers) {\n watcher.close();\n }\n },\n };\n}\n\nexport async function runRun(options: RunOptions): Promise<RunResult> {\n const command = options.command;\n const host = options.host ?? process.env;\n const inner = invocationOf(options.environment, command);\n\n // Before anything is opened or read: a nested run is refused on what it is,\n // not on what the project turns out to hold.\n assertNotNested(host, inner);\n const source = assertSource(options.source ?? \"project\", inner);\n if (command.length === 0) {\n throw noCommand();\n }\n\n if (source === \"snapshot\") {\n // `--watch` synchronises a tree from a provider, and neither exists here. It\n // is refused rather than ignored: a flag that quietly does nothing is a\n // developer waiting for a restart that is never coming.\n if (options.watch === true) {\n throw new PenvError(\n \"RUN_SNAPSHOT_WATCH\",\n \"`--watch` re-syncs the project tree, and a run from a sealed artifact has no tree to watch\",\n \"Drop `--watch` — an artifact is built once and read unchanged. Watch the project instead: `penv run --watch -- <command>`.\",\n );\n }\n // A release container has no project to open, so none is.\n const snapshot = prepareFromSnapshot(host, options.environment, command);\n return startAndReport(\n snapshot.environment,\n source,\n command,\n snapshot.prepared,\n options.start ?? startChild,\n options.cwd,\n );\n }\n\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n const invocation = invocationOf(environment, command);\n const start = options.start ?? startChild;\n const pull = options.pull ?? runPull;\n\n if (options.watch) {\n await sync(project, environment, pull);\n }\n\n const first = await prepare(project, environment, host, invocation);\n if (options.watch !== true) {\n return startAndReport(environment, source, command, first, start, project.root);\n }\n announce(environment, source, first);\n\n let current = start({ command, env: first.env, cwd: project.root });\n\n // What the running child was given, which is what the run reports: after a\n // restart the first environment is history, and reporting it would count\n // variables nothing is using.\n let latest = first;\n let restarts = 0;\n let restarting: Promise<void> | undefined;\n let closed = false;\n\n const changed = (options.changes ?? ((onChange) => watchProject(project, onChange)))(() => {\n if (closed || restarting !== undefined) {\n return;\n }\n restarting = (async () => {\n // A failed sync or a failed check leaves the child exactly where it was.\n // That is the guarantee of the mode: an edit mid-thought, or a provider\n // that will not answer, must not take the dev server down — and the\n // environment the child already has is still the last one that validated.\n if (!(await sync(project, environment, pull))) {\n return;\n }\n let next: Prepared;\n try {\n next = await prepare(project, environment, host, invocation);\n } catch (error) {\n const previous = process.exitCode;\n reportError(error);\n process.exitCode = previous;\n return;\n }\n if (closed) {\n return;\n }\n await stop(current, options.stopGraceMs ?? STOP_GRACE_MS);\n current = start({ command, env: next.env, cwd: project.root });\n latest = next;\n restarts += 1;\n })().finally(() => {\n restarting = undefined;\n });\n });\n\n try {\n for (;;) {\n const ended = await current.ended;\n // The child ended while a restart was in flight — the restart is what\n // ended it, so wait for the replacement rather than reporting the kill.\n if (restarting !== undefined) {\n await restarting;\n continue;\n }\n closed = true;\n return report(environment, source, command, latest, ended, restarts);\n }\n } finally {\n closed = true;\n changed.close();\n }\n}\n\n/**\n * penv's one line, on stderr: the child owns stdout, and a run whose output is\n * piped somewhere must deliver the child's bytes and nothing else.\n */\nfunction announce(environment: string, source: RunSource, prepared: Prepared): void {\n writeError([\n heading(\n `penv run · ${environment}`,\n `${source} · ${prepared.written} variables${prepared.deleted === 0 ? \"\" : ` · ${prepared.deleted} deleted`}`,\n ),\n ]);\n}\n\n/** The plain run, whichever source prepared it: announce, start, wait, report. */\nasync function startAndReport(\n environment: string,\n source: RunSource,\n command: readonly string[],\n prepared: Prepared,\n start: StartChild,\n cwd: string,\n): Promise<RunResult> {\n announce(environment, source, prepared);\n const ended = await start({ command, env: prepared.env, cwd }).ended;\n return report(environment, source, command, prepared, ended, 0);\n}\n\nfunction report(\n environment: string,\n source: RunSource,\n command: readonly string[],\n prepared: Prepared,\n ended: ChildResult,\n restarts: number,\n): RunResult {\n return {\n environment,\n source,\n command,\n written: prepared.written,\n deleted: prepared.deleted,\n stripped: prepared.stripped,\n exitCode: ended.exitCode,\n signal: ended.signal,\n restarts,\n };\n}\n\nexport const runCommand = defineCommand({\n meta: {\n name: \"run\",\n description: \"Start a command in a penv-owned child environment\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to run against\" },\n source: {\n type: \"string\",\n description: \"Where values come from: project (default) or snapshot\",\n },\n watch: { type: \"boolean\", description: \"Re-sync and restart the child when the tree changes\" },\n },\n run({ args, rawArgs }) {\n return guard(async () => {\n // The command is taken from the raw arguments, not from the parsed\n // positionals: `--` is the boundary the user drew, and re-deriving it from\n // a parse would be penv having an opinion about the argument list it\n // promised not to read.\n const separator = rawArgs.indexOf(\"--\");\n const command = separator === -1 ? [] : rawArgs.slice(separator + 1);\n\n const result = await runRun({\n cwd: process.cwd(),\n command,\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.source === undefined ? {} : { source: args.source }),\n ...(args.watch === true ? { watch: true } : {}),\n envFlags: shorthandCandidates(args, [\"env\", \"source\", \"watch\"]),\n });\n\n // The child's status is the run's status, both halves of it. A signal is\n // re-raised on penv itself so a shell sees the death it would have seen\n // without the wrapper.\n if (result.signal !== null) {\n process.kill(process.pid, result.signal);\n return;\n }\n process.exitCode = result.exitCode;\n });\n },\n});\n","/**\n * The dotenv files a project's framework reads, and what each one says.\n *\n * One module answers this for both ends of adoption: `penv init` offers these\n * files for the cutover, and `penv run` refuses the ones that come back\n * afterwards. Two readings of \"which files are active\" would eventually let init\n * move a file run does not watch, or run refuse a file init never offered.\n *\n * The four scopes are invariant 4's, which are Next.js's and Vite's:\n * `.env` > `.env.local` > `.env.<environment>` > `.env.<environment>.local`.\n * Anything else with an `.env` prefix is documentation (`.env.example`), a\n * leftover (`.env.backup`), or a filename penv has no reading of — none of them\n * is configuration a framework loads, so none is offered or refused.\n *\n * Reading an environment out of a filename here is not inference: nothing\n * reaches `penv.config.ts` until a human selects the file, and\n * {@link activeDotenvFiles} judges the segment against the declared whitelist\n * (invariant 10) rather than believing it.\n */\n\nimport { readdirSync } from \"node:fs\";\nimport type { PenvConfig } from \"@penvhq/core\";\nimport { environmentNames, isLegalEnvironmentName, RESERVED_TOKENS } from \"@penvhq/core\";\n\n/** The prefix every dotenv filename carries, and the bare shared-default name. */\nconst SHARED = \".env\";\nconst LOCAL = \"local\";\n\n/**\n * Segments that look like an environment but are documentation (`.env.example`),\n * a copy (`.env.backup`, which `penv import` itself writes), or one of the\n * grammar's reserved scope markers. A file named for one of these is never\n * offered: it declares nothing, and adopting it would put a name in the\n * whitelist no value file can be scoped to.\n */\nconst NOT_ENVIRONMENTS: readonly string[] = [\n ...RESERVED_TOKENS,\n \"example\",\n \"sample\",\n \"template\",\n \"backup\",\n];\n\n/** Where a dotenv file sits in the cascade. */\nexport type DotenvKind = \"shared\" | \"local\" | \"environment\" | \"environment-local\";\n\nexport interface DotenvFile {\n /** The filename exactly as it is on disk — what undo restores. */\n readonly name: string;\n readonly kind: DotenvKind;\n /** The environment the filename names, for the two environment-scoped kinds. */\n readonly environment?: string;\n /** How the file is described in the selection table. */\n readonly label: string;\n}\n\nfunction classify(name: string): DotenvFile | undefined {\n if (name === SHARED) {\n return { name, kind: \"shared\", label: \"shared default\" };\n }\n if (!name.startsWith(`${SHARED}.`)) {\n return undefined;\n }\n const segments = name.slice(SHARED.length + 1).split(\".\");\n const [first, second] = segments;\n if (first === undefined || first.length === 0) {\n return undefined;\n }\n if (segments.length === 1) {\n if (first === LOCAL) {\n return { name, kind: \"local\", label: \"local override\" };\n }\n return environmentFile(name, first, \"environment\");\n }\n if (segments.length === 2 && second === LOCAL) {\n return environmentFile(name, first, \"environment-local\");\n }\n // Three or more segments, or `.env.local.production` — no scope penv reads.\n return undefined;\n}\n\nfunction environmentFile(\n name: string,\n environment: string,\n kind: \"environment\" | \"environment-local\",\n): DotenvFile | undefined {\n if (!isLegalEnvironmentName(environment) || NOT_ENVIRONMENTS.includes(environment)) {\n return undefined;\n }\n return {\n name,\n kind,\n environment,\n label: kind === \"environment\" ? environment : `${environment}-local`,\n };\n}\n\n/** Shared, then local, then each environment's pair, alphabetically — the same list everywhere. */\nfunction order(file: DotenvFile): string {\n switch (file.kind) {\n case \"shared\":\n return \"0\";\n case \"local\":\n return \"1\";\n case \"environment\":\n return `2${file.environment}0`;\n default:\n return `2${file.environment}1`;\n }\n}\n\n/**\n * Every dotenv file at the project root that carries one of the four scopes,\n * in display order. A directory named `.env.something` is not a file a framework\n * reads, so `withFileTypes` keeps it out.\n */\nexport function discoverDotenvFiles(root: string): DotenvFile[] {\n let entries: readonly string[];\n try {\n entries = readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isFile())\n .map((entry) => entry.name);\n } catch {\n return [];\n }\n\n const files: DotenvFile[] = [];\n for (const entry of entries) {\n const file = classify(entry);\n if (file !== undefined) {\n files.push(file);\n }\n }\n return files.sort((a, b) => (order(a) < order(b) ? -1 : order(a) > order(b) ? 1 : 0));\n}\n\n/**\n * The files this project's framework would actually load: the two unscoped ones,\n * and the environment-scoped ones whose environment the config declares.\n *\n * A `.env.staging` in a project that never declared `staging` is not active — no\n * framework loads it, and reading it as one would be penv inferring the\n * environment invariant 10 forbids it from inferring.\n */\nexport function activeDotenvFiles(root: string, config: PenvConfig): DotenvFile[] {\n const declared = environmentNames(config);\n return discoverDotenvFiles(root).filter(\n (file) => file.environment === undefined || declared.includes(file.environment),\n );\n}\n\n/** The environments a set of selected files declares. `.env` alone declares none. */\nexport function environmentsDeclaredBy(files: readonly DotenvFile[]): string[] {\n const names = new Set<string>();\n for (const file of files) {\n if (file.environment !== undefined) {\n names.add(file.environment);\n }\n }\n return [...names].sort();\n}\n\n/** The cascade `environment` reads, most general first — invariant 4's four levels. */\nexport function cascadeFor(environment: string): string[] {\n return [\n SHARED,\n `${SHARED}.${LOCAL}`,\n `${SHARED}.${environment}`,\n `${SHARED}.${environment}.${LOCAL}`,\n ];\n}\n","/**\n * `penv pull` — materialise the local `.penv` tree from an environment's\n * source-of-truth provider. It is the inverse of the deploy-time injection most\n * stacks already have: instead of reading the tree to feed a backend, it reads\n * the backend to feed the tree.\n *\n * It only means anything when the environment declares a real backend\n * (`vault`, `mock`): those hold the truth somewhere penv does not edit in place,\n * and pulling copies it down so every other command — which reads the local tree\n * — sees it. An environment whose entry names the filesystem provider has the\n * local tree *as* its source of truth, so a pull would be the tree copying onto\n * itself; that degenerate case is reported as nothing to do, never a self-copy.\n *\n * Values cross verbatim. They are opaque envelope strings the source holds and\n * penv does not open here — a sealed value stays sealed, byte-for-byte, so the\n * key that opens it never has to be present to pull it.\n */\n\nimport type { AnyProvider, Meta, ProjectionProvider } from \"@penvhq/core\";\nimport { holdsProjection, refFromVariable } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { shorthandCandidates } from \"../env-flags.js\";\nimport type { Project } from \"../project.js\";\nimport {\n localTree,\n openProject,\n refsFrom,\n sourceProviderFor,\n targetEnvironment,\n} from \"../project.js\";\nimport { LOCAL_TREE_TYPE } from \"../registry.js\";\nimport { CHECK, formatRows, guard, WARN, write } from \"../ui.js\";\n\nexport interface PullOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n /** Injected in tests: the source provider. Defaults to the one the config declares. */\n readonly source?: AnyProvider;\n}\n\nexport interface PullResult {\n readonly environment: string;\n /** The source provider's type — `filesystem` when the environment declares no separate backend. */\n readonly source: string;\n /**\n * True when the source *is* the local tree, so there was nothing to pull. The\n * caller distinguishes \"pulled nothing because the backend was empty\" from\n * \"there is no backend to pull from\" — opposite situations.\n */\n readonly localSource: boolean;\n /** Value files written into the local tree. */\n readonly values: number;\n /** Meta files written into the local tree. */\n readonly meta: number;\n /** Distinct parameters the pull touched, at any scope. */\n readonly refs: number;\n /**\n * True when the source declares `readsValues: false`: names and meta came\n * down, values stayed absent — the destination never returns one, and the\n * pull says so rather than dressing emptiness as freshness.\n */\n readonly valuesUnreadable?: boolean;\n}\n\n/**\n * Pull from a value-withholding provider: materialise what the store can\n * honestly give. Listing names is the one read it allows, so each name comes\n * down as a flat parameter (the same `refFromVariable` mapping `import` uses —\n * structure is never guessed back out of a flat namespace), a meta stub marks\n * the parameters the destination holds, and values stay absent for\n * `penv validate` to flag and the user to fill.\n */\nasync function pullProjection(\n project: Project,\n source: ProjectionProvider,\n environment: string,\n): Promise<PullResult> {\n const tree = localTree(project);\n const names = new Set<string>();\n for (const secret of await source.list({ kind: \"repository\" })) {\n names.add(secret.name);\n }\n for (const secret of await source.list({ kind: \"environment\", environment })) {\n names.add(secret.name);\n }\n\n let meta = 0;\n for (const name of [...names].sort()) {\n const ref = refFromVariable(name);\n // A stub only where no meta exists: a pull must never overwrite policy the\n // user already wrote with an empty marker.\n if (tree.readMetaSync(ref) === undefined) {\n tree.writeMetaSync(ref, {});\n meta += 1;\n }\n }\n\n return {\n environment,\n source: source.type,\n localSource: false,\n values: 0,\n meta,\n refs: names.size,\n valuesUnreadable: true,\n };\n}\n\nexport async function runPull(options: PullOptions): Promise<PullResult> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n const source = options.source ?? (await sourceProviderFor(project, environment));\n\n // The local tree already IS the source of truth for an environment with no\n // declared backend: `sourceProviderFor` handed back the filesystem tree, and\n // pulling it onto itself would be a no-op dressed as work. Report the truth.\n if (source.type === LOCAL_TREE_TYPE) {\n return { environment, source: source.type, localSource: true, values: 0, meta: 0, refs: 0 };\n }\n\n // A projection-holding source cannot return values, so its pull is the\n // names-and-meta materialisation — everything the store honestly has.\n if (holdsProjection(source)) {\n return pullProjection(project, source, environment);\n }\n\n const tree = localTree(project);\n const files = await source.list();\n\n let values = 0;\n for (const file of files) {\n const value = await source.read(file);\n // Absent is not written: `list` and `read` can disagree across a concurrent\n // prune, and a missing value is nothing to materialise.\n if (value === undefined) {\n continue;\n }\n // Verbatim — the value is an opaque envelope, sealed or not, and penv does\n // not open it to move it.\n tree.writeSync(file, value);\n values += 1;\n }\n\n // Meta is per-parameter, so it is pulled once per distinct ref rather than once\n // per value file — two scopes of one parameter share the one policy.\n const refs = refsFrom(files);\n let meta = 0;\n for (const ref of refs) {\n const block: Meta | undefined = await source.readMeta(ref);\n if (block === undefined) {\n continue;\n }\n tree.writeMetaSync(ref, block);\n meta += 1;\n }\n\n return { environment, source: source.type, localSource: false, values, meta, refs: refs.length };\n}\n\nexport function renderPull(result: PullResult): string[] {\n if (result.localSource) {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Nothing to pull\",\n subject: `environment ${result.environment} has no separate source of truth`,\n detail: \"its values live in the local .penv tree already\",\n },\n ]);\n }\n\n if (result.valuesUnreadable === true) {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Pulled\",\n subject: `${result.refs} ${result.refs === 1 ? \"parameter name\" : \"parameter names\"}`,\n detail: `from ${result.source} for environment ${result.environment}`,\n },\n {\n glyph: WARN,\n label: \"Values not readable\",\n subject: \"this destination never returns a secret's value\",\n detail:\n \"fill them locally with `penv set` or `penv fill` — `penv validate` names every gap\",\n },\n ]);\n }\n\n return formatRows([\n {\n glyph: CHECK,\n label: \"Pulled\",\n subject: `${result.values} ${result.values === 1 ? \"value\" : \"values\"}`,\n detail: `from the ${result.source} provider for environment ${result.environment}`,\n },\n {\n glyph: CHECK,\n label: \"Parameters\",\n subject: `${result.refs} ${result.refs === 1 ? \"parameter\" : \"parameters\"}, ${result.meta} with meta`,\n detail: \"written into the local .penv tree\",\n },\n ]);\n}\n\nexport const pullCommand = defineCommand({\n meta: {\n name: \"pull\",\n description: \"Materialise the local .penv tree from an environment's source-of-truth provider\",\n },\n args: {\n env: {\n type: \"string\",\n description: \"The environment to pull (or pass it as a bare flag: --production)\",\n },\n },\n run({ args }) {\n return guard(async () => {\n const result = await runPull({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n envFlags: shorthandCandidates(args, [\"env\"]),\n });\n write(renderPull(result));\n });\n },\n});\n","/**\n * `penv validate` — build the target environment's configuration and check it\n * against the one schema.\n *\n * Three failures land here rather than anywhere else, and all three are errors:\n * a reserved token in a name (invariant 11), two parameters mapping to one\n * generated variable (invariant 12 — never last-write-wins), and a config object\n * the schema rejects. A passing run means the schema is internally consistent;\n * it does not mean the schema is correct. That is your review, especially after\n * an inferred import.\n */\n\nimport { resolve as resolvePath } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { ParameterRef, Resolution, ValueFile } from \"@penvhq/core\";\nimport {\n accessPath,\n checkNameCollisions,\n jitiFor,\n NameCollisionError,\n PenvError,\n ReservedTokenError,\n resolveAll,\n SCHEMA_HARVEST_ENV,\n schemaFileOf,\n validateConfig,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { z } from \"zod\";\nimport { shorthandCandidates } from \"../env-flags.js\";\nimport type { Project } from \"../project.js\";\nimport {\n keySourceFor,\n openProject,\n refsFrom,\n schemaShapeFileOf,\n targetEnvironment,\n} from \"../project.js\";\nimport type { DriftReport } from \"../schema.js\";\nimport { computeDrift, EMPTY_DRIFT } from \"../schema.js\";\nimport { out } from \"../style.js\";\nimport { CHECK, CROSS, formatRows, guard, type Row, tip, write } from \"../ui.js\";\n\nexport type ValidateIssueKind = \"config\" | \"reserved\" | \"collision\" | \"schema\" | \"undecryptable\";\n\nexport interface ValidateIssue {\n readonly kind: ValidateIssueKind;\n /** What the line is about: a parameter, a variable, a token, or a file. */\n readonly subject: string;\n readonly message: string;\n readonly remedy?: string;\n}\n\nexport interface ValidateResult {\n readonly ok: boolean;\n readonly environment: string;\n readonly parameters: number;\n readonly issues: readonly ValidateIssue[];\n /**\n * The distance between the schema and the tree, carried for the callers\n * that report it (`watch`). Never folded into `ok` and never rendered by\n * `renderValidate`: drift is a report, and CI's verdict must not move because\n * a parameter the schema tolerates is absent. Empty when the schema did not\n * load, since there is nothing to measure against.\n */\n readonly drift: DriftReport;\n}\n\nexport interface ValidateOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n}\n\nconst SCHEMA_EXPORT = \"schema\";\n\nconst LABELS: Readonly<Record<ValidateIssueKind, string>> = {\n config: \"Config\",\n reserved: \"Reserved token\",\n collision: \"Name collision\",\n schema: \"Invalid parameter\",\n undecryptable: \"Undecryptable value\",\n};\n\nfunction firstLine(text: string): string {\n return text.split(\"\\n\")[0] ?? text;\n}\n\nfunction issueFrom(error: PenvError, fallbackSubject: string): ValidateIssue {\n const base = {\n message: firstLine(error.message),\n ...(error.remedy === undefined ? {} : { remedy: error.remedy }),\n };\n if (error instanceof ReservedTokenError) {\n return { kind: \"reserved\", subject: error.token, ...base };\n }\n if (error instanceof NameCollisionError) {\n return { kind: \"collision\", subject: error.variable, ...base };\n }\n return { kind: \"config\", subject: fallbackSubject, ...base };\n}\n\n/**\n * Places a value at its access path. Values are placed exactly as the provider\n * holds them: coercion is the schema's job, so a value file's contents stay a\n * string here.\n */\nfunction place(root: Record<string, unknown>, path: readonly string[], value: string): void {\n const leaf = path[path.length - 1];\n if (leaf === undefined) {\n return;\n }\n let node = root;\n for (const key of path.slice(0, -1)) {\n const existing = node[key];\n if (typeof existing === \"object\" && existing !== null) {\n node = existing as Record<string, unknown>;\n continue;\n }\n const child: Record<string, unknown> = {};\n node[key] = child;\n node = child;\n }\n node[leaf] = value;\n}\n\nfunction isZodType(value: unknown): value is z.ZodType {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"safeParse\" in value &&\n typeof (value as { safeParse: unknown }).safeParse === \"function\"\n );\n}\n\nexport interface SchemaLoad {\n /** Absent when the module could not be evaluated. `issues` says why. */\n readonly schema?: z.ZodType;\n readonly issues: readonly ValidateIssue[];\n}\n\n/**\n * A penv error raised inside the user's own schema module, identified by its\n * `code` rather than by `instanceof`.\n *\n * The error is thrown by *their* copy of penv, which is a different module realm\n * from this one, so `instanceof` is false across the boundary. `code` is the\n * stable, machine-readable discriminator, and this is exactly what it is for.\n */\nfunction validationIssuesOf(\n cause: unknown,\n schemaPath: string,\n schemaShapeFile: string,\n): readonly ValidateIssue[] | undefined {\n if (typeof cause !== \"object\" || cause === null) {\n return undefined;\n }\n const error = cause as { code?: unknown; issues?: unknown };\n if (error.code !== \"VALIDATION_FAILED\" || !Array.isArray(error.issues)) {\n return undefined;\n }\n return error.issues.map((issue: unknown) => {\n const { parameter, message } = issue as { parameter?: unknown; message?: unknown };\n return {\n kind: \"schema\" as const,\n subject: typeof parameter === \"string\" && parameter !== \"\" ? parameter : schemaPath,\n message: typeof message === \"string\" ? message : String(issue),\n // `schemaPath` is the loader penv evaluated; the shape to adjust lives in\n // `schemaShapeFile`, which is that same file for an old-layout project and\n // `penv.schema.ts` for one on the split.\n remedy: `Fix the value, or adjust the schema in ${schemaShapeFile} if the shape is wrong.`,\n };\n });\n}\n\n/**\n * Serialises the `PENV_ENV` pin in {@link loadSchema}.\n *\n * The environment reaches the user's module through a process global, because\n * that is the only channel their scaffolded `load(schema)` reads. A global\n * pinned across an `await` is not re-entrant: two overlapping loads interleave,\n * the second captures the first's value as `previous`, and restoring it on the\n * way out leaves the global pinned to an environment nobody asked for — every\n * later cycle then silently validates the wrong one. The window is real because\n * `runValidate` is exported and nothing stops a caller validating two\n * environments at once; `watch` is safe only by accident of its single-flight.\n *\n * A queue rather than a fix to the channel: the global *is* the contract with\n * the user's module, so the pin cannot go away. Only one load may hold it.\n */\nlet schemaLoads: Promise<unknown> = Promise.resolve();\n\nfunction exclusively<T>(work: () => Promise<T>): Promise<T> {\n const result = schemaLoads.then(work, work);\n // Never let a rejection break the chain for the next caller.\n schemaLoads = result.then(\n () => undefined,\n () => undefined,\n );\n return result;\n}\n\n/**\n * The one schema, read from wherever `schemaFile` puts it.\n *\n * Only the `schema` export is read, never `env` — a command whose job is to\n * *report* on configuration must not be stopped by it. That is the whole reason\n * the docs tell type-only consumers to import `schema`: a type-only import is\n * erased and never evaluates the module at all.\n *\n * A *runtime* read cannot have that guarantee: evaluating the module runs its\n * top level, and the scaffolded module ends in an eager\n * `export const env = load(schema)`. Against a tree with no values yet that load\n * would throw and take the whole namespace — including the `schema` export —\n * down with it, leaving `fill` blind to the very gap it exists to close. So the\n * schema-harvest flag is pinned alongside `PENV_ENV` for this one import:\n * `load()` defers under it (see `SCHEMA_HARVEST_ENV` in core), the module\n * evaluates, and the schema is always reachable. A module that fails for its own\n * reasons still reports honestly — a penv validation error raised at its top\n * level is unwrapped back into per-parameter issues, and anything else is a\n * config issue naming the file.\n *\n * The pins are process globals, so only one load may hold them at a time — see\n * {@link exclusively}. Loads queue rather than overlap.\n */\nexport function loadSchema(project: Project, environment: string): Promise<SchemaLoad> {\n // Resolved against the project root, not `.penv/`: `schemaFile` is relative to\n // penv.config.ts, so a schema at `src/env.ts` is looked for where it is.\n const schemaPath = schemaFileOf(project.config);\n // The file to name in an \"adjust the schema\" remedy, which is not always the\n // loader `schemaPath`: after the split the shape lives in `penv.schema.ts`.\n const schemaShapeFile = schemaShapeFileOf(project);\n const file = pathToFileURL(resolvePath(project.root, schemaPath)).href;\n return exclusively(() => loadSchemaExclusively(file, schemaPath, schemaShapeFile, environment));\n}\n\n/** {@link loadSchema}'s body, run only while it holds the `PENV_ENV` + harvest pins. */\nasync function loadSchemaExclusively(\n file: string,\n schemaPath: string,\n schemaShapeFile: string,\n environment: string,\n): Promise<SchemaLoad> {\n // Resolved from the user's own file: `zod` and `penv` are their dependencies,\n // not the CLI's. Shared with config loading (jitiFor) so both evaluate user modules\n // identically — including resolving `server-only` to its no-throw variant so a\n // server-guarded `.penv/env.ts` still yields its `schema` export.\n const jiti = jitiFor(file);\n\n // Two pins, one window: `PENV_ENV` so anything the module resolves targets the\n // environment being validated, and the schema-harvest flag so the scaffolded\n // eager `export const env = load(schema)` defers instead of throwing — a tree\n // with no values yet would otherwise take the `schema` export down with it,\n // and `fill` could never see the gap it exists to close.\n const previous = process.env.PENV_ENV;\n const previousHarvest = process.env[SCHEMA_HARVEST_ENV];\n process.env.PENV_ENV = environment;\n process.env[SCHEMA_HARVEST_ENV] = \"1\";\n let loaded: unknown;\n try {\n loaded = await jiti.import(file);\n } catch (cause) {\n const issues = validationIssuesOf(cause, schemaPath, schemaShapeFile);\n if (issues !== undefined) {\n return { issues };\n }\n const detail = cause instanceof Error ? firstLine(cause.message) : String(cause);\n return {\n issues: [\n {\n kind: \"config\",\n subject: schemaPath,\n message: `${schemaPath} could not be loaded: ${detail}`,\n remedy: `Fix the error above. penv reads the \\`${SCHEMA_EXPORT}\\` export of ${schemaPath}, which is yours to edit.`,\n },\n ],\n };\n } finally {\n if (previous === undefined) {\n delete process.env.PENV_ENV;\n } else {\n process.env.PENV_ENV = previous;\n }\n if (previousHarvest === undefined) {\n delete process.env[SCHEMA_HARVEST_ENV];\n } else {\n process.env[SCHEMA_HARVEST_ENV] = previousHarvest;\n }\n }\n\n const exported =\n typeof loaded === \"object\" && loaded !== null\n ? (loaded as Record<string, unknown>)[SCHEMA_EXPORT]\n : undefined;\n\n if (!isZodType(exported)) {\n return {\n issues: [\n {\n kind: \"config\",\n subject: schemaPath,\n message: `${schemaPath} exports no \\`${SCHEMA_EXPORT}\\``,\n remedy: `Export the shape as \\`export const ${SCHEMA_EXPORT} = z.object({ ... })\\`. One schema drives both validation and types.`,\n },\n ],\n };\n }\n return { schema: exported, issues: [] };\n}\n\n/**\n * One environment, checked — and everything the check produced on the way.\n *\n * The verdict is `result` and it is the only verdict penv has. The rest is what\n * `penv run` needs to build a child environment, handed back rather than\n * recomputed: a second walk of the same tree could disagree with the one the\n * verdict was reached on, and then `run` would start a process `validate`\n * refuses.\n */\nexport interface EnvironmentCheck {\n readonly result: ValidateResult;\n /** Absent when the schema module could not be evaluated — `result.issues` says why. */\n readonly schema?: z.ZodType;\n /** Every parameter the tree holds, resolved for this environment. */\n readonly resolutions: readonly Resolution[];\n /** The schema-validated object. Present only when the verdict passed. */\n readonly validated?: unknown;\n}\n\nexport async function runValidate(options: ValidateOptions): Promise<ValidateResult> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n return (await checkEnvironment(project, environment)).result;\n}\n\nexport async function checkEnvironment(\n project: Project,\n environment: string,\n): Promise<EnvironmentCheck> {\n const schemaPath = schemaFileOf(project.config);\n const schemaShapeFile = schemaShapeFileOf(project);\n const issues: ValidateIssue[] = [];\n\n // Invariant 11: a reserved token in a filename is an error, never a silent\n // misparse — so listing the tree is itself a check.\n let files: ValueFile[];\n try {\n files = await project.provider.list();\n } catch (error) {\n if (!(error instanceof PenvError)) {\n throw error;\n }\n return {\n result: {\n ok: false,\n environment,\n parameters: 0,\n issues: [issueFrom(error, schemaPath)],\n drift: EMPTY_DRIFT,\n },\n resolutions: [],\n };\n }\n\n const refs: ParameterRef[] = refsFrom(files);\n\n // The config decides what an environment is, so a broken config is not a\n // smaller problem than a broken value — it is the problem that makes value\n // files unreadable. `validateConfig` collects every one of them, and until it\n // was called from here it collected them for nobody: a config declaring an\n // environment with no provider, or a name no filename can hold, passed\n // `penv validate` with a ✓.\n for (const error of validateConfig(project.config)) {\n issues.push(issueFrom(error, \"penv.config.ts\"));\n }\n\n // Invariant 12: two parameters mapping to one generated variable would lose a\n // value on `penv generate`. It fails here rather than there.\n for (const collision of checkNameCollisions(refs, project.config)) {\n issues.push(issueFrom(collision, collision.variable));\n }\n\n const { schema, issues: schemaIssues } = await loadSchema(project, environment);\n issues.push(...schemaIssues);\n\n let drift: DriftReport = EMPTY_DRIFT;\n let resolutions: readonly Resolution[] = [];\n let validated: unknown;\n\n if (schema !== undefined) {\n resolutions = await resolveAll(\n environment,\n project.provider,\n keySourceFor(project, environment),\n );\n const object: Record<string, unknown> = {};\n // The access paths whose value exists and could not be read. Nothing is\n // placed at them, so the schema will call each one absent — see below.\n const undecryptable = new Set<string>();\n for (const resolution of resolutions) {\n if (resolution.undecryptable !== undefined) {\n undecryptable.add(accessPath(resolution.ref).join(\".\"));\n issues.push({\n kind: \"undecryptable\",\n subject: resolution.parameter,\n message: `${resolution.winner?.location ?? \"the winning value file\"} could not be decrypted: ${resolution.undecryptable.detail}`,\n remedy:\n \"Make the key available, or re-seal the value under a key you hold with `penv encrypt`. \" +\n \"The value is there — penv cannot read it.\",\n });\n continue;\n }\n if (resolution.value !== undefined) {\n place(object, accessPath(resolution.ref), resolution.value);\n }\n }\n // Measured from the same resolutions the verdict below is reached on, so the\n // report can never describe a tree the verdict did not read.\n drift = computeDrift({\n schema,\n resolutions,\n config: project.config,\n environment,\n schemaShapeFile,\n });\n\n const result = schema.safeParse(object);\n if (result.success) {\n validated = result.data;\n } else {\n for (const problem of result.error.issues) {\n const path = problem.path.join(\".\");\n // One absence, one line. The schema is right that nothing is there, but\n // \"expected string, received undefined\" is the wrong answer to why: the\n // value exists and penv could not read it, which is already reported\n // above with the remedy that fixes it. Printing both puts the true line\n // and the misleading one next to each other and lets the reader pick.\n if (undecryptable.has(path)) {\n continue;\n }\n issues.push({\n kind: \"schema\",\n subject: path || schemaPath,\n message: problem.message,\n remedy: `Fix the value, or adjust the schema in ${schemaShapeFile} if the shape is wrong.`,\n });\n }\n }\n }\n\n return {\n result: { ok: issues.length === 0, environment, parameters: refs.length, issues, drift },\n ...(schema === undefined ? {} : { schema }),\n resolutions,\n ...(validated === undefined ? {} : { validated }),\n };\n}\n\nexport function renderValidate(result: ValidateResult): string[] {\n if (result.ok) {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Schema valid\",\n subject: `${result.parameters} parameters for environment ${result.environment}`,\n },\n ]);\n }\n\n // Every issue validate reports is an error — that is the command's contract\n // with CI — so the glyph is the failure cross, never the warning sign.\n const rows: Row[] = result.issues.map((issue) => ({\n glyph: CROSS,\n label: LABELS[issue.kind],\n subject: issue.subject,\n detail: issue.message,\n }));\n\n const lines = formatRows(rows);\n const remedies = [...new Set(result.issues.map((issue) => issue.remedy))].filter(\n (remedy): remedy is string => remedy !== undefined,\n );\n if (remedies.length > 0) {\n lines.push(\"\");\n for (const remedy of remedies) {\n lines.push(tip(remedy));\n }\n }\n const count = result.issues.length;\n lines.push(\n \"\",\n `${out.red(CROSS)} ${count} ${count === 1 ? \"issue\" : \"issues\"} for environment ${result.environment}`,\n );\n return lines;\n}\n\nexport const validateCommand = defineCommand({\n meta: {\n name: \"validate\",\n description: \"Validate configuration against the schema; non-zero on failure\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to validate\" },\n },\n run({ args }) {\n return guard(async () => {\n const result = await runValidate({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n envFlags: shorthandCandidates(args, [\"env\"]),\n });\n write(renderValidate(result));\n if (!result.ok) {\n process.exitCode = 1;\n }\n });\n },\n});\n","/**\n * Reading the user's schema, and the distance between it and the parameter tree.\n *\n * The schema declares what must exist and the tree holds what does. The gap\n * between them is the signal `penv validate` exists to raise; this module makes\n * it legible without closing it. Nothing here writes or deletes a value file —\n * a declaration has no value, so materialising one could only invent it, and an\n * invented value is the silent-value-reaching-runtime failure penv exists to\n * delete. `penv set` stays the only writer.\n *\n * The introspection below lives here, not in `doctor`, because `doctor` and\n * `watch` both report drift and two readers of the same schema would be two\n * answers to one question.\n *\n * Every helper answers \"I cannot tell\" rather than guessing. A report is only\n * worth reading if every line in it is true, so a field this module cannot\n * understand produces no line at all.\n */\n\nimport type { ParameterRef, PenvConfig, Resolution } from \"@penvhq/core\";\nimport {\n accessPath,\n isReservedToken,\n parameterId,\n refFromAccessPath,\n variableName,\n} from \"@penvhq/core\";\nimport type { z } from \"zod\";\n\nfunction defOf(node: unknown): Record<string, unknown> | undefined {\n if (typeof node !== \"object\" || node === null) {\n return undefined;\n }\n const def = (node as { def?: unknown }).def;\n return typeof def === \"object\" && def !== null ? (def as Record<string, unknown>) : undefined;\n}\n\nexport function typeOf(node: unknown): string | undefined {\n const type = defOf(node)?.type;\n return typeof type === \"string\" ? type : undefined;\n}\n\n/** Peels `.optional()`, `.default()`, `.nullable()` — wrappers, not shapes. */\nexport function unwrap(node: unknown): unknown {\n let current = node;\n for (let depth = 0; depth < 8; depth += 1) {\n const inner = defOf(current)?.innerType;\n if (inner === undefined) {\n return current;\n }\n current = inner;\n }\n return current;\n}\n\nexport function shapeOf(node: unknown): Record<string, unknown> | undefined {\n if (typeOf(node) !== \"object\") {\n return undefined;\n }\n const shape = (node as { shape?: unknown }).shape;\n return typeof shape === \"object\" && shape !== null\n ? (shape as Record<string, unknown>)\n : undefined;\n}\n\nexport type Lookup =\n | { readonly kind: \"found\"; readonly node: unknown }\n | { readonly kind: \"absent\" }\n /** The schema is not introspectable this far down. Every check skips it. */\n | { readonly kind: \"unknown\" };\n\nexport function lookup(root: z.ZodType, path: readonly string[]): Lookup {\n let node: unknown = unwrap(root);\n for (const key of path) {\n const shape = shapeOf(node);\n if (shape === undefined) {\n return { kind: \"unknown\" };\n }\n if (!Object.hasOwn(shape, key)) {\n return { kind: \"absent\" };\n }\n node = unwrap(shape[key]);\n }\n return { kind: \"found\", node };\n}\n\n/** The declared minimum length, when the field is a string that declares one. */\nexport function minLengthOf(node: unknown): number | undefined {\n if (typeOf(node) !== \"string\") {\n return undefined;\n }\n const min = (node as { minLength?: unknown }).minLength;\n return typeof min === \"number\" ? min : undefined;\n}\n\n/**\n * Wrappers that make an absent key legal: the schema itself says this parameter\n * need not have a value, so its absence is a declaration, not drift.\n */\nconst ABSENCE_PERMITTED = new Set([\"optional\", \"default\", \"catch\", \"prefault\"]);\n\n/**\n * Wrappers that still demand the key be present. `z.string().nullable()` accepts\n * `null`, which no value file can produce — a missing file is `undefined`, and\n * `undefined` is what the schema rejects. So a nullable field with no value is\n * drift exactly as a bare one is.\n */\nconst ABSENCE_REFUSED = new Set([\"nullable\", \"nonoptional\", \"readonly\"]);\n\n/**\n * Whether the schema permits this field to have no value at all.\n * `undefined` when a wrapper is not recognised — see the module note.\n */\nfunction permitsAbsence(node: unknown): boolean | undefined {\n let current = node;\n for (let depth = 0; depth < 8; depth += 1) {\n const type = typeOf(current);\n if (type !== undefined && ABSENCE_PERMITTED.has(type)) {\n return true;\n }\n const inner = defOf(current)?.innerType;\n if (inner === undefined) {\n // A plain type, wrapped in nothing that excuses absence.\n return type === undefined ? undefined : false;\n }\n if (type === undefined || !ABSENCE_REFUSED.has(type)) {\n // A wrapper this module has never heard of. It may or may not excuse\n // absence, and guessing either way puts an untrue line in the report.\n return undefined;\n }\n current = inner;\n }\n return undefined;\n}\n\n/** One schema key that takes a value: the leaf of a path through the object shapes. */\ninterface Leaf {\n readonly path: readonly string[];\n /** False only when this key, and every namespace above it, must be present. */\n readonly absencePermitted: boolean | undefined;\n /** The schema node as declared, wrappers intact, so a `.default()` stays readable. */\n readonly node: unknown;\n}\n\n/**\n * Every leaf the schema declares. An object is a namespace and is descended\n * into; anything else is a value. A branch whose shape cannot be read is left\n * alone rather than reported as a leaf — an unreadable object is not a string.\n *\n * Absence permission is inherited, because it is inherited in fact: under\n * `z.object({ ... }).optional()` the whole namespace may be absent, so every\n * value beneath it may be too, and a leaf judged on its own wrapper would be\n * reported as drift while the schema is perfectly happy without it.\n */\nfunction leaves(\n node: unknown,\n path: readonly string[],\n inherited: boolean | undefined,\n out: Leaf[],\n): void {\n // `undefined` — a wrapper this module does not understand — is inherited as\n // \"cannot tell\" rather than collapsing to false, so an unreadable namespace\n // never makes its children look required.\n const own = permitsAbsence(node);\n const absencePermitted = inherited === true || own === true ? true : combine(inherited, own);\n\n const shape = shapeOf(unwrap(node));\n if (shape === undefined) {\n if (path.length > 0) {\n out.push({ path, absencePermitted, node });\n }\n return;\n }\n for (const key of Object.keys(shape)) {\n leaves(shape[key], [...path, key], absencePermitted, out);\n }\n}\n\n/** False only when both answers are a definite false; unknown is contagious. */\nfunction combine(left: boolean | undefined, right: boolean | undefined): boolean | undefined {\n return left === undefined || right === undefined ? undefined : false;\n}\n\nexport function declaredLeaves(schema: z.ZodType): Leaf[] {\n const out: Leaf[] = [];\n leaves(schema, [], false, out);\n return out;\n}\n\n/**\n * The declared default of a leaf, rendered for a prompt, when the leaf's wrapper\n * chain carries one this module can read and display. Only a value a reader can\n * take in at a glance is rendered — a string, a number, a boolean — because the\n * display's one job is telling the user what Enter keeps, and `[object Object]`\n * tells them nothing. A factory default is invoked to be shown; one that throws\n * is a default this module cannot know, so no value is claimed (see the module\n * note: no line is better than an untrue line).\n */\nexport function defaultValueOf(node: unknown): string | undefined {\n let current = node;\n for (let depth = 0; depth < 8; depth += 1) {\n const def = defOf(current);\n if (def === undefined) {\n return undefined;\n }\n if (typeOf(current) === \"default\" || typeOf(current) === \"prefault\") {\n let value = def.defaultValue;\n if (typeof value === \"function\") {\n try {\n value = (value as () => unknown)();\n } catch {\n return undefined;\n }\n }\n if (typeof value === \"string\") {\n return JSON.stringify(value);\n }\n if (typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\") {\n return String(value);\n }\n return undefined;\n }\n const inner = def.innerType;\n if (inner === undefined) {\n return undefined;\n }\n current = inner;\n }\n return undefined;\n}\n\n/** A parameter the schema declares that the tree has no value for. */\nexport interface DeclaredDrift {\n /** The parameter id, or the dotted schema path when no filename could reach it. */\n readonly subject: string;\n /** Absent when no filename reaches this key, which is drift `penv set` cannot close. */\n readonly ref?: ParameterRef;\n /** The line to paste: the `penv set` that closes this, or the rename that must precede it. */\n readonly remedy: string;\n readonly detail: string;\n}\n\n/** A parameter the tree holds a value for that the schema does not declare. */\nexport interface UndeclaredDrift {\n readonly ref: ParameterRef;\n /** The generated variable, which is the name the application would have read. */\n readonly variable: string;\n}\n\n/**\n * A parameter the schema declares but does not require — `.optional()`,\n * `.default()`, and their kin — that the tree has no value for. Not drift in the\n * verdict sense: absence here is a state the schema itself blessed, so `doctor`\n * and `watch` say nothing about it. It is measured for `fill`, whose reader is\n * deciding what to write, and for whom \"the schema would take an override here\"\n * is exactly the kind of fact a silent skip would hide.\n */\nexport interface OptionalDrift {\n /** The parameter id, or the dotted schema path when no filename could reach it. */\n readonly subject: string;\n /** Absent when no filename reaches this key — an override `penv set` cannot write. */\n readonly ref?: ParameterRef;\n /** What the schema falls back to, rendered for display, when it declares one this module can read. */\n readonly defaultValue?: string;\n /** The rename that must precede any override, for the key no filename reaches. */\n readonly remedy: string;\n}\n\n/**\n * The distance between the schema and the tree, in both directions. Named\n * `declared`/`undeclared` for the side that has it, not for a verdict: neither\n * direction is by itself an error, and only `validate` decides that. `optional`\n * is the deliberately verdict-free third list — see {@link OptionalDrift}.\n */\nexport interface DriftReport {\n readonly declared: readonly DeclaredDrift[];\n readonly undeclared: readonly UndeclaredDrift[];\n readonly optional: readonly OptionalDrift[];\n}\n\nexport const EMPTY_DRIFT: DriftReport = { declared: [], undeclared: [], optional: [] };\n\nexport interface DriftInput {\n readonly schema: z.ZodType;\n /** Every parameter the tree holds, resolved for `environment`. */\n readonly resolutions: readonly Resolution[];\n readonly config: PenvConfig;\n readonly environment: string;\n /**\n * The file that holds the editable schema shape, named in the remedies below.\n * Cohort-aware (see `schemaShapeFileOf`): `penv.schema.ts` for a project on the\n * split, the self-contained `schemaFile` for one scaffolded before it — a\n * hard-coded path would misdirect whichever cohort it is not from.\n */\n readonly schemaShapeFile: string;\n}\n\n/**\n * A parameter has a value for this environment when *some* file wins, not when\n * penv can read it: an `.enc` winner is a value that exists, and reporting it as\n * missing would send the user to `penv set` to overwrite a secret they have.\n */\nfunction hasValue(resolution: Resolution): boolean {\n return resolution.winner !== undefined;\n}\n\nexport function computeDrift(input: DriftInput): DriftReport {\n const { schema, resolutions, config, environment, schemaShapeFile } = input;\n\n const valued = new Set(resolutions.filter(hasValue).map((resolution) => resolution.parameter));\n\n const declared: DeclaredDrift[] = [];\n const optional: OptionalDrift[] = [];\n for (const leaf of declaredLeaves(schema)) {\n // \"Cannot tell\" produces no line at all — see the module note. Only a leaf\n // the schema definitely requires is drift, and only one it definitely\n // excuses is an optional override; a wrapper this module has never heard of\n // is neither.\n if (leaf.absencePermitted === undefined) {\n continue;\n }\n const path = leaf.path.join(\".\");\n const ref = refFromAccessPath(leaf.path);\n const renameRemedy =\n `Rename the \\`${path}\\` key in ${schemaShapeFile} — a parameter name is lower-case, ` +\n `hyphenated, and never a reserved token, so no value file reaches this key.`;\n // Declared, and permanently unreachable — two ways, one consequence. Either\n // the key is outside the name transform's image (`apiURL`), or it spells a\n // reserved token, which the filename grammar refuses as a parameter name\n // (invariant 11). No value file resolves to this key either way, so the\n // remedy is a rename: a `penv set` line here would be a command that errors.\n // An optional key is not excused from this: the schema's default will serve,\n // but the override the wrapper promises is one no file can ever deliver.\n if (ref === undefined || isReservedToken(ref.name, config)) {\n if (leaf.absencePermitted) {\n optional.push({ subject: path, remedy: renameRemedy });\n } else {\n declared.push({\n subject: path,\n remedy: renameRemedy,\n detail: \"declared, no filename reaches it\",\n });\n }\n continue;\n }\n if (valued.has(parameterId(ref))) {\n continue;\n }\n if (leaf.absencePermitted) {\n const defaultValue = defaultValueOf(leaf.node);\n optional.push({\n subject: parameterId(ref),\n ref,\n ...(defaultValue === undefined ? {} : { defaultValue }),\n remedy: `penv set ${[...ref.namespace, ref.name].join(\"/\")} --env ${environment}`,\n });\n continue;\n }\n declared.push({\n subject: parameterId(ref),\n ref,\n remedy: `penv set ${[...ref.namespace, ref.name].join(\"/\")} --env ${environment}`,\n detail: `declared in ${schemaShapeFile}, no value for ${environment}`,\n });\n }\n\n const undeclared: UndeclaredDrift[] = [];\n for (const resolution of resolutions) {\n if (lookup(schema, accessPath(resolution.ref)).kind !== \"absent\") {\n continue;\n }\n undeclared.push({\n ref: resolution.ref,\n variable: variableName(resolution.ref, config),\n });\n }\n\n return { declared, undeclared, optional };\n}\n","/**\n * `penv cleanup` — the end of a dotenv migration.\n *\n * The cutover keeps one rollback bundle so `penv init undo` can put the original\n * files back. This drops it, and only it: the records, the schema, the config\n * and the loader are the project's, and cleaning up after a migration is not the\n * same as undoing an adoption. It is also what unblocks a second migration,\n * which is refused while a bundle is unresolved.\n */\n\nimport { CUTOVER_PATH, ROLLBACK_DOTENV_PATH } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { CleanupResult } from \"../cutover.js\";\nimport { runCleanup } from \"../cutover.js\";\nimport { out } from \"../style.js\";\nimport { CHECK, formatSteps, guard, type Step, write } from \"../ui.js\";\n\nexport function renderCleanup(result: CleanupResult): string[] {\n if (!result.cleaned) {\n return [`${out.green(CHECK)} No dotenv rollback bundle to clean up.`];\n }\n const steps: Step[] = [\n ...result.removed.map((name) => ({\n glyph: CHECK,\n text: `Removed ${name}`,\n note: `from ${ROLLBACK_DOTENV_PATH}/`,\n })),\n { glyph: CHECK, text: `Removed ${CUTOVER_PATH}` },\n ];\n return [\n ...formatSteps(steps),\n \"\",\n `${out.green(CHECK)} ${out.bold(\"Cleaned up.\")} The migration is over; your records, schema and config are untouched.`,\n ];\n}\n\nexport const cleanupCommand = defineCommand({\n meta: {\n name: \"cleanup\",\n description: \"Drop the dotenv rollback bundle the last `penv init` kept\",\n },\n run() {\n return guard(async () => {\n write(renderCleanup(runCleanup({ cwd: process.cwd() })));\n });\n },\n});\n","/**\n * The recovery state of one dotenv cutover.\n *\n * `penv init` moves a project's active dotenv files into\n * `.penv/state/rollback/dotenv/` and writes `.penv/state/cutover.json` beside\n * it. Together they are a single migration's undo, and deliberately nothing\n * more: this is not local secret versioning, and a second cutover is refused\n * while a bundle is unresolved rather than stacked on top of it.\n *\n * Both are ignored by the committed `state/.gitignore`. The bundle holds the\n * plaintext values that were in the user's `.env` (invariant 20), and the state\n * file names a bundle that exists on exactly one machine — a teammate who cloned\n * it would be told a migration they never ran is waiting to be undone.\n */\n\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport {\n CUTOVER_PATH,\n findConfigFile,\n PenvError,\n ROLLBACK_DOTENV_PATH,\n ROLLBACK_PATH,\n} from \"@penvhq/core\";\n\n/** The only cutover format penv reads. A later one is a penv the project needs. */\nexport const CUTOVER_FORMAT = 1;\n\nexport interface Cutover {\n readonly format: number;\n /** When the files were moved, ISO-8601 UTC. */\n readonly movedAt: string;\n /** The filenames as they were at the project root — what undo restores, exactly. */\n readonly files: readonly string[];\n /** The environments the cutover declared, so a report can name them without the config. */\n readonly environments: readonly string[];\n}\n\nfunction fileFor(root: string, relativePosix: string): string {\n return join(root, ...relativePosix.split(\"/\"));\n}\n\n/** The bundle directory of `root`, absolute. */\nexport function bundleDir(root: string): string {\n return fileFor(root, ROLLBACK_DOTENV_PATH);\n}\n\nexport function cutoverFile(root: string): string {\n return fileFor(root, CUTOVER_PATH);\n}\n\n/**\n * The project `undo` and `cleanup` act on: the directory holding the\n * `penv.config.ts` this one is inside, exactly as every other command finds it.\n *\n * Rooted at the working directory instead, both commands would report nothing to\n * do from any subdirectory of the project they were meant to recover.\n */\nexport function cutoverRoot(cwd: string): string {\n const file = findConfigFile(cwd);\n return file === undefined ? resolve(cwd) : dirname(file);\n}\n\n/** The filenames the rollback bundle holds, sorted. Empty when there is no bundle. */\nexport function bundledFiles(root: string): string[] {\n try {\n return readdirSync(bundleDir(root)).sort();\n } catch {\n return [];\n }\n}\n\n/**\n * True while a cutover is still waiting on `penv init undo` or `penv cleanup`.\n *\n * The bundle counts on its own, not only the record that names it: a bundle with\n * no `cutover.json` is a cutover whose record was deleted by hand, and reading it\n * as \"no cutover\" is how a second migration would move a second set of files over\n * the first one's — into a gitignored directory nothing would ever look in again.\n */\nexport function bundleUnresolved(root: string): boolean {\n return readCutover(root) !== undefined || bundledFiles(root).length > 0;\n}\n\n/**\n * The recorded cutover, or `undefined` when this project has none. A file that\n * exists and cannot be read is an error, never an absence: reading it as \"no\n * cutover\" is how a second migration would move a second set of files over the\n * first one's bundle.\n */\nexport function readCutover(root: string): Cutover | undefined {\n const file = cutoverFile(root);\n if (!existsSync(file)) {\n return undefined;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(readFileSync(file, \"utf8\"));\n } catch {\n throw unreadable(\"it is not JSON\");\n }\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw unreadable(\"it is not an object\");\n }\n const record = parsed as Record<string, unknown>;\n if (record.format !== CUTOVER_FORMAT) {\n throw unreadable(\n `it is format ${JSON.stringify(record.format)}, and penv reads format ${CUTOVER_FORMAT}`,\n );\n }\n const files = record.files;\n if (!Array.isArray(files) || files.some((name) => typeof name !== \"string\")) {\n throw unreadable(\"it lists no filenames\");\n }\n const environments = Array.isArray(record.environments)\n ? record.environments.filter((name): name is string => typeof name === \"string\")\n : [];\n return {\n format: CUTOVER_FORMAT,\n movedAt: typeof record.movedAt === \"string\" ? record.movedAt : \"\",\n files: files as string[],\n environments,\n };\n}\n\nfunction unreadable(what: string): PenvError {\n return new PenvError(\n \"CUTOVER_UNREADABLE\",\n `${CUTOVER_PATH} records the last dotenv cutover, and ${what}`,\n `Run \\`penv cleanup\\` to drop that record and the rollback bundle it names.`,\n );\n}\n\n/** Sorted keys and a trailing newline, so the file is the same bytes on every machine. */\nexport function serializeCutover(cutover: Cutover): string {\n return `${JSON.stringify(\n {\n environments: [...cutover.environments],\n files: [...cutover.files],\n format: cutover.format,\n movedAt: cutover.movedAt,\n },\n null,\n 2,\n )}\\n`;\n}\n\n/**\n * Records the cutover, then moves the selected dotenv files into the bundle.\n *\n * The move is last in a cutover — everything else has already been written and\n * validated — so a failure before it leaves a project whose dotenv files are\n * exactly where they were. Within the move, the record goes first and names every\n * file the move intends: a crash or a file lock between two renames then leaves a\n * bundle penv can still describe, and `penv init undo` puts back what arrived.\n * Written the other way round, the files already moved would be orphaned in a\n * gitignored directory no command knew to look in.\n */\nexport function bundleDotenvFiles(\n root: string,\n files: readonly string[],\n environments: readonly string[],\n now: Date = new Date(),\n): Cutover {\n const cutover: Cutover = {\n format: CUTOVER_FORMAT,\n movedAt: now.toISOString(),\n files: [...files],\n environments: [...environments],\n };\n const file = cutoverFile(root);\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, serializeCutover(cutover), \"utf8\");\n\n const bundle = bundleDir(root);\n mkdirSync(bundle, { recursive: true });\n for (const name of files) {\n renameSync(join(root, name), join(bundle, name));\n }\n return cutover;\n}\n\nexport interface UndoResult {\n readonly root: string;\n /** The files put back, in the order they were moved. */\n readonly restored: readonly string[];\n /** Recorded names already at the project root — what an interrupted undo had reached. */\n readonly alreadyBack: readonly string[];\n /** Recorded names in neither the bundle nor the project root. Nothing penv can restore. */\n readonly missing: readonly string[];\n}\n\n/**\n * Puts every bundled file back under its exact original name, then drops the\n * bundle and the state that named it.\n *\n * Undo is resumable, because the thing it recovers from is an interruption. A\n * name already at the project root and no longer in the bundle is a file an\n * earlier run put back, not a collision — only a name that is in both places at\n * once is, and that is the one case worth refusing over, since restoring would\n * write over whatever came back. A name in neither place is reported rather than\n * refused: the old refusal's remedy was `penv cleanup`, which would have deleted\n * every file that was still recoverable.\n */\nexport function runUndo(options: { readonly cwd: string }): UndoResult {\n const root = cutoverRoot(options.cwd);\n const cutover = readCutover(root);\n const bundled = bundledFiles(root);\n if (cutover === undefined && bundled.length === 0) {\n throw new PenvError(\n \"INIT_UNDO_NOTHING\",\n \"There is no dotenv cutover to undo in this project\",\n \"Run `penv init` to adopt your dotenv files; undo puts them back afterwards.\",\n );\n }\n\n // The record's order, then anything the bundle holds that it does not name.\n // Only a cutover ever writes into the bundle, so a file filed there belongs at\n // the project root under the name it is filed under, recorded or not.\n const recorded = cutover?.files ?? [];\n const names = [...recorded, ...bundled.filter((name) => !recorded.includes(name))];\n\n const bundle = bundleDir(root);\n const held = new Set(bundled);\n const occupied = names.filter((name) => held.has(name) && existsSync(join(root, name)));\n if (occupied.length > 0) {\n const listed = occupied.join(\", \");\n const many = occupied.length > 1;\n throw new PenvError(\n \"INIT_UNDO_OCCUPIED\",\n `${listed} ${many ? \"exist\" : \"exists\"} again, and restoring what penv moved aside would write over ${many ? \"them\" : \"it\"}`,\n `Move ${listed} out of the way, or run \\`penv cleanup\\` to keep ${many ? \"them\" : \"it\"} and drop the bundle. Nothing was restored.`,\n );\n }\n\n const restored: string[] = [];\n const alreadyBack: string[] = [];\n const missing: string[] = [];\n for (const name of names) {\n if (held.has(name)) {\n renameSync(join(bundle, name), join(root, name));\n restored.push(name);\n } else if (existsSync(join(root, name))) {\n alreadyBack.push(name);\n } else {\n missing.push(name);\n }\n }\n removeBundle(root);\n return { root, restored, alreadyBack, missing };\n}\n\nexport interface CleanupResult {\n readonly root: string;\n /** The files the bundle held. Empty when there was nothing to clean up. */\n readonly removed: readonly string[];\n readonly cleaned: boolean;\n}\n\n/**\n * Drops the rollback bundle and the cutover state, and nothing else. The records\n * tree, the schema, the config and the loader are the project's — cleanup is the\n * end of the migration, not the end of the adoption.\n */\nexport function runCleanup(options: { readonly cwd: string }): CleanupResult {\n const root = cutoverRoot(options.cwd);\n const held = bundledFiles(root);\n const cleaned =\n held.length > 0 || existsSync(cutoverFile(root)) || existsSync(fileFor(root, ROLLBACK_PATH));\n removeBundle(root);\n return { root, removed: held, cleaned };\n}\n\nfunction removeBundle(root: string): void {\n rmSync(fileFor(root, ROLLBACK_PATH), { recursive: true, force: true });\n rmSync(cutoverFile(root), { force: true });\n}\n","/**\n * `penv doctor` — one report of everything that has drifted.\n *\n * Each check earns its place by catching something no other command can:\n *\n * - **missing** — meta marks a parameter required for this environment and it\n * resolves to nothing. Requiredness per environment is meta policy, not a\n * second schema (invariant 1).\n * - **declared** — the schema declares a parameter the tree has no value for.\n * The other half of the same distance `unused` measures, and a different\n * question from `missing`: this one is asked of the schema and answered for\n * every declared key, including one with no file anywhere — which no\n * tree-driven check can see, because a parameter with no file has no meta\n * either. It reports, and never writes: see `../schema.ts`.\n * - **weak** — the schema declares a minimum length the value does not meet.\n * - **unused** — a value file exists that the schema has no key for.\n * - **unscoped-fallback** — a real environment resolving via the unscoped\n * default. Invariant 13: fallback is never silent.\n * - **plaintext-secret** — meta declares the parameter a secret and the winning\n * value file carries no `.enc` marker. Invariant 14: encryption is\n * policy-driven, so the filename is checked *against* the policy and is never\n * the authority on what is secret.\n * - **public-secret** — meta declares the parameter a secret and its generated\n * variable carries a prefix the framework inlines into the client bundle.\n * - **rotation-overdue** — meta declares a rotation policy and more than its\n * interval has elapsed since the last completed rotation. A clock no other\n * check keeps: `missing` sees an absent value, never a stale present one.\n * - **rotation-stuck** — a `dual-valid` grace window opened and never closed. The\n * overdue clock's opposite: not a rotation that never ran, but one that started\n * and stalled with two credentials live at once.\n * - **provider-value-drift** — the local tree and the environment's readable\n * source-of-truth provider hold different opaque values for the same address.\n * The one drift a value-withholding destination can never report, because a\n * record-holding provider can be read back and a projection cannot.\n * - **artifact-in-tree** — a sealed deployment artifact is sitting inside the\n * repository. It is an external release input, built per environment and\n * mounted by the container; one in the source tree is a production ciphertext\n * a clone away from git history, and it is not a layout penv supports.\n *\n * Warnings are reported; failures are reported and exit non-zero.\n */\n\nimport type { Dirent } from \"node:fs\";\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport type {\n Meta,\n PenvConfig,\n ProjectionProvider,\n ProjectionSecret,\n Provider,\n Resolution,\n Scope,\n SecretScope,\n ValueFile,\n} from \"@penvhq/core\";\nimport {\n ARTIFACT_BUILD_COMMAND,\n accessPath,\n assertNever,\n effectiveMeta,\n environmentEntry,\n formatValueFile,\n holdsProjection,\n holdsRecords,\n isPublicVariable,\n isRequired,\n isSecret,\n isStuck,\n openValue,\n RECORDS_PATH,\n resolveAll,\n rotationOf,\n tryParseDuration,\n variableName,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { z } from \"zod\";\nimport { shadowedEnvironments, shorthandCandidates } from \"../env-flags.js\";\nimport type { Project } from \"../project.js\";\nimport {\n keySourceFor,\n openProject,\n schemaShapeFileOf,\n sourceProviderFor,\n targetEnvironment,\n} from \"../project.js\";\nimport { LOCAL_TREE_TYPE, localExtensions } from \"../registry.js\";\nimport type { DriftReport } from \"../schema.js\";\nimport { computeDrift, lookup, minLengthOf } from \"../schema.js\";\nimport { out } from \"../style.js\";\nimport {\n CHECK,\n CROSS,\n formatRows,\n guard,\n heading,\n type Row,\n tip,\n UNKNOWN,\n WARN,\n write,\n} from \"../ui.js\";\nimport { LAST_PUSHED_KEY } from \"./push.js\";\nimport { loadSchema } from \"./validate.js\";\n\n/**\n * A check reports one of four verdicts. `unknown` — a check that ran but could\n * not reach a verdict — is never rendered as a pass: \"I looked and found nothing\n * wrong\" and \"I could not look\" are opposite situations with opposite remedies,\n * and a value-withholding destination makes most of what doctor can say the\n * second kind.\n */\nexport type DoctorSeverity = \"pass\" | \"warning\" | \"failure\" | \"unknown\";\n\nexport type DoctorCheck =\n | \"schema\"\n | \"missing\"\n | \"declared\"\n | \"weak\"\n | \"unused\"\n | \"unscoped-fallback\"\n | \"secrecy-undeclared\"\n | \"plaintext-secret\"\n | \"public-secret\"\n | \"encryption\"\n | \"rotation-overdue\"\n | \"rotation-stuck\"\n | \"provider-value-drift\"\n | \"provider\"\n | \"projection-unreachable\"\n | \"projection-name-drift\"\n | \"projection-manual-edit\"\n | \"projection-value-drift\"\n | \"environment-flag-shadow\"\n | \"local-extension\"\n | \"artifact-in-tree\";\n\nexport interface DoctorFinding {\n readonly check: DoctorCheck;\n readonly severity: DoctorSeverity;\n readonly label: string;\n readonly subject?: string;\n readonly detail?: string;\n /** A line the reader can act on — the `penv set` to paste, where there is one. */\n readonly remedy?: string;\n}\n\nexport interface DoctorReport {\n readonly environment: string;\n readonly findings: readonly DoctorFinding[];\n /** False when any finding is a failure. Warnings and unknowns do not fail the run. */\n readonly ok: boolean;\n}\n\nexport interface DoctorOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n /** Injected in tests: the projection-holding destination to check against. Defaults to the one the config declares. */\n readonly projection?: ProjectionProvider;\n /**\n * Injected in tests: the source-of-truth provider to compare the local tree\n * against. Defaults to the one the config declares (`sourceProviderFor`).\n * Mirrors `projection`, for the same reason — the drift checks stay driveable\n * without a live backend.\n */\n readonly source?: Provider;\n /** Injected in tests: the wall-clock reading the rotation clocks are read against. Defaults to now. */\n readonly now?: string;\n /** Injected in tests: how long a `dual-valid` window may stay open before it reads as stuck. Defaults to 24h. */\n readonly stuckThresholdMs?: number;\n}\n\n/**\n * How long a `dual-valid` grace window may stay open before `rotation-stuck`\n * flags it. A day is generous for the overlap most rotations need — long enough\n * that a healthy rotation completing within a deploy or two never trips it, short\n * enough that a window left open for a week is caught while it still matters.\n */\nconst STUCK_THRESHOLD_MS = 86_400_000;\n\ninterface Subject {\n readonly resolution: Resolution;\n readonly meta: Meta | undefined;\n}\n\n/**\n * A check the schema failure above made impossible: `unknown`, not `warning`.\n * penv did not look, so it cannot claim there is nothing to find — and it cannot\n * claim a problem either. The verdict is \"I could not tell\".\n */\nfunction skipped(check: DoctorCheck, label: string): DoctorFinding {\n return {\n check,\n severity: \"unknown\",\n label,\n subject: \"not checked\",\n detail: \"the schema did not load, so this check could not run\",\n };\n}\n\nexport async function runDoctor(options: DoctorOptions): Promise<DoctorReport> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n const findings: DoctorFinding[] = [];\n // The wall clock, read once and passed down — never read inside a check — so the\n // rotation boundaries the roadmap names are testable without mocking time, the\n // same discipline `rotation.ts` and `push.ts` keep.\n const now = new Date(options.now ?? new Date().toISOString());\n const stuckThresholdMs = options.stuckThresholdMs ?? STUCK_THRESHOLD_MS;\n\n // Rule 1 of the environment shorthand flags: a real flag always wins, so an\n // environment sharing a flag's name simply has no shorthand. Said here, once,\n // rather than discovered as a flag that quietly means something else.\n for (const shadowed of shadowedEnvironments(project.config)) {\n findings.push({\n check: \"environment-flag-shadow\",\n severity: \"warning\",\n label: \"Environment shadows a flag\",\n subject: shadowed,\n detail: `\\`--${shadowed}\\` is a flag penv defines, so this environment has no shorthand — \\`--env ${shadowed}\\` always works`,\n });\n }\n\n const { schema, issues } = await loadSchema(project, environment);\n if (schema !== undefined) {\n findings.push({ check: \"schema\", severity: \"pass\", label: \"Schema valid\" });\n } else {\n for (const issue of issues) {\n findings.push({\n check: \"schema\",\n severity: \"failure\",\n label: \"Schema\",\n subject: issue.subject,\n detail: issue.message,\n });\n }\n }\n\n const resolutions = await resolveAll(\n environment,\n project.provider,\n keySourceFor(project, environment),\n );\n const subjects: Subject[] = await Promise.all(\n resolutions.map(async (resolution) => ({\n resolution,\n meta: await project.provider.readMeta(resolution.ref),\n })),\n );\n\n const missing = missingFindings(subjects, environment);\n findings.push(...missing);\n // A check that could not run says so. Printing nothing where a check belongs\n // reads as \"nothing found\", which is the one thing a report must never imply.\n if (schema === undefined) {\n findings.push(\n skipped(\"declared\", \"Schema coverage\"),\n skipped(\"weak\", \"Secret strength\"),\n skipped(\"unused\", \"Value coverage\"),\n );\n } else {\n const schemaShapeFile = schemaShapeFileOf(project);\n const drift = computeDrift({\n schema,\n resolutions: subjects.map(({ resolution }) => resolution),\n config: project.config,\n environment,\n schemaShapeFile,\n });\n findings.push(...declaredFindings(drift, missing, environment, schemaShapeFile));\n findings.push(...weakFindings(subjects, schema));\n findings.push(...unusedFindings(drift));\n }\n findings.push(...fallbackFindings(subjects, environment));\n findings.push(...secrecyFindings(subjects, environment));\n findings.push(...plaintextSecretFindings(subjects, environment));\n findings.push(...publicSecretFindings(subjects, environment, project.config));\n findings.push(...encryptionFindings(subjects, environment));\n // The rotation clocks read the environment's SOURCE provider, not `subjects`,\n // whose meta is the local tree's. `penv rotate` writes `rotatingSince` /\n // `state` / `lastRotated` to the source of truth (a `dual-valid` rotation\n // REQUIRES a retaining backend, so its rotating-state meta is never in the\n // local tree at all) — reading `subjects` here saw stale local meta and never\n // fired for a backend-backed environment.\n const rotation = await rotationSubjects(project, environment, subjects, options.source);\n if (rotation.kind === \"unreachable\") {\n findings.push(rotation.finding);\n } else {\n findings.push(...overdueFindings(rotation.subjects, environment, now));\n findings.push(...stuckFindings(rotation.subjects, environment, now, stuckThresholdMs));\n }\n findings.push(...(await providerDriftFindings(project, environment, options.source)));\n findings.push(...(await projectionFindings(project, environment, options.projection)));\n findings.push(...localExtensionFindings(project));\n findings.push(...artifactFindings(project));\n\n findings.push({\n check: \"provider\",\n severity: \"pass\",\n label: \"Provider\",\n subject: environmentEntry(project.config, environment)?.provider ?? project.provider.type,\n });\n\n return {\n environment,\n findings,\n ok: !findings.some((finding) => finding.severity === \"failure\"),\n };\n}\n\nfunction missingFindings(subjects: readonly Subject[], environment: string): DoctorFinding[] {\n const required = subjects.filter(({ meta }) => isRequired(meta, environment));\n const findings: DoctorFinding[] = required\n .filter(({ resolution }) => resolution.winner === undefined)\n .map(({ resolution }) => ({\n check: \"missing\",\n severity: \"failure\",\n label: \"Missing parameter\",\n subject: resolution.parameter,\n detail: `required for ${environment}, absent`,\n remedy: `penv set ${[...resolution.ref.namespace, resolution.ref.name].join(\"/\")} --env ${environment}`,\n }));\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"missing\",\n severity: \"pass\",\n label: \"Required parameters\",\n subject:\n required.length === 0\n ? `none required for ${environment}`\n : `${required.length} required for ${environment}, all present`,\n },\n ];\n}\n\n/**\n * Schema → tree: declared, with no value for this environment.\n *\n * A warning, not a failure. The schema decides whether an absent value is fatal\n * and `penv validate` is where that verdict is reached; saying it twice, in two\n * voices, would make this report the second authority the design does not have.\n *\n * Parameters the `missing` check already named are dropped rather than repeated:\n * that line is the same absence with meta's stronger verdict on it, and it now\n * carries the same paste line. One absence, one line.\n */\nfunction declaredFindings(\n drift: DriftReport,\n missing: readonly DoctorFinding[],\n environment: string,\n schemaShapeFile: string,\n): DoctorFinding[] {\n const reported = new Set(missing.filter((f) => f.severity !== \"pass\").map((f) => f.subject));\n\n const findings: DoctorFinding[] = drift.declared\n .filter((item) => !reported.has(item.subject))\n .map((item) => ({\n check: \"declared\",\n severity: \"warning\",\n label: \"Declared, no value\",\n subject: item.subject,\n detail: item.detail,\n remedy: item.remedy,\n }));\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"declared\",\n severity: \"pass\",\n label: \"Schema coverage\",\n subject: `every parameter ${schemaShapeFile} requires has a value for ${environment}`,\n },\n ];\n}\n\nfunction weakFindings(subjects: readonly Subject[], schema: z.ZodType): DoctorFinding[] {\n const findings: DoctorFinding[] = [];\n let checked = 0;\n\n for (const { resolution } of subjects) {\n const value = resolution.value;\n // A decrypted secret has a value here, so it is length-checked like any\n // other — an encrypted secret used to be invisible to this check, which made\n // \"the schema declares a minimum\" a promise that quietly excluded exactly the\n // values a minimum is for. Absence is two other checks' business: an\n // undecryptable winner is the encryption check's, and nothing at all is the\n // missing check's.\n if (value === undefined) {\n continue;\n }\n const field = lookup(schema, accessPath(resolution.ref));\n if (field.kind !== \"found\") {\n continue;\n }\n const minimum = minLengthOf(field.node);\n if (minimum === undefined) {\n continue;\n }\n checked += 1;\n if (value.length >= minimum) {\n continue;\n }\n findings.push({\n check: \"weak\",\n severity: \"failure\",\n label: \"Weak secret\",\n subject: resolution.parameter,\n detail: `${value.length} chars, schema requires ≥${minimum}`,\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"weak\",\n severity: \"pass\",\n label: \"Secret strength\",\n subject:\n checked === 0\n ? \"no schema field declares a minimum length\"\n : checked === 1\n ? \"1 value meets the schema minimum\"\n : `${checked} values meet the schema minimum`,\n },\n ];\n}\n\n/** Tree → schema: a value the application has no declared way to read. */\nfunction unusedFindings(drift: DriftReport): DoctorFinding[] {\n const findings: DoctorFinding[] = drift.undeclared.map((item) => ({\n check: \"unused\",\n severity: \"warning\",\n label: \"Unused parameter\",\n subject: item.variable,\n detail: \"present, not in schema\",\n }));\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"unused\",\n severity: \"pass\",\n label: \"Value coverage\",\n subject: \"every value file has a schema key\",\n },\n ];\n}\n\nfunction fallbackFindings(subjects: readonly Subject[], environment: string): DoctorFinding[] {\n const findings: DoctorFinding[] = subjects\n .filter(({ resolution }) => resolution.viaUnscopedFallback)\n .map(({ resolution }) => ({\n check: \"unscoped-fallback\",\n severity: \"warning\",\n label: \"Unscoped fallback in use\",\n subject: resolution.parameter,\n detail: `${environment} resolving to default`,\n }));\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"unscoped-fallback\",\n severity: \"pass\",\n label: \"Scoped resolution\",\n subject: `no parameter falls back to the unscoped default for ${environment}`,\n },\n ];\n}\n\n/**\n * The question the encryption checks are answers to, asked of the meta itself.\n *\n * Encryption is policy-driven (invariant 14): meta declares what must be sealed\n * and the filename is never the authority. So a parameter whose meta says\n * nothing about secrecy is not \"not a secret\" — it is one penv has never been\n * told about, and `plaintext-secret` reporting a clean run over it is a promise\n * made from an empty file. That is what the fourth verdict is for.\n *\n * Summarized once. Twenty-five parameters with no meta is one fact about the\n * project, and twenty-five identical rows would bury every other check.\n */\nfunction secrecyFindings(subjects: readonly Subject[], environment: string): DoctorFinding[] {\n const undeclared = subjects.filter(\n ({ meta }) => effectiveMeta(meta, environment).secret === undefined,\n );\n\n if (undeclared.length === 0) {\n return [\n {\n check: \"secrecy-undeclared\",\n severity: \"pass\",\n label: \"Secrecy policy\",\n subject:\n subjects.length === 0\n ? `no parameter resolves for ${environment}`\n : `every parameter declares whether it is secret for ${environment}`,\n },\n ];\n }\n\n return [\n {\n check: \"secrecy-undeclared\",\n severity: \"unknown\",\n label: \"Secrecy policy\",\n subject: `${undeclared.length} of ${subjects.length} declare neither way for ${environment}`,\n detail: \"penv was never told which of these values must be encrypted\",\n remedy: `declare \\`\"secret\": true\\` or \\`\"secret\": false\\` in a parameter's meta file, ${RECORDS_PATH}/<name>.json`,\n },\n ];\n}\n\nfunction plaintextSecretFindings(\n subjects: readonly Subject[],\n environment: string,\n): DoctorFinding[] {\n const secrets = subjects.filter(({ meta }) => isSecret(meta, environment));\n const findings: DoctorFinding[] = [];\n\n for (const { resolution } of secrets) {\n const winner = resolution.winner;\n // Nothing resolves: that is the missing check's business, not this one's.\n if (winner === undefined || winner.file.encrypted) {\n continue;\n }\n findings.push({\n check: \"plaintext-secret\",\n severity: \"failure\",\n label: \"Plaintext secret\",\n subject: winner.location,\n detail: \"value file is not encrypted\",\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"plaintext-secret\",\n severity: \"pass\",\n label: \"Encryption policy\",\n subject:\n secrets.length === 0\n ? `no parameter is declared secret for ${environment}`\n : `every secret resolving for ${environment} is encrypted`,\n },\n ];\n}\n\n/**\n * The third face of the same policy: is it sealed, can it be opened, and is it\n * public. A secret whose generated variable starts with a framework's public\n * prefix is inlined into the client bundle — `NEXT_PUBLIC_STRIPE_SECRET` reaches\n * every browser that loads the page, permanently, in a bundle nobody can recall.\n *\n * Nothing else in the stack can see this. To the framework the prefix *is* the\n * intent: Next inlines `NEXT_PUBLIC_*` by definition and has no notion that the\n * value is secret. The application's own env module knows the name and not the\n * policy. penv holds both — meta says secret, the name transform says public —\n * so this contradiction is only visible from here.\n *\n * Read of the *generated* variable rather than the parameter name, because a\n * `override` entry is what decides the string the framework sees, and it is the\n * one place the prefix can appear with nothing in the tree hinting at it.\n * Absence of a value is deliberately not a reprieve: the name is already wrong,\n * and the next `penv set` is what ships it.\n */\nfunction publicSecretFindings(\n subjects: readonly Subject[],\n environment: string,\n config: PenvConfig,\n): DoctorFinding[] {\n const prefixes = config.publicPrefixes ?? [];\n // Nothing declared, nothing checkable: a prefix penv was never told about is\n // one it cannot recognise. This is the \"I cannot tell\" answer, and it is not\n // the same as a clean report — saying \"no secret is exposed\" here would be a\n // promise made by a check that never looked at anything.\n if (prefixes.length === 0) {\n return [\n {\n check: \"public-secret\",\n severity: \"unknown\",\n label: \"Browser exposure\",\n subject: \"not checked — penv.config.ts declares no `publicPrefixes`\",\n detail: \"penv cannot tell which variables a framework inlines into the browser\",\n },\n ];\n }\n\n const secrets = subjects.filter(({ meta }) => isSecret(meta, environment));\n const findings: DoctorFinding[] = [];\n\n for (const { resolution } of secrets) {\n const variable = variableName(resolution.ref, config);\n if (!isPublicVariable(variable, config)) {\n continue;\n }\n // Which prefix matched is for the message alone; core stays the authority on\n // whether the variable is public at all.\n const prefix = prefixes.find((candidate) => variable.startsWith(candidate));\n findings.push({\n check: \"public-secret\",\n severity: \"failure\",\n label: \"Secret exposed to the browser\",\n subject: variable,\n detail:\n prefix === undefined\n ? \"meta declares this a secret, and its public prefix makes it public\"\n : `meta declares this a secret, and the \\`${prefix}\\` prefix makes it public`,\n remedy:\n \"rename the parameter so it carries no public prefix, or drop `secret` from its meta if it is not one\",\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"public-secret\",\n severity: \"pass\",\n label: \"Browser exposure\",\n subject: `no secret is exposed to the browser for ${environment}`,\n },\n ];\n}\n\n/**\n * The other half of the encryption policy: `plaintext-secret` catches a secret\n * that should be sealed and is not; this catches a sealed value penv cannot open.\n *\n * A failure, not a warning. An unopenable value is indistinguishable from an\n * absent one to everything downstream — the app gets nothing either way — and\n * the whole point of the `undecryptable` field is that penv can tell the\n * difference even when the application cannot.\n */\nfunction encryptionFindings(subjects: readonly Subject[], environment: string): DoctorFinding[] {\n const sealed = subjects.filter(({ resolution }) => resolution.winner?.file.encrypted === true);\n const findings: DoctorFinding[] = [];\n\n for (const { resolution } of sealed) {\n const failure = resolution.undecryptable;\n if (failure === undefined) {\n continue;\n }\n findings.push({\n check: \"encryption\",\n severity: \"failure\",\n label: \"Undecryptable value\",\n subject: resolution.winner?.location ?? resolution.parameter,\n detail: failure.detail,\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n // Two different quiets, reported differently. \"Nothing is encrypted here\" and\n // \"everything encrypted here opens\" are both passes, and a reader who cannot\n // tell them apart cannot tell whether the check ran.\n return [\n {\n check: \"encryption\",\n severity: \"pass\",\n label: \"Encryption\",\n subject:\n sealed.length === 0\n ? `no encrypted value resolves for ${environment}`\n : `every encrypted value resolving for ${environment} decrypts`,\n },\n ];\n}\n\n/**\n * A report against a projection-holding, value-withholding provider is mostly\n * `unknown` by construction, and honest about it. Three tiers, rendered\n * differently (RFC \"Everything the config names is a provider\"):\n *\n * - **names** are exact, because listing them is the one read the destination\n * allows: declared-but-never-pushed, and present-in-the-destination-but-\n * undeclared — the `declared`/`unused` pair pointed at the store.\n * - **manual edits** are detectable indirectly: GitHub's `updated_at` newer than\n * penv's own last-push time (kept per environment in committed meta) means the\n * secret was touched outside penv. A warning, never a failure — it detects that\n * something was touched, not that the copies differ.\n * - **values** are `unknown`, permanently, because they cannot be read back.\n *\n * The whole report is `unknown` when the destination cannot be reached — the\n * fourth verdict earning its keep against a value-withholding store.\n */\n/** Slack between penv's local push time and the destination's server `updated_at` before a difference reads as a hand-edit. */\nconst EDIT_SKEW_MS = 120_000;\n\nfunction errorDetail(error: unknown): string {\n if (error instanceof Error) {\n return error.message.split(\"\\n\")[0] ?? error.message;\n }\n return String(error);\n}\n\nfunction scopeLabel(scope: SecretScope): string {\n return scope.kind === \"repository\"\n ? \"repository secrets\"\n : `environment secrets for ${scope.environment}`;\n}\n\ninterface Expected {\n readonly ref: Resolution[\"ref\"];\n readonly variable: string;\n readonly scope: SecretScope;\n}\n\nasync function projectionFindings(\n project: Project,\n environment: string,\n override: ProjectionProvider | undefined,\n): Promise<DoctorFinding[]> {\n let projection: ProjectionProvider;\n if (override !== undefined) {\n projection = override;\n } else {\n const declared = environmentEntry(project.config, environment);\n if (declared === undefined || declared.provider === LOCAL_TREE_TYPE) {\n return [];\n }\n let source: Awaited<ReturnType<typeof sourceProviderFor>>;\n try {\n source = await sourceProviderFor(project, environment);\n } catch (error) {\n return [\n {\n check: \"projection-unreachable\",\n severity: \"unknown\",\n label: \"Destination\",\n subject: `could not build the ${declared.provider} provider for ${environment}`,\n detail: errorDetail(error),\n },\n ];\n }\n // A record-holding source is checked value by value in\n // `providerDriftFindings`; these tiers exist only for the store that\n // withholds its values.\n if (!holdsProjection(source)) {\n return [];\n }\n projection = source;\n }\n\n try {\n await projection.verify();\n } catch (error) {\n return [\n {\n check: \"projection-unreachable\",\n severity: \"unknown\",\n label: \"Destination\",\n subject: `could not reach the ${projection.type} destination for ${environment}`,\n detail: errorDetail(error),\n },\n ];\n }\n\n let repoSecrets: ProjectionSecret[];\n let envSecrets: ProjectionSecret[];\n try {\n repoSecrets = await projection.list({ kind: \"repository\" });\n envSecrets = await projection.list({ kind: \"environment\", environment });\n } catch (error) {\n return [\n {\n check: \"projection-unreachable\",\n severity: \"unknown\",\n label: \"Destination\",\n subject: `could not list secrets in the ${projection.type} destination for ${environment}`,\n detail: errorDetail(error),\n },\n ];\n }\n\n // The push view: what a push would place, `.local` dropped, so doctor compares\n // the same set a push would send.\n const resolutions = await resolveAll(\n environment,\n project.provider,\n keySourceFor(project, environment),\n true,\n );\n const expected: Expected[] = [];\n for (const resolution of resolutions) {\n const winner = resolution.winner;\n if (winner === undefined) {\n continue;\n }\n expected.push({\n ref: resolution.ref,\n variable: variableName(resolution.ref, project.config),\n scope:\n winner.file.scope.kind === \"unscoped\"\n ? { kind: \"repository\" }\n : { kind: \"environment\", environment },\n });\n }\n\n // GitHub secret names are case-insensitive, and the pre-flight already refused\n // any case collision, so comparing by uppercase is exact and safe.\n const upper = (name: string): string => name.toUpperCase();\n const repoByName = new Map(repoSecrets.map((secret) => [upper(secret.name), secret]));\n const envByName = new Map(envSecrets.map((secret) => [upper(secret.name), secret]));\n const destOf = (scope: SecretScope): Map<string, ProjectionSecret> =>\n scope.kind === \"repository\" ? repoByName : envByName;\n\n const nameDrift: DoctorFinding[] = [];\n const expectedEnv = new Set<string>();\n // Every variable this environment maps, at any scope. A repository secret is\n // shared across all environments, so it is \"declared\" as long as *some*\n // parameter produces its name — even one this environment resolves to an\n // environment-scoped override. Judging a repository secret against only this\n // environment's unscoped winners would flag another environment's default.\n const allVariables = new Set<string>();\n for (const item of expected) {\n const key = upper(item.variable);\n allVariables.add(key);\n if (item.scope.kind === \"environment\") {\n expectedEnv.add(key);\n }\n if (!destOf(item.scope).has(key)) {\n nameDrift.push({\n check: \"projection-name-drift\",\n severity: \"warning\",\n label: \"Declared, not pushed\",\n subject: item.variable,\n detail: `resolves for ${environment} but is absent from the ${scopeLabel(item.scope)}`,\n remedy: `penv push --env ${environment}`,\n });\n }\n }\n for (const secret of repoSecrets) {\n if (!allVariables.has(upper(secret.name))) {\n nameDrift.push({\n check: \"projection-name-drift\",\n severity: \"warning\",\n label: \"In destination, not declared\",\n subject: secret.name,\n detail: `a repository secret with no parameter penv pushes for ${environment}`,\n });\n }\n }\n for (const secret of envSecrets) {\n if (!expectedEnv.has(upper(secret.name))) {\n nameDrift.push({\n check: \"projection-name-drift\",\n severity: \"warning\",\n label: \"In destination, not declared\",\n subject: secret.name,\n detail: `an environment secret with no parameter resolving for ${environment}`,\n });\n }\n }\n\n const manualEdits: DoctorFinding[] = [];\n for (const item of expected) {\n const secret = destOf(item.scope).get(upper(item.variable));\n if (secret === undefined) {\n continue;\n }\n const pushed = effectiveMeta(await project.provider.readMeta(item.ref), environment)[\n LAST_PUSHED_KEY\n ];\n if (typeof pushed !== \"string\") {\n continue;\n }\n const destTime = Date.parse(secret.updatedAt);\n const pushTime = Date.parse(pushed);\n // The tolerance absorbs the skew between penv's local clock and GitHub's\n // server clock (and GitHub's whole-second truncation of `updated_at`), so a\n // clean push does not read as an edit. A genuine UI edit lands minutes to\n // days later, well outside it — this is a sensitive detector, not a proof.\n if (Number.isNaN(destTime) || Number.isNaN(pushTime) || destTime <= pushTime + EDIT_SKEW_MS) {\n continue;\n }\n manualEdits.push({\n check: \"projection-manual-edit\",\n severity: \"warning\",\n label: \"Edited outside penv\",\n subject: item.variable,\n detail: `changed in the destination at ${secret.updatedAt}, after penv last pushed it`,\n });\n }\n\n const findings: DoctorFinding[] = [];\n findings.push(\n ...(nameDrift.length > 0\n ? nameDrift\n : [\n {\n check: \"projection-name-drift\" as const,\n severity: \"pass\" as const,\n label: \"Destination names\",\n subject: `every parameter resolving for ${environment} is present, and nothing undeclared is`,\n },\n ]),\n );\n findings.push(\n ...(manualEdits.length > 0\n ? manualEdits\n : [\n {\n check: \"projection-manual-edit\" as const,\n severity: \"pass\" as const,\n label: \"Destination hand-edits\",\n subject: `no secret has changed outside penv since its last push for ${environment}`,\n },\n ]),\n );\n findings.push({\n check: \"projection-value-drift\",\n severity: \"unknown\",\n label: \"Destination values\",\n subject: \"cannot be read back from a write-only destination\",\n detail: \"value drift between the tree and the destination is unknowable by design\",\n });\n return findings;\n}\n\n/** What a scan never descends into: git's own store, and packages penv did not write. */\nconst UNSCANNED_DIRS: ReadonlySet<string> = new Set([\".git\", \"node_modules\"]);\n\n/** Above this, a file is not the canonical JSON `penv artifact build` writes. */\nconst ARTIFACT_SCAN_LIMIT = 1_048_576;\n\n/**\n * Whether a file is a sealed deployment artifact, decided on its keys.\n *\n * Deliberately looser than {@link parseArtifact}: an artifact whose digest no\n * longer matches, or one a newer penv wrote, is still an artifact sitting in the\n * repository, and the whole point of the finding is that it is *there*. The\n * cheap substring gate runs first so a repository's ordinary JSON is never\n * parsed.\n */\nfunction looksLikeArtifact(text: string): boolean {\n if (!text.includes('\"schemaDigest\"')) {\n return false;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return false;\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return false;\n }\n const keys = [\"format\", \"environment\", \"engineVersion\", \"schemaDigest\", \"keySource\", \"values\"];\n return keys.every((key) => key in parsed);\n}\n\n/** Every `.json` file under `directory` a scan is willing to open. */\nfunction scannableFiles(directory: string, out: string[]): void {\n let entries: Dirent[];\n try {\n entries = readdirSync(directory, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const path = join(directory, entry.name);\n if (entry.isDirectory()) {\n if (!UNSCANNED_DIRS.has(entry.name)) {\n scannableFiles(path, out);\n }\n continue;\n }\n if (entry.isFile() && entry.name.endsWith(\".json\")) {\n out.push(path);\n }\n }\n}\n\n/**\n * A deployment artifact inside the repository.\n *\n * The artifact is the one penv file that is deliberately *not* part of the\n * project: it is built per release, holds one environment's sealed values, and\n * is mounted by the container that runs from it. One in the source tree is a\n * production ciphertext one `git add` away from being permanent — and `dist/` is\n * not an exception, because putting an artifact there does not make any platform\n * load it.\n *\n * The scan is bounded by what the writer produces: canonical JSON, so `.json`\n * files only, under a megabyte, outside `.git` and `node_modules`.\n */\n/**\n * The extensions this project develops rather than pins.\n *\n * Nothing is wrong with the arrangement — a repository that writes a provider\n * has to be able to use it — but nothing pins the bytes either, so penv cannot\n * say the adapter here is the adapter anyone else gets. That is the `?` verdict:\n * reported so the state is visible in the same place every other decision is,\n * rather than living only in whoever's `node_modules` happens to hold it.\n */\nfunction localExtensionFindings(project: Project): DoctorFinding[] {\n const names = localExtensions(project.root);\n if (names.length === 0) {\n return [\n {\n check: \"local-extension\",\n severity: \"pass\",\n label: \"Extensions\",\n subject: \"every extension this project names is pinned\",\n },\n ];\n }\n return [\n {\n check: \"local-extension\",\n severity: \"unknown\",\n label: \"Extensions\",\n subject: names.join(\", \"),\n detail: \"resolved from this project's node_modules — no release, no pinned bytes\",\n remedy: `publish it and run \\`penv add ${names[0]}\\` when this stops being a development path`,\n },\n ];\n}\n\nfunction artifactFindings(project: Project): DoctorFinding[] {\n const files: string[] = [];\n scannableFiles(project.root, files);\n\n const findings: DoctorFinding[] = [];\n for (const file of files) {\n let text: string;\n try {\n if (statSync(file).size > ARTIFACT_SCAN_LIMIT) {\n continue;\n }\n text = readFileSync(file, \"utf8\");\n } catch {\n continue;\n }\n if (!looksLikeArtifact(text)) {\n continue;\n }\n findings.push({\n check: \"artifact-in-tree\",\n severity: \"failure\",\n label: \"Artifact in the repository\",\n subject: relative(project.root, file).split(\"\\\\\").join(\"/\"),\n detail: \"a sealed deployment artifact is an external release input, not part of the source\",\n remedy:\n \"Delete it and build the artifact outside the repository with \" +\n `\\`${ARTIFACT_BUILD_COMMAND}\\`, then mount it at PENV_SNAPSHOT.`,\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"artifact-in-tree\",\n severity: \"pass\",\n label: \"Deployment artifacts\",\n subject: \"none inside the repository\",\n },\n ];\n}\n\n/** A rough, human-facing span — the largest whole unit that fits. Never precise, and never claims to be. */\nfunction humanizeMs(ms: number): string {\n const abs = Math.max(0, ms);\n const day = 86_400_000;\n const hour = 3_600_000;\n const minute = 60_000;\n const round = (value: number, unit: string): string => {\n const n = Math.round(value);\n return `${n} ${unit}${n === 1 ? \"\" : \"s\"}`;\n };\n if (abs >= day) return round(abs / day, \"day\");\n if (abs >= hour) return round(abs / hour, \"hour\");\n if (abs >= minute) return round(abs / minute, \"minute\");\n return round(abs / 1000, \"second\");\n}\n\n/** The `<namespace>/<name>` path a `penv rotate` remedy pastes. */\nfunction refPathOf(ref: Resolution[\"ref\"]): string {\n return [...ref.namespace, ref.name].join(\"/\");\n}\n\n/**\n * The rotation clocks read the environment's source of truth, so this reads each\n * parameter's meta from the SOURCE provider rather than the local tree.\n *\n * `penv rotate` writes rotation state (`rotatingSince` / `state` / `lastRotated`)\n * to `sourceProviderFor(environment)` — a backend for a vault/mock env — and a\n * `dual-valid` rotation cannot run without one, so a backend-backed env's\n * rotating-state meta is NEVER in the local `.penv` tree. Reading `subjects`\n * (whose meta is the local tree's) left the overdue/stuck checks reading stale\n * local meta that never fired.\n *\n * When the source IS the local tree — the env declares no backend, or declares\n * `filesystem` — the two coincide, so the metas already read for `subjects` are\n * reused rather than round-tripping the identical files a second time. A backend\n * is read once, wrapped in try/catch: an unreachable source yields a single\n * `unknown` rotation finding, mirroring `projectionFindings`' tiering, because \"the\n * clock says overdue\" and \"penv could not read the clock\" are opposite verdicts.\n */\ntype RotationSubjects =\n | { readonly kind: \"read\"; readonly subjects: readonly Subject[] }\n | { readonly kind: \"unreachable\"; readonly finding: DoctorFinding };\n\nasync function rotationSubjects(\n project: Project,\n environment: string,\n local: readonly Subject[],\n override: Provider | undefined,\n): Promise<RotationSubjects> {\n const providerConfig = environmentEntry(project.config, environment);\n // No override and a local-tree source: the meta is the same meta `subjects`\n // already hold, so reuse it and make no extra round-trips.\n if (\n override === undefined &&\n (providerConfig === undefined || providerConfig.provider === LOCAL_TREE_TYPE)\n ) {\n return { kind: \"read\", subjects: local };\n }\n\n const source = override ?? (await sourceProviderFor(project, environment));\n // A projection-holding destination stores no meta at all, so the local tree\n // stays the keeper of this environment's rotation clocks.\n if (!holdsRecords(source)) {\n return { kind: \"read\", subjects: local };\n }\n try {\n const subjects: Subject[] = await Promise.all(\n local.map(async ({ resolution }) => ({\n resolution,\n meta: await source.readMeta(resolution.ref),\n })),\n );\n return { kind: \"read\", subjects };\n } catch (error) {\n return {\n kind: \"unreachable\",\n finding: {\n check: \"rotation-overdue\",\n severity: \"unknown\",\n label: \"Rotation\",\n subject: `could not reach the ${providerConfig?.provider ?? source.type} source of truth for ${environment}`,\n detail: errorDetail(error),\n },\n };\n }\n}\n\n/**\n * A staleness clock no other check keeps: `missing` reports a value that is\n * absent, and this reports one that is present and too old. The two are opposite\n * failures — a value nobody set, and a value nobody has changed in longer than\n * its own policy allows — and only meta's `rotationPolicy` plus `lastRotated`\n * make the second visible at all.\n *\n * The policy is parsed ONCE, here, inside `tryParseDuration`. The old code called\n * `isOverdue` (which parses via the throwing `parseDuration`) in this unguarded\n * loop, then parsed a SECOND time for the `overdueBy` text — so a single policy\n * `parseDuration` rejects (`1h30m`, `3 months`) threw straight out and aborted\n * the entire doctor run through `guard()`, blinding every other check on one bad\n * meta field. Now an unparseable policy is a warning on that one parameter and\n * the sweep continues, and the single parsed interval feeds both the overdue\n * decision and the message. A parameter with no policy, or one that has never\n * rotated, is not on a clock and is silently not overdue.\n */\nfunction overdueFindings(\n subjects: readonly Subject[],\n environment: string,\n now: Date,\n): DoctorFinding[] {\n const findings: DoctorFinding[] = [];\n for (const { resolution, meta } of subjects) {\n const { policy, lastRotated } = rotationOf(meta, environment);\n // Not on a clock: no interval declared, or never rotated. Not late.\n if (policy === undefined || lastRotated === null) {\n continue;\n }\n // Parse once, non-throwing. A policy penv cannot read used to throw here and\n // abort the whole run; now it is this parameter's own warning and nothing\n // else is lost.\n const interval = tryParseDuration(policy);\n if (interval === undefined) {\n findings.push({\n check: \"rotation-overdue\",\n severity: \"warning\",\n label: \"Rotation policy invalid\",\n subject: resolution.parameter,\n detail: `rotationPolicy \\`${policy}\\` is not a duration penv can parse (e.g. \\`90d\\`, \\`24h\\`)`,\n });\n continue;\n }\n const last = Date.parse(lastRotated);\n if (Number.isNaN(last)) {\n continue;\n }\n // The same boundary `isOverdue` keeps: exactly at the interval is not yet\n // overdue, strictly past it is. Reusing `interval` is what kills the second\n // parse the old `overdueBy` line made.\n const overdueBy = now.getTime() - last - interval;\n if (overdueBy <= 0) {\n continue;\n }\n findings.push({\n check: \"rotation-overdue\",\n severity: \"warning\",\n label: \"Rotation overdue\",\n subject: resolution.parameter,\n detail: `overdue by ~${humanizeMs(overdueBy)}, policy ${policy}`,\n remedy: `penv rotate ${refPathOf(resolution.ref)} --env ${environment}`,\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"rotation-overdue\",\n severity: \"pass\",\n label: \"Rotation freshness\",\n subject: `no parameter is past its rotation policy for ${environment}`,\n },\n ];\n}\n\n/**\n * The overdue clock's opposite: not a rotation that never ran, but one that\n * started and stalled. A `dual-valid` window is meant to open, let readers move\n * over, and close; a `rotatingSince` older than the threshold is a window that\n * opened and never did.\n *\n * Gated to `dual-valid` entirely — `isStuck` refuses every other mechanism, and\n * that refusal is the point. An `atomic-cutover` parameter overlaps only at the\n * infra layer and holds no penv-layer grace window, so a long-lived\n * `rotatingSince` on one is not stuck and must never be flagged; this check keeps\n * that promise by asking `isStuck` and never re-deriving the mechanism itself.\n */\nfunction stuckFindings(\n subjects: readonly Subject[],\n environment: string,\n now: Date,\n stuckThresholdMs: number,\n): DoctorFinding[] {\n const findings: DoctorFinding[] = [];\n for (const { resolution, meta } of subjects) {\n if (!isStuck(meta, environment, now, stuckThresholdMs)) {\n continue;\n }\n const { rotatingSince } = rotationOf(meta, environment);\n // isStuck was true, so the window is open with a parseable clock; the guard is\n // for the types, not a reachable path.\n if (rotatingSince === null) {\n continue;\n }\n const openFor = now.getTime() - Date.parse(rotatingSince);\n findings.push({\n check: \"rotation-stuck\",\n severity: \"warning\",\n label: \"Rotation stuck\",\n subject: resolution.parameter,\n detail: `dual-valid window open ~${humanizeMs(openFor)}, past the ${humanizeMs(stuckThresholdMs)} grace window`,\n remedy: `penv rotate ${refPathOf(resolution.ref)} --complete --env ${environment}`,\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"rotation-stuck\",\n severity: \"pass\",\n label: \"Rotation progress\",\n subject: `no dual-valid rotation has stayed open past its grace window for ${environment}`,\n },\n ];\n}\n\n/** One value file the drift check has read, kept with its raw stored string so a sealed local value can still be opened. */\ninterface DriftEntry {\n readonly file: ValueFile;\n readonly stored: string;\n}\n\n/**\n * The LOGICAL identity of a value file — namespace, name, and scope — with the\n * `.enc` marker deliberately dropped.\n *\n * `formatValueFile` encodes `encrypted`, so keying by it split an encrypted-local\n * value from its plaintext-source twin: the same logical parameter at the same\n * scope read as two one-sided addresses, a perpetual false drift the byte compare\n * never got to run. Encryption is a property of the local envelope, not of the\n * address, so it must not be part of the key two stores are matched on. Mirrors\n * the mock provider's `valueKey`, minus exactly that `encrypted` field.\n */\nfunction driftKey(file: ValueFile): string {\n return [file.namespace.join(\"/\"), file.name, scopeKey(file.scope)].join(\" \");\n}\n\nfunction scopeKey(scope: Scope): string {\n switch (scope.kind) {\n case \"unscoped\":\n return \"unscoped\";\n case \"environment\":\n return `environment:${scope.environment}`;\n case \"local\":\n return \"local\";\n case \"environment-local\":\n return `environment-local:${scope.environment}`;\n default:\n return assertNever(scope, \"scope\");\n }\n}\n\n/**\n * The value files that have a source-of-truth twin to drift against: the pushable\n * set for this environment — the unscoped default and this environment's own\n * scope, and nothing else.\n *\n * The old check compared the ENTIRE local tree (`project.provider.list()` is\n * every environment's files) against one env's source, so `doctor --env\n * production` flooded \"Only in the local tree\" for every development/staging\n * value. Both `.local` scopes are personal and never reach a backend; every other\n * environment's scoped file is that environment's business, not this one's. The\n * same filter is applied to both sides.\n */\nfunction relevantToEnvironment(file: ValueFile, environment: string): boolean {\n const scope = file.scope;\n if (scope.kind === \"unscoped\") return true;\n if (scope.kind === \"environment\") return scope.environment === environment;\n // Both `.local` scopes, and every other environment's scope: not pushed here.\n return false;\n}\n\n/**\n * Reads a provider's value files relevant to this environment into a logical\n * address → entry map, the raw stored strings kept unopened.\n *\n * Values are read in `list` order and mapped afterwards, so a same-address\n * collision (a plaintext and a sealed file at one scope) resolves the same way on\n * every machine rather than by Promise race. An address that `list` names but\n * `read` returns absent — a concurrent prune — is dropped, nothing to compare.\n */\nasync function readRelevant(\n provider: Provider,\n environment: string,\n): Promise<Map<string, DriftEntry>> {\n const files = (await provider.list()).filter((file) => relevantToEnvironment(file, environment));\n const stored = await Promise.all(files.map((file) => provider.read(file)));\n const entries = new Map<string, DriftEntry>();\n for (const [index, file] of files.entries()) {\n const value = stored[index];\n if (value !== undefined) {\n entries.set(driftKey(file), { file, stored: value });\n }\n }\n return entries;\n}\n\n/**\n * The one drift a value-withholding destination can never report. `projection-value-drift` is permanently\n * `unknown` because a write-only destination cannot be read back; a provider is\n * the system of record precisely because it can, so here penv actually looks —\n * comparing PLAINTEXT, value by value.\n *\n * Custody model: the source of truth holds verbatim plaintext (the way `pull` and\n * `rotate` move it there), while the local tree may hold the value sealed. So a\n * sealed local value is opened before the compare — an encrypted-local vs\n * plaintext-source pair carrying the same secret is IN SYNC, not drift. A sealed\n * value that cannot be opened (the key is gone) is `unknown` for that parameter,\n * never a false disagreement: penv could not read one side, so it cannot say the\n * two agree or differ.\n *\n * When the environment keeps its values in the local tree there is no second\n * system of record, so this is a plain `pass` — \"not applicable\", never\n * `unknown`: penv could look and there was one copy by design. An unreachable\n * source *is* `unknown`, mirroring `projectionFindings`' try/catch tiering: a differing\n * value and an unreachable store are opposite verdicts with opposite remedies.\n */\nasync function providerDriftFindings(\n project: Project,\n environment: string,\n override: Provider | undefined,\n): Promise<DoctorFinding[]> {\n const providerConfig = environmentEntry(project.config, environment);\n if (providerConfig === undefined || providerConfig.provider === LOCAL_TREE_TYPE) {\n return [\n {\n check: \"provider-value-drift\",\n severity: \"pass\",\n label: \"Provider values\",\n subject: `${environment} keeps its values in the local .penv tree, so there is no other source of truth to compare against`,\n },\n ];\n }\n\n const source = override ?? (await sourceProviderFor(project, environment));\n // A value-withholding destination has nothing to compare value by value; its\n // tiers — exact names, unknown values, indirect hand-edits — are\n // `projectionFindings`' and are reported there.\n if (!holdsRecords(source)) {\n return [];\n }\n\n let local: Map<string, DriftEntry>;\n let remote: Map<string, DriftEntry>;\n try {\n local = await readRelevant(project.provider, environment);\n remote = await readRelevant(source, environment);\n } catch (error) {\n return [\n {\n check: \"provider-value-drift\",\n severity: \"unknown\",\n label: \"Provider values\",\n subject: `could not reach the ${providerConfig.provider} provider for ${environment}`,\n detail: errorDetail(error),\n },\n ];\n }\n\n const keys = keySourceFor(project, environment);\n const findings: DoctorFinding[] = [];\n // Sorted so the report is identical on every machine, the same rule `refsFrom` keeps.\n const addresses = [...new Set([...local.keys(), ...remote.keys()])].sort();\n for (const address of addresses) {\n const here = local.get(address);\n const there = remote.get(address);\n if (here !== undefined && there !== undefined) {\n // Open the local value if it is sealed; the source is verbatim plaintext.\n // `openValue` returns a plaintext file unchanged, so this is unconditional.\n const opened = openValue(here.file, here.stored, keys);\n if (opened.kind !== \"plaintext\") {\n // A sealed value penv cannot open: the key is gone. Not drift — penv\n // could not read this side, so it cannot claim the two stores agree or\n // differ. The opposite of a false failure.\n findings.push({\n check: \"provider-value-drift\",\n severity: \"unknown\",\n label: \"Provider value unreadable\",\n subject: formatValueFile(here.file),\n detail: `the local value is sealed and did not open, so it cannot be compared against the ${providerConfig.provider} source of truth`,\n });\n continue;\n }\n // A plaintext comparison. Drift in the system of record is serious: the\n // tree and the backend claim different truths for one address, and\n // something deploys the wrong one.\n if (opened.value !== there.stored) {\n findings.push({\n check: \"provider-value-drift\",\n severity: \"failure\",\n label: \"Provider value drift\",\n subject: formatValueFile(here.file),\n detail: `the local tree and the ${providerConfig.provider} source of truth hold different values`,\n });\n }\n continue;\n }\n const present = here ?? there;\n // `present` is defined: the address is in the union, so at least one side has it.\n if (present === undefined) {\n continue;\n }\n findings.push({\n check: \"provider-value-drift\",\n severity: \"warning\",\n label: here !== undefined ? \"Only in the local tree\" : \"Only in the source\",\n subject: formatValueFile(present.file),\n detail:\n here !== undefined\n ? `present locally, absent from the ${providerConfig.provider} source of truth`\n : `present in the ${providerConfig.provider} source of truth, absent from the local tree`,\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"provider-value-drift\",\n severity: \"pass\",\n label: \"Provider values\",\n subject: `every value matches the ${providerConfig.provider} source of truth for ${environment}`,\n },\n ];\n}\n\nconst GLYPHS: Readonly<Record<DoctorSeverity, string>> = {\n pass: CHECK,\n warning: WARN,\n failure: CROSS,\n unknown: UNKNOWN,\n};\n\n/** The one-line verdict under the table: every severity counted, colored to match its glyph. */\nfunction summarize(report: DoctorReport): string {\n const counts = { pass: 0, warning: 0, failure: 0, unknown: 0 };\n for (const finding of report.findings) {\n counts[finding.severity] += 1;\n }\n const parts = [out.green(`${counts.pass} passed`)];\n if (counts.warning > 0) {\n parts.push(out.yellow(`${counts.warning} ${counts.warning === 1 ? \"warning\" : \"warnings\"}`));\n }\n if (counts.failure > 0) {\n parts.push(out.red(`${counts.failure} ${counts.failure === 1 ? \"failure\" : \"failures\"}`));\n }\n if (counts.unknown > 0) {\n parts.push(out.dim(`${counts.unknown} could not be checked`));\n }\n const verdict = report.ok ? out.green(CHECK) : out.red(CROSS);\n return `${verdict} ${report.findings.length} checks: ${parts.join(out.dim(\" · \"))}`;\n}\n\nexport function renderDoctor(report: DoctorReport): string[] {\n const rows: Row[] = report.findings.map((finding) => ({\n glyph: GLYPHS[finding.severity],\n label: finding.label,\n ...(finding.subject === undefined ? {} : { subject: finding.subject }),\n ...(finding.detail === undefined ? {} : { detail: finding.detail }),\n }));\n\n const lines = [heading(\"penv doctor\", `environment ${report.environment}`), \"\"];\n lines.push(...formatRows(rows));\n // Below the table rather than beside it: these are lines to paste, and a line\n // to paste has to survive being selected without a report's columns coming\n // with it. Deduped, because two parameters can share a remedy.\n const remedies = [\n ...new Set(\n report.findings\n .filter((finding) => finding.severity !== \"pass\")\n .map((finding) => finding.remedy)\n .filter((remedy): remedy is string => remedy !== undefined),\n ),\n ];\n if (remedies.length > 0) {\n lines.push(\"\");\n for (const remedy of remedies) {\n lines.push(tip(remedy));\n }\n }\n lines.push(\"\", summarize(report));\n return lines;\n}\n\nexport const doctorCommand = defineCommand({\n meta: {\n name: \"doctor\",\n description: \"Report missing, weak, unused, fallback, plaintext-secret, and drift issues\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to report on\" },\n },\n run({ args }) {\n return guard(async () => {\n const report = await runDoctor({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n envFlags: shorthandCandidates(args, [\"env\"]),\n });\n write(renderDoctor(report));\n if (!report.ok) {\n process.exitCode = 1;\n }\n });\n },\n});\n","/**\n * `penv push` — ship an environment's values to a provider.\n *\n * The destination is the environment's declared entry, always. A push that could\n * go somewhere the config never declared would be a seam penv cannot see, and an\n * entry is addressed in its provider's own words, so there is no generic place to\n * point one at. What crosses depends on what the destination declares it holds:\n *\n * - **Records** (Vault, SSM, Kubernetes): the local tree is mirrored verbatim —\n * unscoped and target-environment value files byte-for-byte (a sealed value\n * stays sealed; the key never has to be present), plus each parameter's meta.\n * Both `.local` scopes never cross: a personal override is not something a\n * shared store has any business holding.\n * - **A projection** (GitHub Actions Secrets): `penv generate` pointed at CI.\n * The tree is resolved exactly as a deploy would read it — `.local` skipped —\n * every generated name is judged against the destination's own grammar\n * *before* the first PUT, and the resolved values cross in plaintext for the\n * destination to re-seal (sealed values only behind `--allow-decrypt`).\n *\n * A destination-side target that does not exist yet — a GitHub deployment\n * environment — is created only on an explicit yes: the CLI prompts, `--yes`\n * pre-approves for CI, and a refusal names the exact remedy. Creation is an\n * answer, never a guess.\n */\n\nimport type {\n AnyProvider,\n Meta,\n MetaBlock,\n ParameterRef,\n PenvConfig,\n ProjectionProvider,\n Provider,\n SecretScope,\n ValueFile,\n} from \"@penvhq/core\";\nimport {\n checkNameCollisions,\n environmentEntry,\n holdsProjection,\n PenvError,\n recordPath,\n requireValue,\n variableName,\n} from \"@penvhq/core\";\nimport type { FilesystemProvider } from \"@penvhq/provider-filesystem\";\nimport { defineCommand } from \"citty\";\nimport { shorthandCandidates } from \"../env-flags.js\";\nimport { lineReader } from \"../input.js\";\nimport type { Project, SyncResolution } from \"../project.js\";\nimport {\n keySourceFor,\n localTree,\n openProject,\n refsFrom,\n resolveAllSync,\n targetEnvironment,\n} from \"../project.js\";\nimport { createSourceProvider, LOCAL_TREE_TYPE } from \"../registry.js\";\nimport { CHECK, formatRows, guard, WARN, write } from \"../ui.js\";\n\n/** The per-environment meta field recording penv's last push, compared against the destination's `updatedAt`. */\nexport const LAST_PUSHED_KEY = \"lastPushedAt\";\n\nexport interface PushOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n /** Permits sealed values to be decrypted locally and pushed as plaintext for the destination to re-seal. */\n readonly allowDecrypt?: boolean;\n /** Pre-approves creating a missing destination-side target (`--yes`). */\n readonly yes?: boolean;\n /** Injected in tests: the destination provider. Defaults to the one the environment's entry declares. */\n readonly provider?: AnyProvider;\n /** Injected in tests: answers the create-target question. Defaults to a terminal prompt. */\n readonly confirm?: (question: string) => Promise<boolean>;\n /** Injected in tests: the wall-clock reading recorded in meta. Defaults to now. */\n readonly now?: string;\n}\n\nexport interface PushResult {\n readonly environment: string;\n /** The destination provider's type — its package name. */\n readonly destination: string;\n /** What the destination holds, which decided what crossed. */\n readonly mode: \"records\" | \"projection\";\n /** Values sent — resolved secrets for a projection, value files for records. */\n readonly pushed: number;\n /** Meta records mirrored. Records mode only. */\n readonly meta: number;\n readonly repositorySecrets: number;\n readonly environmentSecrets: number;\n /** How many were sealed and crossed as plaintext for the destination to re-seal. */\n readonly decrypted: number;\n /** True when the destination-side target was created by this push, on approval. */\n readonly createdTarget: boolean;\n}\n\n/** One value ready to send, with the destination scope it lands in. */\ninterface Outbound {\n readonly ref: ParameterRef;\n readonly variable: string;\n readonly value: string;\n readonly scope: SecretScope;\n readonly encrypted: boolean;\n}\n\n/**\n * The destination provider: the environment's declared entry, and nothing else.\n * An environment whose provider is the local tree itself has nowhere to push, and\n * says so.\n */\nasync function destinationFor(\n project: Project,\n environment: string,\n options: PushOptions,\n): Promise<AnyProvider> {\n const declared = environmentEntry(project.config, environment);\n if (declared === undefined || declared.provider === LOCAL_TREE_TYPE) {\n throw new PenvError(\n \"NO_DESTINATION\",\n `Environment ${environment}'s provider is the local records tree itself, so penv has nowhere to push`,\n `Declare the backend that holds it in penv.config.ts — e.g. \\`${environment}: { provider: \"@penvhq/provider-github\", repository: \"owner/repo\" }\\` — ` +\n \"and run this again. A push only ever goes where the config says this environment lives.\",\n );\n }\n if (options.provider !== undefined) {\n return options.provider;\n }\n return createSourceProvider(declared.provider, {\n root: project.root,\n config: project.config,\n providerConfig: declared,\n environment,\n });\n}\n\n/**\n * Every value to send, resolved up front so the encrypted/allow-decrypt refusal\n * also happens before anything is pushed. A `.local` scope is already gone (the\n * push resolution dropped it), so a winner is only ever environment-scoped or the\n * unscoped default — the destination scope is that binary.\n */\nfunction plan(\n resolutions: readonly SyncResolution[],\n config: PenvConfig,\n environment: string,\n allowDecrypt: boolean,\n): Outbound[] {\n const outbound: Outbound[] = [];\n for (const resolution of resolutions) {\n const winner = resolution.winner;\n if (winner === undefined) {\n continue;\n }\n let encrypted = false;\n if (winner.file.encrypted) {\n if (!allowDecrypt) {\n throw new PenvError(\n \"ENCRYPTED_VALUE_REFUSED\",\n `Parameter ${resolution.parameter} for environment ${environment} resolves to the encrypted value file ${recordPath(winner.location)}, and a push sends plaintext for the destination to re-seal`,\n \"Re-run with `--allow-decrypt` to decrypt it locally and push it, or push an environment \" +\n \"whose values are plaintext. penv's encryption stops at the projection; the destination \" +\n \"seals it under its own key.\",\n );\n }\n // Throws naming the reason if a sealed winner cannot be opened — never\n // silently dropping the secret CI needs.\n requireValue(resolution, environment);\n encrypted = true;\n }\n if (resolution.value === undefined) {\n continue;\n }\n const scope: SecretScope =\n winner.file.scope.kind === \"unscoped\"\n ? { kind: \"repository\" }\n : { kind: \"environment\", environment };\n outbound.push({\n ref: resolution.ref,\n variable: variableName(resolution.ref, config),\n value: resolution.value,\n scope,\n encrypted,\n });\n }\n return outbound;\n}\n\n/** Records what penv did, per environment, in the committed meta — never a value read back. */\nfunction withLastPushed(meta: Meta | undefined, environment: string, iso: string): Meta {\n const base: Meta = meta ?? {};\n const environments: Record<string, MetaBlock> = { ...(base.environments ?? {}) };\n environments[environment] = { ...(environments[environment] ?? {}), [LAST_PUSHED_KEY]: iso };\n return { ...base, environments };\n}\n\nfunction recordPush(\n tree: FilesystemProvider,\n ref: ParameterRef,\n environment: string,\n iso: string,\n): void {\n const meta = withLastPushed(tree.readMetaSync(ref), environment, iso);\n tree.writeMetaSync(ref, meta);\n}\n\n/** The default create-target prompt: a terminal question, and a refusal anywhere a terminal is not. */\nasync function terminalConfirm(question: string): Promise<boolean> {\n if (process.stdin.isTTY !== true) {\n return false;\n }\n const reader = lineReader();\n try {\n const answer = await reader.ask(`${question} [y/N] `);\n return answer !== undefined && /^y(es)?$/i.test(answer.trim());\n } finally {\n reader.close();\n }\n}\n\n/**\n * Makes sure the destination-side target for this environment exists before the\n * first PUT, creating it only on an explicit yes. A destination with no notion\n * of a target (no `targetExists`) passes through untouched.\n */\nasync function ensureTargetApproved(\n provider: ProjectionProvider,\n environment: string,\n options: PushOptions,\n): Promise<boolean> {\n if (provider.targetExists === undefined) {\n return false;\n }\n if (await provider.targetExists(environment)) {\n return false;\n }\n if (provider.ensureTarget === undefined) {\n throw new PenvError(\n \"MISSING_TARGET\",\n `The destination has no environment \\`${environment}\\` to receive this push, and this provider cannot create one`,\n `Create the environment on the destination side, then run \\`penv push --env ${environment}\\` again.`,\n );\n }\n const approved =\n options.yes === true ||\n (await (options.confirm ?? terminalConfirm)(\n `The destination has no environment \\`${environment}\\`. Create it?`,\n ));\n if (!approved) {\n throw new PenvError(\n \"MISSING_TARGET\",\n `The destination has no environment \\`${environment}\\` to receive this push`,\n `Re-run with \\`--yes\\` to create it, answer \\`y\\` at the prompt, or create it on the destination side yourself.`,\n );\n }\n await provider.ensureTarget(environment);\n return true;\n}\n\n/** The projection push: resolve as CI would read, judge every name, then all or nothing. */\nasync function pushProjection(\n project: Project,\n provider: ProjectionProvider,\n environment: string,\n options: PushOptions,\n): Promise<PushResult> {\n const tree = localTree(project);\n const keys = keySourceFor(project, environment);\n // The push resolution: both `.local` scopes dropped. CI receives what CI would read.\n const resolutions = resolveAllSync(tree, environment, keys, true);\n const refs = refsFrom(resolutions.map((resolution) => resolution.ref));\n\n // Every name judged before a single PUT. Exact-string collisions are core's;\n // the destination's reserved prefixes, charset, and case-insensitivity are the\n // provider's own `checkNames`. Both refuse the whole push, never half of it.\n const collision = checkNameCollisions(refs, project.config)[0];\n if (collision !== undefined) {\n throw collision;\n }\n const nameError = provider.checkNames?.(refs, project.config)[0];\n if (nameError !== undefined) {\n throw nameError;\n }\n\n const outbound = plan(resolutions, project.config, environment, options.allowDecrypt === true);\n\n // Reachable and writable, or penv stops here having placed nothing.\n await provider.verify();\n\n // The target exists — or was just created on an explicit yes — before any PUT.\n const createdTarget =\n outbound.some((item) => item.scope.kind === \"environment\") &&\n (await ensureTargetApproved(provider, environment, options));\n\n let repositorySecrets = 0;\n let environmentSecrets = 0;\n for (const item of outbound) {\n await provider.push(item.variable, item.value, item.scope);\n if (item.scope.kind === \"repository\") {\n repositorySecrets += 1;\n } else {\n environmentSecrets += 1;\n }\n // Stamped AFTER the push, per item — not once before the loop. The destination\n // stamps each secret's `updated_at` when its own PUT lands, and one process\n // runs per parameter, so a single pre-loop time would sit seconds behind the\n // destination's and make `doctor`'s hand-edit check fire on a clean push.\n recordPush(tree, item.ref, environment, options.now ?? new Date().toISOString());\n }\n\n return {\n environment,\n destination: provider.type,\n mode: \"projection\",\n pushed: outbound.length,\n meta: 0,\n repositorySecrets,\n environmentSecrets,\n decrypted: outbound.filter((item) => item.encrypted).length,\n createdTarget,\n };\n}\n\n/** Whether a value file crosses on a records push: the unscoped default and the target environment's scope. */\nfunction crossesToRecords(file: ValueFile, environment: string): boolean {\n const scope = file.scope;\n if (scope.kind === \"unscoped\") {\n return true;\n }\n return scope.kind === \"environment\" && scope.environment === environment;\n}\n\n/**\n * The records push: mirror the tree verbatim. A value is an opaque envelope the\n * destination holds and hands back unchanged — sealed stays sealed, so the key\n * that opens it never has to be present to push it. Both `.local` scopes stay\n * home, and other environments' scoped values stay out of this environment's\n * store — the destination ends up holding exactly what a pull for this\n * environment would bring back.\n */\nasync function pushRecords(\n project: Project,\n provider: Provider,\n environment: string,\n): Promise<PushResult> {\n const tree = localTree(project);\n const files = tree.listSync().filter((file) => crossesToRecords(file, environment));\n\n let pushed = 0;\n for (const file of files) {\n const value = tree.readSync(file);\n if (value === undefined) {\n continue;\n }\n await provider.write(file, value);\n pushed += 1;\n }\n\n const refs = refsFrom(files);\n let meta = 0;\n for (const ref of refs) {\n const block = tree.readMetaSync(ref);\n if (block === undefined) {\n continue;\n }\n await provider.writeMeta(ref, block);\n meta += 1;\n }\n\n return {\n environment,\n destination: provider.type,\n mode: \"records\",\n pushed,\n meta,\n repositorySecrets: 0,\n environmentSecrets: 0,\n decrypted: 0,\n createdTarget: false,\n };\n}\n\nexport async function runPush(options: PushOptions): Promise<PushResult> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n const provider = await destinationFor(project, environment, options);\n\n if (holdsProjection(provider)) {\n return pushProjection(project, provider, environment, options);\n }\n return pushRecords(project, provider, environment);\n}\n\nexport function renderPush(result: PushResult): string[] {\n if (result.pushed === 0 && result.meta === 0) {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Nothing to push\",\n subject: `no values resolve for environment ${result.environment}`,\n },\n ]);\n }\n\n const target = `${result.destination} for environment ${result.environment}`;\n\n if (result.mode === \"records\") {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Pushed\",\n subject: `${result.pushed} value ${result.pushed === 1 ? \"file\" : \"files\"}, ${result.meta} meta`,\n detail: `mirrored verbatim to ${target}`,\n },\n {\n glyph: CHECK,\n label: \"Sealed values\",\n subject: \"crossed byte-for-byte, still sealed\",\n detail: \"the destination holds envelopes; no key was needed to push them\",\n },\n ]);\n }\n\n const rows = [\n {\n glyph: CHECK,\n label: \"Pushed\",\n subject: `${result.pushed} ${result.pushed === 1 ? \"secret\" : \"secrets\"}`,\n detail: `to ${target}`,\n },\n {\n glyph: CHECK,\n label: \"Scopes\",\n subject: `${result.environmentSecrets} environment, ${result.repositorySecrets} repository`,\n detail:\n \"environment secrets override repository secrets, as penv's env scope overrides the default\",\n },\n ];\n if (result.createdTarget) {\n rows.push({\n glyph: CHECK,\n label: \"Created\",\n subject: `the destination environment ${result.environment}`,\n detail: \"it did not exist yet; created on your approval\",\n });\n }\n if (result.decrypted > 0) {\n rows.push({\n glyph: WARN,\n label: \"Decrypted\",\n subject: `${result.decrypted} ${result.decrypted === 1 ? \"secret\" : \"secrets\"}`,\n detail: \"sent as plaintext for the destination to re-seal under its own key\",\n });\n }\n return formatRows(rows);\n}\n\n/**\n * The flags that used to redirect a push, and the one case that must not fall\n * through. citty rejects no unknown flag, and a flag carrying a value is not a\n * shorthand candidate either — so `--destination @penvhq/provider-github` would be\n * dropped in silence and the secrets would land at the declared entry instead.\n */\nconst REDIRECT_FLAGS = [\"destination\", \"dest\", \"d\", \"location\", \"l\"] as const;\n\nexport function assertNoRedirect(args: Readonly<Record<string, unknown>>): void {\n const given = REDIRECT_FLAGS.filter((flag) => args[flag] !== undefined);\n const named = given[0];\n if (named === undefined) {\n return;\n }\n throw new PenvError(\n \"REMOVED_FLAG\",\n `\\`--${named}\\` is not a flag \\`penv push\\` takes`,\n \"A push only ever goes where the config says this environment lives. Declare the \" +\n \"destination in `environments.<env>` — the provider package, addressed in that provider's \" +\n \"own words — and push with `--env <name>`.\",\n );\n}\n\nexport const pushCommand = defineCommand({\n meta: {\n name: \"push\",\n description: \"Push an environment's values to its provider\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to push\" },\n \"allow-decrypt\": {\n type: \"boolean\",\n description:\n \"Decrypt sealed values locally and push them as plaintext for the destination to re-seal\",\n },\n yes: {\n type: \"boolean\",\n alias: \"y\",\n description: \"Create a missing destination-side environment without prompting\",\n },\n },\n run({ args }) {\n return guard(async () => {\n assertNoRedirect(args);\n const result = await runPush({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args[\"allow-decrypt\"] === undefined ? {} : { allowDecrypt: args[\"allow-decrypt\"] }),\n ...(args.yes === undefined ? {} : { yes: args.yes }),\n envFlags: shorthandCandidates(args, [\"env\", \"allow-decrypt\", \"allowDecrypt\", \"yes\", \"y\"]),\n });\n write(renderPush(result));\n });\n },\n});\n","/**\n * Reading answers from a terminal — or from a pipe, where the answers can arrive\n * before the questions.\n *\n * `readline.question` attaches its listener only when asked, so a line piped in\n * ahead of the first prompt — `printf 'value\\n' | penv fill` — was emitted to\n * nobody and lost, and the EOF behind it closed the interface out from under the\n * question that came next (`ERR_USE_AFTER_CLOSE`, or a promise that never\n * settled). This reader listens from the moment it is created: early lines are\n * buffered in arrival order, and once input ends every outstanding and future\n * question resolves to `undefined` — the caller's \"no answer\", which `fill`\n * already treats as a skip. Against a real terminal it is `readline`'s own\n * prompt-and-edit behavior, unchanged.\n */\n\nimport { createInterface } from \"node:readline\";\n\nexport interface LineReader {\n /**\n * The next line of input, or `undefined` when input has ended. The question is\n * written only when the reader must wait for it to be answered — an answer\n * that already arrived belongs to a reader who is not looking at a prompt.\n */\n ask(question: string): Promise<string | undefined>;\n close(): void;\n}\n\nexport function lineReader(\n input: NodeJS.ReadableStream = process.stdin,\n output: NodeJS.WritableStream = process.stdout,\n): LineReader {\n const rl = createInterface({ input, output });\n const buffered: string[] = [];\n const waiting: Array<(line: string | undefined) => void> = [];\n let closed = false;\n\n rl.on(\"line\", (line) => {\n const next = waiting.shift();\n if (next === undefined) {\n buffered.push(line);\n } else {\n next(line);\n }\n });\n rl.on(\"close\", () => {\n closed = true;\n for (const next of waiting.splice(0)) {\n next(undefined);\n }\n });\n\n return {\n ask(question: string): Promise<string | undefined> {\n const early = buffered.shift();\n if (early !== undefined) {\n return Promise.resolve(early);\n }\n if (closed) {\n return Promise.resolve(undefined);\n }\n rl.setPrompt(question);\n rl.prompt();\n return new Promise((resolve) => {\n waiting.push(resolve);\n });\n },\n close(): void {\n rl.close();\n },\n };\n}\n","/**\n * `penv encrypt <key>` and `penv decrypt <key>` — change whether one value file\n * is sealed, without changing what it says.\n *\n * These act on one parameter at one scope, because a scope is the address the\n * provider actually has: `db-password.production` and `db-password` are two\n * files, and a command that \"encrypted the parameter\" would have to guess which.\n *\n * They exist for two moments the policy cannot handle by itself. The first is\n * adoption: `secret: true` added to a parameter that already has values leaves\n * every existing file plaintext, and `penv set` only seals what it writes. The\n * second is re-sealing after a move — a ciphertext is bound to the address it\n * lives at, so a value file that is renamed or re-scoped must be sealed again for\n * its new address.\n *\n * Neither invents a key. `penv encrypt` with no key refuses, because a key penv\n * chose is a key nobody can reproduce — the same reason `penv set` is the only\n * thing that writes a value, and never a value it made up.\n */\n\nimport type { ValueFile } from \"@penvhq/core\";\nimport {\n formatValueFile,\n isSecret,\n openValue,\n PenvError,\n parameterId,\n recordPath,\n sealValue,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { Project } from \"../project.js\";\nimport { keySourceFor, openProject, refFromKey, targetEnvironment } from \"../project.js\";\nimport { CHECK, formatRows, guard, write } from \"../ui.js\";\nimport type { ScopeOptions } from \"./set.js\";\nimport { targetScope } from \"./set.js\";\n\nexport interface ResealOptions extends ScopeOptions {\n readonly cwd: string;\n readonly key: string;\n}\n\nexport interface ResealResult {\n readonly parameter: string;\n /** The file that now holds the value. */\n readonly location: string;\n /** The file that no longer exists, because its twin replaced it. */\n readonly removed: string;\n}\n\n/** The two files one value can live in at a scope. Exactly one of them exists. */\nfunction twins(project: Project, key: string, options: ScopeOptions): [ValueFile, ValueFile] {\n const ref = refFromKey(key, project.config);\n const scope = targetScope(project, options, key);\n return [\n { namespace: ref.namespace, name: ref.name, scope, encrypted: false },\n { namespace: ref.namespace, name: ref.name, scope, encrypted: true },\n ];\n}\n\n/**\n * The environment this scope's policy and key are read from.\n *\n * Unlike `set`, this refuses rather than falling back to the base block: both\n * commands here need a *key*, and a key is declared per environment. A scope that\n * names none has no key penv can choose, and choosing the ambient environment's\n * would seal a file every other environment reads under a key only one of them\n * has.\n */\nfunction environmentFor(project: Project, options: ScopeOptions, verb: string): string {\n if (options.environment === undefined) {\n throw new PenvError(\n \"SECRET_SCOPE_AMBIGUOUS\",\n `\\`penv ${verb}\\` names no environment, and keys are declared per environment`,\n \"Pass `--env <environment>`. penv cannot tell which environment's key applies to a file \" +\n \"that names none, and will not pick one for you.\",\n );\n }\n return targetEnvironment(project, options.environment);\n}\n\nasync function readOne(project: Project, file: ValueFile): Promise<string | undefined> {\n return project.provider.read(file);\n}\n\nexport async function runEncrypt(options: ResealOptions): Promise<ResealResult> {\n const project = openProject(options.cwd);\n const environment = environmentFor(project, options, \"encrypt\");\n const [plain, sealed] = twins(project, options.key, options);\n const parameter = parameterId(plain);\n\n const value = await readOne(project, plain);\n if (value === undefined) {\n const already = await readOne(project, sealed);\n throw new PenvError(\n \"PARAMETER_ABSENT\",\n already === undefined\n ? `Parameter ${parameter} has no value file at ${recordPath(formatValueFile(plain))}`\n : `Parameter ${parameter} is already encrypted at ${recordPath(formatValueFile(sealed))}`,\n already === undefined\n ? `Write it first with \\`penv set ${options.key} --env ${environment}\\`, which seals it ` +\n \"automatically when the parameter's meta declares it a secret.\"\n : \"Nothing to do.\",\n );\n }\n\n const text = sealValue(sealed, value, keySourceFor(project, environment), parameter, environment);\n\n // Written before the plaintext is removed. The reverse order has a window in\n // which the value exists nowhere, and the value is the thing being protected.\n await project.provider.write(sealed, text);\n await project.provider.remove(plain);\n\n return {\n parameter,\n location: formatValueFile(sealed),\n removed: formatValueFile(plain),\n };\n}\n\nexport async function runDecrypt(options: ResealOptions): Promise<ResealResult> {\n const project = openProject(options.cwd);\n const environment = environmentFor(project, options, \"decrypt\");\n const [plain, sealed] = twins(project, options.key, options);\n const parameter = parameterId(plain);\n\n // penv does not ship a command whose purpose is to fail its own check. A\n // secret written in plaintext is a `doctor` failure by policy (invariant 14),\n // and decrypting one on request would manufacture exactly that.\n if (isSecret(await project.provider.readMeta(plain), environment)) {\n throw new PenvError(\n \"SECRET_DECRYPT_REFUSED\",\n `Parameter ${parameter} is declared a secret for environment ${environment}, so penv will not write it in plaintext`,\n \"A secret with a plaintext value file is a `penv doctor` failure. Drop `secret` from the \" +\n \"parameter's meta if it is not one, or run `penv generate --allow-decrypt` if you need \" +\n \"the plaintext value in a `.env` artifact.\",\n );\n }\n\n const stored = await readOne(project, sealed);\n if (stored === undefined) {\n throw new PenvError(\n \"PARAMETER_ABSENT\",\n `Parameter ${parameter} has no encrypted value file at ${recordPath(formatValueFile(sealed))}`,\n `Nothing to decrypt. \\`penv get ${options.key} --env ${environment} --explain\\` shows every file penv looked at.`,\n );\n }\n\n const opened = openValue(sealed, stored, keySourceFor(project, environment));\n if (opened.kind === \"failed\") {\n throw new UndecryptableAt(\n parameter,\n environment,\n formatValueFile(sealed),\n opened.failure.detail,\n );\n }\n\n await project.provider.write(plain, opened.value);\n await project.provider.remove(sealed);\n\n return {\n parameter,\n location: formatValueFile(plain),\n removed: formatValueFile(sealed),\n };\n}\n\n/** The one thing `decrypt` can fail at that `requireValue` does not cover: a named file. */\nclass UndecryptableAt extends PenvError {\n constructor(parameter: string, environment: string, location: string, detail: string) {\n super(\n \"VALUE_UNDECRYPTABLE\",\n `Parameter ${parameter} for environment ${environment} is sealed at ${recordPath(location)}, and penv could not open it: ${detail}`,\n \"Make the key available and run the command again. penv will not replace a value it \" +\n \"cannot read.\",\n );\n }\n}\n\nexport function renderReseal(result: ResealResult, verb: \"Encrypted\" | \"Decrypted\"): string[] {\n return formatRows([\n {\n glyph: CHECK,\n label: verb,\n subject: recordPath(result.location),\n detail: `${recordPath(result.removed)} removed`,\n },\n ]);\n}\n\nconst SCOPE_ARGS = {\n key: { type: \"positional\", required: true, description: \"The parameter, e.g. redis/password\" },\n env: { type: \"string\", description: \"The environment whose value file to act on\" },\n local: {\n type: \"boolean\",\n description: \"Act on the personal override rather than the shared file\",\n },\n} as const;\n\nfunction scopeOptions(args: {\n env?: string | undefined;\n local?: boolean | undefined;\n}): ScopeOptions {\n return {\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.local === undefined ? {} : { local: args.local }),\n };\n}\n\nexport const encryptCommand = defineCommand({\n meta: { name: \"encrypt\", description: \"Encrypt one parameter's value file at one scope\" },\n args: SCOPE_ARGS,\n run({ args }) {\n return guard(async () => {\n const result = await runEncrypt({ cwd: process.cwd(), key: args.key, ...scopeOptions(args) });\n write(renderReseal(result, \"Encrypted\"));\n });\n },\n});\n\nexport const decryptCommand = defineCommand({\n meta: { name: \"decrypt\", description: \"Decrypt one parameter's value file at one scope\" },\n args: SCOPE_ARGS,\n run({ args }) {\n return guard(async () => {\n const result = await runDecrypt({ cwd: process.cwd(), key: args.key, ...scopeOptions(args) });\n write(renderReseal(result, \"Decrypted\"));\n });\n },\n});\n","/**\n * `penv set <key> [value]` — write one value file.\n *\n * The scope is chosen, never inferred: `--env <name>` writes `<name>.<env>`,\n * `--local` writes the personal override — for one environment when combined\n * with `--env`, for every environment on its own — and the default is the\n * unscoped one every environment falls back to. Writing to `--env production`\n * when you meant the default is a different file, so penv never picks for you.\n */\n\nimport type { ParameterRef, Provider, Scope, ValueFile } from \"@penvhq/core\";\nimport {\n environmentNames,\n formatValueFile,\n isSecret,\n PenvError,\n parameterId,\n recordPath,\n sealValue,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { Project } from \"../project.js\";\nimport {\n assertWritableKey,\n keySourceFor,\n openProject,\n refFromKey,\n targetEnvironment,\n} from \"../project.js\";\nimport { CHECK, formatRows, guard, write } from \"../ui.js\";\n\nexport interface ScopeOptions {\n /** The environment scope. Combined with `local`, the environment-scoped override. */\n readonly environment?: string;\n readonly local?: boolean;\n}\n\nexport interface SetOptions extends ScopeOptions {\n readonly cwd: string;\n readonly key: string;\n readonly value: string;\n}\n\nexport interface SetResult {\n readonly parameter: string;\n /** The value file written, relative to the records tree. */\n readonly location: string;\n /** Whether meta's policy sealed it. Reported, so the marker is never a surprise. */\n readonly encrypted: boolean;\n}\n\n/**\n * The scope the flags name — one flag combination per cascade level, all four.\n *\n * `--local --env <e>` is the environment-scoped personal override, mirroring\n * `.env.<e>.local`: the flags compose, because the cascade has a level where\n * both are true. Refusing the combination is what used to leave that level\n * unaddressable from the CLI.\n *\n * `environment` must already be the name {@link targetScope} validated, never\n * the raw flag — the string here becomes a filename segment verbatim.\n */\nexport function scopeFrom(options: ScopeOptions): Scope {\n if (options.local === true) {\n if (options.environment !== undefined) {\n return { kind: \"environment-local\", environment: options.environment };\n }\n return { kind: \"local\" };\n }\n if (options.environment !== undefined) {\n return { kind: \"environment\", environment: options.environment };\n }\n return { kind: \"unscoped\" };\n}\n\n/**\n * The scope a writer may act on: the environment as `targetEnvironment`\n * *returned* it, never as the flag carried it.\n *\n * `resolveEnvironment` trims before it checks the whitelist, so the validated\n * name and the raw flag are two different strings and only the returned one has\n * been checked against the declared environments. Passing the raw one to\n * `formatValueFile` is what let `--env \"production \"` write `api-key.production `\n * — a file the filename grammar refuses to read (invariant 10), so every later\n * `list`/`get`/`generate`/`validate`/`remove` throws and the tree is repairable\n * only by deleting the file by hand. Validation is what makes a string safe to\n * put in a filename, so the validated value is the only one that may reach one.\n *\n * A blank `--env` is refused rather than resolved: `resolveEnvironment` answers\n * it from `PENV_ENV`/`NODE_ENV`, and a writer scoping a file to an environment\n * the user never named is the same wrong file by a quieter route (invariants 10\n * and 13).\n */\nexport function targetScope(project: Project, options: ScopeOptions, key: string): Scope {\n const environment = options.environment;\n if (environment === undefined) {\n return scopeFrom(options);\n }\n if (environment.trim().length === 0) {\n throw new PenvError(\n \"ENVIRONMENT_FLAG_EMPTY\",\n `\\`--env\\` for parameter ${key} names no environment`,\n `Pass a declared environment — ${environmentNames(project.config)\n .map((e) => `\\`${e}\\``)\n .join(\", \")} — ` +\n \"e.g. `--env production`, or drop `--env` to write the scope that has no environment.\",\n );\n }\n return scopeFrom({ ...options, environment: targetEnvironment(project, environment) });\n}\n\n/**\n * The environment whose policy governs the file being written.\n *\n * `undefined` for a scope that carries no environment, which asks meta for its\n * base block — the honest authority for a file every environment reads. Asking\n * `production`'s block about the unscoped default would apply one environment's\n * policy to a file the others fall back to.\n */\nfunction policyEnvironment(project: Project, options: ScopeOptions): string | undefined {\n return options.environment === undefined\n ? undefined\n : targetEnvironment(project, options.environment);\n}\n\n/**\n * Seals a secret, or refuses for a reason it can name.\n *\n * A key source is declared per environment, so a scope that names no environment\n * has no key penv can choose. It refuses rather than reaching for the ambient\n * environment's key: that key would seal a file every *other* environment also\n * reads, and each of them would then fail to open it — a scope-widening leak\n * dressed as a convenience. `penv set redis/password --env production` is one\n * more word and is unambiguous.\n */\nfunction sealFor(\n project: Project,\n file: ValueFile,\n value: string,\n parameter: string,\n environment: string | undefined,\n): string {\n if (environment === undefined) {\n throw new PenvError(\n \"SECRET_SCOPE_AMBIGUOUS\",\n `Parameter ${parameter} is a secret, and ${recordPath(formatValueFile(file))} names no environment`,\n \"A key is declared by its environment's `keySource` in penv.config.ts, so penv cannot \" +\n \"tell which key should seal a file that every environment reads. Write it at an \" +\n \"environment scope — add `--env <environment>` — or drop `secret` from the parameter's meta.\",\n );\n }\n return sealValue(file, value, keySourceFor(project, environment), parameter, environment);\n}\n\n/** What {@link sealAwareWrite} was told to write, and to which store. */\nexport interface SealAwareWriteOptions {\n readonly project: Project;\n /**\n * The store the value lands in, and the meta whose policy governs it is read\n * *from*. `set` passes the local tree; `rotate` passes it only when the\n * environment's source of truth IS the local tree, so the seal-and-twin rule\n * applies exactly where penv's envelope is penv's concern.\n */\n readonly provider: Provider;\n readonly ref: ParameterRef;\n readonly scope: Scope;\n readonly value: string;\n /** The environment whose meta block decides the policy, or `undefined` for the base block. */\n readonly environment: string | undefined;\n}\n\n/** What {@link sealAwareWrite} did: the marker meta chose, and the file it wrote. */\nexport interface SealAwareWriteResult {\n /** Whether meta's policy sealed it. */\n readonly encrypted: boolean;\n /** The value file written, relative to the records tree. */\n readonly location: string;\n}\n\n/**\n * Writes one value file into the local tree, sealing it when meta says the\n * parameter is a secret, and removing the twin at that scope — the one correct\n * physics for a store whose envelope penv owns.\n *\n * There is no `--encrypt` flag, deliberately. A flag would make the command line\n * the authority on what is secret, and meta is (invariant 14) — the `.enc` marker\n * is validated *against* the policy, so a marker chosen at the keyboard would\n * invert the direction the check runs in. The policy decides; the writer obeys.\n *\n * Both `set` and the local-tree branch of `rotate` go through here, so a rotated\n * secret is sealed exactly as a `set` one is: the defect was `rotate` writing the\n * live credential as cleartext into `.penv/` — where plaintext outranks `.enc` at\n * the same scope, so it also shadowed any sealed copy already there.\n */\nexport async function sealAwareWrite(\n options: SealAwareWriteOptions,\n): Promise<SealAwareWriteResult> {\n const { project, provider, ref, scope, value, environment } = options;\n const secret = isSecret(await provider.readMeta(ref), environment);\n\n const file: ValueFile = {\n namespace: ref.namespace,\n name: ref.name,\n scope,\n encrypted: secret,\n };\n\n // Sealed before anything is written, so a secret penv has no key for leaves\n // nothing behind. Writing the plaintext first and letting `doctor` report it\n // afterwards would put the secret on disk in order to complain about it.\n const stored = secret ? sealFor(project, file, value, parameterId(ref), environment) : value;\n\n await provider.write(file, stored);\n\n // The twin at this scope is removed, because one scope holds one value.\n //\n // `.enc` is orthogonal to precedence, so `<name>.<env>` and `<name>.<env>.enc`\n // are two candidates at one address, and the plaintext is considered first.\n // Leaving the twin behind therefore does not leave a harmless extra file — it\n // leaves the one that *wins*. Marking a parameter secret and running `penv set`\n // reported writing a sealed file while `penv get` kept handing back the stale\n // plaintext underneath it: the value you set was not the value you got, and the\n // new secret was inert on disk. Written before the removal, so the value is\n // never in neither file.\n await provider.remove({ ...file, encrypted: !secret });\n\n return { encrypted: secret, location: formatValueFile(file) };\n}\n\n/**\n * Writes one value file, sealing it when meta says the parameter is a secret.\n *\n * The scope is chosen from the flags, then the seal-and-twin write is the shared\n * {@link sealAwareWrite}, against the local tree — the store `set` always edits.\n */\nexport async function runSet(options: SetOptions): Promise<SetResult> {\n const project = openProject(options.cwd);\n assertWritableKey(options.key);\n const ref = refFromKey(options.key, project.config);\n\n // An environment is a whitelist entry or nothing, so a scope naming one is\n // checked before it becomes a filename — including under `--local`, where\n // the environment is a filename segment too.\n const scope = targetScope(project, options, options.key);\n const environment = policyEnvironment(project, options);\n\n const { encrypted, location } = await sealAwareWrite({\n project,\n provider: project.provider,\n ref,\n scope,\n value: options.value,\n environment,\n });\n\n return { parameter: options.key, location, encrypted };\n}\n\nexport function renderSet(result: SetResult): string[] {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Wrote\",\n subject: recordPath(result.location),\n // The `.enc` suffix says this already, but only to a reader who knows the\n // grammar. Meta decided it, not the command line, so the command says so.\n ...(result.encrypted ? { detail: \"encrypted, per the parameter's meta policy\" } : {}),\n },\n ]);\n}\n\n/** The value when it is piped in rather than typed: one trailing newline is the shell's. */\nexport async function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin as AsyncIterable<Buffer>) {\n chunks.push(Buffer.from(chunk));\n }\n const text = Buffer.concat(chunks).toString(\"utf8\");\n return text.endsWith(\"\\n\") ? text.slice(0, -1) : text;\n}\n\nexport const setCommand = defineCommand({\n meta: { name: \"set\", description: \"Update a parameter\" },\n args: {\n key: { type: \"positional\", required: true, description: \"The parameter, e.g. redis/password\" },\n value: {\n type: \"positional\",\n required: false,\n description: \"The value; read from stdin if omitted\",\n },\n env: { type: \"string\", description: \"Write the <name>.<env> scope\" },\n local: {\n type: \"boolean\",\n description: \"Write the personal override: <name>.<env>.local with --env, else <name>.local\",\n },\n },\n run({ args }) {\n return guard(async () => {\n const value = args.value ?? (await readStdin());\n write(\n renderSet(\n await runSet({\n cwd: process.cwd(),\n key: args.key,\n value,\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.local === undefined ? {} : { local: args.local }),\n }),\n ),\n );\n });\n },\n});\n","/**\n * `penv fill` — walk the schema's required-but-missing parameters and ask for\n * each one, deriving the value file's name so the user never has to.\n *\n * The schema-first flow writes `.penv/env.ts` before any value exists, and there\n * the user hits a translation they should not have to make: `databaseUrl` in the\n * schema is `database-url` on disk, and typing the wrong one writes a file the\n * schema still cannot see. `fill` reads the same declared drift `validate`\n * computes, and for each missing parameter asks for a value and writes it through\n * the one writer — `runSet` — deriving the kebab filename from the schema key.\n *\n * A value is never invented: a blank answer skips the parameter, because the\n * silent value reaching runtime is the failure penv exists to delete, and a\n * placeholder written here is exactly that value by a friendlier route.\n *\n * Optional parameters — `.optional()`, `.default()` — are asked too, after the\n * required gaps, tagged so the reader knows an answer is an override and Enter\n * keeps what the schema declared. Skipping them silently was the old behavior,\n * and it hid a real choice: a schema default reaching runtime is legal, but the\n * user who never heard the question never chose it.\n */\n\nimport { PenvError, recordPath, SCHEMA_SHAPE_FILE } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { shorthandCandidates } from \"../env-flags.js\";\nimport { lineReader } from \"../input.js\";\nimport { out } from \"../style.js\";\nimport { CHECK, formatRows, guard, prompt as promptLine, type Row, WARN, write } from \"../ui.js\";\nimport { runSet } from \"./set.js\";\nimport { runValidate, type ValidateIssueKind } from \"./validate.js\";\n\n/**\n * The validation issue kinds that stop `fill` before it writes a thing. A\n * `schema` issue is, on the ordinary run, the missing value `fill` is about to\n * ask for — so it is deliberately absent here, or `fill` would refuse the very\n * gap it exists to close. A collision, a reserved token, or a config/load\n * failure is a structural fault of the tree itself, and filling would only paper\n * over it: `generate` would still drop a value, and \"what is missing\" is not even\n * a meaningful question against a config that does not load.\n */\nconst BLOCKING: ReadonlySet<ValidateIssueKind> = new Set([\"config\", \"collision\", \"reserved\"]);\n\n/** One question `fill` puts to the user: which parameter, in which environment. */\nexport interface FillPrompt {\n /** The value file's key, kebab and slash-separated — the name the user need never derive. */\n readonly parameter: string;\n readonly environment: string;\n /**\n * Whether meta says this is a secret. Carried so a wrapper can mute the echo;\n * v1 does not, and the drift carries no meta, so this is `false` today.\n */\n readonly secret: boolean;\n /**\n * Whether the schema excuses absence — `.optional()`, `.default()`. An answer\n * writes an override; a blank one leaves the schema's own behavior in place,\n * which is a kept default rather than a lingering gap.\n */\n readonly optional: boolean;\n /** What the schema falls back to, rendered for display, when it declares one penv can read. */\n readonly defaultValue?: string;\n readonly description?: string;\n}\n\nexport interface FillOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n /**\n * How a value is obtained for one prompt. `undefined` or an empty answer skips\n * the parameter — the readline half lives only in the wrapper, so `runFill`\n * stays pure and unit-testable.\n */\n readonly ask: (prompt: FillPrompt) => Promise<string | undefined>;\n}\n\nexport interface FillResult {\n readonly environment: string;\n /** The value files written, one per answered prompt. */\n readonly written: ReadonlyArray<{\n readonly parameter: string;\n /** The value file written, relative to the records tree. */\n readonly location: string;\n readonly encrypted: boolean;\n }>;\n /** The parameters a blank answer left for later — never written as an empty value. */\n readonly skipped: readonly string[];\n /**\n * The optional parameters a blank answer left to the schema. Not `skipped`:\n * a skipped parameter is still a gap, and one of these is a decision — the\n * schema's default (or declared absence) is the value, on purpose.\n */\n readonly kept: readonly string[];\n /**\n * The declared keys no filename reaches (`apiURL`, a reserved token). `fill`\n * cannot ask for a value it could never write, so it carries the rename remedy\n * out rather than prompting for a file that would error.\n */\n readonly unreachable: ReadonlyArray<{ readonly subject: string; readonly remedy: string }>;\n}\n\n/**\n * Asks for every declared-but-missing parameter, and writes the ones answered.\n *\n * The drift is `validate`'s, not a second reading of the schema: `runValidate`\n * already computes exactly the required-but-absent set, so `fill` and `validate`\n * can never disagree about what is missing. The writing is `runSet`'s, so a\n * filled secret is sealed exactly as a `set` one is — `fill` owns neither the\n * resolution nor the write, only the prompting between them.\n */\nexport async function runFill(options: FillOptions): Promise<FillResult> {\n const validation = await runValidate({\n cwd: options.cwd,\n ...(options.environment === undefined ? {} : { environment: options.environment }),\n ...(options.envFlags === undefined ? {} : { envFlags: options.envFlags }),\n });\n const environment = validation.environment;\n\n // A tree that fails validation for a *structural* reason is not one `fill`\n // should write into, so it refuses and hands the reasons back rather than\n // prompting. Keying off the issue kinds — not `validation.ok` — is the load-\n // bearing choice: a required parameter with no value fails the schema too, and\n // that failure *is* the drift `fill` exists to close, so blocking on `ok` would\n // refuse every ordinary run. The `EMPTY_DRIFT` sentinel is not consulted: a\n // schema that never loaded surfaces here as a `config` blocker with its real\n // reason, so a provider-list failure no longer masquerades as \"no schema\".\n const blockers = validation.issues.filter((issue) => BLOCKING.has(issue.kind));\n if (blockers.length > 0) {\n const detail = blockers\n .map(\n (issue) => ` - ${issue.message}${issue.remedy === undefined ? \"\" : ` (${issue.remedy})`}`,\n )\n .join(\"\\n\");\n throw new PenvError(\n \"FILL_BLOCKED\",\n `penv fill cannot run: environment ${environment} has ${blockers.length} unresolved ` +\n `configuration ${blockers.length === 1 ? \"issue\" : \"issues\"}:\\n${detail}`,\n \"Fix these — `penv validate` reports them — then run `penv fill`. If you have not written a \" +\n `schema yet, declare the required parameters in ${SCHEMA_SHAPE_FILE}.`,\n );\n }\n\n const written: Array<{ parameter: string; location: string; encrypted: boolean }> = [];\n const skipped: string[] = [];\n const kept: string[] = [];\n const unreachable: Array<{ subject: string; remedy: string }> = [];\n\n for (const drift of validation.drift.declared) {\n // A key outside the name transform's image, or a reserved token: no value\n // file reaches it, so the remedy is a rename, not a value. Prompting here\n // would ask for a file penv would then refuse to write.\n if (drift.ref === undefined) {\n unreachable.push({ subject: drift.subject, remedy: drift.remedy });\n continue;\n }\n\n const ref = drift.ref;\n const key = [...ref.namespace, ref.name].join(\"/\");\n // `secret` stays false: the drift carries no meta, and echo-muting is not a\n // v1 feature. The write below still seals per meta — `runSet` reads it there.\n const value = await options.ask({\n parameter: key,\n environment,\n secret: false,\n optional: false,\n });\n if (value === undefined || value === \"\") {\n skipped.push(drift.subject);\n continue;\n }\n\n const result = await runSet({ cwd: options.cwd, key, value, environment });\n written.push({\n parameter: drift.subject,\n location: result.location,\n encrypted: result.encrypted,\n });\n }\n\n // The optional parameters, asked after the required gaps: the schema excuses\n // their absence, so a blank answer here is a decision to keep the schema's\n // default rather than a gap left open — `kept`, not `skipped`. Asking at all\n // is the point: an override the user never hears about is one they can never\n // choose, and the tag on the prompt is what keeps the choice a free one.\n for (const item of validation.drift.optional) {\n if (item.ref === undefined) {\n unreachable.push({ subject: item.subject, remedy: item.remedy });\n continue;\n }\n\n const ref = item.ref;\n const key = [...ref.namespace, ref.name].join(\"/\");\n const value = await options.ask({\n parameter: key,\n environment,\n secret: false,\n optional: true,\n ...(item.defaultValue === undefined ? {} : { defaultValue: item.defaultValue }),\n });\n if (value === undefined || value === \"\") {\n kept.push(item.subject);\n continue;\n }\n\n const result = await runSet({ cwd: options.cwd, key, value, environment });\n written.push({\n parameter: item.subject,\n location: result.location,\n encrypted: result.encrypted,\n });\n }\n\n return { environment, written, skipped, kept, unreachable };\n}\n\n/** The one line that reports the run's shape when nothing else needs a row. */\nfunction summaryLine(result: FillResult): string {\n const filled = result.written.length;\n if (\n filled === 0 &&\n result.skipped.length === 0 &&\n result.kept.length === 0 &&\n result.unreachable.length === 0\n ) {\n return `${out.green(CHECK)} Nothing to fill for environment ${result.environment}: every declared parameter has a value`;\n }\n const parts = [`${filled} written`];\n if (result.skipped.length > 0) {\n parts.push(`${result.skipped.length} skipped`);\n }\n if (result.kept.length > 0) {\n parts.push(`${result.kept.length} left to the schema's defaults`);\n }\n if (result.unreachable.length > 0) {\n parts.push(`${result.unreachable.length} unreachable`);\n }\n return `${parts.join(\", \")} for environment ${result.environment}`;\n}\n\nexport function renderFill(result: FillResult): string[] {\n const rows: Row[] = result.written.map((entry) => ({\n glyph: CHECK,\n label: \"Wrote\",\n subject: recordPath(entry.location),\n // Meta decided the seal, not the answer, so the line says so — as `set` does.\n ...(entry.encrypted ? { detail: \"encrypted, per the parameter's meta policy\" } : {}),\n }));\n\n // A key no filename reaches is not skipped — it is unwritable until it is\n // renamed, so it carries its rename remedy rather than a value prompt.\n for (const entry of result.unreachable) {\n rows.push({ glyph: WARN, label: \"Unreachable\", subject: entry.subject, detail: entry.remedy });\n }\n\n const lines = formatRows(rows);\n lines.push(summaryLine(result));\n return lines;\n}\n\n/**\n * The prompt's aside: what Enter does. For a required gap it skips; for an\n * optional parameter it keeps whatever the schema declared — named exactly,\n * with the default shown when penv can read it, because \"optional\" alone tells\n * the user a choice exists without telling them what not choosing means. A\n * default too long to sit inside a prompt is elided rather than allowed to push\n * the cursor off the line.\n */\nfunction contextFor(prompt: FillPrompt): string {\n if (!prompt.optional) {\n return `${prompt.environment}, Enter to skip`;\n }\n if (prompt.defaultValue === undefined) {\n return `${prompt.environment} · optional, Enter leaves it unset`;\n }\n const shown =\n prompt.defaultValue.length > 24 ? `${prompt.defaultValue.slice(0, 23)}…` : prompt.defaultValue;\n return `${prompt.environment} · optional, Enter keeps ${shown}`;\n}\n\nexport const fillCommand = defineCommand({\n meta: {\n name: \"fill\",\n description: \"Prompt for each declared parameter the tree has no value for\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to fill\" },\n },\n run({ args }) {\n return guard(async () => {\n const reader = lineReader();\n // TODO: a `prompt.secret` answer still echoes — echo-muting is out of scope\n // for v1. The prompt shows the derived key, so a reader sees the file name\n // their answer becomes. An empty answer skips — the prompt's aside says so,\n // because the skip is a feature and an undiscoverable feature is not one.\n const ask = (prompt: FillPrompt): Promise<string | undefined> =>\n reader.ask(promptLine(prompt.parameter, contextFor(prompt)));\n try {\n write(\n renderFill(\n await runFill({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n ask,\n envFlags: shorthandCandidates(args, [\"env\"]),\n }),\n ),\n );\n } finally {\n reader.close();\n }\n });\n },\n});\n","/**\n * `penv generate` — write a flat `.env` artifact for deploy targets that expect\n * one.\n *\n * The output is an artifact, never an input: invariant 15 makes `.penv/` the\n * source of truth, and a hand-edit here is not absorbed back. Ordering is\n * normalized rather than preserved — one value per file discards the source\n * file's sequence by construction, so `generate` emits a deterministic sorted\n * order and the output is stable and diffable across machines.\n */\n\nimport { writeFileSync } from \"node:fs\";\nimport { isAbsolute, relative, resolve } from \"node:path\";\nimport type { DotenvEntry } from \"@penvhq/core\";\nimport {\n checkNameCollisions,\n effectiveMeta,\n PenvError,\n recordPath,\n requireValue,\n serializeDotenv,\n variableName,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { shorthandCandidates } from \"../env-flags.js\";\nimport type { Project } from \"../project.js\";\nimport {\n keySourceFor,\n localTree,\n openProject,\n refsFrom,\n resolveAllSync,\n targetEnvironment,\n} from \"../project.js\";\nimport { CHECK, formatRows, guard, WARN, write } from \"../ui.js\";\n\nexport const DEFAULT_OUTPUT = \".env\";\n\nexport interface GenerateOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n /** Where to write, absolute or relative to `cwd`. Defaults to `.env` at the project root. */\n readonly out?: string;\n /** Permits sealed values to be written into the artifact as plaintext. */\n readonly allowDecrypt?: boolean;\n}\n\nexport interface GenerateResult {\n readonly file: string;\n readonly environment: string;\n readonly entries: number;\n /** How many of them were sealed and are now plaintext in the artifact. */\n readonly decrypted: number;\n}\n\n/**\n * The variables for one environment, and how many of them were sealed.\n *\n * The count is returned rather than discarded because decrypting a secret into a\n * plaintext artifact is the one thing this command does that the user cannot see\n * by looking at the tree. `generate` reports it (invariant 13).\n */\ninterface Artifact {\n readonly entries: DotenvEntry[];\n readonly decrypted: number;\n}\n\nfunction entriesFor(project: Project, environment: string, allowDecrypt: boolean): Artifact {\n const keys = keySourceFor(project, environment);\n const tree = localTree(project);\n const resolutions = resolveAllSync(tree, environment, keys);\n\n // Invariant 12, enforced where the loss would happen: two parameters mapping\n // to one variable would silently drop a value from this file.\n const collision = checkNameCollisions(\n refsFrom(resolutions.map((resolution) => resolution.ref)),\n project.config,\n )[0];\n if (collision !== undefined) {\n throw collision;\n }\n\n const entries: DotenvEntry[] = [];\n let decrypted = 0;\n for (const resolution of resolutions) {\n const winner = resolution.winner;\n if (winner?.file.encrypted === true) {\n // A `.env` is plaintext by construction, so writing a sealed value into one\n // unseals it. penv will do that — the leaving guarantee is that a working\n // `.env` is always reachable — but never as a side effect of a command the\n // user ran for another reason. Asking makes the moment the secret becomes\n // plaintext a moment they chose.\n if (!allowDecrypt) {\n throw new PenvError(\n \"ENCRYPTED_VALUE_REFUSED\",\n `Parameter ${resolution.parameter} for environment ${environment} resolves to the encrypted value file ${recordPath(winner.location)}, and \\`penv generate\\` writes plaintext`,\n `Re-run with \\`--allow-decrypt\\` to write the decrypted value into the artifact, or generate for an environment whose values are plaintext. The artifact is gitignored; a committed plaintext secret is a \\`penv doctor\\` failure.`,\n );\n }\n // Throws when it cannot be opened, naming the reason — never silently\n // omitting the variable, which would produce an artifact that is missing\n // exactly the secret the deploy needs.\n requireValue(resolution, environment);\n decrypted += 1;\n }\n if (resolution.value === undefined) {\n continue;\n }\n // A parameter's description is a comment in the generated file, so the\n // annotation that arrived on import survives the round trip back out.\n const description = effectiveMeta(tree.readMetaSync(resolution.ref), environment).description;\n entries.push({\n key: variableName(resolution.ref, project.config),\n value: resolution.value,\n ...(typeof description === \"string\" ? { description } : {}),\n });\n }\n\n // Sorted by the generated variable, which is what a reader of this file sees.\n entries.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));\n return { entries, decrypted };\n}\n\n/** The `.env` text for one environment — what `penv generate` writes. */\nexport function generateDotenv(options: Omit<GenerateOptions, \"out\">): string {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n return serializeDotenv(entriesFor(project, environment, options.allowDecrypt === true).entries);\n}\n\nexport function runGenerate(options: GenerateOptions): GenerateResult {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n const { entries, decrypted } = entriesFor(project, environment, options.allowDecrypt === true);\n\n // `--out` is the caller's path, so it is relative to where they are standing;\n // the default artifact belongs next to the config it was generated from.\n const file =\n options.out === undefined\n ? resolve(project.root, DEFAULT_OUTPUT)\n : isAbsolute(options.out)\n ? options.out\n : resolve(options.cwd, options.out);\n\n writeFileSync(file, serializeDotenv(entries), \"utf8\");\n return { file, environment, entries: entries.length, decrypted };\n}\n\n/** The artifact's path as the caller would type it, when it is below them. */\nfunction displayPath(cwd: string, file: string): string {\n const rel = relative(cwd, file);\n return rel === \"\" || rel.startsWith(\"..\") ? file : rel.split(\"\\\\\").join(\"/\");\n}\n\nexport function renderGenerate(result: GenerateResult, cwd: string): string[] {\n const rows = [\n {\n glyph: CHECK,\n label: \"Generated\",\n subject: displayPath(cwd, result.file),\n detail: `${result.entries} variables for environment ${result.environment}`,\n },\n ];\n // A secret that was sealed a moment ago and is plaintext now is worth a line of\n // its own. The artifact is gitignored, which is a reason it is safe to write —\n // not a reason to write it quietly.\n if (result.decrypted > 0) {\n rows.push({\n glyph: WARN,\n label: \"Decrypted\",\n subject: `${result.decrypted} ${result.decrypted === 1 ? \"secret\" : \"secrets\"}`,\n detail: \"written as plaintext into the artifact\",\n });\n }\n return formatRows(rows);\n}\n\nexport const generateCommand = defineCommand({\n meta: { name: \"generate\", description: \"Write a standard .env artifact for deploy targets\" },\n args: {\n env: { type: \"string\", description: \"The environment to generate for\" },\n out: { type: \"string\", description: \"Where to write, instead of .env\" },\n \"allow-decrypt\": {\n type: \"boolean\",\n description: \"Write encrypted values into the artifact as plaintext\",\n },\n },\n run({ args }) {\n return guard(async () => {\n const cwd = process.cwd();\n const result = runGenerate({\n cwd,\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.out === undefined ? {} : { out: args.out }),\n ...(args[\"allow-decrypt\"] === undefined ? {} : { allowDecrypt: args[\"allow-decrypt\"] }),\n envFlags: shorthandCandidates(args, [\"env\", \"out\", \"allow-decrypt\", \"allowDecrypt\"]),\n });\n write(renderGenerate(result, cwd));\n });\n },\n});\n","/**\n * `penv get <key>` — read a parameter, or explain which file wins and why.\n *\n * Fallback is never silent, and neither is precedence: `--explain` prints every\n * candidate in the order the cascade considered them, so a value quietly coming\n * from a shared default has nowhere to hide.\n */\n\nimport { PenvError, recordPath, requireValue, resolveParameter } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { keySourceFor, openProject, refFromKey, targetEnvironment } from \"../project.js\";\nimport { out } from \"../style.js\";\nimport { CROSS, columns, guard, write } from \"../ui.js\";\n\nexport interface GetOptions {\n readonly cwd: string;\n readonly key: string;\n readonly environment?: string;\n}\n\nexport interface GetExplanation {\n readonly parameter: string;\n readonly environment: string;\n /** `undefined` when no candidate was present. */\n readonly location: string | undefined;\n /**\n * Why the winning file did not open, when it is `.enc` and did not.\n *\n * A winner that cannot be decrypted is not a skipped candidate — it won, and\n * the cascade is over. Reporting it as a skip would say a lower scope should\n * have been reached, which is the scope-widening answer the cascade refuses.\n */\n readonly undecryptable?: string;\n readonly candidates: readonly GetCandidate[];\n}\n\nexport interface GetCandidate {\n readonly location: string;\n readonly present: boolean;\n readonly wins: boolean;\n /** Why a present candidate did not win, or why it was never considered. */\n readonly skipped: string | undefined;\n}\n\n/**\n * The value, or a named error.\n *\n * `requireValue` answers first, so a winner that exists but did not decrypt is\n * reported as undecryptable rather than as absent. Only a genuine absence — no\n * candidate at any scope — reaches the refusal below, which is what keeps `penv\n * set` from being offered as the fix for a secret the user still has.\n */\nexport async function runGet(options: GetOptions): Promise<string> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment);\n const ref = refFromKey(options.key);\n\n const keys = keySourceFor(project, environment);\n const resolution = await resolveParameter(ref, environment, project.provider, keys);\n const value = requireValue(resolution, environment);\n if (value === undefined) {\n throw new PenvError(\n \"PARAMETER_ABSENT\",\n `Parameter ${resolution.parameter} resolves to no value for environment ${environment}`,\n `Set it with \\`penv set ${options.key} --env ${environment}\\`, or run \\`penv get ${options.key} --env ${environment} --explain\\` to see every file penv looked at.`,\n );\n }\n return value;\n}\n\nfunction skipReason(reason: string | undefined): string | undefined {\n if (reason === \"lower-precedence\") {\n // Not \"a more specific scope wins\". Within one scope the plaintext file is\n // considered before its `.enc` twin, so the file that beat this one is\n // sometimes at the *same* scope — and a reader told the winner was more\n // specific would go looking for a scope that does not exist.\n return \"skipped, a higher-precedence file wins\";\n }\n if (reason === \"local-skipped-in-test\") {\n return \"skipped, .local never applies in test\";\n }\n return undefined;\n}\n\n/**\n * Which file wins, and why — never a value, so this must not be stopped by the\n * winner being unreadable. Core describes an `.enc` winner rather than refusing\n * it, so `--explain` is the same walk every other command does.\n */\nexport async function runExplain(options: GetOptions): Promise<GetExplanation> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment);\n const ref = refFromKey(options.key);\n\n const keys = keySourceFor(project, environment);\n const resolution = await resolveParameter(ref, environment, project.provider, keys);\n const winner = resolution.winner;\n\n return {\n parameter: resolution.parameter,\n environment,\n location: winner === undefined ? undefined : winner.location,\n ...(resolution.undecryptable === undefined\n ? {}\n : { undecryptable: resolution.undecryptable.detail }),\n candidates: resolution.candidates.map((candidate) => ({\n location: candidate.location,\n present: candidate.present,\n wins: candidate === winner,\n skipped: skipReason(candidate.skippedReason),\n })),\n };\n}\n\nexport function renderExplain(explanation: GetExplanation): string[] {\n const target = explanation.location === undefined ? \"nothing\" : recordPath(explanation.location);\n\n // Candidates stay in the order the cascade considered them: the answer to\n // \"why this file\" is the list above it that did not win. The winner is the one\n // line in color; everything that lost is metadata and reads dimmed.\n const rows = explanation.candidates.map((candidate) => [\n candidate.wins ? candidate.location : out.dim(candidate.location),\n candidate.wins\n ? out.green(\"present, wins\")\n : out.dim(\n candidate.present ? (candidate.skipped ?? \"present\") : (candidate.skipped ?? \"absent\"),\n ),\n ]);\n\n return [\n `${out.bold(explanation.parameter)} resolves to ${target} for environment ${explanation.environment}`,\n ...(explanation.undecryptable === undefined\n ? []\n : [` ${out.red(CROSS)} penv cannot decrypt it: ${explanation.undecryptable}`]),\n \"\",\n ...columns(rows).map((line) => ` ${line}`),\n ];\n}\n\nexport const getCommand = defineCommand({\n meta: { name: \"get\", description: \"Read a parameter\" },\n args: {\n key: { type: \"positional\", required: true, description: \"The parameter, e.g. redis/password\" },\n env: { type: \"string\", description: \"The environment to read\" },\n explain: { type: \"boolean\", description: \"Print which file wins, and why\" },\n },\n run({ args }) {\n return guard(async () => {\n const options: GetOptions = {\n cwd: process.cwd(),\n key: args.key,\n ...(args.env === undefined ? {} : { environment: args.env }),\n };\n if (args.explain === true) {\n write(renderExplain(await runExplain(options)));\n return;\n }\n write([await runGet(options)]);\n });\n },\n});\n","/**\n * `penv import <file>` — adopt an existing dotenv file.\n *\n * Invariant 15: this is one-directional. After it runs, `.penv/` is the source of\n * truth and `.env` is an artifact `penv generate` writes; there is no reverse\n * sync of hand-edits back out of the generated file.\n *\n * It takes one file; `penv init` takes a whole cascade in one cutover. The\n * checks and the write they share live in `adopt.ts`.\n *\n * Scope, unlike namespace, *is* readable from the source: the filename says it,\n * in the four-level vocabulary invariant 4 adopts wholesale. `.env.production`\n * carries `production` the way `.env` carries nothing, so import reads it rather\n * than flattening it — a `.env.development.local` written to the unscoped default\n * would serve every environment, and one developer's machine would become\n * production's fallback.\n *\n * `--env` is the other half of that reading. A file the filename says nothing\n * about — `prod-secrets.txt`, or a plain `.env` the user is adopting as one\n * environment's values — has its scope named by the flag instead, because \"these\n * are production's values\" is what `--env production` means at an import. Only a\n * file that names neither is the unscoped default.\n */\n\nimport { copyFileSync, existsSync, readFileSync } from \"node:fs\";\nimport { basename, isAbsolute, relative, resolve } from \"node:path\";\nimport type { PenvConfig, Scope } from \"@penvhq/core\";\nimport {\n assertNever,\n environmentNames,\n FilenameGrammarError,\n findConfigFile,\n loadConfigFrom,\n lookupEnvironment,\n PenvError,\n parseDotenv,\n schemaFileOf,\n UnknownEnvironmentError,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { assertNoCollisions, refsForEntries, writeEntries } from \"../adopt.js\";\nimport { detectAlias } from \"../detect.js\";\nimport { draftFields } from \"../draft-schema.js\";\nimport { localTree, openProject } from \"../project.js\";\nimport { CHECK, formatSteps, guard, type Step, WARN, write } from \"../ui.js\";\nimport type { InitDecisions, InitStep } from \"./init.js\";\nimport { planInit, scaffold, writeConfigFile } from \"./init.js\";\nimport type { ValidateResult } from \"./validate.js\";\nimport { renderValidate, runValidate } from \"./validate.js\";\n\nexport interface ImportOptions {\n readonly cwd: string;\n /** The dotenv file to adopt, absolute or relative to `cwd`. */\n readonly file: string;\n /**\n * `--env`. It reads as \"these are <environment>'s values\", so for a file whose\n * name carries no environment it names the *scope* as well as the environment\n * to run against: `penv import prod-secrets.txt --env production` writes\n * `<name>.production`, and `--env production` on `.env.local` writes\n * `<name>.production.local`. The filename supplies both when it carries an\n * environment, so the flag is needed only for a file that does not — and\n * contradicting the filename is an error rather than a silent choice between\n * the two.\n */\n readonly environment?: string;\n}\n\nexport interface ImportReport {\n readonly root: string;\n readonly file: string;\n readonly backup: string;\n /** The scope the source named — filename, `--env`, or both — and the scope every value was written at. */\n readonly scope: Scope;\n /**\n * The environment the import ran against, or `undefined` when none is set.\n *\n * Undefined only ever accompanies the unscoped default: any other scope names\n * an environment, so it always has one. It means the values were written and\n * the closing validation was skipped, which the output states.\n */\n readonly environment: string | undefined;\n /** The declared environments, so a skipped validation can name one to pass. */\n readonly environments: readonly string[];\n readonly variables: number;\n /**\n * Comment blocks that belonged to no variable. Reported rather than discarded\n * silently: a file header has no parameter to describe, but that is not a\n * reason to pretend it was never there.\n */\n readonly orphanComments: number;\n readonly steps: readonly InitStep[];\n}\n\nconst BACKUP_SUFFIX = \".backup\";\n\n/** The segment that starts a dotenv filename's scope. `.env`, `.env.production`. */\nconst DOTENV_SEGMENT = \"env\";\nconst LOCAL = \"local\";\n\n/**\n * Invariant 10: a segment is an environment because `penv.config.ts` declares\n * it, never because it looks like one. This matches the whitelist — the thing\n * the invariant permits — and refuses everything else.\n *\n * Refusing is the whole point. Falling back to the unscoped default for an\n * undeclared segment is precisely the leak: `.env.staging` in a project that\n * never declared `staging` would become the value every environment reads.\n */\nfunction assertDeclared(segment: string, config: PenvConfig): string {\n const declared = environmentNames(config);\n if (declared.includes(segment)) {\n return segment;\n }\n throw new UnknownEnvironmentError(segment, declared);\n}\n\n/**\n * The scope the source filename names, in the vocabulary invariant 4 shares with\n * Next.js and Vite: `.env` > unscoped, `.env.<env>`, `.env.local`, and\n * `.env.<env>.local`.\n *\n * Parsing starts at the first `env` segment, because `import` reads whatever\n * file it is pointed at and the basename may carry a prefix. A file with no\n * `env` segment at all is the plain-`.env` case — there is no scope written on\n * it, so there is none to read, and the unscoped default is what it means.\n */\nfunction scopeFromFilename(file: string, config: PenvConfig): Scope {\n const name = basename(file);\n const segments = name.split(\".\");\n const start = segments.indexOf(DOTENV_SEGMENT);\n if (start === -1) {\n return { kind: \"unscoped\" };\n }\n\n const rest = segments.slice(start + 1).filter((segment) => segment.length > 0);\n const first = rest[0];\n const second = rest[1];\n\n if (first === undefined) {\n return { kind: \"unscoped\" };\n }\n\n if (second === undefined) {\n if (first === LOCAL) {\n return { kind: LOCAL };\n }\n return { kind: \"environment\", environment: assertDeclared(first, config) };\n }\n\n if (rest.length === 2 && second === LOCAL && first !== LOCAL) {\n return { kind: \"environment-local\", environment: assertDeclared(first, config) };\n }\n\n // The order is fixed at both ends of the import: the environment precedes\n // `local` in the dotenv filename this reads and in the value filename it\n // writes, so `.env.local.production` is an error rather than a synonym.\n if (first === LOCAL && rest.length === 2) {\n throw new FilenameGrammarError(\n name,\n \"`local` precedes the environment segment\",\n `The environment segment always precedes \\`local\\` — \\`.env.${second}.${LOCAL}\\` is the ` +\n `file Next.js and Vite read, and \\`.env.${LOCAL}.${second}\\` is not a synonym for it. ` +\n `Rename it to \\`.env.${second}.${LOCAL}\\`, then import it again. Nothing was imported.`,\n );\n }\n\n throw new FilenameGrammarError(\n name,\n `\\`${rest.join(\"` and `\")}\\` are ${rest.length} scope segments`,\n \"A dotenv file carries exactly one scope: `.env`, `.env.<environment>`, `.env.local`, or \" +\n \"`.env.<environment>.local`. Point `penv import` at one of those. Nothing was imported.\",\n );\n}\n\n/**\n * The environment a scope names, or `undefined` when it names none.\n *\n * The `default` is load-bearing rather than ceremonial: a fifth scope carrying\n * an environment would otherwise report `undefined` here, and import would fall\n * back to `--env` — silently widening exactly the way the three-level cascade did.\n */\nfunction environmentOf(scope: Scope): string | undefined {\n switch (scope.kind) {\n case \"environment\":\n case \"environment-local\":\n return scope.environment;\n case \"unscoped\":\n case \"local\":\n return undefined;\n default:\n return assertNever(scope, \"scope\");\n }\n}\n\n/**\n * The scope `--env <environment>` names, given the scope the filename named.\n *\n * `--env` reads as \"these are <environment>'s values\", so it names a scope and\n * not merely a validation target. Deriving the scope from the filename alone was\n * the scope-widening leak: `penv import prod-secrets.txt --env production` wrote\n * the unscoped default, and `development` read the production secret.\n *\n * A filename that already names an environment keeps its scope untouched: by the\n * time this runs the two agree, because a contradiction is an error. `.env.local`\n * names a scope but no environment, so the two compose — the filename says\n * personal override, `--env` says which environment it overrides, and together\n * they are `.env.<environment>.local`.\n */\nfunction scopeWithEnvironment(scope: Scope, environment: string): Scope {\n switch (scope.kind) {\n case \"unscoped\":\n return { kind: \"environment\", environment };\n case LOCAL:\n return { kind: \"environment-local\", environment };\n case \"environment\":\n case \"environment-local\":\n return scope;\n default:\n return assertNever(scope, \"scope\");\n }\n}\n\n/**\n * `--env`, normalized the way `resolveEnvironment` normalizes it — but a flag\n * that is present and blank is refused rather than normalized away.\n *\n * `--env \"$ENVIRONMENT\"` with the variable unset arrives here as `\"\"`. Reading\n * that as \"no `--env`\" silently demotes the scope the user asked for to the\n * unscoped default, so `penv import prod-secrets.txt --env \"\"` writes the\n * production secret to the file every environment falls back to — the leak this\n * flag exists to close, through a quieter door. An absent flag still means the\n * unscoped default: that is the user declining to name a scope, not failing to.\n */\nfunction explicitEnvironment(options: ImportOptions, source: string, config: PenvConfig): string {\n const value = options.environment?.trim() ?? \"\";\n if (value.length > 0) {\n return value;\n }\n throw new PenvError(\n \"IMPORT_ENV_FLAG_EMPTY\",\n `\\`--env\\` for the import of ${source} names no environment`,\n `Pass a declared environment — ${environmentNames(config)\n .map((e) => `\\`${e}\\``)\n .join(\", \")} — e.g. ` +\n `\\`--env production\\`, or drop \\`--env\\` to import ${source} as the scope that has no ` +\n `environment. Nothing was imported.`,\n );\n}\n\n/**\n * `penv import .env.production --env development` names two environments and\n * means one of them. penv cannot know which, and both readings are destructive:\n * honouring `--env` validates the wrong environment, honouring the filename\n * ignores what the user typed. It says so instead of choosing.\n */\nfunction assertEnvironmentAgrees(\n derived: string | undefined,\n explicit: string | undefined,\n source: string,\n): void {\n if (derived === undefined || explicit === undefined || derived === explicit) {\n return;\n }\n throw new PenvError(\n \"IMPORT_ENV_CONFLICT\",\n `The file ${source} is scoped to environment ${derived}, but \\`--env ${explicit}\\` names ${explicit}`,\n `Drop \\`--env\\` to import ${source} as ${derived}, pass \\`--env ${derived}\\` to say the same ` +\n `thing twice, or point \\`penv import\\` at the file that holds ${explicit}'s values. ` +\n `Nothing was imported.`,\n );\n}\n\n/**\n * The config `import` must judge names against: the project's own when it has\n * one, and otherwise the one `penv init` writes, since that is the config the\n * scaffold below is about to put in place.\n *\n * Writing it *first* is what lets every name check run before a single value\n * file exists. It is safe to leave behind if a check then fails: it is byte for\n * byte the file `penv init` writes, it holds nothing read out of the `.env`, and\n * it is the file the reserved-token and `override` remedies both tell the user to\n * go and edit.\n */\n/**\n * The environment this run names, read lexically — before any config exists to\n * check it against.\n *\n * `scopeFromFilename` cannot answer this: it validates against the whitelist, and\n * on a greenfield project the whitelist is the thing being written. So the\n * segment is read here without being believed, handed to the scaffold as a\n * declaration, and then checked by the ordinary path like any other.\n *\n * Reading it is not inference. Invariant 10 forbids penv deciding that a file in\n * a tree belongs to an environment nobody declared; this is the user typing\n * `penv import .env.production` and thereby saying which environment the file is\n * for. The command line is a declaration — the only one available on a project\n * that has no config yet.\n */\nfunction environmentNamed(file: string, explicit: string | undefined): string | undefined {\n if (explicit !== undefined && explicit.trim().length > 0) {\n return explicit.trim();\n }\n const segments = basename(file).split(\".\");\n const start = segments.indexOf(DOTENV_SEGMENT);\n if (start === -1) {\n return undefined;\n }\n const first = segments.slice(start + 1).filter((segment) => segment.length > 0)[0];\n return first === undefined || first === LOCAL ? undefined : first;\n}\n\n/**\n * The config to check every name against, scaffolding one when the project has none.\n *\n * Writing it *first* is what lets every name check run before a single value\n * file exists. It is safe to leave behind if a check then fails: it holds\n * nothing read out of the `.env`, and it is the file the reserved-token and\n * `override` remedies both tell the user to go and edit.\n *\n * The scaffold declares the environment this import names, and nothing else.\n * `penv init` refuses to invent environments because it cannot observe a\n * deployment — but here the user has named one, and a config that omitted it\n * would be penv writing a file that makes penv's own next step fail.\n */\ninterface Adoption {\n readonly config: PenvConfig;\n /**\n * What the rest of the scaffold must write, and the reason this is returned\n * rather than recomputed.\n *\n * `scaffold` takes `decisions` with a default, so a caller that forgot them\n * compiled and quietly wrote `DEFAULT_DECISIONS` instead. Import forgot them:\n * the config it wrote said `schemaFile: \"src/env.ts\"` while the schema it\n * scaffolded a moment later went to `.penv/env.ts`, and the two disagreed for\n * exactly as long as the project lived. The optional parameter is what hid it\n * from the compiler; carrying the decisions is what stops the two halves of one\n * scaffold answering the same question differently.\n */\n readonly decisions: InitDecisions;\n}\n\n/** The decisions a config already records. The alias is read from the files that resolve it. */\nfunction decisionsOf(config: PenvConfig, cwd: string): InitDecisions {\n return {\n environments: environmentNames(config),\n // `import` re-scaffolds env.ts for an existing project; injection is an init\n // choice, so it is not turned on here.\n inject: false,\n schemaFile: schemaFileOf(config),\n publicPrefixes: config.publicPrefixes ?? [],\n alias: detectAlias(cwd),\n };\n}\n\nfunction configInEffect(cwd: string, environment: string | undefined): Adoption {\n const existing = findConfigFile(cwd);\n if (existing !== undefined) {\n const config = loadConfigFrom(existing);\n return { config, decisions: decisionsOf(config, cwd) };\n }\n // The same plan `penv init` would make without being asked anything — import\n // is a scaffold too, and two scaffolds that disagreed about where the schema\n // goes would make the answer depend on which command the user reached for.\n const planned = planInit(cwd).decisions;\n const decisions: InitDecisions = {\n ...planned,\n environments: environment === undefined ? planned.environments : [environment],\n };\n writeConfigFile(cwd, decisions);\n return { config: openProject(cwd).config, decisions };\n}\n\n/**\n * Adopts the file: parses it, scaffolds the project, writes one value file per\n * variable and each attached comment into that parameter's meta, and backs the\n * source up. Validation is the caller's next step rather than part of adoption —\n * an inferred schema is a draft, and a draft that needs correcting has still\n * imported every value correctly.\n *\n * Adoption is all or nothing. Every name is checked against the config, and any\n * environment the source names resolved, before the tree is scaffolded or a\n * value written. The two names that fail here fail *destructively*: a reserved\n * name bricks every later command, and a lossy name renames the user's variable\n * behind their back. What the source names is resolved here rather than left to\n * the closing `validate` because a command that writes a tree and *then*\n * discovers it cannot name an environment has already half-adopted the project\n * it just refused. A half-imported tree would be the drift penv exists to\n * remove, introduced by penv itself.\n *\n * An environment nothing names is a different case, and not an error: an\n * unscoped import writes at the unscoped default, which needs no environment.\n * Only the validation that follows needs one, so it is skipped and said to be\n * skipped. Requiring one here would fail `penv import .env` on a greenfield\n * project — the first command the quickstart gives, where no environment could\n * plausibly be set yet — to satisfy a step that is the caller's next one.\n */\nexport function importDotenv(options: ImportOptions): ImportReport {\n const cwd = resolve(options.cwd);\n const file = isAbsolute(options.file) ? options.file : resolve(cwd, options.file);\n if (!existsSync(file)) {\n throw new PenvError(\n \"IMPORT_FILE_MISSING\",\n `There is no file at ${file} to import`,\n \"Point `penv import` at an existing dotenv file, e.g. `penv import .env`.\",\n );\n }\n\n const parsed = parseDotenv(readFileSync(file, \"utf8\"));\n const { config, decisions } = configInEffect(cwd, environmentNamed(file, options.environment));\n const source = displayPath(cwd, file);\n\n const named = scopeFromFilename(file, config);\n const derived = environmentOf(named);\n // Absent means the unscoped default; present-but-blank is refused, never\n // normalized into absent.\n const explicit =\n options.environment === undefined ? undefined : explicitEnvironment(options, source, config);\n assertEnvironmentAgrees(derived, explicit, source);\n // `--env` must reach the scope, not just the environment: reading it into the\n // environment alone is what wrote a production secret to the unscoped default.\n // Invariant 10 first — an undeclared `--env` names no scope to write at.\n const scope =\n explicit === undefined ? named : scopeWithEnvironment(named, assertDeclared(explicit, config));\n // The filename is an environment the user has already stated, so `penv import\n // .env.production` needs no `--env` to mean production. Nothing naming one is\n // the unscoped default's ordinary case, not a failure — the values still have\n // a scope to be written at, and only the closing validate goes without.\n const environment = lookupEnvironment(config, explicit ?? derived);\n\n const refs = refsForEntries(parsed.entries, source, config);\n assertNoCollisions(refs, config);\n\n // Every check has passed, so from here the import runs to completion.\n // The decisions the config was written from, not the defaults: the two halves\n // of one scaffold must not disagree about where the schema lives.\n const steps = scaffold(cwd, draftFields(parsed.entries), true, decisions);\n const project = openProject(cwd);\n const tree = localTree(project);\n\n // A comment sitting directly above a variable describes it, so it becomes that\n // parameter's meta description and `generate` re-emits it as a comment.\n writeEntries(tree, parsed.entries, refs, scope);\n\n const backup = `${file}${BACKUP_SUFFIX}`;\n copyFileSync(file, backup);\n\n return {\n root: project.root,\n file,\n backup,\n scope,\n environment,\n environments: environmentNames(config),\n variables: parsed.entries.length,\n orphanComments: parsed.orphanComments,\n steps,\n };\n}\n\nfunction displayPath(root: string, file: string): string {\n const rel = relative(root, file);\n return rel === \"\" || rel.startsWith(\"..\") ? file : rel.split(\"\\\\\").join(\"/\");\n}\n\n/**\n * Invariant 2 kept the user's `env.ts`; invariant 13 says so out loud.\n *\n * `penv init` then `penv import` is the ordinary path, and it lands here: the\n * schema penv scaffolded is an empty `z.object({})`, the draft that would have\n * declared the imported parameters is not written, and the closing `validate`\n * passes — an empty object validates against an empty schema. A ✓ on that line\n * reports a project where nothing is declared as a project that is fine.\n *\n * The count is every imported parameter, because penv declared none of them: it\n * did not write the draft, and it does not read the user's schema to guess which\n * ones they had already declared themselves.\n */\nfunction keptSchemaStep(step: InitStep, variables: number): Step {\n const plural = variables === 1 ? \"parameter\" : \"parameters\";\n return {\n glyph: WARN,\n // The step's own text, which names the file that was actually kept. This\n // line rebuilt it from a hardcoded `.penv/env.ts`, so a project whose schema\n // lives in `src/` was told penv had kept a file it does not have — the one\n // line whose whole job is \"your schema is untouched\" naming the wrong\n // schema. Only the glyph and the note are this function's business.\n text: step.text,\n note: `(yours — ${variables} imported ${plural} undeclared, draft schema skipped)`,\n };\n}\n\n/**\n * Invariant 13: the validation that did not run says so.\n *\n * A skipped check and a passed check must never look alike — the import wrote\n * every value, so a silent skip would read as a validated tree. The remedy names\n * a declared environment because the user has not chosen one yet; that is the\n * whole reason this line exists.\n */\nfunction skippedValidationStep(environments: readonly string[]): Step {\n const example = environments[0] ?? \"<environment>\";\n return {\n glyph: WARN,\n text: \"Skipped validation\",\n note: `(no environment set — run \\`penv validate --env ${example}\\`)`,\n };\n}\n\nexport function renderImport(\n result: ImportReport,\n validation: ValidateResult | undefined,\n): string[] {\n const steps: Step[] = [{ glyph: CHECK, text: `Found ${result.variables} variables` }];\n\n // Dropped, but never silently: a comment attached to nothing has no parameter\n // to belong to, and how many there were is the user's to know.\n if (result.orphanComments > 0) {\n const plural = result.orphanComments === 1 ? \"comment\" : \"comments\";\n steps.push({\n glyph: WARN,\n text: `Dropped ${result.orphanComments} orphan ${plural}`,\n note: \"attached to no variable, so nothing to describe\",\n });\n }\n\n for (const step of result.steps) {\n if (step.target === \"schema\" && step.action === \"kept\") {\n steps.push(keptSchemaStep(step, result.variables));\n continue;\n }\n // A conflicted step is the one init reports that is not a success — the same\n // reason it wears a warning there.\n const glyph = step.action === \"conflicted\" ? WARN : CHECK;\n steps.push(\n step.note === undefined\n ? { glyph, text: step.text }\n : { glyph, text: step.text, note: step.note },\n );\n }\n steps.push({ glyph: CHECK, text: `Created ${displayPath(result.root, result.backup)}` });\n\n const lines = formatSteps(steps);\n if (validation === undefined) {\n lines.push(...formatSteps([skippedValidationStep(result.environments)]));\n } else if (validation.ok) {\n lines.push(...formatSteps([{ glyph: CHECK, text: \"Validated configuration\" }]));\n } else {\n lines.push(...renderValidate(validation));\n }\n\n lines.push(\"\", \"Done. The records tree is now your source of truth.\");\n return lines;\n}\n\nexport const importCommand = defineCommand({\n meta: {\n name: \"import\",\n description: \"Import an existing dotenv file; it becomes the source of truth\",\n },\n args: {\n file: {\n type: \"positional\",\n required: true,\n description: \"The dotenv file to import, e.g. .env\",\n },\n env: {\n type: \"string\",\n description:\n \"The environment these are the values of; scopes them to it. The filename supplies it \" +\n \"when it carries one\",\n },\n },\n run({ args }) {\n return guard(async () => {\n const cwd = process.cwd();\n const report = importDotenv({\n cwd,\n file: args.file,\n ...(args.env === undefined ? {} : { environment: args.env }),\n });\n // The environment `import` already resolved, so the closing validate cannot\n // target a different one than the values were just written for. Without one\n // there is nothing to validate against, and the render says it was skipped.\n const validation =\n report.environment === undefined\n ? undefined\n : await runValidate({ cwd, environment: report.environment });\n write(renderImport(report, validation));\n });\n },\n});\n","/**\n * Turning dotenv variables into penv records — the checks that must pass before\n * a single value file is written, and the write itself.\n *\n * Two commands adopt: `penv import` takes one file, `penv init` takes a whole\n * cascade in one all-or-nothing cutover. They share this module because the two\n * names that fail here fail *destructively* — a reserved name bricks every later\n * command, and a lossy name renames the user's variable behind their back — and\n * two implementations of \"is this variable adoptable\" would eventually let one\n * command write what the other refuses.\n *\n * Import creates flat parameters. `refFromVariable` never infers a namespace,\n * because a flat `.env` carries no structure to read: `REDIS_PASSWORD` cannot say\n * whether it came from `redis/password` or `redis-password`. Namespacing is a\n * deliberate refactor afterwards, not a guess made during adoption.\n */\n\nimport type { DotenvEntry, Meta, ParameterRef, PenvConfig, Scope } from \"@penvhq/core\";\nimport {\n checkNameCollisions,\n isReservedToken,\n PenvError,\n ReservedTokenError,\n refFromVariable,\n roundTripsCleanly,\n variableName,\n} from \"@penvhq/core\";\nimport type { FilesystemProvider } from \"@penvhq/provider-filesystem\";\n\n/**\n * Filenames are split on `.`, so a variable that becomes a dotted name would\n * parse back as a scope segment rather than the parameter it came from.\n */\nfunction assertImportable(ref: ParameterRef, variable: string): void {\n if (!ref.name.includes(\".\")) {\n return;\n }\n throw new PenvError(\n \"IMPORT_UNPARSEABLE_NAME\",\n `The variable ${variable} becomes the parameter \\`${ref.name}\\`, whose \\`.\\` would be read as a scope`,\n `Filenames are split on \\`.\\`. Rename ${variable} in the source file, then import it again.`,\n );\n}\n\n/**\n * Invariant 11: `enc`, `json`, `toml`, `yml`, `local`, and every declared\n * environment are reserved, and a collision is an error rather than a warning.\n *\n * A written `.penv/state/records/enc` does not merely import badly — it re-parses as a scope\n * segment, so every later `list()` throws and `get`, `generate`, `validate`, and\n * even `remove` stop working. The project can only be repaired by deleting the\n * file by hand, which is why this runs before anything is written rather than\n * leaving `penv validate` to report the wreckage afterwards.\n *\n * The error names the *variable*, not the parameter: the user is reading their\n * `.env`, where the line says `ENC=`, and `enc` is penv's word for it.\n */\nfunction assertNotReserved(\n ref: ParameterRef,\n variable: string,\n where: string,\n config: PenvConfig,\n): void {\n if (isReservedToken(ref.name, config)) {\n throw new ReservedTokenError(\"parameter\", variable, where);\n }\n}\n\n/**\n * The v0.1 gate: every variable survives `import` then `generate` unchanged,\n * *modulo declared name overrides*.\n *\n * `MY-VAR` imports to the parameter `my-var` and regenerates as `MY_VAR`, so the\n * application's `process.env[\"MY-VAR\"]` reads `undefined` after a round trip. A\n * flat `.env` cannot tell `MY-VAR` from `MY_VAR` once both collapse to one\n * parameter, so no escape scheme rescues it — the honest move is to refuse. An\n * explicit `override` entry is the exception the gate allows: it makes the\n * generated name a stated decision instead of an accident. Silence does not.\n */\nfunction assertRoundTrips(ref: ParameterRef, variable: string, config: PenvConfig): void {\n if (roundTripsCleanly(variable)) {\n return;\n }\n // The declared override the gate's \"modulo\" clause means. Checked against the\n // real transform, so an override that does not actually restore the variable\n // is not mistaken for one that does.\n if (variableName(ref, config) === variable) {\n return;\n }\n const generated = variableName(ref, config);\n throw new PenvError(\n \"IMPORT_LOSSY_NAME\",\n `The variable ${variable} becomes the parameter \\`${ref.name}\\`, which regenerates as ${generated}`,\n `\\`penv generate\\` would write ${generated}, so anything reading ` +\n `\\`process.env[\"${variable}\"]\\` would read \\`undefined\\`. Declare the name you want in the ` +\n `\\`override\\` block of penv.config.ts — \\`override: { \"${ref.name}\": \"${variable}\" }\\` — then ` +\n `import it again. Nothing was imported.`,\n );\n}\n\n/**\n * Every entry's parameter, with every name check already passed — or the first\n * refusal, thrown before anything is written. `where` is the source as the user\n * typed it, because that is the file they will go and edit.\n */\nexport function refsForEntries(\n entries: readonly DotenvEntry[],\n where: string,\n config: PenvConfig,\n): ParameterRef[] {\n const refs: ParameterRef[] = [];\n for (const entry of entries) {\n const ref = refFromVariable(entry.key);\n assertImportable(ref, entry.key);\n assertNotReserved(ref, entry.key, where, config);\n assertRoundTrips(ref, entry.key, config);\n refs.push(ref);\n }\n return refs;\n}\n\n/** Invariant 12: two parameters mapping to one variable is an error, never last-write-wins. */\nexport function assertNoCollisions(refs: readonly ParameterRef[], config: PenvConfig): void {\n const first = checkNameCollisions(refs, config)[0];\n if (first !== undefined) {\n throw first;\n }\n}\n\n/**\n * Writes one file's variables into the tree at `scope`, with each attached\n * comment becoming that parameter's meta description so `penv generate` can\n * re-emit it.\n */\nexport function writeEntries(\n tree: FilesystemProvider,\n entries: readonly DotenvEntry[],\n refs: readonly ParameterRef[],\n scope: Scope,\n): void {\n for (const [index, entry] of entries.entries()) {\n const ref = refs[index];\n if (ref === undefined) {\n continue;\n }\n tree.writeSync(\n { namespace: ref.namespace, name: ref.name, scope, encrypted: false },\n entry.value,\n );\n if (entry.description !== undefined) {\n const meta: Meta = { ...tree.readMetaSync(ref), description: entry.description };\n tree.writeMetaSync(ref, meta);\n }\n }\n}\n","/**\n * What the codebase already says about itself.\n *\n * `penv init` asks a human to confirm a plan, and a plan the human has to fill\n * in from scratch is an interrogation. So penv reads the two facts it can\n * observe — the framework in `package.json`, and whether a `src/` directory\n * exists — and offers them as a suggestion.\n *\n * The line this module does not cross: a framework is an identity, never a\n * config key. Nothing here is written to `penv.config.ts` as `framework: \"next\"`\n * — the answers become concrete decisions (`schemaFile`, `publicPrefixes`) that\n * mean the same thing in a year, when the project has been rewritten twice and\n * penv would otherwise still be reinterpreting a name it read once.\n *\n * Everything here is a suggestion. The one thing that is never suggested is an\n * environment: deployment topology is not in `package.json`, and invariant 10\n * forbids inferring it.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { DEFAULT_SCHEMA_FILE } from \"@penvhq/core\";\n\n/** A framework penv recognised, and what it implies about a project's layout. */\nexport interface Detected {\n /** The framework's own name, as a human writes it — `\"Next.js\"`. */\n readonly name: string;\n /** Where this framework's projects keep their modules, relative to the root. */\n readonly schemaFile: string;\n /**\n * The conventional path penv stepped aside from, because a module that is not\n * penv's schema already lives there. Set only when it happened, so the plan can\n * say why the schema is not where the convention would have put it.\n */\n readonly displacedFrom?: string;\n /** The prefixes this framework inlines into its client bundle. */\n readonly publicPrefixes: readonly string[];\n}\n\n/**\n * One framework's signature. `packages` is checked against dependencies and\n * devDependencies alike: a framework is a framework wherever it was installed,\n * and the two lists disagree often enough that reading one is reading half.\n */\ninterface Signature {\n readonly name: string;\n readonly packages: readonly string[];\n readonly publicPrefixes: readonly string[];\n}\n\n/**\n * Ordered most specific first: TanStack Start is Vite underneath and Next.js\n * projects carry Vite for their tests, so a signature that matches a framework's\n * *foundation* must never answer before the framework itself does.\n *\n * Remix and React Router 7 are deliberately absent. Their public-variable story\n * is not one prefix, and a guess here is worse than the fallback: the fallback\n * is reported and asks, while a wrong prefix silently arms the one `doctor`\n * check that exists to keep a secret out of a browser bundle.\n */\nconst SIGNATURES: readonly Signature[] = [\n { name: \"Next.js\", packages: [\"next\"], publicPrefixes: [\"NEXT_PUBLIC_\"] },\n { name: \"SvelteKit\", packages: [\"@sveltejs/kit\"], publicPrefixes: [\"PUBLIC_\"] },\n { name: \"Nuxt\", packages: [\"nuxt\"], publicPrefixes: [\"NUXT_PUBLIC_\"] },\n {\n name: \"TanStack Start\",\n packages: [\"@tanstack/react-start\", \"@tanstack/start\"],\n publicPrefixes: [\"VITE_\"],\n },\n { name: \"Astro\", packages: [\"astro\"], publicPrefixes: [\"PUBLIC_\"] },\n { name: \"Vite\", packages: [\"vite\"], publicPrefixes: [\"VITE_\"] },\n];\n\n/**\n * Whether the module at `file` looks like it exports penv's schema.\n *\n * A scan, not a parse, and deliberately conservative in one direction: it can\n * fail to recognise an exotic re-export and say \"no\", which costs a note and a\n * different filename. It cannot invent a `schema` that is not written down, so it\n * never claims someone else's module is penv's.\n *\n * The question this answers is not \"does the file exist\". `src/env.ts` existing\n * is the common case on a re-run — it is the schema penv wrote, and keeping it is\n * invariant 2 working. The question is whether the file at the path penv wants is\n * *penv's*, because the alternative is penv choosing a path already occupied by\n * someone else's module and then reporting, later and from somewhere else, that\n * it exports no schema.\n */\nfunction exportsSchema(file: string): boolean {\n let source: string;\n try {\n source = readFileSync(file, \"utf8\");\n } catch {\n return false;\n }\n return (\n // `export const schema = z.object({ ... })` — what penv scaffolds.\n /export\\s+(?:const|let|var)\\s+schema\\b/.test(source) ||\n // `export { schema }`, `export { shape as schema }`.\n /export\\s*\\{[^}]*\\bschema\\b[^}]*\\}/.test(source)\n );\n}\n\n/** True when something that is not penv's schema already lives at `relative`. */\nfunction occupied(cwd: string, relative: string): boolean {\n const file = join(cwd, ...relative.split(\"/\"));\n return existsSync(file) && !exportsSchema(file);\n}\n\n/**\n * Where a framework's projects keep the schema — and where penv puts it instead\n * when that address is already someone else's.\n *\n * `src/env.ts` is the convention and it is also a name projects already use for\n * their own env module. Proposing it regardless is how penv came to scaffold\n * around a file it could not use: it kept the user's module (invariant 2, right),\n * then `validate` failed with \"src/env.ts exports no `schema`\" — a complaint\n * about a path penv itself had chosen.\n *\n * Stepping aside is not a guess. The file being there, and not exporting a\n * schema, is a fact about the codebase — the kind penv may default from, because\n * a wrong answer is visible in the plan and writes nothing over anything.\n */\nexport function schemaFileFor(cwd: string): { file: string; displaced?: string } {\n const dir = srcPrefix(cwd);\n const preferred = `${dir}env.ts`;\n if (!occupied(cwd, preferred)) {\n return { file: preferred };\n }\n\n const beside = `${dir}penv-env.ts`;\n if (!occupied(cwd, beside)) {\n return { file: beside, displaced: preferred };\n }\n // Both names taken by modules that are not penv's. `.penv/` is penv's own\n // directory, so it is the one address no other tool has a claim on.\n return { file: DEFAULT_SCHEMA_FILE, displaced: preferred };\n}\n\n/**\n * Every dependency name the manifest declares, or `undefined` when there is no\n * manifest to read. An unreadable or malformed `package.json` answers the same\n * way an absent one does — \"I cannot tell\" — because init's fallback is correct\n * and reported, while a parse error thrown from a suggestion would fail a\n * command that had not yet asked the user anything.\n */\n/**\n * `\"src/\"` when the project keeps its modules under `src/`, else `\"\"` — the one\n * fact both the schema location and a framework's seam file key off, read in one\n * place so the two cannot disagree about whether a project uses `src/`.\n */\nexport function srcPrefix(cwd: string): string {\n return existsSync(join(cwd, \"src\")) ? \"src/\" : \"\";\n}\n\nfunction dependenciesOf(cwd: string): ReadonlySet<string> | undefined {\n const manifest = manifestOf(cwd);\n if (manifest === undefined) {\n return undefined;\n }\n\n const names = new Set<string>();\n for (const field of [\"dependencies\", \"devDependencies\"] as const) {\n const block: unknown = manifest[field];\n if (block !== null && typeof block === \"object\" && !Array.isArray(block)) {\n for (const name of Object.keys(block)) {\n names.add(name);\n }\n }\n }\n return names;\n}\n\n/**\n * The project's manifest, or `undefined` when there is nothing readable to read.\n *\n * An absent or unparseable `package.json` is not an error here: detection's whole\n * contract is that it may answer \"I cannot tell\", and a project penv is asked to\n * scaffold before its manifest exists is a project, not a mistake.\n */\nfunction manifestOf(cwd: string): Readonly<Record<string, unknown>> | undefined {\n const file = join(cwd, \"package.json\");\n if (!existsSync(file)) {\n return undefined;\n }\n let manifest: unknown;\n try {\n manifest = JSON.parse(readFileSync(file, \"utf8\"));\n } catch {\n return undefined;\n }\n return manifest === null || typeof manifest !== \"object\" || Array.isArray(manifest)\n ? undefined\n : (manifest as Readonly<Record<string, unknown>>);\n}\n\n/**\n * The framework this project is built with, or `undefined` when penv cannot\n * tell. `undefined` is an answer, not a failure: init falls back to the default\n * schema path and says that it did.\n */\nexport function detectFramework(cwd: string): Detected | undefined {\n const dependencies = dependenciesOf(cwd);\n if (dependencies === undefined) {\n return undefined;\n }\n for (const signature of SIGNATURES) {\n if (signature.packages.some((name) => dependencies.has(name))) {\n return detectedFrom(cwd, signature.name, signature.publicPrefixes);\n }\n }\n // Bun is a runtime, not a package, so no dependency names it. A framework above\n // would have answered first (a Next-on-Bun project is a Next project); only a\n // project with no framework and a `bunfig.toml` is a plain Bun one, whose seam\n // is Bun's preload rather than Node's `--import`. It has no client bundle, so no\n // public prefix.\n if (existsSync(join(cwd, \"bunfig.toml\")) || dependencies.has(\"bun-types\")) {\n return detectedFrom(cwd, \"Bun\", []);\n }\n return undefined;\n}\n\nfunction detectedFrom(cwd: string, name: string, publicPrefixes: readonly string[]): Detected {\n const schema = schemaFileFor(cwd);\n return {\n name,\n schemaFile: schema.file,\n ...(schema.displaced === undefined ? {} : { displacedFrom: schema.displaced }),\n publicPrefixes,\n };\n}\n\n/** The alias penv writes when the project says nothing about how it names its own modules. */\nexport const DEFAULT_ALIAS = \"@env\";\n\n/** The alias for a project that already speaks Node's subpath imports. */\nexport const IMPORTS_ALIAS = \"#env\";\n\n/**\n * The alias to offer, read from how the project already refers to itself.\n *\n * The two forms are not interchangeable, and the difference is not taste:\n *\n * - `@env` is a `tsconfig.json` `paths` entry. TypeScript understands it and a\n * bundler resolves it. Plain `node dist/index.js` does not — `paths` is erased\n * by the compiler, so the emitted `import ... from \"@env\"` reaches Node as a\n * package that is not installed.\n * - `#env` is a `package.json` `imports` entry, which Node resolves natively and\n * every current bundler honours. It needs a modern `moduleResolution` for the\n * types to follow, which is why it is not simply the default.\n *\n * A project carrying an `imports` block has already answered the question, so\n * that is what is offered. Anything else gets `@env`, which is what the docs\n * describe and what a framework project wants. This is a suggestion either way:\n * the human confirms it, and the answer is written down as a decision.\n */\nexport function detectAlias(cwd: string): string {\n return hasImportsBlock(cwd) ? IMPORTS_ALIAS : DEFAULT_ALIAS;\n}\n\nfunction hasImportsBlock(cwd: string): boolean {\n const manifest = manifestOf(cwd);\n const imports = manifest?.imports;\n return imports !== null && typeof imports === \"object\" && !Array.isArray(imports);\n}\n","/**\n * The draft schema penv writes when it adopts a dotenv file.\n *\n * It is a draft and says so in the file it lands in: single-sample inference\n * cannot know that a boolean seen as `true` must also accept `1`, or that a\n * string is really a URL. penv scaffolds `penv.schema.ts` once and never\n * regenerates it (invariant 2), so every correction the reader makes is safe.\n *\n * Requiredness across several files is the one judgement here, and it is\n * deliberately coarse: a field observed in every adopted environment starts\n * required, and a field missing from any of them starts optional. That is not\n * per-environment requiredness — there is one schema, never one per environment\n * (invariant 1) — it is the weakest shape that every adopted environment\n * satisfies, which is what makes the first `penv run` after a cutover pass with\n * no edits.\n */\n\nimport type { DotenvEntry } from \"@penvhq/core\";\nimport { accessPath, refFromVariable } from \"@penvhq/core\";\n\n/** One schema field, rendered into `penv.schema.ts` as `<key>: <type>,`. */\nexport interface SchemaField {\n readonly key: string;\n /** The Zod expression, e.g. `z.url()` — `.optional()` already applied when it belongs. */\n readonly type: string;\n}\n\n/** A drafted field, plus the verdict a report prints. */\nexport interface DraftField extends SchemaField {\n readonly required: boolean;\n}\n\n/** A URL of any scheme — `postgres://` is as much a URL as `https://`. */\nconst URL_LIKE = /^[a-z][a-z0-9+.-]*:\\/\\/\\S+$/i;\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n/**\n * The Zod expression for one sampled value. Values arrive as strings, so a\n * schema that must accept them declares the coercion: `z.boolean()` would reject\n * the string `\"true\"` this very file just imported.\n */\nexport function inferType(value: string): string {\n if (URL_LIKE.test(value)) {\n return \"z.url()\";\n }\n if (/^(true|false)$/i.test(value)) {\n return \"z.stringbool()\";\n }\n if (value.trim() !== \"\" && Number.isFinite(Number(value))) {\n return \"z.coerce.number()\";\n }\n return \"z.string()\";\n}\n\n/** The schema key one variable becomes, quoted only when it has to be. */\nfunction keyFor(variable: string): string {\n const key = accessPath(refFromVariable(variable)).join(\".\");\n return IDENTIFIER.test(key) ? key : JSON.stringify(key);\n}\n\n/** Sorted, so the draft is identical on every machine. */\nfunction byKey<T extends SchemaField>(fields: T[]): T[] {\n return fields.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));\n}\n\n/** One file's variables as schema fields, all required — `penv import`'s single source. */\nexport function draftFields(entries: readonly DotenvEntry[]): SchemaField[] {\n return byKey(entries.map((entry) => ({ key: keyFor(entry.key), type: inferType(entry.value) })));\n}\n\n/**\n * One adopted file, and which environment its values reach. `environment` is\n * absent for the two unscoped scopes (`.env`, `.env.local`), whose values serve\n * every environment.\n */\nexport interface DraftSource {\n readonly environment?: string;\n readonly entries: readonly DotenvEntry[];\n}\n\ninterface Observed {\n readonly types: Set<string>;\n readonly environments: Set<string>;\n /** True when an unscoped file carries this variable, so every environment has it. */\n everywhere: boolean;\n}\n\n/**\n * The draft for a whole cutover: every variable any adopted file declares, typed\n * from what was seen and required only where every adopted environment has it.\n *\n * Two files disagreeing about a variable's type (`true` here, `8080` there)\n * collapse to `z.string()` rather than to whichever file was read first — a\n * drafted type that rejects a value the project already had would fail the first\n * run, which is the one thing this draft exists to avoid.\n */\nexport function draftFieldsAcross(\n sources: readonly DraftSource[],\n environments: readonly string[],\n): DraftField[] {\n const observed = new Map<string, Observed>();\n for (const source of sources) {\n for (const entry of source.entries) {\n const seen = observed.get(entry.key) ?? {\n types: new Set<string>(),\n environments: new Set<string>(),\n everywhere: false,\n };\n seen.types.add(inferType(entry.value));\n if (source.environment === undefined) {\n seen.everywhere = true;\n } else {\n seen.environments.add(source.environment);\n }\n observed.set(entry.key, seen);\n }\n }\n\n const fields: DraftField[] = [];\n for (const [variable, seen] of observed) {\n const required = seen.everywhere || environments.every((name) => seen.environments.has(name));\n const type = (seen.types.size === 1 ? [...seen.types][0] : undefined) ?? \"z.string()\";\n fields.push({ key: keyFor(variable), type: required ? type : `${type}.optional()`, required });\n }\n return byKey(fields);\n}\n","/**\n * `penv init` — scaffold a project, and adopt its dotenv files completely.\n *\n * A project with `.env` files gets a cutover: init lists every dotenv file it\n * found, the developer picks the ones penv takes, and then penv either takes all\n * of them or none. There is no half-adopted state, because a project whose\n * values live half in `.env` and half in penv has two truths about its own\n * configuration — the drift penv exists to delete, introduced by penv itself. So\n * everything is preflighted first: the selection, the environments it declares,\n * every variable name, the draft schema, the dependency install, and the\n * generated variable each parameter maps to. A failed preflight moves nothing,\n * writes nothing, and never reports partial success.\n *\n * Only after the imported values validate do the dotenv files move — into one\n * ignored `.penv/state/rollback/dotenv/` bundle, recorded in\n * `.penv/state/cutover.json`, which `penv init undo` restores by exact name and\n * `penv cleanup` drops.\n *\n * Every step is idempotent, and two of them are write-once on purpose: the\n * schema module is yours the moment it exists (invariant 2 — penv scaffolds it,\n * never regenerates it), and `penv.config.ts` is the environment whitelist you\n * declared. Re-running init reports what it kept rather than overwriting it.\n *\n * What init writes is a set of decisions, and the two kinds are kept apart. penv\n * may default what it can *observe* — the framework in `package.json`, whether\n * `src/` exists — because a wrong guess about the codebase is visible in the\n * codebase. It must ask for what it cannot observe: which environments exist is\n * deployment topology, it is nowhere on disk, and a project that carries a\n * `staging` penv invented is a project whose config is fiction (invariant 10).\n * Selecting `.env.production` is the developer declaring production; selecting\n * `.env` alone declares nothing, and init asks which environment those values\n * are for rather than deciding.\n */\n\nimport { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\nimport type { DotenvDiagnostic, DotenvEntry, ParameterRef, Scope } from \"@penvhq/core\";\nimport {\n CUTOVER_PATH,\n DEFAULT_SCHEMA_FILE,\n environmentNames,\n isLegalEnvironmentName,\n loadConfigFrom,\n PENV_DIR,\n type PenvConfig,\n PenvError,\n parameterId,\n parseDotenv,\n RECORDS_PATH,\n RESERVED_TOKENS,\n ROLLBACK_DOTENV_PATH,\n renderStateGitignore,\n SCHEMA_SHAPE_FILE,\n STATE_GITIGNORE_PATH,\n schemaFileOf,\n validateConfig,\n validateSchemaFile,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { assertNoCollisions, refsForEntries, writeEntries } from \"../adopt.js\";\nimport { bundleDotenvFiles, bundleUnresolved, runUndo } from \"../cutover.js\";\nimport {\n DEFAULT_ALIAS,\n type Detected,\n detectAlias,\n detectFramework,\n srcPrefix,\n} from \"../detect.js\";\nimport type { DotenvFile } from \"../dotenv-files.js\";\nimport { cascadeFor, discoverDotenvFiles, environmentsDeclaredBy } from \"../dotenv-files.js\";\nimport type { DraftField, SchemaField } from \"../draft-schema.js\";\nimport { draftFieldsAcross } from \"../draft-schema.js\";\nimport type { InstallPlan, InstallRuntime } from \"../install.js\";\nimport {\n detectPackageManager,\n installedPackages,\n installWithPackageManager,\n planInstall,\n renderInstallPlan,\n} from \"../install.js\";\nimport { localTree, openProject, selfContainedSchemaModule } from \"../project.js\";\nimport { captureScaffold, restoreScaffold } from \"../scaffold-undo.js\";\nimport { type ScaffoldSeam, type Seam, seamFor } from \"../seams.js\";\nimport { out } from \"../style.js\";\nimport { CHECK, columns, formatSteps, guard, prompt, type Step, tip, WARN, write } from \"../ui.js\";\nimport type { ValidateResult } from \"./validate.js\";\nimport { checkEnvironment } from \"./validate.js\";\n\nexport const SCHEMA_FILE = \"env.ts\";\n\n/**\n * The shape module, at the project root beside `penv.config.ts`. It is pure — a\n * `z.object` and the type registration, no `load` — so importing it never loads\n * configuration, which is what lets a tooling config (drizzle-kit, a CI script)\n * import the one schema without a side effect instead of hand-inlining a second\n * `z.object` that drifts (invariant 2). `.penv/env.ts` is the thin wrapper that\n * re-exports it and calls `load`.\n *\n * Fixed at the root rather than following `schemaFile`: `schemaFile` names the\n * *wrapper* (see {@link writeEnvFile}), and the shape is the one file every\n * consumer derives from wherever the wrapper is kept.\n *\n * `schemaFile` stays on the wrapper `.penv/env.ts` rather than being pointed at\n * this shape module: the wrapper is what `load` runs, and the harvester\n * (loadSchema) reads one `schema` export from `schemaFile`, which the wrapper\n * re-exports. Neither module sits in the records tree, so the walker meets\n * neither.\n *\n * The path itself (`penv.schema.ts`, at the root) is core's — `watch` watches it,\n * the grammar excludes it, and one authority answers where it is.\n */\nexport { SCHEMA_SHAPE_FILE };\n\n/** The basename the wrapper imports the shape by, extension appended per {@link shapeSpecifier}. */\nconst SCHEMA_SHAPE_BASENAME = \"penv.schema\";\n\nexport const CONFIG_FILE = \"penv.config.ts\";\nexport const TSCONFIG_FILE = \"tsconfig.json\";\n\n/**\n * The alias forms penv can write, and the only two a specifier can take that is\n * not a package: `@name` resolves through tsconfig `paths`, `#name` through\n * package.json `imports`.\n */\nconst ALIAS_NAME = /^[@#][A-Za-z0-9_-]+$/;\n\n/** The prefix that means Node resolves the alias itself, with no bundler involved. */\nconst IMPORTS_PREFIX = \"#\";\n\nconst PACKAGE_FILE = \"package.json\";\n\n/** What init touched, so a caller can report it and a test can assert it. */\nexport type InitTarget =\n | \"penv-dir\"\n | \"schema\"\n | \"env\"\n | \"config\"\n | \"tsconfig\"\n | \"gitignore\"\n | \"seam\";\n/**\n * `conflicted` is the one that is not a success. penv wanted to write something,\n * found the user's file already saying something else about the same thing, and\n * left it alone — so the step is reported with a warning rather than a ✓, and the\n * text says what will not work until the user decides.\n *\n * `info` is a step penv did not perform automatically — a manual instruction (the\n * injection seam for a framework penv cannot scaffold), reported so the user\n * knows the one thing left to do.\n */\nexport type InitAction = \"created\" | \"kept\" | \"updated\" | \"conflicted\" | \"info\";\n\nexport interface InitStep {\n readonly target: InitTarget;\n readonly action: InitAction;\n /** The reported line, in the docs' voice. */\n readonly text: string;\n readonly note?: string;\n}\n\n/**\n * The answers init writes down. Every one of these is a decision a human either\n * made or consented to — never an identity penv recorded to reinterpret later.\n * There is deliberately no `framework` here: `schemaFile` and `publicPrefixes`\n * still mean exactly what they say after the project is rewritten in something\n * else, and `framework: \"next\"` would not.\n */\nexport interface InitDecisions {\n /** The whitelist. Empty unless a human named them — penv never infers one. */\n readonly environments: readonly string[];\n /**\n * The environment every command falls back to when `--env` is absent (seal 3).\n * Written only when the cutover adopted one — a declared decision, so the\n * whitelist rule is untouched, and CI keeps naming `--env` anyway.\n */\n readonly defaultEnvironment?: string;\n /** The schema module, relative to the project root, POSIX. */\n readonly schemaFile: string;\n /** The prefixes the framework inlines into its client bundle. */\n readonly publicPrefixes: readonly string[];\n /**\n * How the user's code names the schema module — `@env` or `#env`.\n *\n * Two forms, resolved by two different things: `@env` is a tsconfig `paths`\n * entry that a bundler resolves and plain Node does not, and `#env` is a\n * package.json `imports` entry that Node resolves itself. Which one a project\n * wants is a fact about the project, so penv reads what it already does and\n * offers that.\n */\n readonly alias: string;\n /**\n * Whether to inject the validated config into `process.env` for libraries that\n * read it directly, so `env.ts` loads with `{ inject: true }` and penv places\n * the framework's pre-app seam. Off by default and only ever turned on by an\n * explicit yes — a project that reads config only through `@env` gets none.\n */\n readonly inject: boolean;\n}\n\n/** What init would write with no further input: the defaults, and nothing invented. */\nexport const DEFAULT_DECISIONS: InitDecisions = {\n environments: [],\n inject: false,\n schemaFile: DEFAULT_SCHEMA_FILE,\n publicPrefixes: [],\n alias: DEFAULT_ALIAS,\n};\n\nexport interface InitResult {\n readonly root: string;\n readonly decisions: InitDecisions;\n readonly steps: readonly InitStep[];\n}\n\nexport interface InitOptions {\n readonly cwd: string;\n /** What to write. Omitted means the plan's defaults, as `--yes` takes them. */\n readonly decisions?: InitDecisions;\n /** The detected framework name, passed by the command so the seam step need not re-detect it. */\n readonly framework?: string;\n}\n\n/*\n * The plan: what penv observed, what it would write, and why.\n */\n\n/** Flags that decide without asking, so a script never meets a prompt. */\nexport interface InitFlags {\n /** `--schema <path>`. */\n readonly schema?: string;\n /** `--env`, already split. Absent means no answer; present means the answer. */\n readonly environments?: readonly string[];\n /** `--alias <name>`. */\n readonly alias?: string;\n /**\n * `--yes` on a project with nothing to adopt. It takes `development` and the\n * local provider — the machine the command was typed on, which is the one\n * environment penv can declare without claiming a deployment exists.\n */\n readonly yes?: boolean;\n}\n\nexport interface InitPlan {\n readonly detected: Detected | undefined;\n /** What init writes unless a human edits it. */\n readonly decisions: InitDecisions;\n /** Environments the `.env*` files on disk are evidence for. Offered, never taken. */\n readonly suggestedEnvironments: readonly string[];\n /** Why each decision is what it is. Printed — a fallback penv takes silently is a guess. */\n readonly notes: readonly string[];\n}\n\n/**\n * Names that look like an environment in a `.env` filename but are not one:\n * `.env.example` is documentation, and the grammar's reserved tokens are\n * scope markers. Suggesting either would put a name into the whitelist that no\n * value file can ever be scoped to.\n */\nconst NOT_ENVIRONMENTS: readonly string[] = [...RESERVED_TOKENS, \"example\", \"sample\", \"template\"];\n\n/**\n * The environments the project's own `.env*` files are evidence for.\n *\n * This is not inference: nothing here reaches `penv.config.ts` unless a human\n * reads the suggestion and presses Enter. Invariant 10 is about what penv\n * *declares*, and showing someone the filenames they wrote is not a declaration\n * — it is the difference between \"you seem to have a production\" and penv\n * quietly deciding that you do.\n */\nexport function suggestEnvironments(root: string): string[] {\n let entries: string[];\n try {\n entries = readdirSync(root);\n } catch {\n return [];\n }\n\n const found = new Set<string>();\n for (const entry of entries) {\n if (!entry.startsWith(\".env.\")) {\n continue;\n }\n const segments = entry.slice(\".env.\".length).split(\".\");\n // `.env.production.local` is production's file; `.env.local` names no\n // environment at all, and neither does anything with more segments left\n // over, which is a filename penv has no reading of.\n const withoutLocal = segments.at(-1) === \"local\" ? segments.slice(0, -1) : segments;\n const name = withoutLocal.length === 1 ? withoutLocal[0] : undefined;\n if (name === undefined || !isLegalEnvironmentName(name) || NOT_ENVIRONMENTS.includes(name)) {\n continue;\n }\n found.add(name);\n }\n // Sorted so the same project shows the same line on every machine: directory\n // order is the filesystem's answer, not the project's.\n return [...found].sort();\n}\n\n/** A flag that is present but says nothing is refused, never read as absent. */\nfunction emptyFlag(flag: \"schema\" | \"env\" | \"alias\"): PenvError {\n return new PenvError(\n \"INIT_FLAG_EMPTY\",\n `\\`--${flag}\\` was given without a value`,\n flag === \"schema\"\n ? \"Name the module that exports the schema, e.g. `--schema src/env.ts`, or drop the flag \" +\n `to use ${DEFAULT_SCHEMA_FILE}.`\n : \"Name the environment, e.g. `--env production`, or drop the flag to leave the whitelist \" +\n \"empty and declare it in penv.config.ts.\",\n );\n}\n\n/** One list of environment names, however it was written. */\nfunction splitEnvironments(value: string): string[] {\n return value\n .split(\",\")\n .map((name) => name.trim())\n .filter((name) => name.length > 0);\n}\n\n/**\n * `--env` as the whitelist it declares, or `undefined` when it was not given —\n * which is no answer, not an empty one. Repeatable and comma-separated both\n * work: `--env development --env production` and `--env development,production`\n * are the same answer, and a shell that made one of them awkward is not a reason\n * to have declared a different set of environments.\n */\nexport function environmentsFromFlag(flag: unknown): readonly string[] | undefined {\n if (flag === undefined) {\n return undefined;\n }\n const given = Array.isArray(flag) ? (flag as readonly unknown[]) : [flag];\n const names = given.flatMap((value) => splitEnvironments(String(value)));\n if (names.length === 0) {\n throw emptyFlag(\"env\");\n }\n return [...new Set(names)];\n}\n\n/**\n * The names init collected, as the record the config declares them in. Init only\n * ever scaffolds the local tree, so every entry is the string shorthand — a\n * remote backend is a decision the developer makes in the config, not one penv\n * invents from a name it was handed.\n */\nfunction environmentsRecord(names: readonly string[]): Record<string, string> {\n return Object.fromEntries(names.map((environment) => [environment, LOCAL_PROVIDER]));\n}\n\n/** The config the decisions describe, so core answers questions about it, not init. */\nfunction configOf(decisions: InitDecisions): PenvConfig {\n return {\n environments: environmentsRecord(decisions.environments),\n schemaFile: decisions.schemaFile,\n };\n}\n\n/**\n * The decisions this project already recorded, or `undefined` when it has none.\n *\n * Only the config init itself would write or keep — the one beside `root`, not\n * whatever `findConfigFile` turns up two directories above. A monorepo's root\n * config is not this package's declaration, and `writeConfigFile` has always\n * looked exactly here.\n *\n * A config that exists and cannot be read is an error rather than an absence.\n * Treating it as absent is how the re-run bug worked in the first place: penv\n * would decide the project had declared nothing, re-detect, and scaffold a\n * second schema beside the one already there.\n */\nfunction declaredIn(root: string): PenvConfig | undefined {\n const file = join(root, CONFIG_FILE);\n if (!existsSync(file)) {\n return undefined;\n }\n return loadConfigFrom(file);\n}\n\n/**\n * What penv observed and what it proposes to write. The notes are the point as\n * much as the decisions are: a project that ends up with `.penv/env.ts` because\n * detection failed must be told that detection failed, or the fallback is\n * indistinguishable from a choice penv made on their behalf.\n *\n * Precedence is the whole design in one list: a flag is the human deciding now, a\n * config is the human having decided already, and detection is a suggestion that\n * loses to both. Guess once, declare forever — so once `penv.config.ts` exists,\n * re-detection cannot move what it says. Re-running init on a project that\n * declared `src/lib/env.ts` used to scaffold a *second* schema at the detected\n * path, warn that its own correct alias pointed at the wrong file, and announce\n * that a project with a declared `production` had declared none.\n */\nexport function planInit(root: string, flags: InitFlags = {}): InitPlan {\n const declared = declaredIn(root);\n const detected = detectFramework(root);\n const notes: string[] = [];\n\n if (declared !== undefined) {\n notes.push(`${CONFIG_FILE} already exists — init keeps every decision it records.`);\n } else if (detected === undefined) {\n notes.push(\n `No framework detected in package.json — the schema goes to ${DEFAULT_SCHEMA_FILE}.`,\n );\n } else {\n notes.push(`Detected ${detected.name}.`);\n if (detected.displacedFrom !== undefined) {\n notes.push(\n `${detected.displacedFrom} is already a module of yours that exports no \\`schema\\`, so ` +\n `the schema goes to ${detected.schemaFile}. penv never writes over a file it did not ` +\n `write — delete yours and re-run if you want it there, or pass \\`--schema\\`.`,\n );\n }\n }\n\n // Flag, then what the project already declared, then detection. `schemaFileOf`\n // rather than `config.schemaFile`: a config that omits the key has still\n // answered — with the default — and re-detection must not move a schema that\n // is already sitting where the project says it is.\n const schemaFile =\n flags.schema === undefined\n ? declared !== undefined\n ? schemaFileOf(declared)\n : (detected?.schemaFile ?? DEFAULT_SCHEMA_FILE)\n : flags.schema.trim();\n if (flags.schema !== undefined) {\n if (schemaFile.length === 0) {\n throw emptyFlag(\"schema\");\n }\n // Every rule a committed path has to satisfy lives in core, so `--schema`\n // is judged by the same validator `penv validate` will judge the config by.\n // Refusing here is refusing before a file is written; refusing there is\n // refusing after the project already has one in the wrong place.\n const error = validateSchemaFile({ environments: {}, schemaFile })[0];\n if (error !== undefined) {\n throw error;\n }\n }\n\n const alias = flags.alias === undefined ? detectAlias(root) : flags.alias.trim();\n if (flags.alias !== undefined && alias.length === 0) {\n throw emptyFlag(\"alias\");\n }\n if (!ALIAS_NAME.test(alias)) {\n throw new PenvError(\n \"INIT_ALIAS_INVALID\",\n `\\`${alias}\\` is not an alias penv can write`,\n `An alias is \\`@name\\` — a tsconfig \\`paths\\` entry a bundler resolves — or \\`#name\\`, a ` +\n \"package.json `imports` entry Node resolves itself. Those are the two things a module \" +\n \"specifier can be that is not a package.\",\n );\n }\n // Only when penv worked it out. `--alias` needs no explanation of why penv\n // chose it, and this note would have explained a reason that was not true:\n // it fired on the *form* of the alias rather than on where it came from, so a\n // forced `#env` was told its own package.json had asked for it.\n if (flags.alias === undefined && alias.startsWith(IMPORTS_PREFIX)) {\n notes.push(\n `Your ${PACKAGE_FILE} declares \\`imports\\`, so the alias is \\`${alias}\\` — Node resolves it without a bundler.`,\n );\n }\n\n const suggestedEnvironments = suggestEnvironments(root);\n // `--yes` takes `development` and nothing else (PRD §6). It is the machine the\n // command was typed on rather than a claim that a deployment exists, which is\n // what separates it from the production/staging/preview it still never invents.\n const safeDefault = flags.yes === true && declared === undefined;\n const environments =\n flags.environments ??\n (declared === undefined ? undefined : environmentNames(declared)) ??\n (safeDefault ? [DEVELOPMENT] : []);\n const defaultEnvironment =\n declared?.defaultEnvironment ?? (safeDefault ? DEVELOPMENT : undefined);\n if (safeDefault) {\n notes.push(\n `\\`--yes\\` declares ${DEVELOPMENT} with the local provider — the one environment penv can ` +\n \"name without inventing a deployment.\",\n );\n }\n // The empty whitelist is worth a line only when it is still empty. A project\n // that declared `production` being told it has declared nothing is penv\n // reading its own config wrong out loud.\n if (environments.length === 0) {\n notes.push(\"No environments declared: penv does not infer them.\");\n if (suggestedEnvironments.length > 0) {\n notes.push(\n `Your \\`.env\\` files mention ${suggestedEnvironments.join(\", \")} — declare the ones you ` +\n `really deploy in ${CONFIG_FILE}, with a provider for each.`,\n );\n }\n }\n\n return {\n detected,\n decisions: {\n environments,\n // A recorded decision, carried forward so a re-run reports the project as\n // it is. `writeConfigFile` keeps an existing config either way.\n ...(defaultEnvironment === undefined ? {} : { defaultEnvironment }),\n // Injection is a choice about the app's needs, not something on disk — so\n // the plan defaults it off, and only the interactive prompt turns it on.\n inject: false,\n schemaFile,\n publicPrefixes: declared?.publicPrefixes ?? detected?.publicPrefixes ?? [],\n alias,\n },\n suggestedEnvironments,\n notes,\n };\n}\n\n/*\n * The prompt.\n *\n * A plan the human confirms, not an interrogation they answer: penv already\n * knows everything but the one fact it must not guess, so it shows the whole\n * page and asks once. The io is a parameter so the decision logic is a plain\n * function — the tests call it, they do not spawn a terminal.\n */\n\nexport interface PromptIo {\n readonly ask: (question: string) => Promise<string>;\n readonly write: (line: string) => void;\n}\n\n/** The plan as one screen. */\nexport function renderPlan(plan: InitPlan): string[] {\n const rows: string[][] = [];\n rows.push([\n ` ${out.dim(\"environments\")}`,\n plan.suggestedEnvironments.length === 0\n ? \"\"\n : out.cyan(`[${plan.suggestedEnvironments.join(\", \")}]`),\n out.dim(\n plan.suggestedEnvironments.length === 0\n ? \"← name them, or Enter to leave the whitelist empty\"\n : \"← from your .env files; edit, or Enter to accept\",\n ),\n ]);\n rows.push([\n ` ${out.dim(\"schemaFile\")}`,\n plan.decisions.schemaFile,\n plan.decisions.schemaFile === DEFAULT_SCHEMA_FILE\n ? \"\"\n : out.dim(`(default: ${DEFAULT_SCHEMA_FILE})`),\n ]);\n for (const prefix of plan.decisions.publicPrefixes) {\n rows.push([` ${out.dim(\"publicPrefix\")}`, prefix, \"\"]);\n }\n\n const headline = out.bold(\n plan.detected === undefined\n ? \"No framework detected in package.json.\"\n : `Detected ${plan.detected.name}.`,\n );\n return [headline, \"\", ...columns(rows), \"\"];\n}\n\nfunction environmentsHint(plan: InitPlan): string {\n return plan.suggestedEnvironments.length === 0\n ? prompt(\"environments\", \"comma-separated, Enter for none\")\n : prompt(\"environments\", 'Enter to accept, \"none\" for an empty whitelist');\n}\n\n/**\n * The plan, confirmed. `undefined` is the human declining, which is an outcome\n * and not a failure: nothing is written and the run says so.\n *\n * An answer that is neither yes nor no declines, because the two mistakes are\n * not symmetrical — a decline costs a re-run, while reading \"no thanks\" as\n * consent scaffolds a project someone said no to.\n */\nexport async function promptForDecisions(\n plan: InitPlan,\n io: PromptIo,\n): Promise<InitDecisions | undefined> {\n for (const line of renderPlan(plan)) {\n io.write(line);\n }\n\n const answer = (await io.ask(environmentsHint(plan))).trim();\n const environments =\n answer.length === 0\n ? plan.suggestedEnvironments\n : answer.toLowerCase() === \"none\"\n ? []\n : splitEnvironments(answer);\n // The confirmation has to be about what is actually written, so an edited\n // line is echoed before `Proceed?` rather than confirmed in the abstract.\n if (answer.length > 0) {\n io.write(\"\");\n io.write(\n environments.length === 0\n ? \" environments [] (declare them later in penv.config.ts)\"\n : ` environments [${environments.join(\", \")}]`,\n );\n io.write(\"\");\n }\n\n // `Proceed?` is asked FIRST, so the confirmation muscle-memory — Enter, then a\n // decline — still declines: a new question inserted above it would otherwise\n // eat the \"n\" and default Proceed to yes, scaffolding a project someone meant to\n // refuse. Injection is a refinement of a scaffold already agreed to, so it is\n // asked only after that yes — and never on a runtime injection cannot serve.\n const proceed = (await io.ask(prompt(\"Proceed?\", \"Y/n\"))).trim().toLowerCase();\n if (proceed.length > 0 && proceed !== \"y\" && proceed !== \"yes\") {\n return undefined;\n }\n const inject = seamKindFor(plan) === \"none\" ? false : await askInject(io);\n return { ...plan.decisions, environments, inject };\n}\n\n/** The seam kind for the plan's framework, so the prompt can skip a runtime injection cannot serve. */\nfunction seamKindFor(plan: InitPlan): Seam[\"kind\"] {\n return seamFor(plan.detected?.name, {\n alias: plan.decisions.alias,\n srcDir: plan.decisions.schemaFile.startsWith(\"src/\") ? \"src/\" : \"\",\n schemaFile: plan.decisions.schemaFile,\n }).kind;\n}\n\n/**\n * The injection question, implication-first: the developer reads what yes and no\n * each *do*, not a premise about libraries. Default is no.\n */\nasync function askInject(io: PromptIo): Promise<boolean> {\n io.write(\"\");\n io.write(\"Also inject your validated config into process.env?\");\n io.write(\" y libraries that read process.env directly (WorkOS, Prisma…) just work\");\n io.write(' n config stays available only through import { env } from \"@env\"');\n const answer = (await io.ask(prompt(\"inject\", \"y/N\"))).trim().toLowerCase();\n return answer === \"y\" || answer === \"yes\";\n}\n\n/*\n * Templates.\n */\n\nexport type { SchemaField };\n\nconst EMPTY_SCHEMA_BODY =\n \" // One key per parameter, e.g. `databaseUrl: z.url(),`. Nesting a key nests\\n\" +\n \" // the parameter: `redis: z.object({ password: z.string() })` is redis/password.\";\n\nconst DRAFT_HEADER =\n \"// DRAFT — generated from the dotenv values penv adopted, and yours to correct.\\n\" +\n \"// Inference from a sample cannot know that a boolean seen as `true` must also\\n\" +\n \"// accept `1`/`0`, or that a string is really a URL. A field every adopted\\n\" +\n \"// environment had starts required; one that was missing anywhere starts\\n\" +\n \"// optional. penv scaffolds this file once and never regenerates it, so edits\\n\" +\n \"// here are safe.\\n\";\n\n/**\n * `penv.schema.ts` — the shape, and nothing that loads. This is the side-effect\n * free half of the split: a `z.object` plus the type registration, so importing\n * it (or `z.infer<typeof schema>`) never touches configuration. Tooling that\n * needs the schema imports *this* — never a second `z.object` over the same\n * store, which is the drift invariant 2 exists to prevent.\n *\n * The draft header and the harvested fields land here, because this is where the\n * parameters live: `penv import` writes the shape it inferred into the shape\n * module, and `.penv/env.ts` wraps whatever it finds.\n */\nexport function renderSchemaShapeModule(fields: readonly SchemaField[], draft: boolean): string {\n const body =\n fields.length === 0\n ? EMPTY_SCHEMA_BODY\n : fields.map((field) => ` ${field.key}: ${field.type},`).join(\"\\n\");\n\n return (\n `${draft ? DRAFT_HEADER : \"\"}import { z } from \"zod\";\\n` +\n `\\n` +\n `// The shape — the one definition every consumer derives from. Import this (or\\n` +\n `// z.infer<typeof schema>) when you only need the type — tests, tooling — so you\\n` +\n `// don't trigger config loading. .penv/env.ts wraps it with load().\\n` +\n `export const schema = z.object({\\n${body}\\n});\\n` +\n `\\n` +\n `// Registers the schema's shape with penv's types (erased at runtime, so\\n` +\n `// nothing cycles). This is what makes \\`override\\` keys in penv.config.ts\\n` +\n `// autocomplete from this schema — a typo'd parameter id is a compile error.\\n` +\n `declare module \"@penvhq/core\" {\\n` +\n ` interface PenvSchemaShape {\\n` +\n ` readonly shape: z.infer<typeof schema>;\\n` +\n ` }\\n` +\n `}\\n`\n );\n}\n\n/**\n * The specifier `.penv/env.ts` imports the shape by, relative to wherever the\n * wrapper is kept. The shape is always at the project root, so this is the climb\n * back up to it: `.penv/env.ts` → `../penv.schema.js`, a root `env.ts` →\n * `./penv.schema.js`, `src/lib/env.ts` → `../../penv.schema.js`.\n *\n * The `.js` extension is deliberate, not a typo for the `.ts` file it names: a\n * relative import under `moduleResolution: node16`/`nodenext` must carry the\n * *output* extension, and TypeScript maps `penv.schema.js` back to\n * `penv.schema.ts` for the type. Bundler resolution accepts it too, so one\n * specifier is correct everywhere — an extensionless one would fail to resolve for\n * a project on nodenext.\n */\nfunction shapeSpecifier(schemaFile: string): string {\n const depth = schemaFile.split(\"/\").length - 1;\n const climb = depth === 0 ? \"./\" : \"../\".repeat(depth);\n return `${climb}${SCHEMA_SHAPE_BASENAME}.js`;\n}\n\n/**\n * `.penv/env.ts` — the thin wrapper. It imports the shape from\n * `penv.schema.ts`, re-exports it so a type-only consumer can reach the schema\n * through `@env` without loading, and calls `load`. This is the module the\n * `@env`/`#env` alias resolves to and the module `schemaFile` names, so\n * application code still `import { env } from \"@env\"` exactly as before.\n *\n * The re-export is what keeps the harvester (loadSchema) working unchanged: it\n * reads the `schema` export of `schemaFile`, and the wrapper has one.\n */\nexport function renderEnvModule(schemaFile: string, inject = false): string {\n const loadComment = inject\n ? \"// The loaded, validated values for the current environment. Import this in app\\n\" +\n \"// code. `inject: true` also copies the values into process.env, for libraries\\n\" +\n \"// that read process.env directly.\\n\"\n : \"// The loaded, validated values for the current environment. Import this in app\\n\" +\n \"// code. Importing it loads configuration and throws (naming the parameter and\\n\" +\n \"// environment) if anything required is missing or invalid.\\n\";\n const loadCall = inject\n ? \"export const env = load(schema, { inject: true });\\n\"\n : \"export const env = load(schema);\\n\";\n\n return (\n `import { load } from \"@penvhq/penv\";\\n` +\n `import { schema } from \"${shapeSpecifier(schemaFile)}\";\\n` +\n `\\n` +\n `// Re-exported so type-only consumers can import the shape through @env without\\n` +\n `// triggering config loading — the shape itself lives in ${SCHEMA_SHAPE_FILE}.\\n` +\n `export { schema };\\n` +\n `\\n` +\n loadComment +\n loadCall\n );\n}\n\n/** An environment name as an object key: bare where it is a legal identifier. */\nfunction entryKey(name: string): string {\n return /^[A-Za-z_$][\\w$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\n/**\n * The whitelist block. Empty is the honest answer to a question nothing on disk\n * can settle, so the comment carries what an empty file cannot: that penv left\n * it empty on purpose, and the exact shape of the entry that fills it in.\n */\nfunction renderEnvironments(decisions: InitDecisions): string {\n const shared =\n \" // Environments are a whitelist, and each entry is that environment's whole\\n\" +\n \" // declaration: which provider holds it, in that provider's own words, and\\n\" +\n \" // which key seals it. A segment is an environment only if it is named here.\\n\";\n if (decisions.environments.length === 0) {\n return (\n `${shared}` +\n \" // It starts empty because which environments you deploy is not something penv\\n\" +\n \" // can read off your codebase, and an environment you do not have is worse\\n\" +\n \" // than one you have not declared yet. Name yours:\\n\" +\n \" // environments: {\\n\" +\n ' // development: \"@penvhq/provider-filesystem\",\\n' +\n ' // production: { provider: \"@penvhq/provider-vault\", path: \"penv\", keySource: \"env\" },\\n' +\n \" // },\\n\" +\n \" environments: {},\\n\"\n );\n }\n const entries = decisions.environments\n .map((name) => ` ${entryKey(name)}: ${JSON.stringify(LOCAL_PROVIDER)},\\n`)\n .join(\"\");\n return (\n `${shared} // A provider that needs no fields is just its package name.\\n` +\n ` environments: {\\n${entries} },\\n`\n );\n}\n\n/** The config, carrying only the decisions that were actually made. */\nexport function renderConfigModule(decisions: InitDecisions): string {\n let body = renderEnvironments(decisions);\n\n // Seal 3: what turns `penv run --env development -- pnpm dev` into\n // `penv run -- pnpm dev`. A declared decision, so invariant 10 is untouched —\n // this is not `NODE_ENV`, a branch name or a filename being believed.\n if (decisions.defaultEnvironment !== undefined) {\n body +=\n \"\\n // The environment a command uses when `--env` is absent. A pipeline names\\n\" +\n \" // `--env` anyway: a deploy that leans on this is one edit from the wrong one.\\n\" +\n ` defaultEnvironment: ${JSON.stringify(decisions.defaultEnvironment)},\\n`;\n }\n\n // The default is written by not writing it: a key that restates the default is\n // noise the next reader has to check against the docs before they can ignore it.\n if (decisions.schemaFile !== DEFAULT_SCHEMA_FILE) {\n body +=\n \"\\n // The module that exports the schema. It is yours — penv scaffolds it once\\n\" +\n \" // and never regenerates it — so this says where you keep it.\\n\" +\n ` schemaFile: ${JSON.stringify(decisions.schemaFile)},\\n`;\n }\n if (decisions.publicPrefixes.length > 0) {\n const prefixes = decisions.publicPrefixes.map((prefix) => JSON.stringify(prefix)).join(\", \");\n body +=\n \"\\n // The prefixes your framework inlines into the browser bundle. `penv doctor`\\n\" +\n \" // reports a parameter your meta declares `secret: true` whose variable name\\n\" +\n \" // starts with one of these — penv is the only thing holding both facts.\\n\" +\n ` publicPrefixes: [${prefixes}],\\n`;\n }\n\n return `import { defineConfig } from \"@penvhq/penv\";\\n\\nexport default defineConfig({\\n${body}});\\n`;\n}\n\n/*\n * The tsconfig.json edit.\n *\n * The alias is inserted into the user's own file, so the file is scanned rather\n * than parsed and re-emitted: reformatting someone's tsconfig — dropping its\n * comments, resorting its keys — to add one path is not a minimal edit.\n */\n\nfunction skipTrivia(source: string, index: number): number {\n let i = index;\n for (;;) {\n const ch = source.charAt(i);\n if (ch === \" \" || ch === \"\\t\" || ch === \"\\n\" || ch === \"\\r\") {\n i += 1;\n continue;\n }\n if (ch === \"/\" && source.charAt(i + 1) === \"/\") {\n const end = source.indexOf(\"\\n\", i);\n i = end === -1 ? source.length : end + 1;\n continue;\n }\n if (ch === \"/\" && source.charAt(i + 1) === \"*\") {\n const end = source.indexOf(\"*/\", i + 2);\n i = end === -1 ? source.length : end + 2;\n continue;\n }\n return i;\n }\n}\n\n/** Index just past the closing quote of the string opening at `index`. */\nfunction endOfString(source: string, index: number): number {\n let i = index + 1;\n while (i < source.length) {\n const ch = source.charAt(i);\n if (ch === \"\\\\\") {\n i += 2;\n continue;\n }\n if (ch === '\"') {\n return i + 1;\n }\n i += 1;\n }\n return source.length;\n}\n\n/** Index just past the bracket matching the one at `index`. */\nfunction endOfBracket(source: string, index: number): number {\n const open = source.charAt(index);\n const close = open === \"{\" ? \"}\" : \"]\";\n let depth = 0;\n let i = index;\n while (i < source.length) {\n const ch = source.charAt(i);\n if (ch === '\"') {\n i = endOfString(source, i);\n continue;\n }\n if (ch === \"/\" && (source.charAt(i + 1) === \"/\" || source.charAt(i + 1) === \"*\")) {\n i = skipTrivia(source, i);\n continue;\n }\n if (ch === open) {\n depth += 1;\n i += 1;\n continue;\n }\n if (ch === close) {\n depth -= 1;\n i += 1;\n if (depth === 0) {\n return i;\n }\n continue;\n }\n i += 1;\n }\n return source.length;\n}\n\nfunction endOfValue(source: string, index: number): number {\n const ch = source.charAt(index);\n if (ch === '\"') {\n return endOfString(source, index);\n }\n if (ch === \"{\" || ch === \"[\") {\n return endOfBracket(source, index);\n }\n let i = index;\n while (i < source.length) {\n const c = source.charAt(i);\n if (c === \",\" || c === \"}\" || c === \"]\" || c === \"\\n\") {\n return i;\n }\n i += 1;\n }\n return source.length;\n}\n\ninterface Member {\n readonly valueStart: number;\n}\n\n/** The member named `key` directly inside the object whose `{` is at `open`. */\nfunction findMember(source: string, open: number, key: string): Member | undefined {\n const close = endOfBracket(source, open) - 1;\n let i = skipTrivia(source, open + 1);\n while (i < close) {\n if (source.charAt(i) !== '\"') {\n return undefined;\n }\n const keyEnd = endOfString(source, i);\n const name = source.slice(i + 1, keyEnd - 1);\n const colon = skipTrivia(source, keyEnd);\n if (source.charAt(colon) !== \":\") {\n return undefined;\n }\n const valueStart = skipTrivia(source, colon + 1);\n const valueEnd = endOfValue(source, valueStart);\n if (name === key) {\n return { valueStart };\n }\n let next = skipTrivia(source, valueEnd);\n if (source.charAt(next) === \",\") {\n next = skipTrivia(source, next + 1);\n }\n i = next;\n }\n return undefined;\n}\n\n/** The indentation of the line `index` sits on. */\nfunction lineIndent(source: string, index: number): string {\n const lineStart = source.lastIndexOf(\"\\n\", index) + 1;\n const match = /^[ \\t]*/.exec(source.slice(lineStart, index));\n return match?.[0] ?? \"\";\n}\n\n/** The file's own indentation unit, so the inserted line looks like its neighbours. */\nfunction indentUnit(source: string): string {\n const match = /\\n([ \\t]+)\"/.exec(source);\n return match?.[1] ?? \" \";\n}\n\nfunction insertMember(source: string, open: number, member: string, unit: string): string {\n const objectIndent = lineIndent(source, open);\n const entryIndent = objectIndent + unit;\n const close = endOfBracket(source, open) - 1;\n if (skipTrivia(source, open + 1) === close) {\n return `${source.slice(0, open + 1)}\\n${entryIndent}${member}\\n${objectIndent}${source.slice(close)}`;\n }\n return `${source.slice(0, open + 1)}\\n${entryIndent}${member},${source.slice(open + 1)}`;\n}\n\nfunction shapeError(what: string, target: string, alias: string): PenvError {\n return new PenvError(\n \"TSCONFIG_SHAPE\",\n `penv cannot add the \\`${alias}\\` path alias to tsconfig.json: ${what}`,\n `Add it by hand: \\`{ \"compilerOptions\": { \"paths\": { \"${alias}\": [\"${target}\"] } } }\\`.`,\n );\n}\n\nexport interface AliasEdit {\n readonly source: string;\n readonly changed: boolean;\n /**\n * What the alias already points at, when that is not penv's schema.\n *\n * The alias is how the user's code reaches penv, so an alias that resolves\n * somewhere else is not a small problem: `import { env } from \"@env\"` compiles,\n * runs, and hands back another module's export. Reporting \"kept the alias\"\n * because the *key* was present is how penv would say that was fine — a silent\n * seam, in the scaffolder of the tool whose subject is silent seams.\n *\n * Left as the user's, never rewritten: penv cannot tell a stale mapping from a\n * deliberate one, and the file is theirs.\n */\n readonly conflict?: string;\n}\n\n/**\n * `tsconfig.json` with the `@env` alias present, everything else untouched.\n * Already-aliased input comes back unchanged rather than gaining a duplicate.\n *\n * The alias is why the schema can live anywhere: application code imports\n * `@env`, and this line is the only thing that has to know where that is.\n */\nexport function insertEnvAlias(\n source: string,\n target: string = DEFAULT_SCHEMA_FILE,\n name: string = DEFAULT_ALIAS,\n): AliasEdit {\n const alias = `\"${name}\": [\"${target}\"]`;\n const root = skipTrivia(source, 0);\n if (source.charAt(root) !== \"{\") {\n throw shapeError(\"its contents are not a JSON object\", target, name);\n }\n\n const unit = indentUnit(source);\n const compilerOptions = findMember(source, root, \"compilerOptions\");\n if (compilerOptions === undefined) {\n return {\n source: insertMember(source, root, `\"compilerOptions\": { \"paths\": { ${alias} } }`, unit),\n changed: true,\n };\n }\n if (source.charAt(compilerOptions.valueStart) !== \"{\") {\n throw shapeError(\"`compilerOptions` is not an object\", target, name);\n }\n\n const paths = findMember(source, compilerOptions.valueStart, \"paths\");\n if (paths === undefined) {\n return {\n source: insertMember(source, compilerOptions.valueStart, `\"paths\": { ${alias} }`, unit),\n changed: true,\n };\n }\n if (source.charAt(paths.valueStart) !== \"{\") {\n throw shapeError(\"`compilerOptions.paths` is not an object\", target, name);\n }\n\n const existing = findMember(source, paths.valueStart, name);\n if (existing !== undefined) {\n // The key being present is not the question. Where it points is.\n const points = source.slice(existing.valueStart, endOfValue(source, existing.valueStart));\n return points.includes(`\"${target}\"`)\n ? { source, changed: false }\n : { source, changed: false, conflict: points.trim() };\n }\n return { source: insertMember(source, paths.valueStart, alias, unit), changed: true };\n}\n\n/**\n * `package.json` with the `#env` subpath import present, everything else untouched.\n *\n * The same scanning edit the tsconfig gets, for the same reason: a manifest is\n * the project's file, and rewriting it through `JSON.parse`/`stringify` to add\n * one key resorts nothing but reformats everything.\n *\n * `imports` is Node's own mechanism, so an alias written here needs no bundler to\n * resolve — which is the whole reason a project would choose it.\n */\nexport function insertImportsAlias(source: string, target: string, name: string): AliasEdit {\n const entry = `\"${name}\": \"./${target}\"`;\n const root = skipTrivia(source, 0);\n if (source.charAt(root) !== \"{\") {\n throw shapeError(\"its contents are not a JSON object\", target, name);\n }\n\n const unit = indentUnit(source);\n const imports = findMember(source, root, \"imports\");\n if (imports === undefined) {\n return { source: insertMember(source, root, `\"imports\": { ${entry} }`, unit), changed: true };\n }\n if (source.charAt(imports.valueStart) !== \"{\") {\n throw shapeError(\"`imports` is not an object\", target, name);\n }\n\n const existing = findMember(source, imports.valueStart, name);\n if (existing !== undefined) {\n const points = source.slice(existing.valueStart, endOfValue(source, existing.valueStart));\n return points.includes(`\"./${target}\"`)\n ? { source, changed: false }\n : { source, changed: false, conflict: points.trim() };\n }\n return { source: insertMember(source, imports.valueStart, entry, unit), changed: true };\n}\n\nfunction renderTsconfig(target: string, alias: string): string {\n return `{\\n \"compilerOptions\": {\\n \"paths\": { \"${alias}\": [\"${target}\"] }\\n }\\n}\\n`;\n}\n\n/*\n * The steps themselves. Each returns what it did so the caller reports it.\n */\n\nexport function ensurePenvDir(root: string): InitStep {\n const dir = resolve(root, PENV_DIR);\n if (existsSync(dir)) {\n return { target: \"penv-dir\", action: \"kept\", text: `Found ${PENV_DIR}/` };\n }\n mkdirSync(dir, { recursive: true });\n return { target: \"penv-dir\", action: \"created\", text: `Created ${PENV_DIR}/` };\n}\n\n/**\n * Invariant 2, first half: the shape module `penv.schema.ts` is scaffolded once\n * and never regenerated. It holds the parameters (and the draft `penv import`\n * infers), so an existing one is the user's schema — keeping it, rather than\n * overwriting it, is the whole point.\n */\nexport function writeSchemaShapeFile(\n root: string,\n fields: readonly SchemaField[],\n draft: boolean,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n): InitStep {\n const file = join(root, SCHEMA_SHAPE_FILE);\n if (existsSync(file)) {\n return {\n target: \"schema\",\n action: \"kept\",\n text: `Kept ${SCHEMA_SHAPE_FILE}`,\n note: \"(yours — penv never regenerates it)\",\n };\n }\n // A project scaffolded before the split keeps its `z.object` inside the module\n // `schemaFile` names (0.5+ also its `PenvSchemaShape` augmentation there), not\n // in a separate `penv.schema.ts`. Writing one now would stand a second, empty\n // `z.object` beside the real one — the second drifting schema invariant 2\n // forbids — and, for a 0.5+ layout, a duplicate `PenvSchemaShape` block that\n // fails to typecheck (TS2717). So the old file stays the one schema, and penv\n // says how to split it by hand rather than doing it destructively.\n const oldLayout = selfContainedSchemaModule(root, decisions.schemaFile);\n if (oldLayout !== undefined) {\n return {\n target: \"schema\",\n action: \"conflicted\",\n text: `Kept your schema in ${oldLayout}`,\n note:\n `(the shape lives there, from before the ${SCHEMA_SHAPE_FILE} split — penv did not add a ` +\n `second one. To adopt the split: move the \\`z.object\\` (and any \\`declare module\\` block) ` +\n `into ${SCHEMA_SHAPE_FILE}, leaving ${oldLayout} importing \\`schema\\` from it and calling \\`load\\`.)`,\n };\n }\n writeFileSync(file, renderSchemaShapeModule(fields, draft), \"utf8\");\n return {\n target: \"schema\",\n action: \"created\",\n text: `Generated ${SCHEMA_SHAPE_FILE}`,\n note: draft ? \"(draft schema — review it, it's yours)\" : \"(the shape — yours to edit)\",\n };\n}\n\n/**\n * Invariant 2, second half: the wrapper `.penv/env.ts` is scaffolded once and\n * never regenerated either. It is the module the alias resolves to and the\n * module `schemaFile` names, so it goes wherever the decisions put it — the\n * default `.penv/env.ts`, or a framework's `src/env.ts`. An existing one is the\n * user's, whatever penv would have written, and that holds at any path.\n */\nexport function writeEnvFile(root: string, decisions: InitDecisions = DEFAULT_DECISIONS): InitStep {\n const file = join(root, ...decisions.schemaFile.split(\"/\"));\n if (existsSync(file)) {\n return {\n target: \"env\",\n action: \"kept\",\n text: `Kept ${decisions.schemaFile}`,\n note: \"(yours — penv never regenerates it)\",\n };\n }\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, renderEnvModule(decisions.schemaFile, decisions.inject), \"utf8\");\n return {\n target: \"env\",\n action: \"created\",\n text: `Generated ${decisions.schemaFile}`,\n note: \"(loads the shape — yours to edit)\",\n };\n}\n\nexport function writeConfigFile(\n root: string,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n): InitStep {\n const file = join(root, CONFIG_FILE);\n if (existsSync(file)) {\n return { target: \"config\", action: \"kept\", text: `Kept ${CONFIG_FILE}` };\n }\n writeFileSync(file, renderConfigModule(decisions), \"utf8\");\n return { target: \"config\", action: \"created\", text: `Generated ${CONFIG_FILE}` };\n}\n\nexport function writeTsconfigAlias(\n root: string,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n): InitStep {\n const alias = decisions.alias;\n // `#env` is Node's mechanism and lives in the manifest; `@env` is TypeScript's\n // and lives in the tsconfig. Writing one into the other's file produces a key\n // nothing reads — the alias would simply never resolve, and penv would have\n // reported writing it.\n const imports = alias.startsWith(IMPORTS_PREFIX);\n const file = join(root, imports ? PACKAGE_FILE : TSCONFIG_FILE);\n const where = imports ? PACKAGE_FILE : TSCONFIG_FILE;\n\n if (!existsSync(file)) {\n // A project with no manifest is not one penv invents a manifest for: the\n // manifest is the project's identity, and `imports` is a key on something\n // that already exists. A tsconfig penv can honestly create from nothing.\n if (imports) {\n return {\n target: \"tsconfig\",\n action: \"conflicted\",\n text: `No ${PACKAGE_FILE} to add the ${alias} import to`,\n note: `(run \\`npm init\\` first, or use \\`--alias @env\\` to alias through ${TSCONFIG_FILE})`,\n };\n }\n writeFileSync(file, renderTsconfig(decisions.schemaFile, alias), \"utf8\");\n return {\n target: \"tsconfig\",\n action: \"created\",\n text: `Created ${TSCONFIG_FILE} with the ${alias} path alias`,\n };\n }\n\n const source = readFileSync(file, \"utf8\");\n const edit = imports\n ? insertImportsAlias(source, decisions.schemaFile, alias)\n : insertEnvAlias(source, decisions.schemaFile, alias);\n\n if (edit.conflict !== undefined) {\n return {\n target: \"tsconfig\",\n action: \"conflicted\",\n text: `${where} already maps ${alias} to ${edit.conflict}`,\n note: `(left alone — \\`import { env } from \"${alias}\"\\` will not reach ${decisions.schemaFile})`,\n };\n }\n if (!edit.changed) {\n return {\n target: \"tsconfig\",\n action: \"kept\",\n text: `Kept the ${alias} alias in ${where}`,\n };\n }\n writeFileSync(file, edit.source, \"utf8\");\n return {\n target: \"tsconfig\",\n action: \"updated\",\n text: `Added ${alias} alias to ${where}`,\n };\n}\n\n/**\n * The ignore file lives at the top of `state/`, over everything penv manages:\n * penv owns it outright, so it is rewritten when it drifts. A weakened ignore\n * file is how a plaintext secret gets committed, which invariant 20 exists to\n * prevent.\n */\nexport function writeGitignore(\n root: string,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n): InitStep {\n const file = join(root, ...STATE_GITIGNORE_PATH.split(\"/\"));\n const wanted = renderStateGitignore(configOf(decisions));\n const existing = existsSync(file) ? readFileSync(file, \"utf8\") : undefined;\n if (existing === wanted) {\n return { target: \"gitignore\", action: \"kept\", text: `Kept ${STATE_GITIGNORE_PATH}` };\n }\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, wanted, \"utf8\");\n return {\n target: \"gitignore\",\n action: existing === undefined ? \"created\" : \"updated\",\n text: `${existing === undefined ? \"Created\" : \"Updated\"} ${STATE_GITIGNORE_PATH}`,\n };\n}\n\n/** The first `@penvhq/penv` release whose `load` honours `{ inject: true }`. */\nconst INJECT_MIN_VERSION = \"0.6.0\";\n\n/**\n * A warning when the project's installed runtime is too old to honour\n * `{ inject: true }` — the option is ignored on an older `@penvhq/penv`, so the\n * seam would run and `process.env` would stay empty while init reported success.\n * `undefined` when the runtime is new enough, or absent (init may run before an\n * install, and penv does not warn about what it cannot see).\n */\nfunction outdatedRuntimeWarning(root: string): string | undefined {\n const version = installedPenvVersion(root);\n if (version === undefined || !isBelow(version, INJECT_MIN_VERSION)) {\n return undefined;\n }\n return `Injection needs @penvhq/penv ${INJECT_MIN_VERSION}+ — this project has ${version}, whose \\`load\\` ignores \\`{ inject: true }\\`. Upgrade, or process.env stays empty.`;\n}\n\nfunction installedPenvVersion(root: string): string | undefined {\n const file = join(root, \"node_modules\", \"@penvhq\", \"penv\", \"package.json\");\n if (!existsSync(file)) {\n return undefined;\n }\n try {\n const version = JSON.parse(readFileSync(file, \"utf8\")).version;\n return typeof version === \"string\" ? version : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** The `[major, minor, patch]` of a semver, pre-release tag ignored, missing parts zero. */\nfunction releaseTriple(version: string): [number, number, number] {\n const parts = (version.split(\"-\")[0] ?? \"\").split(\".\");\n const at = (i: number) => Number.parseInt(parts[i] ?? \"0\", 10) || 0;\n return [at(0), at(1), at(2)];\n}\n\n/** True when semver `a` is strictly below `b`, comparing the release triple. */\nfunction isBelow(a: string, b: string): boolean {\n const [am, an, ap] = releaseTriple(a);\n const [bm, bn, bp] = releaseTriple(b);\n if (am !== bm) return am < bm;\n if (an !== bn) return an < bn;\n return ap < bp;\n}\n\n/**\n * Places the injection seam for the detected framework — the file whose one\n * `import \"@env\"` runs before app code, so an injected `process.env` is populated\n * before a library reads it. penv scaffolds a fresh seam file, but never edits a\n * hook the user already owns: an existing file, or a framework with no file penv\n * can safely own, becomes a printed instruction instead. Returns nothing when\n * injection was not chosen. `framework` is passed by the command (which already\n * detected it) to avoid re-reading `package.json`; it falls back to detecting.\n */\nexport function writeSeam(\n root: string,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n framework: string | undefined = detectFramework(root)?.name,\n): InitStep | undefined {\n if (!decisions.inject) {\n return undefined;\n }\n const seam = seamFor(framework, {\n alias: decisions.alias,\n srcDir: srcPrefix(root),\n schemaFile: decisions.schemaFile,\n });\n\n // Regardless of the seam's shape, `env.ts` now carries `{ inject: true }`, so an\n // outdated runtime is the same silent no-op everywhere — warn once, here.\n const outdated = outdatedRuntimeWarning(root);\n\n if (seam.kind === \"none\") {\n return { target: \"seam\", action: \"info\", text: \"No injection seam needed\", note: seam.reason };\n }\n if (seam.kind === \"instruct\") {\n return {\n target: \"seam\",\n action: \"info\",\n text: \"Place the injection seam\",\n note: withWarning(seam.instruction, outdated),\n };\n }\n\n // A companion file the seam also needs (Bun's bunfig.toml). Same rule: write it\n // when absent, otherwise print where to add the entry. Its outcome joins the\n // seam step's note, so the whole setup is one line to read.\n const alsoNote = writeAlso(root, seam.also);\n\n const file = join(root, ...seam.file.split(\"/\"));\n const baseNotes = [...seam.notes, ...(alsoNote === undefined ? [] : [alsoNote])];\n const notes = baseNotes.length === 0 ? \"\" : `\\n${baseNotes.map((n) => ` ${n}`).join(\"\\n\")}`;\n if (existsSync(file)) {\n return {\n target: \"seam\",\n action: \"info\",\n text: `Add the injection seam to ${seam.file}`,\n note: withWarning(`${seam.ifPresent}${notes}`, outdated),\n };\n }\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, seam.content, \"utf8\");\n return {\n target: \"seam\",\n action: outdated === undefined ? \"created\" : \"info\",\n text: `Wrote ${seam.file} (runs the injection before your app)`,\n ...(notes === \"\" && outdated === undefined\n ? {}\n : { note: withWarning(notes.trimStart(), outdated) }),\n };\n}\n\n/**\n * The companion file (Bun's `bunfig.toml`), written when absent and reported as a\n * note; when present it is the user's, so the note tells them where to add the\n * entry rather than penv editing their config. `undefined` when there is none.\n */\nfunction writeAlso(root: string, also: ScaffoldSeam[\"also\"]): string | undefined {\n if (also === undefined) {\n return undefined;\n }\n const file = join(root, ...also.file.split(\"/\"));\n if (existsSync(file)) {\n return also.ifPresent;\n }\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, also.content, \"utf8\");\n return `Wrote ${also.file} to register it.`;\n}\n\n/** Appends a runtime warning to a seam note, when there is one. */\nfunction withWarning(note: string, warning: string | undefined): string {\n if (warning === undefined) {\n return note;\n }\n return note === \"\" ? warning : `${note}\\n ⚠ ${warning}`;\n}\n\n/** Everything `init` scaffolds, in the order it is reported. */\nexport function scaffold(\n root: string,\n fields: readonly SchemaField[],\n draft: boolean,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n framework: string | undefined = detectFramework(root)?.name,\n): InitStep[] {\n const steps = [\n ensurePenvDir(root),\n // The shape at the root, then the wrapper that loads it — both write-once.\n // The shape step needs the decisions too: an old-layout `schemaFile` already\n // holds the shape, and a second `penv.schema.ts` beside it would not compile.\n writeSchemaShapeFile(root, fields, draft, decisions),\n writeEnvFile(root, decisions),\n writeConfigFile(root, decisions),\n writeTsconfigAlias(root, decisions),\n writeGitignore(root, decisions),\n ];\n const seam = writeSeam(root, decisions, framework);\n return seam === undefined ? steps : [...steps, seam];\n}\n\n/**\n * Every path {@link scaffold} may write, so a failure after it can put the\n * project back exactly as it was. Listed here rather than discovered afterwards:\n * a rollback that guessed at what init touched would be a second answer to the\n * question this function already answers.\n */\nexport function scaffoldPaths(\n root: string,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n framework: string | undefined = detectFramework(root)?.name,\n): string[] {\n const fileAt = (relative: string): string => join(root, ...relative.split(\"/\"));\n const seam = decisions.inject\n ? seamFor(framework, {\n alias: decisions.alias,\n srcDir: srcPrefix(root),\n schemaFile: decisions.schemaFile,\n })\n : undefined;\n return [\n fileAt(PENV_DIR),\n fileAt(SCHEMA_SHAPE_FILE),\n fileAt(decisions.schemaFile),\n fileAt(CONFIG_FILE),\n fileAt(TSCONFIG_FILE),\n fileAt(PACKAGE_FILE),\n ...(seam?.kind === \"scaffold\"\n ? [fileAt(seam.file), ...(seam.also === undefined ? [] : [fileAt(seam.also.file)])]\n : []),\n ];\n}\n\n/*\n * The cutover.\n *\n * Everything from here down is all-or-nothing by construction: `planCutover`\n * reads and checks, `applyCutover` writes and moves, and nothing between them\n * decides anything. That split is what lets a preflight failure be a refusal\n * with no cleanup to do.\n */\n\n/** The environment `--yes` takes and the file list preselects. */\nexport const DEVELOPMENT = \"development\";\n\n/** The provider a scaffolded environment reads from until the project says otherwise. */\nconst LOCAL_PROVIDER = \"@penvhq/provider-filesystem\";\n\n/** One adopted file: what it holds, and the scope its values are written at. */\ninterface Adopted {\n readonly file: DotenvFile;\n readonly entries: readonly DotenvEntry[];\n readonly refs: readonly ParameterRef[];\n readonly scope: Scope;\n}\n\nexport interface AdoptionPlan {\n readonly root: string;\n /** Every dotenv file penv found, in the order the list shows them. */\n readonly found: readonly DotenvFile[];\n /** Checked when the list is first shown: the development cascade, where it exists. */\n readonly preselected: readonly string[];\n}\n\n/** What there is to adopt, and what penv proposes taking. */\nexport function planAdoption(root: string): AdoptionPlan {\n const found = discoverDotenvFiles(root);\n return {\n root,\n found,\n preselected: found\n .filter((file) => file.environment === undefined || file.environment === DEVELOPMENT)\n .map((file) => file.name),\n };\n}\n\n/** The scope a file's values are written at — invariant 4's four levels, unchanged. */\nfunction scopeOf(file: DotenvFile): Scope {\n if (file.kind === \"shared\") {\n return { kind: \"unscoped\" };\n }\n if (file.kind === \"local\") {\n return { kind: \"local\" };\n }\n const environment = file.environment ?? \"\";\n return file.kind === \"environment\"\n ? { kind: \"environment\", environment }\n : { kind: \"environment-local\", environment };\n}\n\nexport interface CutoverPlan {\n readonly root: string;\n readonly selected: readonly DotenvFile[];\n readonly adopted: readonly Adopted[];\n /** The whitelist after this cutover — what the config declares, or is about to. */\n readonly environments: readonly string[];\n /**\n * The environments this cutover is *about*: the ones its files name. Narrower\n * than the whitelist on a project that already declared more, and the ones the\n * draft is judged against and the import is validated for — an environment\n * this cutover did not touch must not fail it for a state it was already in.\n */\n readonly adopting: readonly string[];\n readonly decisions: InitDecisions;\n readonly fields: readonly DraftField[];\n readonly variables: number;\n /** Values the parser read but that look like a mistake. Shown, never fixed. */\n readonly diagnostics: readonly DotenvDiagnostic[];\n readonly install: InstallPlan;\n readonly framework: string | undefined;\n /** True when `penv.config.ts` already existed, so init keeps every decision it records. */\n readonly configured: boolean;\n}\n\nexport interface CutoverInput {\n readonly root: string;\n /** What init would scaffold anyway: detection, the schema's home, the alias. */\n readonly base: InitPlan;\n readonly selected: readonly DotenvFile[];\n /** The environment named when the selection declares none — `.env` alone declares nothing. */\n readonly environment?: string;\n /** The `@penvhq/penv` version to pin. Defaults to this engine's own. */\n readonly version?: string;\n readonly inject?: boolean;\n}\n\n/**\n * Everything a cutover needs, checked before anything is written.\n *\n * The order is the order the failures matter in: an unresolved bundle first\n * (there is nothing to plan on top of it), then what the selection declares,\n * then whether the selection is complete, then every variable name, and only\n * then the schema and the install. Each one throws, so the caller has a plan or\n * a refusal and never a half-answer.\n */\nexport function planCutover(input: CutoverInput): CutoverPlan {\n const { root, base } = input;\n assertBundleResolved(root);\n\n const selected = [...input.selected];\n if (selected.length === 0) {\n throw new PenvError(\n \"INIT_NOTHING_SELECTED\",\n \"No dotenv file was selected, so there is nothing to migrate\",\n \"Run `penv init` again and choose the files penv should adopt.\",\n );\n }\n\n const declared = declaredIn(root);\n const named = environmentsDeclaredBy(selected);\n const chosen = named.length > 0 ? named : [requireEnvironment(input)];\n const environments = declared === undefined ? chosen : environmentNames(declared);\n for (const environment of chosen) {\n if (!environments.includes(environment)) {\n throw new PenvError(\n \"INIT_ENVIRONMENT_UNDECLARED\",\n `${CONFIG_FILE} declares ${describeList(environments)}, and adopting these files needs \\`${environment}\\` declared too`,\n `Add \\`${environment}: \"${LOCAL_PROVIDER}\"\\` to \\`environments\\` in ${CONFIG_FILE}, or name the backend that holds it, then run \\`penv init\\` again. Nothing was changed.`,\n );\n }\n }\n\n const defaultEnvironment =\n declared === undefined ? proposedDefault(chosen) : declared.defaultEnvironment;\n const decisions: InitDecisions = {\n ...base.decisions,\n environments,\n ...(defaultEnvironment === undefined ? {} : { defaultEnvironment }),\n ...(input.inject === undefined ? {} : { inject: input.inject }),\n };\n\n // The config init is about to write, judged by the same validator `penv\n // validate` will judge it by — before it exists, rather than after.\n const config = declared ?? configFor(decisions);\n const configError = validateConfig(config)[0];\n if (configError !== undefined) {\n throw configError;\n }\n\n assertCascadeComplete(root, selected, chosen);\n\n const adopted: Adopted[] = [];\n const refs: ParameterRef[] = [];\n const diagnostics: DotenvDiagnostic[] = [];\n let variables = 0;\n for (const file of selected) {\n const parsed = parseDotenv(readFileSync(join(root, file.name), \"utf8\"));\n const fileRefs = refsForEntries(parsed.entries, file.name, config);\n adopted.push({ file, entries: parsed.entries, refs: fileRefs, scope: scopeOf(file) });\n refs.push(...fileRefs);\n diagnostics.push(...parsed.diagnostics);\n variables += parsed.entries.length;\n }\n // Invariant 12, across the whole cutover rather than one file at a time: two\n // files may each be fine and still map two parameters to one variable. One\n // parameter written at four scopes is not that — `DATABASE_URL` in `.env` and\n // in `.env.development.local` is the cascade doing its job — so the refs are\n // deduplicated first.\n assertNoCollisions(distinct(refs), config);\n\n const fields = draftFieldsAcross(\n adopted.map((entry) => ({\n ...(entry.file.environment === undefined ? {} : { environment: entry.file.environment }),\n entries: entry.entries,\n })),\n chosen,\n );\n\n return {\n root,\n selected,\n adopted,\n environments,\n adopting: chosen,\n decisions,\n fields,\n variables,\n diagnostics,\n install: planInstall(root, input.version),\n framework: base.detected?.name,\n configured: declared !== undefined,\n };\n}\n\n/**\n * Seal 3, decided once: `development` when the development cascade was adopted,\n * and otherwise the single environment this cutover is about. Two or more\n * environments and no development among them is a project whose daily\n * environment penv cannot know, so it declares none and `--env` keeps its job.\n */\nfunction proposedDefault(chosen: readonly string[]): string | undefined {\n if (chosen.includes(DEVELOPMENT)) {\n return DEVELOPMENT;\n }\n return chosen.length === 1 ? chosen[0] : undefined;\n}\n\n/** One entry per parameter, whatever number of scopes it was seen at. */\nfunction distinct(refs: readonly ParameterRef[]): ParameterRef[] {\n const seen = new Map<string, ParameterRef>();\n for (const ref of refs) {\n seen.set(parameterId(ref), ref);\n }\n return [...seen.values()];\n}\n\nfunction configFor(decisions: InitDecisions): PenvConfig {\n return {\n environments: environmentsRecord(decisions.environments),\n schemaFile: decisions.schemaFile,\n ...(decisions.defaultEnvironment === undefined\n ? {}\n : { defaultEnvironment: decisions.defaultEnvironment }),\n ...(decisions.publicPrefixes.length === 0\n ? {}\n : { publicPrefixes: [...decisions.publicPrefixes] }),\n };\n}\n\nfunction describeList(names: readonly string[]): string {\n return names.length === 0 ? \"no environments\" : names.map((name) => `\\`${name}\\``).join(\", \");\n}\n\n/**\n * `.env` alone declares no environment (PRD §6), and penv will not pick one for\n * it. The caller asks; this is the guard that the answer arrived.\n */\nfunction requireEnvironment(input: CutoverInput): string {\n const environment = input.environment?.trim() ?? \"\";\n if (environment.length > 0) {\n return environment;\n }\n throw new PenvError(\n \"INIT_ENVIRONMENT_UNNAMED\",\n \"The selected files name no environment, and penv does not invent one\",\n `Run \\`penv init --env ${DEVELOPMENT}\\` to say which environment these values are for.`,\n );\n}\n\n/**\n * PRD §6: every framework-discoverable file in an adopted environment's cascade\n * has to come too. Adopting `.env.development` while leaving `.env` behind\n * leaves the framework loading values penv does not hold — a project with two\n * live sources, which is the state a complete cutover exists to prevent.\n */\nfunction assertCascadeComplete(\n root: string,\n selected: readonly DotenvFile[],\n environments: readonly string[],\n): void {\n const present = new Set(discoverDotenvFiles(root).map((file) => file.name));\n const taken = new Set(selected.map((file) => file.name));\n for (const environment of environments) {\n for (const name of cascadeFor(environment)) {\n if (present.has(name) && !taken.has(name)) {\n throw new PenvError(\n \"INIT_CUTOVER_INCOMPLETE\",\n `${name} is part of ${environment}'s cascade and was not selected, so your framework would keep reading it beside penv`,\n \"Run `penv init` again and take every file penv listed for that environment. Nothing was changed.\",\n );\n }\n }\n }\n}\n\n/**\n * A second migration over an unresolved bundle would bury the first one's files.\n *\n * The bundle decides, not the record: an interrupted cutover can leave files in\n * it, and keying this off `cutover.json` alone let a re-run write a fresh record\n * naming only the files that had not moved yet.\n */\nfunction assertBundleResolved(root: string): void {\n if (!bundleUnresolved(root)) {\n return;\n }\n throw new PenvError(\n \"INIT_BUNDLE_UNRESOLVED\",\n `The dotenv files from the last cutover are still in ${ROLLBACK_DOTENV_PATH}/, and penv will not migrate a second time over them`,\n \"Run `penv init undo` to put them back, or `penv cleanup` to drop them once you are happy with the migration.\",\n );\n}\n\n/**\n * `--yes` takes the development cascade, and refuses when another environment is\n * leaning on the shared `.env` this cutover would move (PRD §6). Which files\n * that environment should keep is a decision, and `--yes` means \"I trust your\n * defaults\", never \"decide my other environments for me\".\n */\nexport function selectionForYes(plan: AdoptionPlan): DotenvFile[] {\n const shared = plan.found.find((file) => file.kind === \"shared\");\n const other = plan.found.find(\n (file) => file.environment !== undefined && file.environment !== DEVELOPMENT,\n );\n if (shared !== undefined && other !== undefined) {\n throw new PenvError(\n \"INIT_YES_SHARED_FALLBACK\",\n `${other.name} falls back to the shared ${shared.name} this cutover would move, so \\`--yes\\` will not decide what happens to ${other.environment ?? \"\"}`,\n \"Run `penv init` without `--yes` and choose every file the cutover takes. Nothing was changed.\",\n );\n }\n return plan.found.filter((file) => plan.preselected.includes(file.name));\n}\n\nexport interface CutoverResult {\n readonly plan: CutoverPlan;\n readonly steps: readonly InitStep[];\n /** The dotenv files moved into the bundle, by name. */\n readonly moved: readonly string[];\n /** The environments whose imported values were validated before the move. */\n readonly validated: readonly string[];\n}\n\nexport interface CutoverOptions {\n /** Injected in tests: how the runtime dependency is installed. Never spawns there. */\n readonly install?: InstallRuntime;\n}\n\n/**\n * Installs, scaffolds, imports, validates — and only then moves the dotenv\n * files aside. The order is the guarantee: every step before the move leaves a\n * project whose `.env` files are exactly where they were, so a refusal at any\n * of them costs a re-run and nothing else.\n *\n * The scaffold is snapshotted first, and rolled back when anything after it\n * refuses. Without that, \"a refusal costs a re-run\" was only true of the dotenv\n * files: a failed run still left a config, a draft schema, an edited tsconfig\n * and an imported records tree behind, and the next run kept every one of them\n * rather than starting clean. The install is not rolled back — it is the one\n * step the developer consented to by itself, and a re-run finds it satisfied.\n */\nexport async function applyCutover(\n plan: CutoverPlan,\n options: CutoverOptions = {},\n): Promise<CutoverResult> {\n if (!plan.install.satisfied) {\n await (options.install ?? installWithPackageManager)(plan.install);\n }\n\n const undo = captureScaffold(plan.root, scaffoldPaths(plan.root, plan.decisions, plan.framework));\n let steps: readonly InitStep[];\n try {\n steps = scaffold(plan.root, plan.fields, true, plan.decisions, plan.framework);\n const project = openProject(plan.root);\n const tree = localTree(project);\n for (const adopted of plan.adopted) {\n writeEntries(tree, adopted.entries, adopted.refs, adopted.scope);\n }\n\n // Every environment this cutover adopted, not just the daily one: the draft\n // is the weakest shape all of them satisfy, so if one of them does not, the\n // draft is wrong and the files must stay where they are. An environment the\n // cutover did not touch is not judged here — it was already in whatever\n // state it was in.\n for (const environment of plan.adopting) {\n const check = await checkEnvironment(project, environment);\n // The draft not loading and the values not fitting it are different\n // answers: one is a verdict, the other is penv never having reached one.\n if (check.schema === undefined) {\n throw draftNotLoaded(check.result);\n }\n if (!check.result.ok) {\n throw invalidAfterImport(check.result);\n }\n }\n } catch (error) {\n restoreScaffold(undo);\n throw error;\n }\n\n const cutover = bundleDotenvFiles(\n plan.root,\n plan.selected.map((file) => file.name),\n plan.environments,\n );\n return { plan, steps, moved: cutover.files, validated: plan.adopting };\n}\n\nfunction issueLines(result: ValidateResult): string {\n return result.issues.map((issue) => ` ${issue.subject}: ${issue.message}`).join(\"\\n\");\n}\n\n/** Nothing was left behind, so every refusal after the scaffold ends the same way. */\nconst SCAFFOLD_ROLLED_BACK =\n \"penv put the project back as it found it — your dotenv files and everything else are exactly where they were.\";\n\nfunction invalidAfterImport(result: ValidateResult): PenvError {\n return new PenvError(\n \"INIT_CUTOVER_INVALID\",\n `The imported values do not satisfy the draft schema for ${result.environment}:\\n${issueLines(result)}`,\n `Correct the values above, then run \\`penv init\\` again. ${SCAFFOLD_ROLLED_BACK}`,\n );\n}\n\n/**\n * The draft could not be evaluated at all — a missing dependency, a syntax\n * error. Reporting that as \"the imported values do not satisfy the draft schema\"\n * claims a check penv never ran, and sends the reader to correct values that\n * were never looked at.\n */\nfunction draftNotLoaded(result: ValidateResult): PenvError {\n return new PenvError(\n \"INIT_DRAFT_NOT_LOADED\",\n `penv could not load the schema it drafted for ${result.environment}, so nothing was checked against it:\\n${issueLines(result)}`,\n `Fix the error above, then run \\`penv init\\` again. ${SCAFFOLD_ROLLED_BACK}`,\n );\n}\n\n/*\n * The cutover's screens.\n */\n\n/** The file list, checkboxes and all — the one screen the selection is made on. */\nexport function renderSelection(\n plan: AdoptionPlan,\n selected: readonly string[] = plan.preselected,\n): string[] {\n const rows = plan.found.map((file) => [\n ` ${selected.includes(file.name) ? \"[x]\" : \"[ ]\"}`,\n file.name,\n out.dim(file.label),\n ]);\n return [out.bold(\"Found dotenv files. Which should penv adopt?\"), \"\", ...columns(rows), \"\"];\n}\n\n/** The plan, and the install it is conditional on. Nothing here has happened yet. */\nexport function renderCutoverPlan(plan: CutoverPlan): string[] {\n const required = plan.fields.filter((field) => field.required).length;\n const optional = plan.fields.length - required;\n const rows: string[][] = [\n [` ${out.dim(\"environments\")}`, out.cyan(`[${plan.environments.join(\", \")}]`), \"\"],\n ];\n if (plan.decisions.defaultEnvironment !== undefined) {\n rows.push([\n ` ${out.dim(\"default\")}`,\n plan.decisions.defaultEnvironment,\n out.dim(\"← so `penv run -- pnpm dev` needs no --env\"),\n ]);\n }\n rows.push([\n ` ${out.dim(\"schema\")}`,\n `${plan.fields.length} parameters`,\n out.dim(`← ${required} required, ${optional} optional — a draft you own`),\n ]);\n rows.push([\n ` ${out.dim(\"values\")}`,\n `${RECORDS_PATH}/`,\n out.dim(`← from ${plan.variables} variables`),\n ]);\n rows.push([\n ` ${out.dim(\"dotenv\")}`,\n `${ROLLBACK_DOTENV_PATH}/`,\n out.dim(\"← recoverable with `penv init undo`\"),\n ]);\n\n return [\n out.bold(\"The cutover\"),\n \"\",\n ...columns(rows),\n \"\",\n ...plan.diagnostics.map((diagnostic) => `${out.yellow(WARN)} ${diagnostic.detail}`),\n ...(plan.diagnostics.length === 0 ? [] : [\"\"]),\n ...renderInstallPlan(plan.install),\n \"\",\n ];\n}\n\n/** What actually happened, and the one command the project starts through now. */\nexport function renderCutover(result: CutoverResult): string[] {\n const { plan } = result;\n const plural = plan.environments.length === 1 ? \"environment\" : \"environments\";\n const steps: Step[] = [\n {\n glyph: plan.configured ? WARN : CHECK,\n text: `Declared ${plural}`,\n note: plan.configured\n ? `${plan.environments.join(\", \")} (already in ${CONFIG_FILE} — penv kept it)`\n : plan.environments.join(\", \"),\n },\n ...result.steps.map((step) => {\n const glyph = step.action === \"conflicted\" ? WARN : step.action === \"info\" ? \"→\" : CHECK;\n return step.note === undefined\n ? { glyph, text: step.text }\n : { glyph, text: step.text, note: step.note };\n }),\n ...installedPackages(plan.install).map((entry) => ({\n glyph: CHECK,\n text: `Installed ${entry.name}`,\n note: entry.version,\n })),\n {\n glyph: CHECK,\n text: `Imported ${plan.fields.length} parameters`,\n note: `into ${RECORDS_PATH}/`,\n },\n { glyph: CHECK, text: `Validated ${result.validated.join(\", \")}` },\n {\n glyph: CHECK,\n text: `Moved ${result.moved.length} dotenv ${result.moved.length === 1 ? \"file\" : \"files\"}`,\n note: `${ROLLBACK_DOTENV_PATH}/ (penv init undo restores them)`,\n },\n ];\n\n return [\n ...formatSteps(steps),\n \"\",\n `${out.green(CHECK)} ${out.bold(\"Done.\")} Start your app with penv:`,\n tip(out.cyan(dailyCommand(plan.root))),\n ];\n}\n\n/**\n * The daily command, shown and never written (seal 1 as amended). penv cannot\n * compose a script line containing a command it did not write, and wrapping\n * inside a script would run `pre*`/`post*` hooks outside penv's environment — so\n * the wrapper stays outside, and this is copy.\n */\nexport function dailyCommand(root: string): string {\n return `penv run -- ${detectPackageManager(root)} ${devScript(root)}`;\n}\n\n/** The script the project already has, so the line shown is one the reader can paste. */\nfunction devScript(root: string): string {\n const file = join(root, PACKAGE_FILE);\n if (!existsSync(file)) {\n return \"dev\";\n }\n try {\n const scripts: unknown = JSON.parse(readFileSync(file, \"utf8\")).scripts;\n if (scripts !== null && typeof scripts === \"object\" && !Array.isArray(scripts)) {\n const named = Object.keys(scripts);\n return [\"dev\", \"start\"].find((script) => named.includes(script)) ?? named[0] ?? \"dev\";\n }\n } catch {\n // An unreadable manifest is not a reason to print nothing: `dev` is what the\n // reader will recognise, and the line is copy either way.\n }\n return \"dev\";\n}\n\nexport function runInit(options: InitOptions): InitResult {\n const root = resolve(options.cwd);\n const decisions = options.decisions ?? planInit(root).decisions;\n // `options.framework` is the name the command already detected; passing it (or\n // `undefined`, which lets `scaffold` detect) avoids a second `package.json` read.\n return { root, decisions, steps: scaffold(root, [], false, decisions, options.framework) };\n}\n\nexport function renderInit(result: InitResult): string[] {\n const steps: Step[] = result.steps.map((step) => {\n // A conflict is the one step that is not a success, so it must not wear the\n // glyph every success wears: a ✓ beside \"penv could not wire your alias\" is\n // the line a reader skims past. An `info` step is a thing left for the user\n // to do, so it wears the tip arrow rather than a ✓ it did not earn.\n const glyph = step.action === \"conflicted\" ? WARN : step.action === \"info\" ? \"→\" : CHECK;\n return step.note === undefined\n ? { glyph, text: step.text }\n : { glyph, text: step.text, note: step.note };\n });\n // The shape is in `penv.schema.ts` for a project on the split, but a project\n // whose old-layout schema init just kept (the `conflicted` step) still holds it\n // in `schemaFile` — penv wrote no `penv.schema.ts` there, so pointing at one\n // would name a file that does not exist.\n const schemaStep = result.steps.find((step) => step.target === \"schema\");\n const shapeFile =\n schemaStep?.action === \"conflicted\" ? result.decisions.schemaFile : SCHEMA_SHAPE_FILE;\n return [\n ...formatSteps(steps),\n \"\",\n `${out.green(CHECK)} ${out.bold(\"Done.\")} Declare your parameters in ${shapeFile}, then:`,\n tip(out.cyan(\"penv set <key>\")),\n ...(result.decisions.environments.length === 0\n ? [\n `Then declare your environments in ${CONFIG_FILE}: penv leaves the whitelist empty ` +\n `rather than inventing one, and every command needs it.`,\n ]\n : []),\n ];\n}\n\n/*\n * The cutover conversation: one screen at a time, and every answer a decision\n * penv could not observe. The io is a parameter throughout, so the tests drive\n * the conversation without a terminal.\n */\n\n/**\n * The files to adopt. `undefined` is the developer declining, which is an\n * outcome and not a failure — nothing is written and the run says so.\n *\n * Enter takes the checked list, because the checked list is the complete\n * development cascade and taking all of it is what makes the cutover complete.\n */\nexport async function promptForSelection(\n plan: AdoptionPlan,\n io: PromptIo,\n): Promise<DotenvFile[] | undefined> {\n for (const line of renderSelection(plan)) {\n io.write(line);\n }\n\n const answer = (await io.ask(prompt(\"files\", \"Enter to take the checked ones\"))).trim();\n if (answer.toLowerCase() === \"none\") {\n return undefined;\n }\n const names =\n answer.length === 0\n ? plan.preselected\n : answer.toLowerCase() === \"all\"\n ? plan.found.map((file) => file.name)\n : answer\n .split(/[\\s,]+/)\n .map((name) => name.trim())\n .filter((name) => name.length > 0);\n\n const selected: DotenvFile[] = [];\n for (const name of names) {\n const file = plan.found.find((candidate) => candidate.name === name);\n if (file === undefined) {\n throw new PenvError(\n \"INIT_SELECTION_UNKNOWN\",\n `\\`${name}\\` is not one of the dotenv files penv found`,\n \"Run `penv init` again and name the files exactly as they are listed, e.g. `.env.production`.\",\n );\n }\n selected.push(file);\n }\n return selected.length === 0 ? undefined : selected;\n}\n\n/**\n * Which environment a selection that declares none is for. Offered, never\n * assumed: `development` is the answer for almost every project adopting a plain\n * `.env`, and pressing Enter is the developer giving it.\n */\nexport async function askEnvironment(io: PromptIo, offered: string): Promise<string> {\n io.write(\"\");\n io.write(\"Selecting `.env` alone declares no environment, and penv never infers one.\");\n const answer = (await io.ask(prompt(\"environment\", `Enter for ${offered}`))).trim();\n return answer.length === 0 ? offered : answer;\n}\n\n/** The last question before anything is written. */\nasync function askProceed(io: PromptIo): Promise<boolean> {\n const answer = (await io.ask(prompt(\"Proceed?\", \"Y/n\"))).trim().toLowerCase();\n return answer.length === 0 || answer === \"y\" || answer === \"yes\";\n}\n\n/** A terminal, or `undefined` when there is nobody to ask. */\nfunction terminal(): { readonly io: PromptIo; close(): void } {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return {\n io: {\n ask: (question) => rl.question(question),\n write: (line) => process.stdout.write(`${line}\\n`),\n },\n close: () => rl.close(),\n };\n}\n\n/** The prompt runs only against a real terminal; anything else has nobody to ask. */\nasync function askOnTty(plan: InitPlan): Promise<InitDecisions | undefined> {\n const rl = terminal();\n try {\n return await promptForDecisions(plan, rl.io);\n } finally {\n rl.close();\n }\n}\n\n/** The scaffold-only path: a project with no dotenv files to adopt. */\nasync function scaffoldOnly(root: string, plan: InitPlan, asked: boolean): Promise<void> {\n const decisions = asked ? await askOnTty(plan) : plan.decisions;\n if (decisions === undefined) {\n write([\"Nothing written. Re-run `penv init` when you want to scaffold.\"]);\n return;\n }\n if (!asked) {\n write([...plan.notes, \"\"]);\n }\n write(\n renderInit(\n runInit({ cwd: root, decisions, ...(plan.detected && { framework: plan.detected.name }) }),\n ),\n );\n}\n\n/** The cutover path, asked one screen at a time. */\nasync function cutoverInteractively(\n root: string,\n base: InitPlan,\n adoption: AdoptionPlan,\n): Promise<void> {\n const rl = terminal();\n let plan: CutoverPlan;\n let inject = false;\n try {\n const selected = await promptForSelection(adoption, rl.io);\n if (selected === undefined) {\n write([\"Nothing written. Re-run `penv init` when you want to migrate.\"]);\n return;\n }\n const named = environmentsDeclaredBy(selected);\n const environment =\n named.length > 0 ? undefined : await askEnvironment(rl.io, offeredEnvironment(root));\n\n plan = planCutover({\n root,\n base,\n selected,\n ...(environment === undefined ? {} : { environment }),\n });\n for (const line of renderCutoverPlan(plan)) {\n rl.io.write(line);\n }\n if (!(await askProceed(rl.io))) {\n write([\"Nothing written. Re-run `penv init` when you want to migrate.\"]);\n return;\n }\n inject = seamKindFor(base) === \"none\" ? false : await askInject(rl.io);\n } finally {\n rl.close();\n }\n\n write([\"\"]);\n write(renderCutover(await applyCutover({ ...plan, decisions: { ...plan.decisions, inject } })));\n}\n\n/** What the environment question offers: what the project already declared, else development. */\nfunction offeredEnvironment(root: string): string {\n const declared = declaredIn(root);\n if (declared === undefined) {\n return DEVELOPMENT;\n }\n const names = environmentNames(declared);\n return (\n declared.defaultEnvironment ??\n (names.includes(DEVELOPMENT) ? DEVELOPMENT : (names[0] ?? DEVELOPMENT))\n );\n}\n\n/** `penv init --yes`: the development cascade, the filesystem provider, and no questions. */\nasync function cutoverWithYes(root: string, base: InitPlan, adoption: AdoptionPlan): Promise<void> {\n const selected = selectionForYes(adoption);\n const plan = planCutover({ root, base, selected, environment: DEVELOPMENT });\n write([...renderCutoverPlan(plan), \"\"]);\n write(renderCutover(await applyCutover(plan)));\n}\n\nexport const initCommand = defineCommand({\n meta: {\n name: \"init\",\n description: \"Adopt your dotenv files, or scaffold a project (.penv/, env.ts, config, @env)\",\n },\n args: {\n action: {\n type: \"positional\",\n required: false,\n description: \"`undo` puts the dotenv files of the last cutover back, under their exact names\",\n },\n yes: {\n type: \"boolean\",\n description:\n `Take the development cascade and the ${LOCAL_PROVIDER} provider without asking. It ` +\n \"never invents production, staging or preview\",\n },\n schema: {\n type: \"string\",\n description: `Where the schema module goes, e.g. src/env.ts (default: ${DEFAULT_SCHEMA_FILE})`,\n },\n alias: {\n type: \"string\",\n description:\n \"How your code names the schema: @env (tsconfig paths, needs a bundler) or #env \" +\n \"(package.json imports, resolved by node itself)\",\n },\n env: {\n type: \"string\",\n description:\n \"Declare an environment. Repeatable, or comma-separated: --env development,production\",\n },\n },\n run({ args }) {\n return guard(async () => {\n const root = resolve(process.cwd());\n if (args.action !== undefined) {\n runUndoAction(root, String(args.action));\n return;\n }\n\n const environments = environmentsFromFlag(args.env);\n const adoption = planAdoption(root);\n // The `--yes` default is for a project with nothing to adopt; where there\n // is a cascade, the files declare the environments and the flag only means\n // \"take the checked ones\".\n const bare = adoption.found.length === 0;\n const plan = planInit(root, {\n ...(args.schema === undefined ? {} : { schema: args.schema }),\n ...(args.alias === undefined ? {} : { alias: args.alias }),\n ...(environments === undefined ? {} : { environments }),\n ...(bare && args.yes === true ? { yes: true } : {}),\n });\n\n const tty = process.stdin.isTTY === true;\n if (bare) {\n // No terminal is not a reason to guess: it is a reason to take the\n // defaults and say what they were, so a CI log carries the decisions.\n await scaffoldOnly(root, plan, tty && args.yes !== true && environments === undefined);\n return;\n }\n if (args.yes === true) {\n await cutoverWithYes(root, plan, adoption);\n return;\n }\n if (!tty) {\n // A cutover moves the developer's files, so it is never taken by a\n // script that did not ask for it. The plan is printed; nothing is done.\n write([...renderSelection(adoption), \"penv found dotenv files to migrate.\"]);\n write([tip(out.cyan(\"penv init --yes\"))]);\n return;\n }\n await cutoverInteractively(root, plan, adoption);\n });\n },\n});\n\n/** `penv init undo` — the only positional this command takes. */\nfunction runUndoAction(root: string, action: string): void {\n if (action !== \"undo\") {\n throw new PenvError(\n \"INIT_UNKNOWN_ACTION\",\n `\\`penv init ${action}\\` is not something init does`,\n \"Run `penv init undo` to put back the dotenv files of the last cutover.\",\n );\n }\n const result = runUndo({ cwd: root });\n write([\n ...formatSteps([\n ...result.restored.map((name) => ({\n glyph: CHECK,\n text: `Restored ${name}`,\n note: `from ${ROLLBACK_DOTENV_PATH}/`,\n })),\n ...result.alreadyBack.map((name) => ({\n glyph: CHECK,\n text: `${name} was already back`,\n note: \"put there by an earlier undo\",\n })),\n ...result.missing.map((name) => ({\n glyph: WARN,\n text: `${name} is gone`,\n note: \"not in the bundle, not at the project root\",\n })),\n ]),\n \"\",\n result.missing.length === 0\n ? `${out.green(CHECK)} ${out.bold(\"Undone.\")} Your dotenv files are back exactly as they were, and ` +\n `${CUTOVER_PATH} is gone.`\n : `${out.yellow(WARN)} ${out.bold(\"Undone as far as penv could.\")} Everything still in the bundle is back, and ` +\n `${CUTOVER_PATH} is gone.`,\n `penv's records are still in ${RECORDS_PATH}/ — nothing penv scaffolded is yours to lose.`,\n ]);\n}\n","/**\n * Putting a project back exactly as init found it.\n *\n * `penv init` is all-or-nothing, and everything before the dotenv move is\n * arranged so a refusal costs a re-run and nothing else. The scaffold is the one\n * step that reaches that promise by construction only until it doesn't: the\n * draft schema is written, the records are imported, and *then* the draft is\n * loaded — so a draft that cannot be loaded used to leave `penv.config.ts`,\n * `penv.schema.ts`, a rewritten `tsconfig.json`, `.penv/env.ts` and a records\n * tree behind, and the next `penv init` kept all of it rather than starting\n * clean.\n *\n * So the paths init may write are snapshotted before it writes them, and put\n * back on the way out: a file penv created is deleted, a file penv edited is\n * rewritten byte for byte, and a directory penv made is removed. Nothing outside\n * the snapshotted paths is touched, which is why the caller names them rather\n * than this module guessing at the project.\n */\n\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmdirSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nexport interface ScaffoldUndo {\n /** The project root. Nothing above it is ever removed. */\n readonly root: string;\n /** The files and directories init may write, absolute. */\n readonly paths: readonly string[];\n /** What each file held before, byte for byte. */\n readonly files: ReadonlyMap<string, Buffer>;\n /** The directories that already existed, so the rest are penv's to remove. */\n readonly dirs: ReadonlySet<string>;\n}\n\nfunction record(path: string, files: Map<string, Buffer>, dirs: Set<string>): void {\n let stats: ReturnType<typeof statSync>;\n try {\n stats = statSync(path);\n } catch {\n return;\n }\n if (stats.isDirectory()) {\n dirs.add(path);\n for (const entry of readdirSync(path)) {\n record(join(path, entry), files, dirs);\n }\n return;\n }\n if (stats.isFile()) {\n files.set(path, readFileSync(path));\n }\n}\n\n/** The state of `paths` right now, enough to restore it exactly. */\nexport function captureScaffold(root: string, paths: readonly string[]): ScaffoldUndo {\n const files = new Map<string, Buffer>();\n const dirs = new Set<string>();\n for (const path of paths) {\n for (let dir = dirname(path); dir.startsWith(root) && dir !== root; dir = dirname(dir)) {\n if (existsSync(dir)) {\n dirs.add(dir);\n }\n }\n record(path, files, dirs);\n }\n return { root, paths: [...paths], files, dirs };\n}\n\n/** The project as {@link captureScaffold} found it. */\nexport function restoreScaffold(undo: ScaffoldUndo): void {\n for (const path of undo.paths) {\n removeAdded(path, undo);\n }\n for (const path of undo.paths) {\n pruneAncestors(path, undo);\n }\n for (const [file, contents] of undo.files) {\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, contents);\n }\n}\n\nfunction removeAdded(path: string, undo: ScaffoldUndo): void {\n let stats: ReturnType<typeof statSync>;\n try {\n stats = statSync(path);\n } catch {\n return;\n }\n if (stats.isFile()) {\n if (!undo.files.has(path)) {\n unlinkSync(path);\n }\n return;\n }\n if (!stats.isDirectory()) {\n return;\n }\n for (const entry of readdirSync(path)) {\n removeAdded(join(path, entry), undo);\n }\n if (!undo.dirs.has(path) && readdirSync(path).length === 0) {\n rmdirSync(path);\n }\n}\n\n/** The directories a created file needed, when they were created for it. */\nfunction pruneAncestors(path: string, undo: ScaffoldUndo): void {\n for (\n let dir = dirname(path);\n dir.startsWith(undo.root) && dir !== undo.root;\n dir = dirname(dir)\n ) {\n if (undo.dirs.has(dir)) {\n return;\n }\n try {\n rmdirSync(dir);\n } catch {\n return;\n }\n }\n}\n","/**\n * The injection seams — where `penv init` places `import \"@env\"` so it runs\n * before any app code, per framework.\n *\n * When a project opts into injection (`load(schema, { inject: true })`), the SDK\n * that reads `process.env` directly only finds the values if the injection ran\n * first. Every framework ships a hook it *guarantees* runs before app code; this\n * module knows, per framework, which hook that is and exactly what belongs in it.\n * The specifics here were verified against each framework's current documentation\n * — the ordering guarantee, the filename rules, the runtime guards — not written\n * from memory, because a seam that runs a beat too late is a seam that does\n * nothing.\n *\n * Three shapes of seam:\n *\n * - **scaffold** — the framework has a clean pre-app file penv can write. penv\n * creates it *only when it does not already exist*; an existing hook is the\n * user's, so penv prints where to add the line instead of editing it in place.\n * - **instruct** — no file penv can safely own (plain Node has no framework hook;\n * TanStack's entry is version-shaped; Astro has no universal hook). penv prints\n * the exact, verified line and where it goes.\n * - **none** — no server runtime reads `process.env` at all (a pure client SPA),\n * so injection does not apply and penv says so.\n *\n * The import specifier is the project's own alias — `@env` where a bundler\n * resolves it (Next, SvelteKit, Nuxt, Bun-with-tsconfig), `#env` where Node\n * resolves it natively (plain Node). That choice is the project's, made at init;\n * the seam only carries it through.\n */\n\n/** What init knows when it builds a seam: the project's alias, layout, and schema module. */\nexport interface SeamContext {\n /** The import specifier the project resolves the schema module by — `@env` or `#env`. */\n readonly alias: string;\n /** `\"src/\"` when the project keeps modules under `src/`, else `\"\"`. */\n readonly srcDir: string;\n /** The schema module path, relative to the project root, POSIX — e.g. `.penv/env.ts` or `src/env.ts`. */\n readonly schemaFile: string;\n}\n\n/** A seam penv can write to a file, created only when the file is absent. */\nexport interface ScaffoldSeam {\n readonly kind: \"scaffold\";\n /** The file to create, relative to the project root, POSIX. */\n readonly file: string;\n /** Exactly what penv writes into a fresh file — the framework-explaining comment and the import. */\n readonly content: string;\n /**\n * What penv prints when the file already exists (penv will not edit a hook the\n * user owns) — where to add the line, verbatim.\n */\n readonly ifPresent: string;\n /** Extra one-line notes penv surfaces after scaffolding — an alias-wiring caveat, say. */\n readonly notes: readonly string[];\n /**\n * A second file the seam also needs, under the same create-if-absent rule — Bun's\n * `bunfig.toml`, which must register the preload file or it never runs. penv\n * creates it when absent; when present it is the user's, so penv prints where to\n * add the entry rather than editing their config.\n */\n readonly also?: {\n readonly file: string;\n readonly content: string;\n readonly ifPresent: string;\n };\n}\n\n/** A seam penv cannot own; it prints the exact instruction instead. */\nexport interface InstructSeam {\n readonly kind: \"instruct\";\n readonly instruction: string;\n}\n\n/** No server runtime reads `process.env`; injection does not apply. */\nexport interface NoSeam {\n readonly kind: \"none\";\n readonly reason: string;\n}\n\nexport type Seam = ScaffoldSeam | InstructSeam | NoSeam;\n\n/** Builds a framework's seam for one project's alias and layout. */\nexport type SeamFor = (context: SeamContext) => Seam;\n\nfunction nextjs({ alias, srcDir }: SeamContext): Seam {\n return {\n kind: \"scaffold\",\n file: `${srcDir}instrumentation.ts`,\n content:\n \"// This is instrumentation.ts, Next.js's own startup hook — Next runs it once,\\n\" +\n \"// before any of your app code, on every server boot. penv put one line here so\\n\" +\n \"// your config is in process.env before the first library reads it. The filename\\n\" +\n \"// is Next's requirement (it only finds `instrumentation.ts`), so keep it as-is.\\n\" +\n \"export async function register() {\\n\" +\n \" // Next also calls register on the Edge runtime, where penv cannot read the\\n\" +\n \" // filesystem — so inject runs on the Node runtime only.\\n\" +\n ' if (process.env.NEXT_RUNTIME === \"nodejs\") {\\n' +\n ` await import(\"${alias}\");\\n` +\n \" }\\n\" +\n \"}\\n\",\n ifPresent:\n `Add to your existing \\`${srcDir}instrumentation.ts\\`, inside \\`register()\\` and first:\\n` +\n ` if (process.env.NEXT_RUNTIME === \"nodejs\") { await import(\"${alias}\"); }`,\n notes: [],\n };\n}\n\nfunction sveltekit({ alias }: SeamContext): Seam {\n return {\n kind: \"scaffold\",\n // SvelteKit's hooks module is always under `src/`, whatever the schema path.\n file: \"src/hooks.server.ts\",\n content:\n \"// This is hooks.server.ts, SvelteKit's server-startup module — it loads before\\n\" +\n \"// your routes handle a request. penv put this import first so your config is in\\n\" +\n \"// process.env before any library reads it. Keep it the first line; the name and\\n\" +\n \"// location are SvelteKit's, not penv's.\\n\" +\n `import \"${alias}\";\\n`,\n ifPresent: `Add \\`import \"${alias}\";\\` as the FIRST line of src/hooks.server.ts, above every other import.`,\n notes: [\n `SvelteKit resolves app aliases through \\`kit.alias\\` — make sure \\`${alias}\\` is registered in svelte.config.js, not only tsconfig.`,\n ],\n };\n}\n\nfunction nuxt({ alias }: SeamContext): Seam {\n return {\n kind: \"scaffold\",\n // The `0.` prefix is load-bearing: Nitro sorts plugin filenames as strings,\n // so it must sort first to run before any other plugin reads process.env.\n file: \"server/plugins/0.penv.ts\",\n content:\n \"// This is a Nitro server plugin (Nuxt's server layer runs it once at startup,\\n\" +\n \"// before any middleware or request handler). penv put the import here so your\\n\" +\n \"// config is in process.env before a library reads it. The `0.` prefix keeps this\\n\" +\n \"// plugin first — Nitro sorts plugin filenames as text — so don't rename it.\\n\" +\n `import \"${alias}\";\\n` +\n \"\\n\" +\n \"// Nitro requires every plugin file to default-export a function; the injection\\n\" +\n \"// above already ran at import, so this body is intentionally empty.\\n\" +\n \"export default defineNitroPlugin(() => {});\\n\",\n ifPresent: `Create server/plugins/0.penv.ts with \\`import \"${alias}\";\\` and \\`export default defineNitroPlugin(() => {});\\`.`,\n notes: [\n `Wire \\`${alias}\\` for the Nitro (server) build so it never leaks into the client bundle.`,\n ],\n };\n}\n\nfunction bun({ alias }: SeamContext): Seam {\n return {\n kind: \"scaffold\",\n file: \".penv/preload.ts\",\n content:\n \"// Bun evaluates this file before your entry point, because it is listed under\\n\" +\n \"// `preload` in bunfig.toml. Running it injects your config into process.env\\n\" +\n \"// before any library reads it.\\n\" +\n `import \"${alias}\";\\n`,\n ifPresent: `Keep .penv/preload.ts as \\`import \"${alias}\";\\`.`,\n notes: [`\\`${alias}\\` must be a tsconfig \\`paths\\` alias for Bun to resolve it.`],\n // The preload file is inert until bunfig.toml points at it — so penv writes\n // that too, both for the runtime and for `bun test`. Only when there is no\n // bunfig to overwrite; an existing one is the user's, and penv prints instead.\n also: {\n file: \"bunfig.toml\",\n content: 'preload = [\"./.penv/preload.ts\"]\\n\\n[test]\\npreload = [\"./.penv/preload.ts\"]\\n',\n ifPresent:\n 'Add \"./.penv/preload.ts\" to the `preload` array in bunfig.toml — and mirror it under `[test]` so `bun test` injects too.',\n },\n };\n}\n\nfunction node({ alias, schemaFile }: SeamContext): Seam {\n // Plain Node owns no pre-app file, and `@env` (a tsconfig alias) does not\n // resolve at raw-Node runtime — so steer to `#env` (a package.json imports\n // alias Node resolves itself), or the built schema module by path when the\n // project is on `@env`. The path is the schema module's own location (`.penv/`\n // is at the repo root, never under `src/`), with `.ts` swapped for the emitted\n // `.js`.\n const builtSchema = `./${schemaFile.replace(/\\.ts$/, \".js\")}`;\n const runtimeSpecifier = alias.startsWith(\"#\") ? alias : builtSchema;\n return {\n kind: \"instruct\",\n instruction:\n \"Plain Node / Express / Fastify have no framework hook that runs before your\\n\" +\n \"code, so place the injection yourself, one of two ways (both run first):\\n\" +\n ` • Preload at launch — add to your start script: node --import \"${runtimeSpecifier}\" your-entry.js\\n` +\n ` • Or make it the FIRST line of your entry file: import \"${runtimeSpecifier}\";\\n` +\n (alias.startsWith(\"#\")\n ? \"\"\n : `Note: \\`${alias}\\` is a tsconfig alias that Node does not resolve at runtime — the paths above point at the built schema module instead.\\n`),\n };\n}\n\nfunction tanstack({ alias, srcDir }: SeamContext): Seam {\n // TanStack Start's server entry carries version-shaped boilerplate, so penv\n // prints the line rather than scaffold boilerplate that could drift.\n return {\n kind: \"instruct\",\n instruction:\n `Add \\`import \"${alias}\";\\` as the FIRST line of ${srcDir}server.ts (TanStack Start's\\n` +\n \"server entry), above the `@tanstack/react-start/server-entry` import — nothing may\\n\" +\n \"import before it. If you have no server.ts yet, create it from TanStack's server-entry\\n\" +\n \"template and put that import first.\",\n };\n}\n\nfunction astro({ alias }: SeamContext): Seam {\n return {\n kind: \"instruct\",\n instruction:\n \"Astro has no single pre-app hook. Add a small integration to astro.config that\\n\" +\n \"injects the import into every SSR page, then cover the routes it cannot reach:\\n\" +\n \" • In astro.config integrations, add:\\n\" +\n ' { name: \"penv\", hooks: { \"astro:config:setup\": ({ injectScript }) =>\\n' +\n ` injectScript(\"page-ssr\", 'import \"${alias}\";') } }\\n` +\n ` • Also add \\`import \"${alias}\";\\` as the first line of src/middleware.ts and of any\\n` +\n \" endpoint route (src/pages/*.ts) that imports a library reading process.env.\\n\" +\n \"Injection only applies under a server (on-demand) adapter, not a static build.\",\n };\n}\n\nfunction viteSpa(_context: SeamContext): Seam {\n return {\n kind: \"none\",\n reason:\n \"This is a client-only app — nothing reads process.env at runtime, so injection \" +\n \"does not apply. Read client config through import.meta.env (only VITE_-prefixed \" +\n \"vars, which ship to the browser and must not hold secrets). If you add a server \" +\n \"later, place the injection there.\",\n };\n}\n\n/**\n * The seam for a framework, keyed by the name {@link import(\"./detect.js\").Detected}\n * carries. A framework penv recognises but has no seam entry for falls back to the\n * plain-Node instruction, which works for any runtime.\n */\nconst SEAMS: Readonly<Record<string, SeamFor>> = {\n \"Next.js\": nextjs,\n SvelteKit: sveltekit,\n Nuxt: nuxt,\n Bun: bun,\n \"TanStack Start\": tanstack,\n Astro: astro,\n Vite: viteSpa,\n};\n\n/**\n * The seam for a detected framework, or the universal plain-Node instruction when\n * penv has no framework-specific one — that instruction runs before app code on\n * any runtime, so it is a correct fallback rather than a guess.\n */\nexport function seamFor(framework: string | undefined, context: SeamContext): Seam {\n const build = framework === undefined ? node : (SEAMS[framework] ?? node);\n return build(context);\n}\n","/**\n * `penv key create --env <e>` — mint a key of the right shape.\n *\n * This exists because `penv encrypt` refuses to invent one. A key penv generated\n * behind your back is a key nobody can reproduce, restore, or rotate, and the\n * first time it matters is the first time it is gone. So minting is its own act,\n * run deliberately, and the key it prints is yours to store.\n *\n * Where penv stores it depends on the source. With `env`, the key *is* whatever\n * the process environment holds — a deploy unwraps it from a KMS and exports it —\n * so there is nowhere for penv to put it that would not be the repo-adjacent file\n * the design forbids; printing the export line is the whole job. With `keychain`,\n * the OS keychain is exactly the place a key may live, so penv stores it there and\n * prints nothing to copy — the key exists in one place, on this machine, which is\n * the point of the keychain.\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport type { Keychain } from \"@penvhq/core\";\nimport { KEY_BYTES, KEYCHAIN_SERVICE, keyConfigFor, PenvError } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { defaultKeychain } from \"../keychain.js\";\nimport { openProject, targetEnvironment } from \"../project.js\";\nimport { out } from \"../style.js\";\nimport { CHECK, guard, write } from \"../ui.js\";\n\nexport interface KeyCreateOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Replace an existing keychain key instead of refusing. Orphans values sealed under the old one. */\n readonly force?: boolean;\n /** Injected in tests: the keychain to store into. Defaults to the real OS binding. */\n readonly keychain?: Keychain;\n}\n\nexport interface KeyCreateResult {\n readonly source: \"env\" | \"keychain\";\n readonly environment: string;\n readonly id: string;\n /** Env source only: the variable to export the key under. */\n readonly variable?: string;\n /** Env source only: the key, base64, ready to export. penv holds no copy. */\n readonly key?: string;\n}\n\n/** Mirrors the transform in core's env key source, which is the thing that reads it. */\nfunction envVarFor(id: string): string {\n return `PENV_KEY_${id.replace(/[^A-Za-z0-9]/g, \"_\").toUpperCase()}`;\n}\n\nexport function runKeyCreate(options: KeyCreateOptions): KeyCreateResult {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment);\n\n const declared = keyConfigFor(project.config, environment);\n if (declared === undefined) {\n throw new PenvError(\n \"KEY_SOURCE_UNDECLARED\",\n `Environment ${environment} declares no key source, so penv does not know what a key for it would be`,\n `Give its entry in penv.config.ts a \\`keySource\\` — e.g. \\`${environment}: { provider: ` +\n `\"@penvhq/provider-filesystem\", keySource: \"env\" }\\` — then run this again. The key is named ` +\n \"after the environment unless the object form names another.\",\n );\n }\n\n const key = randomBytes(KEY_BYTES).toString(\"base64\");\n\n if (declared.source === \"keychain\") {\n const keychain = options.keychain ?? defaultKeychain;\n if (options.force !== true) {\n // Replacing the key orphans every value already sealed under the old one —\n // they could never be decrypted again. Refuse unless the user forces it.\n let existing: string | null;\n try {\n existing = keychain.getPassword(KEYCHAIN_SERVICE, declared.id);\n } catch (cause) {\n // The binding being absent already carries its own remedy, and it is not\n // \"unlock your keychain\" — that advice would send the user to a keychain\n // penv never reached.\n if (cause instanceof PenvError) {\n throw cause;\n }\n throw new PenvError(\n \"KEYCHAIN_UNAVAILABLE\",\n `penv could not read your OS keychain to check for an existing key \\`${declared.id}\\``,\n `Unlock your keychain and run this again. Original error: ${cause instanceof Error ? cause.message : String(cause)}`,\n );\n }\n if (existing !== null) {\n throw new PenvError(\n \"KEY_EXISTS\",\n `Environment ${environment} already has a key \\`${declared.id}\\` in your OS keychain`,\n \"Replacing it would orphan every value already sealed under it — they could never be \" +\n \"decrypted again. Re-run with `--force` only if you are certain nothing is sealed under \" +\n \"the current key.\",\n );\n }\n }\n keychain.setPassword(KEYCHAIN_SERVICE, declared.id, key);\n return { source: \"keychain\", environment, id: declared.id };\n }\n\n return {\n source: \"env\",\n environment,\n id: declared.id,\n variable: envVarFor(declared.id),\n key,\n };\n}\n\nexport function renderKeyCreate(result: KeyCreateResult): string[] {\n if (result.source === \"keychain\") {\n return [\n `${out.green(CHECK)} A new key for environment ${result.environment}, stored in your OS keychain as \\`${result.id}\\`.`,\n \"\",\n out.dim(\n \"penv kept no copy. Anything sealed under it is unreadable without your keychain, and running\",\n ),\n out.dim(\n \"`penv key create` again would replace it — so it lives in exactly one place, on this machine.\",\n ),\n ];\n }\n return [\n `${out.green(CHECK)} A new key for environment ${result.environment}. penv did not store it.`,\n \"\",\n ` ${out.cyan(`${result.variable}=${result.key}`)}`,\n \"\",\n out.dim(\n \"Export it where penv runs, and put it wherever this environment's secrets already live —\",\n ),\n out.dim(\n \"a KMS, your CI's secret store, a password manager. Anything sealed under it is unreadable\",\n ),\n out.dim(\"without it, and penv keeps no copy to fall back on.\"),\n ];\n}\n\nexport const keyCommand = defineCommand({\n meta: { name: \"key\", description: \"Work with encryption keys\" },\n subCommands: {\n create: defineCommand({\n meta: { name: \"create\", description: \"Generate a key for an environment\" },\n args: {\n env: { type: \"string\", description: \"The environment the key is for\" },\n force: {\n type: \"boolean\",\n description: \"Replace an existing keychain key (orphans values sealed under the old one)\",\n },\n },\n run({ args }) {\n return guard(async () => {\n write(\n renderKeyCreate(\n runKeyCreate({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.force === undefined ? {} : { force: args.force }),\n }),\n ),\n );\n });\n },\n }),\n },\n});\n","/**\n * The OS-keychain binding, and the one place the native module is touched.\n *\n * `@penvhq/core` defines the `Keychain` contract but carries no native dependency:\n * `load` runs in every deploy, and a native module in the runtime's tree is a\n * build failure in someone's container. So the binding lives here, in the CLI —\n * whose dependency budget is looser and which never ships inside a user's app —\n * and is registered into core (see `runMain`). Where it is never registered (the\n * runtime), a keychain source answers `unavailable`, which is the honest verdict.\n *\n * The native module is required lazily, so it loads only when a keychain key is\n * actually read or written — never merely because the CLI started, and never on\n * an env-source path that has no business touching it. That laziness is load\n * bearing twice over: an engine installed from an npm tarball into `$PENV_HOME`\n * has no `node_modules`, so the binding is genuinely absent there, and every\n * command that is not a keychain command must still work.\n */\n\nimport { createRequire } from \"node:module\";\nimport { type Keychain, PenvError } from \"@penvhq/core\";\n\n/** The native package this binding is. Named in the refusal, so it is a constant. */\nexport const KEYRING_MODULE = \"@napi-rs/keyring\";\n\n/** The synchronous slice of `@napi-rs/keyring`'s `Entry` this binding uses. */\ninterface Entry {\n getPassword(): string | null;\n setPassword(password: string): void;\n}\ntype EntryConstructor = new (service: string, account: string) => Entry;\n\n/** How the native module is reached. Injected in tests; nothing else replaces it. */\nexport type NativeLoader = (id: string) => unknown;\n\nconst nodeRequire: NativeLoader = (id) => createRequire(import.meta.url)(id);\n\n/** Node appends a require stack to a resolution failure; the sentence is the useful part. */\nfunction firstLine(cause: unknown): string {\n return (cause instanceof Error ? cause.message : String(cause)).split(\"\\n\")[0] ?? \"\";\n}\n\n/**\n * The binding is missing, which is neither \"the keychain is locked\" nor \"there is\n * no such key\" — it is penv having no way to ask at all, and it has one cause.\n */\nfunction keyringMissing(cause: unknown): PenvError {\n return new PenvError(\n \"KEYCHAIN_BINDING_MISSING\",\n `penv could not load ${KEYRING_MODULE}, the native binding it reads your OS keychain through`,\n `This penv engine was installed as a plain tarball, which carries no native modules. ` +\n `Install penv with \\`npm install -g @penvhq/launcher\\`, or declare \\`source: \"env\"\\` for ` +\n `this environment and export its key. Original error: ${firstLine(cause)}`,\n );\n}\n\n/**\n * The real binding, backed by `@napi-rs/keyring`'s synchronous `Entry`. Its\n * `getPassword` returns `null` for a missing entry (never throws for absence) and\n * throws only when the keychain genuinely cannot be read — which the core source\n * turns into `unavailable`, not `absent`.\n */\nexport function createKeychain(load: NativeLoader = nodeRequire): Keychain {\n let cached: EntryConstructor | undefined;\n\n const entryConstructor = (): EntryConstructor => {\n if (cached === undefined) {\n let module: { Entry: EntryConstructor };\n try {\n module = load(KEYRING_MODULE) as { Entry: EntryConstructor };\n } catch (cause) {\n throw keyringMissing(cause);\n }\n cached = module.Entry;\n }\n return cached;\n };\n\n return {\n getPassword(service, account) {\n const Entry = entryConstructor();\n return new Entry(service, account).getPassword();\n },\n setPassword(service, account, password) {\n const Entry = entryConstructor();\n new Entry(service, account).setPassword(password);\n },\n };\n}\n\nexport const defaultKeychain: Keychain = createKeychain();\n","/**\n * `penv list` — every parameter, and the scope that wins for one environment.\n *\n * The winning scope is the point: `production` and `default` are both \"it\n * resolves\", and only one of them means the value was written for production.\n */\n\nimport type { Scope } from \"@penvhq/core\";\nimport { assertNever, RECORDS_PATH, resolveAll, variableName } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { keySourceFor, openProject, targetEnvironment } from \"../project.js\";\nimport { out } from \"../style.js\";\nimport { columns, guard, heading, tip, write } from \"../ui.js\";\n\nexport interface ListOptions {\n readonly cwd: string;\n readonly environment?: string;\n}\n\nexport interface ListEntry {\n readonly parameter: string;\n /** The generated `.env` variable, so the two names are legible side by side. */\n readonly variable: string;\n /** `<env>.local`, `local`, an environment name, `default`, or `absent`. */\n readonly scope: string;\n /** The winning value file relative to the records tree, or `undefined` when nothing wins. */\n readonly location: string | undefined;\n readonly encrypted: boolean;\n readonly viaUnscopedFallback: boolean;\n}\n\nexport interface ListResult {\n readonly environment: string;\n readonly parameters: readonly ListEntry[];\n}\n\n/**\n * The cascade level a winning scope names, spelled as its filename suffix so the\n * column reads back as the file on disk. Each of the four levels is distinct:\n * `production.local` and `local` are different files with different reach, and a\n * column that called both `local` would hide which one won.\n */\nfunction scopeLabel(scope: Scope): string {\n switch (scope.kind) {\n case \"environment\":\n return scope.environment;\n case \"local\":\n return \"local\";\n case \"environment-local\":\n return `${scope.environment}.local`;\n case \"unscoped\":\n return \"default\";\n default:\n return assertNever(scope, \"scope\");\n }\n}\n\nexport async function runList(options: ListOptions): Promise<ListResult> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment);\n\n const keys = keySourceFor(project, environment);\n const parameters: ListEntry[] = [];\n // `list` names which file wins, never a value, so an undecryptable winner is\n // listed exactly like any other: the scope column is the answer here.\n for (const resolution of await resolveAll(environment, project.provider, keys)) {\n const winner = resolution.winner;\n const scope = winner?.file.scope;\n parameters.push({\n parameter: resolution.parameter,\n variable: variableName(resolution.ref, project.config),\n scope: scope === undefined ? \"absent\" : scopeLabel(scope),\n location: winner?.location,\n encrypted: winner?.file.encrypted === true,\n viaUnscopedFallback: resolution.viaUnscopedFallback,\n });\n }\n\n return { environment, parameters };\n}\n\n/**\n * The scope column is the report, so it carries the verdict's color: green for a\n * value written for this environment, yellow for the silent-drift shapes —\n * `absent`, and a real environment riding the unscoped default (invariant 13:\n * fallback is never silent) — and plain for everything else.\n */\nfunction paintScope(entry: ListEntry): string {\n if (entry.scope === \"absent\" || entry.viaUnscopedFallback) {\n return out.yellow(entry.scope);\n }\n return out.green(entry.scope);\n}\n\nexport function renderList(result: ListResult): string[] {\n if (result.parameters.length === 0) {\n return [\n `No parameters in ${RECORDS_PATH}/ for environment ${result.environment}.`,\n tip(`penv set <key> --env ${result.environment}`),\n ];\n }\n const header = [\"parameter\", \"scope\", \"variable\", \"\"].map((cell) => out.dim(cell));\n const rows = result.parameters.map((entry) => [\n entry.parameter,\n paintScope(entry),\n entry.variable,\n entry.encrypted ? out.dim(\"encrypted\") : \"\",\n ]);\n return [\n heading(\"penv list\", `environment ${result.environment}`),\n \"\",\n ...columns([header, ...rows]),\n ];\n}\n\nexport const listCommand = defineCommand({\n meta: { name: \"list\", description: \"List parameters\" },\n args: {\n env: { type: \"string\", description: \"The environment to resolve against\" },\n json: { type: \"boolean\", description: \"Print machine-readable JSON\" },\n },\n run({ args }) {\n return guard(async () => {\n const result = await runList({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n });\n write(args.json === true ? [JSON.stringify(result, null, 2)] : renderList(result));\n });\n },\n});\n","/**\n * `penv migrate` — move a project's records under `.penv/state/records/`.\n *\n * penv reads one layout, so this is the one command that knows two. It is a\n * relocation and nothing else: records move byte for byte, keeping their names,\n * so the grammar, the cascade, the meta and the AAD that binds a ciphertext to\n * its address all mean afterwards exactly what they meant before.\n * `penv.schema.ts`, `penv.config.ts` and `.penv/env.ts` are the project's, and\n * are never touched.\n *\n * It previews before it moves, because the one thing a migration must not do is\n * surprise the person who ran it — and it refuses a half-migrated tree rather\n * than merging two, since which copy of a parameter is current is a question\n * only the user can answer.\n */\n\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\nimport {\n loadConfig,\n oldLayoutEntries,\n PENV_DIR,\n PenvError,\n RECORDS_PATH,\n recordsDir,\n renderStateGitignore,\n STATE_GITIGNORE_PATH,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { out } from \"../style.js\";\nimport { CHECK, formatSteps, guard, prompt, type Step, tip, write } from \"../ui.js\";\n\n/** The ignore file the old layout kept its boundary in, which this command replaces. */\nconst OLD_GITIGNORE = `${PENV_DIR}/.gitignore`;\n\n/** One thing that moves, project-relative and POSIX. */\nexport interface MigrateMove {\n readonly from: string;\n readonly to: string;\n}\n\nexport interface MigratePlan {\n readonly root: string;\n /** What moves, in the order it is reported. */\n readonly moves: readonly MigrateMove[];\n /** What penv writes that is not there yet — the tree root and the safety boundary. */\n readonly creates: readonly string[];\n /** What penv removes: the ignore file that described the old layout. */\n readonly removes: readonly string[];\n}\n\n/**\n * `previewed` is a plan nobody approved, so nothing was written; `current` is a\n * project that was already on the new layout, which is what a second run says.\n */\nexport type MigrateStatus = \"migrated\" | \"current\" | \"previewed\";\n\nexport interface MigrateResult extends MigratePlan {\n readonly status: MigrateStatus;\n}\n\nexport interface MigrateOptions {\n readonly cwd: string;\n /** Approve the plan. Without it `migrate` previews and writes nothing. */\n readonly yes?: boolean;\n}\n\n/**\n * What a migration would do, without doing any of it.\n *\n * The move list is `oldLayoutEntries` — the same list every command's refusal is\n * keyed off — so the preview can never describe a different migration from the\n * one that runs.\n */\nexport function planMigrate(cwd: string): MigratePlan {\n const { config, file } = loadConfig(cwd);\n const root = dirname(file);\n const entries = oldLayoutEntries(root, config);\n const tree = recordsDir(root);\n\n // Only a name on both sides is a question penv cannot answer: two copies of one\n // record, and moving would pick a winner silently. Entries the tree does not\n // hold are simply the rest of the migration — an interruption between two\n // renames leaves exactly that, and refusing it wedged the project, since every\n // other command answers an old-layout tree by naming this one.\n const collisions = collidingEntries(entries, tree);\n if (collisions.length > 0) {\n throw new PenvError(\n \"HALF_MIGRATED\",\n `${describe(collisions)} in both \\`${PENV_DIR}/\\` and \\`${RECORDS_PATH}/\\`, and penv cannot tell which copy is current`,\n `Move what is left under \\`${PENV_DIR}/\\` into \\`${RECORDS_PATH}/\\` yourself, keeping the copy you want, then run \\`penv validate\\`.`,\n );\n }\n\n const creates: string[] = [];\n if (entries.length > 0 && !existsSync(tree)) {\n creates.push(`${RECORDS_PATH}/`);\n }\n if (\n readIfPresent(join(root, ...STATE_GITIGNORE_PATH.split(\"/\"))) !== renderStateGitignore(config)\n ) {\n creates.push(STATE_GITIGNORE_PATH);\n }\n\n return {\n root,\n moves: entries.map((entry) => ({\n from: `${PENV_DIR}/${entry}`,\n to: `${RECORDS_PATH}/${entry}`,\n })),\n creates,\n removes: existsSync(join(root, ...OLD_GITIGNORE.split(\"/\"))) ? [OLD_GITIGNORE] : [],\n };\n}\n\nfunction readIfPresent(file: string): string | undefined {\n return existsSync(file) ? readFileSync(file, \"utf8\") : undefined;\n}\n\n/**\n * The names the move would land on top of, sorted.\n *\n * Folded to lower case, because on a case-insensitive filesystem `DB` and `db`\n * are one name and the rename would overwrite rather than collide.\n */\nfunction collidingEntries(entries: readonly string[], tree: string): string[] {\n let held: string[];\n try {\n held = readdirSync(tree);\n } catch {\n return [];\n }\n const taken = new Set(held.map((name) => name.toLowerCase()));\n return entries.filter((entry) => taken.has(entry.toLowerCase())).sort();\n}\n\nfunction describe(names: readonly string[]): string {\n return names.length === 1\n ? `\\`${names[0]}\\` is`\n : `${names.map((name) => `\\`${name}\\``).join(\", \")} are`;\n}\n\n/** True when a plan would change nothing at all. */\nexport function isNoop(plan: MigratePlan): boolean {\n return plan.moves.length === 0 && plan.creates.length === 0 && plan.removes.length === 0;\n}\n\n/**\n * Performs a plan. Separate from {@link planMigrate} so what runs is the plan the\n * user approved, not a second reading of the disk between the question and the\n * answer.\n */\nexport function applyMigrate(plan: MigratePlan): MigrateResult {\n if (isNoop(plan)) {\n return { ...plan, status: \"current\" };\n }\n\n const { config } = loadConfig(plan.root);\n if (plan.moves.length > 0) {\n mkdirSync(recordsDir(plan.root), { recursive: true });\n for (const move of plan.moves) {\n renameSync(join(plan.root, ...move.from.split(\"/\")), join(plan.root, ...move.to.split(\"/\")));\n }\n }\n\n // The new boundary is written before the old one goes, so the records this\n // command just moved are never unignored for an instant. The old one still has\n // to go: left in place it would keep ignoring `.penv/env.ts`, which the new\n // layout commits.\n if (plan.creates.includes(STATE_GITIGNORE_PATH)) {\n const ignore = join(plan.root, ...STATE_GITIGNORE_PATH.split(\"/\"));\n mkdirSync(dirname(ignore), { recursive: true });\n writeFileSync(ignore, renderStateGitignore(config), \"utf8\");\n }\n\n for (const removed of plan.removes) {\n rmSync(join(plan.root, ...removed.split(\"/\")), { force: true });\n }\n\n return { ...plan, status: \"migrated\" };\n}\n\n/** Plans, and applies only when the move was approved. */\nexport function runMigrate(options: MigrateOptions): MigrateResult {\n const plan = planMigrate(options.cwd);\n if (isNoop(plan)) {\n return { ...plan, status: \"current\" };\n }\n return options.yes === true ? applyMigrate(plan) : { ...plan, status: \"previewed\" };\n}\n\nexport function renderMigrate(result: MigrateResult): string[] {\n if (result.status === \"current\") {\n return [`${out.green(CHECK)} Already on ${RECORDS_PATH}/ — nothing to migrate.`];\n }\n\n const done = result.status === \"migrated\";\n const glyph = done ? CHECK : \"→\";\n const steps: Step[] = [\n ...result.moves.map((move) => ({\n glyph,\n text: `${done ? \"Moved\" : \"Move\"} ${move.from}`,\n note: `to ${move.to}`,\n })),\n ...result.creates.map((created) => ({ glyph, text: `${done ? \"Wrote\" : \"Write\"} ${created}` })),\n ...result.removes.map((removed) => ({\n glyph,\n text: `${done ? \"Removed\" : \"Remove\"} ${removed}`,\n note: `replaced by ${STATE_GITIGNORE_PATH}`,\n })),\n ];\n\n return [\n ...formatSteps(steps),\n \"\",\n ...(done\n ? [\n `${out.green(CHECK)} ${out.bold(\"Migrated.\")} Commit the move, then:`,\n tip(out.cyan(\"penv validate\")),\n ]\n : [\n \"Your schema, config and loader are untouched, and every record keeps its name.\",\n tip(out.cyan(\"penv migrate --yes\")),\n ]),\n ];\n}\n\n/** The question, asked only against a real terminal — anything else has nobody to ask. */\nasync function approveOnTty(): Promise<boolean> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const answer = await rl.question(prompt(\"Move them\", \"y/N\"));\n return /^y(es)?$/i.test(answer.trim());\n } finally {\n rl.close();\n }\n}\n\nexport const migrateCommand = defineCommand({\n meta: {\n name: \"migrate\",\n description: `Move a project written under an earlier layout to ${RECORDS_PATH}/`,\n },\n args: {\n yes: { type: \"boolean\", description: \"Apply the previewed move without asking\" },\n },\n run({ args }) {\n return guard(async () => {\n const plan = planMigrate(process.cwd());\n if (isNoop(plan)) {\n write(renderMigrate({ ...plan, status: \"current\" }));\n return;\n }\n\n write(renderMigrate({ ...plan, status: \"previewed\" }));\n const approved =\n args.yes === true || (process.stdin.isTTY === true && (await approveOnTty()));\n if (!approved) {\n return;\n }\n write([\"\", ...renderMigrate(applyMigrate(plan))]);\n });\n },\n});\n","/**\n * `penv mv <from> <to>` — rename a parameter, every scope at once.\n *\n * A parameter is not one file. It is up to eight — four cascade levels, each\n * with a plaintext and an encrypted address — plus its meta, and a rename that\n * moved some of them would split one parameter into two. So this moves all of\n * them or none of them, and the whole plan is checked before a single byte is\n * written.\n *\n * **This is the only correct way to move an encrypted value.** A ciphertext is\n * sealed against the address it lives at, so `mv redis-password.production.enc\n * redis/password.production.enc` at the shell produces a file that will never\n * open again — the value is not moved, it is destroyed, and the shell reports\n * success. Re-sealing at the new address is the whole reason this command\n * exists: penv asked for namespacing to be \"a deliberate refactor afterwards\"\n * and then, once values could be encrypted, made doing it by hand a way to lose\n * them.\n *\n * It moves the tree and never the schema. `.penv/env.ts` is yours (invariant 2),\n * so renaming `database-url` to `database/url` leaves it declaring the old access\n * path — and the drift report is what says so. penv names the distance; you close\n * it. This command's report says which line to change rather than changing it.\n */\n\nimport type { Meta, ParameterRef, ValueFile } from \"@penvhq/core\";\nimport {\n accessPath,\n formatMetaFile,\n formatValueFile,\n openValue,\n PenvError,\n parameterId,\n recordPath,\n sealValue,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { Project } from \"../project.js\";\nimport {\n assertWritableKey,\n keySourceFor,\n openProject,\n refFromKey,\n schemaShapeFileOf,\n} from \"../project.js\";\nimport { CHECK, formatRows, guard, type Row, tip, write } from \"../ui.js\";\n\nexport interface MoveOptions {\n readonly cwd: string;\n readonly from: string;\n readonly to: string;\n}\n\nexport interface MovedFile {\n readonly from: string;\n readonly to: string;\n /** True when the value was opened and sealed again for its new address. */\n readonly resealed: boolean;\n}\n\nexport interface MoveResult {\n readonly from: string;\n readonly to: string;\n readonly files: readonly MovedFile[];\n /** The meta file's new location, or `undefined` when the parameter had none. */\n readonly meta: string | undefined;\n /** The access path the schema still declares, and the one it should now. */\n readonly schema: { readonly was: string; readonly now: string };\n /** The file that holds the shape to rename — cohort-aware, so the tip names one that exists. */\n readonly schemaFile: string;\n}\n\n/** The environment a scope names, or `undefined` for the scopes that name none. */\nfunction environmentOf(file: ValueFile): string | undefined {\n const scope = file.scope;\n return scope.kind === \"environment\" || scope.kind === \"environment-local\"\n ? scope.environment\n : undefined;\n}\n\n/** One file's move, resolved to the bytes that will be written at the far end. */\ninterface Planned {\n readonly source: ValueFile;\n readonly target: ValueFile;\n readonly contents: string;\n readonly resealed: boolean;\n}\n\n/**\n * Reads one file and works out what it must say at its new address.\n *\n * A plaintext value is bytes and moves as bytes. An encrypted one cannot: the\n * address is authenticated, so the ciphertext is only valid where it is. It is\n * opened here and sealed again below — and if it cannot be opened, the whole move\n * is refused rather than carrying a file to a place it will never open from.\n */\nasync function planFile(\n project: Project,\n source: ValueFile,\n target: ValueFile,\n parameter: string,\n): Promise<Planned | undefined> {\n const stored = await project.provider.read(source);\n if (stored === undefined) {\n return undefined;\n }\n if (!source.encrypted) {\n return { source, target, contents: stored, resealed: false };\n }\n\n // A key is declared per environment, so a sealed value at a scope that names\n // none has no key penv can choose — the same refusal `penv set` makes, for the\n // same reason, and the same one that keeps penv from creating such a file.\n const environment = environmentOf(source);\n if (environment === undefined) {\n throw new PenvError(\n \"SECRET_SCOPE_AMBIGUOUS\",\n `${recordPath(formatValueFile(source))} is encrypted at a scope that names no environment, so penv cannot tell which key would re-seal it`,\n \"A key is declared by its environment's `keySource` in penv.config.ts. Decrypt it with \" +\n \"`penv decrypt`, move the parameter, then encrypt it again at its new address.\",\n );\n }\n\n const keys = keySourceFor(project, environment);\n const opened = openValue(source, stored, keys);\n if (opened.kind === \"failed\") {\n throw new PenvError(\n \"VALUE_UNDECRYPTABLE\",\n `${recordPath(formatValueFile(source))} could not be decrypted, so penv cannot re-seal it at its new address: ${opened.failure.detail}`,\n \"A sealed value is bound to the file it lives in, so moving it means opening it and \" +\n \"sealing it again. Make the key available and run this again. Nothing has been moved.\",\n );\n }\n\n return {\n source,\n target,\n contents: sealValue(target, opened.value, keys, parameter, environment),\n resealed: true,\n };\n}\n\n/** Every file the provider actually holds for one parameter. */\nfunction filesOf(all: readonly ValueFile[], ref: ParameterRef): ValueFile[] {\n const id = parameterId(ref);\n return all.filter((file) => parameterId(file) === id);\n}\n\nexport async function runMove(options: MoveOptions): Promise<MoveResult> {\n const project = openProject(options.cwd);\n const from = refFromKey(options.from, project.config);\n assertWritableKey(options.to);\n const to = refFromKey(options.to, project.config);\n\n if (parameterId(from) === parameterId(to)) {\n throw new PenvError(\n \"PARAMETER_UNCHANGED\",\n `\\`${options.from}\\` and \\`${options.to}\\` are the same parameter`,\n \"Name a different destination, e.g. `penv mv redis-password redis/password`.\",\n );\n }\n\n const all = await project.provider.list();\n const sources = filesOf(all, from);\n const meta: Meta | undefined = await project.provider.readMeta(from);\n\n if (sources.length === 0 && meta === undefined) {\n throw new PenvError(\n \"PARAMETER_ABSENT\",\n `Parameter ${parameterId(from)} has no value files and no meta, so there is nothing to move`,\n `\\`penv list\\` shows every parameter penv holds.`,\n );\n }\n\n // Nothing is overwritten, ever. A destination that already exists is two\n // parameters being merged into one, which loses whichever penv wrote second —\n // the same loss `validate` refuses for name collisions (invariant 12).\n const occupied = filesOf(all, to);\n if (occupied.length > 0 || (await project.provider.readMeta(to)) !== undefined) {\n throw new PenvError(\n \"PARAMETER_EXISTS\",\n `Parameter ${parameterId(to)} already exists, and penv will not merge two parameters into one`,\n `Remove or rename ${parameterId(to)} first. \\`penv get ${options.to} --explain\\` shows every file it holds.`,\n );\n }\n\n // Planned in full before anything is written. Every read, every decryption and\n // every key lookup happens here, so a move that cannot finish fails having\n // changed nothing — rather than halfway, with a parameter that is now two.\n const planned: Planned[] = [];\n for (const source of sources) {\n const target: ValueFile = { ...source, namespace: to.namespace, name: to.name };\n const one = await planFile(project, source, target, parameterId(to));\n if (one !== undefined) {\n planned.push(one);\n }\n }\n\n for (const file of planned) {\n await project.provider.write(file.target, file.contents);\n }\n if (meta !== undefined) {\n await project.provider.writeMeta(to, meta);\n }\n\n // Removed only once every new file is on disk, so the value is never in\n // neither place. The cost is a window where it is in both, which a crash\n // leaves recoverable; the reverse leaves it gone.\n for (const file of planned) {\n await project.provider.remove(file.source);\n }\n if (meta !== undefined) {\n await project.provider.removeMeta(from);\n }\n\n return {\n from: parameterId(from),\n to: parameterId(to),\n files: planned.map((file) => ({\n from: formatValueFile(file.source),\n to: formatValueFile(file.target),\n resealed: file.resealed,\n })),\n // The meta's path, not the parameter's dotted id: `redis.password` is what\n // the schema calls it and `redis/password.json` is the file, and a report\n // that printed the first while moving the second names no file on disk.\n meta: meta === undefined ? undefined : formatMetaFile({ ...to, format: \"json\" }),\n schema: { was: accessPath(from).join(\".\"), now: accessPath(to).join(\".\") },\n schemaFile: schemaShapeFileOf(project),\n };\n}\n\nexport function renderMove(result: MoveResult): string[] {\n const rows: Row[] = result.files.map((file) => ({\n glyph: CHECK,\n label: \"Moved\",\n subject: recordPath(file.to),\n ...(file.resealed ? { detail: \"re-sealed for its new address\" } : {}),\n }));\n if (result.meta !== undefined) {\n rows.push({ glyph: CHECK, label: \"Moved\", subject: recordPath(result.meta) });\n }\n\n const lines = formatRows(rows);\n // The tree moved and the schema did not, because the schema is the user's file\n // and penv does not write it. Saying so here is cheaper than letting them find\n // out from a failing `validate` — and it names the edit rather than the fault.\n lines.push(\n \"\",\n tip(\n `${result.schemaFile} still declares \\`${result.schema.was}\\` — rename it to \\`${result.schema.now}\\`, ` +\n \"or `penv validate` will report the value as unused and the declaration as unset.\",\n ),\n );\n return lines;\n}\n\nexport const mvCommand = defineCommand({\n meta: { name: \"mv\", description: \"Rename a parameter, every scope and its meta at once\" },\n args: {\n from: {\n type: \"positional\",\n required: true,\n description: \"The parameter now, e.g. redis-password\",\n },\n to: {\n type: \"positional\",\n required: true,\n description: \"The parameter after, e.g. redis/password\",\n },\n },\n run({ args }) {\n return guard(async () => {\n write(renderMove(await runMove({ cwd: process.cwd(), from: args.from, to: args.to })));\n });\n },\n});\n","/**\n * `penv remove <key>` — delete one value file.\n *\n * The scope is selected exactly as `penv set` selects it, so what you removed is\n * the file you would have written. Meta is left alone: policy is a property of\n * the parameter across every environment, not of the value you just deleted.\n */\n\nimport type { ValueFile } from \"@penvhq/core\";\nimport { formatValueFile, recordPath } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { openProject, refFromKey } from \"../project.js\";\nimport { CHECK, formatRows, guard, type Row, WARN, write } from \"../ui.js\";\nimport { type ScopeOptions, targetScope } from \"./set.js\";\n\nexport interface RemoveOptions extends ScopeOptions {\n readonly cwd: string;\n readonly key: string;\n}\n\nexport interface RemoveResult {\n readonly parameter: string;\n /** The value files that existed and are now gone, relative to the records tree. */\n readonly removed: readonly string[];\n /** Both files penv looked at, whether or not they were there. */\n readonly considered: readonly string[];\n}\n\nexport async function runRemove(options: RemoveOptions): Promise<RemoveResult> {\n const project = openProject(options.cwd);\n const ref = refFromKey(options.key);\n\n // The same scope selection `set` writes through, for the same reason: the file\n // `remove` names has to be the file `set` named, byte for byte.\n const scope = targetScope(project, options, options.key);\n // `.enc` is orthogonal to scope: the encrypted file at this scope is the same\n // parameter at the same precedence, so removing the scope removes both.\n const files: ValueFile[] = [false, true].map((encrypted) => ({\n namespace: ref.namespace,\n name: ref.name,\n scope,\n encrypted,\n }));\n\n const removed: string[] = [];\n for (const file of files) {\n if ((await project.provider.read(file)) === undefined) {\n continue;\n }\n await project.provider.remove(file);\n removed.push(formatValueFile(file));\n }\n\n return {\n parameter: options.key,\n removed,\n considered: files.map((file) => formatValueFile(file)),\n };\n}\n\nexport function renderRemove(result: RemoveResult): string[] {\n if (result.removed.length === 0) {\n const first = result.considered[0] ?? result.parameter;\n return formatRows([\n {\n glyph: WARN,\n label: \"Nothing to remove\",\n subject: recordPath(first),\n detail: \"no value file at that scope\",\n },\n ]);\n }\n const rows: Row[] = result.removed.map((location) => ({\n glyph: CHECK,\n label: \"Removed\",\n subject: recordPath(location),\n }));\n return formatRows(rows);\n}\n\nexport const removeCommand = defineCommand({\n meta: { name: \"remove\", description: \"Delete a parameter\" },\n args: {\n key: { type: \"positional\", required: true, description: \"The parameter, e.g. redis/password\" },\n env: { type: \"string\", description: \"Remove the <name>.<env> scope\" },\n local: {\n type: \"boolean\",\n description: \"Remove the personal override: <name>.<env>.local with --env, else <name>.local\",\n },\n },\n run({ args }) {\n return guard(async () => {\n write(\n renderRemove(\n await runRemove({\n cwd: process.cwd(),\n key: args.key,\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.local === undefined ? {} : { local: args.local }),\n }),\n ),\n );\n });\n },\n});\n","/**\n * `penv rotate <key>` — turn one parameter over to a new value, by the mechanism\n * its meta declares, against the environment's source-of-truth provider.\n *\n * The two mechanisms are two different physics, never one code path with a flag\n * (rotation.ts says as much). `dual-valid` is a *window*: the new value goes live\n * while the provider still serves the old one, both credentials valid at once,\n * and the window closes only when every reader has moved over. `atomic-cutover`\n * is an *instant*: one flip, old value gone the moment the new one lands, no\n * overlap to hold open. So the command shape mirrors the physics —\n *\n * - `--begin` / `--complete` bracket a `dual-valid` window (`active → rotating →\n * active`), and demand a {@link RetainingProvider}, because a window whose old\n * value the provider does not retain is not a window at all — the overlap the\n * mechanism promises would silently not exist. penv refuses that up front\n * rather than opening a grace window that is a fiction.\n * - a bare `penv rotate` is the `atomic-cutover` flip: write the new value and\n * stamp the completion in one step, never touching `rotatingSince`, never\n * requiring retention — there is no penv-layer overlap to record or to lean on.\n *\n * Like `push`, the real work is an exported plain function returning a structured\n * result, and `now` is injectable so the meta clocks are testable without mocking\n * time. The rotation clock itself lives in core (`beginRotation` /\n * `completeRotation`); this command only decides *which* to apply, writes the\n * value at the right moment relative to it, and persists both to the provider.\n */\n\nimport type {\n Meta,\n ParameterRef,\n Provider,\n RetainingProvider,\n RotationMechanism,\n RotationState,\n ValueFile,\n} from \"@penvhq/core\";\nimport {\n beginRotation,\n completeRotation,\n holdsRecords,\n PenvError,\n retainsPrevious,\n rotationOf,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { Project } from \"../project.js\";\nimport { openProject, refFromKey, sourceProviderFor, targetEnvironment } from \"../project.js\";\nimport { LOCAL_TREE_TYPE } from \"../registry.js\";\nimport { CHECK, formatRows, guard, write } from \"../ui.js\";\nimport { readStdin, sealAwareWrite } from \"./set.js\";\n\nexport interface RotateOptions {\n readonly cwd: string;\n readonly key: string;\n readonly environment?: string;\n /** Open a `dual-valid` window: write the new value while the old is still retained. */\n readonly begin?: boolean;\n /** Close a `dual-valid` window: return to `active`, stamp the completion. */\n readonly complete?: boolean;\n /**\n * The new value. A `begin` and an `atomic-cutover` flip write it; a `complete`\n * does not touch the value at all, so it needs none. Injected in tests; on the\n * CLI it is the positional argument or stdin, the same source `set` reads.\n */\n readonly value?: string;\n /** Injected in tests: the wall-clock reading recorded in meta. Defaults to now. */\n readonly now?: string;\n}\n\n/** The single step a run performed — the three the two mechanisms decompose into. */\nexport type RotatePhase = \"begin\" | \"complete\" | \"cutover\";\n\nexport interface RotateResult {\n readonly parameter: string;\n readonly environment: string;\n readonly mechanism: RotationMechanism;\n readonly phase: RotatePhase;\n /** The source provider's type — where the value and its meta were written. */\n readonly source: string;\n /** True when this run wrote a new value. `begin` and `cutover` do; `complete` does not. */\n readonly wroteValue: boolean;\n /** The rotation state after this run — `rotating` after a begin, `active` otherwise. */\n readonly state: RotationState;\n /** When the current window opened, ISO. Set only after a `begin`, else `null`. */\n readonly rotatingSince: string | null;\n /** When a rotation last completed, ISO. Set after a `complete` or a `cutover`. */\n readonly lastRotated: string | null;\n}\n\n/**\n * The value file a rotation writes to a *backend* and reads back — the parameter\n * at its environment scope, verbatim.\n *\n * A rotating secret belongs to exactly one environment (the credential Vault\n * issues for production is not development's), so the environment scope is its\n * home, and pinning it here is what lets `readPrevious` find the prior version\n * during the window: the write and the retention read must address the same\n * value file byte-for-byte. `encrypted: false` because the value crosses to a\n * backend source of truth verbatim, the way `push` moves it — the backend holds\n * custody of its own store, and penv's envelope is the *local tree's* concern,\n * not the backend's. When the source of truth is instead the local tree,\n * {@link writeRotatedValue} routes to {@link sealAwareWrite}, which seals per\n * meta and removes the twin; this file shape is only ever the backend's.\n */\nfunction rotatingFile(ref: ParameterRef, environment: string): ValueFile {\n return {\n namespace: ref.namespace,\n name: ref.name,\n scope: { kind: \"environment\", environment },\n encrypted: false,\n };\n}\n\n/**\n * Writes the new value to the environment's source of truth, by the custody rule\n * the store's *type* sets — the fix for a rotation that used to persist the live\n * credential as cleartext.\n *\n * The local `.penv` tree is penv's own to seal, so a secret rotated into it must\n * be sealed and its plaintext twin removed, exactly as `set` does: otherwise the\n * value lands as cleartext `.penv/<name>.<env>`, which is committed to git and,\n * because plaintext outranks `.enc` at one scope, also shadows any sealed copy\n * already there. So the local tree goes through {@link sealAwareWrite}, honouring\n * meta's policy. A real backend (vault, mock) holds custody of its own store and\n * penv's envelope is not its concern — the value crosses verbatim via\n * {@link rotatingFile}, the way `push` sends plaintext for a projection destination to re-seal.\n *\n * `--begin` only ever reaches a backend (a dual-valid window demands a retaining\n * provider, which the local tree is not), but it is routed here too, so both\n * value-write sites share one custody decision.\n */\nasync function writeRotatedValue(\n project: Project,\n provider: Provider,\n ref: ParameterRef,\n environment: string,\n value: string,\n): Promise<void> {\n if (provider.type === LOCAL_TREE_TYPE) {\n await sealAwareWrite({\n project,\n provider,\n ref,\n scope: { kind: \"environment\", environment },\n value,\n environment,\n });\n return;\n }\n await provider.write(rotatingFile(ref, environment), value);\n}\n\n/** The new value a write step requires, or a refusal that names the phase needing it. */\nfunction requireNewValue(value: string | undefined, phase: RotatePhase, key: string): string {\n if (value === undefined) {\n throw new PenvError(\n \"ROTATION_NO_VALUE\",\n `A ${phase} rotation of ${key} writes a new value, and none was given`,\n \"Pass the new value as the argument — `penv rotate <key> <value>` — or pipe it in on stdin.\",\n );\n }\n return value;\n}\n\n/**\n * A `dual-valid` rotation against a provider that does not retain its previous\n * value — the one situation the mechanism cannot survive, refused before a single\n * write.\n *\n * The window's whole promise is that the old credential keeps working while the\n * new one takes over; a provider that overwrites in place breaks that the instant\n * `begin` writes, and no meta clock can put the old value back. So this is not a\n * best-effort with a warning — it is a hard refusal, thrown here so the caller\n * never opens a grace window that is already a lie. `atomic-cutover` reaches this\n * function's callers not at all: it has no overlap to retain.\n */\nfunction requireRetaining(provider: Provider, environment: string): RetainingProvider {\n if (!retainsPrevious(provider)) {\n throw new PenvError(\n \"ROTATION_NOT_RETAINING\",\n `A dual-valid rotation needs the previous value to stay readable during the grace window, and the \\`${provider.type}\\` provider for environment ${environment} does not retain it`,\n \"Point this environment at a provider that keeps prior versions (its `readPrevious` is what penv reads during the window), \" +\n \"or, if a momentary overlap is not required, declare the parameter `atomic-cutover` in its meta and flip it in one step.\",\n );\n }\n return provider;\n}\n\nexport async function runRotate(options: RotateOptions): Promise<RotateResult> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment);\n const ref = refFromKey(options.key, project.config);\n const source = await sourceProviderFor(project, environment);\n\n // A rotation reads state back mid-flight — the phase in meta, the previous\n // value during a grace window — and a projection-holding store cannot return\n // either. Refused on the declared capability, before a single write.\n if (!holdsRecords(source)) {\n throw new PenvError(\n \"ROTATION_NOT_RECORDS\",\n `Environment ${environment} is backed by \\`${source.type}\\`, which holds a resolved projection penv cannot rotate in place`,\n \"Rotate the parameter in the environment that holds the records (the local tree, Vault, SSM), \" +\n \"then `penv push` the result to this destination.\",\n );\n }\n const provider: Provider = source;\n\n const nowIso = options.now ?? new Date().toISOString();\n const before: Meta | undefined = await provider.readMeta(ref);\n const { mechanism } = rotationOf(before, environment);\n\n if (mechanism === undefined) {\n throw new PenvError(\n \"ROTATION_NO_MECHANISM\",\n `Parameter ${options.key} declares no rotation mechanism for environment ${environment}, so penv does not know how to rotate it`,\n 'Set `rotationMechanism` in the parameter\\'s meta to `\"dual-valid\"` (a grace-window overlap) or ' +\n '`\"atomic-cutover\"` (a single flip), then run `penv rotate` again.',\n );\n }\n\n const begin = options.begin === true;\n const complete = options.complete === true;\n\n // atomic-cutover: one flip, and `--begin`/`--complete` have no meaning for it —\n // there is no window to bracket. Refuse the flags rather than silently ignore\n // them, so a user who reached for a two-phase rotation learns their parameter\n // is not one before anything is written.\n if (mechanism === \"atomic-cutover\") {\n if (begin || complete) {\n throw new PenvError(\n \"ROTATION_MECHANISM_MISMATCH\",\n `Parameter ${options.key} is atomic-cutover, which flips in one step, so \\`--begin\\`/\\`--complete\\` do not apply`,\n \"Run `penv rotate <key> <value>` with no phase flag to flip it. `--begin`/`--complete` bracket a \" +\n \"dual-valid grace window, which atomic-cutover has none of.\",\n );\n }\n const value = requireNewValue(options.value, \"cutover\", options.key);\n // Value first, then the completion stamp — the flip and its record, in the\n // order that leaves the value present before anything claims it rotated. The\n // write honours the store's custody rule: sealed into the local tree per\n // meta, verbatim to a backend.\n await writeRotatedValue(project, provider, ref, environment, value);\n const after = completeRotation(before, environment, nowIso);\n await provider.writeMeta(ref, after);\n return result(ref, environment, mechanism, \"cutover\", provider.type, true, after);\n }\n\n // dual-valid from here: every path needs a retaining provider, and the two\n // phases are mutually exclusive — exactly one bracket per run.\n const retaining = requireRetaining(provider, environment);\n\n if (begin === complete) {\n throw new PenvError(\n \"ROTATION_PHASE_REQUIRED\",\n `A dual-valid rotation of ${options.key} needs exactly one of \\`--begin\\` or \\`--complete\\``,\n \"`--begin` writes the new value and opens the grace window; `--complete` closes it once every reader \" +\n \"has moved to the new value. Run them in that order, one at a time.\",\n );\n }\n\n if (begin) {\n const value = requireNewValue(options.value, \"begin\", options.key);\n // The new value is written while the provider still holds the previous one —\n // that co-existence IS the window, and `readPrevious` serves the old value\n // until `--complete` closes it. Value first, then `rotatingSince`, so the\n // clock never claims a window an unwritten value has not yet opened. A\n // retaining provider is always a backend, so this crosses verbatim; routed\n // through the shared helper so both write sites share one custody decision.\n await writeRotatedValue(project, retaining, ref, environment, value);\n const after = beginRotation(before, environment, nowIso);\n await retaining.writeMeta(ref, after);\n return result(ref, environment, mechanism, \"begin\", retaining.type, true, after);\n }\n\n // --complete: the window closes. No value is written — the new value has been\n // live since `--begin`; this only returns the clock to `active` and stamps the\n // completion. The provider's previous version may be pruned any time after.\n const after = completeRotation(before, environment, nowIso);\n await retaining.writeMeta(ref, after);\n return result(ref, environment, mechanism, \"complete\", retaining.type, false, after);\n}\n\n/** Reads the settled clocks back out of the meta just written, so the result is the record. */\nfunction result(\n ref: ParameterRef,\n environment: string,\n mechanism: RotationMechanism,\n phase: RotatePhase,\n source: string,\n wroteValue: boolean,\n after: Meta,\n): RotateResult {\n const { state, rotatingSince, lastRotated } = rotationOf(after, environment);\n return {\n parameter: [...ref.namespace, ref.name].join(\"/\"),\n environment,\n mechanism,\n phase,\n source,\n wroteValue,\n state,\n rotatingSince,\n lastRotated,\n };\n}\n\nexport function renderRotate(result: RotateResult): string[] {\n if (result.phase === \"begin\") {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Rotating\",\n subject: result.parameter,\n detail: `dual-valid window open for environment ${result.environment} (since ${result.rotatingSince})`,\n },\n {\n glyph: CHECK,\n label: \"Previous\",\n subject: \"still readable\",\n detail: `on the ${result.source} provider until \\`penv rotate ${result.parameter} --complete\\``,\n },\n ]);\n }\n if (result.phase === \"complete\") {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Rotated\",\n subject: result.parameter,\n detail: `dual-valid window closed for environment ${result.environment} (completed ${result.lastRotated})`,\n },\n ]);\n }\n return formatRows([\n {\n glyph: CHECK,\n label: \"Rotated\",\n subject: result.parameter,\n detail: `atomic-cutover flip for environment ${result.environment} (completed ${result.lastRotated})`,\n },\n ]);\n}\n\nexport const rotateCommand = defineCommand({\n meta: {\n name: \"rotate\",\n description: \"Rotate a parameter's value by the mechanism its meta declares\",\n },\n args: {\n key: { type: \"positional\", required: true, description: \"The parameter, e.g. redis/password\" },\n value: {\n type: \"positional\",\n required: false,\n description: \"The new value; read from stdin if omitted. Not needed with --complete\",\n },\n env: { type: \"string\", description: \"The environment to rotate in\" },\n begin: { type: \"boolean\", description: \"Open a dual-valid grace window with the new value\" },\n complete: { type: \"boolean\", description: \"Close a dual-valid grace window\" },\n },\n run({ args }) {\n return guard(async () => {\n // `--complete` writes no value, so it never blocks on stdin waiting for one\n // that will not come. Every other path reads the value the way `set` does.\n const value = args.complete === true ? undefined : (args.value ?? (await readStdin()));\n write(\n renderRotate(\n await runRotate({\n cwd: process.cwd(),\n key: args.key,\n ...(value === undefined ? {} : { value }),\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.begin === undefined ? {} : { begin: args.begin }),\n ...(args.complete === undefined ? {} : { complete: args.complete }),\n }),\n ),\n );\n });\n },\n});\n","/**\n * `penv watch` — re-run validation whenever the configuration changes.\n *\n * Watch mode reports `penv validate`'s verdict on a loop, and never a second\n * opinion about it: the diagnostics come from `runValidate` itself, so there is\n * no watch-mode verdict that could drift from the command CI runs.\n *\n * It prints one thing `validate` does not — the schema↔tree drift report, which\n * `runValidate` measures and hands back without letting it touch `ok`. The two\n * commands differ because their readers do. CI wants a verdict, and a warning\n * about a parameter the schema tolerates would be noise in a log nobody reads on\n * a passing run. The person with `watch` open is mid-edit, and the distance\n * between what they have just declared and what the tree holds is the thing they\n * are watching *for*. Same facts, same measurement, one of them worth printing\n * only where someone is looking.\n *\n * Three things decide the answer, so three things are watched: the `.penv/` tree\n * (the values and their meta), `penv.config.ts` (the environment whitelist, and\n * the `override` block), and the schema. The schema is two modules: the shape\n * (`penv.schema.ts`, the `z.object` every consumer derives from) always lives at\n * the project root, outside the tree, so nothing above watches it — it gets its\n * own watcher, always. The loader (`.penv/env.ts`, the wrapper `schemaFile` names)\n * is inside the tree at the default and the recursive watcher already covers it; a\n * second watcher on it would report every edit twice, so it earns one only when\n * `schemaFile` moves it outside `.penv/`.\n *\n * `node:fs` does the watching. A dependency-free watcher is worth the handful of\n * lines here: the events this needs are the ones the platform already reports,\n * and debouncing them is the whole of what a library would add.\n */\n\nimport type { FSWatcher } from \"node:fs\";\nimport { existsSync, watch } from \"node:fs\";\nimport { basename, dirname, resolve } from \"node:path\";\nimport { SCHEMA_SHAPE_FILE, schemaFileOf, schemaInsideTree } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { openProject } from \"../project.js\";\nimport type { DriftReport } from \"../schema.js\";\nimport { out } from \"../style.js\";\nimport { formatRows, guard, type Row, reportError, tip, WARN, write } from \"../ui.js\";\nimport type { ValidateResult } from \"./validate.js\";\nimport { renderValidate, runValidate } from \"./validate.js\";\n\n/**\n * Long enough to coalesce an editor's save into one run, short enough to feel\n * immediate. An atomic save is a write, a rename, and sometimes a delete, and a\n * run per event would validate a tree mid-rewrite and report a file that exists\n * again by the time the user reads the line.\n */\nconst DEBOUNCE_MS = 100;\n\nexport interface WatchOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Defaults to {@link DEBOUNCE_MS}. */\n readonly debounceMs?: number;\n /** Called with every completed validation, starting with the initial one. */\n readonly onResult?: (result: ValidateResult) => void;\n /**\n * Called when a cycle could not produce a result at all — an unreadable\n * config, a watcher the platform dropped. Never called for a *failing*\n * validation: that is a result, and it goes to `onResult`.\n */\n readonly onError?: (error: unknown) => void;\n}\n\nexport interface WatchHandle {\n /** Stops watching. Idempotent, and safe to call from inside a callback. */\n close(): void;\n}\n\n/**\n * Watches, and re-validates on change.\n *\n * Returns a handle rather than blocking, so the loop is a plain object a test\n * can drive and close instead of a live process it would have to spawn. The\n * command below is the only thing that turns it into a process that waits.\n */\nexport function runWatch(options: WatchOptions): WatchHandle {\n // Fails fast, and before any watcher exists: a watch on a directory that is\n // not a penv project would report the same error on every keystroke instead.\n const project = openProject(options.cwd);\n const configFile = basename(project.configFile);\n const debounceMs = options.debounceMs ?? DEBOUNCE_MS;\n\n const watchers = new Set<FSWatcher>();\n let timer: ReturnType<typeof setTimeout> | undefined;\n let running = false;\n let pending = false;\n let closed = false;\n\n async function validate(): Promise<void> {\n if (closed) {\n return;\n }\n // One run at a time: a save that lands mid-run would otherwise read the tree\n // twice at once and report whichever finished last.\n if (running) {\n pending = true;\n return;\n }\n running = true;\n try {\n const result = await runValidate({\n cwd: options.cwd,\n ...(options.environment === undefined ? {} : { environment: options.environment }),\n });\n if (!closed) {\n options.onResult?.(result);\n }\n } catch (error) {\n // A file can vanish between the event and the read — that is what an\n // atomic save looks like from here. Report it and keep watching: the\n // rename that follows will schedule the run that gets the real answer.\n if (!closed) {\n options.onError?.(error);\n }\n } finally {\n running = false;\n if (pending && !closed) {\n pending = false;\n void validate();\n }\n }\n }\n\n function schedule(): void {\n if (closed) {\n return;\n }\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n timer = setTimeout(() => {\n timer = undefined;\n void validate();\n }, debounceMs);\n }\n\n function stop(watcher: FSWatcher): void {\n watchers.delete(watcher);\n watcher.close();\n }\n\n /**\n * Waits for a vanished target to come back, by watching its parent for the\n * name to reappear.\n *\n * A branch switch is a delete and then a create, so a watch that merely\n * stopped at the delete would be silent for the rest of the session — the\n * user would be reading a report of a tree that has since returned. The\n * re-armed watcher validates on arrival rather than trusting the report the\n * deletion produced.\n */\n function armRecovery(target: string, recursive: boolean, only?: string): void {\n const parent = dirname(target);\n const name = basename(target);\n let recovery: FSWatcher | undefined;\n\n try {\n recovery = watch(parent, { recursive: false }, (_event, filename) => {\n if (closed || recovery === undefined) {\n return;\n }\n // The parent went too. Watching it would spin exactly the way the\n // vanished target did, and there is nothing left to recover from.\n if (!existsSync(parent)) {\n stop(recovery);\n return;\n }\n if (filename !== null && basename(filename) !== name) {\n return;\n }\n if (!existsSync(target)) {\n return;\n }\n stop(recovery);\n addWatcher(target, recursive, only);\n schedule();\n });\n } catch (error) {\n options.onError?.(error);\n return;\n }\n\n recovery.on(\"error\", (error) => {\n if (!closed) {\n options.onError?.(error);\n }\n });\n watchers.add(recovery);\n }\n\n /**\n * `recursive` is not available on every platform, so a watcher that cannot\n * have it watches the directory itself. Namespace folders below it go\n * unwatched there, which is a weaker watch — never a wrong validation, since\n * the answer always comes from a fresh `runValidate`.\n */\n function addWatcher(target: string, recursive: boolean, only?: string): void {\n let watcher: FSWatcher | undefined;\n\n const listen = (useRecursive: boolean): FSWatcher =>\n watch(target, { recursive: useRecursive }, (_event, filename) => {\n if (closed) {\n return;\n }\n // A deleted target does not stop its watcher, and on Windows does not\n // error either: it re-fires `rename` for the absent path tens of\n // thousands of times a second, forever. Left alone that pins a core,\n // and every event resets the debounce below, so the watch would burn\n // CPU while reporting nothing at all. The check costs a `stat` per\n // event, which is what a `.penv/` that is still there is worth.\n //\n // Deleting the tree is a change like any other, so it is scheduled\n // rather than reported as a failure: `runValidate` has a real verdict\n // for a missing `.penv/`, and watch's job is to say what validate says.\n if (!existsSync(target)) {\n if (watcher !== undefined) {\n stop(watcher);\n }\n armRecovery(target, recursive, only);\n schedule();\n return;\n }\n // Directories are watched rather than files so that an editor's\n // write-to-temp-then-rename is seen as a change to the real name. The\n // cost is hearing about neighbours, so the ones that matter are named.\n if (only !== undefined && (filename === null || basename(filename) !== only)) {\n return;\n }\n schedule();\n });\n\n try {\n watcher = listen(recursive);\n } catch (error) {\n if (!recursive) {\n options.onError?.(error);\n return;\n }\n try {\n watcher = listen(false);\n } catch (fallbackError) {\n options.onError?.(fallbackError);\n return;\n }\n }\n watcher.on(\"error\", (error) => {\n if (!closed) {\n options.onError?.(error);\n }\n });\n watchers.add(watcher);\n }\n\n addWatcher(project.recordsDir, true);\n addWatcher(dirname(project.configFile), false, configFile);\n\n // The schema shape declares what must exist, so an edit to it — a newly declared\n // parameter — changes the answer as much as a value does. It lives at the\n // project root, outside the tree the recursive watcher covers and filtered out\n // of the config-dir watcher above, so nothing else sees it: it always gets its\n // own watcher, or an edit to the one file `penv init` labels \"yours to edit\"\n // would fire nothing at all.\n addWatcher(project.root, false, SCHEMA_SHAPE_FILE);\n\n // The loader `schemaFile` names is the wrapper the alias resolves to. Inside the\n // tree it already has a watcher; one outside `.penv/` would have none, and a\n // watch that keeps reporting a verdict it can no longer see the reason for is the\n // silence this command exists to prevent.\n if (schemaInsideTree(project.config) === undefined) {\n const schemaFile = resolve(project.root, schemaFileOf(project.config));\n addWatcher(dirname(schemaFile), false, basename(schemaFile));\n }\n\n // The current answer, before anything changes: a watch that says nothing until\n // the next keystroke leaves the user guessing at the state they already have.\n void validate();\n\n return {\n close(): void {\n closed = true;\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n for (const watcher of [...watchers]) {\n stop(watcher);\n }\n },\n };\n}\n\n/**\n * One cycle's report: `penv validate`'s, with a rule above it — on a loop, the\n * reader's first question is where the last run ended — and the drift below it.\n *\n * Drift comes last because it is the part that is not a verdict. The rows above\n * say whether the configuration is valid; these say what the schema and the tree\n * disagree about, which is often *why*, and is worth reading even on a run that\n * passed.\n */\nexport function renderWatch(result: ValidateResult): string[] {\n return [\"\", ...renderValidate(result), ...renderDrift(result.drift, result.environment)];\n}\n\n/**\n * The drift rows. Nothing at all when the schema and the tree agree: a loop\n * reprints its whole report on every keystroke, and a block that says \"no drift\"\n * forever is the first thing the eye learns to skip past — taking the block that\n * matters with it.\n */\nexport function renderDrift(drift: DriftReport, environment: string): string[] {\n const rows: Row[] = [\n ...drift.declared.map((item) => ({\n glyph: WARN,\n label: \"Declared, no value\",\n subject: item.subject,\n detail: item.detail,\n })),\n ...drift.undeclared.map((item) => ({\n glyph: WARN,\n label: \"Unused parameter\",\n subject: item.variable,\n detail: \"present, not in schema\",\n })),\n ];\n if (rows.length === 0) {\n return [];\n }\n\n const lines = [\"\", out.bold(`Schema and tree differ for ${environment}:`), ...formatRows(rows)];\n // The paste block, exactly as `doctor` prints it — the reader who sees drift\n // here and drift there is looking at one report, not two that resemble each other.\n for (const remedy of new Set(drift.declared.map((item) => item.remedy))) {\n lines.push(tip(remedy));\n }\n return lines;\n}\n\nexport const watchCommand = defineCommand({\n meta: {\n name: \"watch\",\n description: \"Re-validate whenever .penv/ or penv.config.ts changes\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to validate\" },\n },\n run({ args }) {\n return guard(async () => {\n const handle = runWatch({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n onResult: (result) => {\n write(renderWatch(result));\n },\n // A failing cycle is reported and watching continues. `reportError`\n // marks the process failed, which `validate` wants and a loop does not:\n // a cycle that failed mid-save ten minutes ago must not decide the exit\n // code of a session the user ended deliberately. The message is what is\n // wanted here, not the verdict.\n onError: (error) => {\n const previous = process.exitCode;\n reportError(error);\n process.exitCode = previous;\n },\n });\n write([`Watching .penv/ and penv.config.ts. ${out.dim(\"Ctrl-C to stop.\")}`]);\n await new Promise<void>((resolve) => {\n process.once(\"SIGINT\", () => {\n handle.close();\n resolve();\n });\n });\n });\n },\n});\n"],"mappings":"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","names":["import_core","import_citty","import_node_fs","import_node_path","import_core","import_runtime","import_citty","import_node_fs","import_node_path","import_core","resolve","path","plan","plan","import_node_fs","import_node_path","import_core","import_provider_filesystem","import_core","import_node_fs","import_node_path","import_core","require","import_core","import_node_fs","import_node_module","import_node_path","import_core","import_citty","import_node_fs","import_core","import_core","result","import_node_path","import_node_url","import_core","import_citty","import_core","node","out","own","node","result","resolvePath","result","out","result","import_core","import_citty","import_node_fs","import_node_path","import_core","record","occupied","result","import_node_fs","import_node_path","import_core","import_citty","import_core","import_citty","resolve","result","out","report","import_core","import_citty","import_core","import_citty","result","result","import_core","import_citty","skipped","result","prompt","import_node_fs","import_node_path","import_core","import_citty","displayPath","result","import_core","import_citty","import_node_fs","import_node_path","import_core","import_citty","import_core","where","import_node_fs","import_node_path","import_core","relative","manifestOf","import_core","import_node_fs","import_node_path","import_core","import_citty","import_node_fs","import_node_path","NOT_ENVIRONMENTS","declaredIn","plan","where","relative","result","LOCAL","displayPath","result","report","import_core","import_citty","import_node_module","import_core","import_meta","firstLine","module","result","import_core","import_citty","scopeLabel","result","import_node_fs","import_node_path","import_promises","import_core","import_citty","describe","plan","result","import_core","import_citty","environmentOf","occupied","result","import_core","import_citty","result","import_core","import_citty","after","result","import_node_fs","import_node_path","import_core","import_citty","DEBOUNCE_MS","result","stop","resolve","cittyRunMain"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/artifact.ts","../src/install.ts","../src/child.ts","../src/project.ts","../src/env-flags.ts","../src/registry.ts","../src/ui.ts","../src/style.ts","../src/commands/run.ts","../src/dotenv-files.ts","../src/commands/pull.ts","../src/commands/validate.ts","../src/schema.ts","../src/commands/cleanup.ts","../src/cutover.ts","../src/commands/doctor.ts","../src/commands/push.ts","../src/input.ts","../src/commands/encrypt.ts","../src/commands/set.ts","../src/commands/fill.ts","../src/commands/generate.ts","../src/commands/get.ts","../src/commands/import.ts","../src/adopt.ts","../src/detect.ts","../src/draft-schema.ts","../src/commands/init.ts","../src/scaffold-undo.ts","../src/seams.ts","../src/commands/key.ts","../src/keychain.ts","../src/commands/list.ts","../src/commands/migrate.ts","../src/commands/mv.ts","../src/commands/remove.ts","../src/commands/rotate.ts","../src/commands/watch.ts"],"sourcesContent":["/**\n * penv's command line.\n *\n * The wiring here is deliberately thin: every command's real work is a plain\n * exported function that takes a `cwd` and returns a result, and citty only\n * parses arguments, calls it, and prints what it returned. That is what lets the\n * tests call the commands rather than spawn them.\n */\n\nimport { setKeychain } from \"@penvhq/core\";\nimport { runMain as cittyRunMain, defineCommand } from \"citty\";\nimport { artifactCommand } from \"./commands/artifact.js\";\nimport { cleanupCommand } from \"./commands/cleanup.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\nimport { decryptCommand, encryptCommand } from \"./commands/encrypt.js\";\nimport { fillCommand } from \"./commands/fill.js\";\nimport { generateCommand } from \"./commands/generate.js\";\nimport { getCommand } from \"./commands/get.js\";\nimport { importCommand } from \"./commands/import.js\";\nimport { initCommand } from \"./commands/init.js\";\nimport { keyCommand } from \"./commands/key.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { migrateCommand } from \"./commands/migrate.js\";\nimport { mvCommand } from \"./commands/mv.js\";\nimport { pullCommand } from \"./commands/pull.js\";\nimport { pushCommand } from \"./commands/push.js\";\nimport { removeCommand } from \"./commands/remove.js\";\nimport { rotateCommand } from \"./commands/rotate.js\";\nimport { runCommand } from \"./commands/run.js\";\nimport { setCommand } from \"./commands/set.js\";\nimport { validateCommand } from \"./commands/validate.js\";\nimport { watchCommand } from \"./commands/watch.js\";\nimport { engineVersion } from \"./install.js\";\nimport { defaultKeychain } from \"./keychain.js\";\n\nexport const main = defineCommand({\n // Lazy, so reading the engine's own version off disk is something `--version`\n // does rather than something importing this module does.\n meta: () => ({\n name: \"penv\",\n description: \"Configuration that shares a data model with your production secret manager\",\n version: engineVersion(),\n }),\n subCommands: {\n init: initCommand,\n import: importCommand,\n generate: generateCommand,\n get: getCommand,\n set: setCommand,\n fill: fillCommand,\n mv: mvCommand,\n pull: pullCommand,\n push: pushCommand,\n rotate: rotateCommand,\n run: runCommand,\n remove: removeCommand,\n list: listCommand,\n cleanup: cleanupCommand,\n migrate: migrateCommand,\n encrypt: encryptCommand,\n decrypt: decryptCommand,\n key: keyCommand,\n validate: validateCommand,\n doctor: doctorCommand,\n watch: watchCommand,\n artifact: artifactCommand,\n },\n});\n\nexport function runMain(): Promise<void> {\n // The CLI is where the keychain is read and written; core stays native-free and\n // the runtime never registers a binding. Idempotent, and the binding is lazy —\n // the native module loads only if a keychain key is actually touched.\n setKeychain(defaultKeychain);\n return cittyRunMain(main);\n}\n\nexport type { ArtifactBuildOptions, ArtifactBuildResult } from \"./commands/artifact.js\";\nexport { renderArtifactBuild, runArtifactBuild } from \"./commands/artifact.js\";\nexport type {\n DoctorCheck,\n DoctorFinding,\n DoctorReport,\n DoctorSeverity,\n} from \"./commands/doctor.js\";\nexport { renderDoctor, runDoctor } from \"./commands/doctor.js\";\nexport type { ResealResult } from \"./commands/encrypt.js\";\nexport { runDecrypt, runEncrypt } from \"./commands/encrypt.js\";\nexport type { FillOptions, FillPrompt, FillResult } from \"./commands/fill.js\";\nexport { renderFill, runFill } from \"./commands/fill.js\";\nexport type { GenerateResult } from \"./commands/generate.js\";\nexport { generateDotenv, runGenerate } from \"./commands/generate.js\";\nexport type { GetExplanation } from \"./commands/get.js\";\nexport { runExplain, runGet } from \"./commands/get.js\";\nexport type { ImportReport } from \"./commands/import.js\";\nexport { importDotenv } from \"./commands/import.js\";\nexport type {\n AdoptionPlan,\n CutoverPlan,\n CutoverResult,\n InitResult,\n InitStep,\n} from \"./commands/init.js\";\nexport {\n applyCutover,\n insertEnvAlias,\n planAdoption,\n planCutover,\n runInit,\n} from \"./commands/init.js\";\nexport type { ListResult } from \"./commands/list.js\";\nexport { runList } from \"./commands/list.js\";\nexport type { MigrateMove, MigratePlan, MigrateResult, MigrateStatus } from \"./commands/migrate.js\";\nexport { applyMigrate, planMigrate, renderMigrate, runMigrate } from \"./commands/migrate.js\";\nexport type { MoveResult } from \"./commands/mv.js\";\nexport { renderMove, runMove } from \"./commands/mv.js\";\nexport type { PullOptions, PullResult } from \"./commands/pull.js\";\nexport { renderPull, runPull } from \"./commands/pull.js\";\nexport type { PushOptions, PushResult } from \"./commands/push.js\";\nexport { LAST_PUSHED_KEY, renderPush, runPush } from \"./commands/push.js\";\nexport type { RemoveResult } from \"./commands/remove.js\";\nexport { runRemove } from \"./commands/remove.js\";\nexport type { RotateOptions, RotatePhase, RotateResult } from \"./commands/rotate.js\";\nexport { renderRotate, runRotate } from \"./commands/rotate.js\";\nexport type { RunOptions, RunResult, RunSource } from \"./commands/run.js\";\nexport { runRun } from \"./commands/run.js\";\nexport type { SetResult } from \"./commands/set.js\";\nexport { runSet } from \"./commands/set.js\";\nexport type { EnvironmentCheck, ValidateIssue, ValidateResult } from \"./commands/validate.js\";\nexport { checkEnvironment, runValidate } from \"./commands/validate.js\";\nexport type { WatchHandle, WatchOptions } from \"./commands/watch.js\";\nexport { renderWatch, runWatch } from \"./commands/watch.js\";\nexport type { CleanupResult, Cutover, UndoResult } from \"./cutover.js\";\nexport { runCleanup, runUndo } from \"./cutover.js\";\n","/**\n * `penv artifact build` — the sealed deployment artifact CI hands a release.\n *\n * It is the third step of the sequence PRD §7 names: pull the target\n * environment, validate it, build the artifact, mount it. Each step is a command\n * with one job, and this one's is narrow on purpose — it does not re-reach a\n * verdict `penv validate` already reaches, because two implementations of \"is\n * this configuration good\" would eventually let a release be built that CI had\n * already rejected.\n *\n * Two properties are the whole design:\n *\n * **It never decrypts.** A sealed value is copied ciphertext-and-address into\n * the artifact exactly as the record holds it, so building needs no key at all —\n * CI can produce a production artifact without ever being able to read one. The\n * AAD is still the value file's full name, so the ciphertext stays bound to the\n * scope it was sealed at (invariant 17).\n *\n * **It refuses to guess the environment.** `--env` is named explicitly and never\n * defaulted, `--out` likewise. An artifact built for \"whatever the default was\"\n * is a release that ships the wrong environment's credentials, and the default\n * that made it is one config edit nobody reviewed.\n */\n\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, relative, resolve } from \"node:path\";\nimport type { Artifact, ArtifactEntry, ParameterRef, ValueFile } from \"@penvhq/core\";\nimport {\n ARTIFACT_FORMAT,\n candidatesFor,\n deliveryDigest,\n formatValueFile,\n isSecret,\n keySourceIdentifier,\n PenvError,\n parameterId,\n serializeArtifact,\n variableName,\n} from \"@penvhq/core\";\nimport { assertDeliverableNames, declaredRefs } from \"@penvhq/runtime\";\nimport { defineCommand } from \"citty\";\nimport { engineVersion } from \"../install.js\";\nimport type { Project } from \"../project.js\";\nimport { openProject } from \"../project.js\";\nimport { CHECK, formatRows, guard, WARN, write } from \"../ui.js\";\nimport { assertNoPublicSecret } from \"./run.js\";\nimport { loadSchema } from \"./validate.js\";\n\nexport interface ArtifactBuildOptions {\n readonly cwd: string;\n /** Named explicitly. There is no default, and none is invented. */\n readonly environment?: string;\n /** Named explicitly. Where the release will mount it from. */\n readonly out?: string;\n}\n\nexport interface ArtifactBuildResult {\n readonly file: string;\n readonly environment: string;\n readonly engineVersion: string;\n readonly keySource: string;\n /** Delivery mappings with a value. */\n readonly values: number;\n /** How many of those travelled as ciphertext. */\n readonly sealed: number;\n /** Declared mappings the environment has no non-local winner for. */\n readonly absent: number;\n /** True when the artifact was written inside the project — a `doctor` finding. */\n readonly insideRepo: boolean;\n}\n\n/** The invocation every refusal here points back at, with what is known filled in. */\nfunction buildCommand(environment: string | undefined, out: string | undefined): string {\n return `penv artifact build --env ${environment ?? \"<environment>\"} --out ${out ?? \"<path>\"}`;\n}\n\n/**\n * The environment, taken only from `--env`.\n *\n * Deliberately not `targetEnvironment`: `defaultEnvironment`, `PENV_ENV` and\n * `NODE_ENV` all answer for the machine the command runs on, and the machine a\n * release is built on has no opinion worth acting on about which environment the\n * release is for.\n */\nfunction targetOf(options: ArtifactBuildOptions): string {\n const environment = options.environment?.trim();\n if (environment === undefined || environment.length === 0) {\n throw new PenvError(\n \"ARTIFACT_ENV_REQUIRED\",\n \"`penv artifact build` names the environment it builds for, and `--env` was not given\",\n `Name it: \\`${buildCommand(undefined, options.out)}\\`. An artifact carries one environment, and penv will not pick which.`,\n );\n }\n return environment;\n}\n\n/** The path, taken only from `--out` — there is no default, and none is inside the repo. */\nfunction outputOf(options: ArtifactBuildOptions, environment: string): string {\n const out = options.out?.trim();\n if (out === undefined || out.length === 0) {\n throw new PenvError(\n \"ARTIFACT_OUT_REQUIRED\",\n \"`penv artifact build` writes where it is told, and `--out` was not given\",\n `Name the path: \\`${buildCommand(environment, undefined)}\\`. The artifact belongs outside the repository, so there is no default worth having.`,\n );\n }\n return isAbsolute(out) ? out : resolve(options.cwd, out);\n}\n\n/**\n * The winning value file for one parameter, unopened.\n *\n * `.local` scopes are skipped outright: a personal override is one developer's\n * machine, and shipping it to a release is the scope widening the cascade exists\n * to prevent. The precedence rule itself is not restated here — `candidatesFor`\n * owns the order and this only walks the list it returns.\n */\nasync function winnerOf(\n project: Project,\n ref: ParameterRef,\n environment: string,\n): Promise<{ readonly file: ValueFile; readonly stored: string } | undefined> {\n for (const file of candidatesFor(ref, environment, true)) {\n const stored = await project.provider.read(file);\n if (stored !== undefined) {\n return { file, stored };\n }\n }\n return undefined;\n}\n\n/**\n * A secret whose winner is a plaintext file, refused at the delivery boundary.\n *\n * `doctor` reports this and the artifact refuses it, and that is the difference\n * between a report and a release: an artifact is written once and read\n * unchanged, so a plaintext secret in one is a plaintext secret in every\n * container the release reaches, for as long as it runs. penv holds both halves\n * — meta says secret, the winning filename says plaintext — so this is where it\n * stops.\n */\nfunction plaintextSecret(parameter: string, location: string, environment: string): PenvError {\n return new PenvError(\n \"ARTIFACT_PLAINTEXT_SECRET\",\n `${parameter} is a secret for environment ${environment}, and its value comes from ${location}, which is not sealed`,\n `Seal it with \\`penv encrypt ${parameter} --env ${environment}\\` — an artifact carries ciphertext or nothing.`,\n );\n}\n\nexport async function runArtifactBuild(\n options: ArtifactBuildOptions,\n): Promise<ArtifactBuildResult> {\n const environment = targetOf(options);\n const file = outputOf(options, environment);\n const retry = buildCommand(environment, options.out);\n\n const project = openProject(options.cwd);\n const { schema, issues } = await loadSchema(project, environment);\n if (schema === undefined) {\n const lines = issues.map((issue) => ` ${issue.subject}: ${issue.message}`).join(\"\\n\");\n throw new PenvError(\n \"ARTIFACT_NO_SCHEMA\",\n `The schema did not load, so penv cannot tell what this artifact should deliver:\\n${lines}`,\n `Fix the error above, then run \\`${retry}\\` again.`,\n );\n }\n\n const refs = declaredRefs(schema);\n // The same check delivery makes, made here: an artifact whose entries collide\n // would deliver last-wins in a container, where nothing is left to notice.\n assertDeliverableNames(refs, project.config);\n await assertNoPublicSecret(project, environment, refs, retry);\n\n const values: Record<string, ArtifactEntry> = {};\n let sealed = 0;\n let present = 0;\n for (const ref of refs) {\n const parameter = parameterId(ref);\n const variable = variableName(ref, project.config);\n const winner = await winnerOf(project, ref, environment);\n if (winner === undefined) {\n values[parameter] = { kind: \"absent\", variable };\n continue;\n }\n present += 1;\n const location = formatValueFile(winner.file);\n if (winner.file.encrypted) {\n sealed += 1;\n values[parameter] = { kind: \"sealed\", variable, address: location, sealed: winner.stored };\n continue;\n }\n if (isSecret(await project.provider.readMeta(ref), environment)) {\n throw plaintextSecret(parameter, location, environment);\n }\n values[parameter] = { kind: \"plain\", variable, value: winner.stored };\n }\n\n const artifact: Artifact = {\n format: ARTIFACT_FORMAT,\n environment,\n engineVersion: engineVersion(),\n schemaDigest: deliveryDigest(values),\n keySource: keySourceIdentifier(project.config, environment),\n values,\n };\n\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, serializeArtifact(artifact), \"utf8\");\n\n const inside = relative(project.root, file);\n return {\n file,\n environment,\n engineVersion: artifact.engineVersion,\n keySource: artifact.keySource,\n values: present,\n sealed,\n absent: refs.length - present,\n insideRepo: inside !== \"\" && !inside.startsWith(\"..\") && !isAbsolute(inside),\n };\n}\n\n/** The artifact's path as the caller would type it, when it is below them. */\nfunction displayPath(cwd: string, file: string): string {\n const rel = relative(cwd, file);\n return rel === \"\" || rel.startsWith(\"..\") ? file : rel.split(\"\\\\\").join(\"/\");\n}\n\nexport function renderArtifactBuild(result: ArtifactBuildResult, cwd: string): string[] {\n const rows = [\n {\n glyph: CHECK,\n label: \"Built\",\n subject: displayPath(cwd, result.file),\n detail: `${result.values} values for environment ${result.environment}, ${result.sealed} sealed`,\n },\n ];\n // Said now, while the path can still be changed, and said again by `doctor`\n // for the artifact that was committed anyway.\n if (result.insideRepo) {\n rows.push({\n glyph: WARN,\n label: \"Inside the repository\",\n subject: displayPath(cwd, result.file),\n detail: \"a deployment artifact is stored outside git — write it somewhere else\",\n });\n }\n return formatRows(rows);\n}\n\nconst buildSubcommand = defineCommand({\n meta: {\n name: \"build\",\n description: \"Write the sealed deployment artifact for one environment\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to build for (required)\" },\n out: { type: \"string\", description: \"Where to write the artifact (required)\" },\n },\n run({ args }) {\n return guard(async () => {\n const cwd = process.cwd();\n const result = await runArtifactBuild({\n cwd,\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.out === undefined ? {} : { out: args.out }),\n });\n write(renderArtifactBuild(result, cwd));\n });\n },\n});\n\nexport const artifactCommand = defineCommand({\n meta: {\n name: \"artifact\",\n description: \"Build the sealed deployment artifact a release runs from\",\n },\n subCommands: { build: buildSubcommand },\n});\n","/**\n * The runtime dependencies an adopted project takes, and how they get there.\n *\n * PRD §3: an adopted project depends on `@penvhq/penv` at the engine's own\n * version — the typed `@env` surface, not a CLI distribution. It also depends on\n * zod, because the `penv.schema.ts` init scaffolds imports it: zod is a *peer* of\n * `@penvhq/penv`, and a peer is a package the project supplies. Under pnpm's\n * strict layout nothing hoists it to the project root, so an install that named\n * only `@penvhq/penv` left the very schema init had just written unable to\n * resolve `zod` — and adoption could never finish.\n *\n * Both are installed with the package manager the project already uses, and only\n * after showing the exact `package.json` and lockfile change: an install is the\n * one step of adoption that reaches outside the repository, so it is the one step\n * that is shown before it happens rather than reported after.\n *\n * The install itself is a seam. It shells out to a package manager, which the\n * tests must never do — and a fake here is not a weaker test, because what init\n * has to get right is the plan, the consent, and the refusal when the install\n * does not happen.\n *\n * A plan is a list of steps, because in a workspace \"the project's dependency\"\n * is plural. pnpm refuses a bare `add` at a workspace root (`-w` is how you say\n * you meant the root), and a workspace package that declares `@penvhq/penv`\n * itself is a second copy of the very version the manifest pins — one repository\n * ran the 0.8 bridge under a 0.11 pin for three releases because nothing looked\n * below the root, and the same repository then held two `@penvhq/core`s five\n * minor versions apart because the scan looked for only one name. So every\n * `package.json` that declares either moves, under one consent, and the commands\n * shown are the ones that run.\n *\n * Two commands write that dependency line: `penv init`, which is the engine's,\n * and `penv upgrade`, which is the launcher's. This module is published at\n * `@penvhq/cli/install` so the launcher reaches it without loading the command\n * surface — one answer to \"which package manager, which diff, which spawn\",\n * rather than a second copy on the other side of the launcher/engine split.\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join, relative, sep } from \"node:path\";\nimport { PenvError } from \"@penvhq/core\";\nimport { startChild } from \"./child.js\";\n\n/** The package an adopted project depends on. The CLI engine is not one of its dependencies. */\nexport const RUNTIME_PACKAGE = \"@penvhq/penv\";\n\n/** The peer `penv.schema.ts` imports, which the project supplies because a peer is not hoisted. */\nexport const SCHEMA_PACKAGE = \"zod\";\n\n/**\n * The module every committed provider declaration augments, which the project\n * declares for the same reason it declares zod: nothing hoists it.\n *\n * `penv add` commits a `declare module \"@penvhq/core\"` block, and TypeScript\n * resolves that specifier from the project's own files. Under pnpm's strict\n * layout a transitive dependency is not at the project root, so the specifier\n * resolves to nothing — and an augmentation whose module cannot be found is not\n * an error, it silently degrades to an *ambient* declaration. The map\n * `defineConfig` reads stays empty, a misspelled provider field compiles clean,\n * and no diagnostic anywhere says so. A hoisting package manager hides this; the\n * project declaring it is what makes the declaration bind under all of them.\n *\n * `devDependencies`, because that is the whole of what it is: a type-only\n * augmentation target. No application code imports it, and `@penvhq/penv`\n * carries its own copy of the runtime — so the PRD's one runtime dependency is\n * still one.\n */\nexport const TYPES_PACKAGE = \"@penvhq/core\";\n\nexport type PackageManager = \"pnpm\" | \"npm\" | \"yarn\" | \"bun\";\n\n/** The lockfile that names each manager, checked in this order. */\nconst LOCKFILES: readonly (readonly [PackageManager, string])[] = [\n [\"pnpm\", \"pnpm-lock.yaml\"],\n [\"yarn\", \"yarn.lock\"],\n [\"bun\", \"bun.lock\"],\n [\"bun\", \"bun.lockb\"],\n [\"npm\", \"package-lock.json\"],\n];\n\n/** How each manager is told to add a package. */\nconst ADD: Readonly<Record<PackageManager, readonly [string, string]>> = {\n pnpm: [\"pnpm\", \"add\"],\n npm: [\"npm\", \"install\"],\n yarn: [\"yarn\", \"add\"],\n bun: [\"bun\", \"add\"],\n};\n\n/** How each manager is told to write the version down exactly, with no range. */\nconst EXACT: Readonly<Record<PackageManager, string>> = {\n pnpm: \"--save-exact\",\n npm: \"--save-exact\",\n yarn: \"--exact\",\n bun: \"--exact\",\n};\n\n/** How each manager is told to keep the dependency in the block it is already in. */\nconst DEV: Readonly<Record<PackageManager, string>> = {\n pnpm: \"-D\",\n npm: \"--save-dev\",\n yarn: \"--dev\",\n bun: \"--dev\",\n};\n\n/** pnpm refuses an install at a workspace root without this — `ERR_PNPM_ADDING_TO_ROOT`. */\nconst WORKSPACE_ROOT_FLAG = \"-w\";\n\n/** pnpm's workspace file, which is both what declares the members and what makes the root refuse. */\nconst PNPM_WORKSPACE = \"pnpm-workspace.yaml\";\n\n/** One package the adopted project needs, and what its `package.json` says today. */\nexport interface InstallPackage {\n readonly name: string;\n readonly version: string;\n /** What `package.json` already says about it, when it says anything. */\n readonly declared?: string;\n /** True when this project already has it — nothing to install for this one. */\n readonly satisfied: boolean;\n}\n\n/** One `package.json` the install rewrites, and the command that rewrites it. */\nexport interface InstallStep {\n /** The file the diff names — `package.json`, or a workspace package's path to it. */\n readonly manifest: string;\n /** Everything this file needs, in the order the diff shows them. */\n readonly packages: readonly InstallPackage[];\n /** The command, argv-shaped — run from the project root, whichever file it writes. */\n readonly command: readonly string[];\n /** The block this step writes into, which is what the diff shows. */\n readonly dev: boolean;\n /**\n * True when that block is already in the file. The diff then shows it as the\n * context it is, without a `+`: claiming to create a `devDependencies` beside\n * fourteen entries is the one line in an otherwise literal diff that a reader\n * would go and check by hand.\n */\n readonly blockPresent: boolean;\n /** True when this file already declares every one of them. */\n readonly satisfied: boolean;\n}\n\nexport interface InstallPlan {\n readonly root: string;\n readonly manager: PackageManager;\n /**\n * The root's `package.json` — one step per block it writes, since one command\n * names one — then one per workspace package that declares the runtime package\n * or the types package itself.\n */\n readonly steps: readonly InstallStep[];\n /** The lockfile the manager will rewrite, when the project has one. */\n readonly lockfile?: string;\n /** True when every step is already satisfied — nothing to install. */\n readonly satisfied: boolean;\n}\n\n/** Runs an install plan, or throws. Replaced in tests; never spawns there. */\nexport type InstallRuntime = (plan: InstallPlan) => Promise<void>;\n\n/**\n * The engine's own version, read from its manifest rather than restated in the\n * source: `@penvhq/penv` must match the engine exactly, and a constant beside\n * the version a release bumps is a second answer waiting to drift.\n */\nexport function engineVersion(): string {\n const version = ownManifest()?.version;\n if (typeof version === \"string\" && version.length > 0) {\n return version;\n }\n throw new PenvError(\n \"ENGINE_VERSION_UNREADABLE\",\n \"penv could not read its own version, so it cannot say which `@penvhq/penv` this project needs\",\n `Reinstall penv, then run \\`penv init\\` again.`,\n );\n}\n\n/**\n * The zod an adopted project installs: the floor of the peer range the engine\n * and `@penvhq/penv` both declare, which is the version penv is built and tested\n * against.\n *\n * The floor rather than the range, because the diff shown before the install has\n * to be the line that actually lands — `--save-exact` on `^4.4.3` would write\n * whatever the registry resolved that day, which is not something a reader can\n * consent to in advance.\n */\nexport function schemaPackageVersion(): string {\n const peers = ownManifest()?.peerDependencies;\n const declared =\n peers !== null && typeof peers === \"object\" && !Array.isArray(peers)\n ? (peers as Record<string, unknown>)[SCHEMA_PACKAGE]\n : undefined;\n const floor = typeof declared === \"string\" ? declared.replace(/^[\\^~>=\\s]+/, \"\").trim() : \"\";\n if (floor.length > 0) {\n return floor;\n }\n throw new PenvError(\n \"ENGINE_PEER_UNREADABLE\",\n `penv could not read its own \\`${SCHEMA_PACKAGE}\\` peer range, so it cannot say which ${SCHEMA_PACKAGE} this project needs`,\n `Reinstall penv, then run \\`penv init\\` again.`,\n );\n}\n\n/** The engine's own manifest, or `undefined` when it cannot be read. */\nfunction ownManifest(): Record<string, unknown> | undefined {\n try {\n const parsed: unknown = JSON.parse(\n readFileSync(new URL(\"../package.json\", import.meta.url), \"utf8\"),\n );\n return parsed !== null && typeof parsed === \"object\" && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : undefined;\n } catch {\n // The callers refuse: a version penv guessed would pin a project's\n // dependency to something nobody chose.\n return undefined;\n }\n}\n\n/** The package manager this project already uses: its lockfile, then what it declares, then npm. */\nexport function detectPackageManager(root: string): PackageManager {\n for (const [manager, lockfile] of LOCKFILES) {\n if (existsSync(join(root, lockfile))) {\n return manager;\n }\n }\n return declaredManager(root) ?? \"npm\";\n}\n\n/** `\"packageManager\": \"pnpm@9.1.0\"` — corepack's field, and a project's own answer. */\nfunction declaredManager(root: string): PackageManager | undefined {\n const declared = manifestOf(root)?.packageManager;\n if (typeof declared !== \"string\") {\n return undefined;\n }\n const name = declared.split(\"@\")[0];\n return name === \"pnpm\" || name === \"npm\" || name === \"yarn\" || name === \"bun\" ? name : undefined;\n}\n\nfunction manifestOf(root: string): Record<string, unknown> | undefined {\n const file = join(root, \"package.json\");\n if (!existsSync(file)) {\n return undefined;\n }\n try {\n const manifest: unknown = JSON.parse(readFileSync(file, \"utf8\"));\n return manifest !== null && typeof manifest === \"object\" && !Array.isArray(manifest)\n ? (manifest as Record<string, unknown>)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** What one `package.json` says about a package today, and which block says it. */\ninterface Declaration {\n readonly version: string;\n /** True when it sits in `devDependencies` — where an install has to leave it. */\n readonly dev: boolean;\n}\n\nfunction declaredIn(dir: string, name: string): Declaration | undefined {\n const manifest = manifestOf(dir);\n for (const field of [\"dependencies\", \"devDependencies\"] as const) {\n const block: unknown = manifest?.[field];\n if (block !== null && typeof block === \"object\" && !Array.isArray(block)) {\n const version: unknown = (block as Record<string, unknown>)[name];\n if (typeof version === \"string\") {\n return { version, dev: field === \"devDependencies\" };\n }\n }\n }\n return undefined;\n}\n\n/** True when `package.json` already has the block a step writes into. */\nfunction blockPresentIn(dir: string, dev: boolean): boolean {\n const block: unknown = manifestOf(dir)?.[dev ? \"devDependencies\" : \"dependencies\"];\n return block !== null && typeof block === \"object\" && !Array.isArray(block);\n}\n\n/** True when `root` is the root of a pnpm workspace, which is what `-w` is for. */\nexport function isPnpmWorkspaceRoot(root: string): boolean {\n return existsSync(join(root, PNPM_WORKSPACE)) && existsSync(join(root, \"package.json\"));\n}\n\n/** The `packages:` list from `pnpm-workspace.yaml`, block or flow form. */\nfunction workspaceGlobs(root: string): string[] {\n let text: string;\n try {\n text = readFileSync(join(root, PNPM_WORKSPACE), \"utf8\");\n } catch {\n return [];\n }\n const unquote = (raw: string): string => raw.replace(/^['\"]|['\"]$/g, \"\").trim();\n const globs: string[] = [];\n let inside = false;\n for (const line of text.split(/\\r?\\n/)) {\n const flow = /^packages:\\s*\\[(.*)\\]\\s*$/.exec(line);\n if (flow?.[1] !== undefined) {\n return flow[1]\n .split(\",\")\n .map(unquote)\n .filter((glob) => glob !== \"\");\n }\n if (/^packages:\\s*$/.test(line)) {\n inside = true;\n continue;\n }\n if (!inside) {\n continue;\n }\n const item = /^\\s+-\\s*(.+?)\\s*$/.exec(line);\n if (item?.[1] !== undefined) {\n globs.push(unquote(item[1]));\n continue;\n }\n if (line.trim() !== \"\" && !line.trimStart().startsWith(\"#\")) {\n break;\n }\n }\n return globs;\n}\n\nfunction directoriesIn(dir: string): string[] {\n try {\n return readdirSync(dir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() && entry.name !== \"node_modules\")\n .map((entry) => join(dir, entry.name));\n } catch {\n return [];\n }\n}\n\nfunction isDirectory(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** `packages/*` and `apps/**` against the filesystem, one path segment at a time. */\nfunction expandGlob(root: string, glob: string): string[] {\n let dirs = [root];\n for (const segment of glob.split(\"/\").filter((part) => part !== \"\" && part !== \".\")) {\n const next: string[] = [];\n for (const dir of dirs) {\n if (segment === \"**\") {\n const stack = [dir];\n while (stack.length > 0) {\n const current = stack.pop() as string;\n next.push(current);\n stack.push(...directoriesIn(current));\n }\n continue;\n }\n if (segment.includes(\"*\")) {\n const pattern = new RegExp(\n `^${segment.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \"[^/]*\")}$`,\n );\n next.push(\n ...directoriesIn(dir).filter((child) => pattern.test(child.slice(dir.length + 1))),\n );\n continue;\n }\n const candidate = join(dir, segment);\n if (isDirectory(candidate)) {\n next.push(candidate);\n }\n }\n dirs = next;\n }\n return dirs;\n}\n\n/**\n * Every workspace package that declares `name` itself, root excluded — asked\n * once for `@penvhq/penv` and once for `@penvhq/core`, since a member holding\n * its own copy of either is a second version running under one pin.\n *\n * Only the ones that already declare it: penv moves a dependency a package\n * chose, and adding one to a package that never asked for it is a different\n * decision than the one being consented to.\n */\nfunction workspaceMembers(root: string, name: string): string[] {\n if (!isPnpmWorkspaceRoot(root)) {\n return [];\n }\n const globs = workspaceGlobs(root);\n const excluded = globs\n .filter((glob) => glob.startsWith(\"!\"))\n .flatMap((glob) => expandGlob(root, glob.slice(1)));\n const found = new Set<string>();\n for (const glob of globs.filter((entry) => !entry.startsWith(\"!\"))) {\n for (const dir of expandGlob(root, glob)) {\n if (dir !== root && !excluded.includes(dir) && declaredIn(dir, name) !== undefined) {\n found.add(dir);\n }\n }\n }\n return [...found].sort();\n}\n\n/** The path a diff shows for one of them, in the spelling every penv path uses. */\nfunction manifestPathOf(root: string, dir: string): string {\n const within = relative(root, dir)\n .split(sep)\n .filter((part) => part !== \"\");\n return [...within, \"package.json\"].join(\"/\");\n}\n\nfunction addCommand(\n manager: PackageManager,\n options: { readonly filter?: string; readonly workspaceRoot: boolean; readonly dev: boolean },\n specs: readonly string[],\n): string[] {\n const [bin, verb] = ADD[manager];\n return [\n bin,\n ...(options.filter === undefined ? [] : [\"--filter\", options.filter]),\n verb,\n ...(options.workspaceRoot ? [WORKSPACE_ROOT_FLAG] : []),\n EXACT[manager],\n ...(options.dev ? [DEV[manager]] : []),\n ...specs,\n ];\n}\n\nfunction stepFor(\n manager: PackageManager,\n manifest: string,\n packages: readonly InstallPackage[],\n options: {\n readonly filter?: string;\n readonly workspaceRoot: boolean;\n readonly dev: boolean;\n readonly dir: string;\n },\n): InstallStep {\n const pending = packages.filter((entry) => !entry.satisfied);\n const specs = (pending.length === 0 ? packages : pending).map(\n (entry) => `${entry.name}@${entry.version}`,\n );\n return {\n manifest,\n packages,\n command: addCommand(manager, options, specs),\n dev: options.dev,\n blockPresent: blockPresentIn(options.dir, options.dev),\n satisfied: pending.length === 0,\n };\n}\n\nexport function planInstall(root: string, version: string = engineVersion()): InstallPlan {\n const manager = detectPackageManager(root);\n const lockfile = LOCKFILES.find(\n ([name, file]) => name === manager && existsSync(join(root, file)),\n )?.[1];\n const workspaceRoot = manager === \"pnpm\" && isPnpmWorkspaceRoot(root);\n\n const runtime = declaredIn(root, RUNTIME_PACKAGE);\n const zod = declaredIn(root, SCHEMA_PACKAGE);\n const types = declaredIn(root, TYPES_PACKAGE);\n const packages: InstallPackage[] = [\n {\n name: RUNTIME_PACKAGE,\n version,\n ...(runtime === undefined ? {} : { declared: runtime.version }),\n satisfied: runtime?.version === version,\n },\n {\n name: SCHEMA_PACKAGE,\n version: schemaPackageVersion(),\n ...(zod === undefined ? {} : { declared: zod.version }),\n // Any declared zod counts: which zod a project uses is the project's\n // decision, and penv is here to make sure there is one, not to move it.\n satisfied: zod !== undefined,\n },\n ];\n const typesPackage: InstallPackage = {\n name: TYPES_PACKAGE,\n version,\n ...(types === undefined ? {} : { declared: types.version }),\n // Held to the pin, exactly as a workspace member's copy is. The augmentation\n // binds on the module resolving, but what it binds to is whatever release\n // resolved: a core behind the pin checks `penv.config.ts` against a shape the\n // engine no longer has, and the committed declarations augment interfaces\n // that moved under them.\n satisfied: types?.version === version,\n };\n\n // The block a package chose is the block penv writes back to — but only when\n // every package this step installs lives there, since one command names one.\n // Which is also why the types package is its own step: it belongs in\n // `devDependencies` whatever the other two chose.\n const pending = packages.filter((entry) => !entry.satisfied);\n const steps: InstallStep[] = [\n stepFor(manager, \"package.json\", packages, {\n workspaceRoot,\n dir: root,\n dev:\n runtime?.dev === true &&\n pending.every((entry) => entry.name === RUNTIME_PACKAGE) &&\n pending.length > 0,\n }),\n stepFor(manager, \"package.json\", [typesPackage], { workspaceRoot, dir: root, dev: true }),\n ];\n // Both packages, because a member declaring either holds its own copy of it:\n // `@penvhq/penv` is a second bridge running under the pin, and `@penvhq/core`\n // is a second copy of the interfaces every committed declaration augments.\n for (const name of [RUNTIME_PACKAGE, TYPES_PACKAGE]) {\n for (const dir of workspaceMembers(root, name)) {\n const declared = declaredIn(dir, name) as Declaration;\n steps.push(\n stepFor(\n manager,\n manifestPathOf(root, dir),\n [\n {\n name,\n version,\n declared: declared.version,\n satisfied: declared.version === version,\n },\n ],\n {\n filter: `./${relative(root, dir).split(sep).join(\"/\")}`,\n workspaceRoot: false,\n dir,\n dev: declared.dev,\n },\n ),\n );\n }\n }\n\n return {\n root,\n manager,\n steps,\n ...(lockfile === undefined ? {} : { lockfile }),\n satisfied: steps.every((step) => step.satisfied),\n };\n}\n\nfunction describe(entry: InstallPackage): string {\n return `${entry.name} ${entry.version}`;\n}\n\n/** What this plan actually installs, once per package however many files declare it. */\nexport function installedPackages(plan: InstallPlan): readonly InstallPackage[] {\n const pending = plan.steps.flatMap((step) => step.packages).filter((entry) => !entry.satisfied);\n return [...new Map(pending.map((entry) => [entry.name, entry])).values()];\n}\n\n/** One file the plan wrote, and what landed in it. */\nexport interface InstalledManifest {\n readonly manifest: string;\n /** `@penvhq/penv 1.2.3 and @penvhq/core 1.2.3` — every package this file gained. */\n readonly packages: string;\n}\n\n/**\n * What the install landed, one entry per `package.json`.\n *\n * Per file rather than per step, because the root is two steps and a file is\n * what the reader recognises — and every package in it, because a caller\n * confirming only the one it happened to name leaves the release's own new\n * dependency unmentioned in the lines that say the upgrade worked.\n */\nexport function installedByManifest(plan: InstallPlan): readonly InstalledManifest[] {\n const byManifest = new Map<string, InstallPackage[]>();\n for (const step of plan.steps.filter((entry) => !entry.satisfied)) {\n const landed = byManifest.get(step.manifest) ?? [];\n landed.push(...step.packages.filter((entry) => !entry.satisfied));\n byManifest.set(step.manifest, landed);\n }\n return [...byManifest].map(([manifest, packages]) => ({\n manifest,\n packages: series(\n [...new Map(packages.map((entry) => [entry.name, entry])).values()].map(describe),\n ),\n }));\n}\n\n/** Every package the plan names, once each — the root's blocks are two steps now. */\nfunction plannedPackages(plan: InstallPlan): readonly InstallPackage[] {\n const all = plan.steps.flatMap((step) => step.packages);\n return [...new Map(all.map((entry) => [entry.name, entry])).values()];\n}\n\n/** `a`, `a and b`, `a, b and c`. */\nfunction series(values: readonly string[]): string {\n return values.length < 2\n ? (values[0] ?? \"\")\n : `${values.slice(0, -1).join(\", \")} and ${values.at(-1) as string}`;\n}\n\n/** The lines one `package.json` contributes to the diff. */\nfunction renderStep(step: InstallStep): string[] {\n const pending = step.packages.filter((entry) => !entry.satisfied);\n const added = pending.filter((entry) => entry.declared === undefined);\n const replaced = pending.filter((entry) => entry.declared !== undefined);\n const block = step.dev ? \"devDependencies\" : \"dependencies\";\n // The block's own lines are an insertion only when the block is not there yet.\n const edge = step.blockPresent ? \" \" : \" +\";\n return [\n step.manifest,\n ...(added.length === 0\n ? []\n : [\n `${edge} \"${block}\": {`,\n ...added.map((entry) => ` + \"${entry.name}\": \"${entry.version}\"`),\n `${edge} }`,\n ]),\n ...replaced.flatMap((entry) => [\n ` - \"${entry.name}\": \"${entry.declared}\"`,\n ` + \"${entry.name}\": \"${entry.version}\"`,\n ]),\n ];\n}\n\n/**\n * The change, as it will appear in the diff — the whole point of showing it is\n * that the reader recognises their own file, so these are the `package.json`\n * lines that land and the lockfile that gets rewritten, not a summary of both.\n *\n * In a workspace that is more than one file, and the commands underneath are the\n * ones that run: a \"Run with:\" line the reader cannot paste is worse than none.\n */\nexport function renderInstallPlan(plan: InstallPlan): string[] {\n if (plan.satisfied) {\n return [\n `package.json already has ${series(plannedPackages(plan).map(describe))} — nothing to install.`,\n ];\n }\n const pending = plan.steps.filter((step) => !step.satisfied);\n const [first, ...rest] = pending.map((step) => step.command.join(\" \"));\n const landing = installedPackages(plan).map((entry) => ` + ${entry.name}@${entry.version}`);\n return [\n ...pending.flatMap(renderStep),\n ...(plan.lockfile === undefined ? [] : [plan.lockfile, ...landing]),\n \"\",\n `Run with: ${first ?? \"\"}`,\n ...rest.map((command) => ` then ${command}`),\n ];\n}\n\n/**\n * The real install: the project's own package manager, started the way any other\n * child is (`.cmd` shims on Windows included), with its output the user's to see.\n *\n * Every step runs from the project root — `-w` and `--filter` are how a workspace\n * says which `package.json` it means, so the directory never changes.\n */\nexport const installWithPackageManager: InstallRuntime = async (plan) => {\n for (const step of plan.steps) {\n if (step.satisfied) {\n continue;\n }\n const child = startChild({\n command: step.command,\n env: process.env as Record<string, string>,\n cwd: plan.root,\n purpose: `install ${step.packages.map(describe).join(\" and \")} in ${step.manifest}`,\n });\n const ended = await child.ended;\n if (ended.exitCode !== 0 || ended.signal !== null) {\n throw installFailed(plan, step);\n }\n }\n};\n\n/**\n * What to do about a package manager that refused.\n *\n * Never the command that just failed: the one remediation guaranteed not to work\n * is the one the reader already ran. The manager said why, on their screen, and\n * nothing was migrated — so the answer is that line and a second `penv init`.\n */\nexport function installFailed(plan: InstallPlan, step: InstallStep): PenvError {\n return new PenvError(\n \"INIT_INSTALL_FAILED\",\n `${step.command.join(\" \")} did not finish, so penv migrated nothing`,\n `Read what ${plan.manager} printed above — it names what it refused. Fix that and run this ` +\n \"command again; your dotenv files are exactly where they were.\",\n );\n}\n","/**\n * Starting someone else's command, opaquely.\n *\n * `penv run -- <command>` starts exactly what follows `--`: the argument\n * boundaries the shell already worked out are handed to the operating system\n * untouched, stdio is the parent's, and the child's exit code and terminating\n * signal come back out. penv never parses the command, never rebuilds a command\n * line from it, never wraps it in a shell — a shell would re-split what the user\n * already split, and `penv run -- node -e \"console.log(1 > 2)\"` would redirect to\n * a file called `2`.\n *\n * Windows is the one place where \"hand it to the operating system\" needs help.\n * `pnpm`, `next` and every other node-installed tool are `.cmd` shims there, and\n * Node refuses to execute one without a shell. So a `.cmd`/`.bat` target — and\n * only that — is started through `cmd.exe /d /s /c` with\n * `windowsVerbatimArguments`, building the one command line cmd will accept and\n * escaping every argument so that cmd hands the child the same bytes penv was\n * given. Everything else spawns directly, on every platform.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { delimiter, isAbsolute, join, win32 } from \"node:path\";\nimport { PenvError } from \"@penvhq/core\";\n\n/** How a child ended. Exactly one of these is meaningful, and both are forwarded. */\nexport interface ChildResult {\n /** The child's own exit code, or 1 when a signal ended it. */\n readonly exitCode: number;\n /** The signal that ended the child, when one did. */\n readonly signal: NodeJS.Signals | null;\n}\n\nexport interface ChildInvocation {\n /** The command exactly as it followed `--`: the executable, then its arguments. */\n readonly command: readonly string[];\n readonly env: Record<string, string>;\n readonly cwd: string;\n /**\n * What penv is starting this on its own behalf to do — `init`'s dependency\n * install. Absent means the command is the user's, from after `--`, and the\n * two failures have opposite remedies: one is about what they typed, the other\n * about a program penv chose to run.\n */\n readonly purpose?: string;\n}\n\n/** A started child: how it ends, and the one thing a wrapper may do to it. */\nexport interface ChildHandle {\n /** Resolves when the child has ended, however it ended. */\n readonly ended: Promise<ChildResult>;\n /** Asks the child to stop — what `--watch` does before it starts the next one. */\n kill(signal?: NodeJS.Signals): void;\n}\n\n/** The seam `run` starts a child through — replaced in tests that assert what it was given. */\nexport type StartChild = (invocation: ChildInvocation) => ChildHandle;\n\n/** The signals a wrapper must pass through rather than absorb. */\nconst FORWARDED: readonly NodeJS.Signals[] = [\"SIGINT\", \"SIGTERM\", \"SIGHUP\", \"SIGBREAK\"];\n\nexport const startChild: StartChild = (invocation) => {\n const [executable, ...args] = invocation.command;\n if (executable === undefined) {\n throw noCommand();\n }\n\n const target = resolveTarget(executable, args, invocation.env);\n const child = spawn(target.file, target.args, {\n cwd: invocation.cwd,\n env: invocation.env,\n stdio: \"inherit\",\n ...(target.verbatim ? { windowsVerbatimArguments: true } : {}),\n });\n\n // Forwarded rather than handled: penv is a wrapper, and a Ctrl-C belongs to\n // the program the user is looking at. The child decides what to do with it,\n // and its answer comes back as the signal below.\n const forward = new Map<NodeJS.Signals, () => void>();\n for (const signal of FORWARDED) {\n const handler = (): void => {\n child.kill(signal);\n };\n forward.set(signal, handler);\n process.on(signal, handler);\n }\n const release = (): void => {\n for (const [signal, handler] of forward) {\n process.off(signal, handler);\n }\n };\n\n const ended = new Promise<ChildResult>((resolve, reject) => {\n child.on(\"error\", (cause) => {\n release();\n reject(cannotStart(executable, cause, invocation.purpose));\n });\n child.on(\"exit\", (code, signal) => {\n release();\n resolve({ exitCode: code ?? 1, signal });\n });\n });\n\n return {\n ended,\n kill(signal) {\n child.kill(signal);\n },\n };\n};\n\nexport function noCommand(): PenvError {\n return new PenvError(\n \"RUN_NO_COMMAND\",\n \"`penv run` was given no command to start\",\n \"Put the command after `--`, e.g. `penv run -- pnpm dev`.\",\n );\n}\n\nfunction cannotStart(executable: string, cause: unknown, purpose: string | undefined): PenvError {\n const detail = cause instanceof Error ? cause.message : String(cause);\n if (purpose !== undefined) {\n return new PenvError(\n \"PENV_COMMAND_NOT_STARTED\",\n `penv could not start \\`${executable}\\` to ${purpose}: ${detail}`,\n `Check that \\`${executable}\\` runs on its own — penv starts it the way your shell does, so it has to be on PATH. Nothing was changed.`,\n );\n }\n return new PenvError(\n \"RUN_COMMAND_NOT_STARTED\",\n `\\`${executable}\\` could not be started: ${detail}`,\n `Check the command after \\`--\\` runs on its own — \\`${executable}\\` has to be on PATH, exactly as it is spelled here.`,\n );\n}\n\ninterface SpawnTarget {\n readonly file: string;\n readonly args: readonly string[];\n /** True when the args are one pre-built command line rather than a list. */\n readonly verbatim: boolean;\n}\n\nfunction resolveTarget(\n executable: string,\n args: readonly string[],\n env: Readonly<Record<string, string | undefined>>,\n): SpawnTarget {\n if (process.platform !== \"win32\") {\n return { file: executable, args, verbatim: false };\n }\n const resolved = findExecutable(executable, env);\n if (resolved === undefined || !/\\.(cmd|bat)$/i.test(resolved)) {\n return { file: resolved ?? executable, args, verbatim: false };\n }\n return {\n file: env.ComSpec ?? \"cmd.exe\",\n args: [\"/d\", \"/s\", \"/c\", `\"${cmdCommandLine(resolved, args)}\"`],\n verbatim: true,\n };\n}\n\n/** A package-manager shim, which re-invokes cmd on its own way through. */\nconst SHIM = /(?:^|\\\\)node_modules\\\\\\.bin\\\\[^\\\\]+\\.cmd$/i;\n\n/**\n * The one command line cmd.exe is handed, escaped so the child receives the\n * bytes penv was given.\n *\n * The path is normalized first and *then* judged: `./node_modules/.bin/next.cmd`\n * and `.\\node_modules\\.bin\\next.cmd` are the same shim, and deciding on the\n * un-normalized spelling would escape a forward-slash invocation once while cmd\n * expands it twice — so an argument holding `&` would run as a command inside\n * the shim's second round. Windows' own separator, whatever this process runs\n * on, because this line is only ever read by cmd.exe.\n */\nexport function cmdCommandLine(resolved: string, args: readonly string[]): string {\n const command = win32.normalize(resolved);\n const shim = SHIM.test(command);\n return [escapeCommand(command), ...args.map((argument) => escapeArgument(argument, shim))].join(\n \" \",\n );\n}\n\n/**\n * The extensions a name is tried with, in the order the platform's own launcher\n * tries them.\n *\n * On Windows PATHEXT leads and the bare name comes last, because the bare name\n * is almost never what Windows would run: `pnpm`, `npx` and every\n * `node_modules/.bin` tool ship an extensionless POSIX shell script *beside*\n * their `.CMD` shim, in the same directory. Trying the empty extension first\n * matched that script, which is not executable by CreateProcess and is not a\n * `.cmd`, so the wrapper below was skipped and the spawn failed with ENOENT.\n * Everywhere else there are no extensions at all.\n */\nfunction extensions(\n env: Readonly<Record<string, string | undefined>>,\n platform: NodeJS.Platform,\n): string[] {\n if (platform !== \"win32\") {\n return [\"\"];\n }\n const declared = env.PATHEXT ?? \".COM;.EXE;.BAT;.CMD\";\n return [...declared.split(\";\").filter((extension) => extension.length > 0), \"\"];\n}\n\n/**\n * What the shell would have run, found the way the shell finds it: the name as\n * given if it carries a path, else each PATH directory, each with each\n * executable extension.\n *\n * `platform` is a parameter so the ordering above is testable on either kind of\n * machine — it is the whole behavior, and it differs by platform.\n */\nexport function findExecutable(\n executable: string,\n env: Readonly<Record<string, string | undefined>>,\n platform: NodeJS.Platform = process.platform,\n): string | undefined {\n const candidates = extensions(env, platform);\n const isFile = (path: string): boolean => existsSync(path) && statSync(path).isFile();\n\n if (executable.includes(\"/\") || executable.includes(\"\\\\\") || isAbsolute(executable)) {\n return candidates.map((extension) => executable + extension).find(isFile);\n }\n const path = env.PATH ?? env.Path ?? \"\";\n for (const directory of path.split(delimiter).filter((entry) => entry.length > 0)) {\n const hit = candidates.map((extension) => join(directory, executable + extension)).find(isFile);\n if (hit !== undefined) {\n return hit;\n }\n }\n return undefined;\n}\n\n/** The characters cmd.exe expands before the program ever sees them. */\nconst CMD_METACHARACTERS = /([()\\][%!^\"`<>&|;, *?])/g;\n\n/** The command's own path: cmd's metacharacters escaped, and no quotes to confuse it. */\nfunction escapeCommand(command: string): string {\n return command.replace(CMD_METACHARACTERS, \"^$1\");\n}\n\n/**\n * One argument, quoted so the child's runtime splits it exactly where penv was\n * given it, then escaped so cmd.exe passes those quotes through instead of\n * acting on them.\n */\nfunction escapeArgument(argument: string, doubleEscape: boolean): string {\n const quoted = `\"${argument.replace(/(\\\\*)\"/g, '$1$1\\\\\"').replace(/(\\\\*)$/, \"$1$1\")}\"`;\n const escaped = quoted.replace(CMD_METACHARACTERS, \"^$1\");\n return doubleEscape ? escaped.replace(CMD_METACHARACTERS, \"^$1\") : escaped;\n}\n","/**\n * Opening a penv project from a working directory, and the pieces every command\n * needs once it is open: the config, the environment to act on, the provider\n * rooted at the records tree, and the parameter a CLI key names.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type {\n AnyProvider,\n DecryptFailure,\n KeySource,\n ParameterRef,\n PenvConfig,\n Provider,\n ResolutionCandidate,\n} from \"@penvhq/core\";\nimport {\n assertMigrated,\n candidatesFor,\n environmentEntry,\n formatValueFile,\n isCanonicalSegment,\n isReservedToken,\n loadConfig,\n openValue,\n PenvError,\n parameterId,\n ReservedTokenError,\n recordsDir,\n refFromAccessPath,\n resolveEnvironment,\n resolveKeySource,\n SCHEMA_SHAPE_FILE,\n schemaFileOf,\n} from \"@penvhq/core\";\nimport { FilesystemProvider } from \"@penvhq/provider-filesystem\";\nimport { environmentFromShorthand } from \"./env-flags.js\";\nimport {\n assertProvidersRegistered,\n createProvider,\n createSourceProvider,\n LOCAL_TREE_TYPE,\n} from \"./registry.js\";\n\nexport interface Project {\n /** The directory holding `penv.config.ts`. */\n readonly root: string;\n readonly configFile: string;\n readonly config: PenvConfig;\n /** The parameter tree, absolute — `.penv/state/records/`. */\n readonly recordsDir: string;\n /**\n * The project's provider, as the contract — never the concrete\n * implementation. Shared commands speak the async interface and nothing more;\n * the sync twins a command genuinely needs are reached through `localTree`,\n * which is the one place the filesystem-only surface is named.\n */\n readonly provider: Provider;\n}\n\nexport function openProject(cwd: string): Project {\n const { config, file } = loadConfig(cwd);\n const root = dirname(file);\n // A project whose records still sit directly under `.penv/` is refused here,\n // once, rather than read as an empty tree by every command downstream.\n assertMigrated(root, config);\n // Refuse a config naming a provider this build cannot construct here, at open\n // time, rather than as a crash from whichever command first reached it. Plugin\n // types are resolved against the project (`root`), where the user installed them.\n assertProvidersRegistered(config, root);\n return {\n root,\n configFile: file,\n config,\n recordsDir: recordsDir(root),\n provider: createProvider(LOCAL_TREE_TYPE, { root, config }),\n };\n}\n\n/**\n * The project's provider as the concrete filesystem tree, for the sync reads and\n * writes a synchronous command cannot get from the async contract.\n *\n * `import`, `generate`, and `push` are synchronous — they are the adoption path\n * and the leaving guarantee — and they act on the local `.penv` tree, which is\n * always the filesystem provider (`penv pull` materialises it; the runtime reads\n * it). This narrows to that provider and names the reliance, so the type of\n * `Project.provider` stays the contract everywhere else. The refusal is a\n * belt-and-braces guard: `openProject` builds the tree as filesystem, so a\n * project in hand always narrows.\n */\nexport function localTree(project: Project): FilesystemProvider {\n if (!(project.provider instanceof FilesystemProvider)) {\n throw new PenvError(\n \"PROVIDER_NOT_LOCAL\",\n `This command reads the local .penv tree synchronously, which the \\`${project.provider.type}\\` provider is not`,\n \"Run this against a filesystem-backed project, or use a command that speaks the async provider contract.\",\n );\n }\n return project.provider;\n}\n\n/**\n * The module `schemaFile` names, when it carries the schema shape itself rather\n * than importing it — a project scaffolded before the shape/loader split, whose\n * `.penv/env.ts` (or wherever `schemaFile` points) defines its own `z.object`.\n * Returns that path; `undefined` when there is no such file, or when it is the\n * thin wrapper the current scaffold writes, which imports the shape and declares\n * no `z.object` of its own.\n *\n * Detection is by two markers, because the released layouts differ. penv 0.5+\n * scaffolded a `PenvSchemaShape` augmentation into the self-contained module;\n * penv <= 0.4 scaffolded `export const schema = z.object(...)` with no\n * augmentation at all. Either marker means the module declares its own shape; the\n * current wrapper (a re-export and a `load` call) carries neither.\n */\nexport function selfContainedSchemaModule(root: string, schemaFile: string): string | undefined {\n const file = join(root, ...schemaFile.split(\"/\"));\n if (!existsSync(file)) {\n return undefined;\n }\n const source = readFileSync(file, \"utf8\");\n return source.includes(\"PenvSchemaShape\") || source.includes(\"z.object\") ? schemaFile : undefined;\n}\n\n/**\n * The file that holds the editable schema shape, cohort-aware.\n *\n * A project scaffolded on the split keeps the `z.object` in `penv.schema.ts` and\n * a thin loader in `schemaFile`; one scaffolded before it keeps the shape\n * self-contained in `schemaFile` (invariant 2 — penv never rewrites either layout\n * into the other). Every message that tells the user where to edit the shape must\n * name the file that actually holds it, not a hard-coded path that is wrong for\n * whichever cohort it is not from — the same rule `writeSchemaShapeFile` follows\n * when it keeps an old-layout schema in place rather than standing a second one\n * beside it.\n */\nexport function schemaShapeFileOf(project: Project): string {\n const schemaFile = schemaFileOf(project.config);\n return selfContainedSchemaModule(project.root, schemaFile) ?? SCHEMA_SHAPE_FILE;\n}\n\n/**\n * The environment's DECLARED source-of-truth provider — the backend that holds\n * the truth, as opposed to `Project.provider`, which is always the local\n * filesystem tree every command edits.\n *\n * `pull` and cross-provider `doctor` read here: they compare or copy against what\n * the config says the environment's values live in. An undeclared environment has\n * no separate source of truth, so this falls back to the local tree — the two\n * coincide, and there is nothing to pull from elsewhere. `openProject` is\n * untouched: the working copy stays filesystem regardless.\n */\nexport async function sourceProviderFor(\n project: Project,\n environment: string,\n): Promise<AnyProvider> {\n const providerConfig = environmentEntry(project.config, environment);\n if (providerConfig === undefined) {\n return createProvider(LOCAL_TREE_TYPE, { root: project.root, config: project.config });\n }\n // A declared backend may be a plugin (`penv-cloud`, a third-party provider), so\n // this goes through the async, plugin-aware path rather than the built-in-only\n // `createProvider`. The local tree above is always a built-in and stays sync.\n // The result may hold records or a projection — callers narrow through\n // `holdsRecords`/`holdsProjection` and never call a method the capability\n // declaration did not promise.\n return createSourceProvider(providerConfig.provider, {\n root: project.root,\n config: project.config,\n providerConfig,\n environment,\n });\n}\n\n/**\n * The environment to act on: `--env` (or a whitelisted shorthand flag like\n * `--production`), then `PENV_ENV`, then `NODE_ENV`. `shorthand` carries the\n * bare flags the command did not declare, judged here against the whitelist —\n * the config interprets flags, it never parses them.\n */\nexport function targetEnvironment(\n project: Project,\n explicit?: string,\n shorthand?: readonly string[],\n): string {\n const fromFlags =\n shorthand === undefined\n ? undefined\n : environmentFromShorthand(project.config, shorthand, explicit);\n return resolveEnvironment(project.config, explicit ?? fromFlags);\n}\n\n/** A namespace separator on the command line, either spelling. */\nconst KEY_SEPARATOR = /[./\\\\]/;\n\n/**\n * The reserved set for a caller that has no config to hand: the static tokens\n * and nothing else. Environments are a config whitelist (invariant 10), so a\n * caller without a config cannot know which environment names are reserved.\n */\nconst NO_ENVIRONMENTS: PenvConfig = { environments: {} };\n\n/**\n * The parameter a CLI key names — `redis/password` and `redis.password` are one.\n *\n * `config` is optional because the reserved set is config-driven: given one,\n * a declared environment name is refused here too; without one, only the static\n * tokens are. Pass the open project's config whenever there is one — this is the\n * early, better-worded half of a check the filename grammar makes again when the\n * file is read, never the only half.\n */\nexport function refFromKey(key: string, config?: PenvConfig): ParameterRef {\n const segments = key.split(KEY_SEPARATOR).filter((segment) => segment.length > 0);\n const name = segments[segments.length - 1];\n if (name === undefined) {\n throw new PenvError(\n \"PARAMETER_KEY\",\n `\\`${key}\\` names no parameter`,\n \"A key is `<namespace>/<name>` or `<namespace>.<name>`, e.g. `redis/password`.\",\n );\n }\n if (isReservedToken(name, config ?? NO_ENVIRONMENTS)) {\n throw new ReservedTokenError(\"parameter\", name, key);\n }\n return { namespace: segments.slice(0, -1), name };\n}\n\n/**\n * Refuses a key that no canonical value file can back — the guard for the *write*\n * path only, `set` and the destination of `mv`.\n *\n * It lives apart from {@link refFromKey} deliberately. Read, remove and the\n * source of a rename address a file that already exists by its literal name, and\n * the filename grammar admits a non-canonical name (`dbHost`, `database_url`)\n * that the transform will never *produce* but a hand-written file or an older\n * penv may already have on disk. Guarding those paths would leave such a tree\n * repairable only by deleting the file by hand — the very lockout this function\n * is here to avoid. So only creation is refused: a `set` or a rename *into* a\n * name the schema cannot read is a file that would sit inert, and refusing it\n * early names the file that actually backs the key instead of writing a dead one.\n */\nexport function assertWritableKey(key: string): void {\n const segments = key.split(KEY_SEPARATOR).filter((s) => s.length > 0);\n if (segments.length === 0 || segments.every((s) => isCanonicalSegment(s))) {\n return;\n }\n const ref = refFromAccessPath(segments);\n if (ref !== undefined) {\n const suggestion = [...ref.namespace, ref.name].join(\"/\");\n throw new PenvError(\n \"PARAMETER_KEY_CASING\",\n `\\`${key}\\` is not a canonical parameter name`,\n `Parameter files are lower-case and hyphenated. Did you mean \\`${suggestion}\\`? That is the file that backs the \\`${key}\\` key in your schema.`,\n );\n }\n throw new PenvError(\n \"PARAMETER_KEY_UNREACHABLE\",\n `No value file can be named that reaches \\`${key}\\``,\n \"Parameter files are lower-case and hyphenated, and this key maps to no such file — a run of capitals like `apiURL` cannot be reached (use `api-url`, which the schema reads as `apiUrl`). Run `penv validate` or `penv fill` to see the names penv expects.\",\n );\n}\n\n/**\n * The key source for one environment, chosen by core.\n *\n * The CLI does not decide where keys live — it asks. Two choosers would be two\n * answers to one question, and the runtime is the other caller: a CLI that\n * sealed under a key the runtime could not find would make `penv set` and `load`\n * disagree about the same file.\n */\nexport function keySourceFor(project: Project, environment: string): KeySource {\n return resolveKeySource(project.config, environment);\n}\n\n/**\n * One parameter resolved against the filesystem, without reading it twice.\n *\n * The winner is a `ResolutionCandidate` rather than a bare `ValueFile` so this\n * satisfies core's `ResolvedValue`: the sync walk and the async one then hand the\n * same shape to the same `requireValue`, and there is one place that decides\n * what an unreadable value is.\n */\nexport interface SyncResolution {\n readonly ref: ParameterRef;\n readonly parameter: string;\n /** `undefined` when nothing is present, or when the winner did not open. */\n readonly value: string | undefined;\n readonly winner: ResolutionCandidate | undefined;\n /** Set only when the winner is `.enc` and did not decrypt. Mirrors `Resolution`. */\n readonly undecryptable?: DecryptFailure;\n}\n\n/**\n * The synchronous half of the cascade.\n *\n * `import` and `generate` are synchronous — they are the adoption path, and the\n * v0.1 gate exercises them as plain calls — while the provider contract is\n * async because a network-backed provider cannot be anything else. This walks\n * the filesystem provider's *additional* sync reads, exactly as the runtime\n * loader does for the same reason. It does not restate the precedence rule:\n * `candidatesFor` owns the order, and this only walks the list it returns.\n */\nexport function resolveSync(\n provider: FilesystemProvider,\n ref: ParameterRef,\n environment: string,\n keys: KeySource,\n skipPersonal?: boolean,\n): SyncResolution {\n for (const file of candidatesFor(ref, environment, skipPersonal)) {\n const read = provider.readSync(file);\n if (read === undefined) {\n continue;\n }\n // Unconditional, including for a plaintext file, which comes back verbatim:\n // a branch on `file.encrypted` here would be a second place deciding what\n // encryption means, and this walker is already the second walker.\n const opened = openValue(file, read, keys);\n return {\n ref,\n parameter: parameterId(ref),\n value: opened.kind === \"plaintext\" ? opened.value : undefined,\n ...(opened.kind === \"failed\" ? { undecryptable: opened.failure } : {}),\n winner: { file, location: formatValueFile(file), present: true },\n };\n }\n return { ref, parameter: parameterId(ref), value: undefined, winner: undefined };\n}\n\nexport function resolveAllSync(\n provider: FilesystemProvider,\n environment: string,\n keys: KeySource,\n skipPersonal?: boolean,\n): SyncResolution[] {\n return refsFrom(provider.listSync()).map((ref) =>\n resolveSync(provider, ref, environment, keys, skipPersonal),\n );\n}\n\n/**\n * The parameters a provider holds, scopes collapsed and ordered identically\n * everywhere.\n */\nexport function refsFrom(files: readonly ParameterRef[]): ParameterRef[] {\n const refs = new Map<string, ParameterRef>();\n for (const file of files) {\n const ref: ParameterRef = { namespace: file.namespace, name: file.name };\n const id = parameterId(ref);\n if (!refs.has(id)) {\n refs.set(id, ref);\n }\n }\n // Code-unit order, not locale order: a report must be identical on every machine.\n return [...refs.values()].sort((a, b) => {\n const left = parameterId(a);\n const right = parameterId(b);\n return left < right ? -1 : left > right ? 1 : 0;\n });\n}\n","/**\n * Environment shorthand flags: `penv pull --production` for any environment the\n * config whitelists.\n *\n * User-defined names land in penv's flag namespace under three rules that keep\n * the two from ever fighting:\n *\n * 1. **A real flag always wins.** Candidates are collected *after* every flag\n * the command declares (and penv's globals) is excluded, so an environment\n * named `yes` simply has no shorthand — `--env yes` still works, and config\n * can never rebind a flag penv defines.\n * 2. **Exactly one.** Two environment flags in one invocation is a hard error,\n * never first-wins; a shorthand that contradicts an explicit `--env` is the\n * same error.\n * 3. **`--env` stays canonical.** The shorthand is sugar; scripts and error\n * messages use the spelling that always works, including for names that\n * cannot be flags at all.\n *\n * Resolution happens post-parse against the loaded config's whitelist — the\n * parser knows nothing about environments, so the config cannot influence\n * parsing, only interpretation.\n */\n\nimport type { PenvConfig } from \"@penvhq/core\";\nimport { environmentNames, PenvError } from \"@penvhq/core\";\n\n/** Flags every penv invocation owns regardless of command. */\nconst BASE_RESERVED = [\"help\", \"version\", \"h\", \"v\", \"_\", \"--\"] as const;\n\n/**\n * Every flag name a penv command declares, across commands. An environment named\n * one of these loses its shorthand (rule 1) — `doctor` warns through\n * {@link shadowedEnvironments} so the user hears it once, calmly, rather than\n * discovering a flag that silently means something else.\n */\nconst COMMAND_FLAGS = [...BASE_RESERVED, \"env\", \"out\", \"allow-decrypt\", \"yes\", \"y\"] as const;\n\n/** The declared environments whose names a real flag shadows — no shorthand for these. */\nexport function shadowedEnvironments(config: PenvConfig): string[] {\n const flags = new Set<string>(COMMAND_FLAGS);\n return environmentNames(config).filter((environment) => flags.has(environment));\n}\n\n/**\n * The bare `--<flag>` switches this invocation carries that the command did not\n * declare — the only place an environment shorthand can live. Collected in the\n * command layer, where the declared flag names are known; judged later, where\n * the config is.\n */\nexport function shorthandCandidates(\n args: Readonly<Record<string, unknown>>,\n declared: readonly string[],\n): string[] {\n const reserved = new Set<string>([...BASE_RESERVED, ...declared]);\n return Object.keys(args).filter((key) => !reserved.has(key) && args[key] === true);\n}\n\nfunction quoteList(values: readonly string[]): string {\n return values.map((value) => `\\`--${value}\\``).join(\", \");\n}\n\n/**\n * The environment the shorthand flags name, judged against the whitelist. An\n * unknown bare flag is an error naming the environments that would have worked\n * — before this, a typo'd `--prodction` was silently ignored.\n */\nexport function environmentFromShorthand(\n config: PenvConfig,\n candidates: readonly string[],\n explicit: string | undefined,\n): string | undefined {\n if (candidates.length === 0) {\n return undefined;\n }\n const declared = environmentNames(config);\n const hits = candidates.filter((candidate) => declared.includes(candidate));\n const strangers = candidates.filter((candidate) => !declared.includes(candidate));\n\n if (strangers.length > 0) {\n throw new PenvError(\n \"UNKNOWN_FLAG\",\n `${quoteList(strangers)} ${strangers.length === 1 ? \"is not a flag\" : \"are not flags\"} this command takes, and ${strangers.length === 1 ? \"names\" : \"name\"} no declared environment`,\n `Declared environments work as bare flags: ${quoteList(declared)}. Anything else needs \\`--env <name>\\`.`,\n );\n }\n if (hits.length > 1) {\n throw new PenvError(\n \"ENVIRONMENT_FLAG_AMBIGUOUS\",\n `${quoteList(hits)} name two environments at once, and a command acts on exactly one`,\n \"Pass a single environment flag, or the canonical `--env <name>`.\",\n );\n }\n const hit = hits[0];\n if (hit !== undefined && explicit !== undefined && explicit !== hit) {\n throw new PenvError(\n \"ENVIRONMENT_FLAG_AMBIGUOUS\",\n `\\`--env ${explicit}\\` and \\`--${hit}\\` name two environments at once`,\n \"Drop one of them — `--env` is the canonical spelling.\",\n );\n }\n return hit;\n}\n","/**\n * The provider registry: the one place the CLI turns an environment entry's\n * `provider` into a concrete provider.\n *\n * It lives in the CLI, not in `@penvhq/core` and not in `@penvhq/runtime`. Core owns\n * the `Provider` *contract* and must not know which implementations exist —\n * knowing would make the interface answerable to its callers. The runtime never\n * selects a provider at all: it reads the local records tree whatever an\n * environment declares (see `runtime/src/resolve.ts`), so a registry there would\n * be the ability to dial a network provider at boot, which the design forbids.\n *\n * A provider is the package's fully-qualified name, and the name is the\n * import specifier. The registry pre-installs just two providers — the\n * filesystem tree every command edits and the mock used to rehearse rotation —\n * so \"built-in\" means only \"already installed\", not a different kind of\n * provider. Nothing else in the CLI names an implementation.\n *\n * Everything else is an extension, and {@link resolveExtension} owns the one\n * order every command finds one in: the local-extension list, then the project's\n * own `node_modules`, then `$PENV_HOME` at the version the manifest pins.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type {\n AnyProvider,\n Manifest,\n PenvConfig,\n Provider,\n ProviderFactoryContext,\n} from \"@penvhq/core\";\nimport {\n environmentEntry,\n environmentNames,\n holdsProjection,\n LOCAL_EXTENSIONS_PATH,\n localExtensionsFile,\n MANIFEST_PATH,\n PENV_DIR,\n PenvError,\n packageDir,\n packageEntry,\n parseLocalExtensions,\n parseManifest,\n penvHome,\n providerMissing,\n recordsDir,\n} from \"@penvhq/core\";\nimport { createFilesystemProvider } from \"@penvhq/provider-filesystem\";\nimport { createMockProvider } from \"@penvhq/provider-mock\";\n\n/**\n * What a factory needs to build a provider for one project. The shape is core's:\n * it is the seam provider packages build against, so the CLI consumes the same\n * declaration they do rather than restating it.\n */\nexport type ProviderContext = ProviderFactoryContext;\n\n/** Turns one project's context into a provider of one `type`. */\nexport type ProviderFactory = (context: ProviderContext) => Provider;\n\n/** The factory shape a provider package exports. May be async. */\ntype PluginProviderFactory = (context: ProviderContext) => AnyProvider | Promise<AnyProvider>;\n\n/** The symbol a provider package exports — the entry point this seam calls. */\nconst PLUGIN_FACTORY_EXPORT = \"penvProviderFactory\";\n\n/**\n * The local records tree is always served by the filesystem provider: it is the\n * working copy `penv pull` materialises and every command edits, whatever backend\n * an environment's source of truth lives in. Naming it here keeps the one string\n * literal that means \"the tree on disk\" out of `openProject`.\n */\nexport const LOCAL_TREE_TYPE = \"@penvhq/provider-filesystem\";\n\n/**\n * The providers that ship inside the CLI, so they resolve without the project\n * installing anything: the local tree itself, and the mock that rehearses\n * rotation. Every other provider is a package the project depends on.\n */\nconst REGISTRY = new Map<string, ProviderFactory>([\n [\n LOCAL_TREE_TYPE,\n ({ root, config }) => createFilesystemProvider({ root: recordsDir(root), config }),\n ],\n [\n \"@penvhq/provider-mock\",\n ({ root }) => createMockProvider({ storePath: resolve(root, PENV_DIR, \".penv-mock.json\") }),\n ],\n]);\n\n/** The record contract's methods — what a records-holding provider must carry before penv trusts it. */\nconst RECORD_CONTRACT_METHODS = [\n \"read\",\n \"write\",\n \"list\",\n \"remove\",\n \"readMeta\",\n \"writeMeta\",\n \"removeMeta\",\n] as const;\n\n/** The projection contract's required methods — the smaller surface a projection-holding provider carries. */\nconst PROJECTION_CONTRACT_METHODS = [\"verify\", \"push\", \"list\"] as const;\n\n/**\n * Loaded provider modules, memoized by resolved path, so a command touching\n * several environments backed by one package imports it once.\n */\nconst pluginModuleCache = new Map<string, Promise<Record<string, unknown>>>();\n\n/** Whether a package name is one the CLI ships pre-installed. */\nexport function isProviderRegistered(type: string): boolean {\n return REGISTRY.has(type);\n}\n\n/**\n * Builds a *pre-installed* provider of `type`, refusing any other loudly. This is\n * the synchronous path `openProject` uses for the local filesystem tree, which\n * always ships with the CLI — so it stays sync and never dials a package. A\n * declared source of truth, which may be any installed provider package, is\n * built through {@link createSourceProvider} instead.\n */\nexport function createProvider(type: string, context: ProviderContext): Provider {\n const factory = REGISTRY.get(type);\n if (factory === undefined) {\n throw unknownProvider(type);\n }\n return factory(context);\n}\n\n/**\n * Builds a provider of `type`. A pre-installed provider comes from the static map\n * (synchronously); anything else is imported from the package `type` names and\n * validated against the contract before it is trusted. The import is async,\n * which is why this is — a network provider cannot be constructed on a\n * synchronous path.\n */\nexport async function createSourceProvider(\n type: string,\n context: ProviderContext,\n): Promise<AnyProvider> {\n if (REGISTRY.has(type)) {\n return createProvider(type, context);\n }\n return loadPluginProvider(type, context);\n}\n\nasync function loadPluginProvider(type: string, context: ProviderContext): Promise<AnyProvider> {\n const path = resolveExtension(type, context.root, context.environment);\n\n let mod: Record<string, unknown>;\n try {\n mod = await importPlugin(path);\n } catch (cause) {\n throw providerLoadFailed(type, path, cause);\n }\n\n const factory = mod[PLUGIN_FACTORY_EXPORT];\n if (typeof factory !== \"function\") {\n throw new PenvError(\n \"PROVIDER_PLUGIN_INVALID\",\n `\\`${type}\\` does not export \\`${PLUGIN_FACTORY_EXPORT}\\``,\n `A penv provider package must export \\`${PLUGIN_FACTORY_EXPORT}(context) => Provider\\`.`,\n );\n }\n\n const provider = await (factory as PluginProviderFactory)(context);\n assertSatisfiesContract(provider, type);\n return provider;\n}\n\n/**\n * Refuses at open time every environment whose `provider` names a backend\n * this project cannot construct — the whole config in one pass, so a user with two\n * unknown providers hears about both, and never as a crash from the later command\n * that would have been the first to reach one.\n *\n * An entry naming no provider at all is refused here too, rather than skipped. A\n * half-migrated entry — one that kept `type:` — otherwise opens cleanly, and the\n * credential strip in `child-env.ts` cannot name the credentials of a provider\n * penv was never told about: `penv run` would hand the child `VAULT_TOKEN`.\n *\n * A pre-installed type passes on the map; any other passes only if\n * {@link resolveExtension} finds it — a *synchronous* existence check that runs\n * no provider code, so the open-time guarantee holds without `openProject`\n * turning async. The package's module is imported and its contract checked\n * later, when the environment's source is actually built.\n */\nexport function assertProvidersRegistered(\n config: PenvConfig,\n projectRoot: string,\n options?: { readonly ci?: boolean },\n): void {\n const local = localExtensions(projectRoot);\n const ci = options?.ci ?? isCi(process.env.CI);\n for (const environment of environmentNames(config)) {\n const provider = environmentEntry(config, environment)?.provider;\n if (typeof provider !== \"string\" || provider.trim().length === 0) {\n throw providerMissing(environment);\n }\n if (isProviderRegistered(provider)) {\n continue;\n }\n if (ci && local.includes(provider)) {\n throw localExtensionInCi(provider, environment);\n }\n resolveExtension(provider, projectRoot, environment, local);\n }\n}\n\n/**\n * The one place an extension is located, and the one order it is looked for in.\n * Every command resolves through here, so what `doctor` reports, what\n * `openProject` refuses, and what a provider operation imports are one answer.\n *\n * 1. **The local-extension list.** A package this checkout builds is read out of\n * the project and never out of the store: nothing pins it, so there are no\n * bytes in the store that could be it.\n * 2. **The project's own `node_modules`.** A package the project depends on wins\n * over anything the manifest pins — a repository editing a provider runs the\n * copy it is editing, not a release installed beside it.\n * 3. **`$PENV_HOME/extensions/<name>/<version>`, at the version the manifest\n * pins.** What `penv add` installed, `penv install` restores, and the\n * launcher verified before it passed `$PENV_HOME` to this process. This is\n * the path an extension added from a registry takes: `penv add` leaves\n * nothing in the project but a type declaration, so nothing about it resolves\n * from `node_modules`.\n *\n * Locating is not loading. This runs no provider code; the module is imported\n * only when a command actually performs a provider operation.\n */\nfunction resolveExtension(\n type: string,\n projectRoot: string,\n environment?: string,\n local: readonly string[] = localExtensions(projectRoot),\n): string {\n const fromProject = resolvePlugin(type, projectRoot);\n if (local.includes(type)) {\n if (fromProject === undefined) {\n throw localExtensionUnresolved(type, projectRoot, environment);\n }\n return fromProject;\n }\n if (fromProject !== undefined) {\n return fromProject;\n }\n\n const version = pinnedVersion(type, projectRoot);\n if (version === undefined) {\n throw unknownProvider(type, environment);\n }\n const stored = storedExtension(type, version);\n if (stored === undefined) {\n throw extensionNotInstalled(type, version, environment);\n }\n return stored;\n}\n\n/**\n * The version the manifest pins for `type`, or `undefined` when it pins none.\n *\n * A manifest penv cannot read is not this function's refusal: the launcher reads\n * it first on every run and owns every message about it, so a broken one here\n * means the type is simply not pinned — and the caller's own refusal, which\n * names the package rather than the file, is the better one to arrive.\n */\nfunction pinnedVersion(type: string, projectRoot: string): string | undefined {\n let manifest: Manifest;\n try {\n manifest = parseManifest(readFileSync(join(projectRoot, ...MANIFEST_PATH.split(\"/\")), \"utf8\"));\n } catch {\n return undefined;\n }\n return manifest.extensions[type]?.version;\n}\n\n/** The module of one pinned extension in `$PENV_HOME`, or `undefined` if it is not there. */\nfunction storedExtension(type: string, version: string): string | undefined {\n const entry = packageEntry(packageDir(penvHome(process.env), \"extensions\", type, version));\n return entry?.file;\n}\n\n/** The extensions this project develops, as `penv add --local` recorded them. */\nexport function localExtensions(projectRoot: string): string[] {\n let text: string;\n try {\n text = readFileSync(localExtensionsFile(projectRoot), \"utf8\");\n } catch {\n return [];\n }\n return parseLocalExtensions(text);\n}\n\nfunction isCi(value: string | undefined): boolean {\n return value !== undefined && value !== \"\" && value !== \"0\" && value.toLowerCase() !== \"false\";\n}\n\n/**\n * A local extension is the copy in this checkout, and nothing pins its bytes —\n * which is exactly what a pipeline may not run on. The remedy is the registry\n * path, because that is the one that produces something CI can verify.\n */\nfunction localExtensionInCi(type: string, environment: string): PenvError {\n return new PenvError(\n \"LOCAL_EXTENSION_IN_CI\",\n `The provider \\`${type}\\` for environment ${environment} is a local extension, and this is CI`,\n `${LOCAL_EXTENSIONS_PATH} records it as a package this project develops, so nothing pins ` +\n `the bytes CI would run. Publish it and run \\`penv add ${type}\\` to pin a release.`,\n );\n}\n\n/**\n * Resolves a provider package from the project, synchronously and without running\n * it. Returns the absolute module path, or `undefined` when the package is not\n * installed. `createRequire` is anchored at the project (not the CLI's own\n * install), so a globally-installed penv still finds a provider the project\n * depends on.\n */\nfunction resolvePlugin(specifier: string, fromDir: string): string | undefined {\n try {\n const require = createRequire(resolve(fromDir, \"noop.js\"));\n return require.resolve(specifier);\n } catch {\n return undefined;\n }\n}\n\n/** Imports the resolved module by path, memoized, working from both the ESM and CJS builds. */\nfunction importPlugin(resolvedPath: string): Promise<Record<string, unknown>> {\n const cached = pluginModuleCache.get(resolvedPath);\n if (cached !== undefined) {\n return cached;\n }\n const loading = import(pathToFileURL(resolvedPath).href) as Promise<Record<string, unknown>>;\n pluginModuleCache.set(resolvedPath, loading);\n return loading;\n}\n\n/**\n * Fails loudly if a loaded provider is missing a contract method — at load, not\n * mid-write. Which contract is the provider's own declaration: a\n * `holds: \"projection\"` capability selects the projection surface, anything\n * else the seven-method record contract the filesystem defines.\n */\nfunction assertSatisfiesContract(provider: AnyProvider, specifier: string): void {\n const projection = holdsProjection(provider);\n const methods: readonly string[] = projection\n ? PROJECTION_CONTRACT_METHODS\n : RECORD_CONTRACT_METHODS;\n const contract = projection\n ? \"the @penvhq/core ProjectionProvider contract its declared capabilities select\"\n : \"the @penvhq/core Provider contract that the filesystem provider defines\";\n for (const method of methods) {\n if (typeof (provider as unknown as Record<string, unknown>)[method] !== \"function\") {\n throw new PenvError(\n \"PROVIDER_PLUGIN_INVALID\",\n `The provider from \\`${specifier}\\` is missing \\`${method}()\\``,\n `It must satisfy ${contract}.`,\n );\n }\n }\n}\n\nfunction where(environment: string | undefined): string {\n return environment === undefined ? \"\" : ` for environment ${environment}`;\n}\n\nfunction unknownProvider(type: string, environment?: string): PenvError {\n const preinstalled = [...REGISTRY.keys()].map((name) => `\\`${name}\\``).join(\", \");\n return new PenvError(\n \"UNKNOWN_PROVIDER\",\n `The provider \\`${type}\\`${where(environment)} in penv.config.ts is nowhere penv looks for it`,\n `Run \\`penv add ${type}\\` to pin a release, or \\`penv add --local ${type}\\` if this ` +\n `repository is the one that builds it. penv looks in ${LOCAL_EXTENSIONS_PATH}, this ` +\n `project's node_modules, and then $PENV_HOME at the version ${MANIFEST_PATH} pins. The ` +\n `CLI ships ${preinstalled} pre-installed.`,\n );\n}\n\n/**\n * The manifest pins this extension and `$PENV_HOME` does not hold it — the one\n * unresolvable provider with a command behind it, so it names that command\n * rather than reporting the package as unknown.\n */\nfunction extensionNotInstalled(type: string, version: string, environment?: string): PenvError {\n return new PenvError(\n \"EXTENSION_NOT_INSTALLED\",\n `${MANIFEST_PATH} pins \\`${type}\\` ${version}${where(environment)}, and it is not installed ` +\n `in ${penvHome(process.env)}`,\n \"Run `penv install` — it downloads and verifies every version the manifest pins, extensions \" +\n \"included.\",\n );\n}\n\n/**\n * A local extension that stopped resolving. It is the copy this checkout builds,\n * so the store is not a second place to look — the project either has it or the\n * record is stale.\n */\nfunction localExtensionUnresolved(\n type: string,\n projectRoot: string,\n environment?: string,\n): PenvError {\n return new PenvError(\n \"LOCAL_EXTENSION_UNRESOLVED\",\n `${LOCAL_EXTENSIONS_PATH} records \\`${type}\\`${where(environment)} as a package this project ` +\n `develops, and it does not resolve from ${projectRoot}`,\n `Add it as a dependency of the root (a workspace link is one) and run \\`pnpm install\\`, or ` +\n `drop the name from ${LOCAL_EXTENSIONS_PATH} if this project no longer builds it.`,\n );\n}\n\n/**\n * A provider that resolved and would not import.\n *\n * The cause and the file are the message: `ERR_UNKNOWN_FILE_EXTENSION` on a\n * `src/index.ts` is the whole diagnosis, and a refusal that keeps neither sends\n * the reader to reproduce the import by hand outside penv.\n */\nfunction providerLoadFailed(type: string, path: string, cause: unknown): PenvError {\n const detail = cause instanceof Error ? cause.message : String(cause);\n return new PenvError(\n \"PROVIDER_PLUGIN_LOAD\",\n `The provider package \\`${type}\\` failed to load from ${path}: ${detail}`,\n \"penv imports that file exactly as it stands, with no transform, so it has to be built \" +\n \"JavaScript with its dependencies installed.\",\n );\n}\n","/**\n * The CLI's output voice.\n *\n * Reports are tables: a glyph, a label, and the parameter the line is about.\n * Columns are sized to the widest cell in one block so that a report reads down\n * the page as well as across it, and every command that reports uses this module\n * rather than assembling its own spacing.\n *\n * Color is applied here and nowhere lower: the glyph carries the verdict (green\n * pass, yellow warning, red failure, dim \"could not look\"), details and asides\n * are dimmed as metadata, and a remedy is a cyan-arrowed `tip` — the one shape a\n * reader learns once and then recognizes in every command. All of it degrades to\n * the exact plain bytes when the stream is not a terminal (see `style.ts`), so\n * pipes, CI logs, and tests never see an escape code.\n */\n\nimport { isPenvErrorLike } from \"@penvhq/core\";\nimport { err, out, padVisible, visibleWidth } from \"./style.js\";\n\nexport const CHECK = \"✓\";\nexport const WARN = \"⚠\";\nexport const CROSS = \"✗\";\n/** \"I could not look\" — a check that ran but could not reach a verdict. Never a pass. */\nexport const UNKNOWN = \"?\";\n\n/** The verdict each glyph carries, painted once here so every command agrees. */\nfunction paintGlyph(glyph: string): string {\n switch (glyph) {\n case CHECK:\n return out.green(glyph);\n case WARN:\n return out.yellow(glyph);\n case CROSS:\n return out.red(glyph);\n case UNKNOWN:\n return out.dim(glyph);\n default:\n return glyph;\n }\n}\n\n/** One reported line. `detail` is the last column and is never padded. */\nexport interface Row {\n readonly glyph: string;\n readonly label: string;\n readonly subject?: string;\n readonly detail?: string;\n}\n\n/** A step in a scaffolding run: what penv did, and an aligned aside. */\nexport interface Step {\n readonly glyph: string;\n readonly text: string;\n readonly note?: string;\n}\n\n/** Where a step's aside starts, measured from the glyph. */\nconst NOTE_COLUMN = 29;\n\nfunction widest(values: readonly string[]): number {\n return values.reduce((max, value) => Math.max(max, visibleWidth(value)), 0);\n}\n\nexport function formatRows(rows: readonly Row[]): string[] {\n const labelWidth = widest(rows.map((row) => row.label)) + 2;\n // Only rows that carry a detail need their subject padded; a row whose subject\n // is its last column must not widen the table for every other row.\n const detailed = rows.filter((row) => row.detail !== undefined);\n const subjectWidth = widest(detailed.map((row) => row.subject ?? \"\")) + 1;\n\n return rows.map((row) => {\n const head = `${paintGlyph(row.glyph)} ${padVisible(row.label, labelWidth)}`;\n if (row.detail === undefined) {\n return `${head}${row.subject ?? \"\"}`.trimEnd();\n }\n return `${head}${padVisible(row.subject ?? \"\", subjectWidth)}${out.dim(row.detail)}`.trimEnd();\n });\n}\n\n/**\n * Free-form aligned columns, for output that is a table rather than a report.\n * Every column but the last is padded to its widest cell. Cells may arrive\n * styled: widths are measured on what the terminal renders, not on the bytes.\n */\nexport function columns(rows: readonly (readonly string[])[], gap = 2): string[] {\n const count = rows.reduce((max, row) => Math.max(max, row.length), 0);\n const widths: number[] = [];\n for (let column = 0; column < count; column += 1) {\n widths.push(widest(rows.map((row) => row[column] ?? \"\")) + gap);\n }\n return rows.map((row) =>\n row\n .map((cell, index) =>\n index === row.length - 1 ? cell : padVisible(cell, widths[index] ?? 0),\n )\n .join(\"\")\n .trimEnd(),\n );\n}\n\nexport function formatSteps(steps: readonly Step[]): string[] {\n return steps.map((step) => {\n if (step.note === undefined) {\n return `${paintGlyph(step.glyph)} ${step.text}`;\n }\n // A text wider than the column gets a single space instead of alignment.\n // `padEnd` returns the string untouched when it is already too long, so the\n // aside ran straight into the last word — legible right up until the day a\n // step had something long to say, which is the day it mattered.\n const text =\n visibleWidth(step.text) >= NOTE_COLUMN ? `${step.text} ` : padVisible(step.text, NOTE_COLUMN);\n return `${paintGlyph(step.glyph)} ${text}${out.dim(step.note)}`;\n });\n}\n\n/**\n * A command's title line: what ran, and against which environment. The context\n * is dimmed so the eye lands on the report below, not the banner above it.\n */\nexport function heading(command: string, context?: string): string {\n return context === undefined\n ? out.bold(command)\n : `${out.bold(command)} ${out.dim(`· ${context}`)}`;\n}\n\n/**\n * A line the reader can act on — the `penv set` to paste, the rename to make.\n * One shape for every command: an arrow, then the remedy, indented under the\n * report it belongs to.\n */\nexport function tip(text: string): string {\n return ` ${out.cyan(\"→\")} ${text}`;\n}\n\n/**\n * A styled interactive question: `? parameter · context › `. Every prompt in the\n * CLI is this shape, so answering penv feels like one conversation.\n */\nexport function prompt(subject: string, context?: string): string {\n const head = `${out.cyan(\"?\")} ${out.bold(subject)}`;\n const tail = out.dim(\"› \");\n return context === undefined ? `${head} ${tail}` : `${head} ${out.dim(`· ${context}`)} ${tail}`;\n}\n\nexport function write(lines: readonly string[]): void {\n for (const line of lines) {\n process.stdout.write(`${line}\\n`);\n }\n}\n\n/**\n * The same lines, on stderr — for a command whose stdout belongs to something\n * else. `penv run` is the case: the child's output is the output, and penv's\n * own line must not land in a pipe the child is feeding.\n */\nexport function writeError(lines: readonly string[]): void {\n for (const line of lines) {\n process.stderr.write(`${line}\\n`);\n }\n}\n\n/**\n * A penv refusal already names the parameter, the environment, and the remedy,\n * so it is printed as written — the remedy re-shaped into the same arrowed tip\n * the reports use. Anything else is a bug in penv and keeps its stack.\n *\n * Recognised by shape, not by class: an extension is published self-contained\n * and throws refusals built from its own copy of core's error classes, so\n * `instanceof` would send every provider refusal down the bug path and print ten\n * frames of the provider's `dist` under an otherwise identical block.\n */\nexport function reportError(error: unknown): void {\n if (isPenvErrorLike(error)) {\n // `summary` is the message without the remedy the constructor folds into it,\n // so the remedy can wear the tip shape instead of a bare indent.\n process.stderr.write(`${err.red(CROSS)} ${error.summary}\\n`);\n if (error.remedy !== undefined) {\n process.stderr.write(` ${err.cyan(\"→\")} ${error.remedy}\\n`);\n }\n } else if (error instanceof Error) {\n process.stderr.write(`${err.red(CROSS)} ${error.message}\\n`);\n // The stack minus the message line it repeats, dimmed: it is for the bug\n // report, not the reader — but it must survive a copy-paste, so it is\n // printed rather than hidden.\n const stack = error.stack;\n const frames = stack?.startsWith(`${error.name}: ${error.message}`)\n ? stack.slice(`${error.name}: ${error.message}`.length).replace(/^\\n/, \"\")\n : stack;\n if (frames !== undefined && frames !== \"\") {\n process.stderr.write(`${err.dim(frames)}\\n`);\n }\n } else {\n process.stderr.write(`${err.red(CROSS)} ${String(error)}\\n`);\n }\n process.exitCode = 1;\n}\n\n/** Turns a thrown error into a printed one and a non-zero exit code. */\nexport async function guard(run: () => Promise<void>): Promise<void> {\n try {\n await run();\n } catch (error) {\n reportError(error);\n }\n}\n","/**\n * The CLI's palette.\n *\n * One restrained set of meanings, applied everywhere: green is a verdict that\n * passed, yellow one that warns, red one that failed; cyan marks the actionable —\n * a prompt, a command to paste; dim is metadata the eye should be able to skip.\n * Nothing else gets a color, so a colored word is always a signal.\n *\n * Styling is a property of the stream, not the text: a terminal gets color, a\n * pipe and a test get the exact bytes the plain renderer always produced. The\n * switch honors `NO_COLOR` and `FORCE_COLOR` (in that order — an explicit \"no\"\n * wins), then falls back to whether the stream is a TTY.\n */\n\ninterface ColorStream {\n readonly isTTY?: boolean;\n}\n\nfunction supportsColor(stream: ColorStream): boolean {\n const env = process.env;\n if (env.NO_COLOR !== undefined && env.NO_COLOR !== \"\") {\n return false;\n }\n if (env.FORCE_COLOR !== undefined && env.FORCE_COLOR !== \"\" && env.FORCE_COLOR !== \"0\") {\n return true;\n }\n if (env.TERM === \"dumb\") {\n return false;\n }\n return stream.isTTY === true;\n}\n\n/** Wraps text in one style. Identity when the palette's stream has no color. */\nexport type Paint = (text: string) => string;\n\nexport interface Palette {\n readonly enabled: boolean;\n readonly bold: Paint;\n readonly dim: Paint;\n readonly red: Paint;\n readonly green: Paint;\n readonly yellow: Paint;\n readonly cyan: Paint;\n readonly magenta: Paint;\n}\n\nconst ESC = `${String.fromCharCode(27)}[`;\nconst identity: Paint = (text) => text;\n\nfunction sgr(open: number, close: number, on: boolean): Paint {\n if (!on) {\n return identity;\n }\n const opener = `${ESC}${open}m`;\n const closer = `${ESC}${close}m`;\n return (text) => `${opener}${text}${closer}`;\n}\n\nfunction paletteFor(stream: ColorStream): Palette {\n const on = supportsColor(stream);\n return {\n enabled: on,\n bold: sgr(1, 22, on),\n dim: sgr(2, 22, on),\n red: sgr(31, 39, on),\n green: sgr(32, 39, on),\n yellow: sgr(33, 39, on),\n cyan: sgr(36, 39, on),\n magenta: sgr(35, 39, on),\n };\n}\n\n/** The report palette — everything written through `ui.write`. */\nexport const out: Palette = paletteFor(process.stdout);\n\n/** The error palette — `reportError` writes to stderr, whose TTY-ness is its own. */\nexport const err: Palette = paletteFor(process.stderr);\n\n/**\n * The width a terminal renders, with the style sequences that surround the text\n * counted at zero. Alignment must measure what the reader sees, or a styled cell\n * would push every column after it out of true.\n */\nconst STYLE_PATTERN = new RegExp(`${String.fromCharCode(27)}\\\\[[0-9;]*m`, \"g\");\n\n/**\n * The bytes a terminal actually shows. The one place that knows what a style\n * sequence looks like, so measuring a line and reading one back never disagree\n * — a test asserting a whole line uses this rather than a pattern of its own.\n */\nexport function visibleText(text: string): string {\n return text.replace(STYLE_PATTERN, \"\");\n}\n\nexport function visibleWidth(text: string): number {\n return visibleText(text).length;\n}\n\n/** `padEnd` measured on visible width, so styled and plain cells align in one table. */\nexport function padVisible(text: string, width: number): string {\n const missing = width - visibleWidth(text);\n return missing > 0 ? text + \" \".repeat(missing) : text;\n}\n","/**\n * `penv run` — how an adopted project starts.\n *\n * It resolves the cascade, checks it against the schema, builds a child\n * environment penv owns, and starts the exact command after `--`. Everything\n * after `--` belongs to the child: argument boundaries, pipes, shell syntax,\n * `pre*`/`post*` lifecycle hooks, exit code, signals. penv never rewrites a\n * script, detects an operator, or generates a backing script — the package\n * manager stays the child, and keeps everything that is its business.\n *\n * Two properties are worth stating because they are what the command is for:\n *\n * **It is network-forbidden.** `run` constructs no provider and contacts\n * nothing. It reads what is already materialised locally, and a missing\n * materialisation is a named failure with the `penv pull` line to run — a\n * provider being down is not a reason an application cannot start. `--watch` is\n * the single opt-in exception, and even there a failed sync leaves the running\n * child exactly where it was.\n *\n * **The verdict is `penv validate`'s.** The check runs once, here, and `run`\n * refuses precisely what `validate` refuses: two implementations of \"is this\n * configuration good\" would eventually let `run` start a process CI had already\n * rejected. `checkEnvironment` hands back the resolutions and the validated\n * object it reached that verdict on, so the child environment is built from the\n * same read rather than a second one.\n *\n * The daily form is `penv run -- pnpm dev`: `--source` defaults to `project`,\n * and `--env` falls back to the config's `defaultEnvironment`. CI names both.\n */\n\nimport type { FSWatcher } from \"node:fs\";\nimport { existsSync, readFileSync, watch } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport type { Artifact, ParameterRef, PenvConfig, Resolution } from \"@penvhq/core\";\nimport {\n ARTIFACT_BUILD_COMMAND,\n assertArtifactFor,\n environmentEntry,\n environmentNames,\n isPublicVariable,\n isSecret,\n keySourceFrom,\n MissingMaterializationError,\n openSealed,\n own,\n PenvError,\n parseArtifact,\n RECORDS_PATH,\n UndecryptableValueError,\n variableName,\n} from \"@penvhq/core\";\nimport type { DeclaredCredentials, DeliveredValue } from \"@penvhq/runtime\";\nimport {\n childEnvironment,\n declaredRefs,\n deliveredEnvironment,\n hasRemoteSource,\n RUN_MARKER,\n SNAPSHOT_VARIABLE,\n} from \"@penvhq/runtime\";\nimport { defineCommand } from \"citty\";\nimport type { z } from \"zod\";\nimport type { ChildHandle, ChildResult, StartChild } from \"../child.js\";\nimport { noCommand, startChild } from \"../child.js\";\nimport { activeDotenvFiles } from \"../dotenv-files.js\";\nimport { shorthandCandidates } from \"../env-flags.js\";\nimport { engineVersion } from \"../install.js\";\nimport type { Project } from \"../project.js\";\nimport { openProject, targetEnvironment } from \"../project.js\";\nimport { guard, heading, reportError, writeError } from \"../ui.js\";\nimport type { PullOptions, PullResult } from \"./pull.js\";\nimport { runPull } from \"./pull.js\";\nimport type { EnvironmentCheck, ValidateResult } from \"./validate.js\";\nimport { checkEnvironment } from \"./validate.js\";\n\n/** Where a run reads its values from. `snapshot` is the sealed artifact. */\nexport type RunSource = \"project\" | \"snapshot\";\n\nconst SOURCES: readonly RunSource[] = [\"project\", \"snapshot\"];\n\n/** How long a change waits for its neighbours before `--watch` acts on it. */\nconst DEBOUNCE_MS = 100;\n\n/** How long a child a restart is replacing has to leave before it is made to. */\nconst STOP_GRACE_MS = 5_000;\n\nexport interface RunOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n /** Defaults to `project`. */\n readonly source?: string;\n /** The one mode allowed to synchronise. Off by default. */\n readonly watch?: boolean;\n /** The command exactly as it followed `--`. */\n readonly command: readonly string[];\n /** The environment penv itself was started with. Defaults to `process.env`. */\n readonly host?: Readonly<Record<string, string | undefined>>;\n /** Injected in tests: how a child is started. */\n readonly start?: StartChild;\n /** Injected in tests: the sync `--watch` performs. */\n readonly pull?: (options: PullOptions) => Promise<PullResult>;\n /** Injected in tests: what tells `--watch` something changed. */\n readonly changes?: (onChange: () => void) => { close(): void };\n /** How long a replaced child has to leave before `--watch` insists. Defaults to 5s. */\n readonly stopGraceMs?: number;\n}\n\nexport interface RunResult {\n readonly environment: string;\n readonly source: RunSource;\n readonly command: readonly string[];\n /** Declared variables written into the child. */\n readonly written: number;\n /** Declared-but-valueless variables deleted from the child. */\n readonly deleted: number;\n /** penv's own variables removed before the child saw them. */\n readonly stripped: readonly string[];\n readonly exitCode: number;\n readonly signal: NodeJS.Signals | null;\n /** How many times `--watch` replaced the child. */\n readonly restarts: number;\n}\n\n/**\n * The command a run is, written the way the user would type it. It is what the\n * child carries in {@link RUN_MARKER}, so a nested `penv run` can name the\n * wrapper it found itself inside.\n */\nfunction invocationOf(\n environment: string | undefined,\n command: readonly string[],\n source?: RunSource,\n): string {\n const named = environment === undefined ? \"\" : ` --env ${environment}`;\n // Only `snapshot` is spelled out: `project` is the default, so writing it would\n // teach the reader a flag they never have to type.\n const flags = named + (source === \"snapshot\" ? \" --source snapshot\" : \"\");\n const parts = command.map((part) => (part.includes(\" \") ? JSON.stringify(part) : part));\n return `penv run${flags} -- ${parts.join(\" \")}`;\n}\n\n/**\n * An outer `penv run` meeting an in-script one.\n *\n * Both wrappers are named because neither is wrong on its own and the user\n * wrote them in different files — the outer one at a prompt, the inner one in a\n * `package.json` script they may have forgotten. Nesting is refused rather than\n * resolved: two owned environments over one process means the second silently\n * decides, and which one wins would depend on how the script was written.\n */\nfunction assertNotNested(host: Readonly<Record<string, string | undefined>>, inner: string): void {\n const outer = host[RUN_MARKER];\n if (outer === undefined) {\n return;\n }\n throw new PenvError(\n \"RUN_NESTED\",\n `\\`${inner}\\` is starting inside \\`${outer}\\`, and two penv environments cannot own one process`,\n `Drop one of the two wrappers — the inner one is in a package.json script — then run \\`${outer}\\` again.`,\n );\n}\n\n/** The two sources a run reads. Anything else is refused on what it says, not on what it finds. */\nfunction assertSource(source: string, inner: string): RunSource {\n if (source === \"project\" || source === \"snapshot\") {\n return source;\n }\n throw new PenvError(\n \"RUN_SOURCE_UNKNOWN\",\n `\\`--source ${source}\\` names no source penv reads`,\n `A run reads ${SOURCES.map((name) => `\\`${name}\\``).join(\" or \")}, and \\`project\\` is the default — so \\`${inner}\\` reads the local tree.`,\n );\n}\n\n/**\n * The public-prefix policy, checked before anything starts.\n *\n * `doctor` reports this and `run` refuses it, and that is the difference between\n * a report and a delivery: the variable is about to be written into a process\n * that will inline it into a browser bundle, permanently. penv is the only thing\n * holding both halves — meta says secret, the generated name says public — so it\n * is the only thing that can stop it.\n *\n * `penv artifact build` makes the same refusal for the same reason: the artifact\n * is the other delivery, and the container reading it has no meta to check.\n * `retry` is the command that was refused, so each caller names its own.\n */\nexport async function assertNoPublicSecret(\n project: Project,\n environment: string,\n refs: readonly ParameterRef[],\n retry: string,\n): Promise<void> {\n const prefixes = project.config.publicPrefixes ?? [];\n if (prefixes.length === 0) {\n return;\n }\n for (const ref of refs) {\n const variable = variableName(ref, project.config);\n if (!isPublicVariable(variable, project.config)) {\n continue;\n }\n if (!isSecret(await project.provider.readMeta(ref), environment)) {\n continue;\n }\n const parameter = [...ref.namespace, ref.name].join(\"/\");\n const prefix = prefixes.find((candidate) => variable.startsWith(candidate));\n throw new PenvError(\n \"RUN_PUBLIC_SECRET\",\n `The secret ${parameter} maps to ${variable}, which the \\`${prefix}\\` prefix publishes to the browser`,\n `Rename the parameter, or drop \\`secret\\` from its meta if it is not one — then \\`${retry}\\`.`,\n );\n }\n}\n\n/** A failed check, told to someone who was trying to start something. */\nfunction invalidConfiguration(result: ValidateResult, inner: string): PenvError {\n const lines = result.issues.map((issue) => ` ${issue.subject}: ${issue.message}`).join(\"\\n\");\n return new PenvError(\n \"RUN_INVALID_CONFIGURATION\",\n `Configuration for environment ${result.environment} is not valid, so nothing was started:\\n${lines}`,\n `Fix the values above, then run \\`${inner}\\` again.`,\n );\n}\n\n/** The tree's raw values, in the shape the child-environment assembly takes. */\nfunction valuesOf(\n resolutions: readonly Resolution[],\n): { readonly ref: ParameterRef; readonly value: string }[] {\n const values: { ref: ParameterRef; value: string }[] = [];\n for (const resolution of resolutions) {\n if (resolution.value !== undefined) {\n values.push({ ref: resolution.ref, value: resolution.value });\n }\n }\n return values;\n}\n\n/** What one check produced, once it is known to be startable. */\ninterface Prepared {\n readonly env: Record<string, string>;\n readonly written: number;\n readonly deleted: number;\n readonly stripped: readonly string[];\n}\n\n/**\n * A dotenv file that came back after the project adopted penv (PRD §6).\n *\n * The framework loads `.env`, `.env.local`, `.env.<environment>` and\n * `.env.<environment>.local` on its own, so one of them reappearing beside\n * penv's records is two live sources of configuration — the drift adoption\n * removed, recreated by an editor, a generator, or a teammate's paste. It is\n * refused rather than merged: which of the two is right is not penv's to decide,\n * and the environment the file serves is not always the one being started.\n *\n * `.env.example` and its kin are documentation and no framework loads them, so\n * they are not active files and are never checked. Neither is `.env.staging` in\n * a project that never declared `staging`: nothing loads it either.\n */\nfunction assertNoActiveDotenv(project: Project): void {\n const active = activeDotenvFiles(project.root, project.config);\n const first = active[0];\n if (first === undefined) {\n return;\n }\n throw new PenvError(\n \"RUN_DOTENV_ACTIVE\",\n `${first.name} is active configuration again, and your framework would read it beside penv's records`,\n `Adopt it with \\`penv init\\`, or delete ${first.name} — its values belong in ${RECORDS_PATH}/.`,\n );\n}\n\n/** A generated variable name — the only thing a credential declaration may hold. */\nconst VARIABLE = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The `package.json` of an installed package, found the way the project's own\n * code would find the package: resolved from the project root, then walked up to\n * the manifest that names it. Absent when the package is not installed — the\n * providers penv ships resolve from inside the CLI and have no manifest to read\n * here, which is why they are known rather than asked.\n */\nfunction packageManifest(specifier: string, root: string): Record<string, unknown> | undefined {\n let directory: string;\n try {\n directory = dirname(createRequire(resolve(root, \"noop.js\")).resolve(specifier));\n } catch {\n return undefined;\n }\n for (;;) {\n const file = join(directory, \"package.json\");\n if (existsSync(file)) {\n try {\n const parsed: unknown = JSON.parse(readFileSync(file, \"utf8\"));\n if (isPlainObject(parsed) && parsed.name === specifier) {\n return parsed;\n }\n } catch {\n return undefined;\n }\n }\n const parent = dirname(directory);\n if (parent === directory) {\n return undefined;\n }\n directory = parent;\n }\n}\n\n/**\n * What the providers this config names authenticate with, as each package\n * declares it.\n *\n * penv owns no credential of its own, so a provider's are ambient variables and\n * the only way to keep them out of the child is to name them. The four providers\n * penv ships are named in the runtime, which is where their delivery is decided;\n * every other extension names its own in `penv.credentials` in its package.json\n * — symmetric with `penv.types` — and this reads the declaration off the package\n * the project actually installed, for the providers the config actually names.\n *\n * A declaration that is not a list of variable names is refused rather than\n * skipped. Skipping it would hand that extension's credentials to the\n * application without saying so, which is the one outcome the declaration exists\n * to prevent.\n */\nexport function declaredCredentials(config: PenvConfig, root: string): DeclaredCredentials {\n const declared: Record<string, readonly string[]> = {};\n for (const environment of environmentNames(config)) {\n const provider = environmentEntry(config, environment)?.provider;\n if (provider === undefined || own(declared, provider) !== undefined) {\n continue;\n }\n const penv = packageManifest(provider, root)?.penv;\n const credentials = isPlainObject(penv) ? penv.credentials : undefined;\n if (credentials === undefined) {\n continue;\n }\n if (\n !Array.isArray(credentials) ||\n credentials.some((name) => typeof name !== \"string\" || !VARIABLE.test(name))\n ) {\n throw new PenvError(\n \"PROVIDER_CREDENTIALS_INVALID\",\n `\\`${provider}\\` declares \\`penv.credentials\\`, and it is not a list of variable names`,\n `Its package.json should read \\`\"penv\": { \"credentials\": [\"ACME_TOKEN\"] }\\` — penv strips ` +\n \"exactly what an extension declares, so it will not guess at a declaration it cannot read.\",\n );\n }\n declared[provider] = credentials;\n }\n return declared;\n}\n\nasync function prepare(\n project: Project,\n environment: string,\n host: Readonly<Record<string, string | undefined>>,\n inner: string,\n): Promise<Prepared> {\n assertNoActiveDotenv(project);\n const check: EnvironmentCheck = await checkEnvironment(project, environment);\n\n if (!check.result.ok || check.schema === undefined) {\n // Nothing at all resolved, for an environment whose values live in a\n // provider: this is the clone-and-run case, and the whole tree is what is\n // missing. The schema report below would be a wall of absences with the\n // wrong remedy under it.\n if (\n check.resolutions.every((resolution) => resolution.winner === undefined) &&\n hasRemoteSource(project.config, environment)\n ) {\n throw new MissingMaterializationError(environment);\n }\n throw invalidConfiguration(check.result, inner);\n }\n\n const schema: z.ZodType = check.schema;\n await assertNoPublicSecret(project, environment, declaredRefs(schema), inner);\n\n const { env, written, deleted, stripped } = childEnvironment({\n host,\n config: project.config,\n environment,\n schema,\n values: valuesOf(check.resolutions),\n ...(check.validated === undefined ? {} : { validated: check.validated }),\n credentials: declaredCredentials(project.config, project.root),\n invocation: inner,\n });\n return { env, written, deleted, stripped };\n}\n\n/**\n * The artifact a `--source snapshot` run reads, and only that.\n *\n * `PENV_SNAPSHOT` is the whole of the input. There is no search, no default\n * path, and no fall back to the project tree: a container that was supposed to\n * mount an artifact and did not must say so, not quietly start from whatever\n * happens to be on disk beside it.\n */\nfunction snapshotPath(host: Readonly<Record<string, string | undefined>>): string {\n const path = host[SNAPSHOT_VARIABLE]?.trim();\n if (path === undefined || path.length === 0) {\n throw new PenvError(\n \"RUN_SNAPSHOT_UNSET\",\n `\\`--source snapshot\\` reads the sealed artifact ${SNAPSHOT_VARIABLE} names, and ${SNAPSHOT_VARIABLE} is not set`,\n `Build one with \\`${ARTIFACT_BUILD_COMMAND}\\` and point ${SNAPSHOT_VARIABLE} at it.`,\n );\n }\n return path;\n}\n\nfunction readSnapshot(path: string): string {\n try {\n return readFileSync(path, \"utf8\");\n } catch {\n throw new PenvError(\n \"RUN_SNAPSHOT_MISSING\",\n `${SNAPSHOT_VARIABLE} names ${path}, and penv cannot read a sealed artifact there`,\n `Point ${SNAPSHOT_VARIABLE} at the artifact your release mounted — \\`${ARTIFACT_BUILD_COMMAND}\\` writes one.`,\n );\n }\n}\n\n/**\n * The artifact's values, opened in memory.\n *\n * The key source is the identifier the artifact carries and nothing else — the\n * environment's entry never travelled, because provider and key *configuration*\n * is exactly what an artifact must not hold. A ciphertext that will not open is a\n * refusal here, before the child exists: the alternative is starting an\n * application with a variable silently missing.\n */\nfunction openSnapshot(artifact: Artifact, path: string): DeliveredValue[] {\n const keys = keySourceFrom(artifact.keySource, artifact.environment);\n return Object.entries(artifact.values)\n .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))\n .map(([parameter, entry]): DeliveredValue => {\n if (entry.kind === \"absent\") {\n return { parameter, variable: entry.variable };\n }\n if (entry.kind === \"plain\") {\n return { parameter, variable: entry.variable, value: entry.value };\n }\n const opened = openSealed(entry.address, entry.sealed, keys);\n if (opened.kind === \"failed\") {\n throw new UndecryptableValueError(\n parameter,\n artifact.environment,\n `${entry.address} in ${path}`,\n opened.failure,\n );\n }\n return { parameter, variable: entry.variable, value: opened.value };\n });\n}\n\n/**\n * A run from a sealed artifact: read, verify, open, inject.\n *\n * No project is opened, and that is the point rather than an optimisation.\n * There is no `penv.config.ts`, no records tree and no provider package in a\n * release container, so this path reaches for none of them — and the artifact is\n * verified whole (format, engine, environment, delivery digest) before a single\n * ciphertext is opened.\n */\nfunction prepareFromSnapshot(\n host: Readonly<Record<string, string | undefined>>,\n environment: string | undefined,\n command: readonly string[],\n): { readonly environment: string; readonly prepared: Prepared } {\n const path = snapshotPath(host);\n const artifact = parseArtifact(readSnapshot(path), path);\n assertArtifactFor(\n artifact,\n { engineVersion: engineVersion(), ...(environment === undefined ? {} : { environment }) },\n path,\n );\n\n const { env, written, deleted, stripped } = deliveredEnvironment({\n host,\n environment: artifact.environment,\n values: openSnapshot(artifact, path),\n invocation: invocationOf(artifact.environment, command, \"snapshot\"),\n });\n return { environment: artifact.environment, prepared: { env, written, deleted, stripped } };\n}\n\n/**\n * `--watch`'s sync, and whether it worked.\n *\n * Reported and swallowed rather than thrown: a provider that will not answer\n * must not take a running child down with it. The caller uses the answer to\n * decide whether to go on — mid-session it does not, because restarting on a\n * sync that did not happen would swap a validated environment for the same one\n * and stop the child for nothing.\n */\nasync function sync(\n project: Project,\n environment: string,\n pull: (options: PullOptions) => Promise<PullResult>,\n): Promise<boolean> {\n if (!hasRemoteSource(project.config, environment)) {\n return true;\n }\n try {\n await pull({ cwd: project.root, environment });\n return true;\n } catch (error) {\n // The message is what is wanted here, not the verdict: a provider that would\n // not answer must not decide the exit code of a session the user ends later.\n const previous = process.exitCode;\n reportError(error);\n process.exitCode = previous;\n return false;\n }\n}\n\n/**\n * Stopping the child a restart is replacing: asked, then made to.\n *\n * SIGTERM is the ask, and a dev server that traps it and never leaves would hold\n * the restart open forever — waiting on a child that has decided not to end is a\n * developer watching nothing happen. So the ask is bounded and the escalation is\n * a signal the process cannot decline.\n */\nasync function stop(child: ChildHandle, graceMs: number): Promise<void> {\n child.kill(\"SIGTERM\");\n const escalation = setTimeout(() => child.kill(\"SIGKILL\"), graceMs);\n try {\n await child.ended;\n } finally {\n clearTimeout(escalation);\n }\n}\n\n/** The default change signal: the records tree and the config file, debounced. */\nfunction watchProject(project: Project, onChange: () => void): { close(): void } {\n const watchers = new Set<FSWatcher>();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const schedule = (): void => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n timer = setTimeout(onChange, DEBOUNCE_MS);\n };\n\n const add = (target: string, recursive: boolean, only?: string): void => {\n if (!existsSync(target)) {\n return;\n }\n try {\n const watcher = watch(target, { recursive }, (_event, filename) => {\n if (only !== undefined && (filename === null || basename(filename) !== only)) {\n return;\n }\n schedule();\n });\n watcher.on(\"error\", () => watchers.delete(watcher));\n watchers.add(watcher);\n } catch {\n // A platform that cannot watch this target is a weaker watch, never a\n // wrong run: the child already has the environment penv resolved.\n }\n };\n\n add(project.recordsDir, true);\n add(dirname(project.configFile), false, basename(project.configFile));\n\n return {\n close(): void {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n for (const watcher of watchers) {\n watcher.close();\n }\n },\n };\n}\n\nexport async function runRun(options: RunOptions): Promise<RunResult> {\n const command = options.command;\n const host = options.host ?? process.env;\n const inner = invocationOf(options.environment, command);\n\n // Before anything is opened or read: a nested run is refused on what it is,\n // not on what the project turns out to hold.\n assertNotNested(host, inner);\n const source = assertSource(options.source ?? \"project\", inner);\n if (command.length === 0) {\n throw noCommand();\n }\n\n if (source === \"snapshot\") {\n // `--watch` synchronises a tree from a provider, and neither exists here. It\n // is refused rather than ignored: a flag that quietly does nothing is a\n // developer waiting for a restart that is never coming.\n if (options.watch === true) {\n throw new PenvError(\n \"RUN_SNAPSHOT_WATCH\",\n \"`--watch` re-syncs the project tree, and a run from a sealed artifact has no tree to watch\",\n \"Drop `--watch` — an artifact is built once and read unchanged. Watch the project instead: `penv run --watch -- <command>`.\",\n );\n }\n // A release container has no project to open, so none is.\n const snapshot = prepareFromSnapshot(host, options.environment, command);\n return startAndReport(\n snapshot.environment,\n source,\n command,\n snapshot.prepared,\n options.start ?? startChild,\n options.cwd,\n );\n }\n\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n const invocation = invocationOf(environment, command);\n const start = options.start ?? startChild;\n const pull = options.pull ?? runPull;\n\n if (options.watch) {\n await sync(project, environment, pull);\n }\n\n const first = await prepare(project, environment, host, invocation);\n if (options.watch !== true) {\n return startAndReport(environment, source, command, first, start, project.root);\n }\n announce(environment, source, first);\n\n let current = start({ command, env: first.env, cwd: project.root });\n\n // What the running child was given, which is what the run reports: after a\n // restart the first environment is history, and reporting it would count\n // variables nothing is using.\n let latest = first;\n let restarts = 0;\n let restarting: Promise<void> | undefined;\n let closed = false;\n\n const changed = (options.changes ?? ((onChange) => watchProject(project, onChange)))(() => {\n if (closed || restarting !== undefined) {\n return;\n }\n restarting = (async () => {\n // A failed sync or a failed check leaves the child exactly where it was.\n // That is the guarantee of the mode: an edit mid-thought, or a provider\n // that will not answer, must not take the dev server down — and the\n // environment the child already has is still the last one that validated.\n if (!(await sync(project, environment, pull))) {\n return;\n }\n let next: Prepared;\n try {\n next = await prepare(project, environment, host, invocation);\n } catch (error) {\n const previous = process.exitCode;\n reportError(error);\n process.exitCode = previous;\n return;\n }\n if (closed) {\n return;\n }\n await stop(current, options.stopGraceMs ?? STOP_GRACE_MS);\n current = start({ command, env: next.env, cwd: project.root });\n latest = next;\n restarts += 1;\n })().finally(() => {\n restarting = undefined;\n });\n });\n\n try {\n for (;;) {\n const ended = await current.ended;\n // The child ended while a restart was in flight — the restart is what\n // ended it, so wait for the replacement rather than reporting the kill.\n if (restarting !== undefined) {\n await restarting;\n continue;\n }\n closed = true;\n return report(environment, source, command, latest, ended, restarts);\n }\n } finally {\n closed = true;\n changed.close();\n }\n}\n\n/**\n * penv's one line, on stderr: the child owns stdout, and a run whose output is\n * piped somewhere must deliver the child's bytes and nothing else.\n */\nfunction announce(environment: string, source: RunSource, prepared: Prepared): void {\n writeError([\n heading(\n `penv run · ${environment}`,\n `${source} · ${prepared.written} variables${prepared.deleted === 0 ? \"\" : ` · ${prepared.deleted} deleted`}`,\n ),\n ]);\n}\n\n/** The plain run, whichever source prepared it: announce, start, wait, report. */\nasync function startAndReport(\n environment: string,\n source: RunSource,\n command: readonly string[],\n prepared: Prepared,\n start: StartChild,\n cwd: string,\n): Promise<RunResult> {\n announce(environment, source, prepared);\n const ended = await start({ command, env: prepared.env, cwd }).ended;\n return report(environment, source, command, prepared, ended, 0);\n}\n\nfunction report(\n environment: string,\n source: RunSource,\n command: readonly string[],\n prepared: Prepared,\n ended: ChildResult,\n restarts: number,\n): RunResult {\n return {\n environment,\n source,\n command,\n written: prepared.written,\n deleted: prepared.deleted,\n stripped: prepared.stripped,\n exitCode: ended.exitCode,\n signal: ended.signal,\n restarts,\n };\n}\n\nexport const runCommand = defineCommand({\n meta: {\n name: \"run\",\n description: \"Start a command in a penv-owned child environment\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to run against\" },\n source: {\n type: \"string\",\n description: \"Where values come from: project (default) or snapshot\",\n },\n watch: { type: \"boolean\", description: \"Re-sync and restart the child when the tree changes\" },\n },\n run({ args, rawArgs }) {\n return guard(async () => {\n // The command is taken from the raw arguments, not from the parsed\n // positionals: `--` is the boundary the user drew, and re-deriving it from\n // a parse would be penv having an opinion about the argument list it\n // promised not to read.\n const separator = rawArgs.indexOf(\"--\");\n const command = separator === -1 ? [] : rawArgs.slice(separator + 1);\n\n const result = await runRun({\n cwd: process.cwd(),\n command,\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.source === undefined ? {} : { source: args.source }),\n ...(args.watch === true ? { watch: true } : {}),\n envFlags: shorthandCandidates(args, [\"env\", \"source\", \"watch\"]),\n });\n\n // The child's status is the run's status, both halves of it. A signal is\n // re-raised on penv itself so a shell sees the death it would have seen\n // without the wrapper.\n if (result.signal !== null) {\n process.kill(process.pid, result.signal);\n return;\n }\n process.exitCode = result.exitCode;\n });\n },\n});\n","/**\n * The dotenv files a project's framework reads, and what each one says.\n *\n * One module answers this for both ends of adoption: `penv init` offers these\n * files for the cutover, and `penv run` refuses the ones that come back\n * afterwards. Two readings of \"which files are active\" would eventually let init\n * move a file run does not watch, or run refuse a file init never offered.\n *\n * The four scopes are invariant 4's, which are Next.js's and Vite's:\n * `.env` > `.env.local` > `.env.<environment>` > `.env.<environment>.local`.\n * Anything else with an `.env` prefix is documentation (`.env.example`), a\n * leftover (`.env.backup`), or a filename penv has no reading of — none of them\n * is configuration a framework loads, so none is offered or refused.\n *\n * Reading an environment out of a filename here is not inference: nothing\n * reaches `penv.config.ts` until a human selects the file, and\n * {@link activeDotenvFiles} judges the segment against the declared whitelist\n * (invariant 10) rather than believing it.\n */\n\nimport { readdirSync } from \"node:fs\";\nimport type { PenvConfig } from \"@penvhq/core\";\nimport { environmentNames, isLegalEnvironmentName, RESERVED_TOKENS } from \"@penvhq/core\";\n\n/** The prefix every dotenv filename carries, and the bare shared-default name. */\nconst SHARED = \".env\";\nconst LOCAL = \"local\";\n\n/**\n * Segments that look like an environment but are documentation (`.env.example`),\n * a copy (`.env.backup`, which `penv import` itself writes), or one of the\n * grammar's reserved scope markers. A file named for one of these is never\n * offered: it declares nothing, and adopting it would put a name in the\n * whitelist no value file can be scoped to.\n */\nconst NOT_ENVIRONMENTS: readonly string[] = [\n ...RESERVED_TOKENS,\n \"example\",\n \"sample\",\n \"template\",\n \"backup\",\n];\n\n/** Where a dotenv file sits in the cascade. */\nexport type DotenvKind = \"shared\" | \"local\" | \"environment\" | \"environment-local\";\n\nexport interface DotenvFile {\n /** The filename exactly as it is on disk — what undo restores. */\n readonly name: string;\n readonly kind: DotenvKind;\n /** The environment the filename names, for the two environment-scoped kinds. */\n readonly environment?: string;\n /** How the file is described in the selection table. */\n readonly label: string;\n}\n\nfunction classify(name: string): DotenvFile | undefined {\n if (name === SHARED) {\n return { name, kind: \"shared\", label: \"shared default\" };\n }\n if (!name.startsWith(`${SHARED}.`)) {\n return undefined;\n }\n const segments = name.slice(SHARED.length + 1).split(\".\");\n const [first, second] = segments;\n if (first === undefined || first.length === 0) {\n return undefined;\n }\n if (segments.length === 1) {\n if (first === LOCAL) {\n return { name, kind: \"local\", label: \"local override\" };\n }\n return environmentFile(name, first, \"environment\");\n }\n if (segments.length === 2 && second === LOCAL) {\n return environmentFile(name, first, \"environment-local\");\n }\n // Three or more segments, or `.env.local.production` — no scope penv reads.\n return undefined;\n}\n\nfunction environmentFile(\n name: string,\n environment: string,\n kind: \"environment\" | \"environment-local\",\n): DotenvFile | undefined {\n if (!isLegalEnvironmentName(environment) || NOT_ENVIRONMENTS.includes(environment)) {\n return undefined;\n }\n return {\n name,\n kind,\n environment,\n label: kind === \"environment\" ? environment : `${environment}-local`,\n };\n}\n\n/** Shared, then local, then each environment's pair, alphabetically — the same list everywhere. */\nfunction order(file: DotenvFile): string {\n switch (file.kind) {\n case \"shared\":\n return \"0\";\n case \"local\":\n return \"1\";\n case \"environment\":\n return `2${file.environment}0`;\n default:\n return `2${file.environment}1`;\n }\n}\n\n/**\n * Every dotenv file at the project root that carries one of the four scopes,\n * in display order. A directory named `.env.something` is not a file a framework\n * reads, so `withFileTypes` keeps it out.\n */\nexport function discoverDotenvFiles(root: string): DotenvFile[] {\n let entries: readonly string[];\n try {\n entries = readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isFile())\n .map((entry) => entry.name);\n } catch {\n return [];\n }\n\n const files: DotenvFile[] = [];\n for (const entry of entries) {\n const file = classify(entry);\n if (file !== undefined) {\n files.push(file);\n }\n }\n return files.sort((a, b) => (order(a) < order(b) ? -1 : order(a) > order(b) ? 1 : 0));\n}\n\n/**\n * The files this project's framework would actually load: the two unscoped ones,\n * and the environment-scoped ones whose environment the config declares.\n *\n * A `.env.staging` in a project that never declared `staging` is not active — no\n * framework loads it, and reading it as one would be penv inferring the\n * environment invariant 10 forbids it from inferring.\n */\nexport function activeDotenvFiles(root: string, config: PenvConfig): DotenvFile[] {\n const declared = environmentNames(config);\n return discoverDotenvFiles(root).filter(\n (file) => file.environment === undefined || declared.includes(file.environment),\n );\n}\n\n/** The environments a set of selected files declares. `.env` alone declares none. */\nexport function environmentsDeclaredBy(files: readonly DotenvFile[]): string[] {\n const names = new Set<string>();\n for (const file of files) {\n if (file.environment !== undefined) {\n names.add(file.environment);\n }\n }\n return [...names].sort();\n}\n\n/** The cascade `environment` reads, most general first — invariant 4's four levels. */\nexport function cascadeFor(environment: string): string[] {\n return [\n SHARED,\n `${SHARED}.${LOCAL}`,\n `${SHARED}.${environment}`,\n `${SHARED}.${environment}.${LOCAL}`,\n ];\n}\n","/**\n * `penv pull` — materialise the local `.penv` tree from an environment's\n * source-of-truth provider. It is the inverse of the deploy-time injection most\n * stacks already have: instead of reading the tree to feed a backend, it reads\n * the backend to feed the tree.\n *\n * It only means anything when the environment declares a real backend\n * (`vault`, `mock`): those hold the truth somewhere penv does not edit in place,\n * and pulling copies it down so every other command — which reads the local tree\n * — sees it. An environment whose entry names the filesystem provider has the\n * local tree *as* its source of truth, so a pull would be the tree copying onto\n * itself; that degenerate case is reported as nothing to do, never a self-copy.\n *\n * Values cross verbatim. They are opaque envelope strings the source holds and\n * penv does not open here — a sealed value stays sealed, byte-for-byte, so the\n * key that opens it never has to be present to pull it.\n */\n\nimport type { AnyProvider, Meta, ProjectionProvider } from \"@penvhq/core\";\nimport { holdsProjection, refFromVariable } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { shorthandCandidates } from \"../env-flags.js\";\nimport type { Project } from \"../project.js\";\nimport {\n localTree,\n openProject,\n refsFrom,\n sourceProviderFor,\n targetEnvironment,\n} from \"../project.js\";\nimport { LOCAL_TREE_TYPE } from \"../registry.js\";\nimport { CHECK, formatRows, guard, WARN, write } from \"../ui.js\";\n\nexport interface PullOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n /** Injected in tests: the source provider. Defaults to the one the config declares. */\n readonly source?: AnyProvider;\n}\n\nexport interface PullResult {\n readonly environment: string;\n /** The source provider's type — `filesystem` when the environment declares no separate backend. */\n readonly source: string;\n /**\n * True when the source *is* the local tree, so there was nothing to pull. The\n * caller distinguishes \"pulled nothing because the backend was empty\" from\n * \"there is no backend to pull from\" — opposite situations.\n */\n readonly localSource: boolean;\n /** Value files written into the local tree. */\n readonly values: number;\n /** Meta files written into the local tree. */\n readonly meta: number;\n /** Distinct parameters the pull touched, at any scope. */\n readonly refs: number;\n /**\n * True when the source declares `readsValues: false`: names and meta came\n * down, values stayed absent — the destination never returns one, and the\n * pull says so rather than dressing emptiness as freshness.\n */\n readonly valuesUnreadable?: boolean;\n}\n\n/**\n * Pull from a value-withholding provider: materialise what the store can\n * honestly give. Listing names is the one read it allows, so each name comes\n * down as a flat parameter (the same `refFromVariable` mapping `import` uses —\n * structure is never guessed back out of a flat namespace), a meta stub marks\n * the parameters the destination holds, and values stay absent for\n * `penv validate` to flag and the user to fill.\n */\nasync function pullProjection(\n project: Project,\n source: ProjectionProvider,\n environment: string,\n): Promise<PullResult> {\n const tree = localTree(project);\n const names = new Set<string>();\n for (const secret of await source.list({ kind: \"repository\" })) {\n names.add(secret.name);\n }\n for (const secret of await source.list({ kind: \"environment\", environment })) {\n names.add(secret.name);\n }\n\n let meta = 0;\n for (const name of [...names].sort()) {\n const ref = refFromVariable(name);\n // A stub only where no meta exists: a pull must never overwrite policy the\n // user already wrote with an empty marker.\n if (tree.readMetaSync(ref) === undefined) {\n tree.writeMetaSync(ref, {});\n meta += 1;\n }\n }\n\n return {\n environment,\n source: source.type,\n localSource: false,\n values: 0,\n meta,\n refs: names.size,\n valuesUnreadable: true,\n };\n}\n\nexport async function runPull(options: PullOptions): Promise<PullResult> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n const source = options.source ?? (await sourceProviderFor(project, environment));\n\n // The local tree already IS the source of truth for an environment with no\n // declared backend: `sourceProviderFor` handed back the filesystem tree, and\n // pulling it onto itself would be a no-op dressed as work. Report the truth.\n if (source.type === LOCAL_TREE_TYPE) {\n return { environment, source: source.type, localSource: true, values: 0, meta: 0, refs: 0 };\n }\n\n // A projection-holding source cannot return values, so its pull is the\n // names-and-meta materialisation — everything the store honestly has.\n if (holdsProjection(source)) {\n return pullProjection(project, source, environment);\n }\n\n const tree = localTree(project);\n const files = await source.list();\n\n let values = 0;\n for (const file of files) {\n const value = await source.read(file);\n // Absent is not written: `list` and `read` can disagree across a concurrent\n // prune, and a missing value is nothing to materialise.\n if (value === undefined) {\n continue;\n }\n // Verbatim — the value is an opaque envelope, sealed or not, and penv does\n // not open it to move it.\n tree.writeSync(file, value);\n values += 1;\n }\n\n // Meta is per-parameter, so it is pulled once per distinct ref rather than once\n // per value file — two scopes of one parameter share the one policy.\n const refs = refsFrom(files);\n let meta = 0;\n for (const ref of refs) {\n const block: Meta | undefined = await source.readMeta(ref);\n if (block === undefined) {\n continue;\n }\n tree.writeMetaSync(ref, block);\n meta += 1;\n }\n\n return { environment, source: source.type, localSource: false, values, meta, refs: refs.length };\n}\n\nexport function renderPull(result: PullResult): string[] {\n if (result.localSource) {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Nothing to pull\",\n subject: `environment ${result.environment} has no separate source of truth`,\n detail: \"its values live in the local .penv tree already\",\n },\n ]);\n }\n\n if (result.valuesUnreadable === true) {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Pulled\",\n subject: `${result.refs} ${result.refs === 1 ? \"parameter name\" : \"parameter names\"}`,\n detail: `from ${result.source} for environment ${result.environment}`,\n },\n {\n glyph: WARN,\n label: \"Values not readable\",\n subject: \"this destination never returns a secret's value\",\n detail:\n \"fill them locally with `penv set` or `penv fill` — `penv validate` names every gap\",\n },\n ]);\n }\n\n return formatRows([\n {\n glyph: CHECK,\n label: \"Pulled\",\n subject: `${result.values} ${result.values === 1 ? \"value\" : \"values\"}`,\n detail: `from the ${result.source} provider for environment ${result.environment}`,\n },\n {\n glyph: CHECK,\n label: \"Parameters\",\n subject: `${result.refs} ${result.refs === 1 ? \"parameter\" : \"parameters\"}, ${result.meta} with meta`,\n detail: \"written into the local .penv tree\",\n },\n ]);\n}\n\nexport const pullCommand = defineCommand({\n meta: {\n name: \"pull\",\n description: \"Materialise the local .penv tree from an environment's source-of-truth provider\",\n },\n args: {\n env: {\n type: \"string\",\n description: \"The environment to pull (or pass it as a bare flag: --production)\",\n },\n },\n run({ args }) {\n return guard(async () => {\n const result = await runPull({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n envFlags: shorthandCandidates(args, [\"env\"]),\n });\n write(renderPull(result));\n });\n },\n});\n","/**\n * `penv validate` — build the target environment's configuration and check it\n * against the one schema.\n *\n * Three failures land here rather than anywhere else, and all three are errors:\n * a reserved token in a name (invariant 11), two parameters mapping to one\n * generated variable (invariant 12 — never last-write-wins), and a config object\n * the schema rejects. A passing run means the schema is internally consistent;\n * it does not mean the schema is correct. That is your review, especially after\n * an inferred import.\n */\n\nimport { resolve as resolvePath } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { ParameterRef, Resolution, ValueFile } from \"@penvhq/core\";\nimport {\n accessPath,\n checkNameCollisions,\n jitiFor,\n NameCollisionError,\n PenvError,\n ReservedTokenError,\n resolveAll,\n SCHEMA_HARVEST_ENV,\n schemaFileOf,\n validateConfig,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { z } from \"zod\";\nimport { shorthandCandidates } from \"../env-flags.js\";\nimport type { Project } from \"../project.js\";\nimport {\n keySourceFor,\n openProject,\n refsFrom,\n schemaShapeFileOf,\n targetEnvironment,\n} from \"../project.js\";\nimport type { DriftReport } from \"../schema.js\";\nimport { computeDrift, EMPTY_DRIFT } from \"../schema.js\";\nimport { out } from \"../style.js\";\nimport { CHECK, CROSS, formatRows, guard, type Row, tip, write } from \"../ui.js\";\n\nexport type ValidateIssueKind = \"config\" | \"reserved\" | \"collision\" | \"schema\" | \"undecryptable\";\n\nexport interface ValidateIssue {\n readonly kind: ValidateIssueKind;\n /** What the line is about: a parameter, a variable, a token, or a file. */\n readonly subject: string;\n readonly message: string;\n readonly remedy?: string;\n}\n\nexport interface ValidateResult {\n readonly ok: boolean;\n readonly environment: string;\n readonly parameters: number;\n readonly issues: readonly ValidateIssue[];\n /**\n * The distance between the schema and the tree, carried for the callers\n * that report it (`watch`). Never folded into `ok` and never rendered by\n * `renderValidate`: drift is a report, and CI's verdict must not move because\n * a parameter the schema tolerates is absent. Empty when the schema did not\n * load, since there is nothing to measure against.\n */\n readonly drift: DriftReport;\n}\n\nexport interface ValidateOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n}\n\nconst SCHEMA_EXPORT = \"schema\";\n\nconst LABELS: Readonly<Record<ValidateIssueKind, string>> = {\n config: \"Config\",\n reserved: \"Reserved token\",\n collision: \"Name collision\",\n schema: \"Invalid parameter\",\n undecryptable: \"Undecryptable value\",\n};\n\nfunction firstLine(text: string): string {\n return text.split(\"\\n\")[0] ?? text;\n}\n\nfunction issueFrom(error: PenvError, fallbackSubject: string): ValidateIssue {\n const base = {\n message: firstLine(error.message),\n ...(error.remedy === undefined ? {} : { remedy: error.remedy }),\n };\n if (error instanceof ReservedTokenError) {\n return { kind: \"reserved\", subject: error.token, ...base };\n }\n if (error instanceof NameCollisionError) {\n return { kind: \"collision\", subject: error.variable, ...base };\n }\n return { kind: \"config\", subject: fallbackSubject, ...base };\n}\n\n/**\n * Places a value at its access path. Values are placed exactly as the provider\n * holds them: coercion is the schema's job, so a value file's contents stay a\n * string here.\n */\nfunction place(root: Record<string, unknown>, path: readonly string[], value: string): void {\n const leaf = path[path.length - 1];\n if (leaf === undefined) {\n return;\n }\n let node = root;\n for (const key of path.slice(0, -1)) {\n const existing = node[key];\n if (typeof existing === \"object\" && existing !== null) {\n node = existing as Record<string, unknown>;\n continue;\n }\n const child: Record<string, unknown> = {};\n node[key] = child;\n node = child;\n }\n node[leaf] = value;\n}\n\nfunction isZodType(value: unknown): value is z.ZodType {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"safeParse\" in value &&\n typeof (value as { safeParse: unknown }).safeParse === \"function\"\n );\n}\n\nexport interface SchemaLoad {\n /** Absent when the module could not be evaluated. `issues` says why. */\n readonly schema?: z.ZodType;\n readonly issues: readonly ValidateIssue[];\n}\n\n/**\n * A penv error raised inside the user's own schema module, identified by its\n * `code` rather than by `instanceof`.\n *\n * The error is thrown by *their* copy of penv, which is a different module realm\n * from this one, so `instanceof` is false across the boundary. `code` is the\n * stable, machine-readable discriminator, and this is exactly what it is for.\n */\nfunction validationIssuesOf(\n cause: unknown,\n schemaPath: string,\n schemaShapeFile: string,\n): readonly ValidateIssue[] | undefined {\n if (typeof cause !== \"object\" || cause === null) {\n return undefined;\n }\n const error = cause as { code?: unknown; issues?: unknown };\n if (error.code !== \"VALIDATION_FAILED\" || !Array.isArray(error.issues)) {\n return undefined;\n }\n return error.issues.map((issue: unknown) => {\n const { parameter, message } = issue as { parameter?: unknown; message?: unknown };\n return {\n kind: \"schema\" as const,\n subject: typeof parameter === \"string\" && parameter !== \"\" ? parameter : schemaPath,\n message: typeof message === \"string\" ? message : String(issue),\n // `schemaPath` is the loader penv evaluated; the shape to adjust lives in\n // `schemaShapeFile`, which is that same file for an old-layout project and\n // `penv.schema.ts` for one on the split.\n remedy: `Fix the value, or adjust the schema in ${schemaShapeFile} if the shape is wrong.`,\n };\n });\n}\n\n/**\n * Serialises the `PENV_ENV` pin in {@link loadSchema}.\n *\n * The environment reaches the user's module through a process global, because\n * that is the only channel their scaffolded `load(schema)` reads. A global\n * pinned across an `await` is not re-entrant: two overlapping loads interleave,\n * the second captures the first's value as `previous`, and restoring it on the\n * way out leaves the global pinned to an environment nobody asked for — every\n * later cycle then silently validates the wrong one. The window is real because\n * `runValidate` is exported and nothing stops a caller validating two\n * environments at once; `watch` is safe only by accident of its single-flight.\n *\n * A queue rather than a fix to the channel: the global *is* the contract with\n * the user's module, so the pin cannot go away. Only one load may hold it.\n */\nlet schemaLoads: Promise<unknown> = Promise.resolve();\n\nfunction exclusively<T>(work: () => Promise<T>): Promise<T> {\n const result = schemaLoads.then(work, work);\n // Never let a rejection break the chain for the next caller.\n schemaLoads = result.then(\n () => undefined,\n () => undefined,\n );\n return result;\n}\n\n/**\n * The one schema, read from wherever `schemaFile` puts it.\n *\n * Only the `schema` export is read, never `env` — a command whose job is to\n * *report* on configuration must not be stopped by it. That is the whole reason\n * the docs tell type-only consumers to import `schema`: a type-only import is\n * erased and never evaluates the module at all.\n *\n * A *runtime* read cannot have that guarantee: evaluating the module runs its\n * top level, and the scaffolded module ends in an eager\n * `export const env = load(schema)`. Against a tree with no values yet that load\n * would throw and take the whole namespace — including the `schema` export —\n * down with it, leaving `fill` blind to the very gap it exists to close. So the\n * schema-harvest flag is pinned alongside `PENV_ENV` for this one import:\n * `load()` defers under it (see `SCHEMA_HARVEST_ENV` in core), the module\n * evaluates, and the schema is always reachable. A module that fails for its own\n * reasons still reports honestly — a penv validation error raised at its top\n * level is unwrapped back into per-parameter issues, and anything else is a\n * config issue naming the file.\n *\n * The pins are process globals, so only one load may hold them at a time — see\n * {@link exclusively}. Loads queue rather than overlap.\n */\nexport function loadSchema(project: Project, environment: string): Promise<SchemaLoad> {\n // Resolved against the project root, not `.penv/`: `schemaFile` is relative to\n // penv.config.ts, so a schema at `src/env.ts` is looked for where it is.\n const schemaPath = schemaFileOf(project.config);\n // The file to name in an \"adjust the schema\" remedy, which is not always the\n // loader `schemaPath`: after the split the shape lives in `penv.schema.ts`.\n const schemaShapeFile = schemaShapeFileOf(project);\n const file = pathToFileURL(resolvePath(project.root, schemaPath)).href;\n return exclusively(() => loadSchemaExclusively(file, schemaPath, schemaShapeFile, environment));\n}\n\n/** {@link loadSchema}'s body, run only while it holds the `PENV_ENV` + harvest pins. */\nasync function loadSchemaExclusively(\n file: string,\n schemaPath: string,\n schemaShapeFile: string,\n environment: string,\n): Promise<SchemaLoad> {\n // Resolved from the user's own file: `zod` and `penv` are their dependencies,\n // not the CLI's. Shared with config loading (jitiFor) so both evaluate user modules\n // identically — including resolving `server-only` to its no-throw variant so a\n // server-guarded `.penv/env.ts` still yields its `schema` export.\n const jiti = jitiFor(file);\n\n // Two pins, one window: `PENV_ENV` so anything the module resolves targets the\n // environment being validated, and the schema-harvest flag so the scaffolded\n // eager `export const env = load(schema)` defers instead of throwing — a tree\n // with no values yet would otherwise take the `schema` export down with it,\n // and `fill` could never see the gap it exists to close.\n const previous = process.env.PENV_ENV;\n const previousHarvest = process.env[SCHEMA_HARVEST_ENV];\n process.env.PENV_ENV = environment;\n process.env[SCHEMA_HARVEST_ENV] = \"1\";\n let loaded: unknown;\n try {\n loaded = await jiti.import(file);\n } catch (cause) {\n const issues = validationIssuesOf(cause, schemaPath, schemaShapeFile);\n if (issues !== undefined) {\n return { issues };\n }\n const detail = cause instanceof Error ? firstLine(cause.message) : String(cause);\n return {\n issues: [\n {\n kind: \"config\",\n subject: schemaPath,\n message: `${schemaPath} could not be loaded: ${detail}`,\n remedy: `Fix the error above. penv reads the \\`${SCHEMA_EXPORT}\\` export of ${schemaPath}, which is yours to edit.`,\n },\n ],\n };\n } finally {\n if (previous === undefined) {\n delete process.env.PENV_ENV;\n } else {\n process.env.PENV_ENV = previous;\n }\n if (previousHarvest === undefined) {\n delete process.env[SCHEMA_HARVEST_ENV];\n } else {\n process.env[SCHEMA_HARVEST_ENV] = previousHarvest;\n }\n }\n\n const exported =\n typeof loaded === \"object\" && loaded !== null\n ? (loaded as Record<string, unknown>)[SCHEMA_EXPORT]\n : undefined;\n\n if (!isZodType(exported)) {\n return {\n issues: [\n {\n kind: \"config\",\n subject: schemaPath,\n message: `${schemaPath} exports no \\`${SCHEMA_EXPORT}\\``,\n remedy: `Export the shape as \\`export const ${SCHEMA_EXPORT} = z.object({ ... })\\`. One schema drives both validation and types.`,\n },\n ],\n };\n }\n return { schema: exported, issues: [] };\n}\n\n/**\n * One environment, checked — and everything the check produced on the way.\n *\n * The verdict is `result` and it is the only verdict penv has. The rest is what\n * `penv run` needs to build a child environment, handed back rather than\n * recomputed: a second walk of the same tree could disagree with the one the\n * verdict was reached on, and then `run` would start a process `validate`\n * refuses.\n */\nexport interface EnvironmentCheck {\n readonly result: ValidateResult;\n /** Absent when the schema module could not be evaluated — `result.issues` says why. */\n readonly schema?: z.ZodType;\n /** Every parameter the tree holds, resolved for this environment. */\n readonly resolutions: readonly Resolution[];\n /** The schema-validated object. Present only when the verdict passed. */\n readonly validated?: unknown;\n}\n\nexport async function runValidate(options: ValidateOptions): Promise<ValidateResult> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n return (await checkEnvironment(project, environment)).result;\n}\n\nexport async function checkEnvironment(\n project: Project,\n environment: string,\n): Promise<EnvironmentCheck> {\n const schemaPath = schemaFileOf(project.config);\n const schemaShapeFile = schemaShapeFileOf(project);\n const issues: ValidateIssue[] = [];\n\n // Invariant 11: a reserved token in a filename is an error, never a silent\n // misparse — so listing the tree is itself a check.\n let files: ValueFile[];\n try {\n files = await project.provider.list();\n } catch (error) {\n if (!(error instanceof PenvError)) {\n throw error;\n }\n return {\n result: {\n ok: false,\n environment,\n parameters: 0,\n issues: [issueFrom(error, schemaPath)],\n drift: EMPTY_DRIFT,\n },\n resolutions: [],\n };\n }\n\n const refs: ParameterRef[] = refsFrom(files);\n\n // The config decides what an environment is, so a broken config is not a\n // smaller problem than a broken value — it is the problem that makes value\n // files unreadable. `validateConfig` collects every one of them, and until it\n // was called from here it collected them for nobody: a config declaring an\n // environment with no provider, or a name no filename can hold, passed\n // `penv validate` with a ✓.\n for (const error of validateConfig(project.config)) {\n issues.push(issueFrom(error, \"penv.config.ts\"));\n }\n\n // Invariant 12: two parameters mapping to one generated variable would lose a\n // value on `penv generate`. It fails here rather than there.\n for (const collision of checkNameCollisions(refs, project.config)) {\n issues.push(issueFrom(collision, collision.variable));\n }\n\n const { schema, issues: schemaIssues } = await loadSchema(project, environment);\n issues.push(...schemaIssues);\n\n let drift: DriftReport = EMPTY_DRIFT;\n let resolutions: readonly Resolution[] = [];\n let validated: unknown;\n\n if (schema !== undefined) {\n resolutions = await resolveAll(\n environment,\n project.provider,\n keySourceFor(project, environment),\n );\n const object: Record<string, unknown> = {};\n // The access paths whose value exists and could not be read. Nothing is\n // placed at them, so the schema will call each one absent — see below.\n const undecryptable = new Set<string>();\n for (const resolution of resolutions) {\n if (resolution.undecryptable !== undefined) {\n undecryptable.add(accessPath(resolution.ref).join(\".\"));\n issues.push({\n kind: \"undecryptable\",\n subject: resolution.parameter,\n message: `${resolution.winner?.location ?? \"the winning value file\"} could not be decrypted: ${resolution.undecryptable.detail}`,\n remedy:\n \"Make the key available, or re-seal the value under a key you hold with `penv encrypt`. \" +\n \"The value is there — penv cannot read it.\",\n });\n continue;\n }\n if (resolution.value !== undefined) {\n place(object, accessPath(resolution.ref), resolution.value);\n }\n }\n // Measured from the same resolutions the verdict below is reached on, so the\n // report can never describe a tree the verdict did not read.\n drift = computeDrift({\n schema,\n resolutions,\n config: project.config,\n environment,\n schemaShapeFile,\n });\n\n const result = schema.safeParse(object);\n if (result.success) {\n validated = result.data;\n } else {\n for (const problem of result.error.issues) {\n const path = problem.path.join(\".\");\n // One absence, one line. The schema is right that nothing is there, but\n // \"expected string, received undefined\" is the wrong answer to why: the\n // value exists and penv could not read it, which is already reported\n // above with the remedy that fixes it. Printing both puts the true line\n // and the misleading one next to each other and lets the reader pick.\n if (undecryptable.has(path)) {\n continue;\n }\n issues.push({\n kind: \"schema\",\n subject: path || schemaPath,\n message: problem.message,\n remedy: `Fix the value, or adjust the schema in ${schemaShapeFile} if the shape is wrong.`,\n });\n }\n }\n }\n\n return {\n result: { ok: issues.length === 0, environment, parameters: refs.length, issues, drift },\n ...(schema === undefined ? {} : { schema }),\n resolutions,\n ...(validated === undefined ? {} : { validated }),\n };\n}\n\nexport function renderValidate(result: ValidateResult): string[] {\n if (result.ok) {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Schema valid\",\n subject: `${result.parameters} parameters for environment ${result.environment}`,\n },\n ]);\n }\n\n // Every issue validate reports is an error — that is the command's contract\n // with CI — so the glyph is the failure cross, never the warning sign.\n const rows: Row[] = result.issues.map((issue) => ({\n glyph: CROSS,\n label: LABELS[issue.kind],\n subject: issue.subject,\n detail: issue.message,\n }));\n\n const lines = formatRows(rows);\n const remedies = [...new Set(result.issues.map((issue) => issue.remedy))].filter(\n (remedy): remedy is string => remedy !== undefined,\n );\n if (remedies.length > 0) {\n lines.push(\"\");\n for (const remedy of remedies) {\n lines.push(tip(remedy));\n }\n }\n const count = result.issues.length;\n lines.push(\n \"\",\n `${out.red(CROSS)} ${count} ${count === 1 ? \"issue\" : \"issues\"} for environment ${result.environment}`,\n );\n return lines;\n}\n\nexport const validateCommand = defineCommand({\n meta: {\n name: \"validate\",\n description: \"Validate configuration against the schema; non-zero on failure\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to validate\" },\n },\n run({ args }) {\n return guard(async () => {\n const result = await runValidate({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n envFlags: shorthandCandidates(args, [\"env\"]),\n });\n write(renderValidate(result));\n if (!result.ok) {\n process.exitCode = 1;\n }\n });\n },\n});\n","/**\n * Reading the user's schema, and the distance between it and the parameter tree.\n *\n * The schema declares what must exist and the tree holds what does. The gap\n * between them is the signal `penv validate` exists to raise; this module makes\n * it legible without closing it. Nothing here writes or deletes a value file —\n * a declaration has no value, so materialising one could only invent it, and an\n * invented value is the silent-value-reaching-runtime failure penv exists to\n * delete. `penv set` stays the only writer.\n *\n * The introspection below lives here, not in `doctor`, because `doctor` and\n * `watch` both report drift and two readers of the same schema would be two\n * answers to one question.\n *\n * Every helper answers \"I cannot tell\" rather than guessing. A report is only\n * worth reading if every line in it is true, so a field this module cannot\n * understand produces no line at all.\n */\n\nimport type { ParameterRef, PenvConfig, Resolution } from \"@penvhq/core\";\nimport {\n accessPath,\n isReservedToken,\n parameterId,\n refFromAccessPath,\n variableName,\n} from \"@penvhq/core\";\nimport type { z } from \"zod\";\n\nfunction defOf(node: unknown): Record<string, unknown> | undefined {\n if (typeof node !== \"object\" || node === null) {\n return undefined;\n }\n const def = (node as { def?: unknown }).def;\n return typeof def === \"object\" && def !== null ? (def as Record<string, unknown>) : undefined;\n}\n\nexport function typeOf(node: unknown): string | undefined {\n const type = defOf(node)?.type;\n return typeof type === \"string\" ? type : undefined;\n}\n\n/** Peels `.optional()`, `.default()`, `.nullable()` — wrappers, not shapes. */\nexport function unwrap(node: unknown): unknown {\n let current = node;\n for (let depth = 0; depth < 8; depth += 1) {\n const inner = defOf(current)?.innerType;\n if (inner === undefined) {\n return current;\n }\n current = inner;\n }\n return current;\n}\n\nexport function shapeOf(node: unknown): Record<string, unknown> | undefined {\n if (typeOf(node) !== \"object\") {\n return undefined;\n }\n const shape = (node as { shape?: unknown }).shape;\n return typeof shape === \"object\" && shape !== null\n ? (shape as Record<string, unknown>)\n : undefined;\n}\n\nexport type Lookup =\n | { readonly kind: \"found\"; readonly node: unknown }\n | { readonly kind: \"absent\" }\n /** The schema is not introspectable this far down. Every check skips it. */\n | { readonly kind: \"unknown\" };\n\nexport function lookup(root: z.ZodType, path: readonly string[]): Lookup {\n let node: unknown = unwrap(root);\n for (const key of path) {\n const shape = shapeOf(node);\n if (shape === undefined) {\n return { kind: \"unknown\" };\n }\n if (!Object.hasOwn(shape, key)) {\n return { kind: \"absent\" };\n }\n node = unwrap(shape[key]);\n }\n return { kind: \"found\", node };\n}\n\n/** The declared minimum length, when the field is a string that declares one. */\nexport function minLengthOf(node: unknown): number | undefined {\n if (typeOf(node) !== \"string\") {\n return undefined;\n }\n const min = (node as { minLength?: unknown }).minLength;\n return typeof min === \"number\" ? min : undefined;\n}\n\n/**\n * Wrappers that make an absent key legal: the schema itself says this parameter\n * need not have a value, so its absence is a declaration, not drift.\n */\nconst ABSENCE_PERMITTED = new Set([\"optional\", \"default\", \"catch\", \"prefault\"]);\n\n/**\n * Wrappers that still demand the key be present. `z.string().nullable()` accepts\n * `null`, which no value file can produce — a missing file is `undefined`, and\n * `undefined` is what the schema rejects. So a nullable field with no value is\n * drift exactly as a bare one is.\n */\nconst ABSENCE_REFUSED = new Set([\"nullable\", \"nonoptional\", \"readonly\"]);\n\n/**\n * Whether the schema permits this field to have no value at all.\n * `undefined` when a wrapper is not recognised — see the module note.\n */\nfunction permitsAbsence(node: unknown): boolean | undefined {\n let current = node;\n for (let depth = 0; depth < 8; depth += 1) {\n const type = typeOf(current);\n if (type !== undefined && ABSENCE_PERMITTED.has(type)) {\n return true;\n }\n const inner = defOf(current)?.innerType;\n if (inner === undefined) {\n // A plain type, wrapped in nothing that excuses absence.\n return type === undefined ? undefined : false;\n }\n if (type === undefined || !ABSENCE_REFUSED.has(type)) {\n // A wrapper this module has never heard of. It may or may not excuse\n // absence, and guessing either way puts an untrue line in the report.\n return undefined;\n }\n current = inner;\n }\n return undefined;\n}\n\n/** One schema key that takes a value: the leaf of a path through the object shapes. */\ninterface Leaf {\n readonly path: readonly string[];\n /** False only when this key, and every namespace above it, must be present. */\n readonly absencePermitted: boolean | undefined;\n /** The schema node as declared, wrappers intact, so a `.default()` stays readable. */\n readonly node: unknown;\n}\n\n/**\n * Every leaf the schema declares. An object is a namespace and is descended\n * into; anything else is a value. A branch whose shape cannot be read is left\n * alone rather than reported as a leaf — an unreadable object is not a string.\n *\n * Absence permission is inherited, because it is inherited in fact: under\n * `z.object({ ... }).optional()` the whole namespace may be absent, so every\n * value beneath it may be too, and a leaf judged on its own wrapper would be\n * reported as drift while the schema is perfectly happy without it.\n */\nfunction leaves(\n node: unknown,\n path: readonly string[],\n inherited: boolean | undefined,\n out: Leaf[],\n): void {\n // `undefined` — a wrapper this module does not understand — is inherited as\n // \"cannot tell\" rather than collapsing to false, so an unreadable namespace\n // never makes its children look required.\n const own = permitsAbsence(node);\n const absencePermitted = inherited === true || own === true ? true : combine(inherited, own);\n\n const shape = shapeOf(unwrap(node));\n if (shape === undefined) {\n if (path.length > 0) {\n out.push({ path, absencePermitted, node });\n }\n return;\n }\n for (const key of Object.keys(shape)) {\n leaves(shape[key], [...path, key], absencePermitted, out);\n }\n}\n\n/** False only when both answers are a definite false; unknown is contagious. */\nfunction combine(left: boolean | undefined, right: boolean | undefined): boolean | undefined {\n return left === undefined || right === undefined ? undefined : false;\n}\n\nexport function declaredLeaves(schema: z.ZodType): Leaf[] {\n const out: Leaf[] = [];\n leaves(schema, [], false, out);\n return out;\n}\n\n/**\n * The declared default of a leaf, rendered for a prompt, when the leaf's wrapper\n * chain carries one this module can read and display. Only a value a reader can\n * take in at a glance is rendered — a string, a number, a boolean — because the\n * display's one job is telling the user what Enter keeps, and `[object Object]`\n * tells them nothing. A factory default is invoked to be shown; one that throws\n * is a default this module cannot know, so no value is claimed (see the module\n * note: no line is better than an untrue line).\n */\nexport function defaultValueOf(node: unknown): string | undefined {\n let current = node;\n for (let depth = 0; depth < 8; depth += 1) {\n const def = defOf(current);\n if (def === undefined) {\n return undefined;\n }\n if (typeOf(current) === \"default\" || typeOf(current) === \"prefault\") {\n let value = def.defaultValue;\n if (typeof value === \"function\") {\n try {\n value = (value as () => unknown)();\n } catch {\n return undefined;\n }\n }\n if (typeof value === \"string\") {\n return JSON.stringify(value);\n }\n if (typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\") {\n return String(value);\n }\n return undefined;\n }\n const inner = def.innerType;\n if (inner === undefined) {\n return undefined;\n }\n current = inner;\n }\n return undefined;\n}\n\n/** A parameter the schema declares that the tree has no value for. */\nexport interface DeclaredDrift {\n /** The parameter id, or the dotted schema path when no filename could reach it. */\n readonly subject: string;\n /** Absent when no filename reaches this key, which is drift `penv set` cannot close. */\n readonly ref?: ParameterRef;\n /** The line to paste: the `penv set` that closes this, or the rename that must precede it. */\n readonly remedy: string;\n readonly detail: string;\n}\n\n/** A parameter the tree holds a value for that the schema does not declare. */\nexport interface UndeclaredDrift {\n readonly ref: ParameterRef;\n /** The generated variable, which is the name the application would have read. */\n readonly variable: string;\n}\n\n/**\n * A parameter the schema declares but does not require — `.optional()`,\n * `.default()`, and their kin — that the tree has no value for. Not drift in the\n * verdict sense: absence here is a state the schema itself blessed, so `doctor`\n * and `watch` say nothing about it. It is measured for `fill`, whose reader is\n * deciding what to write, and for whom \"the schema would take an override here\"\n * is exactly the kind of fact a silent skip would hide.\n */\nexport interface OptionalDrift {\n /** The parameter id, or the dotted schema path when no filename could reach it. */\n readonly subject: string;\n /** Absent when no filename reaches this key — an override `penv set` cannot write. */\n readonly ref?: ParameterRef;\n /** What the schema falls back to, rendered for display, when it declares one this module can read. */\n readonly defaultValue?: string;\n /** The rename that must precede any override, for the key no filename reaches. */\n readonly remedy: string;\n}\n\n/**\n * The distance between the schema and the tree, in both directions. Named\n * `declared`/`undeclared` for the side that has it, not for a verdict: neither\n * direction is by itself an error, and only `validate` decides that. `optional`\n * is the deliberately verdict-free third list — see {@link OptionalDrift}.\n */\nexport interface DriftReport {\n readonly declared: readonly DeclaredDrift[];\n readonly undeclared: readonly UndeclaredDrift[];\n readonly optional: readonly OptionalDrift[];\n}\n\nexport const EMPTY_DRIFT: DriftReport = { declared: [], undeclared: [], optional: [] };\n\nexport interface DriftInput {\n readonly schema: z.ZodType;\n /** Every parameter the tree holds, resolved for `environment`. */\n readonly resolutions: readonly Resolution[];\n readonly config: PenvConfig;\n readonly environment: string;\n /**\n * The file that holds the editable schema shape, named in the remedies below.\n * Cohort-aware (see `schemaShapeFileOf`): `penv.schema.ts` for a project on the\n * split, the self-contained `schemaFile` for one scaffolded before it — a\n * hard-coded path would misdirect whichever cohort it is not from.\n */\n readonly schemaShapeFile: string;\n}\n\n/**\n * A parameter has a value for this environment when *some* file wins, not when\n * penv can read it: an `.enc` winner is a value that exists, and reporting it as\n * missing would send the user to `penv set` to overwrite a secret they have.\n */\nfunction hasValue(resolution: Resolution): boolean {\n return resolution.winner !== undefined;\n}\n\nexport function computeDrift(input: DriftInput): DriftReport {\n const { schema, resolutions, config, environment, schemaShapeFile } = input;\n\n const valued = new Set(resolutions.filter(hasValue).map((resolution) => resolution.parameter));\n\n const declared: DeclaredDrift[] = [];\n const optional: OptionalDrift[] = [];\n for (const leaf of declaredLeaves(schema)) {\n // \"Cannot tell\" produces no line at all — see the module note. Only a leaf\n // the schema definitely requires is drift, and only one it definitely\n // excuses is an optional override; a wrapper this module has never heard of\n // is neither.\n if (leaf.absencePermitted === undefined) {\n continue;\n }\n const path = leaf.path.join(\".\");\n const ref = refFromAccessPath(leaf.path);\n const renameRemedy =\n `Rename the \\`${path}\\` key in ${schemaShapeFile} — a parameter name is lower-case, ` +\n `hyphenated, and never a reserved token, so no value file reaches this key.`;\n // Declared, and permanently unreachable — two ways, one consequence. Either\n // the key is outside the name transform's image (`apiURL`), or it spells a\n // reserved token, which the filename grammar refuses as a parameter name\n // (invariant 11). No value file resolves to this key either way, so the\n // remedy is a rename: a `penv set` line here would be a command that errors.\n // An optional key is not excused from this: the schema's default will serve,\n // but the override the wrapper promises is one no file can ever deliver.\n if (ref === undefined || isReservedToken(ref.name, config)) {\n if (leaf.absencePermitted) {\n optional.push({ subject: path, remedy: renameRemedy });\n } else {\n declared.push({\n subject: path,\n remedy: renameRemedy,\n detail: \"declared, no filename reaches it\",\n });\n }\n continue;\n }\n if (valued.has(parameterId(ref))) {\n continue;\n }\n if (leaf.absencePermitted) {\n const defaultValue = defaultValueOf(leaf.node);\n optional.push({\n subject: parameterId(ref),\n ref,\n ...(defaultValue === undefined ? {} : { defaultValue }),\n remedy: `penv set ${[...ref.namespace, ref.name].join(\"/\")} --env ${environment}`,\n });\n continue;\n }\n declared.push({\n subject: parameterId(ref),\n ref,\n remedy: `penv set ${[...ref.namespace, ref.name].join(\"/\")} --env ${environment}`,\n detail: `declared in ${schemaShapeFile}, no value for ${environment}`,\n });\n }\n\n const undeclared: UndeclaredDrift[] = [];\n for (const resolution of resolutions) {\n if (lookup(schema, accessPath(resolution.ref)).kind !== \"absent\") {\n continue;\n }\n undeclared.push({\n ref: resolution.ref,\n variable: variableName(resolution.ref, config),\n });\n }\n\n return { declared, undeclared, optional };\n}\n","/**\n * `penv cleanup` — the end of a dotenv migration.\n *\n * The cutover keeps one rollback bundle so `penv init undo` can put the original\n * files back. This drops it, and only it: the records, the schema, the config\n * and the loader are the project's, and cleaning up after a migration is not the\n * same as undoing an adoption. It is also what unblocks a second migration,\n * which is refused while a bundle is unresolved.\n */\n\nimport { CUTOVER_PATH, ROLLBACK_DOTENV_PATH } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { CleanupResult } from \"../cutover.js\";\nimport { runCleanup } from \"../cutover.js\";\nimport { out } from \"../style.js\";\nimport { CHECK, formatSteps, guard, type Step, write } from \"../ui.js\";\n\nexport function renderCleanup(result: CleanupResult): string[] {\n if (!result.cleaned) {\n return [`${out.green(CHECK)} No dotenv rollback bundle to clean up.`];\n }\n const steps: Step[] = [\n ...result.removed.map((name) => ({\n glyph: CHECK,\n text: `Removed ${name}`,\n note: `from ${ROLLBACK_DOTENV_PATH}/`,\n })),\n { glyph: CHECK, text: `Removed ${CUTOVER_PATH}` },\n ];\n return [\n ...formatSteps(steps),\n \"\",\n `${out.green(CHECK)} ${out.bold(\"Cleaned up.\")} The migration is over; your records, schema and config are untouched.`,\n ];\n}\n\nexport const cleanupCommand = defineCommand({\n meta: {\n name: \"cleanup\",\n description: \"Drop the dotenv rollback bundle the last `penv init` kept\",\n },\n run() {\n return guard(async () => {\n write(renderCleanup(runCleanup({ cwd: process.cwd() })));\n });\n },\n});\n","/**\n * The recovery state of one dotenv cutover.\n *\n * `penv init` moves a project's active dotenv files into\n * `.penv/state/rollback/dotenv/` and writes `.penv/state/cutover.json` beside\n * it. Together they are a single migration's undo, and deliberately nothing\n * more: this is not local secret versioning, and a second cutover is refused\n * while a bundle is unresolved rather than stacked on top of it.\n *\n * Both are ignored by the committed `state/.gitignore`. The bundle holds the\n * plaintext values that were in the user's `.env` (invariant 20), and the state\n * file names a bundle that exists on exactly one machine — a teammate who cloned\n * it would be told a migration they never ran is waiting to be undone.\n */\n\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport {\n CUTOVER_PATH,\n findConfigFile,\n PenvError,\n ROLLBACK_DOTENV_PATH,\n ROLLBACK_PATH,\n} from \"@penvhq/core\";\n\n/** The only cutover format penv reads. A later one is a penv the project needs. */\nexport const CUTOVER_FORMAT = 1;\n\nexport interface Cutover {\n readonly format: number;\n /** When the files were moved, ISO-8601 UTC. */\n readonly movedAt: string;\n /** The filenames as they were at the project root — what undo restores, exactly. */\n readonly files: readonly string[];\n /** The environments the cutover declared, so a report can name them without the config. */\n readonly environments: readonly string[];\n}\n\nfunction fileFor(root: string, relativePosix: string): string {\n return join(root, ...relativePosix.split(\"/\"));\n}\n\n/** The bundle directory of `root`, absolute. */\nexport function bundleDir(root: string): string {\n return fileFor(root, ROLLBACK_DOTENV_PATH);\n}\n\nexport function cutoverFile(root: string): string {\n return fileFor(root, CUTOVER_PATH);\n}\n\n/**\n * The project `undo` and `cleanup` act on: the directory holding the\n * `penv.config.ts` this one is inside, exactly as every other command finds it.\n *\n * Rooted at the working directory instead, both commands would report nothing to\n * do from any subdirectory of the project they were meant to recover.\n */\nexport function cutoverRoot(cwd: string): string {\n const file = findConfigFile(cwd);\n return file === undefined ? resolve(cwd) : dirname(file);\n}\n\n/** The filenames the rollback bundle holds, sorted. Empty when there is no bundle. */\nexport function bundledFiles(root: string): string[] {\n try {\n return readdirSync(bundleDir(root)).sort();\n } catch {\n return [];\n }\n}\n\n/**\n * True while a cutover is still waiting on `penv init undo` or `penv cleanup`.\n *\n * The bundle counts on its own, not only the record that names it: a bundle with\n * no `cutover.json` is a cutover whose record was deleted by hand, and reading it\n * as \"no cutover\" is how a second migration would move a second set of files over\n * the first one's — into a gitignored directory nothing would ever look in again.\n */\nexport function bundleUnresolved(root: string): boolean {\n return readCutover(root) !== undefined || bundledFiles(root).length > 0;\n}\n\n/**\n * The recorded cutover, or `undefined` when this project has none. A file that\n * exists and cannot be read is an error, never an absence: reading it as \"no\n * cutover\" is how a second migration would move a second set of files over the\n * first one's bundle.\n */\nexport function readCutover(root: string): Cutover | undefined {\n const file = cutoverFile(root);\n if (!existsSync(file)) {\n return undefined;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(readFileSync(file, \"utf8\"));\n } catch {\n throw unreadable(\"it is not JSON\");\n }\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw unreadable(\"it is not an object\");\n }\n const record = parsed as Record<string, unknown>;\n if (record.format !== CUTOVER_FORMAT) {\n throw unreadable(\n `it is format ${JSON.stringify(record.format)}, and penv reads format ${CUTOVER_FORMAT}`,\n );\n }\n const files = record.files;\n if (!Array.isArray(files) || files.some((name) => typeof name !== \"string\")) {\n throw unreadable(\"it lists no filenames\");\n }\n const environments = Array.isArray(record.environments)\n ? record.environments.filter((name): name is string => typeof name === \"string\")\n : [];\n return {\n format: CUTOVER_FORMAT,\n movedAt: typeof record.movedAt === \"string\" ? record.movedAt : \"\",\n files: files as string[],\n environments,\n };\n}\n\nfunction unreadable(what: string): PenvError {\n return new PenvError(\n \"CUTOVER_UNREADABLE\",\n `${CUTOVER_PATH} records the last dotenv cutover, and ${what}`,\n `Run \\`penv cleanup\\` to drop that record and the rollback bundle it names.`,\n );\n}\n\n/** Sorted keys and a trailing newline, so the file is the same bytes on every machine. */\nexport function serializeCutover(cutover: Cutover): string {\n return `${JSON.stringify(\n {\n environments: [...cutover.environments],\n files: [...cutover.files],\n format: cutover.format,\n movedAt: cutover.movedAt,\n },\n null,\n 2,\n )}\\n`;\n}\n\n/**\n * Records the cutover, then moves the selected dotenv files into the bundle.\n *\n * The move is last in a cutover — everything else has already been written and\n * validated — so a failure before it leaves a project whose dotenv files are\n * exactly where they were. Within the move, the record goes first and names every\n * file the move intends: a crash or a file lock between two renames then leaves a\n * bundle penv can still describe, and `penv init undo` puts back what arrived.\n * Written the other way round, the files already moved would be orphaned in a\n * gitignored directory no command knew to look in.\n */\nexport function bundleDotenvFiles(\n root: string,\n files: readonly string[],\n environments: readonly string[],\n now: Date = new Date(),\n): Cutover {\n const cutover: Cutover = {\n format: CUTOVER_FORMAT,\n movedAt: now.toISOString(),\n files: [...files],\n environments: [...environments],\n };\n const file = cutoverFile(root);\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, serializeCutover(cutover), \"utf8\");\n\n const bundle = bundleDir(root);\n mkdirSync(bundle, { recursive: true });\n for (const name of files) {\n renameSync(join(root, name), join(bundle, name));\n }\n return cutover;\n}\n\nexport interface UndoResult {\n readonly root: string;\n /** The files put back, in the order they were moved. */\n readonly restored: readonly string[];\n /** Recorded names already at the project root — what an interrupted undo had reached. */\n readonly alreadyBack: readonly string[];\n /** Recorded names in neither the bundle nor the project root. Nothing penv can restore. */\n readonly missing: readonly string[];\n}\n\n/**\n * Puts every bundled file back under its exact original name, then drops the\n * bundle and the state that named it.\n *\n * Undo is resumable, because the thing it recovers from is an interruption. A\n * name already at the project root and no longer in the bundle is a file an\n * earlier run put back, not a collision — only a name that is in both places at\n * once is, and that is the one case worth refusing over, since restoring would\n * write over whatever came back. A name in neither place is reported rather than\n * refused: the old refusal's remedy was `penv cleanup`, which would have deleted\n * every file that was still recoverable.\n */\nexport function runUndo(options: { readonly cwd: string }): UndoResult {\n const root = cutoverRoot(options.cwd);\n const cutover = readCutover(root);\n const bundled = bundledFiles(root);\n if (cutover === undefined && bundled.length === 0) {\n throw new PenvError(\n \"INIT_UNDO_NOTHING\",\n \"There is no dotenv cutover to undo in this project\",\n \"Run `penv init` to adopt your dotenv files; undo puts them back afterwards.\",\n );\n }\n\n // The record's order, then anything the bundle holds that it does not name.\n // Only a cutover ever writes into the bundle, so a file filed there belongs at\n // the project root under the name it is filed under, recorded or not.\n const recorded = cutover?.files ?? [];\n const names = [...recorded, ...bundled.filter((name) => !recorded.includes(name))];\n\n const bundle = bundleDir(root);\n const held = new Set(bundled);\n const occupied = names.filter((name) => held.has(name) && existsSync(join(root, name)));\n if (occupied.length > 0) {\n const listed = occupied.join(\", \");\n const many = occupied.length > 1;\n throw new PenvError(\n \"INIT_UNDO_OCCUPIED\",\n `${listed} ${many ? \"exist\" : \"exists\"} again, and restoring what penv moved aside would write over ${many ? \"them\" : \"it\"}`,\n `Move ${listed} out of the way, or run \\`penv cleanup\\` to keep ${many ? \"them\" : \"it\"} and drop the bundle. Nothing was restored.`,\n );\n }\n\n const restored: string[] = [];\n const alreadyBack: string[] = [];\n const missing: string[] = [];\n for (const name of names) {\n if (held.has(name)) {\n renameSync(join(bundle, name), join(root, name));\n restored.push(name);\n } else if (existsSync(join(root, name))) {\n alreadyBack.push(name);\n } else {\n missing.push(name);\n }\n }\n removeBundle(root);\n return { root, restored, alreadyBack, missing };\n}\n\nexport interface CleanupResult {\n readonly root: string;\n /** The files the bundle held. Empty when there was nothing to clean up. */\n readonly removed: readonly string[];\n readonly cleaned: boolean;\n}\n\n/**\n * Drops the rollback bundle and the cutover state, and nothing else. The records\n * tree, the schema, the config and the loader are the project's — cleanup is the\n * end of the migration, not the end of the adoption.\n */\nexport function runCleanup(options: { readonly cwd: string }): CleanupResult {\n const root = cutoverRoot(options.cwd);\n const held = bundledFiles(root);\n const cleaned =\n held.length > 0 || existsSync(cutoverFile(root)) || existsSync(fileFor(root, ROLLBACK_PATH));\n removeBundle(root);\n return { root, removed: held, cleaned };\n}\n\nfunction removeBundle(root: string): void {\n rmSync(fileFor(root, ROLLBACK_PATH), { recursive: true, force: true });\n rmSync(cutoverFile(root), { force: true });\n}\n","/**\n * `penv doctor` — one report of everything that has drifted.\n *\n * Each check earns its place by catching something no other command can:\n *\n * - **missing** — meta marks a parameter required for this environment and it\n * resolves to nothing. Requiredness per environment is meta policy, not a\n * second schema (invariant 1).\n * - **declared** — the schema declares a parameter the tree has no value for.\n * The other half of the same distance `unused` measures, and a different\n * question from `missing`: this one is asked of the schema and answered for\n * every declared key, including one with no file anywhere — which no\n * tree-driven check can see, because a parameter with no file has no meta\n * either. It reports, and never writes: see `../schema.ts`.\n * - **weak** — the schema declares a minimum length the value does not meet.\n * - **unused** — a value file exists that the schema has no key for.\n * - **unscoped-fallback** — a real environment resolving via the unscoped\n * default. Invariant 13: fallback is never silent.\n * - **plaintext-secret** — meta declares the parameter a secret and the winning\n * value file carries no `.enc` marker. Invariant 14: encryption is\n * policy-driven, so the filename is checked *against* the policy and is never\n * the authority on what is secret.\n * - **public-secret** — meta declares the parameter a secret and its generated\n * variable carries a prefix the framework inlines into the client bundle.\n * - **rotation-overdue** — meta declares a rotation policy and more than its\n * interval has elapsed since the last completed rotation. A clock no other\n * check keeps: `missing` sees an absent value, never a stale present one.\n * - **rotation-stuck** — a `dual-valid` grace window opened and never closed. The\n * overdue clock's opposite: not a rotation that never ran, but one that started\n * and stalled with two credentials live at once.\n * - **provider-value-drift** — the local tree and the environment's readable\n * source-of-truth provider hold different opaque values for the same address.\n * The one drift a value-withholding destination can never report, because a\n * record-holding provider can be read back and a projection cannot.\n * - **artifact-in-tree** — a sealed deployment artifact is sitting inside the\n * repository. It is an external release input, built per environment and\n * mounted by the container; one in the source tree is a production ciphertext\n * a clone away from git history, and it is not a layout penv supports.\n *\n * Warnings are reported; failures are reported and exit non-zero.\n */\n\nimport type { Dirent } from \"node:fs\";\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport type {\n Meta,\n PenvConfig,\n ProjectionProvider,\n ProjectionSecret,\n Provider,\n Resolution,\n Scope,\n SecretScope,\n ValueFile,\n} from \"@penvhq/core\";\nimport {\n ARTIFACT_BUILD_COMMAND,\n accessPath,\n assertNever,\n effectiveMeta,\n environmentEntry,\n formatValueFile,\n holdsProjection,\n holdsRecords,\n isPublicVariable,\n isRequired,\n isSecret,\n isStuck,\n openValue,\n RECORDS_PATH,\n resolveAll,\n rotationOf,\n tryParseDuration,\n variableName,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { z } from \"zod\";\nimport { shadowedEnvironments, shorthandCandidates } from \"../env-flags.js\";\nimport type { Project } from \"../project.js\";\nimport {\n keySourceFor,\n openProject,\n schemaShapeFileOf,\n sourceProviderFor,\n targetEnvironment,\n} from \"../project.js\";\nimport { LOCAL_TREE_TYPE, localExtensions } from \"../registry.js\";\nimport type { DriftReport } from \"../schema.js\";\nimport { computeDrift, lookup, minLengthOf } from \"../schema.js\";\nimport { out } from \"../style.js\";\nimport {\n CHECK,\n CROSS,\n formatRows,\n guard,\n heading,\n type Row,\n tip,\n UNKNOWN,\n WARN,\n write,\n} from \"../ui.js\";\nimport { LAST_PUSHED_KEY } from \"./push.js\";\nimport { loadSchema } from \"./validate.js\";\n\n/**\n * A check reports one of four verdicts. `unknown` — a check that ran but could\n * not reach a verdict — is never rendered as a pass: \"I looked and found nothing\n * wrong\" and \"I could not look\" are opposite situations with opposite remedies,\n * and a value-withholding destination makes most of what doctor can say the\n * second kind.\n */\nexport type DoctorSeverity = \"pass\" | \"warning\" | \"failure\" | \"unknown\";\n\nexport type DoctorCheck =\n | \"schema\"\n | \"missing\"\n | \"declared\"\n | \"weak\"\n | \"unused\"\n | \"unscoped-fallback\"\n | \"secrecy-undeclared\"\n | \"plaintext-secret\"\n | \"public-secret\"\n | \"encryption\"\n | \"rotation-overdue\"\n | \"rotation-stuck\"\n | \"provider-value-drift\"\n | \"provider\"\n | \"projection-unreachable\"\n | \"projection-name-drift\"\n | \"projection-manual-edit\"\n | \"projection-value-drift\"\n | \"environment-flag-shadow\"\n | \"local-extension\"\n | \"artifact-in-tree\";\n\nexport interface DoctorFinding {\n readonly check: DoctorCheck;\n readonly severity: DoctorSeverity;\n readonly label: string;\n readonly subject?: string;\n readonly detail?: string;\n /** A line the reader can act on — the `penv set` to paste, where there is one. */\n readonly remedy?: string;\n}\n\nexport interface DoctorReport {\n readonly environment: string;\n readonly findings: readonly DoctorFinding[];\n /** False when any finding is a failure. Warnings and unknowns do not fail the run. */\n readonly ok: boolean;\n}\n\nexport interface DoctorOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n /** Injected in tests: the projection-holding destination to check against. Defaults to the one the config declares. */\n readonly projection?: ProjectionProvider;\n /**\n * Injected in tests: the source-of-truth provider to compare the local tree\n * against. Defaults to the one the config declares (`sourceProviderFor`).\n * Mirrors `projection`, for the same reason — the drift checks stay driveable\n * without a live backend.\n */\n readonly source?: Provider;\n /** Injected in tests: the wall-clock reading the rotation clocks are read against. Defaults to now. */\n readonly now?: string;\n /** Injected in tests: how long a `dual-valid` window may stay open before it reads as stuck. Defaults to 24h. */\n readonly stuckThresholdMs?: number;\n}\n\n/**\n * How long a `dual-valid` grace window may stay open before `rotation-stuck`\n * flags it. A day is generous for the overlap most rotations need — long enough\n * that a healthy rotation completing within a deploy or two never trips it, short\n * enough that a window left open for a week is caught while it still matters.\n */\nconst STUCK_THRESHOLD_MS = 86_400_000;\n\ninterface Subject {\n readonly resolution: Resolution;\n readonly meta: Meta | undefined;\n}\n\n/**\n * A check the schema failure above made impossible: `unknown`, not `warning`.\n * penv did not look, so it cannot claim there is nothing to find — and it cannot\n * claim a problem either. The verdict is \"I could not tell\".\n */\nfunction skipped(check: DoctorCheck, label: string): DoctorFinding {\n return {\n check,\n severity: \"unknown\",\n label,\n subject: \"not checked\",\n detail: \"the schema did not load, so this check could not run\",\n };\n}\n\nexport async function runDoctor(options: DoctorOptions): Promise<DoctorReport> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n const findings: DoctorFinding[] = [];\n // The wall clock, read once and passed down — never read inside a check — so the\n // rotation boundaries the roadmap names are testable without mocking time, the\n // same discipline `rotation.ts` and `push.ts` keep.\n const now = new Date(options.now ?? new Date().toISOString());\n const stuckThresholdMs = options.stuckThresholdMs ?? STUCK_THRESHOLD_MS;\n\n // Rule 1 of the environment shorthand flags: a real flag always wins, so an\n // environment sharing a flag's name simply has no shorthand. Said here, once,\n // rather than discovered as a flag that quietly means something else.\n for (const shadowed of shadowedEnvironments(project.config)) {\n findings.push({\n check: \"environment-flag-shadow\",\n severity: \"warning\",\n label: \"Environment shadows a flag\",\n subject: shadowed,\n detail: `\\`--${shadowed}\\` is a flag penv defines, so this environment has no shorthand — \\`--env ${shadowed}\\` always works`,\n });\n }\n\n const { schema, issues } = await loadSchema(project, environment);\n if (schema !== undefined) {\n findings.push({ check: \"schema\", severity: \"pass\", label: \"Schema valid\" });\n } else {\n for (const issue of issues) {\n findings.push({\n check: \"schema\",\n severity: \"failure\",\n label: \"Schema\",\n subject: issue.subject,\n detail: issue.message,\n });\n }\n }\n\n const resolutions = await resolveAll(\n environment,\n project.provider,\n keySourceFor(project, environment),\n );\n const subjects: Subject[] = await Promise.all(\n resolutions.map(async (resolution) => ({\n resolution,\n meta: await project.provider.readMeta(resolution.ref),\n })),\n );\n\n const missing = missingFindings(subjects, environment);\n findings.push(...missing);\n // A check that could not run says so. Printing nothing where a check belongs\n // reads as \"nothing found\", which is the one thing a report must never imply.\n if (schema === undefined) {\n findings.push(\n skipped(\"declared\", \"Schema coverage\"),\n skipped(\"weak\", \"Secret strength\"),\n skipped(\"unused\", \"Value coverage\"),\n );\n } else {\n const schemaShapeFile = schemaShapeFileOf(project);\n const drift = computeDrift({\n schema,\n resolutions: subjects.map(({ resolution }) => resolution),\n config: project.config,\n environment,\n schemaShapeFile,\n });\n findings.push(...declaredFindings(drift, missing, environment, schemaShapeFile));\n findings.push(...weakFindings(subjects, schema));\n findings.push(...unusedFindings(drift));\n }\n findings.push(...fallbackFindings(subjects, environment));\n findings.push(...secrecyFindings(subjects, environment));\n findings.push(...plaintextSecretFindings(subjects, environment));\n findings.push(...publicSecretFindings(subjects, environment, project.config));\n findings.push(...encryptionFindings(subjects, environment));\n // The rotation clocks read the environment's SOURCE provider, not `subjects`,\n // whose meta is the local tree's. `penv rotate` writes `rotatingSince` /\n // `state` / `lastRotated` to the source of truth (a `dual-valid` rotation\n // REQUIRES a retaining backend, so its rotating-state meta is never in the\n // local tree at all) — reading `subjects` here saw stale local meta and never\n // fired for a backend-backed environment.\n const rotation = await rotationSubjects(project, environment, subjects, options.source);\n if (rotation.kind === \"unreachable\") {\n findings.push(rotation.finding);\n } else {\n findings.push(...overdueFindings(rotation.subjects, environment, now));\n findings.push(...stuckFindings(rotation.subjects, environment, now, stuckThresholdMs));\n }\n findings.push(...(await providerDriftFindings(project, environment, options.source)));\n findings.push(...(await projectionFindings(project, environment, options.projection)));\n findings.push(...localExtensionFindings(project));\n findings.push(...artifactFindings(project));\n\n findings.push({\n check: \"provider\",\n severity: \"pass\",\n label: \"Provider\",\n subject: environmentEntry(project.config, environment)?.provider ?? project.provider.type,\n });\n\n return {\n environment,\n findings,\n ok: !findings.some((finding) => finding.severity === \"failure\"),\n };\n}\n\nfunction missingFindings(subjects: readonly Subject[], environment: string): DoctorFinding[] {\n const required = subjects.filter(({ meta }) => isRequired(meta, environment));\n const findings: DoctorFinding[] = required\n .filter(({ resolution }) => resolution.winner === undefined)\n .map(({ resolution }) => ({\n check: \"missing\",\n severity: \"failure\",\n label: \"Missing parameter\",\n subject: resolution.parameter,\n detail: `required for ${environment}, absent`,\n remedy: `penv set ${[...resolution.ref.namespace, resolution.ref.name].join(\"/\")} --env ${environment}`,\n }));\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"missing\",\n severity: \"pass\",\n label: \"Required parameters\",\n subject:\n required.length === 0\n ? `none required for ${environment}`\n : `${required.length} required for ${environment}, all present`,\n },\n ];\n}\n\n/**\n * Schema → tree: declared, with no value for this environment.\n *\n * A warning, not a failure. The schema decides whether an absent value is fatal\n * and `penv validate` is where that verdict is reached; saying it twice, in two\n * voices, would make this report the second authority the design does not have.\n *\n * Parameters the `missing` check already named are dropped rather than repeated:\n * that line is the same absence with meta's stronger verdict on it, and it now\n * carries the same paste line. One absence, one line.\n */\nfunction declaredFindings(\n drift: DriftReport,\n missing: readonly DoctorFinding[],\n environment: string,\n schemaShapeFile: string,\n): DoctorFinding[] {\n const reported = new Set(missing.filter((f) => f.severity !== \"pass\").map((f) => f.subject));\n\n const findings: DoctorFinding[] = drift.declared\n .filter((item) => !reported.has(item.subject))\n .map((item) => ({\n check: \"declared\",\n severity: \"warning\",\n label: \"Declared, no value\",\n subject: item.subject,\n detail: item.detail,\n remedy: item.remedy,\n }));\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"declared\",\n severity: \"pass\",\n label: \"Schema coverage\",\n subject: `every parameter ${schemaShapeFile} requires has a value for ${environment}`,\n },\n ];\n}\n\nfunction weakFindings(subjects: readonly Subject[], schema: z.ZodType): DoctorFinding[] {\n const findings: DoctorFinding[] = [];\n let checked = 0;\n\n for (const { resolution } of subjects) {\n const value = resolution.value;\n // A decrypted secret has a value here, so it is length-checked like any\n // other — an encrypted secret used to be invisible to this check, which made\n // \"the schema declares a minimum\" a promise that quietly excluded exactly the\n // values a minimum is for. Absence is two other checks' business: an\n // undecryptable winner is the encryption check's, and nothing at all is the\n // missing check's.\n if (value === undefined) {\n continue;\n }\n const field = lookup(schema, accessPath(resolution.ref));\n if (field.kind !== \"found\") {\n continue;\n }\n const minimum = minLengthOf(field.node);\n if (minimum === undefined) {\n continue;\n }\n checked += 1;\n if (value.length >= minimum) {\n continue;\n }\n findings.push({\n check: \"weak\",\n severity: \"failure\",\n label: \"Weak secret\",\n subject: resolution.parameter,\n detail: `${value.length} chars, schema requires ≥${minimum}`,\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"weak\",\n severity: \"pass\",\n label: \"Secret strength\",\n subject:\n checked === 0\n ? \"no schema field declares a minimum length\"\n : checked === 1\n ? \"1 value meets the schema minimum\"\n : `${checked} values meet the schema minimum`,\n },\n ];\n}\n\n/** Tree → schema: a value the application has no declared way to read. */\nfunction unusedFindings(drift: DriftReport): DoctorFinding[] {\n const findings: DoctorFinding[] = drift.undeclared.map((item) => ({\n check: \"unused\",\n severity: \"warning\",\n label: \"Unused parameter\",\n subject: item.variable,\n detail: \"present, not in schema\",\n }));\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"unused\",\n severity: \"pass\",\n label: \"Value coverage\",\n subject: \"every value file has a schema key\",\n },\n ];\n}\n\nfunction fallbackFindings(subjects: readonly Subject[], environment: string): DoctorFinding[] {\n const findings: DoctorFinding[] = subjects\n .filter(({ resolution }) => resolution.viaUnscopedFallback)\n .map(({ resolution }) => ({\n check: \"unscoped-fallback\",\n severity: \"warning\",\n label: \"Unscoped fallback in use\",\n subject: resolution.parameter,\n detail: `${environment} resolving to default`,\n }));\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"unscoped-fallback\",\n severity: \"pass\",\n label: \"Scoped resolution\",\n subject: `no parameter falls back to the unscoped default for ${environment}`,\n },\n ];\n}\n\n/**\n * The question the encryption checks are answers to, asked of the meta itself.\n *\n * Encryption is policy-driven (invariant 14): meta declares what must be sealed\n * and the filename is never the authority. So a parameter whose meta says\n * nothing about secrecy is not \"not a secret\" — it is one penv has never been\n * told about, and `plaintext-secret` reporting a clean run over it is a promise\n * made from an empty file. That is what the fourth verdict is for.\n *\n * Summarized once. Twenty-five parameters with no meta is one fact about the\n * project, and twenty-five identical rows would bury every other check.\n */\nfunction secrecyFindings(subjects: readonly Subject[], environment: string): DoctorFinding[] {\n const undeclared = subjects.filter(\n ({ meta }) => effectiveMeta(meta, environment).secret === undefined,\n );\n\n if (undeclared.length === 0) {\n return [\n {\n check: \"secrecy-undeclared\",\n severity: \"pass\",\n label: \"Secrecy policy\",\n subject:\n subjects.length === 0\n ? `no parameter resolves for ${environment}`\n : `every parameter declares whether it is secret for ${environment}`,\n },\n ];\n }\n\n return [\n {\n check: \"secrecy-undeclared\",\n severity: \"unknown\",\n label: \"Secrecy policy\",\n subject: `${undeclared.length} of ${subjects.length} declare neither way for ${environment}`,\n detail: \"penv was never told which of these values must be encrypted\",\n remedy: `declare \\`\"secret\": true\\` or \\`\"secret\": false\\` in a parameter's meta file, ${RECORDS_PATH}/<name>.json`,\n },\n ];\n}\n\nfunction plaintextSecretFindings(\n subjects: readonly Subject[],\n environment: string,\n): DoctorFinding[] {\n const secrets = subjects.filter(({ meta }) => isSecret(meta, environment));\n const findings: DoctorFinding[] = [];\n\n for (const { resolution } of secrets) {\n const winner = resolution.winner;\n // Nothing resolves: that is the missing check's business, not this one's.\n if (winner === undefined || winner.file.encrypted) {\n continue;\n }\n findings.push({\n check: \"plaintext-secret\",\n severity: \"failure\",\n label: \"Plaintext secret\",\n subject: winner.location,\n detail: \"value file is not encrypted\",\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"plaintext-secret\",\n severity: \"pass\",\n label: \"Encryption policy\",\n subject:\n secrets.length === 0\n ? `no parameter is declared secret for ${environment}`\n : `every secret resolving for ${environment} is encrypted`,\n },\n ];\n}\n\n/**\n * The third face of the same policy: is it sealed, can it be opened, and is it\n * public. A secret whose generated variable starts with a framework's public\n * prefix is inlined into the client bundle — `NEXT_PUBLIC_STRIPE_SECRET` reaches\n * every browser that loads the page, permanently, in a bundle nobody can recall.\n *\n * Nothing else in the stack can see this. To the framework the prefix *is* the\n * intent: Next inlines `NEXT_PUBLIC_*` by definition and has no notion that the\n * value is secret. The application's own env module knows the name and not the\n * policy. penv holds both — meta says secret, the name transform says public —\n * so this contradiction is only visible from here.\n *\n * Read of the *generated* variable rather than the parameter name, because a\n * `override` entry is what decides the string the framework sees, and it is the\n * one place the prefix can appear with nothing in the tree hinting at it.\n * Absence of a value is deliberately not a reprieve: the name is already wrong,\n * and the next `penv set` is what ships it.\n */\nfunction publicSecretFindings(\n subjects: readonly Subject[],\n environment: string,\n config: PenvConfig,\n): DoctorFinding[] {\n const prefixes = config.publicPrefixes ?? [];\n // Nothing declared, nothing checkable: a prefix penv was never told about is\n // one it cannot recognise. This is the \"I cannot tell\" answer, and it is not\n // the same as a clean report — saying \"no secret is exposed\" here would be a\n // promise made by a check that never looked at anything.\n if (prefixes.length === 0) {\n return [\n {\n check: \"public-secret\",\n severity: \"unknown\",\n label: \"Browser exposure\",\n subject: \"not checked — penv.config.ts declares no `publicPrefixes`\",\n detail: \"penv cannot tell which variables a framework inlines into the browser\",\n },\n ];\n }\n\n const secrets = subjects.filter(({ meta }) => isSecret(meta, environment));\n const findings: DoctorFinding[] = [];\n\n for (const { resolution } of secrets) {\n const variable = variableName(resolution.ref, config);\n if (!isPublicVariable(variable, config)) {\n continue;\n }\n // Which prefix matched is for the message alone; core stays the authority on\n // whether the variable is public at all.\n const prefix = prefixes.find((candidate) => variable.startsWith(candidate));\n findings.push({\n check: \"public-secret\",\n severity: \"failure\",\n label: \"Secret exposed to the browser\",\n subject: variable,\n detail:\n prefix === undefined\n ? \"meta declares this a secret, and its public prefix makes it public\"\n : `meta declares this a secret, and the \\`${prefix}\\` prefix makes it public`,\n remedy:\n \"rename the parameter so it carries no public prefix, or drop `secret` from its meta if it is not one\",\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"public-secret\",\n severity: \"pass\",\n label: \"Browser exposure\",\n subject: `no secret is exposed to the browser for ${environment}`,\n },\n ];\n}\n\n/**\n * The other half of the encryption policy: `plaintext-secret` catches a secret\n * that should be sealed and is not; this catches a sealed value penv cannot open.\n *\n * A failure, not a warning. An unopenable value is indistinguishable from an\n * absent one to everything downstream — the app gets nothing either way — and\n * the whole point of the `undecryptable` field is that penv can tell the\n * difference even when the application cannot.\n */\nfunction encryptionFindings(subjects: readonly Subject[], environment: string): DoctorFinding[] {\n const sealed = subjects.filter(({ resolution }) => resolution.winner?.file.encrypted === true);\n const findings: DoctorFinding[] = [];\n\n for (const { resolution } of sealed) {\n const failure = resolution.undecryptable;\n if (failure === undefined) {\n continue;\n }\n findings.push({\n check: \"encryption\",\n severity: \"failure\",\n label: \"Undecryptable value\",\n subject: resolution.winner?.location ?? resolution.parameter,\n detail: failure.detail,\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n // Two different quiets, reported differently. \"Nothing is encrypted here\" and\n // \"everything encrypted here opens\" are both passes, and a reader who cannot\n // tell them apart cannot tell whether the check ran.\n return [\n {\n check: \"encryption\",\n severity: \"pass\",\n label: \"Encryption\",\n subject:\n sealed.length === 0\n ? `no encrypted value resolves for ${environment}`\n : `every encrypted value resolving for ${environment} decrypts`,\n },\n ];\n}\n\n/**\n * A report against a projection-holding, value-withholding provider is mostly\n * `unknown` by construction, and honest about it. Three tiers, rendered\n * differently (RFC \"Everything the config names is a provider\"):\n *\n * - **names** are exact, because listing them is the one read the destination\n * allows: declared-but-never-pushed, and present-in-the-destination-but-\n * undeclared — the `declared`/`unused` pair pointed at the store.\n * - **manual edits** are detectable indirectly: GitHub's `updated_at` newer than\n * penv's own last-push time (kept per environment in committed meta) means the\n * secret was touched outside penv. A warning, never a failure — it detects that\n * something was touched, not that the copies differ.\n * - **values** are `unknown`, permanently, because they cannot be read back.\n *\n * The whole report is `unknown` when the destination cannot be reached — the\n * fourth verdict earning its keep against a value-withholding store.\n */\n/** Slack between penv's local push time and the destination's server `updated_at` before a difference reads as a hand-edit. */\nconst EDIT_SKEW_MS = 120_000;\n\nfunction errorDetail(error: unknown): string {\n if (error instanceof Error) {\n return error.message.split(\"\\n\")[0] ?? error.message;\n }\n return String(error);\n}\n\nfunction scopeLabel(scope: SecretScope): string {\n return scope.kind === \"repository\"\n ? \"repository secrets\"\n : `environment secrets for ${scope.environment}`;\n}\n\ninterface Expected {\n readonly ref: Resolution[\"ref\"];\n readonly variable: string;\n readonly scope: SecretScope;\n}\n\nasync function projectionFindings(\n project: Project,\n environment: string,\n override: ProjectionProvider | undefined,\n): Promise<DoctorFinding[]> {\n let projection: ProjectionProvider;\n if (override !== undefined) {\n projection = override;\n } else {\n const declared = environmentEntry(project.config, environment);\n if (declared === undefined || declared.provider === LOCAL_TREE_TYPE) {\n return [];\n }\n let source: Awaited<ReturnType<typeof sourceProviderFor>>;\n try {\n source = await sourceProviderFor(project, environment);\n } catch (error) {\n return [\n {\n check: \"projection-unreachable\",\n severity: \"unknown\",\n label: \"Destination\",\n subject: `could not build the ${declared.provider} provider for ${environment}`,\n detail: errorDetail(error),\n },\n ];\n }\n // A record-holding source is checked value by value in\n // `providerDriftFindings`; these tiers exist only for the store that\n // withholds its values.\n if (!holdsProjection(source)) {\n return [];\n }\n projection = source;\n }\n\n try {\n await projection.verify();\n } catch (error) {\n return [\n {\n check: \"projection-unreachable\",\n severity: \"unknown\",\n label: \"Destination\",\n subject: `could not reach the ${projection.type} destination for ${environment}`,\n detail: errorDetail(error),\n },\n ];\n }\n\n let repoSecrets: ProjectionSecret[];\n let envSecrets: ProjectionSecret[];\n try {\n repoSecrets = await projection.list({ kind: \"repository\" });\n envSecrets = await projection.list({ kind: \"environment\", environment });\n } catch (error) {\n return [\n {\n check: \"projection-unreachable\",\n severity: \"unknown\",\n label: \"Destination\",\n subject: `could not list secrets in the ${projection.type} destination for ${environment}`,\n detail: errorDetail(error),\n },\n ];\n }\n\n // The push view: what a push would place, `.local` dropped, so doctor compares\n // the same set a push would send.\n const resolutions = await resolveAll(\n environment,\n project.provider,\n keySourceFor(project, environment),\n true,\n );\n const expected: Expected[] = [];\n for (const resolution of resolutions) {\n const winner = resolution.winner;\n if (winner === undefined) {\n continue;\n }\n expected.push({\n ref: resolution.ref,\n variable: variableName(resolution.ref, project.config),\n scope:\n winner.file.scope.kind === \"unscoped\"\n ? { kind: \"repository\" }\n : { kind: \"environment\", environment },\n });\n }\n\n // GitHub secret names are case-insensitive, and the pre-flight already refused\n // any case collision, so comparing by uppercase is exact and safe.\n const upper = (name: string): string => name.toUpperCase();\n const repoByName = new Map(repoSecrets.map((secret) => [upper(secret.name), secret]));\n const envByName = new Map(envSecrets.map((secret) => [upper(secret.name), secret]));\n const destOf = (scope: SecretScope): Map<string, ProjectionSecret> =>\n scope.kind === \"repository\" ? repoByName : envByName;\n\n const nameDrift: DoctorFinding[] = [];\n const expectedEnv = new Set<string>();\n // Every variable this environment maps, at any scope. A repository secret is\n // shared across all environments, so it is \"declared\" as long as *some*\n // parameter produces its name — even one this environment resolves to an\n // environment-scoped override. Judging a repository secret against only this\n // environment's unscoped winners would flag another environment's default.\n const allVariables = new Set<string>();\n for (const item of expected) {\n const key = upper(item.variable);\n allVariables.add(key);\n if (item.scope.kind === \"environment\") {\n expectedEnv.add(key);\n }\n if (!destOf(item.scope).has(key)) {\n nameDrift.push({\n check: \"projection-name-drift\",\n severity: \"warning\",\n label: \"Declared, not pushed\",\n subject: item.variable,\n detail: `resolves for ${environment} but is absent from the ${scopeLabel(item.scope)}`,\n remedy: `penv push --env ${environment}`,\n });\n }\n }\n for (const secret of repoSecrets) {\n if (!allVariables.has(upper(secret.name))) {\n nameDrift.push({\n check: \"projection-name-drift\",\n severity: \"warning\",\n label: \"In destination, not declared\",\n subject: secret.name,\n detail: `a repository secret with no parameter penv pushes for ${environment}`,\n });\n }\n }\n for (const secret of envSecrets) {\n if (!expectedEnv.has(upper(secret.name))) {\n nameDrift.push({\n check: \"projection-name-drift\",\n severity: \"warning\",\n label: \"In destination, not declared\",\n subject: secret.name,\n detail: `an environment secret with no parameter resolving for ${environment}`,\n });\n }\n }\n\n const manualEdits: DoctorFinding[] = [];\n for (const item of expected) {\n const secret = destOf(item.scope).get(upper(item.variable));\n if (secret === undefined) {\n continue;\n }\n const pushed = effectiveMeta(await project.provider.readMeta(item.ref), environment)[\n LAST_PUSHED_KEY\n ];\n if (typeof pushed !== \"string\") {\n continue;\n }\n const destTime = Date.parse(secret.updatedAt);\n const pushTime = Date.parse(pushed);\n // The tolerance absorbs the skew between penv's local clock and GitHub's\n // server clock (and GitHub's whole-second truncation of `updated_at`), so a\n // clean push does not read as an edit. A genuine UI edit lands minutes to\n // days later, well outside it — this is a sensitive detector, not a proof.\n if (Number.isNaN(destTime) || Number.isNaN(pushTime) || destTime <= pushTime + EDIT_SKEW_MS) {\n continue;\n }\n manualEdits.push({\n check: \"projection-manual-edit\",\n severity: \"warning\",\n label: \"Edited outside penv\",\n subject: item.variable,\n detail: `changed in the destination at ${secret.updatedAt}, after penv last pushed it`,\n });\n }\n\n const findings: DoctorFinding[] = [];\n findings.push(\n ...(nameDrift.length > 0\n ? nameDrift\n : [\n {\n check: \"projection-name-drift\" as const,\n severity: \"pass\" as const,\n label: \"Destination names\",\n subject: `every parameter resolving for ${environment} is present, and nothing undeclared is`,\n },\n ]),\n );\n findings.push(\n ...(manualEdits.length > 0\n ? manualEdits\n : [\n {\n check: \"projection-manual-edit\" as const,\n severity: \"pass\" as const,\n label: \"Destination hand-edits\",\n subject: `no secret has changed outside penv since its last push for ${environment}`,\n },\n ]),\n );\n findings.push({\n check: \"projection-value-drift\",\n severity: \"unknown\",\n label: \"Destination values\",\n subject: \"cannot be read back from a write-only destination\",\n detail: \"value drift between the tree and the destination is unknowable by design\",\n });\n return findings;\n}\n\n/** What a scan never descends into: git's own store, and packages penv did not write. */\nconst UNSCANNED_DIRS: ReadonlySet<string> = new Set([\".git\", \"node_modules\"]);\n\n/** Above this, a file is not the canonical JSON `penv artifact build` writes. */\nconst ARTIFACT_SCAN_LIMIT = 1_048_576;\n\n/**\n * Whether a file is a sealed deployment artifact, decided on its keys.\n *\n * Deliberately looser than {@link parseArtifact}: an artifact whose digest no\n * longer matches, or one a newer penv wrote, is still an artifact sitting in the\n * repository, and the whole point of the finding is that it is *there*. The\n * cheap substring gate runs first so a repository's ordinary JSON is never\n * parsed.\n */\nfunction looksLikeArtifact(text: string): boolean {\n if (!text.includes('\"schemaDigest\"')) {\n return false;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return false;\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return false;\n }\n const keys = [\"format\", \"environment\", \"engineVersion\", \"schemaDigest\", \"keySource\", \"values\"];\n return keys.every((key) => key in parsed);\n}\n\n/** Every `.json` file under `directory` a scan is willing to open. */\nfunction scannableFiles(directory: string, out: string[]): void {\n let entries: Dirent[];\n try {\n entries = readdirSync(directory, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const path = join(directory, entry.name);\n if (entry.isDirectory()) {\n if (!UNSCANNED_DIRS.has(entry.name)) {\n scannableFiles(path, out);\n }\n continue;\n }\n if (entry.isFile() && entry.name.endsWith(\".json\")) {\n out.push(path);\n }\n }\n}\n\n/**\n * A deployment artifact inside the repository.\n *\n * The artifact is the one penv file that is deliberately *not* part of the\n * project: it is built per release, holds one environment's sealed values, and\n * is mounted by the container that runs from it. One in the source tree is a\n * production ciphertext one `git add` away from being permanent — and `dist/` is\n * not an exception, because putting an artifact there does not make any platform\n * load it.\n *\n * The scan is bounded by what the writer produces: canonical JSON, so `.json`\n * files only, under a megabyte, outside `.git` and `node_modules`.\n */\n/**\n * The extensions this project develops rather than pins.\n *\n * Nothing is wrong with the arrangement — a repository that writes a provider\n * has to be able to use it — but nothing pins the bytes either, so penv cannot\n * say the adapter here is the adapter anyone else gets. That is the `?` verdict:\n * reported so the state is visible in the same place every other decision is,\n * rather than living only in whoever's `node_modules` happens to hold it.\n */\nfunction localExtensionFindings(project: Project): DoctorFinding[] {\n const names = localExtensions(project.root);\n if (names.length === 0) {\n return [\n {\n check: \"local-extension\",\n severity: \"pass\",\n label: \"Extensions\",\n subject: \"every extension this project names is pinned\",\n },\n ];\n }\n return [\n {\n check: \"local-extension\",\n severity: \"unknown\",\n label: \"Extensions\",\n subject: names.join(\", \"),\n detail: \"resolved from this project's node_modules — no release, no pinned bytes\",\n remedy: `publish it and run \\`penv add ${names[0]}\\` when this stops being a development path`,\n },\n ];\n}\n\nfunction artifactFindings(project: Project): DoctorFinding[] {\n const files: string[] = [];\n scannableFiles(project.root, files);\n\n const findings: DoctorFinding[] = [];\n for (const file of files) {\n let text: string;\n try {\n if (statSync(file).size > ARTIFACT_SCAN_LIMIT) {\n continue;\n }\n text = readFileSync(file, \"utf8\");\n } catch {\n continue;\n }\n if (!looksLikeArtifact(text)) {\n continue;\n }\n findings.push({\n check: \"artifact-in-tree\",\n severity: \"failure\",\n label: \"Artifact in the repository\",\n subject: relative(project.root, file).split(\"\\\\\").join(\"/\"),\n detail: \"a sealed deployment artifact is an external release input, not part of the source\",\n remedy:\n \"Delete it and build the artifact outside the repository with \" +\n `\\`${ARTIFACT_BUILD_COMMAND}\\`, then mount it at PENV_SNAPSHOT.`,\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"artifact-in-tree\",\n severity: \"pass\",\n label: \"Deployment artifacts\",\n subject: \"none inside the repository\",\n },\n ];\n}\n\n/** A rough, human-facing span — the largest whole unit that fits. Never precise, and never claims to be. */\nfunction humanizeMs(ms: number): string {\n const abs = Math.max(0, ms);\n const day = 86_400_000;\n const hour = 3_600_000;\n const minute = 60_000;\n const round = (value: number, unit: string): string => {\n const n = Math.round(value);\n return `${n} ${unit}${n === 1 ? \"\" : \"s\"}`;\n };\n if (abs >= day) return round(abs / day, \"day\");\n if (abs >= hour) return round(abs / hour, \"hour\");\n if (abs >= minute) return round(abs / minute, \"minute\");\n return round(abs / 1000, \"second\");\n}\n\n/** The `<namespace>/<name>` path a `penv rotate` remedy pastes. */\nfunction refPathOf(ref: Resolution[\"ref\"]): string {\n return [...ref.namespace, ref.name].join(\"/\");\n}\n\n/**\n * The rotation clocks read the environment's source of truth, so this reads each\n * parameter's meta from the SOURCE provider rather than the local tree.\n *\n * `penv rotate` writes rotation state (`rotatingSince` / `state` / `lastRotated`)\n * to `sourceProviderFor(environment)` — a backend for a vault/mock env — and a\n * `dual-valid` rotation cannot run without one, so a backend-backed env's\n * rotating-state meta is NEVER in the local `.penv` tree. Reading `subjects`\n * (whose meta is the local tree's) left the overdue/stuck checks reading stale\n * local meta that never fired.\n *\n * When the source IS the local tree — the env declares no backend, or declares\n * `filesystem` — the two coincide, so the metas already read for `subjects` are\n * reused rather than round-tripping the identical files a second time. A backend\n * is read once, wrapped in try/catch: an unreachable source yields a single\n * `unknown` rotation finding, mirroring `projectionFindings`' tiering, because \"the\n * clock says overdue\" and \"penv could not read the clock\" are opposite verdicts.\n */\ntype RotationSubjects =\n | { readonly kind: \"read\"; readonly subjects: readonly Subject[] }\n | { readonly kind: \"unreachable\"; readonly finding: DoctorFinding };\n\nasync function rotationSubjects(\n project: Project,\n environment: string,\n local: readonly Subject[],\n override: Provider | undefined,\n): Promise<RotationSubjects> {\n const providerConfig = environmentEntry(project.config, environment);\n // No override and a local-tree source: the meta is the same meta `subjects`\n // already hold, so reuse it and make no extra round-trips.\n if (\n override === undefined &&\n (providerConfig === undefined || providerConfig.provider === LOCAL_TREE_TYPE)\n ) {\n return { kind: \"read\", subjects: local };\n }\n\n const source = override ?? (await sourceProviderFor(project, environment));\n // A projection-holding destination stores no meta at all, so the local tree\n // stays the keeper of this environment's rotation clocks.\n if (!holdsRecords(source)) {\n return { kind: \"read\", subjects: local };\n }\n try {\n const subjects: Subject[] = await Promise.all(\n local.map(async ({ resolution }) => ({\n resolution,\n meta: await source.readMeta(resolution.ref),\n })),\n );\n return { kind: \"read\", subjects };\n } catch (error) {\n return {\n kind: \"unreachable\",\n finding: {\n check: \"rotation-overdue\",\n severity: \"unknown\",\n label: \"Rotation\",\n subject: `could not reach the ${providerConfig?.provider ?? source.type} source of truth for ${environment}`,\n detail: errorDetail(error),\n },\n };\n }\n}\n\n/**\n * A staleness clock no other check keeps: `missing` reports a value that is\n * absent, and this reports one that is present and too old. The two are opposite\n * failures — a value nobody set, and a value nobody has changed in longer than\n * its own policy allows — and only meta's `rotationPolicy` plus `lastRotated`\n * make the second visible at all.\n *\n * The policy is parsed ONCE, here, inside `tryParseDuration`. The old code called\n * `isOverdue` (which parses via the throwing `parseDuration`) in this unguarded\n * loop, then parsed a SECOND time for the `overdueBy` text — so a single policy\n * `parseDuration` rejects (`1h30m`, `3 months`) threw straight out and aborted\n * the entire doctor run through `guard()`, blinding every other check on one bad\n * meta field. Now an unparseable policy is a warning on that one parameter and\n * the sweep continues, and the single parsed interval feeds both the overdue\n * decision and the message. A parameter with no policy, or one that has never\n * rotated, is not on a clock and is silently not overdue.\n */\nfunction overdueFindings(\n subjects: readonly Subject[],\n environment: string,\n now: Date,\n): DoctorFinding[] {\n const findings: DoctorFinding[] = [];\n for (const { resolution, meta } of subjects) {\n const { policy, lastRotated } = rotationOf(meta, environment);\n // Not on a clock: no interval declared, or never rotated. Not late.\n if (policy === undefined || lastRotated === null) {\n continue;\n }\n // Parse once, non-throwing. A policy penv cannot read used to throw here and\n // abort the whole run; now it is this parameter's own warning and nothing\n // else is lost.\n const interval = tryParseDuration(policy);\n if (interval === undefined) {\n findings.push({\n check: \"rotation-overdue\",\n severity: \"warning\",\n label: \"Rotation policy invalid\",\n subject: resolution.parameter,\n detail: `rotationPolicy \\`${policy}\\` is not a duration penv can parse (e.g. \\`90d\\`, \\`24h\\`)`,\n });\n continue;\n }\n const last = Date.parse(lastRotated);\n if (Number.isNaN(last)) {\n continue;\n }\n // The same boundary `isOverdue` keeps: exactly at the interval is not yet\n // overdue, strictly past it is. Reusing `interval` is what kills the second\n // parse the old `overdueBy` line made.\n const overdueBy = now.getTime() - last - interval;\n if (overdueBy <= 0) {\n continue;\n }\n findings.push({\n check: \"rotation-overdue\",\n severity: \"warning\",\n label: \"Rotation overdue\",\n subject: resolution.parameter,\n detail: `overdue by ~${humanizeMs(overdueBy)}, policy ${policy}`,\n remedy: `penv rotate ${refPathOf(resolution.ref)} --env ${environment}`,\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"rotation-overdue\",\n severity: \"pass\",\n label: \"Rotation freshness\",\n subject: `no parameter is past its rotation policy for ${environment}`,\n },\n ];\n}\n\n/**\n * The overdue clock's opposite: not a rotation that never ran, but one that\n * started and stalled. A `dual-valid` window is meant to open, let readers move\n * over, and close; a `rotatingSince` older than the threshold is a window that\n * opened and never did.\n *\n * Gated to `dual-valid` entirely — `isStuck` refuses every other mechanism, and\n * that refusal is the point. An `atomic-cutover` parameter overlaps only at the\n * infra layer and holds no penv-layer grace window, so a long-lived\n * `rotatingSince` on one is not stuck and must never be flagged; this check keeps\n * that promise by asking `isStuck` and never re-deriving the mechanism itself.\n */\nfunction stuckFindings(\n subjects: readonly Subject[],\n environment: string,\n now: Date,\n stuckThresholdMs: number,\n): DoctorFinding[] {\n const findings: DoctorFinding[] = [];\n for (const { resolution, meta } of subjects) {\n if (!isStuck(meta, environment, now, stuckThresholdMs)) {\n continue;\n }\n const { rotatingSince } = rotationOf(meta, environment);\n // isStuck was true, so the window is open with a parseable clock; the guard is\n // for the types, not a reachable path.\n if (rotatingSince === null) {\n continue;\n }\n const openFor = now.getTime() - Date.parse(rotatingSince);\n findings.push({\n check: \"rotation-stuck\",\n severity: \"warning\",\n label: \"Rotation stuck\",\n subject: resolution.parameter,\n detail: `dual-valid window open ~${humanizeMs(openFor)}, past the ${humanizeMs(stuckThresholdMs)} grace window`,\n remedy: `penv rotate ${refPathOf(resolution.ref)} --complete --env ${environment}`,\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"rotation-stuck\",\n severity: \"pass\",\n label: \"Rotation progress\",\n subject: `no dual-valid rotation has stayed open past its grace window for ${environment}`,\n },\n ];\n}\n\n/** One value file the drift check has read, kept with its raw stored string so a sealed local value can still be opened. */\ninterface DriftEntry {\n readonly file: ValueFile;\n readonly stored: string;\n}\n\n/**\n * The LOGICAL identity of a value file — namespace, name, and scope — with the\n * `.enc` marker deliberately dropped.\n *\n * `formatValueFile` encodes `encrypted`, so keying by it split an encrypted-local\n * value from its plaintext-source twin: the same logical parameter at the same\n * scope read as two one-sided addresses, a perpetual false drift the byte compare\n * never got to run. Encryption is a property of the local envelope, not of the\n * address, so it must not be part of the key two stores are matched on. Mirrors\n * the mock provider's `valueKey`, minus exactly that `encrypted` field.\n */\nfunction driftKey(file: ValueFile): string {\n return [file.namespace.join(\"/\"), file.name, scopeKey(file.scope)].join(\" \");\n}\n\nfunction scopeKey(scope: Scope): string {\n switch (scope.kind) {\n case \"unscoped\":\n return \"unscoped\";\n case \"environment\":\n return `environment:${scope.environment}`;\n case \"local\":\n return \"local\";\n case \"environment-local\":\n return `environment-local:${scope.environment}`;\n default:\n return assertNever(scope, \"scope\");\n }\n}\n\n/**\n * The value files that have a source-of-truth twin to drift against: the pushable\n * set for this environment — the unscoped default and this environment's own\n * scope, and nothing else.\n *\n * The old check compared the ENTIRE local tree (`project.provider.list()` is\n * every environment's files) against one env's source, so `doctor --env\n * production` flooded \"Only in the local tree\" for every development/staging\n * value. Both `.local` scopes are personal and never reach a backend; every other\n * environment's scoped file is that environment's business, not this one's. The\n * same filter is applied to both sides.\n */\nfunction relevantToEnvironment(file: ValueFile, environment: string): boolean {\n const scope = file.scope;\n if (scope.kind === \"unscoped\") return true;\n if (scope.kind === \"environment\") return scope.environment === environment;\n // Both `.local` scopes, and every other environment's scope: not pushed here.\n return false;\n}\n\n/**\n * Reads a provider's value files relevant to this environment into a logical\n * address → entry map, the raw stored strings kept unopened.\n *\n * Values are read in `list` order and mapped afterwards, so a same-address\n * collision (a plaintext and a sealed file at one scope) resolves the same way on\n * every machine rather than by Promise race. An address that `list` names but\n * `read` returns absent — a concurrent prune — is dropped, nothing to compare.\n */\nasync function readRelevant(\n provider: Provider,\n environment: string,\n): Promise<Map<string, DriftEntry>> {\n const files = (await provider.list()).filter((file) => relevantToEnvironment(file, environment));\n const stored = await Promise.all(files.map((file) => provider.read(file)));\n const entries = new Map<string, DriftEntry>();\n for (const [index, file] of files.entries()) {\n const value = stored[index];\n if (value !== undefined) {\n entries.set(driftKey(file), { file, stored: value });\n }\n }\n return entries;\n}\n\n/**\n * The one drift a value-withholding destination can never report. `projection-value-drift` is permanently\n * `unknown` because a write-only destination cannot be read back; a provider is\n * the system of record precisely because it can, so here penv actually looks —\n * comparing PLAINTEXT, value by value.\n *\n * Custody model: the source of truth holds verbatim plaintext (the way `pull` and\n * `rotate` move it there), while the local tree may hold the value sealed. So a\n * sealed local value is opened before the compare — an encrypted-local vs\n * plaintext-source pair carrying the same secret is IN SYNC, not drift. A sealed\n * value that cannot be opened (the key is gone) is `unknown` for that parameter,\n * never a false disagreement: penv could not read one side, so it cannot say the\n * two agree or differ.\n *\n * When the environment keeps its values in the local tree there is no second\n * system of record, so this is a plain `pass` — \"not applicable\", never\n * `unknown`: penv could look and there was one copy by design. An unreachable\n * source *is* `unknown`, mirroring `projectionFindings`' try/catch tiering: a differing\n * value and an unreachable store are opposite verdicts with opposite remedies.\n */\nasync function providerDriftFindings(\n project: Project,\n environment: string,\n override: Provider | undefined,\n): Promise<DoctorFinding[]> {\n const providerConfig = environmentEntry(project.config, environment);\n if (providerConfig === undefined || providerConfig.provider === LOCAL_TREE_TYPE) {\n return [\n {\n check: \"provider-value-drift\",\n severity: \"pass\",\n label: \"Provider values\",\n subject: `${environment} keeps its values in the local .penv tree, so there is no other source of truth to compare against`,\n },\n ];\n }\n\n const source = override ?? (await sourceProviderFor(project, environment));\n // A value-withholding destination has nothing to compare value by value; its\n // tiers — exact names, unknown values, indirect hand-edits — are\n // `projectionFindings`' and are reported there.\n if (!holdsRecords(source)) {\n return [];\n }\n\n let local: Map<string, DriftEntry>;\n let remote: Map<string, DriftEntry>;\n try {\n local = await readRelevant(project.provider, environment);\n remote = await readRelevant(source, environment);\n } catch (error) {\n return [\n {\n check: \"provider-value-drift\",\n severity: \"unknown\",\n label: \"Provider values\",\n subject: `could not reach the ${providerConfig.provider} provider for ${environment}`,\n detail: errorDetail(error),\n },\n ];\n }\n\n const keys = keySourceFor(project, environment);\n const findings: DoctorFinding[] = [];\n // Sorted so the report is identical on every machine, the same rule `refsFrom` keeps.\n const addresses = [...new Set([...local.keys(), ...remote.keys()])].sort();\n for (const address of addresses) {\n const here = local.get(address);\n const there = remote.get(address);\n if (here !== undefined && there !== undefined) {\n // Open the local value if it is sealed; the source is verbatim plaintext.\n // `openValue` returns a plaintext file unchanged, so this is unconditional.\n const opened = openValue(here.file, here.stored, keys);\n if (opened.kind !== \"plaintext\") {\n // A sealed value penv cannot open: the key is gone. Not drift — penv\n // could not read this side, so it cannot claim the two stores agree or\n // differ. The opposite of a false failure.\n findings.push({\n check: \"provider-value-drift\",\n severity: \"unknown\",\n label: \"Provider value unreadable\",\n subject: formatValueFile(here.file),\n detail: `the local value is sealed and did not open, so it cannot be compared against the ${providerConfig.provider} source of truth`,\n });\n continue;\n }\n // A plaintext comparison. Drift in the system of record is serious: the\n // tree and the backend claim different truths for one address, and\n // something deploys the wrong one.\n if (opened.value !== there.stored) {\n findings.push({\n check: \"provider-value-drift\",\n severity: \"failure\",\n label: \"Provider value drift\",\n subject: formatValueFile(here.file),\n detail: `the local tree and the ${providerConfig.provider} source of truth hold different values`,\n });\n }\n continue;\n }\n const present = here ?? there;\n // `present` is defined: the address is in the union, so at least one side has it.\n if (present === undefined) {\n continue;\n }\n findings.push({\n check: \"provider-value-drift\",\n severity: \"warning\",\n label: here !== undefined ? \"Only in the local tree\" : \"Only in the source\",\n subject: formatValueFile(present.file),\n detail:\n here !== undefined\n ? `present locally, absent from the ${providerConfig.provider} source of truth`\n : `present in the ${providerConfig.provider} source of truth, absent from the local tree`,\n });\n }\n\n if (findings.length > 0) {\n return findings;\n }\n return [\n {\n check: \"provider-value-drift\",\n severity: \"pass\",\n label: \"Provider values\",\n subject: `every value matches the ${providerConfig.provider} source of truth for ${environment}`,\n },\n ];\n}\n\nconst GLYPHS: Readonly<Record<DoctorSeverity, string>> = {\n pass: CHECK,\n warning: WARN,\n failure: CROSS,\n unknown: UNKNOWN,\n};\n\n/** The one-line verdict under the table: every severity counted, colored to match its glyph. */\nfunction summarize(report: DoctorReport): string {\n const counts = { pass: 0, warning: 0, failure: 0, unknown: 0 };\n for (const finding of report.findings) {\n counts[finding.severity] += 1;\n }\n const parts = [out.green(`${counts.pass} passed`)];\n if (counts.warning > 0) {\n parts.push(out.yellow(`${counts.warning} ${counts.warning === 1 ? \"warning\" : \"warnings\"}`));\n }\n if (counts.failure > 0) {\n parts.push(out.red(`${counts.failure} ${counts.failure === 1 ? \"failure\" : \"failures\"}`));\n }\n if (counts.unknown > 0) {\n parts.push(out.dim(`${counts.unknown} could not be checked`));\n }\n const verdict = report.ok ? out.green(CHECK) : out.red(CROSS);\n return `${verdict} ${report.findings.length} checks: ${parts.join(out.dim(\" · \"))}`;\n}\n\nexport function renderDoctor(report: DoctorReport): string[] {\n const rows: Row[] = report.findings.map((finding) => ({\n glyph: GLYPHS[finding.severity],\n label: finding.label,\n ...(finding.subject === undefined ? {} : { subject: finding.subject }),\n ...(finding.detail === undefined ? {} : { detail: finding.detail }),\n }));\n\n const lines = [heading(\"penv doctor\", `environment ${report.environment}`), \"\"];\n lines.push(...formatRows(rows));\n // Below the table rather than beside it: these are lines to paste, and a line\n // to paste has to survive being selected without a report's columns coming\n // with it. Deduped, because two parameters can share a remedy.\n const remedies = [\n ...new Set(\n report.findings\n .filter((finding) => finding.severity !== \"pass\")\n .map((finding) => finding.remedy)\n .filter((remedy): remedy is string => remedy !== undefined),\n ),\n ];\n if (remedies.length > 0) {\n lines.push(\"\");\n for (const remedy of remedies) {\n lines.push(tip(remedy));\n }\n }\n lines.push(\"\", summarize(report));\n return lines;\n}\n\nexport const doctorCommand = defineCommand({\n meta: {\n name: \"doctor\",\n description: \"Report missing, weak, unused, fallback, plaintext-secret, and drift issues\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to report on\" },\n },\n run({ args }) {\n return guard(async () => {\n const report = await runDoctor({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n envFlags: shorthandCandidates(args, [\"env\"]),\n });\n write(renderDoctor(report));\n if (!report.ok) {\n process.exitCode = 1;\n }\n });\n },\n});\n","/**\n * `penv push` — ship an environment's values to a provider.\n *\n * The destination is the environment's declared entry, always. A push that could\n * go somewhere the config never declared would be a seam penv cannot see, and an\n * entry is addressed in its provider's own words, so there is no generic place to\n * point one at. What crosses depends on what the destination declares it holds:\n *\n * - **Records** (Vault, SSM, Kubernetes): the local tree is mirrored verbatim —\n * unscoped and target-environment value files byte-for-byte (a sealed value\n * stays sealed; the key never has to be present), plus each parameter's meta.\n * Both `.local` scopes never cross: a personal override is not something a\n * shared store has any business holding.\n * - **A projection** (GitHub Actions Secrets): `penv generate` pointed at CI.\n * The tree is resolved exactly as a deploy would read it — `.local` skipped —\n * every generated name is judged against the destination's own grammar\n * *before* the first PUT, and the resolved values cross in plaintext for the\n * destination to re-seal (sealed values only behind `--allow-decrypt`).\n *\n * A destination-side target that does not exist yet — a GitHub deployment\n * environment — is created only on an explicit yes: the CLI prompts, `--yes`\n * pre-approves for CI, and a refusal names the exact remedy. Creation is an\n * answer, never a guess.\n */\n\nimport type {\n AnyProvider,\n Meta,\n MetaBlock,\n ParameterRef,\n PenvConfig,\n ProjectionProvider,\n Provider,\n SecretScope,\n ValueFile,\n} from \"@penvhq/core\";\nimport {\n checkNameCollisions,\n environmentEntry,\n holdsProjection,\n PenvError,\n recordPath,\n requireValue,\n variableName,\n} from \"@penvhq/core\";\nimport type { FilesystemProvider } from \"@penvhq/provider-filesystem\";\nimport { defineCommand } from \"citty\";\nimport { shorthandCandidates } from \"../env-flags.js\";\nimport { lineReader } from \"../input.js\";\nimport type { Project, SyncResolution } from \"../project.js\";\nimport {\n keySourceFor,\n localTree,\n openProject,\n refsFrom,\n resolveAllSync,\n targetEnvironment,\n} from \"../project.js\";\nimport { createSourceProvider, LOCAL_TREE_TYPE } from \"../registry.js\";\nimport { CHECK, formatRows, guard, WARN, write } from \"../ui.js\";\n\n/** The per-environment meta field recording penv's last push, compared against the destination's `updatedAt`. */\nexport const LAST_PUSHED_KEY = \"lastPushedAt\";\n\nexport interface PushOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n /** Permits sealed values to be decrypted locally and pushed as plaintext for the destination to re-seal. */\n readonly allowDecrypt?: boolean;\n /** Pre-approves creating a missing destination-side target (`--yes`). */\n readonly yes?: boolean;\n /** Injected in tests: the destination provider. Defaults to the one the environment's entry declares. */\n readonly provider?: AnyProvider;\n /** Injected in tests: answers the create-target question. Defaults to a terminal prompt. */\n readonly confirm?: (question: string) => Promise<boolean>;\n /** Injected in tests: the wall-clock reading recorded in meta. Defaults to now. */\n readonly now?: string;\n}\n\nexport interface PushResult {\n readonly environment: string;\n /** The destination provider's type — its package name. */\n readonly destination: string;\n /** What the destination holds, which decided what crossed. */\n readonly mode: \"records\" | \"projection\";\n /** Values sent — resolved secrets for a projection, value files for records. */\n readonly pushed: number;\n /** Meta records mirrored. Records mode only. */\n readonly meta: number;\n readonly repositorySecrets: number;\n readonly environmentSecrets: number;\n /** How many were sealed and crossed as plaintext for the destination to re-seal. */\n readonly decrypted: number;\n /** True when the destination-side target was created by this push, on approval. */\n readonly createdTarget: boolean;\n}\n\n/** One value ready to send, with the destination scope it lands in. */\ninterface Outbound {\n readonly ref: ParameterRef;\n readonly variable: string;\n readonly value: string;\n readonly scope: SecretScope;\n readonly encrypted: boolean;\n}\n\n/**\n * The destination provider: the environment's declared entry, and nothing else.\n * An environment whose provider is the local tree itself has nowhere to push, and\n * says so.\n */\nasync function destinationFor(\n project: Project,\n environment: string,\n options: PushOptions,\n): Promise<AnyProvider> {\n const declared = environmentEntry(project.config, environment);\n if (declared === undefined || declared.provider === LOCAL_TREE_TYPE) {\n throw new PenvError(\n \"NO_DESTINATION\",\n `Environment ${environment}'s provider is the local records tree itself, so penv has nowhere to push`,\n `Declare the backend that holds it in penv.config.ts — e.g. \\`${environment}: { provider: \"@penvhq/provider-github\", repository: \"owner/repo\" }\\` — ` +\n \"and run this again. A push only ever goes where the config says this environment lives.\",\n );\n }\n if (options.provider !== undefined) {\n return options.provider;\n }\n return createSourceProvider(declared.provider, {\n root: project.root,\n config: project.config,\n providerConfig: declared,\n environment,\n });\n}\n\n/**\n * Every value to send, resolved up front so the encrypted/allow-decrypt refusal\n * also happens before anything is pushed. A `.local` scope is already gone (the\n * push resolution dropped it), so a winner is only ever environment-scoped or the\n * unscoped default — the destination scope is that binary.\n */\nfunction plan(\n resolutions: readonly SyncResolution[],\n config: PenvConfig,\n environment: string,\n allowDecrypt: boolean,\n): Outbound[] {\n const outbound: Outbound[] = [];\n for (const resolution of resolutions) {\n const winner = resolution.winner;\n if (winner === undefined) {\n continue;\n }\n let encrypted = false;\n if (winner.file.encrypted) {\n if (!allowDecrypt) {\n throw new PenvError(\n \"ENCRYPTED_VALUE_REFUSED\",\n `Parameter ${resolution.parameter} for environment ${environment} resolves to the encrypted value file ${recordPath(winner.location)}, and a push sends plaintext for the destination to re-seal`,\n \"Re-run with `--allow-decrypt` to decrypt it locally and push it, or push an environment \" +\n \"whose values are plaintext. penv's encryption stops at the projection; the destination \" +\n \"seals it under its own key.\",\n );\n }\n // Throws naming the reason if a sealed winner cannot be opened — never\n // silently dropping the secret CI needs.\n requireValue(resolution, environment);\n encrypted = true;\n }\n if (resolution.value === undefined) {\n continue;\n }\n const scope: SecretScope =\n winner.file.scope.kind === \"unscoped\"\n ? { kind: \"repository\" }\n : { kind: \"environment\", environment };\n outbound.push({\n ref: resolution.ref,\n variable: variableName(resolution.ref, config),\n value: resolution.value,\n scope,\n encrypted,\n });\n }\n return outbound;\n}\n\n/** Records what penv did, per environment, in the committed meta — never a value read back. */\nfunction withLastPushed(meta: Meta | undefined, environment: string, iso: string): Meta {\n const base: Meta = meta ?? {};\n const environments: Record<string, MetaBlock> = { ...(base.environments ?? {}) };\n environments[environment] = { ...(environments[environment] ?? {}), [LAST_PUSHED_KEY]: iso };\n return { ...base, environments };\n}\n\nfunction recordPush(\n tree: FilesystemProvider,\n ref: ParameterRef,\n environment: string,\n iso: string,\n): void {\n const meta = withLastPushed(tree.readMetaSync(ref), environment, iso);\n tree.writeMetaSync(ref, meta);\n}\n\n/** The default create-target prompt: a terminal question, and a refusal anywhere a terminal is not. */\nasync function terminalConfirm(question: string): Promise<boolean> {\n if (process.stdin.isTTY !== true) {\n return false;\n }\n const reader = lineReader();\n try {\n const answer = await reader.ask(`${question} [y/N] `);\n return answer !== undefined && /^y(es)?$/i.test(answer.trim());\n } finally {\n reader.close();\n }\n}\n\n/**\n * Makes sure the destination-side target for this environment exists before the\n * first PUT, creating it only on an explicit yes. A destination with no notion\n * of a target (no `targetExists`) passes through untouched.\n */\nasync function ensureTargetApproved(\n provider: ProjectionProvider,\n environment: string,\n options: PushOptions,\n): Promise<boolean> {\n if (provider.targetExists === undefined) {\n return false;\n }\n if (await provider.targetExists(environment)) {\n return false;\n }\n if (provider.ensureTarget === undefined) {\n throw new PenvError(\n \"MISSING_TARGET\",\n `The destination has no environment \\`${environment}\\` to receive this push, and this provider cannot create one`,\n `Create the environment on the destination side, then run \\`penv push --env ${environment}\\` again.`,\n );\n }\n const approved =\n options.yes === true ||\n (await (options.confirm ?? terminalConfirm)(\n `The destination has no environment \\`${environment}\\`. Create it?`,\n ));\n if (!approved) {\n throw new PenvError(\n \"MISSING_TARGET\",\n `The destination has no environment \\`${environment}\\` to receive this push`,\n `Re-run with \\`--yes\\` to create it, answer \\`y\\` at the prompt, or create it on the destination side yourself.`,\n );\n }\n await provider.ensureTarget(environment);\n return true;\n}\n\n/** The projection push: resolve as CI would read, judge every name, then all or nothing. */\nasync function pushProjection(\n project: Project,\n provider: ProjectionProvider,\n environment: string,\n options: PushOptions,\n): Promise<PushResult> {\n const tree = localTree(project);\n const keys = keySourceFor(project, environment);\n // The push resolution: both `.local` scopes dropped. CI receives what CI would read.\n const resolutions = resolveAllSync(tree, environment, keys, true);\n const refs = refsFrom(resolutions.map((resolution) => resolution.ref));\n\n // Every name judged before a single PUT. Exact-string collisions are core's;\n // the destination's reserved prefixes, charset, and case-insensitivity are the\n // provider's own `checkNames`. Both refuse the whole push, never half of it.\n const collision = checkNameCollisions(refs, project.config)[0];\n if (collision !== undefined) {\n throw collision;\n }\n const nameError = provider.checkNames?.(refs, project.config)[0];\n if (nameError !== undefined) {\n throw nameError;\n }\n\n const outbound = plan(resolutions, project.config, environment, options.allowDecrypt === true);\n\n // Reachable and writable, or penv stops here having placed nothing.\n await provider.verify();\n\n // The target exists — or was just created on an explicit yes — before any PUT.\n const createdTarget =\n outbound.some((item) => item.scope.kind === \"environment\") &&\n (await ensureTargetApproved(provider, environment, options));\n\n let repositorySecrets = 0;\n let environmentSecrets = 0;\n for (const item of outbound) {\n await provider.push(item.variable, item.value, item.scope);\n if (item.scope.kind === \"repository\") {\n repositorySecrets += 1;\n } else {\n environmentSecrets += 1;\n }\n // Stamped AFTER the push, per item — not once before the loop. The destination\n // stamps each secret's `updated_at` when its own PUT lands, and one process\n // runs per parameter, so a single pre-loop time would sit seconds behind the\n // destination's and make `doctor`'s hand-edit check fire on a clean push.\n recordPush(tree, item.ref, environment, options.now ?? new Date().toISOString());\n }\n\n return {\n environment,\n destination: provider.type,\n mode: \"projection\",\n pushed: outbound.length,\n meta: 0,\n repositorySecrets,\n environmentSecrets,\n decrypted: outbound.filter((item) => item.encrypted).length,\n createdTarget,\n };\n}\n\n/** Whether a value file crosses on a records push: the unscoped default and the target environment's scope. */\nfunction crossesToRecords(file: ValueFile, environment: string): boolean {\n const scope = file.scope;\n if (scope.kind === \"unscoped\") {\n return true;\n }\n return scope.kind === \"environment\" && scope.environment === environment;\n}\n\n/**\n * The records push: mirror the tree verbatim. A value is an opaque envelope the\n * destination holds and hands back unchanged — sealed stays sealed, so the key\n * that opens it never has to be present to push it. Both `.local` scopes stay\n * home, and other environments' scoped values stay out of this environment's\n * store — the destination ends up holding exactly what a pull for this\n * environment would bring back.\n */\nasync function pushRecords(\n project: Project,\n provider: Provider,\n environment: string,\n): Promise<PushResult> {\n const tree = localTree(project);\n const files = tree.listSync().filter((file) => crossesToRecords(file, environment));\n\n let pushed = 0;\n for (const file of files) {\n const value = tree.readSync(file);\n if (value === undefined) {\n continue;\n }\n await provider.write(file, value);\n pushed += 1;\n }\n\n const refs = refsFrom(files);\n let meta = 0;\n for (const ref of refs) {\n const block = tree.readMetaSync(ref);\n if (block === undefined) {\n continue;\n }\n await provider.writeMeta(ref, block);\n meta += 1;\n }\n\n return {\n environment,\n destination: provider.type,\n mode: \"records\",\n pushed,\n meta,\n repositorySecrets: 0,\n environmentSecrets: 0,\n decrypted: 0,\n createdTarget: false,\n };\n}\n\nexport async function runPush(options: PushOptions): Promise<PushResult> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n const provider = await destinationFor(project, environment, options);\n\n if (holdsProjection(provider)) {\n return pushProjection(project, provider, environment, options);\n }\n return pushRecords(project, provider, environment);\n}\n\nexport function renderPush(result: PushResult): string[] {\n if (result.pushed === 0 && result.meta === 0) {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Nothing to push\",\n subject: `no values resolve for environment ${result.environment}`,\n },\n ]);\n }\n\n const target = `${result.destination} for environment ${result.environment}`;\n\n if (result.mode === \"records\") {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Pushed\",\n subject: `${result.pushed} value ${result.pushed === 1 ? \"file\" : \"files\"}, ${result.meta} meta`,\n detail: `mirrored verbatim to ${target}`,\n },\n {\n glyph: CHECK,\n label: \"Sealed values\",\n subject: \"crossed byte-for-byte, still sealed\",\n detail: \"the destination holds envelopes; no key was needed to push them\",\n },\n ]);\n }\n\n const rows = [\n {\n glyph: CHECK,\n label: \"Pushed\",\n subject: `${result.pushed} ${result.pushed === 1 ? \"secret\" : \"secrets\"}`,\n detail: `to ${target}`,\n },\n {\n glyph: CHECK,\n label: \"Scopes\",\n subject: `${result.environmentSecrets} environment, ${result.repositorySecrets} repository`,\n detail:\n \"environment secrets override repository secrets, as penv's env scope overrides the default\",\n },\n ];\n if (result.createdTarget) {\n rows.push({\n glyph: CHECK,\n label: \"Created\",\n subject: `the destination environment ${result.environment}`,\n detail: \"it did not exist yet; created on your approval\",\n });\n }\n if (result.decrypted > 0) {\n rows.push({\n glyph: WARN,\n label: \"Decrypted\",\n subject: `${result.decrypted} ${result.decrypted === 1 ? \"secret\" : \"secrets\"}`,\n detail: \"sent as plaintext for the destination to re-seal under its own key\",\n });\n }\n return formatRows(rows);\n}\n\n/**\n * The flags that used to redirect a push, and the one case that must not fall\n * through. citty rejects no unknown flag, and a flag carrying a value is not a\n * shorthand candidate either — so `--destination @penvhq/provider-github` would be\n * dropped in silence and the secrets would land at the declared entry instead.\n */\nconst REDIRECT_FLAGS = [\"destination\", \"dest\", \"d\", \"location\", \"l\"] as const;\n\nexport function assertNoRedirect(args: Readonly<Record<string, unknown>>): void {\n const given = REDIRECT_FLAGS.filter((flag) => args[flag] !== undefined);\n const named = given[0];\n if (named === undefined) {\n return;\n }\n throw new PenvError(\n \"REMOVED_FLAG\",\n `\\`--${named}\\` is not a flag \\`penv push\\` takes`,\n \"A push only ever goes where the config says this environment lives. Declare the \" +\n \"destination in `environments.<env>` — the provider package, addressed in that provider's \" +\n \"own words — and push with `--env <name>`.\",\n );\n}\n\nexport const pushCommand = defineCommand({\n meta: {\n name: \"push\",\n description: \"Push an environment's values to its provider\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to push\" },\n \"allow-decrypt\": {\n type: \"boolean\",\n description:\n \"Decrypt sealed values locally and push them as plaintext for the destination to re-seal\",\n },\n yes: {\n type: \"boolean\",\n alias: \"y\",\n description: \"Create a missing destination-side environment without prompting\",\n },\n },\n run({ args }) {\n return guard(async () => {\n assertNoRedirect(args);\n const result = await runPush({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args[\"allow-decrypt\"] === undefined ? {} : { allowDecrypt: args[\"allow-decrypt\"] }),\n ...(args.yes === undefined ? {} : { yes: args.yes }),\n envFlags: shorthandCandidates(args, [\"env\", \"allow-decrypt\", \"allowDecrypt\", \"yes\", \"y\"]),\n });\n write(renderPush(result));\n });\n },\n});\n","/**\n * Reading answers from a terminal — or from a pipe, where the answers can arrive\n * before the questions.\n *\n * `readline.question` attaches its listener only when asked, so a line piped in\n * ahead of the first prompt — `printf 'value\\n' | penv fill` — was emitted to\n * nobody and lost, and the EOF behind it closed the interface out from under the\n * question that came next (`ERR_USE_AFTER_CLOSE`, or a promise that never\n * settled). This reader listens from the moment it is created: early lines are\n * buffered in arrival order, and once input ends every outstanding and future\n * question resolves to `undefined` — the caller's \"no answer\", which `fill`\n * already treats as a skip. Against a real terminal it is `readline`'s own\n * prompt-and-edit behavior, unchanged.\n */\n\nimport { createInterface } from \"node:readline\";\n\nexport interface LineReader {\n /**\n * The next line of input, or `undefined` when input has ended. The question is\n * written only when the reader must wait for it to be answered — an answer\n * that already arrived belongs to a reader who is not looking at a prompt.\n */\n ask(question: string): Promise<string | undefined>;\n close(): void;\n}\n\nexport function lineReader(\n input: NodeJS.ReadableStream = process.stdin,\n output: NodeJS.WritableStream = process.stdout,\n): LineReader {\n const rl = createInterface({ input, output });\n const buffered: string[] = [];\n const waiting: Array<(line: string | undefined) => void> = [];\n let closed = false;\n\n rl.on(\"line\", (line) => {\n const next = waiting.shift();\n if (next === undefined) {\n buffered.push(line);\n } else {\n next(line);\n }\n });\n rl.on(\"close\", () => {\n closed = true;\n for (const next of waiting.splice(0)) {\n next(undefined);\n }\n });\n\n return {\n ask(question: string): Promise<string | undefined> {\n const early = buffered.shift();\n if (early !== undefined) {\n return Promise.resolve(early);\n }\n if (closed) {\n return Promise.resolve(undefined);\n }\n rl.setPrompt(question);\n rl.prompt();\n return new Promise((resolve) => {\n waiting.push(resolve);\n });\n },\n close(): void {\n rl.close();\n },\n };\n}\n","/**\n * `penv encrypt <key>` and `penv decrypt <key>` — change whether one value file\n * is sealed, without changing what it says.\n *\n * These act on one parameter at one scope, because a scope is the address the\n * provider actually has: `db-password.production` and `db-password` are two\n * files, and a command that \"encrypted the parameter\" would have to guess which.\n *\n * They exist for two moments the policy cannot handle by itself. The first is\n * adoption: `secret: true` added to a parameter that already has values leaves\n * every existing file plaintext, and `penv set` only seals what it writes. The\n * second is re-sealing after a move — a ciphertext is bound to the address it\n * lives at, so a value file that is renamed or re-scoped must be sealed again for\n * its new address.\n *\n * Neither invents a key. `penv encrypt` with no key refuses, because a key penv\n * chose is a key nobody can reproduce — the same reason `penv set` is the only\n * thing that writes a value, and never a value it made up.\n */\n\nimport type { ValueFile } from \"@penvhq/core\";\nimport {\n formatValueFile,\n isSecret,\n openValue,\n PenvError,\n parameterId,\n recordPath,\n sealValue,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { Project } from \"../project.js\";\nimport { keySourceFor, openProject, refFromKey, targetEnvironment } from \"../project.js\";\nimport { CHECK, formatRows, guard, write } from \"../ui.js\";\nimport type { ScopeOptions } from \"./set.js\";\nimport { targetScope } from \"./set.js\";\n\nexport interface ResealOptions extends ScopeOptions {\n readonly cwd: string;\n readonly key: string;\n}\n\nexport interface ResealResult {\n readonly parameter: string;\n /** The file that now holds the value. */\n readonly location: string;\n /** The file that no longer exists, because its twin replaced it. */\n readonly removed: string;\n}\n\n/** The two files one value can live in at a scope. Exactly one of them exists. */\nfunction twins(project: Project, key: string, options: ScopeOptions): [ValueFile, ValueFile] {\n const ref = refFromKey(key, project.config);\n const scope = targetScope(project, options, key);\n return [\n { namespace: ref.namespace, name: ref.name, scope, encrypted: false },\n { namespace: ref.namespace, name: ref.name, scope, encrypted: true },\n ];\n}\n\n/**\n * The environment this scope's policy and key are read from.\n *\n * Unlike `set`, this refuses rather than falling back to the base block: both\n * commands here need a *key*, and a key is declared per environment. A scope that\n * names none has no key penv can choose, and choosing the ambient environment's\n * would seal a file every other environment reads under a key only one of them\n * has.\n */\nfunction environmentFor(project: Project, options: ScopeOptions, verb: string): string {\n if (options.environment === undefined) {\n throw new PenvError(\n \"SECRET_SCOPE_AMBIGUOUS\",\n `\\`penv ${verb}\\` names no environment, and keys are declared per environment`,\n \"Pass `--env <environment>`. penv cannot tell which environment's key applies to a file \" +\n \"that names none, and will not pick one for you.\",\n );\n }\n return targetEnvironment(project, options.environment);\n}\n\nasync function readOne(project: Project, file: ValueFile): Promise<string | undefined> {\n return project.provider.read(file);\n}\n\nexport async function runEncrypt(options: ResealOptions): Promise<ResealResult> {\n const project = openProject(options.cwd);\n const environment = environmentFor(project, options, \"encrypt\");\n const [plain, sealed] = twins(project, options.key, options);\n const parameter = parameterId(plain);\n\n const value = await readOne(project, plain);\n if (value === undefined) {\n const already = await readOne(project, sealed);\n throw new PenvError(\n \"PARAMETER_ABSENT\",\n already === undefined\n ? `Parameter ${parameter} has no value file at ${recordPath(formatValueFile(plain))}`\n : `Parameter ${parameter} is already encrypted at ${recordPath(formatValueFile(sealed))}`,\n already === undefined\n ? `Write it first with \\`penv set ${options.key} --env ${environment}\\`, which seals it ` +\n \"automatically when the parameter's meta declares it a secret.\"\n : \"Nothing to do.\",\n );\n }\n\n const text = sealValue(sealed, value, keySourceFor(project, environment), parameter, environment);\n\n // Written before the plaintext is removed. The reverse order has a window in\n // which the value exists nowhere, and the value is the thing being protected.\n await project.provider.write(sealed, text);\n await project.provider.remove(plain);\n\n return {\n parameter,\n location: formatValueFile(sealed),\n removed: formatValueFile(plain),\n };\n}\n\nexport async function runDecrypt(options: ResealOptions): Promise<ResealResult> {\n const project = openProject(options.cwd);\n const environment = environmentFor(project, options, \"decrypt\");\n const [plain, sealed] = twins(project, options.key, options);\n const parameter = parameterId(plain);\n\n // penv does not ship a command whose purpose is to fail its own check. A\n // secret written in plaintext is a `doctor` failure by policy (invariant 14),\n // and decrypting one on request would manufacture exactly that.\n if (isSecret(await project.provider.readMeta(plain), environment)) {\n throw new PenvError(\n \"SECRET_DECRYPT_REFUSED\",\n `Parameter ${parameter} is declared a secret for environment ${environment}, so penv will not write it in plaintext`,\n \"A secret with a plaintext value file is a `penv doctor` failure. Drop `secret` from the \" +\n \"parameter's meta if it is not one, or run `penv generate --allow-decrypt` if you need \" +\n \"the plaintext value in a `.env` artifact.\",\n );\n }\n\n const stored = await readOne(project, sealed);\n if (stored === undefined) {\n throw new PenvError(\n \"PARAMETER_ABSENT\",\n `Parameter ${parameter} has no encrypted value file at ${recordPath(formatValueFile(sealed))}`,\n `Nothing to decrypt. \\`penv get ${options.key} --env ${environment} --explain\\` shows every file penv looked at.`,\n );\n }\n\n const opened = openValue(sealed, stored, keySourceFor(project, environment));\n if (opened.kind === \"failed\") {\n throw new UndecryptableAt(\n parameter,\n environment,\n formatValueFile(sealed),\n opened.failure.detail,\n );\n }\n\n await project.provider.write(plain, opened.value);\n await project.provider.remove(sealed);\n\n return {\n parameter,\n location: formatValueFile(plain),\n removed: formatValueFile(sealed),\n };\n}\n\n/** The one thing `decrypt` can fail at that `requireValue` does not cover: a named file. */\nclass UndecryptableAt extends PenvError {\n constructor(parameter: string, environment: string, location: string, detail: string) {\n super(\n \"VALUE_UNDECRYPTABLE\",\n `Parameter ${parameter} for environment ${environment} is sealed at ${recordPath(location)}, and penv could not open it: ${detail}`,\n \"Make the key available and run the command again. penv will not replace a value it \" +\n \"cannot read.\",\n );\n }\n}\n\nexport function renderReseal(result: ResealResult, verb: \"Encrypted\" | \"Decrypted\"): string[] {\n return formatRows([\n {\n glyph: CHECK,\n label: verb,\n subject: recordPath(result.location),\n detail: `${recordPath(result.removed)} removed`,\n },\n ]);\n}\n\nconst SCOPE_ARGS = {\n key: { type: \"positional\", required: true, description: \"The parameter, e.g. redis/password\" },\n env: { type: \"string\", description: \"The environment whose value file to act on\" },\n local: {\n type: \"boolean\",\n description: \"Act on the personal override rather than the shared file\",\n },\n} as const;\n\nfunction scopeOptions(args: {\n env?: string | undefined;\n local?: boolean | undefined;\n}): ScopeOptions {\n return {\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.local === undefined ? {} : { local: args.local }),\n };\n}\n\nexport const encryptCommand = defineCommand({\n meta: { name: \"encrypt\", description: \"Encrypt one parameter's value file at one scope\" },\n args: SCOPE_ARGS,\n run({ args }) {\n return guard(async () => {\n const result = await runEncrypt({ cwd: process.cwd(), key: args.key, ...scopeOptions(args) });\n write(renderReseal(result, \"Encrypted\"));\n });\n },\n});\n\nexport const decryptCommand = defineCommand({\n meta: { name: \"decrypt\", description: \"Decrypt one parameter's value file at one scope\" },\n args: SCOPE_ARGS,\n run({ args }) {\n return guard(async () => {\n const result = await runDecrypt({ cwd: process.cwd(), key: args.key, ...scopeOptions(args) });\n write(renderReseal(result, \"Decrypted\"));\n });\n },\n});\n","/**\n * `penv set <key> [value]` — write one value file.\n *\n * The scope is chosen, never inferred: `--env <name>` writes `<name>.<env>`,\n * `--local` writes the personal override — for one environment when combined\n * with `--env`, for every environment on its own — and the default is the\n * unscoped one every environment falls back to. Writing to `--env production`\n * when you meant the default is a different file, so penv never picks for you.\n */\n\nimport type { ParameterRef, Provider, Scope, ValueFile } from \"@penvhq/core\";\nimport {\n environmentNames,\n formatValueFile,\n isSecret,\n PenvError,\n parameterId,\n recordPath,\n sealValue,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { Project } from \"../project.js\";\nimport {\n assertWritableKey,\n keySourceFor,\n openProject,\n refFromKey,\n targetEnvironment,\n} from \"../project.js\";\nimport { CHECK, formatRows, guard, write } from \"../ui.js\";\n\nexport interface ScopeOptions {\n /** The environment scope. Combined with `local`, the environment-scoped override. */\n readonly environment?: string;\n readonly local?: boolean;\n}\n\nexport interface SetOptions extends ScopeOptions {\n readonly cwd: string;\n readonly key: string;\n readonly value: string;\n}\n\nexport interface SetResult {\n readonly parameter: string;\n /** The value file written, relative to the records tree. */\n readonly location: string;\n /** Whether meta's policy sealed it. Reported, so the marker is never a surprise. */\n readonly encrypted: boolean;\n}\n\n/**\n * The scope the flags name — one flag combination per cascade level, all four.\n *\n * `--local --env <e>` is the environment-scoped personal override, mirroring\n * `.env.<e>.local`: the flags compose, because the cascade has a level where\n * both are true. Refusing the combination is what used to leave that level\n * unaddressable from the CLI.\n *\n * `environment` must already be the name {@link targetScope} validated, never\n * the raw flag — the string here becomes a filename segment verbatim.\n */\nexport function scopeFrom(options: ScopeOptions): Scope {\n if (options.local === true) {\n if (options.environment !== undefined) {\n return { kind: \"environment-local\", environment: options.environment };\n }\n return { kind: \"local\" };\n }\n if (options.environment !== undefined) {\n return { kind: \"environment\", environment: options.environment };\n }\n return { kind: \"unscoped\" };\n}\n\n/**\n * The scope a writer may act on: the environment as `targetEnvironment`\n * *returned* it, never as the flag carried it.\n *\n * `resolveEnvironment` trims before it checks the whitelist, so the validated\n * name and the raw flag are two different strings and only the returned one has\n * been checked against the declared environments. Passing the raw one to\n * `formatValueFile` is what let `--env \"production \"` write `api-key.production `\n * — a file the filename grammar refuses to read (invariant 10), so every later\n * `list`/`get`/`generate`/`validate`/`remove` throws and the tree is repairable\n * only by deleting the file by hand. Validation is what makes a string safe to\n * put in a filename, so the validated value is the only one that may reach one.\n *\n * A blank `--env` is refused rather than resolved: `resolveEnvironment` answers\n * it from `PENV_ENV`/`NODE_ENV`, and a writer scoping a file to an environment\n * the user never named is the same wrong file by a quieter route (invariants 10\n * and 13).\n */\nexport function targetScope(project: Project, options: ScopeOptions, key: string): Scope {\n const environment = options.environment;\n if (environment === undefined) {\n return scopeFrom(options);\n }\n if (environment.trim().length === 0) {\n throw new PenvError(\n \"ENVIRONMENT_FLAG_EMPTY\",\n `\\`--env\\` for parameter ${key} names no environment`,\n `Pass a declared environment — ${environmentNames(project.config)\n .map((e) => `\\`${e}\\``)\n .join(\", \")} — ` +\n \"e.g. `--env production`, or drop `--env` to write the scope that has no environment.\",\n );\n }\n return scopeFrom({ ...options, environment: targetEnvironment(project, environment) });\n}\n\n/**\n * The environment whose policy governs the file being written.\n *\n * `undefined` for a scope that carries no environment, which asks meta for its\n * base block — the honest authority for a file every environment reads. Asking\n * `production`'s block about the unscoped default would apply one environment's\n * policy to a file the others fall back to.\n */\nfunction policyEnvironment(project: Project, options: ScopeOptions): string | undefined {\n return options.environment === undefined\n ? undefined\n : targetEnvironment(project, options.environment);\n}\n\n/**\n * Seals a secret, or refuses for a reason it can name.\n *\n * A key source is declared per environment, so a scope that names no environment\n * has no key penv can choose. It refuses rather than reaching for the ambient\n * environment's key: that key would seal a file every *other* environment also\n * reads, and each of them would then fail to open it — a scope-widening leak\n * dressed as a convenience. `penv set redis/password --env production` is one\n * more word and is unambiguous.\n */\nfunction sealFor(\n project: Project,\n file: ValueFile,\n value: string,\n parameter: string,\n environment: string | undefined,\n): string {\n if (environment === undefined) {\n throw new PenvError(\n \"SECRET_SCOPE_AMBIGUOUS\",\n `Parameter ${parameter} is a secret, and ${recordPath(formatValueFile(file))} names no environment`,\n \"A key is declared by its environment's `keySource` in penv.config.ts, so penv cannot \" +\n \"tell which key should seal a file that every environment reads. Write it at an \" +\n \"environment scope — add `--env <environment>` — or drop `secret` from the parameter's meta.\",\n );\n }\n return sealValue(file, value, keySourceFor(project, environment), parameter, environment);\n}\n\n/** What {@link sealAwareWrite} was told to write, and to which store. */\nexport interface SealAwareWriteOptions {\n readonly project: Project;\n /**\n * The store the value lands in, and the meta whose policy governs it is read\n * *from*. `set` passes the local tree; `rotate` passes it only when the\n * environment's source of truth IS the local tree, so the seal-and-twin rule\n * applies exactly where penv's envelope is penv's concern.\n */\n readonly provider: Provider;\n readonly ref: ParameterRef;\n readonly scope: Scope;\n readonly value: string;\n /** The environment whose meta block decides the policy, or `undefined` for the base block. */\n readonly environment: string | undefined;\n}\n\n/** What {@link sealAwareWrite} did: the marker meta chose, and the file it wrote. */\nexport interface SealAwareWriteResult {\n /** Whether meta's policy sealed it. */\n readonly encrypted: boolean;\n /** The value file written, relative to the records tree. */\n readonly location: string;\n}\n\n/**\n * Writes one value file into the local tree, sealing it when meta says the\n * parameter is a secret, and removing the twin at that scope — the one correct\n * physics for a store whose envelope penv owns.\n *\n * There is no `--encrypt` flag, deliberately. A flag would make the command line\n * the authority on what is secret, and meta is (invariant 14) — the `.enc` marker\n * is validated *against* the policy, so a marker chosen at the keyboard would\n * invert the direction the check runs in. The policy decides; the writer obeys.\n *\n * Both `set` and the local-tree branch of `rotate` go through here, so a rotated\n * secret is sealed exactly as a `set` one is: the defect was `rotate` writing the\n * live credential as cleartext into `.penv/` — where plaintext outranks `.enc` at\n * the same scope, so it also shadowed any sealed copy already there.\n */\nexport async function sealAwareWrite(\n options: SealAwareWriteOptions,\n): Promise<SealAwareWriteResult> {\n const { project, provider, ref, scope, value, environment } = options;\n const secret = isSecret(await provider.readMeta(ref), environment);\n\n const file: ValueFile = {\n namespace: ref.namespace,\n name: ref.name,\n scope,\n encrypted: secret,\n };\n\n // Sealed before anything is written, so a secret penv has no key for leaves\n // nothing behind. Writing the plaintext first and letting `doctor` report it\n // afterwards would put the secret on disk in order to complain about it.\n const stored = secret ? sealFor(project, file, value, parameterId(ref), environment) : value;\n\n await provider.write(file, stored);\n\n // The twin at this scope is removed, because one scope holds one value.\n //\n // `.enc` is orthogonal to precedence, so `<name>.<env>` and `<name>.<env>.enc`\n // are two candidates at one address, and the plaintext is considered first.\n // Leaving the twin behind therefore does not leave a harmless extra file — it\n // leaves the one that *wins*. Marking a parameter secret and running `penv set`\n // reported writing a sealed file while `penv get` kept handing back the stale\n // plaintext underneath it: the value you set was not the value you got, and the\n // new secret was inert on disk. Written before the removal, so the value is\n // never in neither file.\n await provider.remove({ ...file, encrypted: !secret });\n\n return { encrypted: secret, location: formatValueFile(file) };\n}\n\n/**\n * Writes one value file, sealing it when meta says the parameter is a secret.\n *\n * The scope is chosen from the flags, then the seal-and-twin write is the shared\n * {@link sealAwareWrite}, against the local tree — the store `set` always edits.\n */\nexport async function runSet(options: SetOptions): Promise<SetResult> {\n const project = openProject(options.cwd);\n assertWritableKey(options.key);\n const ref = refFromKey(options.key, project.config);\n\n // An environment is a whitelist entry or nothing, so a scope naming one is\n // checked before it becomes a filename — including under `--local`, where\n // the environment is a filename segment too.\n const scope = targetScope(project, options, options.key);\n const environment = policyEnvironment(project, options);\n\n const { encrypted, location } = await sealAwareWrite({\n project,\n provider: project.provider,\n ref,\n scope,\n value: options.value,\n environment,\n });\n\n return { parameter: options.key, location, encrypted };\n}\n\nexport function renderSet(result: SetResult): string[] {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Wrote\",\n subject: recordPath(result.location),\n // The `.enc` suffix says this already, but only to a reader who knows the\n // grammar. Meta decided it, not the command line, so the command says so.\n ...(result.encrypted ? { detail: \"encrypted, per the parameter's meta policy\" } : {}),\n },\n ]);\n}\n\n/** The value when it is piped in rather than typed: one trailing newline is the shell's. */\nexport async function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin as AsyncIterable<Buffer>) {\n chunks.push(Buffer.from(chunk));\n }\n const text = Buffer.concat(chunks).toString(\"utf8\");\n return text.endsWith(\"\\n\") ? text.slice(0, -1) : text;\n}\n\nexport const setCommand = defineCommand({\n meta: { name: \"set\", description: \"Update a parameter\" },\n args: {\n key: { type: \"positional\", required: true, description: \"The parameter, e.g. redis/password\" },\n value: {\n type: \"positional\",\n required: false,\n description: \"The value; read from stdin if omitted\",\n },\n env: { type: \"string\", description: \"Write the <name>.<env> scope\" },\n local: {\n type: \"boolean\",\n description: \"Write the personal override: <name>.<env>.local with --env, else <name>.local\",\n },\n },\n run({ args }) {\n return guard(async () => {\n const value = args.value ?? (await readStdin());\n write(\n renderSet(\n await runSet({\n cwd: process.cwd(),\n key: args.key,\n value,\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.local === undefined ? {} : { local: args.local }),\n }),\n ),\n );\n });\n },\n});\n","/**\n * `penv fill` — walk the schema's required-but-missing parameters and ask for\n * each one, deriving the value file's name so the user never has to.\n *\n * The schema-first flow writes `.penv/env.ts` before any value exists, and there\n * the user hits a translation they should not have to make: `databaseUrl` in the\n * schema is `database-url` on disk, and typing the wrong one writes a file the\n * schema still cannot see. `fill` reads the same declared drift `validate`\n * computes, and for each missing parameter asks for a value and writes it through\n * the one writer — `runSet` — deriving the kebab filename from the schema key.\n *\n * A value is never invented: a blank answer skips the parameter, because the\n * silent value reaching runtime is the failure penv exists to delete, and a\n * placeholder written here is exactly that value by a friendlier route.\n *\n * Optional parameters — `.optional()`, `.default()` — are asked too, after the\n * required gaps, tagged so the reader knows an answer is an override and Enter\n * keeps what the schema declared. Skipping them silently was the old behavior,\n * and it hid a real choice: a schema default reaching runtime is legal, but the\n * user who never heard the question never chose it.\n */\n\nimport { PenvError, recordPath, SCHEMA_SHAPE_FILE } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { shorthandCandidates } from \"../env-flags.js\";\nimport { lineReader } from \"../input.js\";\nimport { out } from \"../style.js\";\nimport { CHECK, formatRows, guard, prompt as promptLine, type Row, WARN, write } from \"../ui.js\";\nimport { runSet } from \"./set.js\";\nimport { runValidate, type ValidateIssueKind } from \"./validate.js\";\n\n/**\n * The validation issue kinds that stop `fill` before it writes a thing. A\n * `schema` issue is, on the ordinary run, the missing value `fill` is about to\n * ask for — so it is deliberately absent here, or `fill` would refuse the very\n * gap it exists to close. A collision, a reserved token, or a config/load\n * failure is a structural fault of the tree itself, and filling would only paper\n * over it: `generate` would still drop a value, and \"what is missing\" is not even\n * a meaningful question against a config that does not load.\n */\nconst BLOCKING: ReadonlySet<ValidateIssueKind> = new Set([\"config\", \"collision\", \"reserved\"]);\n\n/** One question `fill` puts to the user: which parameter, in which environment. */\nexport interface FillPrompt {\n /** The value file's key, kebab and slash-separated — the name the user need never derive. */\n readonly parameter: string;\n readonly environment: string;\n /**\n * Whether meta says this is a secret. Carried so a wrapper can mute the echo;\n * v1 does not, and the drift carries no meta, so this is `false` today.\n */\n readonly secret: boolean;\n /**\n * Whether the schema excuses absence — `.optional()`, `.default()`. An answer\n * writes an override; a blank one leaves the schema's own behavior in place,\n * which is a kept default rather than a lingering gap.\n */\n readonly optional: boolean;\n /** What the schema falls back to, rendered for display, when it declares one penv can read. */\n readonly defaultValue?: string;\n readonly description?: string;\n}\n\nexport interface FillOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n /**\n * How a value is obtained for one prompt. `undefined` or an empty answer skips\n * the parameter — the readline half lives only in the wrapper, so `runFill`\n * stays pure and unit-testable.\n */\n readonly ask: (prompt: FillPrompt) => Promise<string | undefined>;\n}\n\nexport interface FillResult {\n readonly environment: string;\n /** The value files written, one per answered prompt. */\n readonly written: ReadonlyArray<{\n readonly parameter: string;\n /** The value file written, relative to the records tree. */\n readonly location: string;\n readonly encrypted: boolean;\n }>;\n /** The parameters a blank answer left for later — never written as an empty value. */\n readonly skipped: readonly string[];\n /**\n * The optional parameters a blank answer left to the schema. Not `skipped`:\n * a skipped parameter is still a gap, and one of these is a decision — the\n * schema's default (or declared absence) is the value, on purpose.\n */\n readonly kept: readonly string[];\n /**\n * The declared keys no filename reaches (`apiURL`, a reserved token). `fill`\n * cannot ask for a value it could never write, so it carries the rename remedy\n * out rather than prompting for a file that would error.\n */\n readonly unreachable: ReadonlyArray<{ readonly subject: string; readonly remedy: string }>;\n}\n\n/**\n * Asks for every declared-but-missing parameter, and writes the ones answered.\n *\n * The drift is `validate`'s, not a second reading of the schema: `runValidate`\n * already computes exactly the required-but-absent set, so `fill` and `validate`\n * can never disagree about what is missing. The writing is `runSet`'s, so a\n * filled secret is sealed exactly as a `set` one is — `fill` owns neither the\n * resolution nor the write, only the prompting between them.\n */\nexport async function runFill(options: FillOptions): Promise<FillResult> {\n const validation = await runValidate({\n cwd: options.cwd,\n ...(options.environment === undefined ? {} : { environment: options.environment }),\n ...(options.envFlags === undefined ? {} : { envFlags: options.envFlags }),\n });\n const environment = validation.environment;\n\n // A tree that fails validation for a *structural* reason is not one `fill`\n // should write into, so it refuses and hands the reasons back rather than\n // prompting. Keying off the issue kinds — not `validation.ok` — is the load-\n // bearing choice: a required parameter with no value fails the schema too, and\n // that failure *is* the drift `fill` exists to close, so blocking on `ok` would\n // refuse every ordinary run. The `EMPTY_DRIFT` sentinel is not consulted: a\n // schema that never loaded surfaces here as a `config` blocker with its real\n // reason, so a provider-list failure no longer masquerades as \"no schema\".\n const blockers = validation.issues.filter((issue) => BLOCKING.has(issue.kind));\n if (blockers.length > 0) {\n const detail = blockers\n .map(\n (issue) => ` - ${issue.message}${issue.remedy === undefined ? \"\" : ` (${issue.remedy})`}`,\n )\n .join(\"\\n\");\n throw new PenvError(\n \"FILL_BLOCKED\",\n `penv fill cannot run: environment ${environment} has ${blockers.length} unresolved ` +\n `configuration ${blockers.length === 1 ? \"issue\" : \"issues\"}:\\n${detail}`,\n \"Fix these — `penv validate` reports them — then run `penv fill`. If you have not written a \" +\n `schema yet, declare the required parameters in ${SCHEMA_SHAPE_FILE}.`,\n );\n }\n\n const written: Array<{ parameter: string; location: string; encrypted: boolean }> = [];\n const skipped: string[] = [];\n const kept: string[] = [];\n const unreachable: Array<{ subject: string; remedy: string }> = [];\n\n for (const drift of validation.drift.declared) {\n // A key outside the name transform's image, or a reserved token: no value\n // file reaches it, so the remedy is a rename, not a value. Prompting here\n // would ask for a file penv would then refuse to write.\n if (drift.ref === undefined) {\n unreachable.push({ subject: drift.subject, remedy: drift.remedy });\n continue;\n }\n\n const ref = drift.ref;\n const key = [...ref.namespace, ref.name].join(\"/\");\n // `secret` stays false: the drift carries no meta, and echo-muting is not a\n // v1 feature. The write below still seals per meta — `runSet` reads it there.\n const value = await options.ask({\n parameter: key,\n environment,\n secret: false,\n optional: false,\n });\n if (value === undefined || value === \"\") {\n skipped.push(drift.subject);\n continue;\n }\n\n const result = await runSet({ cwd: options.cwd, key, value, environment });\n written.push({\n parameter: drift.subject,\n location: result.location,\n encrypted: result.encrypted,\n });\n }\n\n // The optional parameters, asked after the required gaps: the schema excuses\n // their absence, so a blank answer here is a decision to keep the schema's\n // default rather than a gap left open — `kept`, not `skipped`. Asking at all\n // is the point: an override the user never hears about is one they can never\n // choose, and the tag on the prompt is what keeps the choice a free one.\n for (const item of validation.drift.optional) {\n if (item.ref === undefined) {\n unreachable.push({ subject: item.subject, remedy: item.remedy });\n continue;\n }\n\n const ref = item.ref;\n const key = [...ref.namespace, ref.name].join(\"/\");\n const value = await options.ask({\n parameter: key,\n environment,\n secret: false,\n optional: true,\n ...(item.defaultValue === undefined ? {} : { defaultValue: item.defaultValue }),\n });\n if (value === undefined || value === \"\") {\n kept.push(item.subject);\n continue;\n }\n\n const result = await runSet({ cwd: options.cwd, key, value, environment });\n written.push({\n parameter: item.subject,\n location: result.location,\n encrypted: result.encrypted,\n });\n }\n\n return { environment, written, skipped, kept, unreachable };\n}\n\n/** The one line that reports the run's shape when nothing else needs a row. */\nfunction summaryLine(result: FillResult): string {\n const filled = result.written.length;\n if (\n filled === 0 &&\n result.skipped.length === 0 &&\n result.kept.length === 0 &&\n result.unreachable.length === 0\n ) {\n return `${out.green(CHECK)} Nothing to fill for environment ${result.environment}: every declared parameter has a value`;\n }\n const parts = [`${filled} written`];\n if (result.skipped.length > 0) {\n parts.push(`${result.skipped.length} skipped`);\n }\n if (result.kept.length > 0) {\n parts.push(`${result.kept.length} left to the schema's defaults`);\n }\n if (result.unreachable.length > 0) {\n parts.push(`${result.unreachable.length} unreachable`);\n }\n return `${parts.join(\", \")} for environment ${result.environment}`;\n}\n\nexport function renderFill(result: FillResult): string[] {\n const rows: Row[] = result.written.map((entry) => ({\n glyph: CHECK,\n label: \"Wrote\",\n subject: recordPath(entry.location),\n // Meta decided the seal, not the answer, so the line says so — as `set` does.\n ...(entry.encrypted ? { detail: \"encrypted, per the parameter's meta policy\" } : {}),\n }));\n\n // A key no filename reaches is not skipped — it is unwritable until it is\n // renamed, so it carries its rename remedy rather than a value prompt.\n for (const entry of result.unreachable) {\n rows.push({ glyph: WARN, label: \"Unreachable\", subject: entry.subject, detail: entry.remedy });\n }\n\n const lines = formatRows(rows);\n lines.push(summaryLine(result));\n return lines;\n}\n\n/**\n * The prompt's aside: what Enter does. For a required gap it skips; for an\n * optional parameter it keeps whatever the schema declared — named exactly,\n * with the default shown when penv can read it, because \"optional\" alone tells\n * the user a choice exists without telling them what not choosing means. A\n * default too long to sit inside a prompt is elided rather than allowed to push\n * the cursor off the line.\n */\nfunction contextFor(prompt: FillPrompt): string {\n if (!prompt.optional) {\n return `${prompt.environment}, Enter to skip`;\n }\n if (prompt.defaultValue === undefined) {\n return `${prompt.environment} · optional, Enter leaves it unset`;\n }\n const shown =\n prompt.defaultValue.length > 24 ? `${prompt.defaultValue.slice(0, 23)}…` : prompt.defaultValue;\n return `${prompt.environment} · optional, Enter keeps ${shown}`;\n}\n\nexport const fillCommand = defineCommand({\n meta: {\n name: \"fill\",\n description: \"Prompt for each declared parameter the tree has no value for\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to fill\" },\n },\n run({ args }) {\n return guard(async () => {\n const reader = lineReader();\n // TODO: a `prompt.secret` answer still echoes — echo-muting is out of scope\n // for v1. The prompt shows the derived key, so a reader sees the file name\n // their answer becomes. An empty answer skips — the prompt's aside says so,\n // because the skip is a feature and an undiscoverable feature is not one.\n const ask = (prompt: FillPrompt): Promise<string | undefined> =>\n reader.ask(promptLine(prompt.parameter, contextFor(prompt)));\n try {\n write(\n renderFill(\n await runFill({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n ask,\n envFlags: shorthandCandidates(args, [\"env\"]),\n }),\n ),\n );\n } finally {\n reader.close();\n }\n });\n },\n});\n","/**\n * `penv generate` — write a flat `.env` artifact for deploy targets that expect\n * one.\n *\n * The output is an artifact, never an input: invariant 15 makes `.penv/` the\n * source of truth, and a hand-edit here is not absorbed back. Ordering is\n * normalized rather than preserved — one value per file discards the source\n * file's sequence by construction, so `generate` emits a deterministic sorted\n * order and the output is stable and diffable across machines.\n */\n\nimport { writeFileSync } from \"node:fs\";\nimport { isAbsolute, relative, resolve } from \"node:path\";\nimport type { DotenvEntry } from \"@penvhq/core\";\nimport {\n checkNameCollisions,\n effectiveMeta,\n PenvError,\n recordPath,\n requireValue,\n serializeDotenv,\n variableName,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { shorthandCandidates } from \"../env-flags.js\";\nimport type { Project } from \"../project.js\";\nimport {\n keySourceFor,\n localTree,\n openProject,\n refsFrom,\n resolveAllSync,\n targetEnvironment,\n} from \"../project.js\";\nimport { CHECK, formatRows, guard, WARN, write } from \"../ui.js\";\n\nexport const DEFAULT_OUTPUT = \".env\";\n\nexport interface GenerateOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Bare flags the command did not declare — environment shorthands, judged against the whitelist. */\n readonly envFlags?: readonly string[];\n /** Where to write, absolute or relative to `cwd`. Defaults to `.env` at the project root. */\n readonly out?: string;\n /** Permits sealed values to be written into the artifact as plaintext. */\n readonly allowDecrypt?: boolean;\n}\n\nexport interface GenerateResult {\n readonly file: string;\n readonly environment: string;\n readonly entries: number;\n /** How many of them were sealed and are now plaintext in the artifact. */\n readonly decrypted: number;\n}\n\n/**\n * The variables for one environment, and how many of them were sealed.\n *\n * The count is returned rather than discarded because decrypting a secret into a\n * plaintext artifact is the one thing this command does that the user cannot see\n * by looking at the tree. `generate` reports it (invariant 13).\n */\ninterface Artifact {\n readonly entries: DotenvEntry[];\n readonly decrypted: number;\n}\n\nfunction entriesFor(project: Project, environment: string, allowDecrypt: boolean): Artifact {\n const keys = keySourceFor(project, environment);\n const tree = localTree(project);\n const resolutions = resolveAllSync(tree, environment, keys);\n\n // Invariant 12, enforced where the loss would happen: two parameters mapping\n // to one variable would silently drop a value from this file.\n const collision = checkNameCollisions(\n refsFrom(resolutions.map((resolution) => resolution.ref)),\n project.config,\n )[0];\n if (collision !== undefined) {\n throw collision;\n }\n\n const entries: DotenvEntry[] = [];\n let decrypted = 0;\n for (const resolution of resolutions) {\n const winner = resolution.winner;\n if (winner?.file.encrypted === true) {\n // A `.env` is plaintext by construction, so writing a sealed value into one\n // unseals it. penv will do that — the leaving guarantee is that a working\n // `.env` is always reachable — but never as a side effect of a command the\n // user ran for another reason. Asking makes the moment the secret becomes\n // plaintext a moment they chose.\n if (!allowDecrypt) {\n throw new PenvError(\n \"ENCRYPTED_VALUE_REFUSED\",\n `Parameter ${resolution.parameter} for environment ${environment} resolves to the encrypted value file ${recordPath(winner.location)}, and \\`penv generate\\` writes plaintext`,\n `Re-run with \\`--allow-decrypt\\` to write the decrypted value into the artifact, or generate for an environment whose values are plaintext. The artifact is gitignored; a committed plaintext secret is a \\`penv doctor\\` failure.`,\n );\n }\n // Throws when it cannot be opened, naming the reason — never silently\n // omitting the variable, which would produce an artifact that is missing\n // exactly the secret the deploy needs.\n requireValue(resolution, environment);\n decrypted += 1;\n }\n if (resolution.value === undefined) {\n continue;\n }\n // A parameter's description is a comment in the generated file, so the\n // annotation that arrived on import survives the round trip back out.\n const description = effectiveMeta(tree.readMetaSync(resolution.ref), environment).description;\n entries.push({\n key: variableName(resolution.ref, project.config),\n value: resolution.value,\n ...(typeof description === \"string\" ? { description } : {}),\n });\n }\n\n // Sorted by the generated variable, which is what a reader of this file sees.\n entries.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));\n return { entries, decrypted };\n}\n\n/** The `.env` text for one environment — what `penv generate` writes. */\nexport function generateDotenv(options: Omit<GenerateOptions, \"out\">): string {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n return serializeDotenv(entriesFor(project, environment, options.allowDecrypt === true).entries);\n}\n\nexport function runGenerate(options: GenerateOptions): GenerateResult {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment, options.envFlags);\n const { entries, decrypted } = entriesFor(project, environment, options.allowDecrypt === true);\n\n // `--out` is the caller's path, so it is relative to where they are standing;\n // the default artifact belongs next to the config it was generated from.\n const file =\n options.out === undefined\n ? resolve(project.root, DEFAULT_OUTPUT)\n : isAbsolute(options.out)\n ? options.out\n : resolve(options.cwd, options.out);\n\n writeFileSync(file, serializeDotenv(entries), \"utf8\");\n return { file, environment, entries: entries.length, decrypted };\n}\n\n/** The artifact's path as the caller would type it, when it is below them. */\nfunction displayPath(cwd: string, file: string): string {\n const rel = relative(cwd, file);\n return rel === \"\" || rel.startsWith(\"..\") ? file : rel.split(\"\\\\\").join(\"/\");\n}\n\nexport function renderGenerate(result: GenerateResult, cwd: string): string[] {\n const rows = [\n {\n glyph: CHECK,\n label: \"Generated\",\n subject: displayPath(cwd, result.file),\n detail: `${result.entries} variables for environment ${result.environment}`,\n },\n ];\n // A secret that was sealed a moment ago and is plaintext now is worth a line of\n // its own. The artifact is gitignored, which is a reason it is safe to write —\n // not a reason to write it quietly.\n if (result.decrypted > 0) {\n rows.push({\n glyph: WARN,\n label: \"Decrypted\",\n subject: `${result.decrypted} ${result.decrypted === 1 ? \"secret\" : \"secrets\"}`,\n detail: \"written as plaintext into the artifact\",\n });\n }\n return formatRows(rows);\n}\n\nexport const generateCommand = defineCommand({\n meta: { name: \"generate\", description: \"Write a standard .env artifact for deploy targets\" },\n args: {\n env: { type: \"string\", description: \"The environment to generate for\" },\n out: { type: \"string\", description: \"Where to write, instead of .env\" },\n \"allow-decrypt\": {\n type: \"boolean\",\n description: \"Write encrypted values into the artifact as plaintext\",\n },\n },\n run({ args }) {\n return guard(async () => {\n const cwd = process.cwd();\n const result = runGenerate({\n cwd,\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.out === undefined ? {} : { out: args.out }),\n ...(args[\"allow-decrypt\"] === undefined ? {} : { allowDecrypt: args[\"allow-decrypt\"] }),\n envFlags: shorthandCandidates(args, [\"env\", \"out\", \"allow-decrypt\", \"allowDecrypt\"]),\n });\n write(renderGenerate(result, cwd));\n });\n },\n});\n","/**\n * `penv get <key>` — read a parameter, or explain which file wins and why.\n *\n * Fallback is never silent, and neither is precedence: `--explain` prints every\n * candidate in the order the cascade considered them, so a value quietly coming\n * from a shared default has nowhere to hide.\n */\n\nimport { PenvError, recordPath, requireValue, resolveParameter } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { keySourceFor, openProject, refFromKey, targetEnvironment } from \"../project.js\";\nimport { out } from \"../style.js\";\nimport { CROSS, columns, guard, write } from \"../ui.js\";\n\nexport interface GetOptions {\n readonly cwd: string;\n readonly key: string;\n readonly environment?: string;\n}\n\nexport interface GetExplanation {\n readonly parameter: string;\n readonly environment: string;\n /** `undefined` when no candidate was present. */\n readonly location: string | undefined;\n /**\n * Why the winning file did not open, when it is `.enc` and did not.\n *\n * A winner that cannot be decrypted is not a skipped candidate — it won, and\n * the cascade is over. Reporting it as a skip would say a lower scope should\n * have been reached, which is the scope-widening answer the cascade refuses.\n */\n readonly undecryptable?: string;\n readonly candidates: readonly GetCandidate[];\n}\n\nexport interface GetCandidate {\n readonly location: string;\n readonly present: boolean;\n readonly wins: boolean;\n /** Why a present candidate did not win, or why it was never considered. */\n readonly skipped: string | undefined;\n}\n\n/**\n * The value, or a named error.\n *\n * `requireValue` answers first, so a winner that exists but did not decrypt is\n * reported as undecryptable rather than as absent. Only a genuine absence — no\n * candidate at any scope — reaches the refusal below, which is what keeps `penv\n * set` from being offered as the fix for a secret the user still has.\n */\nexport async function runGet(options: GetOptions): Promise<string> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment);\n const ref = refFromKey(options.key);\n\n const keys = keySourceFor(project, environment);\n const resolution = await resolveParameter(ref, environment, project.provider, keys);\n const value = requireValue(resolution, environment);\n if (value === undefined) {\n throw new PenvError(\n \"PARAMETER_ABSENT\",\n `Parameter ${resolution.parameter} resolves to no value for environment ${environment}`,\n `Set it with \\`penv set ${options.key} --env ${environment}\\`, or run \\`penv get ${options.key} --env ${environment} --explain\\` to see every file penv looked at.`,\n );\n }\n return value;\n}\n\nfunction skipReason(reason: string | undefined): string | undefined {\n if (reason === \"lower-precedence\") {\n // Not \"a more specific scope wins\". Within one scope the plaintext file is\n // considered before its `.enc` twin, so the file that beat this one is\n // sometimes at the *same* scope — and a reader told the winner was more\n // specific would go looking for a scope that does not exist.\n return \"skipped, a higher-precedence file wins\";\n }\n if (reason === \"local-skipped-in-test\") {\n return \"skipped, .local never applies in test\";\n }\n return undefined;\n}\n\n/**\n * Which file wins, and why — never a value, so this must not be stopped by the\n * winner being unreadable. Core describes an `.enc` winner rather than refusing\n * it, so `--explain` is the same walk every other command does.\n */\nexport async function runExplain(options: GetOptions): Promise<GetExplanation> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment);\n const ref = refFromKey(options.key);\n\n const keys = keySourceFor(project, environment);\n const resolution = await resolveParameter(ref, environment, project.provider, keys);\n const winner = resolution.winner;\n\n return {\n parameter: resolution.parameter,\n environment,\n location: winner === undefined ? undefined : winner.location,\n ...(resolution.undecryptable === undefined\n ? {}\n : { undecryptable: resolution.undecryptable.detail }),\n candidates: resolution.candidates.map((candidate) => ({\n location: candidate.location,\n present: candidate.present,\n wins: candidate === winner,\n skipped: skipReason(candidate.skippedReason),\n })),\n };\n}\n\nexport function renderExplain(explanation: GetExplanation): string[] {\n const target = explanation.location === undefined ? \"nothing\" : recordPath(explanation.location);\n\n // Candidates stay in the order the cascade considered them: the answer to\n // \"why this file\" is the list above it that did not win. The winner is the one\n // line in color; everything that lost is metadata and reads dimmed.\n const rows = explanation.candidates.map((candidate) => [\n candidate.wins ? candidate.location : out.dim(candidate.location),\n candidate.wins\n ? out.green(\"present, wins\")\n : out.dim(\n candidate.present ? (candidate.skipped ?? \"present\") : (candidate.skipped ?? \"absent\"),\n ),\n ]);\n\n return [\n `${out.bold(explanation.parameter)} resolves to ${target} for environment ${explanation.environment}`,\n ...(explanation.undecryptable === undefined\n ? []\n : [` ${out.red(CROSS)} penv cannot decrypt it: ${explanation.undecryptable}`]),\n \"\",\n ...columns(rows).map((line) => ` ${line}`),\n ];\n}\n\nexport const getCommand = defineCommand({\n meta: { name: \"get\", description: \"Read a parameter\" },\n args: {\n key: { type: \"positional\", required: true, description: \"The parameter, e.g. redis/password\" },\n env: { type: \"string\", description: \"The environment to read\" },\n explain: { type: \"boolean\", description: \"Print which file wins, and why\" },\n },\n run({ args }) {\n return guard(async () => {\n const options: GetOptions = {\n cwd: process.cwd(),\n key: args.key,\n ...(args.env === undefined ? {} : { environment: args.env }),\n };\n if (args.explain === true) {\n write(renderExplain(await runExplain(options)));\n return;\n }\n write([await runGet(options)]);\n });\n },\n});\n","/**\n * `penv import <file>` — adopt an existing dotenv file.\n *\n * Invariant 15: this is one-directional. After it runs, `.penv/` is the source of\n * truth and `.env` is an artifact `penv generate` writes; there is no reverse\n * sync of hand-edits back out of the generated file.\n *\n * It takes one file; `penv init` takes a whole cascade in one cutover. The\n * checks and the write they share live in `adopt.ts`.\n *\n * Scope, unlike namespace, *is* readable from the source: the filename says it,\n * in the four-level vocabulary invariant 4 adopts wholesale. `.env.production`\n * carries `production` the way `.env` carries nothing, so import reads it rather\n * than flattening it — a `.env.development.local` written to the unscoped default\n * would serve every environment, and one developer's machine would become\n * production's fallback.\n *\n * `--env` is the other half of that reading. A file the filename says nothing\n * about — `prod-secrets.txt`, or a plain `.env` the user is adopting as one\n * environment's values — has its scope named by the flag instead, because \"these\n * are production's values\" is what `--env production` means at an import. Only a\n * file that names neither is the unscoped default.\n */\n\nimport { copyFileSync, existsSync, readFileSync } from \"node:fs\";\nimport { basename, isAbsolute, relative, resolve } from \"node:path\";\nimport type { PenvConfig, Scope } from \"@penvhq/core\";\nimport {\n assertNever,\n environmentNames,\n FilenameGrammarError,\n findConfigFile,\n loadConfigFrom,\n lookupEnvironment,\n PenvError,\n parseDotenv,\n schemaFileOf,\n UnknownEnvironmentError,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { assertNoCollisions, refsForEntries, writeEntries } from \"../adopt.js\";\nimport { detectAlias } from \"../detect.js\";\nimport { draftFields } from \"../draft-schema.js\";\nimport { localTree, openProject } from \"../project.js\";\nimport { CHECK, formatSteps, guard, type Step, WARN, write } from \"../ui.js\";\nimport type { InitDecisions, InitStep } from \"./init.js\";\nimport { planInit, scaffold, writeConfigFile } from \"./init.js\";\nimport type { ValidateResult } from \"./validate.js\";\nimport { renderValidate, runValidate } from \"./validate.js\";\n\nexport interface ImportOptions {\n readonly cwd: string;\n /** The dotenv file to adopt, absolute or relative to `cwd`. */\n readonly file: string;\n /**\n * `--env`. It reads as \"these are <environment>'s values\", so for a file whose\n * name carries no environment it names the *scope* as well as the environment\n * to run against: `penv import prod-secrets.txt --env production` writes\n * `<name>.production`, and `--env production` on `.env.local` writes\n * `<name>.production.local`. The filename supplies both when it carries an\n * environment, so the flag is needed only for a file that does not — and\n * contradicting the filename is an error rather than a silent choice between\n * the two.\n */\n readonly environment?: string;\n}\n\nexport interface ImportReport {\n readonly root: string;\n readonly file: string;\n readonly backup: string;\n /** The scope the source named — filename, `--env`, or both — and the scope every value was written at. */\n readonly scope: Scope;\n /**\n * The environment the import ran against, or `undefined` when none is set.\n *\n * Undefined only ever accompanies the unscoped default: any other scope names\n * an environment, so it always has one. It means the values were written and\n * the closing validation was skipped, which the output states.\n */\n readonly environment: string | undefined;\n /** The declared environments, so a skipped validation can name one to pass. */\n readonly environments: readonly string[];\n readonly variables: number;\n /**\n * Comment blocks that belonged to no variable. Reported rather than discarded\n * silently: a file header has no parameter to describe, but that is not a\n * reason to pretend it was never there.\n */\n readonly orphanComments: number;\n readonly steps: readonly InitStep[];\n}\n\nconst BACKUP_SUFFIX = \".backup\";\n\n/** The segment that starts a dotenv filename's scope. `.env`, `.env.production`. */\nconst DOTENV_SEGMENT = \"env\";\nconst LOCAL = \"local\";\n\n/**\n * Invariant 10: a segment is an environment because `penv.config.ts` declares\n * it, never because it looks like one. This matches the whitelist — the thing\n * the invariant permits — and refuses everything else.\n *\n * Refusing is the whole point. Falling back to the unscoped default for an\n * undeclared segment is precisely the leak: `.env.staging` in a project that\n * never declared `staging` would become the value every environment reads.\n */\nfunction assertDeclared(segment: string, config: PenvConfig): string {\n const declared = environmentNames(config);\n if (declared.includes(segment)) {\n return segment;\n }\n throw new UnknownEnvironmentError(segment, declared);\n}\n\n/**\n * The scope the source filename names, in the vocabulary invariant 4 shares with\n * Next.js and Vite: `.env` > unscoped, `.env.<env>`, `.env.local`, and\n * `.env.<env>.local`.\n *\n * Parsing starts at the first `env` segment, because `import` reads whatever\n * file it is pointed at and the basename may carry a prefix. A file with no\n * `env` segment at all is the plain-`.env` case — there is no scope written on\n * it, so there is none to read, and the unscoped default is what it means.\n */\nfunction scopeFromFilename(file: string, config: PenvConfig): Scope {\n const name = basename(file);\n const segments = name.split(\".\");\n const start = segments.indexOf(DOTENV_SEGMENT);\n if (start === -1) {\n return { kind: \"unscoped\" };\n }\n\n const rest = segments.slice(start + 1).filter((segment) => segment.length > 0);\n const first = rest[0];\n const second = rest[1];\n\n if (first === undefined) {\n return { kind: \"unscoped\" };\n }\n\n if (second === undefined) {\n if (first === LOCAL) {\n return { kind: LOCAL };\n }\n return { kind: \"environment\", environment: assertDeclared(first, config) };\n }\n\n if (rest.length === 2 && second === LOCAL && first !== LOCAL) {\n return { kind: \"environment-local\", environment: assertDeclared(first, config) };\n }\n\n // The order is fixed at both ends of the import: the environment precedes\n // `local` in the dotenv filename this reads and in the value filename it\n // writes, so `.env.local.production` is an error rather than a synonym.\n if (first === LOCAL && rest.length === 2) {\n throw new FilenameGrammarError(\n name,\n \"`local` precedes the environment segment\",\n `The environment segment always precedes \\`local\\` — \\`.env.${second}.${LOCAL}\\` is the ` +\n `file Next.js and Vite read, and \\`.env.${LOCAL}.${second}\\` is not a synonym for it. ` +\n `Rename it to \\`.env.${second}.${LOCAL}\\`, then import it again. Nothing was imported.`,\n );\n }\n\n throw new FilenameGrammarError(\n name,\n `\\`${rest.join(\"` and `\")}\\` are ${rest.length} scope segments`,\n \"A dotenv file carries exactly one scope: `.env`, `.env.<environment>`, `.env.local`, or \" +\n \"`.env.<environment>.local`. Point `penv import` at one of those. Nothing was imported.\",\n );\n}\n\n/**\n * The environment a scope names, or `undefined` when it names none.\n *\n * The `default` is load-bearing rather than ceremonial: a fifth scope carrying\n * an environment would otherwise report `undefined` here, and import would fall\n * back to `--env` — silently widening exactly the way the three-level cascade did.\n */\nfunction environmentOf(scope: Scope): string | undefined {\n switch (scope.kind) {\n case \"environment\":\n case \"environment-local\":\n return scope.environment;\n case \"unscoped\":\n case \"local\":\n return undefined;\n default:\n return assertNever(scope, \"scope\");\n }\n}\n\n/**\n * The scope `--env <environment>` names, given the scope the filename named.\n *\n * `--env` reads as \"these are <environment>'s values\", so it names a scope and\n * not merely a validation target. Deriving the scope from the filename alone was\n * the scope-widening leak: `penv import prod-secrets.txt --env production` wrote\n * the unscoped default, and `development` read the production secret.\n *\n * A filename that already names an environment keeps its scope untouched: by the\n * time this runs the two agree, because a contradiction is an error. `.env.local`\n * names a scope but no environment, so the two compose — the filename says\n * personal override, `--env` says which environment it overrides, and together\n * they are `.env.<environment>.local`.\n */\nfunction scopeWithEnvironment(scope: Scope, environment: string): Scope {\n switch (scope.kind) {\n case \"unscoped\":\n return { kind: \"environment\", environment };\n case LOCAL:\n return { kind: \"environment-local\", environment };\n case \"environment\":\n case \"environment-local\":\n return scope;\n default:\n return assertNever(scope, \"scope\");\n }\n}\n\n/**\n * `--env`, normalized the way `resolveEnvironment` normalizes it — but a flag\n * that is present and blank is refused rather than normalized away.\n *\n * `--env \"$ENVIRONMENT\"` with the variable unset arrives here as `\"\"`. Reading\n * that as \"no `--env`\" silently demotes the scope the user asked for to the\n * unscoped default, so `penv import prod-secrets.txt --env \"\"` writes the\n * production secret to the file every environment falls back to — the leak this\n * flag exists to close, through a quieter door. An absent flag still means the\n * unscoped default: that is the user declining to name a scope, not failing to.\n */\nfunction explicitEnvironment(options: ImportOptions, source: string, config: PenvConfig): string {\n const value = options.environment?.trim() ?? \"\";\n if (value.length > 0) {\n return value;\n }\n throw new PenvError(\n \"IMPORT_ENV_FLAG_EMPTY\",\n `\\`--env\\` for the import of ${source} names no environment`,\n `Pass a declared environment — ${environmentNames(config)\n .map((e) => `\\`${e}\\``)\n .join(\", \")} — e.g. ` +\n `\\`--env production\\`, or drop \\`--env\\` to import ${source} as the scope that has no ` +\n `environment. Nothing was imported.`,\n );\n}\n\n/**\n * `penv import .env.production --env development` names two environments and\n * means one of them. penv cannot know which, and both readings are destructive:\n * honouring `--env` validates the wrong environment, honouring the filename\n * ignores what the user typed. It says so instead of choosing.\n */\nfunction assertEnvironmentAgrees(\n derived: string | undefined,\n explicit: string | undefined,\n source: string,\n): void {\n if (derived === undefined || explicit === undefined || derived === explicit) {\n return;\n }\n throw new PenvError(\n \"IMPORT_ENV_CONFLICT\",\n `The file ${source} is scoped to environment ${derived}, but \\`--env ${explicit}\\` names ${explicit}`,\n `Drop \\`--env\\` to import ${source} as ${derived}, pass \\`--env ${derived}\\` to say the same ` +\n `thing twice, or point \\`penv import\\` at the file that holds ${explicit}'s values. ` +\n `Nothing was imported.`,\n );\n}\n\n/**\n * The config `import` must judge names against: the project's own when it has\n * one, and otherwise the one `penv init` writes, since that is the config the\n * scaffold below is about to put in place.\n *\n * Writing it *first* is what lets every name check run before a single value\n * file exists. It is safe to leave behind if a check then fails: it is byte for\n * byte the file `penv init` writes, it holds nothing read out of the `.env`, and\n * it is the file the reserved-token and `override` remedies both tell the user to\n * go and edit.\n */\n/**\n * The environment this run names, read lexically — before any config exists to\n * check it against.\n *\n * `scopeFromFilename` cannot answer this: it validates against the whitelist, and\n * on a greenfield project the whitelist is the thing being written. So the\n * segment is read here without being believed, handed to the scaffold as a\n * declaration, and then checked by the ordinary path like any other.\n *\n * Reading it is not inference. Invariant 10 forbids penv deciding that a file in\n * a tree belongs to an environment nobody declared; this is the user typing\n * `penv import .env.production` and thereby saying which environment the file is\n * for. The command line is a declaration — the only one available on a project\n * that has no config yet.\n */\nfunction environmentNamed(file: string, explicit: string | undefined): string | undefined {\n if (explicit !== undefined && explicit.trim().length > 0) {\n return explicit.trim();\n }\n const segments = basename(file).split(\".\");\n const start = segments.indexOf(DOTENV_SEGMENT);\n if (start === -1) {\n return undefined;\n }\n const first = segments.slice(start + 1).filter((segment) => segment.length > 0)[0];\n return first === undefined || first === LOCAL ? undefined : first;\n}\n\n/**\n * The config to check every name against, scaffolding one when the project has none.\n *\n * Writing it *first* is what lets every name check run before a single value\n * file exists. It is safe to leave behind if a check then fails: it holds\n * nothing read out of the `.env`, and it is the file the reserved-token and\n * `override` remedies both tell the user to go and edit.\n *\n * The scaffold declares the environment this import names, and nothing else.\n * `penv init` refuses to invent environments because it cannot observe a\n * deployment — but here the user has named one, and a config that omitted it\n * would be penv writing a file that makes penv's own next step fail.\n */\ninterface Adoption {\n readonly config: PenvConfig;\n /**\n * What the rest of the scaffold must write, and the reason this is returned\n * rather than recomputed.\n *\n * `scaffold` takes `decisions` with a default, so a caller that forgot them\n * compiled and quietly wrote `DEFAULT_DECISIONS` instead. Import forgot them:\n * the config it wrote said `schemaFile: \"src/env.ts\"` while the schema it\n * scaffolded a moment later went to `.penv/env.ts`, and the two disagreed for\n * exactly as long as the project lived. The optional parameter is what hid it\n * from the compiler; carrying the decisions is what stops the two halves of one\n * scaffold answering the same question differently.\n */\n readonly decisions: InitDecisions;\n}\n\n/** The decisions a config already records. The alias is read from the files that resolve it. */\nfunction decisionsOf(config: PenvConfig, cwd: string): InitDecisions {\n return {\n environments: environmentNames(config),\n // `import` re-scaffolds env.ts for an existing project; injection is an init\n // choice, so it is not turned on here.\n inject: false,\n schemaFile: schemaFileOf(config),\n publicPrefixes: config.publicPrefixes ?? [],\n alias: detectAlias(cwd),\n };\n}\n\nfunction configInEffect(cwd: string, environment: string | undefined): Adoption {\n const existing = findConfigFile(cwd);\n if (existing !== undefined) {\n const config = loadConfigFrom(existing);\n return { config, decisions: decisionsOf(config, cwd) };\n }\n // The same plan `penv init` would make without being asked anything — import\n // is a scaffold too, and two scaffolds that disagreed about where the schema\n // goes would make the answer depend on which command the user reached for.\n const planned = planInit(cwd).decisions;\n const decisions: InitDecisions = {\n ...planned,\n environments: environment === undefined ? planned.environments : [environment],\n };\n writeConfigFile(cwd, decisions);\n return { config: openProject(cwd).config, decisions };\n}\n\n/**\n * Adopts the file: parses it, scaffolds the project, writes one value file per\n * variable and each attached comment into that parameter's meta, and backs the\n * source up. Validation is the caller's next step rather than part of adoption —\n * an inferred schema is a draft, and a draft that needs correcting has still\n * imported every value correctly.\n *\n * Adoption is all or nothing. Every name is checked against the config, and any\n * environment the source names resolved, before the tree is scaffolded or a\n * value written. The two names that fail here fail *destructively*: a reserved\n * name bricks every later command, and a lossy name renames the user's variable\n * behind their back. What the source names is resolved here rather than left to\n * the closing `validate` because a command that writes a tree and *then*\n * discovers it cannot name an environment has already half-adopted the project\n * it just refused. A half-imported tree would be the drift penv exists to\n * remove, introduced by penv itself.\n *\n * An environment nothing names is a different case, and not an error: an\n * unscoped import writes at the unscoped default, which needs no environment.\n * Only the validation that follows needs one, so it is skipped and said to be\n * skipped. Requiring one here would fail `penv import .env` on a greenfield\n * project — the first command the quickstart gives, where no environment could\n * plausibly be set yet — to satisfy a step that is the caller's next one.\n */\nexport function importDotenv(options: ImportOptions): ImportReport {\n const cwd = resolve(options.cwd);\n const file = isAbsolute(options.file) ? options.file : resolve(cwd, options.file);\n if (!existsSync(file)) {\n throw new PenvError(\n \"IMPORT_FILE_MISSING\",\n `There is no file at ${file} to import`,\n \"Point `penv import` at an existing dotenv file, e.g. `penv import .env`.\",\n );\n }\n\n const parsed = parseDotenv(readFileSync(file, \"utf8\"));\n const { config, decisions } = configInEffect(cwd, environmentNamed(file, options.environment));\n const source = displayPath(cwd, file);\n\n const named = scopeFromFilename(file, config);\n const derived = environmentOf(named);\n // Absent means the unscoped default; present-but-blank is refused, never\n // normalized into absent.\n const explicit =\n options.environment === undefined ? undefined : explicitEnvironment(options, source, config);\n assertEnvironmentAgrees(derived, explicit, source);\n // `--env` must reach the scope, not just the environment: reading it into the\n // environment alone is what wrote a production secret to the unscoped default.\n // Invariant 10 first — an undeclared `--env` names no scope to write at.\n const scope =\n explicit === undefined ? named : scopeWithEnvironment(named, assertDeclared(explicit, config));\n // The filename is an environment the user has already stated, so `penv import\n // .env.production` needs no `--env` to mean production. Nothing naming one is\n // the unscoped default's ordinary case, not a failure — the values still have\n // a scope to be written at, and only the closing validate goes without.\n const environment = lookupEnvironment(config, explicit ?? derived);\n\n const refs = refsForEntries(parsed.entries, source, config);\n assertNoCollisions(refs, config);\n\n // Every check has passed, so from here the import runs to completion.\n // The decisions the config was written from, not the defaults: the two halves\n // of one scaffold must not disagree about where the schema lives.\n const steps = scaffold(cwd, draftFields(parsed.entries), true, decisions);\n const project = openProject(cwd);\n const tree = localTree(project);\n\n // A comment sitting directly above a variable describes it, so it becomes that\n // parameter's meta description and `generate` re-emits it as a comment.\n writeEntries(tree, parsed.entries, refs, scope);\n\n const backup = `${file}${BACKUP_SUFFIX}`;\n copyFileSync(file, backup);\n\n return {\n root: project.root,\n file,\n backup,\n scope,\n environment,\n environments: environmentNames(config),\n variables: parsed.entries.length,\n orphanComments: parsed.orphanComments,\n steps,\n };\n}\n\nfunction displayPath(root: string, file: string): string {\n const rel = relative(root, file);\n return rel === \"\" || rel.startsWith(\"..\") ? file : rel.split(\"\\\\\").join(\"/\");\n}\n\n/**\n * Invariant 2 kept the user's `env.ts`; invariant 13 says so out loud.\n *\n * `penv init` then `penv import` is the ordinary path, and it lands here: the\n * schema penv scaffolded is an empty `z.object({})`, the draft that would have\n * declared the imported parameters is not written, and the closing `validate`\n * passes — an empty object validates against an empty schema. A ✓ on that line\n * reports a project where nothing is declared as a project that is fine.\n *\n * The count is every imported parameter, because penv declared none of them: it\n * did not write the draft, and it does not read the user's schema to guess which\n * ones they had already declared themselves.\n */\nfunction keptSchemaStep(step: InitStep, variables: number): Step {\n const plural = variables === 1 ? \"parameter\" : \"parameters\";\n return {\n glyph: WARN,\n // The step's own text, which names the file that was actually kept. This\n // line rebuilt it from a hardcoded `.penv/env.ts`, so a project whose schema\n // lives in `src/` was told penv had kept a file it does not have — the one\n // line whose whole job is \"your schema is untouched\" naming the wrong\n // schema. Only the glyph and the note are this function's business.\n text: step.text,\n note: `(yours — ${variables} imported ${plural} undeclared, draft schema skipped)`,\n };\n}\n\n/**\n * Invariant 13: the validation that did not run says so.\n *\n * A skipped check and a passed check must never look alike — the import wrote\n * every value, so a silent skip would read as a validated tree. The remedy names\n * a declared environment because the user has not chosen one yet; that is the\n * whole reason this line exists.\n */\nfunction skippedValidationStep(environments: readonly string[]): Step {\n const example = environments[0] ?? \"<environment>\";\n return {\n glyph: WARN,\n text: \"Skipped validation\",\n note: `(no environment set — run \\`penv validate --env ${example}\\`)`,\n };\n}\n\nexport function renderImport(\n result: ImportReport,\n validation: ValidateResult | undefined,\n): string[] {\n const steps: Step[] = [{ glyph: CHECK, text: `Found ${result.variables} variables` }];\n\n // Dropped, but never silently: a comment attached to nothing has no parameter\n // to belong to, and how many there were is the user's to know.\n if (result.orphanComments > 0) {\n const plural = result.orphanComments === 1 ? \"comment\" : \"comments\";\n steps.push({\n glyph: WARN,\n text: `Dropped ${result.orphanComments} orphan ${plural}`,\n note: \"attached to no variable, so nothing to describe\",\n });\n }\n\n for (const step of result.steps) {\n if (step.target === \"schema\" && step.action === \"kept\") {\n steps.push(keptSchemaStep(step, result.variables));\n continue;\n }\n // A conflicted step is the one init reports that is not a success — the same\n // reason it wears a warning there.\n const glyph = step.action === \"conflicted\" ? WARN : CHECK;\n steps.push(\n step.note === undefined\n ? { glyph, text: step.text }\n : { glyph, text: step.text, note: step.note },\n );\n }\n steps.push({ glyph: CHECK, text: `Created ${displayPath(result.root, result.backup)}` });\n\n const lines = formatSteps(steps);\n if (validation === undefined) {\n lines.push(...formatSteps([skippedValidationStep(result.environments)]));\n } else if (validation.ok) {\n lines.push(...formatSteps([{ glyph: CHECK, text: \"Validated configuration\" }]));\n } else {\n lines.push(...renderValidate(validation));\n }\n\n lines.push(\"\", \"Done. The records tree is now your source of truth.\");\n return lines;\n}\n\nexport const importCommand = defineCommand({\n meta: {\n name: \"import\",\n description: \"Import an existing dotenv file; it becomes the source of truth\",\n },\n args: {\n file: {\n type: \"positional\",\n required: true,\n description: \"The dotenv file to import, e.g. .env\",\n },\n env: {\n type: \"string\",\n description:\n \"The environment these are the values of; scopes them to it. The filename supplies it \" +\n \"when it carries one\",\n },\n },\n run({ args }) {\n return guard(async () => {\n const cwd = process.cwd();\n const report = importDotenv({\n cwd,\n file: args.file,\n ...(args.env === undefined ? {} : { environment: args.env }),\n });\n // The environment `import` already resolved, so the closing validate cannot\n // target a different one than the values were just written for. Without one\n // there is nothing to validate against, and the render says it was skipped.\n const validation =\n report.environment === undefined\n ? undefined\n : await runValidate({ cwd, environment: report.environment });\n write(renderImport(report, validation));\n });\n },\n});\n","/**\n * Turning dotenv variables into penv records — the checks that must pass before\n * a single value file is written, and the write itself.\n *\n * Two commands adopt: `penv import` takes one file, `penv init` takes a whole\n * cascade in one all-or-nothing cutover. They share this module because the two\n * names that fail here fail *destructively* — a reserved name bricks every later\n * command, and a lossy name renames the user's variable behind their back — and\n * two implementations of \"is this variable adoptable\" would eventually let one\n * command write what the other refuses.\n *\n * Import creates flat parameters. `refFromVariable` never infers a namespace,\n * because a flat `.env` carries no structure to read: `REDIS_PASSWORD` cannot say\n * whether it came from `redis/password` or `redis-password`. Namespacing is a\n * deliberate refactor afterwards, not a guess made during adoption.\n */\n\nimport type { DotenvEntry, Meta, ParameterRef, PenvConfig, Scope } from \"@penvhq/core\";\nimport {\n checkNameCollisions,\n isReservedToken,\n PenvError,\n ReservedTokenError,\n refFromVariable,\n roundTripsCleanly,\n variableName,\n} from \"@penvhq/core\";\nimport type { FilesystemProvider } from \"@penvhq/provider-filesystem\";\n\n/**\n * Filenames are split on `.`, so a variable that becomes a dotted name would\n * parse back as a scope segment rather than the parameter it came from.\n */\nfunction assertImportable(ref: ParameterRef, variable: string): void {\n if (!ref.name.includes(\".\")) {\n return;\n }\n throw new PenvError(\n \"IMPORT_UNPARSEABLE_NAME\",\n `The variable ${variable} becomes the parameter \\`${ref.name}\\`, whose \\`.\\` would be read as a scope`,\n `Filenames are split on \\`.\\`. Rename ${variable} in the source file, then import it again.`,\n );\n}\n\n/**\n * Invariant 11: `enc`, `json`, `toml`, `yml`, `local`, and every declared\n * environment are reserved, and a collision is an error rather than a warning.\n *\n * A written `.penv/state/records/enc` does not merely import badly — it re-parses as a scope\n * segment, so every later `list()` throws and `get`, `generate`, `validate`, and\n * even `remove` stop working. The project can only be repaired by deleting the\n * file by hand, which is why this runs before anything is written rather than\n * leaving `penv validate` to report the wreckage afterwards.\n *\n * The error names the *variable*, not the parameter: the user is reading their\n * `.env`, where the line says `ENC=`, and `enc` is penv's word for it.\n */\nfunction assertNotReserved(\n ref: ParameterRef,\n variable: string,\n where: string,\n config: PenvConfig,\n): void {\n if (isReservedToken(ref.name, config)) {\n throw new ReservedTokenError(\"parameter\", variable, where);\n }\n}\n\n/**\n * The v0.1 gate: every variable survives `import` then `generate` unchanged,\n * *modulo declared name overrides*.\n *\n * `MY-VAR` imports to the parameter `my-var` and regenerates as `MY_VAR`, so the\n * application's `process.env[\"MY-VAR\"]` reads `undefined` after a round trip. A\n * flat `.env` cannot tell `MY-VAR` from `MY_VAR` once both collapse to one\n * parameter, so no escape scheme rescues it — the honest move is to refuse. An\n * explicit `override` entry is the exception the gate allows: it makes the\n * generated name a stated decision instead of an accident. Silence does not.\n */\nfunction assertRoundTrips(ref: ParameterRef, variable: string, config: PenvConfig): void {\n if (roundTripsCleanly(variable)) {\n return;\n }\n // The declared override the gate's \"modulo\" clause means. Checked against the\n // real transform, so an override that does not actually restore the variable\n // is not mistaken for one that does.\n if (variableName(ref, config) === variable) {\n return;\n }\n const generated = variableName(ref, config);\n throw new PenvError(\n \"IMPORT_LOSSY_NAME\",\n `The variable ${variable} becomes the parameter \\`${ref.name}\\`, which regenerates as ${generated}`,\n `\\`penv generate\\` would write ${generated}, so anything reading ` +\n `\\`process.env[\"${variable}\"]\\` would read \\`undefined\\`. Declare the name you want in the ` +\n `\\`override\\` block of penv.config.ts — \\`override: { \"${ref.name}\": \"${variable}\" }\\` — then ` +\n `import it again. Nothing was imported.`,\n );\n}\n\n/**\n * Every entry's parameter, with every name check already passed — or the first\n * refusal, thrown before anything is written. `where` is the source as the user\n * typed it, because that is the file they will go and edit.\n */\nexport function refsForEntries(\n entries: readonly DotenvEntry[],\n where: string,\n config: PenvConfig,\n): ParameterRef[] {\n const refs: ParameterRef[] = [];\n for (const entry of entries) {\n const ref = refFromVariable(entry.key);\n assertImportable(ref, entry.key);\n assertNotReserved(ref, entry.key, where, config);\n assertRoundTrips(ref, entry.key, config);\n refs.push(ref);\n }\n return refs;\n}\n\n/** Invariant 12: two parameters mapping to one variable is an error, never last-write-wins. */\nexport function assertNoCollisions(refs: readonly ParameterRef[], config: PenvConfig): void {\n const first = checkNameCollisions(refs, config)[0];\n if (first !== undefined) {\n throw first;\n }\n}\n\n/**\n * Writes one file's variables into the tree at `scope`, with each attached\n * comment becoming that parameter's meta description so `penv generate` can\n * re-emit it.\n */\nexport function writeEntries(\n tree: FilesystemProvider,\n entries: readonly DotenvEntry[],\n refs: readonly ParameterRef[],\n scope: Scope,\n): void {\n for (const [index, entry] of entries.entries()) {\n const ref = refs[index];\n if (ref === undefined) {\n continue;\n }\n tree.writeSync(\n { namespace: ref.namespace, name: ref.name, scope, encrypted: false },\n entry.value,\n );\n if (entry.description !== undefined) {\n const meta: Meta = { ...tree.readMetaSync(ref), description: entry.description };\n tree.writeMetaSync(ref, meta);\n }\n }\n}\n","/**\n * What the codebase already says about itself.\n *\n * `penv init` asks a human to confirm a plan, and a plan the human has to fill\n * in from scratch is an interrogation. So penv reads the two facts it can\n * observe — the framework in `package.json`, and whether a `src/` directory\n * exists — and offers them as a suggestion.\n *\n * The line this module does not cross: a framework is an identity, never a\n * config key. Nothing here is written to `penv.config.ts` as `framework: \"next\"`\n * — the answers become concrete decisions (`schemaFile`, `publicPrefixes`) that\n * mean the same thing in a year, when the project has been rewritten twice and\n * penv would otherwise still be reinterpreting a name it read once.\n *\n * Everything here is a suggestion. The one thing that is never suggested is an\n * environment: deployment topology is not in `package.json`, and invariant 10\n * forbids inferring it.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { DEFAULT_SCHEMA_FILE } from \"@penvhq/core\";\n\n/** A framework penv recognised, and what it implies about a project's layout. */\nexport interface Detected {\n /** The framework's own name, as a human writes it — `\"Next.js\"`. */\n readonly name: string;\n /** Where this framework's projects keep their modules, relative to the root. */\n readonly schemaFile: string;\n /**\n * The conventional path penv stepped aside from, because a module that is not\n * penv's schema already lives there. Set only when it happened, so the plan can\n * say why the schema is not where the convention would have put it.\n */\n readonly displacedFrom?: string;\n /** The prefixes this framework inlines into its client bundle. */\n readonly publicPrefixes: readonly string[];\n}\n\n/**\n * One framework's signature. `packages` is checked against dependencies and\n * devDependencies alike: a framework is a framework wherever it was installed,\n * and the two lists disagree often enough that reading one is reading half.\n */\ninterface Signature {\n readonly name: string;\n readonly packages: readonly string[];\n readonly publicPrefixes: readonly string[];\n}\n\n/**\n * Ordered most specific first: TanStack Start is Vite underneath and Next.js\n * projects carry Vite for their tests, so a signature that matches a framework's\n * *foundation* must never answer before the framework itself does.\n *\n * Remix and React Router 7 are deliberately absent. Their public-variable story\n * is not one prefix, and a guess here is worse than the fallback: the fallback\n * is reported and asks, while a wrong prefix silently arms the one `doctor`\n * check that exists to keep a secret out of a browser bundle.\n */\nconst SIGNATURES: readonly Signature[] = [\n { name: \"Next.js\", packages: [\"next\"], publicPrefixes: [\"NEXT_PUBLIC_\"] },\n { name: \"SvelteKit\", packages: [\"@sveltejs/kit\"], publicPrefixes: [\"PUBLIC_\"] },\n { name: \"Nuxt\", packages: [\"nuxt\"], publicPrefixes: [\"NUXT_PUBLIC_\"] },\n {\n name: \"TanStack Start\",\n packages: [\"@tanstack/react-start\", \"@tanstack/start\"],\n publicPrefixes: [\"VITE_\"],\n },\n { name: \"Astro\", packages: [\"astro\"], publicPrefixes: [\"PUBLIC_\"] },\n { name: \"Vite\", packages: [\"vite\"], publicPrefixes: [\"VITE_\"] },\n];\n\n/**\n * Whether the module at `file` looks like it exports penv's schema.\n *\n * A scan, not a parse, and deliberately conservative in one direction: it can\n * fail to recognise an exotic re-export and say \"no\", which costs a note and a\n * different filename. It cannot invent a `schema` that is not written down, so it\n * never claims someone else's module is penv's.\n *\n * The question this answers is not \"does the file exist\". `src/env.ts` existing\n * is the common case on a re-run — it is the schema penv wrote, and keeping it is\n * invariant 2 working. The question is whether the file at the path penv wants is\n * *penv's*, because the alternative is penv choosing a path already occupied by\n * someone else's module and then reporting, later and from somewhere else, that\n * it exports no schema.\n */\nfunction exportsSchema(file: string): boolean {\n let source: string;\n try {\n source = readFileSync(file, \"utf8\");\n } catch {\n return false;\n }\n return (\n // `export const schema = z.object({ ... })` — what penv scaffolds.\n /export\\s+(?:const|let|var)\\s+schema\\b/.test(source) ||\n // `export { schema }`, `export { shape as schema }`.\n /export\\s*\\{[^}]*\\bschema\\b[^}]*\\}/.test(source)\n );\n}\n\n/** True when something that is not penv's schema already lives at `relative`. */\nfunction occupied(cwd: string, relative: string): boolean {\n const file = join(cwd, ...relative.split(\"/\"));\n return existsSync(file) && !exportsSchema(file);\n}\n\n/**\n * Where a framework's projects keep the schema — and where penv puts it instead\n * when that address is already someone else's.\n *\n * `src/env.ts` is the convention and it is also a name projects already use for\n * their own env module. Proposing it regardless is how penv came to scaffold\n * around a file it could not use: it kept the user's module (invariant 2, right),\n * then `validate` failed with \"src/env.ts exports no `schema`\" — a complaint\n * about a path penv itself had chosen.\n *\n * Stepping aside is not a guess. The file being there, and not exporting a\n * schema, is a fact about the codebase — the kind penv may default from, because\n * a wrong answer is visible in the plan and writes nothing over anything.\n */\nexport function schemaFileFor(cwd: string): { file: string; displaced?: string } {\n const dir = srcPrefix(cwd);\n const preferred = `${dir}env.ts`;\n if (!occupied(cwd, preferred)) {\n return { file: preferred };\n }\n\n const beside = `${dir}penv-env.ts`;\n if (!occupied(cwd, beside)) {\n return { file: beside, displaced: preferred };\n }\n // Both names taken by modules that are not penv's. `.penv/` is penv's own\n // directory, so it is the one address no other tool has a claim on.\n return { file: DEFAULT_SCHEMA_FILE, displaced: preferred };\n}\n\n/**\n * Every dependency name the manifest declares, or `undefined` when there is no\n * manifest to read. An unreadable or malformed `package.json` answers the same\n * way an absent one does — \"I cannot tell\" — because init's fallback is correct\n * and reported, while a parse error thrown from a suggestion would fail a\n * command that had not yet asked the user anything.\n */\n/**\n * `\"src/\"` when the project keeps its modules under `src/`, else `\"\"` — the one\n * fact both the schema location and a framework's seam file key off, read in one\n * place so the two cannot disagree about whether a project uses `src/`.\n */\nexport function srcPrefix(cwd: string): string {\n return existsSync(join(cwd, \"src\")) ? \"src/\" : \"\";\n}\n\nfunction dependenciesOf(cwd: string): ReadonlySet<string> | undefined {\n const manifest = manifestOf(cwd);\n if (manifest === undefined) {\n return undefined;\n }\n\n const names = new Set<string>();\n for (const field of [\"dependencies\", \"devDependencies\"] as const) {\n const block: unknown = manifest[field];\n if (block !== null && typeof block === \"object\" && !Array.isArray(block)) {\n for (const name of Object.keys(block)) {\n names.add(name);\n }\n }\n }\n return names;\n}\n\n/**\n * The project's manifest, or `undefined` when there is nothing readable to read.\n *\n * An absent or unparseable `package.json` is not an error here: detection's whole\n * contract is that it may answer \"I cannot tell\", and a project penv is asked to\n * scaffold before its manifest exists is a project, not a mistake.\n */\nfunction manifestOf(cwd: string): Readonly<Record<string, unknown>> | undefined {\n const file = join(cwd, \"package.json\");\n if (!existsSync(file)) {\n return undefined;\n }\n let manifest: unknown;\n try {\n manifest = JSON.parse(readFileSync(file, \"utf8\"));\n } catch {\n return undefined;\n }\n return manifest === null || typeof manifest !== \"object\" || Array.isArray(manifest)\n ? undefined\n : (manifest as Readonly<Record<string, unknown>>);\n}\n\n/**\n * The framework this project is built with, or `undefined` when penv cannot\n * tell. `undefined` is an answer, not a failure: init falls back to the default\n * schema path and says that it did.\n */\nexport function detectFramework(cwd: string): Detected | undefined {\n const dependencies = dependenciesOf(cwd);\n if (dependencies === undefined) {\n return undefined;\n }\n for (const signature of SIGNATURES) {\n if (signature.packages.some((name) => dependencies.has(name))) {\n return detectedFrom(cwd, signature.name, signature.publicPrefixes);\n }\n }\n // Bun is a runtime, not a package, so no dependency names it. A framework above\n // would have answered first (a Next-on-Bun project is a Next project); only a\n // project with no framework and a `bunfig.toml` is a plain Bun one, whose seam\n // is Bun's preload rather than Node's `--import`. It has no client bundle, so no\n // public prefix.\n if (existsSync(join(cwd, \"bunfig.toml\")) || dependencies.has(\"bun-types\")) {\n return detectedFrom(cwd, \"Bun\", []);\n }\n return undefined;\n}\n\nfunction detectedFrom(cwd: string, name: string, publicPrefixes: readonly string[]): Detected {\n const schema = schemaFileFor(cwd);\n return {\n name,\n schemaFile: schema.file,\n ...(schema.displaced === undefined ? {} : { displacedFrom: schema.displaced }),\n publicPrefixes,\n };\n}\n\n/** The alias penv writes when the project says nothing about how it names its own modules. */\nexport const DEFAULT_ALIAS = \"@env\";\n\n/** The alias for a project that already speaks Node's subpath imports. */\nexport const IMPORTS_ALIAS = \"#env\";\n\n/**\n * The alias to offer, read from how the project already refers to itself.\n *\n * The two forms are not interchangeable, and the difference is not taste:\n *\n * - `@env` is a `tsconfig.json` `paths` entry. TypeScript understands it and a\n * bundler resolves it. Plain `node dist/index.js` does not — `paths` is erased\n * by the compiler, so the emitted `import ... from \"@env\"` reaches Node as a\n * package that is not installed.\n * - `#env` is a `package.json` `imports` entry, which Node resolves natively and\n * every current bundler honours. It needs a modern `moduleResolution` for the\n * types to follow, which is why it is not simply the default.\n *\n * A project carrying an `imports` block has already answered the question, so\n * that is what is offered. Anything else gets `@env`, which is what the docs\n * describe and what a framework project wants. This is a suggestion either way:\n * the human confirms it, and the answer is written down as a decision.\n */\nexport function detectAlias(cwd: string): string {\n return hasImportsBlock(cwd) ? IMPORTS_ALIAS : DEFAULT_ALIAS;\n}\n\nfunction hasImportsBlock(cwd: string): boolean {\n const manifest = manifestOf(cwd);\n const imports = manifest?.imports;\n return imports !== null && typeof imports === \"object\" && !Array.isArray(imports);\n}\n","/**\n * The draft schema penv writes when it adopts a dotenv file.\n *\n * It is a draft and says so in the file it lands in: single-sample inference\n * cannot know that a boolean seen as `true` must also accept `1`, or that a\n * string is really a URL. penv scaffolds `penv.schema.ts` once and never\n * regenerates it (invariant 2), so every correction the reader makes is safe.\n *\n * Requiredness across several files is the one judgement here, and it is\n * deliberately coarse: a field observed in every adopted environment starts\n * required, and a field missing from any of them starts optional. That is not\n * per-environment requiredness — there is one schema, never one per environment\n * (invariant 1) — it is the weakest shape that every adopted environment\n * satisfies, which is what makes the first `penv run` after a cutover pass with\n * no edits.\n */\n\nimport type { DotenvEntry } from \"@penvhq/core\";\nimport { accessPath, refFromVariable } from \"@penvhq/core\";\n\n/** One schema field, rendered into `penv.schema.ts` as `<key>: <type>,`. */\nexport interface SchemaField {\n readonly key: string;\n /** The Zod expression, e.g. `z.url()` — `.optional()` already applied when it belongs. */\n readonly type: string;\n}\n\n/** A drafted field, plus the verdict a report prints. */\nexport interface DraftField extends SchemaField {\n readonly required: boolean;\n}\n\n/** A URL of any scheme — `postgres://` is as much a URL as `https://`. */\nconst URL_LIKE = /^[a-z][a-z0-9+.-]*:\\/\\/\\S+$/i;\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n/**\n * The Zod expression for one sampled value. Values arrive as strings, so a\n * schema that must accept them declares the coercion: `z.boolean()` would reject\n * the string `\"true\"` this very file just imported.\n */\nexport function inferType(value: string): string {\n if (URL_LIKE.test(value)) {\n return \"z.url()\";\n }\n if (/^(true|false)$/i.test(value)) {\n return \"z.stringbool()\";\n }\n if (value.trim() !== \"\" && Number.isFinite(Number(value))) {\n return \"z.coerce.number()\";\n }\n return \"z.string()\";\n}\n\n/** The schema key one variable becomes, quoted only when it has to be. */\nfunction keyFor(variable: string): string {\n const key = accessPath(refFromVariable(variable)).join(\".\");\n return IDENTIFIER.test(key) ? key : JSON.stringify(key);\n}\n\n/** Sorted, so the draft is identical on every machine. */\nfunction byKey<T extends SchemaField>(fields: T[]): T[] {\n return fields.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));\n}\n\n/** One file's variables as schema fields, all required — `penv import`'s single source. */\nexport function draftFields(entries: readonly DotenvEntry[]): SchemaField[] {\n return byKey(entries.map((entry) => ({ key: keyFor(entry.key), type: inferType(entry.value) })));\n}\n\n/**\n * One adopted file, and which environment its values reach. `environment` is\n * absent for the two unscoped scopes (`.env`, `.env.local`), whose values serve\n * every environment.\n */\nexport interface DraftSource {\n readonly environment?: string;\n readonly entries: readonly DotenvEntry[];\n}\n\ninterface Observed {\n readonly types: Set<string>;\n readonly environments: Set<string>;\n /** True when an unscoped file carries this variable, so every environment has it. */\n everywhere: boolean;\n}\n\n/**\n * The draft for a whole cutover: every variable any adopted file declares, typed\n * from what was seen and required only where every adopted environment has it.\n *\n * Two files disagreeing about a variable's type (`true` here, `8080` there)\n * collapse to `z.string()` rather than to whichever file was read first — a\n * drafted type that rejects a value the project already had would fail the first\n * run, which is the one thing this draft exists to avoid.\n */\nexport function draftFieldsAcross(\n sources: readonly DraftSource[],\n environments: readonly string[],\n): DraftField[] {\n const observed = new Map<string, Observed>();\n for (const source of sources) {\n for (const entry of source.entries) {\n const seen = observed.get(entry.key) ?? {\n types: new Set<string>(),\n environments: new Set<string>(),\n everywhere: false,\n };\n seen.types.add(inferType(entry.value));\n if (source.environment === undefined) {\n seen.everywhere = true;\n } else {\n seen.environments.add(source.environment);\n }\n observed.set(entry.key, seen);\n }\n }\n\n const fields: DraftField[] = [];\n for (const [variable, seen] of observed) {\n const required = seen.everywhere || environments.every((name) => seen.environments.has(name));\n const type = (seen.types.size === 1 ? [...seen.types][0] : undefined) ?? \"z.string()\";\n fields.push({ key: keyFor(variable), type: required ? type : `${type}.optional()`, required });\n }\n return byKey(fields);\n}\n","/**\n * `penv init` — scaffold a project, and adopt its dotenv files completely.\n *\n * A project with `.env` files gets a cutover: init lists every dotenv file it\n * found, the developer picks the ones penv takes, and then penv either takes all\n * of them or none. There is no half-adopted state, because a project whose\n * values live half in `.env` and half in penv has two truths about its own\n * configuration — the drift penv exists to delete, introduced by penv itself. So\n * everything is preflighted first: the selection, the environments it declares,\n * every variable name, the draft schema, the dependency install, and the\n * generated variable each parameter maps to. A failed preflight moves nothing,\n * writes nothing, and never reports partial success.\n *\n * Only after the imported values validate do the dotenv files move — into one\n * ignored `.penv/state/rollback/dotenv/` bundle, recorded in\n * `.penv/state/cutover.json`, which `penv init undo` restores by exact name and\n * `penv cleanup` drops.\n *\n * Every step is idempotent, and two of them are write-once on purpose: the\n * schema module is yours the moment it exists (invariant 2 — penv scaffolds it,\n * never regenerates it), and `penv.config.ts` is the environment whitelist you\n * declared. Re-running init reports what it kept rather than overwriting it.\n *\n * What init writes is a set of decisions, and the two kinds are kept apart. penv\n * may default what it can *observe* — the framework in `package.json`, whether\n * `src/` exists — because a wrong guess about the codebase is visible in the\n * codebase. It must ask for what it cannot observe: which environments exist is\n * deployment topology, it is nowhere on disk, and a project that carries a\n * `staging` penv invented is a project whose config is fiction (invariant 10).\n * Selecting `.env.production` is the developer declaring production; selecting\n * `.env` alone declares nothing, and init asks which environment those values\n * are for rather than deciding.\n */\n\nimport { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\nimport type { DotenvDiagnostic, DotenvEntry, ParameterRef, Scope } from \"@penvhq/core\";\nimport {\n CUTOVER_PATH,\n DEFAULT_SCHEMA_FILE,\n environmentNames,\n isLegalEnvironmentName,\n loadConfigFrom,\n PENV_DIR,\n type PenvConfig,\n PenvError,\n parameterId,\n parseDotenv,\n RECORDS_PATH,\n RESERVED_TOKENS,\n ROLLBACK_DOTENV_PATH,\n renderStateGitignore,\n SCHEMA_SHAPE_FILE,\n STATE_GITIGNORE_PATH,\n schemaFileOf,\n validateConfig,\n validateSchemaFile,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { assertNoCollisions, refsForEntries, writeEntries } from \"../adopt.js\";\nimport { bundleDotenvFiles, bundleUnresolved, runUndo } from \"../cutover.js\";\nimport {\n DEFAULT_ALIAS,\n type Detected,\n detectAlias,\n detectFramework,\n srcPrefix,\n} from \"../detect.js\";\nimport type { DotenvFile } from \"../dotenv-files.js\";\nimport { cascadeFor, discoverDotenvFiles, environmentsDeclaredBy } from \"../dotenv-files.js\";\nimport type { DraftField, SchemaField } from \"../draft-schema.js\";\nimport { draftFieldsAcross } from \"../draft-schema.js\";\nimport type { InstallPlan, InstallRuntime } from \"../install.js\";\nimport {\n detectPackageManager,\n installedPackages,\n installWithPackageManager,\n planInstall,\n renderInstallPlan,\n} from \"../install.js\";\nimport { localTree, openProject, selfContainedSchemaModule } from \"../project.js\";\nimport { captureScaffold, restoreScaffold } from \"../scaffold-undo.js\";\nimport { type ScaffoldSeam, type Seam, seamFor } from \"../seams.js\";\nimport { out } from \"../style.js\";\nimport { CHECK, columns, formatSteps, guard, prompt, type Step, tip, WARN, write } from \"../ui.js\";\nimport type { ValidateResult } from \"./validate.js\";\nimport { checkEnvironment } from \"./validate.js\";\n\nexport const SCHEMA_FILE = \"env.ts\";\n\n/**\n * The shape module, at the project root beside `penv.config.ts`. It is pure — a\n * `z.object` and the type registration, no `load` — so importing it never loads\n * configuration, which is what lets a tooling config (drizzle-kit, a CI script)\n * import the one schema without a side effect instead of hand-inlining a second\n * `z.object` that drifts (invariant 2). `.penv/env.ts` is the thin wrapper that\n * re-exports it and calls `load`.\n *\n * Fixed at the root rather than following `schemaFile`: `schemaFile` names the\n * *wrapper* (see {@link writeEnvFile}), and the shape is the one file every\n * consumer derives from wherever the wrapper is kept.\n *\n * `schemaFile` stays on the wrapper `.penv/env.ts` rather than being pointed at\n * this shape module: the wrapper is what `load` runs, and the harvester\n * (loadSchema) reads one `schema` export from `schemaFile`, which the wrapper\n * re-exports. Neither module sits in the records tree, so the walker meets\n * neither.\n *\n * The path itself (`penv.schema.ts`, at the root) is core's — `watch` watches it,\n * the grammar excludes it, and one authority answers where it is.\n */\nexport { SCHEMA_SHAPE_FILE };\n\n/** The basename the wrapper imports the shape by, extension appended per {@link shapeSpecifier}. */\nconst SCHEMA_SHAPE_BASENAME = \"penv.schema\";\n\nexport const CONFIG_FILE = \"penv.config.ts\";\nexport const TSCONFIG_FILE = \"tsconfig.json\";\n\n/**\n * The alias forms penv can write, and the only two a specifier can take that is\n * not a package: `@name` resolves through tsconfig `paths`, `#name` through\n * package.json `imports`.\n */\nconst ALIAS_NAME = /^[@#][A-Za-z0-9_-]+$/;\n\n/** The prefix that means Node resolves the alias itself, with no bundler involved. */\nconst IMPORTS_PREFIX = \"#\";\n\nconst PACKAGE_FILE = \"package.json\";\n\n/** What init touched, so a caller can report it and a test can assert it. */\nexport type InitTarget =\n | \"penv-dir\"\n | \"schema\"\n | \"env\"\n | \"config\"\n | \"tsconfig\"\n | \"gitignore\"\n | \"seam\";\n/**\n * `conflicted` is the one that is not a success. penv wanted to write something,\n * found the user's file already saying something else about the same thing, and\n * left it alone — so the step is reported with a warning rather than a ✓, and the\n * text says what will not work until the user decides.\n *\n * `info` is a step penv did not perform automatically — a manual instruction (the\n * injection seam for a framework penv cannot scaffold), reported so the user\n * knows the one thing left to do.\n */\nexport type InitAction = \"created\" | \"kept\" | \"updated\" | \"conflicted\" | \"info\";\n\nexport interface InitStep {\n readonly target: InitTarget;\n readonly action: InitAction;\n /** The reported line, in the docs' voice. */\n readonly text: string;\n readonly note?: string;\n}\n\n/**\n * The answers init writes down. Every one of these is a decision a human either\n * made or consented to — never an identity penv recorded to reinterpret later.\n * There is deliberately no `framework` here: `schemaFile` and `publicPrefixes`\n * still mean exactly what they say after the project is rewritten in something\n * else, and `framework: \"next\"` would not.\n */\nexport interface InitDecisions {\n /** The whitelist. Empty unless a human named them — penv never infers one. */\n readonly environments: readonly string[];\n /**\n * The environment every command falls back to when `--env` is absent (seal 3).\n * Written only when the cutover adopted one — a declared decision, so the\n * whitelist rule is untouched, and CI keeps naming `--env` anyway.\n */\n readonly defaultEnvironment?: string;\n /** The schema module, relative to the project root, POSIX. */\n readonly schemaFile: string;\n /** The prefixes the framework inlines into its client bundle. */\n readonly publicPrefixes: readonly string[];\n /**\n * How the user's code names the schema module — `@env` or `#env`.\n *\n * Two forms, resolved by two different things: `@env` is a tsconfig `paths`\n * entry that a bundler resolves and plain Node does not, and `#env` is a\n * package.json `imports` entry that Node resolves itself. Which one a project\n * wants is a fact about the project, so penv reads what it already does and\n * offers that.\n */\n readonly alias: string;\n /**\n * Whether to inject the validated config into `process.env` for libraries that\n * read it directly, so `env.ts` loads with `{ inject: true }` and penv places\n * the framework's pre-app seam. Off by default and only ever turned on by an\n * explicit yes — a project that reads config only through `@env` gets none.\n */\n readonly inject: boolean;\n}\n\n/** What init would write with no further input: the defaults, and nothing invented. */\nexport const DEFAULT_DECISIONS: InitDecisions = {\n environments: [],\n inject: false,\n schemaFile: DEFAULT_SCHEMA_FILE,\n publicPrefixes: [],\n alias: DEFAULT_ALIAS,\n};\n\nexport interface InitResult {\n readonly root: string;\n readonly decisions: InitDecisions;\n readonly steps: readonly InitStep[];\n}\n\nexport interface InitOptions {\n readonly cwd: string;\n /** What to write. Omitted means the plan's defaults, as `--yes` takes them. */\n readonly decisions?: InitDecisions;\n /** The detected framework name, passed by the command so the seam step need not re-detect it. */\n readonly framework?: string;\n}\n\n/*\n * The plan: what penv observed, what it would write, and why.\n */\n\n/** Flags that decide without asking, so a script never meets a prompt. */\nexport interface InitFlags {\n /** `--schema <path>`. */\n readonly schema?: string;\n /** `--env`, already split. Absent means no answer; present means the answer. */\n readonly environments?: readonly string[];\n /** `--alias <name>`. */\n readonly alias?: string;\n /**\n * `--yes` on a project with nothing to adopt. It takes `development` and the\n * local provider — the machine the command was typed on, which is the one\n * environment penv can declare without claiming a deployment exists.\n */\n readonly yes?: boolean;\n}\n\nexport interface InitPlan {\n readonly detected: Detected | undefined;\n /** What init writes unless a human edits it. */\n readonly decisions: InitDecisions;\n /** Environments the `.env*` files on disk are evidence for. Offered, never taken. */\n readonly suggestedEnvironments: readonly string[];\n /** Why each decision is what it is. Printed — a fallback penv takes silently is a guess. */\n readonly notes: readonly string[];\n}\n\n/**\n * Names that look like an environment in a `.env` filename but are not one:\n * `.env.example` is documentation, and the grammar's reserved tokens are\n * scope markers. Suggesting either would put a name into the whitelist that no\n * value file can ever be scoped to.\n */\nconst NOT_ENVIRONMENTS: readonly string[] = [...RESERVED_TOKENS, \"example\", \"sample\", \"template\"];\n\n/**\n * The environments the project's own `.env*` files are evidence for.\n *\n * This is not inference: nothing here reaches `penv.config.ts` unless a human\n * reads the suggestion and presses Enter. Invariant 10 is about what penv\n * *declares*, and showing someone the filenames they wrote is not a declaration\n * — it is the difference between \"you seem to have a production\" and penv\n * quietly deciding that you do.\n */\nexport function suggestEnvironments(root: string): string[] {\n let entries: string[];\n try {\n entries = readdirSync(root);\n } catch {\n return [];\n }\n\n const found = new Set<string>();\n for (const entry of entries) {\n if (!entry.startsWith(\".env.\")) {\n continue;\n }\n const segments = entry.slice(\".env.\".length).split(\".\");\n // `.env.production.local` is production's file; `.env.local` names no\n // environment at all, and neither does anything with more segments left\n // over, which is a filename penv has no reading of.\n const withoutLocal = segments.at(-1) === \"local\" ? segments.slice(0, -1) : segments;\n const name = withoutLocal.length === 1 ? withoutLocal[0] : undefined;\n if (name === undefined || !isLegalEnvironmentName(name) || NOT_ENVIRONMENTS.includes(name)) {\n continue;\n }\n found.add(name);\n }\n // Sorted so the same project shows the same line on every machine: directory\n // order is the filesystem's answer, not the project's.\n return [...found].sort();\n}\n\n/** A flag that is present but says nothing is refused, never read as absent. */\nfunction emptyFlag(flag: \"schema\" | \"env\" | \"alias\"): PenvError {\n return new PenvError(\n \"INIT_FLAG_EMPTY\",\n `\\`--${flag}\\` was given without a value`,\n flag === \"schema\"\n ? \"Name the module that exports the schema, e.g. `--schema src/env.ts`, or drop the flag \" +\n `to use ${DEFAULT_SCHEMA_FILE}.`\n : \"Name the environment, e.g. `--env production`, or drop the flag to leave the whitelist \" +\n \"empty and declare it in penv.config.ts.\",\n );\n}\n\n/** One list of environment names, however it was written. */\nfunction splitEnvironments(value: string): string[] {\n return value\n .split(\",\")\n .map((name) => name.trim())\n .filter((name) => name.length > 0);\n}\n\n/**\n * `--env` as the whitelist it declares, or `undefined` when it was not given —\n * which is no answer, not an empty one. Repeatable and comma-separated both\n * work: `--env development --env production` and `--env development,production`\n * are the same answer, and a shell that made one of them awkward is not a reason\n * to have declared a different set of environments.\n */\nexport function environmentsFromFlag(flag: unknown): readonly string[] | undefined {\n if (flag === undefined) {\n return undefined;\n }\n const given = Array.isArray(flag) ? (flag as readonly unknown[]) : [flag];\n const names = given.flatMap((value) => splitEnvironments(String(value)));\n if (names.length === 0) {\n throw emptyFlag(\"env\");\n }\n return [...new Set(names)];\n}\n\n/**\n * The names init collected, as the record the config declares them in. Init only\n * ever scaffolds the local tree, so every entry is the string shorthand — a\n * remote backend is a decision the developer makes in the config, not one penv\n * invents from a name it was handed.\n */\nfunction environmentsRecord(names: readonly string[]): Record<string, string> {\n return Object.fromEntries(names.map((environment) => [environment, LOCAL_PROVIDER]));\n}\n\n/** The config the decisions describe, so core answers questions about it, not init. */\nfunction configOf(decisions: InitDecisions): PenvConfig {\n return {\n environments: environmentsRecord(decisions.environments),\n schemaFile: decisions.schemaFile,\n };\n}\n\n/**\n * The decisions this project already recorded, or `undefined` when it has none.\n *\n * Only the config init itself would write or keep — the one beside `root`, not\n * whatever `findConfigFile` turns up two directories above. A monorepo's root\n * config is not this package's declaration, and `writeConfigFile` has always\n * looked exactly here.\n *\n * A config that exists and cannot be read is an error rather than an absence.\n * Treating it as absent is how the re-run bug worked in the first place: penv\n * would decide the project had declared nothing, re-detect, and scaffold a\n * second schema beside the one already there.\n */\nfunction declaredIn(root: string): PenvConfig | undefined {\n const file = join(root, CONFIG_FILE);\n if (!existsSync(file)) {\n return undefined;\n }\n return loadConfigFrom(file);\n}\n\n/**\n * What penv observed and what it proposes to write. The notes are the point as\n * much as the decisions are: a project that ends up with `.penv/env.ts` because\n * detection failed must be told that detection failed, or the fallback is\n * indistinguishable from a choice penv made on their behalf.\n *\n * Precedence is the whole design in one list: a flag is the human deciding now, a\n * config is the human having decided already, and detection is a suggestion that\n * loses to both. Guess once, declare forever — so once `penv.config.ts` exists,\n * re-detection cannot move what it says. Re-running init on a project that\n * declared `src/lib/env.ts` used to scaffold a *second* schema at the detected\n * path, warn that its own correct alias pointed at the wrong file, and announce\n * that a project with a declared `production` had declared none.\n */\nexport function planInit(root: string, flags: InitFlags = {}): InitPlan {\n const declared = declaredIn(root);\n const detected = detectFramework(root);\n const notes: string[] = [];\n\n if (declared !== undefined) {\n notes.push(`${CONFIG_FILE} already exists — init keeps every decision it records.`);\n } else if (detected === undefined) {\n notes.push(\n `No framework detected in package.json — the schema goes to ${DEFAULT_SCHEMA_FILE}.`,\n );\n } else {\n notes.push(`Detected ${detected.name}.`);\n if (detected.displacedFrom !== undefined) {\n notes.push(\n `${detected.displacedFrom} is already a module of yours that exports no \\`schema\\`, so ` +\n `the schema goes to ${detected.schemaFile}. penv never writes over a file it did not ` +\n `write — delete yours and re-run if you want it there, or pass \\`--schema\\`.`,\n );\n }\n }\n\n // Flag, then what the project already declared, then detection. `schemaFileOf`\n // rather than `config.schemaFile`: a config that omits the key has still\n // answered — with the default — and re-detection must not move a schema that\n // is already sitting where the project says it is.\n const schemaFile =\n flags.schema === undefined\n ? declared !== undefined\n ? schemaFileOf(declared)\n : (detected?.schemaFile ?? DEFAULT_SCHEMA_FILE)\n : flags.schema.trim();\n if (flags.schema !== undefined) {\n if (schemaFile.length === 0) {\n throw emptyFlag(\"schema\");\n }\n // Every rule a committed path has to satisfy lives in core, so `--schema`\n // is judged by the same validator `penv validate` will judge the config by.\n // Refusing here is refusing before a file is written; refusing there is\n // refusing after the project already has one in the wrong place.\n const error = validateSchemaFile({ environments: {}, schemaFile })[0];\n if (error !== undefined) {\n throw error;\n }\n }\n\n const alias = flags.alias === undefined ? detectAlias(root) : flags.alias.trim();\n if (flags.alias !== undefined && alias.length === 0) {\n throw emptyFlag(\"alias\");\n }\n if (!ALIAS_NAME.test(alias)) {\n throw new PenvError(\n \"INIT_ALIAS_INVALID\",\n `\\`${alias}\\` is not an alias penv can write`,\n `An alias is \\`@name\\` — a tsconfig \\`paths\\` entry a bundler resolves — or \\`#name\\`, a ` +\n \"package.json `imports` entry Node resolves itself. Those are the two things a module \" +\n \"specifier can be that is not a package.\",\n );\n }\n // Only when penv worked it out. `--alias` needs no explanation of why penv\n // chose it, and this note would have explained a reason that was not true:\n // it fired on the *form* of the alias rather than on where it came from, so a\n // forced `#env` was told its own package.json had asked for it.\n if (flags.alias === undefined && alias.startsWith(IMPORTS_PREFIX)) {\n notes.push(\n `Your ${PACKAGE_FILE} declares \\`imports\\`, so the alias is \\`${alias}\\` — Node resolves it without a bundler.`,\n );\n }\n\n const suggestedEnvironments = suggestEnvironments(root);\n // `--yes` takes `development` and nothing else (PRD §6). It is the machine the\n // command was typed on rather than a claim that a deployment exists, which is\n // what separates it from the production/staging/preview it still never invents.\n const safeDefault = flags.yes === true && declared === undefined;\n const environments =\n flags.environments ??\n (declared === undefined ? undefined : environmentNames(declared)) ??\n (safeDefault ? [DEVELOPMENT] : []);\n const defaultEnvironment =\n declared?.defaultEnvironment ?? (safeDefault ? DEVELOPMENT : undefined);\n if (safeDefault) {\n notes.push(\n `\\`--yes\\` declares ${DEVELOPMENT} with the local provider — the one environment penv can ` +\n \"name without inventing a deployment.\",\n );\n }\n // The empty whitelist is worth a line only when it is still empty. A project\n // that declared `production` being told it has declared nothing is penv\n // reading its own config wrong out loud.\n if (environments.length === 0) {\n notes.push(\"No environments declared: penv does not infer them.\");\n if (suggestedEnvironments.length > 0) {\n notes.push(\n `Your \\`.env\\` files mention ${suggestedEnvironments.join(\", \")} — declare the ones you ` +\n `really deploy in ${CONFIG_FILE}, with a provider for each.`,\n );\n }\n }\n\n return {\n detected,\n decisions: {\n environments,\n // A recorded decision, carried forward so a re-run reports the project as\n // it is. `writeConfigFile` keeps an existing config either way.\n ...(defaultEnvironment === undefined ? {} : { defaultEnvironment }),\n // Injection is a choice about the app's needs, not something on disk — so\n // the plan defaults it off, and only the interactive prompt turns it on.\n inject: false,\n schemaFile,\n publicPrefixes: declared?.publicPrefixes ?? detected?.publicPrefixes ?? [],\n alias,\n },\n suggestedEnvironments,\n notes,\n };\n}\n\n/*\n * The prompt.\n *\n * A plan the human confirms, not an interrogation they answer: penv already\n * knows everything but the one fact it must not guess, so it shows the whole\n * page and asks once. The io is a parameter so the decision logic is a plain\n * function — the tests call it, they do not spawn a terminal.\n */\n\nexport interface PromptIo {\n readonly ask: (question: string) => Promise<string>;\n readonly write: (line: string) => void;\n}\n\n/** The plan as one screen. */\nexport function renderPlan(plan: InitPlan): string[] {\n const rows: string[][] = [];\n rows.push([\n ` ${out.dim(\"environments\")}`,\n plan.suggestedEnvironments.length === 0\n ? \"\"\n : out.cyan(`[${plan.suggestedEnvironments.join(\", \")}]`),\n out.dim(\n plan.suggestedEnvironments.length === 0\n ? \"← name them, or Enter to leave the whitelist empty\"\n : \"← from your .env files; edit, or Enter to accept\",\n ),\n ]);\n rows.push([\n ` ${out.dim(\"schemaFile\")}`,\n plan.decisions.schemaFile,\n plan.decisions.schemaFile === DEFAULT_SCHEMA_FILE\n ? \"\"\n : out.dim(`(default: ${DEFAULT_SCHEMA_FILE})`),\n ]);\n for (const prefix of plan.decisions.publicPrefixes) {\n rows.push([` ${out.dim(\"publicPrefix\")}`, prefix, \"\"]);\n }\n\n const headline = out.bold(\n plan.detected === undefined\n ? \"No framework detected in package.json.\"\n : `Detected ${plan.detected.name}.`,\n );\n return [headline, \"\", ...columns(rows), \"\"];\n}\n\nfunction environmentsHint(plan: InitPlan): string {\n return plan.suggestedEnvironments.length === 0\n ? prompt(\"environments\", \"comma-separated, Enter for none\")\n : prompt(\"environments\", 'Enter to accept, \"none\" for an empty whitelist');\n}\n\n/**\n * The plan, confirmed. `undefined` is the human declining, which is an outcome\n * and not a failure: nothing is written and the run says so.\n *\n * An answer that is neither yes nor no declines, because the two mistakes are\n * not symmetrical — a decline costs a re-run, while reading \"no thanks\" as\n * consent scaffolds a project someone said no to.\n */\nexport async function promptForDecisions(\n plan: InitPlan,\n io: PromptIo,\n): Promise<InitDecisions | undefined> {\n for (const line of renderPlan(plan)) {\n io.write(line);\n }\n\n const answer = (await io.ask(environmentsHint(plan))).trim();\n const environments =\n answer.length === 0\n ? plan.suggestedEnvironments\n : answer.toLowerCase() === \"none\"\n ? []\n : splitEnvironments(answer);\n // The confirmation has to be about what is actually written, so an edited\n // line is echoed before `Proceed?` rather than confirmed in the abstract.\n if (answer.length > 0) {\n io.write(\"\");\n io.write(\n environments.length === 0\n ? \" environments [] (declare them later in penv.config.ts)\"\n : ` environments [${environments.join(\", \")}]`,\n );\n io.write(\"\");\n }\n\n // `Proceed?` is asked FIRST, so the confirmation muscle-memory — Enter, then a\n // decline — still declines: a new question inserted above it would otherwise\n // eat the \"n\" and default Proceed to yes, scaffolding a project someone meant to\n // refuse. Injection is a refinement of a scaffold already agreed to, so it is\n // asked only after that yes — and never on a runtime injection cannot serve.\n const proceed = (await io.ask(prompt(\"Proceed?\", \"Y/n\"))).trim().toLowerCase();\n if (proceed.length > 0 && proceed !== \"y\" && proceed !== \"yes\") {\n return undefined;\n }\n const inject = seamKindFor(plan) === \"none\" ? false : await askInject(io);\n return { ...plan.decisions, environments, inject };\n}\n\n/** The seam kind for the plan's framework, so the prompt can skip a runtime injection cannot serve. */\nfunction seamKindFor(plan: InitPlan): Seam[\"kind\"] {\n return seamFor(plan.detected?.name, {\n alias: plan.decisions.alias,\n srcDir: plan.decisions.schemaFile.startsWith(\"src/\") ? \"src/\" : \"\",\n schemaFile: plan.decisions.schemaFile,\n }).kind;\n}\n\n/**\n * The injection question, implication-first: the developer reads what yes and no\n * each *do*, not a premise about libraries. Default is no.\n */\nasync function askInject(io: PromptIo): Promise<boolean> {\n io.write(\"\");\n io.write(\"Also inject your validated config into process.env?\");\n io.write(\" y libraries that read process.env directly (WorkOS, Prisma…) just work\");\n io.write(' n config stays available only through import { env } from \"@env\"');\n const answer = (await io.ask(prompt(\"inject\", \"y/N\"))).trim().toLowerCase();\n return answer === \"y\" || answer === \"yes\";\n}\n\n/*\n * Templates.\n */\n\nexport type { SchemaField };\n\nconst EMPTY_SCHEMA_BODY =\n \" // One key per parameter, e.g. `databaseUrl: z.url(),`. Nesting a key nests\\n\" +\n \" // the parameter: `redis: z.object({ password: z.string() })` is redis/password.\";\n\nconst DRAFT_HEADER =\n \"// DRAFT — generated from the dotenv values penv adopted, and yours to correct.\\n\" +\n \"// Inference from a sample cannot know that a boolean seen as `true` must also\\n\" +\n \"// accept `1`/`0`, or that a string is really a URL. A field every adopted\\n\" +\n \"// environment had starts required; one that was missing anywhere starts\\n\" +\n \"// optional. penv scaffolds this file once and never regenerates it, so edits\\n\" +\n \"// here are safe.\\n\";\n\n/**\n * `penv.schema.ts` — the shape, and nothing that loads. This is the side-effect\n * free half of the split: a `z.object` plus the type registration, so importing\n * it (or `z.infer<typeof schema>`) never touches configuration. Tooling that\n * needs the schema imports *this* — never a second `z.object` over the same\n * store, which is the drift invariant 2 exists to prevent.\n *\n * The draft header and the harvested fields land here, because this is where the\n * parameters live: `penv import` writes the shape it inferred into the shape\n * module, and `.penv/env.ts` wraps whatever it finds.\n */\nexport function renderSchemaShapeModule(fields: readonly SchemaField[], draft: boolean): string {\n const body =\n fields.length === 0\n ? EMPTY_SCHEMA_BODY\n : fields.map((field) => ` ${field.key}: ${field.type},`).join(\"\\n\");\n\n return (\n `${draft ? DRAFT_HEADER : \"\"}import { z } from \"zod\";\\n` +\n `\\n` +\n `// The shape — the one definition every consumer derives from. Import this (or\\n` +\n `// z.infer<typeof schema>) when you only need the type — tests, tooling — so you\\n` +\n `// don't trigger config loading. .penv/env.ts wraps it with load().\\n` +\n `export const schema = z.object({\\n${body}\\n});\\n` +\n `\\n` +\n `// Registers the schema's shape with penv's types (erased at runtime, so\\n` +\n `// nothing cycles). This is what makes \\`override\\` keys in penv.config.ts\\n` +\n `// autocomplete from this schema — a typo'd parameter id is a compile error.\\n` +\n `declare module \"@penvhq/core\" {\\n` +\n ` interface PenvSchemaShape {\\n` +\n ` readonly shape: z.infer<typeof schema>;\\n` +\n ` }\\n` +\n `}\\n`\n );\n}\n\n/**\n * The specifier `.penv/env.ts` imports the shape by, relative to wherever the\n * wrapper is kept. The shape is always at the project root, so this is the climb\n * back up to it: `.penv/env.ts` → `../penv.schema.js`, a root `env.ts` →\n * `./penv.schema.js`, `src/lib/env.ts` → `../../penv.schema.js`.\n *\n * The `.js` extension is deliberate, not a typo for the `.ts` file it names: a\n * relative import under `moduleResolution: node16`/`nodenext` must carry the\n * *output* extension, and TypeScript maps `penv.schema.js` back to\n * `penv.schema.ts` for the type. Bundler resolution accepts it too, so one\n * specifier is correct everywhere — an extensionless one would fail to resolve for\n * a project on nodenext.\n */\nfunction shapeSpecifier(schemaFile: string): string {\n const depth = schemaFile.split(\"/\").length - 1;\n const climb = depth === 0 ? \"./\" : \"../\".repeat(depth);\n return `${climb}${SCHEMA_SHAPE_BASENAME}.js`;\n}\n\n/**\n * `.penv/env.ts` — the thin wrapper. It imports the shape from\n * `penv.schema.ts`, re-exports it so a type-only consumer can reach the schema\n * through `@env` without loading, and calls `load`. This is the module the\n * `@env`/`#env` alias resolves to and the module `schemaFile` names, so\n * application code still `import { env } from \"@env\"` exactly as before.\n *\n * The re-export is what keeps the harvester (loadSchema) working unchanged: it\n * reads the `schema` export of `schemaFile`, and the wrapper has one.\n */\nexport function renderEnvModule(schemaFile: string, inject = false): string {\n const loadComment = inject\n ? \"// The loaded, validated values for the current environment. Import this in app\\n\" +\n \"// code. `inject: true` also copies the values into process.env, for libraries\\n\" +\n \"// that read process.env directly.\\n\"\n : \"// The loaded, validated values for the current environment. Import this in app\\n\" +\n \"// code. Importing it loads configuration and throws (naming the parameter and\\n\" +\n \"// environment) if anything required is missing or invalid.\\n\";\n const loadCall = inject\n ? \"export const env = load(schema, { inject: true });\\n\"\n : \"export const env = load(schema);\\n\";\n\n return (\n `import { load } from \"@penvhq/penv\";\\n` +\n `import { schema } from \"${shapeSpecifier(schemaFile)}\";\\n` +\n `\\n` +\n `// Re-exported so type-only consumers can import the shape through @env without\\n` +\n `// triggering config loading — the shape itself lives in ${SCHEMA_SHAPE_FILE}.\\n` +\n `export { schema };\\n` +\n `\\n` +\n loadComment +\n loadCall\n );\n}\n\n/** An environment name as an object key: bare where it is a legal identifier. */\nfunction entryKey(name: string): string {\n return /^[A-Za-z_$][\\w$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\n/**\n * The whitelist block. Empty is the honest answer to a question nothing on disk\n * can settle, so the comment carries what an empty file cannot: that penv left\n * it empty on purpose, and the exact shape of the entry that fills it in.\n */\nfunction renderEnvironments(decisions: InitDecisions): string {\n const shared =\n \" // Environments are a whitelist, and each entry is that environment's whole\\n\" +\n \" // declaration: which provider holds it, in that provider's own words, and\\n\" +\n \" // which key seals it. A segment is an environment only if it is named here.\\n\";\n if (decisions.environments.length === 0) {\n return (\n `${shared}` +\n \" // It starts empty because which environments you deploy is not something penv\\n\" +\n \" // can read off your codebase, and an environment you do not have is worse\\n\" +\n \" // than one you have not declared yet. Name yours:\\n\" +\n \" // environments: {\\n\" +\n ' // development: \"@penvhq/provider-filesystem\",\\n' +\n ' // production: { provider: \"@penvhq/provider-vault\", path: \"penv\", keySource: \"env\" },\\n' +\n \" // },\\n\" +\n \" environments: {},\\n\"\n );\n }\n const entries = decisions.environments\n .map((name) => ` ${entryKey(name)}: ${JSON.stringify(LOCAL_PROVIDER)},\\n`)\n .join(\"\");\n return (\n `${shared} // A provider that needs no fields is just its package name.\\n` +\n ` environments: {\\n${entries} },\\n`\n );\n}\n\n/** The config, carrying only the decisions that were actually made. */\nexport function renderConfigModule(decisions: InitDecisions): string {\n let body = renderEnvironments(decisions);\n\n // Seal 3: what turns `penv run --env development -- pnpm dev` into\n // `penv run -- pnpm dev`. A declared decision, so invariant 10 is untouched —\n // this is not `NODE_ENV`, a branch name or a filename being believed.\n if (decisions.defaultEnvironment !== undefined) {\n body +=\n \"\\n // The environment a command uses when `--env` is absent. A pipeline names\\n\" +\n \" // `--env` anyway: a deploy that leans on this is one edit from the wrong one.\\n\" +\n ` defaultEnvironment: ${JSON.stringify(decisions.defaultEnvironment)},\\n`;\n }\n\n // The default is written by not writing it: a key that restates the default is\n // noise the next reader has to check against the docs before they can ignore it.\n if (decisions.schemaFile !== DEFAULT_SCHEMA_FILE) {\n body +=\n \"\\n // The module that exports the schema. It is yours — penv scaffolds it once\\n\" +\n \" // and never regenerates it — so this says where you keep it.\\n\" +\n ` schemaFile: ${JSON.stringify(decisions.schemaFile)},\\n`;\n }\n if (decisions.publicPrefixes.length > 0) {\n const prefixes = decisions.publicPrefixes.map((prefix) => JSON.stringify(prefix)).join(\", \");\n body +=\n \"\\n // The prefixes your framework inlines into the browser bundle. `penv doctor`\\n\" +\n \" // reports a parameter your meta declares `secret: true` whose variable name\\n\" +\n \" // starts with one of these — penv is the only thing holding both facts.\\n\" +\n ` publicPrefixes: [${prefixes}],\\n`;\n }\n\n return `import { defineConfig } from \"@penvhq/penv\";\\n\\nexport default defineConfig({\\n${body}});\\n`;\n}\n\n/*\n * The tsconfig.json edit.\n *\n * The alias is inserted into the user's own file, so the file is scanned rather\n * than parsed and re-emitted: reformatting someone's tsconfig — dropping its\n * comments, resorting its keys — to add one path is not a minimal edit.\n */\n\nfunction skipTrivia(source: string, index: number): number {\n let i = index;\n for (;;) {\n const ch = source.charAt(i);\n if (ch === \" \" || ch === \"\\t\" || ch === \"\\n\" || ch === \"\\r\") {\n i += 1;\n continue;\n }\n if (ch === \"/\" && source.charAt(i + 1) === \"/\") {\n const end = source.indexOf(\"\\n\", i);\n i = end === -1 ? source.length : end + 1;\n continue;\n }\n if (ch === \"/\" && source.charAt(i + 1) === \"*\") {\n const end = source.indexOf(\"*/\", i + 2);\n i = end === -1 ? source.length : end + 2;\n continue;\n }\n return i;\n }\n}\n\n/** Index just past the closing quote of the string opening at `index`. */\nfunction endOfString(source: string, index: number): number {\n let i = index + 1;\n while (i < source.length) {\n const ch = source.charAt(i);\n if (ch === \"\\\\\") {\n i += 2;\n continue;\n }\n if (ch === '\"') {\n return i + 1;\n }\n i += 1;\n }\n return source.length;\n}\n\n/** Index just past the bracket matching the one at `index`. */\nfunction endOfBracket(source: string, index: number): number {\n const open = source.charAt(index);\n const close = open === \"{\" ? \"}\" : \"]\";\n let depth = 0;\n let i = index;\n while (i < source.length) {\n const ch = source.charAt(i);\n if (ch === '\"') {\n i = endOfString(source, i);\n continue;\n }\n if (ch === \"/\" && (source.charAt(i + 1) === \"/\" || source.charAt(i + 1) === \"*\")) {\n i = skipTrivia(source, i);\n continue;\n }\n if (ch === open) {\n depth += 1;\n i += 1;\n continue;\n }\n if (ch === close) {\n depth -= 1;\n i += 1;\n if (depth === 0) {\n return i;\n }\n continue;\n }\n i += 1;\n }\n return source.length;\n}\n\nfunction endOfValue(source: string, index: number): number {\n const ch = source.charAt(index);\n if (ch === '\"') {\n return endOfString(source, index);\n }\n if (ch === \"{\" || ch === \"[\") {\n return endOfBracket(source, index);\n }\n let i = index;\n while (i < source.length) {\n const c = source.charAt(i);\n if (c === \",\" || c === \"}\" || c === \"]\" || c === \"\\n\") {\n return i;\n }\n i += 1;\n }\n return source.length;\n}\n\ninterface Member {\n readonly valueStart: number;\n}\n\n/** The member named `key` directly inside the object whose `{` is at `open`. */\nfunction findMember(source: string, open: number, key: string): Member | undefined {\n const close = endOfBracket(source, open) - 1;\n let i = skipTrivia(source, open + 1);\n while (i < close) {\n if (source.charAt(i) !== '\"') {\n return undefined;\n }\n const keyEnd = endOfString(source, i);\n const name = source.slice(i + 1, keyEnd - 1);\n const colon = skipTrivia(source, keyEnd);\n if (source.charAt(colon) !== \":\") {\n return undefined;\n }\n const valueStart = skipTrivia(source, colon + 1);\n const valueEnd = endOfValue(source, valueStart);\n if (name === key) {\n return { valueStart };\n }\n let next = skipTrivia(source, valueEnd);\n if (source.charAt(next) === \",\") {\n next = skipTrivia(source, next + 1);\n }\n i = next;\n }\n return undefined;\n}\n\n/** The indentation of the line `index` sits on. */\nfunction lineIndent(source: string, index: number): string {\n const lineStart = source.lastIndexOf(\"\\n\", index) + 1;\n const match = /^[ \\t]*/.exec(source.slice(lineStart, index));\n return match?.[0] ?? \"\";\n}\n\n/** The file's own indentation unit, so the inserted line looks like its neighbours. */\nfunction indentUnit(source: string): string {\n const match = /\\n([ \\t]+)\"/.exec(source);\n return match?.[1] ?? \" \";\n}\n\nfunction insertMember(source: string, open: number, member: string, unit: string): string {\n const objectIndent = lineIndent(source, open);\n const entryIndent = objectIndent + unit;\n const close = endOfBracket(source, open) - 1;\n if (skipTrivia(source, open + 1) === close) {\n return `${source.slice(0, open + 1)}\\n${entryIndent}${member}\\n${objectIndent}${source.slice(close)}`;\n }\n return `${source.slice(0, open + 1)}\\n${entryIndent}${member},${source.slice(open + 1)}`;\n}\n\nfunction shapeError(what: string, target: string, alias: string): PenvError {\n return new PenvError(\n \"TSCONFIG_SHAPE\",\n `penv cannot add the \\`${alias}\\` path alias to tsconfig.json: ${what}`,\n `Add it by hand: \\`{ \"compilerOptions\": { \"paths\": { \"${alias}\": [\"${target}\"] } } }\\`.`,\n );\n}\n\nexport interface AliasEdit {\n readonly source: string;\n readonly changed: boolean;\n /**\n * What the alias already points at, when that is not penv's schema.\n *\n * The alias is how the user's code reaches penv, so an alias that resolves\n * somewhere else is not a small problem: `import { env } from \"@env\"` compiles,\n * runs, and hands back another module's export. Reporting \"kept the alias\"\n * because the *key* was present is how penv would say that was fine — a silent\n * seam, in the scaffolder of the tool whose subject is silent seams.\n *\n * Left as the user's, never rewritten: penv cannot tell a stale mapping from a\n * deliberate one, and the file is theirs.\n */\n readonly conflict?: string;\n}\n\n/**\n * `tsconfig.json` with the `@env` alias present, everything else untouched.\n * Already-aliased input comes back unchanged rather than gaining a duplicate.\n *\n * The alias is why the schema can live anywhere: application code imports\n * `@env`, and this line is the only thing that has to know where that is.\n */\nexport function insertEnvAlias(\n source: string,\n target: string = DEFAULT_SCHEMA_FILE,\n name: string = DEFAULT_ALIAS,\n): AliasEdit {\n const alias = `\"${name}\": [\"${target}\"]`;\n const root = skipTrivia(source, 0);\n if (source.charAt(root) !== \"{\") {\n throw shapeError(\"its contents are not a JSON object\", target, name);\n }\n\n const unit = indentUnit(source);\n const compilerOptions = findMember(source, root, \"compilerOptions\");\n if (compilerOptions === undefined) {\n return {\n source: insertMember(source, root, `\"compilerOptions\": { \"paths\": { ${alias} } }`, unit),\n changed: true,\n };\n }\n if (source.charAt(compilerOptions.valueStart) !== \"{\") {\n throw shapeError(\"`compilerOptions` is not an object\", target, name);\n }\n\n const paths = findMember(source, compilerOptions.valueStart, \"paths\");\n if (paths === undefined) {\n return {\n source: insertMember(source, compilerOptions.valueStart, `\"paths\": { ${alias} }`, unit),\n changed: true,\n };\n }\n if (source.charAt(paths.valueStart) !== \"{\") {\n throw shapeError(\"`compilerOptions.paths` is not an object\", target, name);\n }\n\n const existing = findMember(source, paths.valueStart, name);\n if (existing !== undefined) {\n // The key being present is not the question. Where it points is.\n const points = source.slice(existing.valueStart, endOfValue(source, existing.valueStart));\n return points.includes(`\"${target}\"`)\n ? { source, changed: false }\n : { source, changed: false, conflict: points.trim() };\n }\n return { source: insertMember(source, paths.valueStart, alias, unit), changed: true };\n}\n\n/**\n * `package.json` with the `#env` subpath import present, everything else untouched.\n *\n * The same scanning edit the tsconfig gets, for the same reason: a manifest is\n * the project's file, and rewriting it through `JSON.parse`/`stringify` to add\n * one key resorts nothing but reformats everything.\n *\n * `imports` is Node's own mechanism, so an alias written here needs no bundler to\n * resolve — which is the whole reason a project would choose it.\n */\nexport function insertImportsAlias(source: string, target: string, name: string): AliasEdit {\n const entry = `\"${name}\": \"./${target}\"`;\n const root = skipTrivia(source, 0);\n if (source.charAt(root) !== \"{\") {\n throw shapeError(\"its contents are not a JSON object\", target, name);\n }\n\n const unit = indentUnit(source);\n const imports = findMember(source, root, \"imports\");\n if (imports === undefined) {\n return { source: insertMember(source, root, `\"imports\": { ${entry} }`, unit), changed: true };\n }\n if (source.charAt(imports.valueStart) !== \"{\") {\n throw shapeError(\"`imports` is not an object\", target, name);\n }\n\n const existing = findMember(source, imports.valueStart, name);\n if (existing !== undefined) {\n const points = source.slice(existing.valueStart, endOfValue(source, existing.valueStart));\n return points.includes(`\"./${target}\"`)\n ? { source, changed: false }\n : { source, changed: false, conflict: points.trim() };\n }\n return { source: insertMember(source, imports.valueStart, entry, unit), changed: true };\n}\n\nfunction renderTsconfig(target: string, alias: string): string {\n return `{\\n \"compilerOptions\": {\\n \"paths\": { \"${alias}\": [\"${target}\"] }\\n }\\n}\\n`;\n}\n\n/*\n * The steps themselves. Each returns what it did so the caller reports it.\n */\n\nexport function ensurePenvDir(root: string): InitStep {\n const dir = resolve(root, PENV_DIR);\n if (existsSync(dir)) {\n return { target: \"penv-dir\", action: \"kept\", text: `Found ${PENV_DIR}/` };\n }\n mkdirSync(dir, { recursive: true });\n return { target: \"penv-dir\", action: \"created\", text: `Created ${PENV_DIR}/` };\n}\n\n/**\n * Invariant 2, first half: the shape module `penv.schema.ts` is scaffolded once\n * and never regenerated. It holds the parameters (and the draft `penv import`\n * infers), so an existing one is the user's schema — keeping it, rather than\n * overwriting it, is the whole point.\n */\nexport function writeSchemaShapeFile(\n root: string,\n fields: readonly SchemaField[],\n draft: boolean,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n): InitStep {\n const file = join(root, SCHEMA_SHAPE_FILE);\n if (existsSync(file)) {\n return {\n target: \"schema\",\n action: \"kept\",\n text: `Kept ${SCHEMA_SHAPE_FILE}`,\n note: \"(yours — penv never regenerates it)\",\n };\n }\n // A project scaffolded before the split keeps its `z.object` inside the module\n // `schemaFile` names (0.5+ also its `PenvSchemaShape` augmentation there), not\n // in a separate `penv.schema.ts`. Writing one now would stand a second, empty\n // `z.object` beside the real one — the second drifting schema invariant 2\n // forbids — and, for a 0.5+ layout, a duplicate `PenvSchemaShape` block that\n // fails to typecheck (TS2717). So the old file stays the one schema, and penv\n // says how to split it by hand rather than doing it destructively.\n const oldLayout = selfContainedSchemaModule(root, decisions.schemaFile);\n if (oldLayout !== undefined) {\n return {\n target: \"schema\",\n action: \"conflicted\",\n text: `Kept your schema in ${oldLayout}`,\n note:\n `(the shape lives there, from before the ${SCHEMA_SHAPE_FILE} split — penv did not add a ` +\n `second one. To adopt the split: move the \\`z.object\\` (and any \\`declare module\\` block) ` +\n `into ${SCHEMA_SHAPE_FILE}, leaving ${oldLayout} importing \\`schema\\` from it and calling \\`load\\`.)`,\n };\n }\n writeFileSync(file, renderSchemaShapeModule(fields, draft), \"utf8\");\n return {\n target: \"schema\",\n action: \"created\",\n text: `Generated ${SCHEMA_SHAPE_FILE}`,\n note: draft ? \"(draft schema — review it, it's yours)\" : \"(the shape — yours to edit)\",\n };\n}\n\n/**\n * Invariant 2, second half: the wrapper `.penv/env.ts` is scaffolded once and\n * never regenerated either. It is the module the alias resolves to and the\n * module `schemaFile` names, so it goes wherever the decisions put it — the\n * default `.penv/env.ts`, or a framework's `src/env.ts`. An existing one is the\n * user's, whatever penv would have written, and that holds at any path.\n */\nexport function writeEnvFile(root: string, decisions: InitDecisions = DEFAULT_DECISIONS): InitStep {\n const file = join(root, ...decisions.schemaFile.split(\"/\"));\n if (existsSync(file)) {\n return {\n target: \"env\",\n action: \"kept\",\n text: `Kept ${decisions.schemaFile}`,\n note: \"(yours — penv never regenerates it)\",\n };\n }\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, renderEnvModule(decisions.schemaFile, decisions.inject), \"utf8\");\n return {\n target: \"env\",\n action: \"created\",\n text: `Generated ${decisions.schemaFile}`,\n note: \"(loads the shape — yours to edit)\",\n };\n}\n\nexport function writeConfigFile(\n root: string,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n): InitStep {\n const file = join(root, CONFIG_FILE);\n if (existsSync(file)) {\n return { target: \"config\", action: \"kept\", text: `Kept ${CONFIG_FILE}` };\n }\n writeFileSync(file, renderConfigModule(decisions), \"utf8\");\n return { target: \"config\", action: \"created\", text: `Generated ${CONFIG_FILE}` };\n}\n\nexport function writeTsconfigAlias(\n root: string,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n): InitStep {\n const alias = decisions.alias;\n // `#env` is Node's mechanism and lives in the manifest; `@env` is TypeScript's\n // and lives in the tsconfig. Writing one into the other's file produces a key\n // nothing reads — the alias would simply never resolve, and penv would have\n // reported writing it.\n const imports = alias.startsWith(IMPORTS_PREFIX);\n const file = join(root, imports ? PACKAGE_FILE : TSCONFIG_FILE);\n const where = imports ? PACKAGE_FILE : TSCONFIG_FILE;\n\n if (!existsSync(file)) {\n // A project with no manifest is not one penv invents a manifest for: the\n // manifest is the project's identity, and `imports` is a key on something\n // that already exists. A tsconfig penv can honestly create from nothing.\n if (imports) {\n return {\n target: \"tsconfig\",\n action: \"conflicted\",\n text: `No ${PACKAGE_FILE} to add the ${alias} import to`,\n note: `(run \\`npm init\\` first, or use \\`--alias @env\\` to alias through ${TSCONFIG_FILE})`,\n };\n }\n writeFileSync(file, renderTsconfig(decisions.schemaFile, alias), \"utf8\");\n return {\n target: \"tsconfig\",\n action: \"created\",\n text: `Created ${TSCONFIG_FILE} with the ${alias} path alias`,\n };\n }\n\n const source = readFileSync(file, \"utf8\");\n const edit = imports\n ? insertImportsAlias(source, decisions.schemaFile, alias)\n : insertEnvAlias(source, decisions.schemaFile, alias);\n\n if (edit.conflict !== undefined) {\n return {\n target: \"tsconfig\",\n action: \"conflicted\",\n text: `${where} already maps ${alias} to ${edit.conflict}`,\n note: `(left alone — \\`import { env } from \"${alias}\"\\` will not reach ${decisions.schemaFile})`,\n };\n }\n if (!edit.changed) {\n return {\n target: \"tsconfig\",\n action: \"kept\",\n text: `Kept the ${alias} alias in ${where}`,\n };\n }\n writeFileSync(file, edit.source, \"utf8\");\n return {\n target: \"tsconfig\",\n action: \"updated\",\n text: `Added ${alias} alias to ${where}`,\n };\n}\n\n/**\n * The ignore file lives at the top of `state/`, over everything penv manages:\n * penv owns it outright, so it is rewritten when it drifts. A weakened ignore\n * file is how a plaintext secret gets committed, which invariant 20 exists to\n * prevent.\n */\nexport function writeGitignore(\n root: string,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n): InitStep {\n const file = join(root, ...STATE_GITIGNORE_PATH.split(\"/\"));\n const wanted = renderStateGitignore(configOf(decisions));\n const existing = existsSync(file) ? readFileSync(file, \"utf8\") : undefined;\n if (existing === wanted) {\n return { target: \"gitignore\", action: \"kept\", text: `Kept ${STATE_GITIGNORE_PATH}` };\n }\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, wanted, \"utf8\");\n return {\n target: \"gitignore\",\n action: existing === undefined ? \"created\" : \"updated\",\n text: `${existing === undefined ? \"Created\" : \"Updated\"} ${STATE_GITIGNORE_PATH}`,\n };\n}\n\n/** The first `@penvhq/penv` release whose `load` honours `{ inject: true }`. */\nconst INJECT_MIN_VERSION = \"0.6.0\";\n\n/**\n * A warning when the project's installed runtime is too old to honour\n * `{ inject: true }` — the option is ignored on an older `@penvhq/penv`, so the\n * seam would run and `process.env` would stay empty while init reported success.\n * `undefined` when the runtime is new enough, or absent (init may run before an\n * install, and penv does not warn about what it cannot see).\n */\nfunction outdatedRuntimeWarning(root: string): string | undefined {\n const version = installedPenvVersion(root);\n if (version === undefined || !isBelow(version, INJECT_MIN_VERSION)) {\n return undefined;\n }\n return `Injection needs @penvhq/penv ${INJECT_MIN_VERSION}+ — this project has ${version}, whose \\`load\\` ignores \\`{ inject: true }\\`. Upgrade, or process.env stays empty.`;\n}\n\nfunction installedPenvVersion(root: string): string | undefined {\n const file = join(root, \"node_modules\", \"@penvhq\", \"penv\", \"package.json\");\n if (!existsSync(file)) {\n return undefined;\n }\n try {\n const version = JSON.parse(readFileSync(file, \"utf8\")).version;\n return typeof version === \"string\" ? version : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** The `[major, minor, patch]` of a semver, pre-release tag ignored, missing parts zero. */\nfunction releaseTriple(version: string): [number, number, number] {\n const parts = (version.split(\"-\")[0] ?? \"\").split(\".\");\n const at = (i: number) => Number.parseInt(parts[i] ?? \"0\", 10) || 0;\n return [at(0), at(1), at(2)];\n}\n\n/** True when semver `a` is strictly below `b`, comparing the release triple. */\nfunction isBelow(a: string, b: string): boolean {\n const [am, an, ap] = releaseTriple(a);\n const [bm, bn, bp] = releaseTriple(b);\n if (am !== bm) return am < bm;\n if (an !== bn) return an < bn;\n return ap < bp;\n}\n\n/**\n * Places the injection seam for the detected framework — the file whose one\n * `import \"@env\"` runs before app code, so an injected `process.env` is populated\n * before a library reads it. penv scaffolds a fresh seam file, but never edits a\n * hook the user already owns: an existing file, or a framework with no file penv\n * can safely own, becomes a printed instruction instead. Returns nothing when\n * injection was not chosen. `framework` is passed by the command (which already\n * detected it) to avoid re-reading `package.json`; it falls back to detecting.\n */\nexport function writeSeam(\n root: string,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n framework: string | undefined = detectFramework(root)?.name,\n): InitStep | undefined {\n if (!decisions.inject) {\n return undefined;\n }\n const seam = seamFor(framework, {\n alias: decisions.alias,\n srcDir: srcPrefix(root),\n schemaFile: decisions.schemaFile,\n });\n\n // Regardless of the seam's shape, `env.ts` now carries `{ inject: true }`, so an\n // outdated runtime is the same silent no-op everywhere — warn once, here.\n const outdated = outdatedRuntimeWarning(root);\n\n if (seam.kind === \"none\") {\n return { target: \"seam\", action: \"info\", text: \"No injection seam needed\", note: seam.reason };\n }\n if (seam.kind === \"instruct\") {\n return {\n target: \"seam\",\n action: \"info\",\n text: \"Place the injection seam\",\n note: withWarning(seam.instruction, outdated),\n };\n }\n\n // A companion file the seam also needs (Bun's bunfig.toml). Same rule: write it\n // when absent, otherwise print where to add the entry. Its outcome joins the\n // seam step's note, so the whole setup is one line to read.\n const alsoNote = writeAlso(root, seam.also);\n\n const file = join(root, ...seam.file.split(\"/\"));\n const baseNotes = [...seam.notes, ...(alsoNote === undefined ? [] : [alsoNote])];\n const notes = baseNotes.length === 0 ? \"\" : `\\n${baseNotes.map((n) => ` ${n}`).join(\"\\n\")}`;\n if (existsSync(file)) {\n return {\n target: \"seam\",\n action: \"info\",\n text: `Add the injection seam to ${seam.file}`,\n note: withWarning(`${seam.ifPresent}${notes}`, outdated),\n };\n }\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, seam.content, \"utf8\");\n return {\n target: \"seam\",\n action: outdated === undefined ? \"created\" : \"info\",\n text: `Wrote ${seam.file} (runs the injection before your app)`,\n ...(notes === \"\" && outdated === undefined\n ? {}\n : { note: withWarning(notes.trimStart(), outdated) }),\n };\n}\n\n/**\n * The companion file (Bun's `bunfig.toml`), written when absent and reported as a\n * note; when present it is the user's, so the note tells them where to add the\n * entry rather than penv editing their config. `undefined` when there is none.\n */\nfunction writeAlso(root: string, also: ScaffoldSeam[\"also\"]): string | undefined {\n if (also === undefined) {\n return undefined;\n }\n const file = join(root, ...also.file.split(\"/\"));\n if (existsSync(file)) {\n return also.ifPresent;\n }\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, also.content, \"utf8\");\n return `Wrote ${also.file} to register it.`;\n}\n\n/** Appends a runtime warning to a seam note, when there is one. */\nfunction withWarning(note: string, warning: string | undefined): string {\n if (warning === undefined) {\n return note;\n }\n return note === \"\" ? warning : `${note}\\n ⚠ ${warning}`;\n}\n\n/** Everything `init` scaffolds, in the order it is reported. */\nexport function scaffold(\n root: string,\n fields: readonly SchemaField[],\n draft: boolean,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n framework: string | undefined = detectFramework(root)?.name,\n): InitStep[] {\n const steps = [\n ensurePenvDir(root),\n // The shape at the root, then the wrapper that loads it — both write-once.\n // The shape step needs the decisions too: an old-layout `schemaFile` already\n // holds the shape, and a second `penv.schema.ts` beside it would not compile.\n writeSchemaShapeFile(root, fields, draft, decisions),\n writeEnvFile(root, decisions),\n writeConfigFile(root, decisions),\n writeTsconfigAlias(root, decisions),\n writeGitignore(root, decisions),\n ];\n const seam = writeSeam(root, decisions, framework);\n return seam === undefined ? steps : [...steps, seam];\n}\n\n/**\n * Every path {@link scaffold} may write, so a failure after it can put the\n * project back exactly as it was. Listed here rather than discovered afterwards:\n * a rollback that guessed at what init touched would be a second answer to the\n * question this function already answers.\n */\nexport function scaffoldPaths(\n root: string,\n decisions: InitDecisions = DEFAULT_DECISIONS,\n framework: string | undefined = detectFramework(root)?.name,\n): string[] {\n const fileAt = (relative: string): string => join(root, ...relative.split(\"/\"));\n const seam = decisions.inject\n ? seamFor(framework, {\n alias: decisions.alias,\n srcDir: srcPrefix(root),\n schemaFile: decisions.schemaFile,\n })\n : undefined;\n return [\n fileAt(PENV_DIR),\n fileAt(SCHEMA_SHAPE_FILE),\n fileAt(decisions.schemaFile),\n fileAt(CONFIG_FILE),\n fileAt(TSCONFIG_FILE),\n fileAt(PACKAGE_FILE),\n ...(seam?.kind === \"scaffold\"\n ? [fileAt(seam.file), ...(seam.also === undefined ? [] : [fileAt(seam.also.file)])]\n : []),\n ];\n}\n\n/*\n * The cutover.\n *\n * Everything from here down is all-or-nothing by construction: `planCutover`\n * reads and checks, `applyCutover` writes and moves, and nothing between them\n * decides anything. That split is what lets a preflight failure be a refusal\n * with no cleanup to do.\n */\n\n/** The environment `--yes` takes and the file list preselects. */\nexport const DEVELOPMENT = \"development\";\n\n/** The provider a scaffolded environment reads from until the project says otherwise. */\nconst LOCAL_PROVIDER = \"@penvhq/provider-filesystem\";\n\n/** One adopted file: what it holds, and the scope its values are written at. */\ninterface Adopted {\n readonly file: DotenvFile;\n readonly entries: readonly DotenvEntry[];\n readonly refs: readonly ParameterRef[];\n readonly scope: Scope;\n}\n\nexport interface AdoptionPlan {\n readonly root: string;\n /** Every dotenv file penv found, in the order the list shows them. */\n readonly found: readonly DotenvFile[];\n /** Checked when the list is first shown: the development cascade, where it exists. */\n readonly preselected: readonly string[];\n}\n\n/** What there is to adopt, and what penv proposes taking. */\nexport function planAdoption(root: string): AdoptionPlan {\n const found = discoverDotenvFiles(root);\n return {\n root,\n found,\n preselected: found\n .filter((file) => file.environment === undefined || file.environment === DEVELOPMENT)\n .map((file) => file.name),\n };\n}\n\n/** The scope a file's values are written at — invariant 4's four levels, unchanged. */\nfunction scopeOf(file: DotenvFile): Scope {\n if (file.kind === \"shared\") {\n return { kind: \"unscoped\" };\n }\n if (file.kind === \"local\") {\n return { kind: \"local\" };\n }\n const environment = file.environment ?? \"\";\n return file.kind === \"environment\"\n ? { kind: \"environment\", environment }\n : { kind: \"environment-local\", environment };\n}\n\nexport interface CutoverPlan {\n readonly root: string;\n readonly selected: readonly DotenvFile[];\n readonly adopted: readonly Adopted[];\n /** The whitelist after this cutover — what the config declares, or is about to. */\n readonly environments: readonly string[];\n /**\n * The environments this cutover is *about*: the ones its files name. Narrower\n * than the whitelist on a project that already declared more, and the ones the\n * draft is judged against and the import is validated for — an environment\n * this cutover did not touch must not fail it for a state it was already in.\n */\n readonly adopting: readonly string[];\n readonly decisions: InitDecisions;\n readonly fields: readonly DraftField[];\n readonly variables: number;\n /** Values the parser read but that look like a mistake. Shown, never fixed. */\n readonly diagnostics: readonly DotenvDiagnostic[];\n readonly install: InstallPlan;\n readonly framework: string | undefined;\n /** True when `penv.config.ts` already existed, so init keeps every decision it records. */\n readonly configured: boolean;\n}\n\nexport interface CutoverInput {\n readonly root: string;\n /** What init would scaffold anyway: detection, the schema's home, the alias. */\n readonly base: InitPlan;\n readonly selected: readonly DotenvFile[];\n /** The environment named when the selection declares none — `.env` alone declares nothing. */\n readonly environment?: string;\n /** The `@penvhq/penv` version to pin. Defaults to this engine's own. */\n readonly version?: string;\n readonly inject?: boolean;\n}\n\n/**\n * Everything a cutover needs, checked before anything is written.\n *\n * The order is the order the failures matter in: an unresolved bundle first\n * (there is nothing to plan on top of it), then what the selection declares,\n * then whether the selection is complete, then every variable name, and only\n * then the schema and the install. Each one throws, so the caller has a plan or\n * a refusal and never a half-answer.\n */\nexport function planCutover(input: CutoverInput): CutoverPlan {\n const { root, base } = input;\n assertBundleResolved(root);\n\n const selected = [...input.selected];\n if (selected.length === 0) {\n throw new PenvError(\n \"INIT_NOTHING_SELECTED\",\n \"No dotenv file was selected, so there is nothing to migrate\",\n \"Run `penv init` again and choose the files penv should adopt.\",\n );\n }\n\n const declared = declaredIn(root);\n const named = environmentsDeclaredBy(selected);\n const chosen = named.length > 0 ? named : [requireEnvironment(input)];\n const environments = declared === undefined ? chosen : environmentNames(declared);\n for (const environment of chosen) {\n if (!environments.includes(environment)) {\n throw new PenvError(\n \"INIT_ENVIRONMENT_UNDECLARED\",\n `${CONFIG_FILE} declares ${describeList(environments)}, and adopting these files needs \\`${environment}\\` declared too`,\n `Add \\`${environment}: \"${LOCAL_PROVIDER}\"\\` to \\`environments\\` in ${CONFIG_FILE}, or name the backend that holds it, then run \\`penv init\\` again. Nothing was changed.`,\n );\n }\n }\n\n const defaultEnvironment =\n declared === undefined ? proposedDefault(chosen) : declared.defaultEnvironment;\n const decisions: InitDecisions = {\n ...base.decisions,\n environments,\n ...(defaultEnvironment === undefined ? {} : { defaultEnvironment }),\n ...(input.inject === undefined ? {} : { inject: input.inject }),\n };\n\n // The config init is about to write, judged by the same validator `penv\n // validate` will judge it by — before it exists, rather than after.\n const config = declared ?? configFor(decisions);\n const configError = validateConfig(config)[0];\n if (configError !== undefined) {\n throw configError;\n }\n\n assertCascadeComplete(root, selected, chosen);\n\n const adopted: Adopted[] = [];\n const refs: ParameterRef[] = [];\n const diagnostics: DotenvDiagnostic[] = [];\n let variables = 0;\n for (const file of selected) {\n const parsed = parseDotenv(readFileSync(join(root, file.name), \"utf8\"));\n const fileRefs = refsForEntries(parsed.entries, file.name, config);\n adopted.push({ file, entries: parsed.entries, refs: fileRefs, scope: scopeOf(file) });\n refs.push(...fileRefs);\n diagnostics.push(...parsed.diagnostics);\n variables += parsed.entries.length;\n }\n // Invariant 12, across the whole cutover rather than one file at a time: two\n // files may each be fine and still map two parameters to one variable. One\n // parameter written at four scopes is not that — `DATABASE_URL` in `.env` and\n // in `.env.development.local` is the cascade doing its job — so the refs are\n // deduplicated first.\n assertNoCollisions(distinct(refs), config);\n\n const fields = draftFieldsAcross(\n adopted.map((entry) => ({\n ...(entry.file.environment === undefined ? {} : { environment: entry.file.environment }),\n entries: entry.entries,\n })),\n chosen,\n );\n\n return {\n root,\n selected,\n adopted,\n environments,\n adopting: chosen,\n decisions,\n fields,\n variables,\n diagnostics,\n install: planInstall(root, input.version),\n framework: base.detected?.name,\n configured: declared !== undefined,\n };\n}\n\n/**\n * Seal 3, decided once: `development` when the development cascade was adopted,\n * and otherwise the single environment this cutover is about. Two or more\n * environments and no development among them is a project whose daily\n * environment penv cannot know, so it declares none and `--env` keeps its job.\n */\nfunction proposedDefault(chosen: readonly string[]): string | undefined {\n if (chosen.includes(DEVELOPMENT)) {\n return DEVELOPMENT;\n }\n return chosen.length === 1 ? chosen[0] : undefined;\n}\n\n/** One entry per parameter, whatever number of scopes it was seen at. */\nfunction distinct(refs: readonly ParameterRef[]): ParameterRef[] {\n const seen = new Map<string, ParameterRef>();\n for (const ref of refs) {\n seen.set(parameterId(ref), ref);\n }\n return [...seen.values()];\n}\n\nfunction configFor(decisions: InitDecisions): PenvConfig {\n return {\n environments: environmentsRecord(decisions.environments),\n schemaFile: decisions.schemaFile,\n ...(decisions.defaultEnvironment === undefined\n ? {}\n : { defaultEnvironment: decisions.defaultEnvironment }),\n ...(decisions.publicPrefixes.length === 0\n ? {}\n : { publicPrefixes: [...decisions.publicPrefixes] }),\n };\n}\n\nfunction describeList(names: readonly string[]): string {\n return names.length === 0 ? \"no environments\" : names.map((name) => `\\`${name}\\``).join(\", \");\n}\n\n/**\n * `.env` alone declares no environment (PRD §6), and penv will not pick one for\n * it. The caller asks; this is the guard that the answer arrived.\n */\nfunction requireEnvironment(input: CutoverInput): string {\n const environment = input.environment?.trim() ?? \"\";\n if (environment.length > 0) {\n return environment;\n }\n throw new PenvError(\n \"INIT_ENVIRONMENT_UNNAMED\",\n \"The selected files name no environment, and penv does not invent one\",\n `Run \\`penv init --env ${DEVELOPMENT}\\` to say which environment these values are for.`,\n );\n}\n\n/**\n * PRD §6: every framework-discoverable file in an adopted environment's cascade\n * has to come too. Adopting `.env.development` while leaving `.env` behind\n * leaves the framework loading values penv does not hold — a project with two\n * live sources, which is the state a complete cutover exists to prevent.\n */\nfunction assertCascadeComplete(\n root: string,\n selected: readonly DotenvFile[],\n environments: readonly string[],\n): void {\n const present = new Set(discoverDotenvFiles(root).map((file) => file.name));\n const taken = new Set(selected.map((file) => file.name));\n for (const environment of environments) {\n for (const name of cascadeFor(environment)) {\n if (present.has(name) && !taken.has(name)) {\n throw new PenvError(\n \"INIT_CUTOVER_INCOMPLETE\",\n `${name} is part of ${environment}'s cascade and was not selected, so your framework would keep reading it beside penv`,\n \"Run `penv init` again and take every file penv listed for that environment. Nothing was changed.\",\n );\n }\n }\n }\n}\n\n/**\n * A second migration over an unresolved bundle would bury the first one's files.\n *\n * The bundle decides, not the record: an interrupted cutover can leave files in\n * it, and keying this off `cutover.json` alone let a re-run write a fresh record\n * naming only the files that had not moved yet.\n */\nfunction assertBundleResolved(root: string): void {\n if (!bundleUnresolved(root)) {\n return;\n }\n throw new PenvError(\n \"INIT_BUNDLE_UNRESOLVED\",\n `The dotenv files from the last cutover are still in ${ROLLBACK_DOTENV_PATH}/, and penv will not migrate a second time over them`,\n \"Run `penv init undo` to put them back, or `penv cleanup` to drop them once you are happy with the migration.\",\n );\n}\n\n/**\n * `--yes` takes the development cascade, and refuses when another environment is\n * leaning on the shared `.env` this cutover would move (PRD §6). Which files\n * that environment should keep is a decision, and `--yes` means \"I trust your\n * defaults\", never \"decide my other environments for me\".\n */\nexport function selectionForYes(plan: AdoptionPlan): DotenvFile[] {\n const shared = plan.found.find((file) => file.kind === \"shared\");\n const other = plan.found.find(\n (file) => file.environment !== undefined && file.environment !== DEVELOPMENT,\n );\n if (shared !== undefined && other !== undefined) {\n throw new PenvError(\n \"INIT_YES_SHARED_FALLBACK\",\n `${other.name} falls back to the shared ${shared.name} this cutover would move, so \\`--yes\\` will not decide what happens to ${other.environment ?? \"\"}`,\n \"Run `penv init` without `--yes` and choose every file the cutover takes. Nothing was changed.\",\n );\n }\n return plan.found.filter((file) => plan.preselected.includes(file.name));\n}\n\nexport interface CutoverResult {\n readonly plan: CutoverPlan;\n readonly steps: readonly InitStep[];\n /** The dotenv files moved into the bundle, by name. */\n readonly moved: readonly string[];\n /** The environments whose imported values were validated before the move. */\n readonly validated: readonly string[];\n}\n\nexport interface CutoverOptions {\n /** Injected in tests: how the runtime dependency is installed. Never spawns there. */\n readonly install?: InstallRuntime;\n}\n\n/**\n * Installs, scaffolds, imports, validates — and only then moves the dotenv\n * files aside. The order is the guarantee: every step before the move leaves a\n * project whose `.env` files are exactly where they were, so a refusal at any\n * of them costs a re-run and nothing else.\n *\n * The scaffold is snapshotted first, and rolled back when anything after it\n * refuses. Without that, \"a refusal costs a re-run\" was only true of the dotenv\n * files: a failed run still left a config, a draft schema, an edited tsconfig\n * and an imported records tree behind, and the next run kept every one of them\n * rather than starting clean. The install is not rolled back — it is the one\n * step the developer consented to by itself, and a re-run finds it satisfied.\n */\nexport async function applyCutover(\n plan: CutoverPlan,\n options: CutoverOptions = {},\n): Promise<CutoverResult> {\n if (!plan.install.satisfied) {\n await (options.install ?? installWithPackageManager)(plan.install);\n }\n\n const undo = captureScaffold(plan.root, scaffoldPaths(plan.root, plan.decisions, plan.framework));\n let steps: readonly InitStep[];\n try {\n steps = scaffold(plan.root, plan.fields, true, plan.decisions, plan.framework);\n const project = openProject(plan.root);\n const tree = localTree(project);\n for (const adopted of plan.adopted) {\n writeEntries(tree, adopted.entries, adopted.refs, adopted.scope);\n }\n\n // Every environment this cutover adopted, not just the daily one: the draft\n // is the weakest shape all of them satisfy, so if one of them does not, the\n // draft is wrong and the files must stay where they are. An environment the\n // cutover did not touch is not judged here — it was already in whatever\n // state it was in.\n for (const environment of plan.adopting) {\n const check = await checkEnvironment(project, environment);\n // The draft not loading and the values not fitting it are different\n // answers: one is a verdict, the other is penv never having reached one.\n if (check.schema === undefined) {\n throw draftNotLoaded(check.result);\n }\n if (!check.result.ok) {\n throw invalidAfterImport(check.result);\n }\n }\n } catch (error) {\n restoreScaffold(undo);\n throw error;\n }\n\n const cutover = bundleDotenvFiles(\n plan.root,\n plan.selected.map((file) => file.name),\n plan.environments,\n );\n return { plan, steps, moved: cutover.files, validated: plan.adopting };\n}\n\nfunction issueLines(result: ValidateResult): string {\n return result.issues.map((issue) => ` ${issue.subject}: ${issue.message}`).join(\"\\n\");\n}\n\n/** Nothing was left behind, so every refusal after the scaffold ends the same way. */\nconst SCAFFOLD_ROLLED_BACK =\n \"penv put the project back as it found it — your dotenv files and everything else are exactly where they were.\";\n\nfunction invalidAfterImport(result: ValidateResult): PenvError {\n return new PenvError(\n \"INIT_CUTOVER_INVALID\",\n `The imported values do not satisfy the draft schema for ${result.environment}:\\n${issueLines(result)}`,\n `Correct the values above, then run \\`penv init\\` again. ${SCAFFOLD_ROLLED_BACK}`,\n );\n}\n\n/**\n * The draft could not be evaluated at all — a missing dependency, a syntax\n * error. Reporting that as \"the imported values do not satisfy the draft schema\"\n * claims a check penv never ran, and sends the reader to correct values that\n * were never looked at.\n */\nfunction draftNotLoaded(result: ValidateResult): PenvError {\n return new PenvError(\n \"INIT_DRAFT_NOT_LOADED\",\n `penv could not load the schema it drafted for ${result.environment}, so nothing was checked against it:\\n${issueLines(result)}`,\n `Fix the error above, then run \\`penv init\\` again. ${SCAFFOLD_ROLLED_BACK}`,\n );\n}\n\n/*\n * The cutover's screens.\n */\n\n/** The file list, checkboxes and all — the one screen the selection is made on. */\nexport function renderSelection(\n plan: AdoptionPlan,\n selected: readonly string[] = plan.preselected,\n): string[] {\n const rows = plan.found.map((file) => [\n ` ${selected.includes(file.name) ? \"[x]\" : \"[ ]\"}`,\n file.name,\n out.dim(file.label),\n ]);\n return [out.bold(\"Found dotenv files. Which should penv adopt?\"), \"\", ...columns(rows), \"\"];\n}\n\n/** The plan, and the install it is conditional on. Nothing here has happened yet. */\nexport function renderCutoverPlan(plan: CutoverPlan): string[] {\n const required = plan.fields.filter((field) => field.required).length;\n const optional = plan.fields.length - required;\n const rows: string[][] = [\n [` ${out.dim(\"environments\")}`, out.cyan(`[${plan.environments.join(\", \")}]`), \"\"],\n ];\n if (plan.decisions.defaultEnvironment !== undefined) {\n rows.push([\n ` ${out.dim(\"default\")}`,\n plan.decisions.defaultEnvironment,\n out.dim(\"← so `penv run -- pnpm dev` needs no --env\"),\n ]);\n }\n rows.push([\n ` ${out.dim(\"schema\")}`,\n `${plan.fields.length} parameters`,\n out.dim(`← ${required} required, ${optional} optional — a draft you own`),\n ]);\n rows.push([\n ` ${out.dim(\"values\")}`,\n `${RECORDS_PATH}/`,\n out.dim(`← from ${plan.variables} variables`),\n ]);\n rows.push([\n ` ${out.dim(\"dotenv\")}`,\n `${ROLLBACK_DOTENV_PATH}/`,\n out.dim(\"← recoverable with `penv init undo`\"),\n ]);\n\n return [\n out.bold(\"The cutover\"),\n \"\",\n ...columns(rows),\n \"\",\n ...plan.diagnostics.map((diagnostic) => `${out.yellow(WARN)} ${diagnostic.detail}`),\n ...(plan.diagnostics.length === 0 ? [] : [\"\"]),\n ...renderInstallPlan(plan.install),\n \"\",\n ];\n}\n\n/** What actually happened, and the one command the project starts through now. */\nexport function renderCutover(result: CutoverResult): string[] {\n const { plan } = result;\n const plural = plan.environments.length === 1 ? \"environment\" : \"environments\";\n const steps: Step[] = [\n {\n glyph: plan.configured ? WARN : CHECK,\n text: `Declared ${plural}`,\n note: plan.configured\n ? `${plan.environments.join(\", \")} (already in ${CONFIG_FILE} — penv kept it)`\n : plan.environments.join(\", \"),\n },\n ...result.steps.map((step) => {\n const glyph = step.action === \"conflicted\" ? WARN : step.action === \"info\" ? \"→\" : CHECK;\n return step.note === undefined\n ? { glyph, text: step.text }\n : { glyph, text: step.text, note: step.note };\n }),\n ...installedPackages(plan.install).map((entry) => ({\n glyph: CHECK,\n text: `Installed ${entry.name}`,\n note: entry.version,\n })),\n {\n glyph: CHECK,\n text: `Imported ${plan.fields.length} parameters`,\n note: `into ${RECORDS_PATH}/`,\n },\n { glyph: CHECK, text: `Validated ${result.validated.join(\", \")}` },\n {\n glyph: CHECK,\n text: `Moved ${result.moved.length} dotenv ${result.moved.length === 1 ? \"file\" : \"files\"}`,\n note: `${ROLLBACK_DOTENV_PATH}/ (penv init undo restores them)`,\n },\n ];\n\n return [\n ...formatSteps(steps),\n \"\",\n `${out.green(CHECK)} ${out.bold(\"Done.\")} Start your app with penv:`,\n tip(out.cyan(dailyCommand(plan.root))),\n ];\n}\n\n/**\n * The daily command, shown and never written (seal 1 as amended). penv cannot\n * compose a script line containing a command it did not write, and wrapping\n * inside a script would run `pre*`/`post*` hooks outside penv's environment — so\n * the wrapper stays outside, and this is copy.\n */\nexport function dailyCommand(root: string): string {\n return `penv run -- ${detectPackageManager(root)} ${devScript(root)}`;\n}\n\n/** The script the project already has, so the line shown is one the reader can paste. */\nfunction devScript(root: string): string {\n const file = join(root, PACKAGE_FILE);\n if (!existsSync(file)) {\n return \"dev\";\n }\n try {\n const scripts: unknown = JSON.parse(readFileSync(file, \"utf8\")).scripts;\n if (scripts !== null && typeof scripts === \"object\" && !Array.isArray(scripts)) {\n const named = Object.keys(scripts);\n return [\"dev\", \"start\"].find((script) => named.includes(script)) ?? named[0] ?? \"dev\";\n }\n } catch {\n // An unreadable manifest is not a reason to print nothing: `dev` is what the\n // reader will recognise, and the line is copy either way.\n }\n return \"dev\";\n}\n\nexport function runInit(options: InitOptions): InitResult {\n const root = resolve(options.cwd);\n const decisions = options.decisions ?? planInit(root).decisions;\n // `options.framework` is the name the command already detected; passing it (or\n // `undefined`, which lets `scaffold` detect) avoids a second `package.json` read.\n return { root, decisions, steps: scaffold(root, [], false, decisions, options.framework) };\n}\n\nexport function renderInit(result: InitResult): string[] {\n const steps: Step[] = result.steps.map((step) => {\n // A conflict is the one step that is not a success, so it must not wear the\n // glyph every success wears: a ✓ beside \"penv could not wire your alias\" is\n // the line a reader skims past. An `info` step is a thing left for the user\n // to do, so it wears the tip arrow rather than a ✓ it did not earn.\n const glyph = step.action === \"conflicted\" ? WARN : step.action === \"info\" ? \"→\" : CHECK;\n return step.note === undefined\n ? { glyph, text: step.text }\n : { glyph, text: step.text, note: step.note };\n });\n // The shape is in `penv.schema.ts` for a project on the split, but a project\n // whose old-layout schema init just kept (the `conflicted` step) still holds it\n // in `schemaFile` — penv wrote no `penv.schema.ts` there, so pointing at one\n // would name a file that does not exist.\n const schemaStep = result.steps.find((step) => step.target === \"schema\");\n const shapeFile =\n schemaStep?.action === \"conflicted\" ? result.decisions.schemaFile : SCHEMA_SHAPE_FILE;\n return [\n ...formatSteps(steps),\n \"\",\n `${out.green(CHECK)} ${out.bold(\"Done.\")} Declare your parameters in ${shapeFile}, then:`,\n tip(out.cyan(\"penv set <key>\")),\n ...(result.decisions.environments.length === 0\n ? [\n `Then declare your environments in ${CONFIG_FILE}: penv leaves the whitelist empty ` +\n `rather than inventing one, and every command needs it.`,\n ]\n : []),\n ];\n}\n\n/*\n * The cutover conversation: one screen at a time, and every answer a decision\n * penv could not observe. The io is a parameter throughout, so the tests drive\n * the conversation without a terminal.\n */\n\n/**\n * The files to adopt. `undefined` is the developer declining, which is an\n * outcome and not a failure — nothing is written and the run says so.\n *\n * Enter takes the checked list, because the checked list is the complete\n * development cascade and taking all of it is what makes the cutover complete.\n */\nexport async function promptForSelection(\n plan: AdoptionPlan,\n io: PromptIo,\n): Promise<DotenvFile[] | undefined> {\n for (const line of renderSelection(plan)) {\n io.write(line);\n }\n\n const answer = (await io.ask(prompt(\"files\", \"Enter to take the checked ones\"))).trim();\n if (answer.toLowerCase() === \"none\") {\n return undefined;\n }\n const names =\n answer.length === 0\n ? plan.preselected\n : answer.toLowerCase() === \"all\"\n ? plan.found.map((file) => file.name)\n : answer\n .split(/[\\s,]+/)\n .map((name) => name.trim())\n .filter((name) => name.length > 0);\n\n const selected: DotenvFile[] = [];\n for (const name of names) {\n const file = plan.found.find((candidate) => candidate.name === name);\n if (file === undefined) {\n throw new PenvError(\n \"INIT_SELECTION_UNKNOWN\",\n `\\`${name}\\` is not one of the dotenv files penv found`,\n \"Run `penv init` again and name the files exactly as they are listed, e.g. `.env.production`.\",\n );\n }\n selected.push(file);\n }\n return selected.length === 0 ? undefined : selected;\n}\n\n/**\n * Which environment a selection that declares none is for. Offered, never\n * assumed: `development` is the answer for almost every project adopting a plain\n * `.env`, and pressing Enter is the developer giving it.\n */\nexport async function askEnvironment(io: PromptIo, offered: string): Promise<string> {\n io.write(\"\");\n io.write(\"Selecting `.env` alone declares no environment, and penv never infers one.\");\n const answer = (await io.ask(prompt(\"environment\", `Enter for ${offered}`))).trim();\n return answer.length === 0 ? offered : answer;\n}\n\n/** The last question before anything is written. */\nasync function askProceed(io: PromptIo): Promise<boolean> {\n const answer = (await io.ask(prompt(\"Proceed?\", \"Y/n\"))).trim().toLowerCase();\n return answer.length === 0 || answer === \"y\" || answer === \"yes\";\n}\n\n/** A terminal, or `undefined` when there is nobody to ask. */\nfunction terminal(): { readonly io: PromptIo; close(): void } {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return {\n io: {\n ask: (question) => rl.question(question),\n write: (line) => process.stdout.write(`${line}\\n`),\n },\n close: () => rl.close(),\n };\n}\n\n/** The prompt runs only against a real terminal; anything else has nobody to ask. */\nasync function askOnTty(plan: InitPlan): Promise<InitDecisions | undefined> {\n const rl = terminal();\n try {\n return await promptForDecisions(plan, rl.io);\n } finally {\n rl.close();\n }\n}\n\n/** The scaffold-only path: a project with no dotenv files to adopt. */\nasync function scaffoldOnly(root: string, plan: InitPlan, asked: boolean): Promise<void> {\n const decisions = asked ? await askOnTty(plan) : plan.decisions;\n if (decisions === undefined) {\n write([\"Nothing written. Re-run `penv init` when you want to scaffold.\"]);\n return;\n }\n if (!asked) {\n write([...plan.notes, \"\"]);\n }\n write(\n renderInit(\n runInit({ cwd: root, decisions, ...(plan.detected && { framework: plan.detected.name }) }),\n ),\n );\n}\n\n/** The cutover path, asked one screen at a time. */\nasync function cutoverInteractively(\n root: string,\n base: InitPlan,\n adoption: AdoptionPlan,\n): Promise<void> {\n const rl = terminal();\n let plan: CutoverPlan;\n let inject = false;\n try {\n const selected = await promptForSelection(adoption, rl.io);\n if (selected === undefined) {\n write([\"Nothing written. Re-run `penv init` when you want to migrate.\"]);\n return;\n }\n const named = environmentsDeclaredBy(selected);\n const environment =\n named.length > 0 ? undefined : await askEnvironment(rl.io, offeredEnvironment(root));\n\n plan = planCutover({\n root,\n base,\n selected,\n ...(environment === undefined ? {} : { environment }),\n });\n for (const line of renderCutoverPlan(plan)) {\n rl.io.write(line);\n }\n if (!(await askProceed(rl.io))) {\n write([\"Nothing written. Re-run `penv init` when you want to migrate.\"]);\n return;\n }\n inject = seamKindFor(base) === \"none\" ? false : await askInject(rl.io);\n } finally {\n rl.close();\n }\n\n write([\"\"]);\n write(renderCutover(await applyCutover({ ...plan, decisions: { ...plan.decisions, inject } })));\n}\n\n/** What the environment question offers: what the project already declared, else development. */\nfunction offeredEnvironment(root: string): string {\n const declared = declaredIn(root);\n if (declared === undefined) {\n return DEVELOPMENT;\n }\n const names = environmentNames(declared);\n return (\n declared.defaultEnvironment ??\n (names.includes(DEVELOPMENT) ? DEVELOPMENT : (names[0] ?? DEVELOPMENT))\n );\n}\n\n/** `penv init --yes`: the development cascade, the filesystem provider, and no questions. */\nasync function cutoverWithYes(root: string, base: InitPlan, adoption: AdoptionPlan): Promise<void> {\n const selected = selectionForYes(adoption);\n const plan = planCutover({ root, base, selected, environment: DEVELOPMENT });\n write([...renderCutoverPlan(plan), \"\"]);\n write(renderCutover(await applyCutover(plan)));\n}\n\nexport const initCommand = defineCommand({\n meta: {\n name: \"init\",\n description: \"Adopt your dotenv files, or scaffold a project (.penv/, env.ts, config, @env)\",\n },\n args: {\n action: {\n type: \"positional\",\n required: false,\n description: \"`undo` puts the dotenv files of the last cutover back, under their exact names\",\n },\n yes: {\n type: \"boolean\",\n description:\n `Take the development cascade and the ${LOCAL_PROVIDER} provider without asking. It ` +\n \"never invents production, staging or preview\",\n },\n schema: {\n type: \"string\",\n description: `Where the schema module goes, e.g. src/env.ts (default: ${DEFAULT_SCHEMA_FILE})`,\n },\n alias: {\n type: \"string\",\n description:\n \"How your code names the schema: @env (tsconfig paths, needs a bundler) or #env \" +\n \"(package.json imports, resolved by node itself)\",\n },\n env: {\n type: \"string\",\n description:\n \"Declare an environment. Repeatable, or comma-separated: --env development,production\",\n },\n },\n run({ args }) {\n return guard(async () => {\n const root = resolve(process.cwd());\n if (args.action !== undefined) {\n runUndoAction(root, String(args.action));\n return;\n }\n\n const environments = environmentsFromFlag(args.env);\n const adoption = planAdoption(root);\n // The `--yes` default is for a project with nothing to adopt; where there\n // is a cascade, the files declare the environments and the flag only means\n // \"take the checked ones\".\n const bare = adoption.found.length === 0;\n const plan = planInit(root, {\n ...(args.schema === undefined ? {} : { schema: args.schema }),\n ...(args.alias === undefined ? {} : { alias: args.alias }),\n ...(environments === undefined ? {} : { environments }),\n ...(bare && args.yes === true ? { yes: true } : {}),\n });\n\n const tty = process.stdin.isTTY === true;\n if (bare) {\n // No terminal is not a reason to guess: it is a reason to take the\n // defaults and say what they were, so a CI log carries the decisions.\n await scaffoldOnly(root, plan, tty && args.yes !== true && environments === undefined);\n return;\n }\n if (args.yes === true) {\n await cutoverWithYes(root, plan, adoption);\n return;\n }\n if (!tty) {\n // A cutover moves the developer's files, so it is never taken by a\n // script that did not ask for it. The plan is printed; nothing is done.\n write([...renderSelection(adoption), \"penv found dotenv files to migrate.\"]);\n write([tip(out.cyan(\"penv init --yes\"))]);\n return;\n }\n await cutoverInteractively(root, plan, adoption);\n });\n },\n});\n\n/** `penv init undo` — the only positional this command takes. */\nfunction runUndoAction(root: string, action: string): void {\n if (action !== \"undo\") {\n throw new PenvError(\n \"INIT_UNKNOWN_ACTION\",\n `\\`penv init ${action}\\` is not something init does`,\n \"Run `penv init undo` to put back the dotenv files of the last cutover.\",\n );\n }\n const result = runUndo({ cwd: root });\n write([\n ...formatSteps([\n ...result.restored.map((name) => ({\n glyph: CHECK,\n text: `Restored ${name}`,\n note: `from ${ROLLBACK_DOTENV_PATH}/`,\n })),\n ...result.alreadyBack.map((name) => ({\n glyph: CHECK,\n text: `${name} was already back`,\n note: \"put there by an earlier undo\",\n })),\n ...result.missing.map((name) => ({\n glyph: WARN,\n text: `${name} is gone`,\n note: \"not in the bundle, not at the project root\",\n })),\n ]),\n \"\",\n result.missing.length === 0\n ? `${out.green(CHECK)} ${out.bold(\"Undone.\")} Your dotenv files are back exactly as they were, and ` +\n `${CUTOVER_PATH} is gone.`\n : `${out.yellow(WARN)} ${out.bold(\"Undone as far as penv could.\")} Everything still in the bundle is back, and ` +\n `${CUTOVER_PATH} is gone.`,\n `penv's records are still in ${RECORDS_PATH}/ — nothing penv scaffolded is yours to lose.`,\n ]);\n}\n","/**\n * Putting a project back exactly as init found it.\n *\n * `penv init` is all-or-nothing, and everything before the dotenv move is\n * arranged so a refusal costs a re-run and nothing else. The scaffold is the one\n * step that reaches that promise by construction only until it doesn't: the\n * draft schema is written, the records are imported, and *then* the draft is\n * loaded — so a draft that cannot be loaded used to leave `penv.config.ts`,\n * `penv.schema.ts`, a rewritten `tsconfig.json`, `.penv/env.ts` and a records\n * tree behind, and the next `penv init` kept all of it rather than starting\n * clean.\n *\n * So the paths init may write are snapshotted before it writes them, and put\n * back on the way out: a file penv created is deleted, a file penv edited is\n * rewritten byte for byte, and a directory penv made is removed. Nothing outside\n * the snapshotted paths is touched, which is why the caller names them rather\n * than this module guessing at the project.\n */\n\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmdirSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nexport interface ScaffoldUndo {\n /** The project root. Nothing above it is ever removed. */\n readonly root: string;\n /** The files and directories init may write, absolute. */\n readonly paths: readonly string[];\n /** What each file held before, byte for byte. */\n readonly files: ReadonlyMap<string, Buffer>;\n /** The directories that already existed, so the rest are penv's to remove. */\n readonly dirs: ReadonlySet<string>;\n}\n\nfunction record(path: string, files: Map<string, Buffer>, dirs: Set<string>): void {\n let stats: ReturnType<typeof statSync>;\n try {\n stats = statSync(path);\n } catch {\n return;\n }\n if (stats.isDirectory()) {\n dirs.add(path);\n for (const entry of readdirSync(path)) {\n record(join(path, entry), files, dirs);\n }\n return;\n }\n if (stats.isFile()) {\n files.set(path, readFileSync(path));\n }\n}\n\n/** The state of `paths` right now, enough to restore it exactly. */\nexport function captureScaffold(root: string, paths: readonly string[]): ScaffoldUndo {\n const files = new Map<string, Buffer>();\n const dirs = new Set<string>();\n for (const path of paths) {\n for (let dir = dirname(path); dir.startsWith(root) && dir !== root; dir = dirname(dir)) {\n if (existsSync(dir)) {\n dirs.add(dir);\n }\n }\n record(path, files, dirs);\n }\n return { root, paths: [...paths], files, dirs };\n}\n\n/** The project as {@link captureScaffold} found it. */\nexport function restoreScaffold(undo: ScaffoldUndo): void {\n for (const path of undo.paths) {\n removeAdded(path, undo);\n }\n for (const path of undo.paths) {\n pruneAncestors(path, undo);\n }\n for (const [file, contents] of undo.files) {\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, contents);\n }\n}\n\nfunction removeAdded(path: string, undo: ScaffoldUndo): void {\n let stats: ReturnType<typeof statSync>;\n try {\n stats = statSync(path);\n } catch {\n return;\n }\n if (stats.isFile()) {\n if (!undo.files.has(path)) {\n unlinkSync(path);\n }\n return;\n }\n if (!stats.isDirectory()) {\n return;\n }\n for (const entry of readdirSync(path)) {\n removeAdded(join(path, entry), undo);\n }\n if (!undo.dirs.has(path) && readdirSync(path).length === 0) {\n rmdirSync(path);\n }\n}\n\n/** The directories a created file needed, when they were created for it. */\nfunction pruneAncestors(path: string, undo: ScaffoldUndo): void {\n for (\n let dir = dirname(path);\n dir.startsWith(undo.root) && dir !== undo.root;\n dir = dirname(dir)\n ) {\n if (undo.dirs.has(dir)) {\n return;\n }\n try {\n rmdirSync(dir);\n } catch {\n return;\n }\n }\n}\n","/**\n * The injection seams — where `penv init` places `import \"@env\"` so it runs\n * before any app code, per framework.\n *\n * When a project opts into injection (`load(schema, { inject: true })`), the SDK\n * that reads `process.env` directly only finds the values if the injection ran\n * first. Every framework ships a hook it *guarantees* runs before app code; this\n * module knows, per framework, which hook that is and exactly what belongs in it.\n * The specifics here were verified against each framework's current documentation\n * — the ordering guarantee, the filename rules, the runtime guards — not written\n * from memory, because a seam that runs a beat too late is a seam that does\n * nothing.\n *\n * Three shapes of seam:\n *\n * - **scaffold** — the framework has a clean pre-app file penv can write. penv\n * creates it *only when it does not already exist*; an existing hook is the\n * user's, so penv prints where to add the line instead of editing it in place.\n * - **instruct** — no file penv can safely own (plain Node has no framework hook;\n * TanStack's entry is version-shaped; Astro has no universal hook). penv prints\n * the exact, verified line and where it goes.\n * - **none** — no server runtime reads `process.env` at all (a pure client SPA),\n * so injection does not apply and penv says so.\n *\n * The import specifier is the project's own alias — `@env` where a bundler\n * resolves it (Next, SvelteKit, Nuxt, Bun-with-tsconfig), `#env` where Node\n * resolves it natively (plain Node). That choice is the project's, made at init;\n * the seam only carries it through.\n */\n\n/** What init knows when it builds a seam: the project's alias, layout, and schema module. */\nexport interface SeamContext {\n /** The import specifier the project resolves the schema module by — `@env` or `#env`. */\n readonly alias: string;\n /** `\"src/\"` when the project keeps modules under `src/`, else `\"\"`. */\n readonly srcDir: string;\n /** The schema module path, relative to the project root, POSIX — e.g. `.penv/env.ts` or `src/env.ts`. */\n readonly schemaFile: string;\n}\n\n/** A seam penv can write to a file, created only when the file is absent. */\nexport interface ScaffoldSeam {\n readonly kind: \"scaffold\";\n /** The file to create, relative to the project root, POSIX. */\n readonly file: string;\n /** Exactly what penv writes into a fresh file — the framework-explaining comment and the import. */\n readonly content: string;\n /**\n * What penv prints when the file already exists (penv will not edit a hook the\n * user owns) — where to add the line, verbatim.\n */\n readonly ifPresent: string;\n /** Extra one-line notes penv surfaces after scaffolding — an alias-wiring caveat, say. */\n readonly notes: readonly string[];\n /**\n * A second file the seam also needs, under the same create-if-absent rule — Bun's\n * `bunfig.toml`, which must register the preload file or it never runs. penv\n * creates it when absent; when present it is the user's, so penv prints where to\n * add the entry rather than editing their config.\n */\n readonly also?: {\n readonly file: string;\n readonly content: string;\n readonly ifPresent: string;\n };\n}\n\n/** A seam penv cannot own; it prints the exact instruction instead. */\nexport interface InstructSeam {\n readonly kind: \"instruct\";\n readonly instruction: string;\n}\n\n/** No server runtime reads `process.env`; injection does not apply. */\nexport interface NoSeam {\n readonly kind: \"none\";\n readonly reason: string;\n}\n\nexport type Seam = ScaffoldSeam | InstructSeam | NoSeam;\n\n/** Builds a framework's seam for one project's alias and layout. */\nexport type SeamFor = (context: SeamContext) => Seam;\n\nfunction nextjs({ alias, srcDir }: SeamContext): Seam {\n return {\n kind: \"scaffold\",\n file: `${srcDir}instrumentation.ts`,\n content:\n \"// This is instrumentation.ts, Next.js's own startup hook — Next runs it once,\\n\" +\n \"// before any of your app code, on every server boot. penv put one line here so\\n\" +\n \"// your config is in process.env before the first library reads it. The filename\\n\" +\n \"// is Next's requirement (it only finds `instrumentation.ts`), so keep it as-is.\\n\" +\n \"export async function register() {\\n\" +\n \" // Next also calls register on the Edge runtime, where penv cannot read the\\n\" +\n \" // filesystem — so inject runs on the Node runtime only.\\n\" +\n ' if (process.env.NEXT_RUNTIME === \"nodejs\") {\\n' +\n ` await import(\"${alias}\");\\n` +\n \" }\\n\" +\n \"}\\n\",\n ifPresent:\n `Add to your existing \\`${srcDir}instrumentation.ts\\`, inside \\`register()\\` and first:\\n` +\n ` if (process.env.NEXT_RUNTIME === \"nodejs\") { await import(\"${alias}\"); }`,\n notes: [],\n };\n}\n\nfunction sveltekit({ alias }: SeamContext): Seam {\n return {\n kind: \"scaffold\",\n // SvelteKit's hooks module is always under `src/`, whatever the schema path.\n file: \"src/hooks.server.ts\",\n content:\n \"// This is hooks.server.ts, SvelteKit's server-startup module — it loads before\\n\" +\n \"// your routes handle a request. penv put this import first so your config is in\\n\" +\n \"// process.env before any library reads it. Keep it the first line; the name and\\n\" +\n \"// location are SvelteKit's, not penv's.\\n\" +\n `import \"${alias}\";\\n`,\n ifPresent: `Add \\`import \"${alias}\";\\` as the FIRST line of src/hooks.server.ts, above every other import.`,\n notes: [\n `SvelteKit resolves app aliases through \\`kit.alias\\` — make sure \\`${alias}\\` is registered in svelte.config.js, not only tsconfig.`,\n ],\n };\n}\n\nfunction nuxt({ alias }: SeamContext): Seam {\n return {\n kind: \"scaffold\",\n // The `0.` prefix is load-bearing: Nitro sorts plugin filenames as strings,\n // so it must sort first to run before any other plugin reads process.env.\n file: \"server/plugins/0.penv.ts\",\n content:\n \"// This is a Nitro server plugin (Nuxt's server layer runs it once at startup,\\n\" +\n \"// before any middleware or request handler). penv put the import here so your\\n\" +\n \"// config is in process.env before a library reads it. The `0.` prefix keeps this\\n\" +\n \"// plugin first — Nitro sorts plugin filenames as text — so don't rename it.\\n\" +\n `import \"${alias}\";\\n` +\n \"\\n\" +\n \"// Nitro requires every plugin file to default-export a function; the injection\\n\" +\n \"// above already ran at import, so this body is intentionally empty.\\n\" +\n \"export default defineNitroPlugin(() => {});\\n\",\n ifPresent: `Create server/plugins/0.penv.ts with \\`import \"${alias}\";\\` and \\`export default defineNitroPlugin(() => {});\\`.`,\n notes: [\n `Wire \\`${alias}\\` for the Nitro (server) build so it never leaks into the client bundle.`,\n ],\n };\n}\n\nfunction bun({ alias }: SeamContext): Seam {\n return {\n kind: \"scaffold\",\n file: \".penv/preload.ts\",\n content:\n \"// Bun evaluates this file before your entry point, because it is listed under\\n\" +\n \"// `preload` in bunfig.toml. Running it injects your config into process.env\\n\" +\n \"// before any library reads it.\\n\" +\n `import \"${alias}\";\\n`,\n ifPresent: `Keep .penv/preload.ts as \\`import \"${alias}\";\\`.`,\n notes: [`\\`${alias}\\` must be a tsconfig \\`paths\\` alias for Bun to resolve it.`],\n // The preload file is inert until bunfig.toml points at it — so penv writes\n // that too, both for the runtime and for `bun test`. Only when there is no\n // bunfig to overwrite; an existing one is the user's, and penv prints instead.\n also: {\n file: \"bunfig.toml\",\n content: 'preload = [\"./.penv/preload.ts\"]\\n\\n[test]\\npreload = [\"./.penv/preload.ts\"]\\n',\n ifPresent:\n 'Add \"./.penv/preload.ts\" to the `preload` array in bunfig.toml — and mirror it under `[test]` so `bun test` injects too.',\n },\n };\n}\n\nfunction node({ alias, schemaFile }: SeamContext): Seam {\n // Plain Node owns no pre-app file, and `@env` (a tsconfig alias) does not\n // resolve at raw-Node runtime — so steer to `#env` (a package.json imports\n // alias Node resolves itself), or the built schema module by path when the\n // project is on `@env`. The path is the schema module's own location (`.penv/`\n // is at the repo root, never under `src/`), with `.ts` swapped for the emitted\n // `.js`.\n const builtSchema = `./${schemaFile.replace(/\\.ts$/, \".js\")}`;\n const runtimeSpecifier = alias.startsWith(\"#\") ? alias : builtSchema;\n return {\n kind: \"instruct\",\n instruction:\n \"Plain Node / Express / Fastify have no framework hook that runs before your\\n\" +\n \"code, so place the injection yourself, one of two ways (both run first):\\n\" +\n ` • Preload at launch — add to your start script: node --import \"${runtimeSpecifier}\" your-entry.js\\n` +\n ` • Or make it the FIRST line of your entry file: import \"${runtimeSpecifier}\";\\n` +\n (alias.startsWith(\"#\")\n ? \"\"\n : `Note: \\`${alias}\\` is a tsconfig alias that Node does not resolve at runtime — the paths above point at the built schema module instead.\\n`),\n };\n}\n\nfunction tanstack({ alias, srcDir }: SeamContext): Seam {\n // TanStack Start's server entry carries version-shaped boilerplate, so penv\n // prints the line rather than scaffold boilerplate that could drift.\n return {\n kind: \"instruct\",\n instruction:\n `Add \\`import \"${alias}\";\\` as the FIRST line of ${srcDir}server.ts (TanStack Start's\\n` +\n \"server entry), above the `@tanstack/react-start/server-entry` import — nothing may\\n\" +\n \"import before it. If you have no server.ts yet, create it from TanStack's server-entry\\n\" +\n \"template and put that import first.\",\n };\n}\n\nfunction astro({ alias }: SeamContext): Seam {\n return {\n kind: \"instruct\",\n instruction:\n \"Astro has no single pre-app hook. Add a small integration to astro.config that\\n\" +\n \"injects the import into every SSR page, then cover the routes it cannot reach:\\n\" +\n \" • In astro.config integrations, add:\\n\" +\n ' { name: \"penv\", hooks: { \"astro:config:setup\": ({ injectScript }) =>\\n' +\n ` injectScript(\"page-ssr\", 'import \"${alias}\";') } }\\n` +\n ` • Also add \\`import \"${alias}\";\\` as the first line of src/middleware.ts and of any\\n` +\n \" endpoint route (src/pages/*.ts) that imports a library reading process.env.\\n\" +\n \"Injection only applies under a server (on-demand) adapter, not a static build.\",\n };\n}\n\nfunction viteSpa(_context: SeamContext): Seam {\n return {\n kind: \"none\",\n reason:\n \"This is a client-only app — nothing reads process.env at runtime, so injection \" +\n \"does not apply. Read client config through import.meta.env (only VITE_-prefixed \" +\n \"vars, which ship to the browser and must not hold secrets). If you add a server \" +\n \"later, place the injection there.\",\n };\n}\n\n/**\n * The seam for a framework, keyed by the name {@link import(\"./detect.js\").Detected}\n * carries. A framework penv recognises but has no seam entry for falls back to the\n * plain-Node instruction, which works for any runtime.\n */\nconst SEAMS: Readonly<Record<string, SeamFor>> = {\n \"Next.js\": nextjs,\n SvelteKit: sveltekit,\n Nuxt: nuxt,\n Bun: bun,\n \"TanStack Start\": tanstack,\n Astro: astro,\n Vite: viteSpa,\n};\n\n/**\n * The seam for a detected framework, or the universal plain-Node instruction when\n * penv has no framework-specific one — that instruction runs before app code on\n * any runtime, so it is a correct fallback rather than a guess.\n */\nexport function seamFor(framework: string | undefined, context: SeamContext): Seam {\n const build = framework === undefined ? node : (SEAMS[framework] ?? node);\n return build(context);\n}\n","/**\n * `penv key create --env <e>` — mint a key of the right shape.\n *\n * This exists because `penv encrypt` refuses to invent one. A key penv generated\n * behind your back is a key nobody can reproduce, restore, or rotate, and the\n * first time it matters is the first time it is gone. So minting is its own act,\n * run deliberately, and the key it prints is yours to store.\n *\n * Where penv stores it depends on the source. With `env`, the key *is* whatever\n * the process environment holds — a deploy unwraps it from a KMS and exports it —\n * so there is nowhere for penv to put it that would not be the repo-adjacent file\n * the design forbids; printing the export line is the whole job. With `keychain`,\n * the OS keychain is exactly the place a key may live, so penv stores it there and\n * prints nothing to copy — the key exists in one place, on this machine, which is\n * the point of the keychain.\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport type { Keychain } from \"@penvhq/core\";\nimport { KEY_BYTES, KEYCHAIN_SERVICE, keyConfigFor, PenvError } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { defaultKeychain } from \"../keychain.js\";\nimport { openProject, targetEnvironment } from \"../project.js\";\nimport { out } from \"../style.js\";\nimport { CHECK, guard, write } from \"../ui.js\";\n\nexport interface KeyCreateOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Replace an existing keychain key instead of refusing. Orphans values sealed under the old one. */\n readonly force?: boolean;\n /** Injected in tests: the keychain to store into. Defaults to the real OS binding. */\n readonly keychain?: Keychain;\n}\n\nexport interface KeyCreateResult {\n readonly source: \"env\" | \"keychain\";\n readonly environment: string;\n readonly id: string;\n /** Env source only: the variable to export the key under. */\n readonly variable?: string;\n /** Env source only: the key, base64, ready to export. penv holds no copy. */\n readonly key?: string;\n}\n\n/** Mirrors the transform in core's env key source, which is the thing that reads it. */\nfunction envVarFor(id: string): string {\n return `PENV_KEY_${id.replace(/[^A-Za-z0-9]/g, \"_\").toUpperCase()}`;\n}\n\nexport function runKeyCreate(options: KeyCreateOptions): KeyCreateResult {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment);\n\n const declared = keyConfigFor(project.config, environment);\n if (declared === undefined) {\n throw new PenvError(\n \"KEY_SOURCE_UNDECLARED\",\n `Environment ${environment} declares no key source, so penv does not know what a key for it would be`,\n `Give its entry in penv.config.ts a \\`keySource\\` — e.g. \\`${environment}: { provider: ` +\n `\"@penvhq/provider-filesystem\", keySource: \"env\" }\\` — then run this again. The key is named ` +\n \"after the environment unless the object form names another.\",\n );\n }\n\n const key = randomBytes(KEY_BYTES).toString(\"base64\");\n\n if (declared.source === \"keychain\") {\n const keychain = options.keychain ?? defaultKeychain;\n if (options.force !== true) {\n // Replacing the key orphans every value already sealed under the old one —\n // they could never be decrypted again. Refuse unless the user forces it.\n let existing: string | null;\n try {\n existing = keychain.getPassword(KEYCHAIN_SERVICE, declared.id);\n } catch (cause) {\n // The binding being absent already carries its own remedy, and it is not\n // \"unlock your keychain\" — that advice would send the user to a keychain\n // penv never reached.\n if (cause instanceof PenvError) {\n throw cause;\n }\n throw new PenvError(\n \"KEYCHAIN_UNAVAILABLE\",\n `penv could not read your OS keychain to check for an existing key \\`${declared.id}\\``,\n `Unlock your keychain and run this again. Original error: ${cause instanceof Error ? cause.message : String(cause)}`,\n );\n }\n if (existing !== null) {\n throw new PenvError(\n \"KEY_EXISTS\",\n `Environment ${environment} already has a key \\`${declared.id}\\` in your OS keychain`,\n \"Replacing it would orphan every value already sealed under it — they could never be \" +\n \"decrypted again. Re-run with `--force` only if you are certain nothing is sealed under \" +\n \"the current key.\",\n );\n }\n }\n keychain.setPassword(KEYCHAIN_SERVICE, declared.id, key);\n return { source: \"keychain\", environment, id: declared.id };\n }\n\n return {\n source: \"env\",\n environment,\n id: declared.id,\n variable: envVarFor(declared.id),\n key,\n };\n}\n\nexport function renderKeyCreate(result: KeyCreateResult): string[] {\n if (result.source === \"keychain\") {\n return [\n `${out.green(CHECK)} A new key for environment ${result.environment}, stored in your OS keychain as \\`${result.id}\\`.`,\n \"\",\n out.dim(\n \"penv kept no copy. Anything sealed under it is unreadable without your keychain, and running\",\n ),\n out.dim(\n \"`penv key create` again would replace it — so it lives in exactly one place, on this machine.\",\n ),\n ];\n }\n return [\n `${out.green(CHECK)} A new key for environment ${result.environment}. penv did not store it.`,\n \"\",\n ` ${out.cyan(`${result.variable}=${result.key}`)}`,\n \"\",\n out.dim(\n \"Export it where penv runs, and put it wherever this environment's secrets already live —\",\n ),\n out.dim(\n \"a KMS, your CI's secret store, a password manager. Anything sealed under it is unreadable\",\n ),\n out.dim(\"without it, and penv keeps no copy to fall back on.\"),\n ];\n}\n\nexport const keyCommand = defineCommand({\n meta: { name: \"key\", description: \"Work with encryption keys\" },\n subCommands: {\n create: defineCommand({\n meta: { name: \"create\", description: \"Generate a key for an environment\" },\n args: {\n env: { type: \"string\", description: \"The environment the key is for\" },\n force: {\n type: \"boolean\",\n description: \"Replace an existing keychain key (orphans values sealed under the old one)\",\n },\n },\n run({ args }) {\n return guard(async () => {\n write(\n renderKeyCreate(\n runKeyCreate({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.force === undefined ? {} : { force: args.force }),\n }),\n ),\n );\n });\n },\n }),\n },\n});\n","/**\n * The OS-keychain binding, and the one place the native module is touched.\n *\n * `@penvhq/core` defines the `Keychain` contract but carries no native dependency:\n * `load` runs in every deploy, and a native module in the runtime's tree is a\n * build failure in someone's container. So the binding lives here, in the CLI —\n * whose dependency budget is looser and which never ships inside a user's app —\n * and is registered into core (see `runMain`). Where it is never registered (the\n * runtime), a keychain source answers `unavailable`, which is the honest verdict.\n *\n * The native module is required lazily, so it loads only when a keychain key is\n * actually read or written — never merely because the CLI started, and never on\n * an env-source path that has no business touching it. That laziness is load\n * bearing twice over: an engine installed from an npm tarball into `$PENV_HOME`\n * has no `node_modules`, so the binding is genuinely absent there, and every\n * command that is not a keychain command must still work.\n */\n\nimport { createRequire } from \"node:module\";\nimport { type Keychain, PenvError } from \"@penvhq/core\";\n\n/** The native package this binding is. Named in the refusal, so it is a constant. */\nexport const KEYRING_MODULE = \"@napi-rs/keyring\";\n\n/** The synchronous slice of `@napi-rs/keyring`'s `Entry` this binding uses. */\ninterface Entry {\n getPassword(): string | null;\n setPassword(password: string): void;\n}\ntype EntryConstructor = new (service: string, account: string) => Entry;\n\n/** How the native module is reached. Injected in tests; nothing else replaces it. */\nexport type NativeLoader = (id: string) => unknown;\n\nconst nodeRequire: NativeLoader = (id) => createRequire(import.meta.url)(id);\n\n/** Node appends a require stack to a resolution failure; the sentence is the useful part. */\nfunction firstLine(cause: unknown): string {\n return (cause instanceof Error ? cause.message : String(cause)).split(\"\\n\")[0] ?? \"\";\n}\n\n/**\n * The binding is missing, which is neither \"the keychain is locked\" nor \"there is\n * no such key\" — it is penv having no way to ask at all, and it has one cause.\n */\nfunction keyringMissing(cause: unknown): PenvError {\n return new PenvError(\n \"KEYCHAIN_BINDING_MISSING\",\n `penv could not load ${KEYRING_MODULE}, the native binding it reads your OS keychain through`,\n `This penv engine was installed as a plain tarball, which carries no native modules. ` +\n `Install penv with \\`npm install -g @penvhq/launcher\\`, or declare \\`source: \"env\"\\` for ` +\n `this environment and export its key. Original error: ${firstLine(cause)}`,\n );\n}\n\n/**\n * The real binding, backed by `@napi-rs/keyring`'s synchronous `Entry`. Its\n * `getPassword` returns `null` for a missing entry (never throws for absence) and\n * throws only when the keychain genuinely cannot be read — which the core source\n * turns into `unavailable`, not `absent`.\n */\nexport function createKeychain(load: NativeLoader = nodeRequire): Keychain {\n let cached: EntryConstructor | undefined;\n\n const entryConstructor = (): EntryConstructor => {\n if (cached === undefined) {\n let module: { Entry: EntryConstructor };\n try {\n module = load(KEYRING_MODULE) as { Entry: EntryConstructor };\n } catch (cause) {\n throw keyringMissing(cause);\n }\n cached = module.Entry;\n }\n return cached;\n };\n\n return {\n getPassword(service, account) {\n const Entry = entryConstructor();\n return new Entry(service, account).getPassword();\n },\n setPassword(service, account, password) {\n const Entry = entryConstructor();\n new Entry(service, account).setPassword(password);\n },\n };\n}\n\nexport const defaultKeychain: Keychain = createKeychain();\n","/**\n * `penv list` — every parameter, and the scope that wins for one environment.\n *\n * The winning scope is the point: `production` and `default` are both \"it\n * resolves\", and only one of them means the value was written for production.\n */\n\nimport type { Scope } from \"@penvhq/core\";\nimport { assertNever, RECORDS_PATH, resolveAll, variableName } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { keySourceFor, openProject, targetEnvironment } from \"../project.js\";\nimport { out } from \"../style.js\";\nimport { columns, guard, heading, tip, write } from \"../ui.js\";\n\nexport interface ListOptions {\n readonly cwd: string;\n readonly environment?: string;\n}\n\nexport interface ListEntry {\n readonly parameter: string;\n /** The generated `.env` variable, so the two names are legible side by side. */\n readonly variable: string;\n /** `<env>.local`, `local`, an environment name, `default`, or `absent`. */\n readonly scope: string;\n /** The winning value file relative to the records tree, or `undefined` when nothing wins. */\n readonly location: string | undefined;\n readonly encrypted: boolean;\n readonly viaUnscopedFallback: boolean;\n}\n\nexport interface ListResult {\n readonly environment: string;\n readonly parameters: readonly ListEntry[];\n}\n\n/**\n * The cascade level a winning scope names, spelled as its filename suffix so the\n * column reads back as the file on disk. Each of the four levels is distinct:\n * `production.local` and `local` are different files with different reach, and a\n * column that called both `local` would hide which one won.\n */\nfunction scopeLabel(scope: Scope): string {\n switch (scope.kind) {\n case \"environment\":\n return scope.environment;\n case \"local\":\n return \"local\";\n case \"environment-local\":\n return `${scope.environment}.local`;\n case \"unscoped\":\n return \"default\";\n default:\n return assertNever(scope, \"scope\");\n }\n}\n\nexport async function runList(options: ListOptions): Promise<ListResult> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment);\n\n const keys = keySourceFor(project, environment);\n const parameters: ListEntry[] = [];\n // `list` names which file wins, never a value, so an undecryptable winner is\n // listed exactly like any other: the scope column is the answer here.\n for (const resolution of await resolveAll(environment, project.provider, keys)) {\n const winner = resolution.winner;\n const scope = winner?.file.scope;\n parameters.push({\n parameter: resolution.parameter,\n variable: variableName(resolution.ref, project.config),\n scope: scope === undefined ? \"absent\" : scopeLabel(scope),\n location: winner?.location,\n encrypted: winner?.file.encrypted === true,\n viaUnscopedFallback: resolution.viaUnscopedFallback,\n });\n }\n\n return { environment, parameters };\n}\n\n/**\n * The scope column is the report, so it carries the verdict's color: green for a\n * value written for this environment, yellow for the silent-drift shapes —\n * `absent`, and a real environment riding the unscoped default (invariant 13:\n * fallback is never silent) — and plain for everything else.\n */\nfunction paintScope(entry: ListEntry): string {\n if (entry.scope === \"absent\" || entry.viaUnscopedFallback) {\n return out.yellow(entry.scope);\n }\n return out.green(entry.scope);\n}\n\nexport function renderList(result: ListResult): string[] {\n if (result.parameters.length === 0) {\n return [\n `No parameters in ${RECORDS_PATH}/ for environment ${result.environment}.`,\n tip(`penv set <key> --env ${result.environment}`),\n ];\n }\n const header = [\"parameter\", \"scope\", \"variable\", \"\"].map((cell) => out.dim(cell));\n const rows = result.parameters.map((entry) => [\n entry.parameter,\n paintScope(entry),\n entry.variable,\n entry.encrypted ? out.dim(\"encrypted\") : \"\",\n ]);\n return [\n heading(\"penv list\", `environment ${result.environment}`),\n \"\",\n ...columns([header, ...rows]),\n ];\n}\n\nexport const listCommand = defineCommand({\n meta: { name: \"list\", description: \"List parameters\" },\n args: {\n env: { type: \"string\", description: \"The environment to resolve against\" },\n json: { type: \"boolean\", description: \"Print machine-readable JSON\" },\n },\n run({ args }) {\n return guard(async () => {\n const result = await runList({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n });\n write(args.json === true ? [JSON.stringify(result, null, 2)] : renderList(result));\n });\n },\n});\n","/**\n * `penv migrate` — move a project's records under `.penv/state/records/`.\n *\n * penv reads one layout, so this is the one command that knows two. It is a\n * relocation and nothing else: records move byte for byte, keeping their names,\n * so the grammar, the cascade, the meta and the AAD that binds a ciphertext to\n * its address all mean afterwards exactly what they meant before.\n * `penv.schema.ts`, `penv.config.ts` and `.penv/env.ts` are the project's, and\n * are never touched.\n *\n * It previews before it moves, because the one thing a migration must not do is\n * surprise the person who ran it — and it refuses a half-migrated tree rather\n * than merging two, since which copy of a parameter is current is a question\n * only the user can answer.\n */\n\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\nimport {\n loadConfig,\n oldLayoutEntries,\n PENV_DIR,\n PenvError,\n RECORDS_PATH,\n recordsDir,\n renderStateGitignore,\n STATE_GITIGNORE_PATH,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { out } from \"../style.js\";\nimport { CHECK, formatSteps, guard, prompt, type Step, tip, write } from \"../ui.js\";\n\n/** The ignore file the old layout kept its boundary in, which this command replaces. */\nconst OLD_GITIGNORE = `${PENV_DIR}/.gitignore`;\n\n/** One thing that moves, project-relative and POSIX. */\nexport interface MigrateMove {\n readonly from: string;\n readonly to: string;\n}\n\nexport interface MigratePlan {\n readonly root: string;\n /** What moves, in the order it is reported. */\n readonly moves: readonly MigrateMove[];\n /** What penv writes that is not there yet — the tree root and the safety boundary. */\n readonly creates: readonly string[];\n /** What penv removes: the ignore file that described the old layout. */\n readonly removes: readonly string[];\n}\n\n/**\n * `previewed` is a plan nobody approved, so nothing was written; `current` is a\n * project that was already on the new layout, which is what a second run says.\n */\nexport type MigrateStatus = \"migrated\" | \"current\" | \"previewed\";\n\nexport interface MigrateResult extends MigratePlan {\n readonly status: MigrateStatus;\n}\n\nexport interface MigrateOptions {\n readonly cwd: string;\n /** Approve the plan. Without it `migrate` previews and writes nothing. */\n readonly yes?: boolean;\n}\n\n/**\n * What a migration would do, without doing any of it.\n *\n * The move list is `oldLayoutEntries` — the same list every command's refusal is\n * keyed off — so the preview can never describe a different migration from the\n * one that runs.\n */\nexport function planMigrate(cwd: string): MigratePlan {\n const { config, file } = loadConfig(cwd);\n const root = dirname(file);\n const entries = oldLayoutEntries(root, config);\n const tree = recordsDir(root);\n\n // Only a name on both sides is a question penv cannot answer: two copies of one\n // record, and moving would pick a winner silently. Entries the tree does not\n // hold are simply the rest of the migration — an interruption between two\n // renames leaves exactly that, and refusing it wedged the project, since every\n // other command answers an old-layout tree by naming this one.\n const collisions = collidingEntries(entries, tree);\n if (collisions.length > 0) {\n throw new PenvError(\n \"HALF_MIGRATED\",\n `${describe(collisions)} in both \\`${PENV_DIR}/\\` and \\`${RECORDS_PATH}/\\`, and penv cannot tell which copy is current`,\n `Move what is left under \\`${PENV_DIR}/\\` into \\`${RECORDS_PATH}/\\` yourself, keeping the copy you want, then run \\`penv validate\\`.`,\n );\n }\n\n const creates: string[] = [];\n if (entries.length > 0 && !existsSync(tree)) {\n creates.push(`${RECORDS_PATH}/`);\n }\n if (\n readIfPresent(join(root, ...STATE_GITIGNORE_PATH.split(\"/\"))) !== renderStateGitignore(config)\n ) {\n creates.push(STATE_GITIGNORE_PATH);\n }\n\n return {\n root,\n moves: entries.map((entry) => ({\n from: `${PENV_DIR}/${entry}`,\n to: `${RECORDS_PATH}/${entry}`,\n })),\n creates,\n removes: existsSync(join(root, ...OLD_GITIGNORE.split(\"/\"))) ? [OLD_GITIGNORE] : [],\n };\n}\n\nfunction readIfPresent(file: string): string | undefined {\n return existsSync(file) ? readFileSync(file, \"utf8\") : undefined;\n}\n\n/**\n * The names the move would land on top of, sorted.\n *\n * Folded to lower case, because on a case-insensitive filesystem `DB` and `db`\n * are one name and the rename would overwrite rather than collide.\n */\nfunction collidingEntries(entries: readonly string[], tree: string): string[] {\n let held: string[];\n try {\n held = readdirSync(tree);\n } catch {\n return [];\n }\n const taken = new Set(held.map((name) => name.toLowerCase()));\n return entries.filter((entry) => taken.has(entry.toLowerCase())).sort();\n}\n\nfunction describe(names: readonly string[]): string {\n return names.length === 1\n ? `\\`${names[0]}\\` is`\n : `${names.map((name) => `\\`${name}\\``).join(\", \")} are`;\n}\n\n/** True when a plan would change nothing at all. */\nexport function isNoop(plan: MigratePlan): boolean {\n return plan.moves.length === 0 && plan.creates.length === 0 && plan.removes.length === 0;\n}\n\n/**\n * Performs a plan. Separate from {@link planMigrate} so what runs is the plan the\n * user approved, not a second reading of the disk between the question and the\n * answer.\n */\nexport function applyMigrate(plan: MigratePlan): MigrateResult {\n if (isNoop(plan)) {\n return { ...plan, status: \"current\" };\n }\n\n const { config } = loadConfig(plan.root);\n if (plan.moves.length > 0) {\n mkdirSync(recordsDir(plan.root), { recursive: true });\n for (const move of plan.moves) {\n renameSync(join(plan.root, ...move.from.split(\"/\")), join(plan.root, ...move.to.split(\"/\")));\n }\n }\n\n // The new boundary is written before the old one goes, so the records this\n // command just moved are never unignored for an instant. The old one still has\n // to go: left in place it would keep ignoring `.penv/env.ts`, which the new\n // layout commits.\n if (plan.creates.includes(STATE_GITIGNORE_PATH)) {\n const ignore = join(plan.root, ...STATE_GITIGNORE_PATH.split(\"/\"));\n mkdirSync(dirname(ignore), { recursive: true });\n writeFileSync(ignore, renderStateGitignore(config), \"utf8\");\n }\n\n for (const removed of plan.removes) {\n rmSync(join(plan.root, ...removed.split(\"/\")), { force: true });\n }\n\n return { ...plan, status: \"migrated\" };\n}\n\n/** Plans, and applies only when the move was approved. */\nexport function runMigrate(options: MigrateOptions): MigrateResult {\n const plan = planMigrate(options.cwd);\n if (isNoop(plan)) {\n return { ...plan, status: \"current\" };\n }\n return options.yes === true ? applyMigrate(plan) : { ...plan, status: \"previewed\" };\n}\n\nexport function renderMigrate(result: MigrateResult): string[] {\n if (result.status === \"current\") {\n return [`${out.green(CHECK)} Already on ${RECORDS_PATH}/ — nothing to migrate.`];\n }\n\n const done = result.status === \"migrated\";\n const glyph = done ? CHECK : \"→\";\n const steps: Step[] = [\n ...result.moves.map((move) => ({\n glyph,\n text: `${done ? \"Moved\" : \"Move\"} ${move.from}`,\n note: `to ${move.to}`,\n })),\n ...result.creates.map((created) => ({ glyph, text: `${done ? \"Wrote\" : \"Write\"} ${created}` })),\n ...result.removes.map((removed) => ({\n glyph,\n text: `${done ? \"Removed\" : \"Remove\"} ${removed}`,\n note: `replaced by ${STATE_GITIGNORE_PATH}`,\n })),\n ];\n\n return [\n ...formatSteps(steps),\n \"\",\n ...(done\n ? [\n `${out.green(CHECK)} ${out.bold(\"Migrated.\")} Commit the move, then:`,\n tip(out.cyan(\"penv validate\")),\n ]\n : [\n \"Your schema, config and loader are untouched, and every record keeps its name.\",\n tip(out.cyan(\"penv migrate --yes\")),\n ]),\n ];\n}\n\n/** The question, asked only against a real terminal — anything else has nobody to ask. */\nasync function approveOnTty(): Promise<boolean> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const answer = await rl.question(prompt(\"Move them\", \"y/N\"));\n return /^y(es)?$/i.test(answer.trim());\n } finally {\n rl.close();\n }\n}\n\nexport const migrateCommand = defineCommand({\n meta: {\n name: \"migrate\",\n description: `Move a project written under an earlier layout to ${RECORDS_PATH}/`,\n },\n args: {\n yes: { type: \"boolean\", description: \"Apply the previewed move without asking\" },\n },\n run({ args }) {\n return guard(async () => {\n const plan = planMigrate(process.cwd());\n if (isNoop(plan)) {\n write(renderMigrate({ ...plan, status: \"current\" }));\n return;\n }\n\n write(renderMigrate({ ...plan, status: \"previewed\" }));\n const approved =\n args.yes === true || (process.stdin.isTTY === true && (await approveOnTty()));\n if (!approved) {\n return;\n }\n write([\"\", ...renderMigrate(applyMigrate(plan))]);\n });\n },\n});\n","/**\n * `penv mv <from> <to>` — rename a parameter, every scope at once.\n *\n * A parameter is not one file. It is up to eight — four cascade levels, each\n * with a plaintext and an encrypted address — plus its meta, and a rename that\n * moved some of them would split one parameter into two. So this moves all of\n * them or none of them, and the whole plan is checked before a single byte is\n * written.\n *\n * **This is the only correct way to move an encrypted value.** A ciphertext is\n * sealed against the address it lives at, so `mv redis-password.production.enc\n * redis/password.production.enc` at the shell produces a file that will never\n * open again — the value is not moved, it is destroyed, and the shell reports\n * success. Re-sealing at the new address is the whole reason this command\n * exists: penv asked for namespacing to be \"a deliberate refactor afterwards\"\n * and then, once values could be encrypted, made doing it by hand a way to lose\n * them.\n *\n * It moves the tree and never the schema. `.penv/env.ts` is yours (invariant 2),\n * so renaming `database-url` to `database/url` leaves it declaring the old access\n * path — and the drift report is what says so. penv names the distance; you close\n * it. This command's report says which line to change rather than changing it.\n */\n\nimport type { Meta, ParameterRef, ValueFile } from \"@penvhq/core\";\nimport {\n accessPath,\n formatMetaFile,\n formatValueFile,\n openValue,\n PenvError,\n parameterId,\n recordPath,\n sealValue,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { Project } from \"../project.js\";\nimport {\n assertWritableKey,\n keySourceFor,\n openProject,\n refFromKey,\n schemaShapeFileOf,\n} from \"../project.js\";\nimport { CHECK, formatRows, guard, type Row, tip, write } from \"../ui.js\";\n\nexport interface MoveOptions {\n readonly cwd: string;\n readonly from: string;\n readonly to: string;\n}\n\nexport interface MovedFile {\n readonly from: string;\n readonly to: string;\n /** True when the value was opened and sealed again for its new address. */\n readonly resealed: boolean;\n}\n\nexport interface MoveResult {\n readonly from: string;\n readonly to: string;\n readonly files: readonly MovedFile[];\n /** The meta file's new location, or `undefined` when the parameter had none. */\n readonly meta: string | undefined;\n /** The access path the schema still declares, and the one it should now. */\n readonly schema: { readonly was: string; readonly now: string };\n /** The file that holds the shape to rename — cohort-aware, so the tip names one that exists. */\n readonly schemaFile: string;\n}\n\n/** The environment a scope names, or `undefined` for the scopes that name none. */\nfunction environmentOf(file: ValueFile): string | undefined {\n const scope = file.scope;\n return scope.kind === \"environment\" || scope.kind === \"environment-local\"\n ? scope.environment\n : undefined;\n}\n\n/** One file's move, resolved to the bytes that will be written at the far end. */\ninterface Planned {\n readonly source: ValueFile;\n readonly target: ValueFile;\n readonly contents: string;\n readonly resealed: boolean;\n}\n\n/**\n * Reads one file and works out what it must say at its new address.\n *\n * A plaintext value is bytes and moves as bytes. An encrypted one cannot: the\n * address is authenticated, so the ciphertext is only valid where it is. It is\n * opened here and sealed again below — and if it cannot be opened, the whole move\n * is refused rather than carrying a file to a place it will never open from.\n */\nasync function planFile(\n project: Project,\n source: ValueFile,\n target: ValueFile,\n parameter: string,\n): Promise<Planned | undefined> {\n const stored = await project.provider.read(source);\n if (stored === undefined) {\n return undefined;\n }\n if (!source.encrypted) {\n return { source, target, contents: stored, resealed: false };\n }\n\n // A key is declared per environment, so a sealed value at a scope that names\n // none has no key penv can choose — the same refusal `penv set` makes, for the\n // same reason, and the same one that keeps penv from creating such a file.\n const environment = environmentOf(source);\n if (environment === undefined) {\n throw new PenvError(\n \"SECRET_SCOPE_AMBIGUOUS\",\n `${recordPath(formatValueFile(source))} is encrypted at a scope that names no environment, so penv cannot tell which key would re-seal it`,\n \"A key is declared by its environment's `keySource` in penv.config.ts. Decrypt it with \" +\n \"`penv decrypt`, move the parameter, then encrypt it again at its new address.\",\n );\n }\n\n const keys = keySourceFor(project, environment);\n const opened = openValue(source, stored, keys);\n if (opened.kind === \"failed\") {\n throw new PenvError(\n \"VALUE_UNDECRYPTABLE\",\n `${recordPath(formatValueFile(source))} could not be decrypted, so penv cannot re-seal it at its new address: ${opened.failure.detail}`,\n \"A sealed value is bound to the file it lives in, so moving it means opening it and \" +\n \"sealing it again. Make the key available and run this again. Nothing has been moved.\",\n );\n }\n\n return {\n source,\n target,\n contents: sealValue(target, opened.value, keys, parameter, environment),\n resealed: true,\n };\n}\n\n/** Every file the provider actually holds for one parameter. */\nfunction filesOf(all: readonly ValueFile[], ref: ParameterRef): ValueFile[] {\n const id = parameterId(ref);\n return all.filter((file) => parameterId(file) === id);\n}\n\nexport async function runMove(options: MoveOptions): Promise<MoveResult> {\n const project = openProject(options.cwd);\n const from = refFromKey(options.from, project.config);\n assertWritableKey(options.to);\n const to = refFromKey(options.to, project.config);\n\n if (parameterId(from) === parameterId(to)) {\n throw new PenvError(\n \"PARAMETER_UNCHANGED\",\n `\\`${options.from}\\` and \\`${options.to}\\` are the same parameter`,\n \"Name a different destination, e.g. `penv mv redis-password redis/password`.\",\n );\n }\n\n const all = await project.provider.list();\n const sources = filesOf(all, from);\n const meta: Meta | undefined = await project.provider.readMeta(from);\n\n if (sources.length === 0 && meta === undefined) {\n throw new PenvError(\n \"PARAMETER_ABSENT\",\n `Parameter ${parameterId(from)} has no value files and no meta, so there is nothing to move`,\n `\\`penv list\\` shows every parameter penv holds.`,\n );\n }\n\n // Nothing is overwritten, ever. A destination that already exists is two\n // parameters being merged into one, which loses whichever penv wrote second —\n // the same loss `validate` refuses for name collisions (invariant 12).\n const occupied = filesOf(all, to);\n if (occupied.length > 0 || (await project.provider.readMeta(to)) !== undefined) {\n throw new PenvError(\n \"PARAMETER_EXISTS\",\n `Parameter ${parameterId(to)} already exists, and penv will not merge two parameters into one`,\n `Remove or rename ${parameterId(to)} first. \\`penv get ${options.to} --explain\\` shows every file it holds.`,\n );\n }\n\n // Planned in full before anything is written. Every read, every decryption and\n // every key lookup happens here, so a move that cannot finish fails having\n // changed nothing — rather than halfway, with a parameter that is now two.\n const planned: Planned[] = [];\n for (const source of sources) {\n const target: ValueFile = { ...source, namespace: to.namespace, name: to.name };\n const one = await planFile(project, source, target, parameterId(to));\n if (one !== undefined) {\n planned.push(one);\n }\n }\n\n for (const file of planned) {\n await project.provider.write(file.target, file.contents);\n }\n if (meta !== undefined) {\n await project.provider.writeMeta(to, meta);\n }\n\n // Removed only once every new file is on disk, so the value is never in\n // neither place. The cost is a window where it is in both, which a crash\n // leaves recoverable; the reverse leaves it gone.\n for (const file of planned) {\n await project.provider.remove(file.source);\n }\n if (meta !== undefined) {\n await project.provider.removeMeta(from);\n }\n\n return {\n from: parameterId(from),\n to: parameterId(to),\n files: planned.map((file) => ({\n from: formatValueFile(file.source),\n to: formatValueFile(file.target),\n resealed: file.resealed,\n })),\n // The meta's path, not the parameter's dotted id: `redis.password` is what\n // the schema calls it and `redis/password.json` is the file, and a report\n // that printed the first while moving the second names no file on disk.\n meta: meta === undefined ? undefined : formatMetaFile({ ...to, format: \"json\" }),\n schema: { was: accessPath(from).join(\".\"), now: accessPath(to).join(\".\") },\n schemaFile: schemaShapeFileOf(project),\n };\n}\n\nexport function renderMove(result: MoveResult): string[] {\n const rows: Row[] = result.files.map((file) => ({\n glyph: CHECK,\n label: \"Moved\",\n subject: recordPath(file.to),\n ...(file.resealed ? { detail: \"re-sealed for its new address\" } : {}),\n }));\n if (result.meta !== undefined) {\n rows.push({ glyph: CHECK, label: \"Moved\", subject: recordPath(result.meta) });\n }\n\n const lines = formatRows(rows);\n // The tree moved and the schema did not, because the schema is the user's file\n // and penv does not write it. Saying so here is cheaper than letting them find\n // out from a failing `validate` — and it names the edit rather than the fault.\n lines.push(\n \"\",\n tip(\n `${result.schemaFile} still declares \\`${result.schema.was}\\` — rename it to \\`${result.schema.now}\\`, ` +\n \"or `penv validate` will report the value as unused and the declaration as unset.\",\n ),\n );\n return lines;\n}\n\nexport const mvCommand = defineCommand({\n meta: { name: \"mv\", description: \"Rename a parameter, every scope and its meta at once\" },\n args: {\n from: {\n type: \"positional\",\n required: true,\n description: \"The parameter now, e.g. redis-password\",\n },\n to: {\n type: \"positional\",\n required: true,\n description: \"The parameter after, e.g. redis/password\",\n },\n },\n run({ args }) {\n return guard(async () => {\n write(renderMove(await runMove({ cwd: process.cwd(), from: args.from, to: args.to })));\n });\n },\n});\n","/**\n * `penv remove <key>` — delete one value file.\n *\n * The scope is selected exactly as `penv set` selects it, so what you removed is\n * the file you would have written. Meta is left alone: policy is a property of\n * the parameter across every environment, not of the value you just deleted.\n */\n\nimport type { ValueFile } from \"@penvhq/core\";\nimport { formatValueFile, recordPath } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { openProject, refFromKey } from \"../project.js\";\nimport { CHECK, formatRows, guard, type Row, WARN, write } from \"../ui.js\";\nimport { type ScopeOptions, targetScope } from \"./set.js\";\n\nexport interface RemoveOptions extends ScopeOptions {\n readonly cwd: string;\n readonly key: string;\n}\n\nexport interface RemoveResult {\n readonly parameter: string;\n /** The value files that existed and are now gone, relative to the records tree. */\n readonly removed: readonly string[];\n /** Both files penv looked at, whether or not they were there. */\n readonly considered: readonly string[];\n}\n\nexport async function runRemove(options: RemoveOptions): Promise<RemoveResult> {\n const project = openProject(options.cwd);\n const ref = refFromKey(options.key);\n\n // The same scope selection `set` writes through, for the same reason: the file\n // `remove` names has to be the file `set` named, byte for byte.\n const scope = targetScope(project, options, options.key);\n // `.enc` is orthogonal to scope: the encrypted file at this scope is the same\n // parameter at the same precedence, so removing the scope removes both.\n const files: ValueFile[] = [false, true].map((encrypted) => ({\n namespace: ref.namespace,\n name: ref.name,\n scope,\n encrypted,\n }));\n\n const removed: string[] = [];\n for (const file of files) {\n if ((await project.provider.read(file)) === undefined) {\n continue;\n }\n await project.provider.remove(file);\n removed.push(formatValueFile(file));\n }\n\n return {\n parameter: options.key,\n removed,\n considered: files.map((file) => formatValueFile(file)),\n };\n}\n\nexport function renderRemove(result: RemoveResult): string[] {\n if (result.removed.length === 0) {\n const first = result.considered[0] ?? result.parameter;\n return formatRows([\n {\n glyph: WARN,\n label: \"Nothing to remove\",\n subject: recordPath(first),\n detail: \"no value file at that scope\",\n },\n ]);\n }\n const rows: Row[] = result.removed.map((location) => ({\n glyph: CHECK,\n label: \"Removed\",\n subject: recordPath(location),\n }));\n return formatRows(rows);\n}\n\nexport const removeCommand = defineCommand({\n meta: { name: \"remove\", description: \"Delete a parameter\" },\n args: {\n key: { type: \"positional\", required: true, description: \"The parameter, e.g. redis/password\" },\n env: { type: \"string\", description: \"Remove the <name>.<env> scope\" },\n local: {\n type: \"boolean\",\n description: \"Remove the personal override: <name>.<env>.local with --env, else <name>.local\",\n },\n },\n run({ args }) {\n return guard(async () => {\n write(\n renderRemove(\n await runRemove({\n cwd: process.cwd(),\n key: args.key,\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.local === undefined ? {} : { local: args.local }),\n }),\n ),\n );\n });\n },\n});\n","/**\n * `penv rotate <key>` — turn one parameter over to a new value, by the mechanism\n * its meta declares, against the environment's source-of-truth provider.\n *\n * The two mechanisms are two different physics, never one code path with a flag\n * (rotation.ts says as much). `dual-valid` is a *window*: the new value goes live\n * while the provider still serves the old one, both credentials valid at once,\n * and the window closes only when every reader has moved over. `atomic-cutover`\n * is an *instant*: one flip, old value gone the moment the new one lands, no\n * overlap to hold open. So the command shape mirrors the physics —\n *\n * - `--begin` / `--complete` bracket a `dual-valid` window (`active → rotating →\n * active`), and demand a {@link RetainingProvider}, because a window whose old\n * value the provider does not retain is not a window at all — the overlap the\n * mechanism promises would silently not exist. penv refuses that up front\n * rather than opening a grace window that is a fiction.\n * - a bare `penv rotate` is the `atomic-cutover` flip: write the new value and\n * stamp the completion in one step, never touching `rotatingSince`, never\n * requiring retention — there is no penv-layer overlap to record or to lean on.\n *\n * Like `push`, the real work is an exported plain function returning a structured\n * result, and `now` is injectable so the meta clocks are testable without mocking\n * time. The rotation clock itself lives in core (`beginRotation` /\n * `completeRotation`); this command only decides *which* to apply, writes the\n * value at the right moment relative to it, and persists both to the provider.\n */\n\nimport type {\n Meta,\n ParameterRef,\n Provider,\n RetainingProvider,\n RotationMechanism,\n RotationState,\n ValueFile,\n} from \"@penvhq/core\";\nimport {\n beginRotation,\n completeRotation,\n holdsRecords,\n PenvError,\n retainsPrevious,\n rotationOf,\n} from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport type { Project } from \"../project.js\";\nimport { openProject, refFromKey, sourceProviderFor, targetEnvironment } from \"../project.js\";\nimport { LOCAL_TREE_TYPE } from \"../registry.js\";\nimport { CHECK, formatRows, guard, write } from \"../ui.js\";\nimport { readStdin, sealAwareWrite } from \"./set.js\";\n\nexport interface RotateOptions {\n readonly cwd: string;\n readonly key: string;\n readonly environment?: string;\n /** Open a `dual-valid` window: write the new value while the old is still retained. */\n readonly begin?: boolean;\n /** Close a `dual-valid` window: return to `active`, stamp the completion. */\n readonly complete?: boolean;\n /**\n * The new value. A `begin` and an `atomic-cutover` flip write it; a `complete`\n * does not touch the value at all, so it needs none. Injected in tests; on the\n * CLI it is the positional argument or stdin, the same source `set` reads.\n */\n readonly value?: string;\n /** Injected in tests: the wall-clock reading recorded in meta. Defaults to now. */\n readonly now?: string;\n}\n\n/** The single step a run performed — the three the two mechanisms decompose into. */\nexport type RotatePhase = \"begin\" | \"complete\" | \"cutover\";\n\nexport interface RotateResult {\n readonly parameter: string;\n readonly environment: string;\n readonly mechanism: RotationMechanism;\n readonly phase: RotatePhase;\n /** The source provider's type — where the value and its meta were written. */\n readonly source: string;\n /** True when this run wrote a new value. `begin` and `cutover` do; `complete` does not. */\n readonly wroteValue: boolean;\n /** The rotation state after this run — `rotating` after a begin, `active` otherwise. */\n readonly state: RotationState;\n /** When the current window opened, ISO. Set only after a `begin`, else `null`. */\n readonly rotatingSince: string | null;\n /** When a rotation last completed, ISO. Set after a `complete` or a `cutover`. */\n readonly lastRotated: string | null;\n}\n\n/**\n * The value file a rotation writes to a *backend* and reads back — the parameter\n * at its environment scope, verbatim.\n *\n * A rotating secret belongs to exactly one environment (the credential Vault\n * issues for production is not development's), so the environment scope is its\n * home, and pinning it here is what lets `readPrevious` find the prior version\n * during the window: the write and the retention read must address the same\n * value file byte-for-byte. `encrypted: false` because the value crosses to a\n * backend source of truth verbatim, the way `push` moves it — the backend holds\n * custody of its own store, and penv's envelope is the *local tree's* concern,\n * not the backend's. When the source of truth is instead the local tree,\n * {@link writeRotatedValue} routes to {@link sealAwareWrite}, which seals per\n * meta and removes the twin; this file shape is only ever the backend's.\n */\nfunction rotatingFile(ref: ParameterRef, environment: string): ValueFile {\n return {\n namespace: ref.namespace,\n name: ref.name,\n scope: { kind: \"environment\", environment },\n encrypted: false,\n };\n}\n\n/**\n * Writes the new value to the environment's source of truth, by the custody rule\n * the store's *type* sets — the fix for a rotation that used to persist the live\n * credential as cleartext.\n *\n * The local `.penv` tree is penv's own to seal, so a secret rotated into it must\n * be sealed and its plaintext twin removed, exactly as `set` does: otherwise the\n * value lands as cleartext `.penv/<name>.<env>`, which is committed to git and,\n * because plaintext outranks `.enc` at one scope, also shadows any sealed copy\n * already there. So the local tree goes through {@link sealAwareWrite}, honouring\n * meta's policy. A real backend (vault, mock) holds custody of its own store and\n * penv's envelope is not its concern — the value crosses verbatim via\n * {@link rotatingFile}, the way `push` sends plaintext for a projection destination to re-seal.\n *\n * `--begin` only ever reaches a backend (a dual-valid window demands a retaining\n * provider, which the local tree is not), but it is routed here too, so both\n * value-write sites share one custody decision.\n */\nasync function writeRotatedValue(\n project: Project,\n provider: Provider,\n ref: ParameterRef,\n environment: string,\n value: string,\n): Promise<void> {\n if (provider.type === LOCAL_TREE_TYPE) {\n await sealAwareWrite({\n project,\n provider,\n ref,\n scope: { kind: \"environment\", environment },\n value,\n environment,\n });\n return;\n }\n await provider.write(rotatingFile(ref, environment), value);\n}\n\n/** The new value a write step requires, or a refusal that names the phase needing it. */\nfunction requireNewValue(value: string | undefined, phase: RotatePhase, key: string): string {\n if (value === undefined) {\n throw new PenvError(\n \"ROTATION_NO_VALUE\",\n `A ${phase} rotation of ${key} writes a new value, and none was given`,\n \"Pass the new value as the argument — `penv rotate <key> <value>` — or pipe it in on stdin.\",\n );\n }\n return value;\n}\n\n/**\n * A `dual-valid` rotation against a provider that does not retain its previous\n * value — the one situation the mechanism cannot survive, refused before a single\n * write.\n *\n * The window's whole promise is that the old credential keeps working while the\n * new one takes over; a provider that overwrites in place breaks that the instant\n * `begin` writes, and no meta clock can put the old value back. So this is not a\n * best-effort with a warning — it is a hard refusal, thrown here so the caller\n * never opens a grace window that is already a lie. `atomic-cutover` reaches this\n * function's callers not at all: it has no overlap to retain.\n */\nfunction requireRetaining(provider: Provider, environment: string): RetainingProvider {\n if (!retainsPrevious(provider)) {\n throw new PenvError(\n \"ROTATION_NOT_RETAINING\",\n `A dual-valid rotation needs the previous value to stay readable during the grace window, and the \\`${provider.type}\\` provider for environment ${environment} does not retain it`,\n \"Point this environment at a provider that keeps prior versions (its `readPrevious` is what penv reads during the window), \" +\n \"or, if a momentary overlap is not required, declare the parameter `atomic-cutover` in its meta and flip it in one step.\",\n );\n }\n return provider;\n}\n\nexport async function runRotate(options: RotateOptions): Promise<RotateResult> {\n const project = openProject(options.cwd);\n const environment = targetEnvironment(project, options.environment);\n const ref = refFromKey(options.key, project.config);\n const source = await sourceProviderFor(project, environment);\n\n // A rotation reads state back mid-flight — the phase in meta, the previous\n // value during a grace window — and a projection-holding store cannot return\n // either. Refused on the declared capability, before a single write.\n if (!holdsRecords(source)) {\n throw new PenvError(\n \"ROTATION_NOT_RECORDS\",\n `Environment ${environment} is backed by \\`${source.type}\\`, which holds a resolved projection penv cannot rotate in place`,\n \"Rotate the parameter in the environment that holds the records (the local tree, Vault, SSM), \" +\n \"then `penv push` the result to this destination.\",\n );\n }\n const provider: Provider = source;\n\n const nowIso = options.now ?? new Date().toISOString();\n const before: Meta | undefined = await provider.readMeta(ref);\n const { mechanism } = rotationOf(before, environment);\n\n if (mechanism === undefined) {\n throw new PenvError(\n \"ROTATION_NO_MECHANISM\",\n `Parameter ${options.key} declares no rotation mechanism for environment ${environment}, so penv does not know how to rotate it`,\n 'Set `rotationMechanism` in the parameter\\'s meta to `\"dual-valid\"` (a grace-window overlap) or ' +\n '`\"atomic-cutover\"` (a single flip), then run `penv rotate` again.',\n );\n }\n\n const begin = options.begin === true;\n const complete = options.complete === true;\n\n // atomic-cutover: one flip, and `--begin`/`--complete` have no meaning for it —\n // there is no window to bracket. Refuse the flags rather than silently ignore\n // them, so a user who reached for a two-phase rotation learns their parameter\n // is not one before anything is written.\n if (mechanism === \"atomic-cutover\") {\n if (begin || complete) {\n throw new PenvError(\n \"ROTATION_MECHANISM_MISMATCH\",\n `Parameter ${options.key} is atomic-cutover, which flips in one step, so \\`--begin\\`/\\`--complete\\` do not apply`,\n \"Run `penv rotate <key> <value>` with no phase flag to flip it. `--begin`/`--complete` bracket a \" +\n \"dual-valid grace window, which atomic-cutover has none of.\",\n );\n }\n const value = requireNewValue(options.value, \"cutover\", options.key);\n // Value first, then the completion stamp — the flip and its record, in the\n // order that leaves the value present before anything claims it rotated. The\n // write honours the store's custody rule: sealed into the local tree per\n // meta, verbatim to a backend.\n await writeRotatedValue(project, provider, ref, environment, value);\n const after = completeRotation(before, environment, nowIso);\n await provider.writeMeta(ref, after);\n return result(ref, environment, mechanism, \"cutover\", provider.type, true, after);\n }\n\n // dual-valid from here: every path needs a retaining provider, and the two\n // phases are mutually exclusive — exactly one bracket per run.\n const retaining = requireRetaining(provider, environment);\n\n if (begin === complete) {\n throw new PenvError(\n \"ROTATION_PHASE_REQUIRED\",\n `A dual-valid rotation of ${options.key} needs exactly one of \\`--begin\\` or \\`--complete\\``,\n \"`--begin` writes the new value and opens the grace window; `--complete` closes it once every reader \" +\n \"has moved to the new value. Run them in that order, one at a time.\",\n );\n }\n\n if (begin) {\n const value = requireNewValue(options.value, \"begin\", options.key);\n // The new value is written while the provider still holds the previous one —\n // that co-existence IS the window, and `readPrevious` serves the old value\n // until `--complete` closes it. Value first, then `rotatingSince`, so the\n // clock never claims a window an unwritten value has not yet opened. A\n // retaining provider is always a backend, so this crosses verbatim; routed\n // through the shared helper so both write sites share one custody decision.\n await writeRotatedValue(project, retaining, ref, environment, value);\n const after = beginRotation(before, environment, nowIso);\n await retaining.writeMeta(ref, after);\n return result(ref, environment, mechanism, \"begin\", retaining.type, true, after);\n }\n\n // --complete: the window closes. No value is written — the new value has been\n // live since `--begin`; this only returns the clock to `active` and stamps the\n // completion. The provider's previous version may be pruned any time after.\n const after = completeRotation(before, environment, nowIso);\n await retaining.writeMeta(ref, after);\n return result(ref, environment, mechanism, \"complete\", retaining.type, false, after);\n}\n\n/** Reads the settled clocks back out of the meta just written, so the result is the record. */\nfunction result(\n ref: ParameterRef,\n environment: string,\n mechanism: RotationMechanism,\n phase: RotatePhase,\n source: string,\n wroteValue: boolean,\n after: Meta,\n): RotateResult {\n const { state, rotatingSince, lastRotated } = rotationOf(after, environment);\n return {\n parameter: [...ref.namespace, ref.name].join(\"/\"),\n environment,\n mechanism,\n phase,\n source,\n wroteValue,\n state,\n rotatingSince,\n lastRotated,\n };\n}\n\nexport function renderRotate(result: RotateResult): string[] {\n if (result.phase === \"begin\") {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Rotating\",\n subject: result.parameter,\n detail: `dual-valid window open for environment ${result.environment} (since ${result.rotatingSince})`,\n },\n {\n glyph: CHECK,\n label: \"Previous\",\n subject: \"still readable\",\n detail: `on the ${result.source} provider until \\`penv rotate ${result.parameter} --complete\\``,\n },\n ]);\n }\n if (result.phase === \"complete\") {\n return formatRows([\n {\n glyph: CHECK,\n label: \"Rotated\",\n subject: result.parameter,\n detail: `dual-valid window closed for environment ${result.environment} (completed ${result.lastRotated})`,\n },\n ]);\n }\n return formatRows([\n {\n glyph: CHECK,\n label: \"Rotated\",\n subject: result.parameter,\n detail: `atomic-cutover flip for environment ${result.environment} (completed ${result.lastRotated})`,\n },\n ]);\n}\n\nexport const rotateCommand = defineCommand({\n meta: {\n name: \"rotate\",\n description: \"Rotate a parameter's value by the mechanism its meta declares\",\n },\n args: {\n key: { type: \"positional\", required: true, description: \"The parameter, e.g. redis/password\" },\n value: {\n type: \"positional\",\n required: false,\n description: \"The new value; read from stdin if omitted. Not needed with --complete\",\n },\n env: { type: \"string\", description: \"The environment to rotate in\" },\n begin: { type: \"boolean\", description: \"Open a dual-valid grace window with the new value\" },\n complete: { type: \"boolean\", description: \"Close a dual-valid grace window\" },\n },\n run({ args }) {\n return guard(async () => {\n // `--complete` writes no value, so it never blocks on stdin waiting for one\n // that will not come. Every other path reads the value the way `set` does.\n const value = args.complete === true ? undefined : (args.value ?? (await readStdin()));\n write(\n renderRotate(\n await runRotate({\n cwd: process.cwd(),\n key: args.key,\n ...(value === undefined ? {} : { value }),\n ...(args.env === undefined ? {} : { environment: args.env }),\n ...(args.begin === undefined ? {} : { begin: args.begin }),\n ...(args.complete === undefined ? {} : { complete: args.complete }),\n }),\n ),\n );\n });\n },\n});\n","/**\n * `penv watch` — re-run validation whenever the configuration changes.\n *\n * Watch mode reports `penv validate`'s verdict on a loop, and never a second\n * opinion about it: the diagnostics come from `runValidate` itself, so there is\n * no watch-mode verdict that could drift from the command CI runs.\n *\n * It prints one thing `validate` does not — the schema↔tree drift report, which\n * `runValidate` measures and hands back without letting it touch `ok`. The two\n * commands differ because their readers do. CI wants a verdict, and a warning\n * about a parameter the schema tolerates would be noise in a log nobody reads on\n * a passing run. The person with `watch` open is mid-edit, and the distance\n * between what they have just declared and what the tree holds is the thing they\n * are watching *for*. Same facts, same measurement, one of them worth printing\n * only where someone is looking.\n *\n * Three things decide the answer, so three things are watched: the `.penv/` tree\n * (the values and their meta), `penv.config.ts` (the environment whitelist, and\n * the `override` block), and the schema. The schema is two modules: the shape\n * (`penv.schema.ts`, the `z.object` every consumer derives from) always lives at\n * the project root, outside the tree, so nothing above watches it — it gets its\n * own watcher, always. The loader (`.penv/env.ts`, the wrapper `schemaFile` names)\n * is inside the tree at the default and the recursive watcher already covers it; a\n * second watcher on it would report every edit twice, so it earns one only when\n * `schemaFile` moves it outside `.penv/`.\n *\n * `node:fs` does the watching. A dependency-free watcher is worth the handful of\n * lines here: the events this needs are the ones the platform already reports,\n * and debouncing them is the whole of what a library would add.\n */\n\nimport type { FSWatcher } from \"node:fs\";\nimport { existsSync, watch } from \"node:fs\";\nimport { basename, dirname, resolve } from \"node:path\";\nimport { SCHEMA_SHAPE_FILE, schemaFileOf, schemaInsideTree } from \"@penvhq/core\";\nimport { defineCommand } from \"citty\";\nimport { openProject } from \"../project.js\";\nimport type { DriftReport } from \"../schema.js\";\nimport { out } from \"../style.js\";\nimport { formatRows, guard, type Row, reportError, tip, WARN, write } from \"../ui.js\";\nimport type { ValidateResult } from \"./validate.js\";\nimport { renderValidate, runValidate } from \"./validate.js\";\n\n/**\n * Long enough to coalesce an editor's save into one run, short enough to feel\n * immediate. An atomic save is a write, a rename, and sometimes a delete, and a\n * run per event would validate a tree mid-rewrite and report a file that exists\n * again by the time the user reads the line.\n */\nconst DEBOUNCE_MS = 100;\n\nexport interface WatchOptions {\n readonly cwd: string;\n readonly environment?: string;\n /** Defaults to {@link DEBOUNCE_MS}. */\n readonly debounceMs?: number;\n /** Called with every completed validation, starting with the initial one. */\n readonly onResult?: (result: ValidateResult) => void;\n /**\n * Called when a cycle could not produce a result at all — an unreadable\n * config, a watcher the platform dropped. Never called for a *failing*\n * validation: that is a result, and it goes to `onResult`.\n */\n readonly onError?: (error: unknown) => void;\n}\n\nexport interface WatchHandle {\n /** Stops watching. Idempotent, and safe to call from inside a callback. */\n close(): void;\n}\n\n/**\n * Watches, and re-validates on change.\n *\n * Returns a handle rather than blocking, so the loop is a plain object a test\n * can drive and close instead of a live process it would have to spawn. The\n * command below is the only thing that turns it into a process that waits.\n */\nexport function runWatch(options: WatchOptions): WatchHandle {\n // Fails fast, and before any watcher exists: a watch on a directory that is\n // not a penv project would report the same error on every keystroke instead.\n const project = openProject(options.cwd);\n const configFile = basename(project.configFile);\n const debounceMs = options.debounceMs ?? DEBOUNCE_MS;\n\n const watchers = new Set<FSWatcher>();\n let timer: ReturnType<typeof setTimeout> | undefined;\n let running = false;\n let pending = false;\n let closed = false;\n\n async function validate(): Promise<void> {\n if (closed) {\n return;\n }\n // One run at a time: a save that lands mid-run would otherwise read the tree\n // twice at once and report whichever finished last.\n if (running) {\n pending = true;\n return;\n }\n running = true;\n try {\n const result = await runValidate({\n cwd: options.cwd,\n ...(options.environment === undefined ? {} : { environment: options.environment }),\n });\n if (!closed) {\n options.onResult?.(result);\n }\n } catch (error) {\n // A file can vanish between the event and the read — that is what an\n // atomic save looks like from here. Report it and keep watching: the\n // rename that follows will schedule the run that gets the real answer.\n if (!closed) {\n options.onError?.(error);\n }\n } finally {\n running = false;\n if (pending && !closed) {\n pending = false;\n void validate();\n }\n }\n }\n\n function schedule(): void {\n if (closed) {\n return;\n }\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n timer = setTimeout(() => {\n timer = undefined;\n void validate();\n }, debounceMs);\n }\n\n function stop(watcher: FSWatcher): void {\n watchers.delete(watcher);\n watcher.close();\n }\n\n /**\n * Waits for a vanished target to come back, by watching its parent for the\n * name to reappear.\n *\n * A branch switch is a delete and then a create, so a watch that merely\n * stopped at the delete would be silent for the rest of the session — the\n * user would be reading a report of a tree that has since returned. The\n * re-armed watcher validates on arrival rather than trusting the report the\n * deletion produced.\n */\n function armRecovery(target: string, recursive: boolean, only?: string): void {\n const parent = dirname(target);\n const name = basename(target);\n let recovery: FSWatcher | undefined;\n\n try {\n recovery = watch(parent, { recursive: false }, (_event, filename) => {\n if (closed || recovery === undefined) {\n return;\n }\n // The parent went too. Watching it would spin exactly the way the\n // vanished target did, and there is nothing left to recover from.\n if (!existsSync(parent)) {\n stop(recovery);\n return;\n }\n if (filename !== null && basename(filename) !== name) {\n return;\n }\n if (!existsSync(target)) {\n return;\n }\n stop(recovery);\n addWatcher(target, recursive, only);\n schedule();\n });\n } catch (error) {\n options.onError?.(error);\n return;\n }\n\n recovery.on(\"error\", (error) => {\n if (!closed) {\n options.onError?.(error);\n }\n });\n watchers.add(recovery);\n }\n\n /**\n * `recursive` is not available on every platform, so a watcher that cannot\n * have it watches the directory itself. Namespace folders below it go\n * unwatched there, which is a weaker watch — never a wrong validation, since\n * the answer always comes from a fresh `runValidate`.\n */\n function addWatcher(target: string, recursive: boolean, only?: string): void {\n let watcher: FSWatcher | undefined;\n\n const listen = (useRecursive: boolean): FSWatcher =>\n watch(target, { recursive: useRecursive }, (_event, filename) => {\n if (closed) {\n return;\n }\n // A deleted target does not stop its watcher, and on Windows does not\n // error either: it re-fires `rename` for the absent path tens of\n // thousands of times a second, forever. Left alone that pins a core,\n // and every event resets the debounce below, so the watch would burn\n // CPU while reporting nothing at all. The check costs a `stat` per\n // event, which is what a `.penv/` that is still there is worth.\n //\n // Deleting the tree is a change like any other, so it is scheduled\n // rather than reported as a failure: `runValidate` has a real verdict\n // for a missing `.penv/`, and watch's job is to say what validate says.\n if (!existsSync(target)) {\n if (watcher !== undefined) {\n stop(watcher);\n }\n armRecovery(target, recursive, only);\n schedule();\n return;\n }\n // Directories are watched rather than files so that an editor's\n // write-to-temp-then-rename is seen as a change to the real name. The\n // cost is hearing about neighbours, so the ones that matter are named.\n if (only !== undefined && (filename === null || basename(filename) !== only)) {\n return;\n }\n schedule();\n });\n\n try {\n watcher = listen(recursive);\n } catch (error) {\n if (!recursive) {\n options.onError?.(error);\n return;\n }\n try {\n watcher = listen(false);\n } catch (fallbackError) {\n options.onError?.(fallbackError);\n return;\n }\n }\n watcher.on(\"error\", (error) => {\n if (!closed) {\n options.onError?.(error);\n }\n });\n watchers.add(watcher);\n }\n\n addWatcher(project.recordsDir, true);\n addWatcher(dirname(project.configFile), false, configFile);\n\n // The schema shape declares what must exist, so an edit to it — a newly declared\n // parameter — changes the answer as much as a value does. It lives at the\n // project root, outside the tree the recursive watcher covers and filtered out\n // of the config-dir watcher above, so nothing else sees it: it always gets its\n // own watcher, or an edit to the one file `penv init` labels \"yours to edit\"\n // would fire nothing at all.\n addWatcher(project.root, false, SCHEMA_SHAPE_FILE);\n\n // The loader `schemaFile` names is the wrapper the alias resolves to. Inside the\n // tree it already has a watcher; one outside `.penv/` would have none, and a\n // watch that keeps reporting a verdict it can no longer see the reason for is the\n // silence this command exists to prevent.\n if (schemaInsideTree(project.config) === undefined) {\n const schemaFile = resolve(project.root, schemaFileOf(project.config));\n addWatcher(dirname(schemaFile), false, basename(schemaFile));\n }\n\n // The current answer, before anything changes: a watch that says nothing until\n // the next keystroke leaves the user guessing at the state they already have.\n void validate();\n\n return {\n close(): void {\n closed = true;\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n for (const watcher of [...watchers]) {\n stop(watcher);\n }\n },\n };\n}\n\n/**\n * One cycle's report: `penv validate`'s, with a rule above it — on a loop, the\n * reader's first question is where the last run ended — and the drift below it.\n *\n * Drift comes last because it is the part that is not a verdict. The rows above\n * say whether the configuration is valid; these say what the schema and the tree\n * disagree about, which is often *why*, and is worth reading even on a run that\n * passed.\n */\nexport function renderWatch(result: ValidateResult): string[] {\n return [\"\", ...renderValidate(result), ...renderDrift(result.drift, result.environment)];\n}\n\n/**\n * The drift rows. Nothing at all when the schema and the tree agree: a loop\n * reprints its whole report on every keystroke, and a block that says \"no drift\"\n * forever is the first thing the eye learns to skip past — taking the block that\n * matters with it.\n */\nexport function renderDrift(drift: DriftReport, environment: string): string[] {\n const rows: Row[] = [\n ...drift.declared.map((item) => ({\n glyph: WARN,\n label: \"Declared, no value\",\n subject: item.subject,\n detail: item.detail,\n })),\n ...drift.undeclared.map((item) => ({\n glyph: WARN,\n label: \"Unused parameter\",\n subject: item.variable,\n detail: \"present, not in schema\",\n })),\n ];\n if (rows.length === 0) {\n return [];\n }\n\n const lines = [\"\", out.bold(`Schema and tree differ for ${environment}:`), ...formatRows(rows)];\n // The paste block, exactly as `doctor` prints it — the reader who sees drift\n // here and drift there is looking at one report, not two that resemble each other.\n for (const remedy of new Set(drift.declared.map((item) => item.remedy))) {\n lines.push(tip(remedy));\n }\n return lines;\n}\n\nexport const watchCommand = defineCommand({\n meta: {\n name: \"watch\",\n description: \"Re-validate whenever .penv/ or penv.config.ts changes\",\n },\n args: {\n env: { type: \"string\", description: \"The environment to validate\" },\n },\n run({ args }) {\n return guard(async () => {\n const handle = runWatch({\n cwd: process.cwd(),\n ...(args.env === undefined ? {} : { environment: args.env }),\n onResult: (result) => {\n write(renderWatch(result));\n },\n // A failing cycle is reported and watching continues. `reportError`\n // marks the process failed, which `validate` wants and a loop does not:\n // a cycle that failed mid-save ten minutes ago must not decide the exit\n // code of a session the user ended deliberately. The message is what is\n // wanted here, not the verdict.\n onError: (error) => {\n const previous = process.exitCode;\n reportError(error);\n process.exitCode = previous;\n },\n });\n write([`Watching .penv/ and penv.config.ts. ${out.dim(\"Ctrl-C to stop.\")}`]);\n await new Promise<void>((resolve) => {\n process.once(\"SIGINT\", () => {\n handle.close();\n resolve();\n });\n });\n });\n },\n});\n"],"mappings":"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","names":["import_core","import_citty","import_node_fs","import_node_path","import_core","import_runtime","import_citty","import_node_fs","import_node_path","import_core","resolve","path","plan","plan","import_node_fs","import_node_path","import_core","import_provider_filesystem","import_core","import_node_fs","import_node_path","import_core","require","import_core","import_node_fs","import_node_module","import_node_path","import_core","import_citty","import_node_fs","import_core","import_core","result","import_node_path","import_node_url","import_core","import_citty","import_core","node","out","own","node","result","resolvePath","result","out","result","import_core","import_citty","import_node_fs","import_node_path","import_core","record","occupied","result","import_node_fs","import_node_path","import_core","import_citty","import_core","import_citty","resolve","result","out","report","import_core","import_citty","import_core","import_citty","result","result","import_core","import_citty","skipped","result","prompt","import_node_fs","import_node_path","import_core","import_citty","displayPath","result","import_core","import_citty","import_node_fs","import_node_path","import_core","import_citty","import_core","where","import_node_fs","import_node_path","import_core","relative","manifestOf","import_core","import_node_fs","import_node_path","import_core","import_citty","import_node_fs","import_node_path","NOT_ENVIRONMENTS","declaredIn","plan","where","relative","result","LOCAL","displayPath","result","report","import_core","import_citty","import_node_module","import_core","import_meta","firstLine","module","result","import_core","import_citty","scopeLabel","result","import_node_fs","import_node_path","import_promises","import_core","import_citty","describe","plan","result","import_core","import_citty","environmentOf","occupied","result","import_core","import_citty","result","import_core","import_citty","after","result","import_node_fs","import_node_path","import_core","import_citty","DEBOUNCE_MS","result","stop","resolve","cittyRunMain"]}