@penvhq/cli 0.9.4 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -57,7 +57,7 @@ declare function renderArtifactBuild(result: ArtifactBuildResult, cwd: string):
57
57
  * second kind.
58
58
  */
59
59
  type DoctorSeverity = "pass" | "warning" | "failure" | "unknown";
60
- type DoctorCheck = "schema" | "missing" | "declared" | "weak" | "unused" | "unscoped-fallback" | "plaintext-secret" | "public-secret" | "encryption" | "rotation-overdue" | "rotation-stuck" | "provider-value-drift" | "provider" | "projection-unreachable" | "projection-name-drift" | "projection-manual-edit" | "projection-value-drift" | "environment-flag-shadow" | "artifact-in-tree";
60
+ type DoctorCheck = "schema" | "missing" | "declared" | "weak" | "unused" | "unscoped-fallback" | "secrecy-undeclared" | "plaintext-secret" | "public-secret" | "encryption" | "rotation-overdue" | "rotation-stuck" | "provider-value-drift" | "provider" | "projection-unreachable" | "projection-name-drift" | "projection-manual-edit" | "projection-value-drift" | "environment-flag-shadow" | "local-extension" | "artifact-in-tree";
61
61
  interface DoctorFinding {
62
62
  readonly check: DoctorCheck;
63
63
  readonly severity: DoctorSeverity;
package/dist/index.d.ts CHANGED
@@ -57,7 +57,7 @@ declare function renderArtifactBuild(result: ArtifactBuildResult, cwd: string):
57
57
  * second kind.
58
58
  */
59
59
  type DoctorSeverity = "pass" | "warning" | "failure" | "unknown";
60
- type DoctorCheck = "schema" | "missing" | "declared" | "weak" | "unused" | "unscoped-fallback" | "plaintext-secret" | "public-secret" | "encryption" | "rotation-overdue" | "rotation-stuck" | "provider-value-drift" | "provider" | "projection-unreachable" | "projection-name-drift" | "projection-manual-edit" | "projection-value-drift" | "environment-flag-shadow" | "artifact-in-tree";
60
+ type DoctorCheck = "schema" | "missing" | "declared" | "weak" | "unused" | "unscoped-fallback" | "secrecy-undeclared" | "plaintext-secret" | "public-secret" | "encryption" | "rotation-overdue" | "rotation-stuck" | "provider-value-drift" | "provider" | "projection-unreachable" | "projection-name-drift" | "projection-manual-edit" | "projection-value-drift" | "environment-flag-shadow" | "local-extension" | "artifact-in-tree";
61
61
  interface DoctorFinding {
62
62
  readonly check: DoctorCheck;
63
63
  readonly severity: DoctorSeverity;
package/dist/index.js CHANGED
@@ -325,7 +325,7 @@ function installFailed(plan2) {
325
325
  }
326
326
 
327
327
  // src/project.ts
328
- import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
328
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
329
329
  import { dirname, join as join3 } from "path";
330
330
  import {
331
331
  assertMigrated,
@@ -406,10 +406,19 @@ function environmentFromShorthand(config, candidates, explicit) {
406
406
  }
407
407
 
408
408
  // src/registry.ts
409
+ import { readFileSync as readFileSync2 } from "fs";
409
410
  import { createRequire } from "module";
410
411
  import { resolve } from "path";
411
412
  import { pathToFileURL } from "url";
412
- import { holdsProjection, PENV_DIR, PenvError as PenvError4, recordsDir } from "@penvhq/core";
413
+ import {
414
+ holdsProjection,
415
+ LOCAL_EXTENSIONS_PATH,
416
+ localExtensionsFile,
417
+ PENV_DIR,
418
+ PenvError as PenvError4,
419
+ parseLocalExtensions,
420
+ recordsDir
421
+ } from "@penvhq/core";
413
422
  import { createFilesystemProvider } from "@penvhq/provider-filesystem";
414
423
  import { createMockProvider } from "@penvhq/provider-mock";
415
424
  var PLUGIN_FACTORY_EXPORT = "penvProviderFactory";
@@ -478,16 +487,40 @@ async function loadPluginProvider(type, context) {
478
487
  assertSatisfiesContract(provider, type);
479
488
  return provider;
480
489
  }
481
- function assertProvidersRegistered(config, projectRoot) {
490
+ function assertProvidersRegistered(config, projectRoot, options) {
491
+ const local = localExtensions(projectRoot);
492
+ const ci = options?.ci ?? isCi(process.env.CI);
482
493
  for (const [environment, provider] of Object.entries(config.providers)) {
483
494
  if (isProviderRegistered(provider.type)) {
484
495
  continue;
485
496
  }
497
+ if (ci && local.includes(provider.type)) {
498
+ throw localExtensionInCi(provider.type, environment);
499
+ }
486
500
  if (resolvePlugin(provider.type, projectRoot) === void 0) {
487
501
  throw unknownProvider(provider.type, environment);
488
502
  }
489
503
  }
490
504
  }
505
+ function localExtensions(projectRoot) {
506
+ let text;
507
+ try {
508
+ text = readFileSync2(localExtensionsFile(projectRoot), "utf8");
509
+ } catch {
510
+ return [];
511
+ }
512
+ return parseLocalExtensions(text);
513
+ }
514
+ function isCi(value) {
515
+ return value !== void 0 && value !== "" && value !== "0" && value.toLowerCase() !== "false";
516
+ }
517
+ function localExtensionInCi(type, environment) {
518
+ return new PenvError4(
519
+ "LOCAL_EXTENSION_IN_CI",
520
+ `The provider \`${type}\` for environment ${environment} is a local extension, and this is CI`,
521
+ `${LOCAL_EXTENSIONS_PATH} records it as a package this project develops, so nothing pins the bytes CI would run. Publish it and run \`penv add ${type}\` to pin a release.`
522
+ );
523
+ }
491
524
  function resolvePlugin(specifier, fromDir) {
492
525
  try {
493
526
  const require2 = createRequire(resolve(fromDir, "noop.js"));
@@ -525,7 +558,7 @@ function unknownProvider(type, environment) {
525
558
  return new PenvError4(
526
559
  "UNKNOWN_PROVIDER",
527
560
  `The provider \`${type}\`${where} in penv.config.ts is not installed in this project`,
528
- `Install it with \`npm i ${type}\` \u2014 a provider's \`type\` is the package penv imports. The CLI ships ${preinstalled} pre-installed.`
561
+ `A provider's \`type\` is the package penv imports, so it has to resolve from this project: install it with \`npm i ${type}\`, or \u2014 if this repository is the one that builds it \u2014 run \`penv add --local ${type}\` once it is a dependency of the root. The CLI ships ${preinstalled} pre-installed.`
529
562
  );
530
563
  }
531
564
 
@@ -558,7 +591,7 @@ function selfContainedSchemaModule(root, schemaFile) {
558
591
  if (!existsSync3(file)) {
559
592
  return void 0;
560
593
  }
561
- const source = readFileSync2(file, "utf8");
594
+ const source = readFileSync3(file, "utf8");
562
595
  return source.includes("PenvSchemaShape") || source.includes("z.object") ? schemaFile : void 0;
563
596
  }
564
597
  function schemaShapeFileOf(project) {
@@ -794,10 +827,7 @@ function writeError(lines) {
794
827
  }
795
828
  function reportError(error) {
796
829
  if (error instanceof PenvError6) {
797
- const suffix = error.remedy === void 0 ? void 0 : `
798
- ${error.remedy}`;
799
- const message = suffix !== void 0 && error.message.endsWith(suffix) ? error.message.slice(0, -suffix.length) : error.message;
800
- process.stderr.write(`${err.red(CROSS)} ${message}
830
+ process.stderr.write(`${err.red(CROSS)} ${error.summary}
801
831
  `);
802
832
  if (error.remedy !== void 0) {
803
833
  process.stderr.write(` ${err.cyan("\u2192")} ${error.remedy}
@@ -827,7 +857,7 @@ async function guard(run) {
827
857
  }
828
858
 
829
859
  // src/commands/run.ts
830
- import { existsSync as existsSync4, readFileSync as readFileSync3, watch } from "fs";
860
+ import { existsSync as existsSync4, readFileSync as readFileSync4, watch } from "fs";
831
861
  import { createRequire as createRequire2 } from "module";
832
862
  import { basename, dirname as dirname2, join as join4, resolve as resolve2 } from "path";
833
863
  import {
@@ -1672,7 +1702,7 @@ function packageManifest(specifier, root) {
1672
1702
  const file = join4(directory, "package.json");
1673
1703
  if (existsSync4(file)) {
1674
1704
  try {
1675
- const parsed = JSON.parse(readFileSync3(file, "utf8"));
1705
+ const parsed = JSON.parse(readFileSync4(file, "utf8"));
1676
1706
  if (isPlainObject(parsed) && parsed.name === specifier) {
1677
1707
  return parsed;
1678
1708
  }
@@ -1745,7 +1775,7 @@ function snapshotPath(host) {
1745
1775
  }
1746
1776
  function readSnapshot(path) {
1747
1777
  try {
1748
- return readFileSync3(path, "utf8");
1778
+ return readFileSync4(path, "utf8");
1749
1779
  } catch {
1750
1780
  throw new PenvError8(
1751
1781
  "RUN_SNAPSHOT_MISSING",
@@ -2166,7 +2196,7 @@ import {
2166
2196
  existsSync as existsSync5,
2167
2197
  mkdirSync as mkdirSync2,
2168
2198
  readdirSync as readdirSync2,
2169
- readFileSync as readFileSync4,
2199
+ readFileSync as readFileSync5,
2170
2200
  renameSync,
2171
2201
  rmSync,
2172
2202
  writeFileSync as writeFileSync2
@@ -2210,7 +2240,7 @@ function readCutover(root) {
2210
2240
  }
2211
2241
  let parsed;
2212
2242
  try {
2213
- parsed = JSON.parse(readFileSync4(file, "utf8"));
2243
+ parsed = JSON.parse(readFileSync5(file, "utf8"));
2214
2244
  } catch {
2215
2245
  throw unreadable("it is not JSON");
2216
2246
  }
@@ -2357,7 +2387,7 @@ var cleanupCommand = defineCommand5({
2357
2387
  });
2358
2388
 
2359
2389
  // src/commands/doctor.ts
2360
- import { readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
2390
+ import { readdirSync as readdirSync3, readFileSync as readFileSync6, statSync as statSync2 } from "fs";
2361
2391
  import { join as join6, relative as relative2 } from "path";
2362
2392
  import {
2363
2393
  ARTIFACT_BUILD_COMMAND as ARTIFACT_BUILD_COMMAND2,
@@ -2372,6 +2402,7 @@ import {
2372
2402
  isSecret as isSecret3,
2373
2403
  isStuck,
2374
2404
  openValue as openValue2,
2405
+ RECORDS_PATH as RECORDS_PATH2,
2375
2406
  resolveAll as resolveAll2,
2376
2407
  rotationOf,
2377
2408
  tryParseDuration,
@@ -2827,6 +2858,7 @@ async function runDoctor(options) {
2827
2858
  findings.push(...unusedFindings(drift));
2828
2859
  }
2829
2860
  findings.push(...fallbackFindings(subjects, environment));
2861
+ findings.push(...secrecyFindings(subjects, environment));
2830
2862
  findings.push(...plaintextSecretFindings(subjects, environment));
2831
2863
  findings.push(...publicSecretFindings(subjects, environment, project.config));
2832
2864
  findings.push(...encryptionFindings(subjects, environment));
@@ -2839,6 +2871,7 @@ async function runDoctor(options) {
2839
2871
  }
2840
2872
  findings.push(...await providerDriftFindings(project, environment, options.source));
2841
2873
  findings.push(...await projectionFindings(project, environment, options.projection));
2874
+ findings.push(...localExtensionFindings(project));
2842
2875
  findings.push(...artifactFindings(project));
2843
2876
  findings.push({
2844
2877
  check: "provider",
@@ -2976,6 +3009,31 @@ function fallbackFindings(subjects, environment) {
2976
3009
  }
2977
3010
  ];
2978
3011
  }
3012
+ function secrecyFindings(subjects, environment) {
3013
+ const undeclared = subjects.filter(
3014
+ ({ meta }) => effectiveMeta(meta, environment).secret === void 0
3015
+ );
3016
+ if (undeclared.length === 0) {
3017
+ return [
3018
+ {
3019
+ check: "secrecy-undeclared",
3020
+ severity: "pass",
3021
+ label: "Secrecy policy",
3022
+ subject: subjects.length === 0 ? `no parameter resolves for ${environment}` : `every parameter declares whether it is secret for ${environment}`
3023
+ }
3024
+ ];
3025
+ }
3026
+ return [
3027
+ {
3028
+ check: "secrecy-undeclared",
3029
+ severity: "unknown",
3030
+ label: "Secrecy policy",
3031
+ subject: `${undeclared.length} of ${subjects.length} declare neither way for ${environment}`,
3032
+ detail: "penv was never told which of these values must be encrypted",
3033
+ remedy: `declare \`"secret": true\` or \`"secret": false\` in a parameter's meta file, ${RECORDS_PATH2}/<name>.json`
3034
+ }
3035
+ ];
3036
+ }
2979
3037
  function plaintextSecretFindings(subjects, environment) {
2980
3038
  const secrets = subjects.filter(({ meta }) => isSecret3(meta, environment));
2981
3039
  const findings = [];
@@ -3296,6 +3354,29 @@ function scannableFiles(directory, out2) {
3296
3354
  }
3297
3355
  }
3298
3356
  }
3357
+ function localExtensionFindings(project) {
3358
+ const names = localExtensions(project.root);
3359
+ if (names.length === 0) {
3360
+ return [
3361
+ {
3362
+ check: "local-extension",
3363
+ severity: "pass",
3364
+ label: "Extensions",
3365
+ subject: "every extension this project names is pinned"
3366
+ }
3367
+ ];
3368
+ }
3369
+ return [
3370
+ {
3371
+ check: "local-extension",
3372
+ severity: "unknown",
3373
+ label: "Extensions",
3374
+ subject: names.join(", "),
3375
+ detail: "resolved from this project's node_modules \u2014 no release, no pinned bytes",
3376
+ remedy: `publish it and run \`penv add ${names[0]}\` when this stops being a development path`
3377
+ }
3378
+ ];
3379
+ }
3299
3380
  function artifactFindings(project) {
3300
3381
  const files = [];
3301
3382
  scannableFiles(project.root, files);
@@ -3306,7 +3387,7 @@ function artifactFindings(project) {
3306
3387
  if (statSync2(file).size > ARTIFACT_SCAN_LIMIT) {
3307
3388
  continue;
3308
3389
  }
3309
- text = readFileSync5(file, "utf8");
3390
+ text = readFileSync6(file, "utf8");
3310
3391
  } catch {
3311
3392
  continue;
3312
3393
  }
@@ -4281,7 +4362,7 @@ var getCommand = defineCommand12({
4281
4362
  });
4282
4363
 
4283
4364
  // src/commands/import.ts
4284
- import { copyFileSync, existsSync as existsSync9, readFileSync as readFileSync9 } from "fs";
4365
+ import { copyFileSync, existsSync as existsSync9, readFileSync as readFileSync10 } from "fs";
4285
4366
  import { basename as basename2, isAbsolute as isAbsolute4, relative as relative4, resolve as resolve7 } from "path";
4286
4367
  import {
4287
4368
  assertNever as assertNever2,
@@ -4370,7 +4451,7 @@ function writeEntries(tree, entries, refs, scope) {
4370
4451
  }
4371
4452
 
4372
4453
  // src/detect.ts
4373
- import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
4454
+ import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
4374
4455
  import { join as join7 } from "path";
4375
4456
  import { DEFAULT_SCHEMA_FILE } from "@penvhq/core";
4376
4457
  var SIGNATURES = [
@@ -4388,7 +4469,7 @@ var SIGNATURES = [
4388
4469
  function exportsSchema(file) {
4389
4470
  let source;
4390
4471
  try {
4391
- source = readFileSync6(file, "utf8");
4472
+ source = readFileSync7(file, "utf8");
4392
4473
  } catch {
4393
4474
  return false;
4394
4475
  }
@@ -4440,7 +4521,7 @@ function manifestOf2(cwd) {
4440
4521
  }
4441
4522
  let manifest;
4442
4523
  try {
4443
- manifest = JSON.parse(readFileSync6(file, "utf8"));
4524
+ manifest = JSON.parse(readFileSync7(file, "utf8"));
4444
4525
  } catch {
4445
4526
  return void 0;
4446
4527
  }
@@ -4535,7 +4616,7 @@ function draftFieldsAcross(sources, environments) {
4535
4616
  }
4536
4617
 
4537
4618
  // src/commands/init.ts
4538
- import { existsSync as existsSync8, mkdirSync as mkdirSync4, readdirSync as readdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
4619
+ import { existsSync as existsSync8, mkdirSync as mkdirSync4, readdirSync as readdirSync5, readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "fs";
4539
4620
  import { dirname as dirname6, join as join9, resolve as resolve6 } from "path";
4540
4621
  import { createInterface as createInterface2 } from "readline/promises";
4541
4622
  import {
@@ -4547,7 +4628,7 @@ import {
4547
4628
  PenvError as PenvError18,
4548
4629
  parameterId as parameterId6,
4549
4630
  parseDotenv,
4550
- RECORDS_PATH as RECORDS_PATH2,
4631
+ RECORDS_PATH as RECORDS_PATH3,
4551
4632
  RESERVED_TOKENS as RESERVED_TOKENS2,
4552
4633
  ROLLBACK_DOTENV_PATH as ROLLBACK_DOTENV_PATH3,
4553
4634
  renderStateGitignore,
@@ -4564,7 +4645,7 @@ import {
4564
4645
  existsSync as existsSync7,
4565
4646
  mkdirSync as mkdirSync3,
4566
4647
  readdirSync as readdirSync4,
4567
- readFileSync as readFileSync7,
4648
+ readFileSync as readFileSync8,
4568
4649
  rmdirSync,
4569
4650
  statSync as statSync3,
4570
4651
  unlinkSync,
@@ -4586,7 +4667,7 @@ function record(path, files, dirs) {
4586
4667
  return;
4587
4668
  }
4588
4669
  if (stats.isFile()) {
4589
- files.set(path, readFileSync7(path));
4670
+ files.set(path, readFileSync8(path));
4590
4671
  }
4591
4672
  }
4592
4673
  function captureScaffold(root, paths) {
@@ -5374,7 +5455,7 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
5374
5455
  text: `Created ${TSCONFIG_FILE} with the ${alias} path alias`
5375
5456
  };
5376
5457
  }
5377
- const source = readFileSync8(file, "utf8");
5458
+ const source = readFileSync9(file, "utf8");
5378
5459
  const edit = imports ? insertImportsAlias(source, decisions.schemaFile, alias) : insertEnvAlias(source, decisions.schemaFile, alias);
5379
5460
  if (edit.conflict !== void 0) {
5380
5461
  return {
@@ -5401,7 +5482,7 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
5401
5482
  function writeGitignore(root, decisions = DEFAULT_DECISIONS) {
5402
5483
  const file = join9(root, ...STATE_GITIGNORE_PATH.split("/"));
5403
5484
  const wanted = renderStateGitignore(configOf(decisions));
5404
- const existing = existsSync8(file) ? readFileSync8(file, "utf8") : void 0;
5485
+ const existing = existsSync8(file) ? readFileSync9(file, "utf8") : void 0;
5405
5486
  if (existing === wanted) {
5406
5487
  return { target: "gitignore", action: "kept", text: `Kept ${STATE_GITIGNORE_PATH}` };
5407
5488
  }
@@ -5427,7 +5508,7 @@ function installedPenvVersion(root) {
5427
5508
  return void 0;
5428
5509
  }
5429
5510
  try {
5430
- const version = JSON.parse(readFileSync8(file, "utf8")).version;
5511
+ const version = JSON.parse(readFileSync9(file, "utf8")).version;
5431
5512
  return typeof version === "string" ? version : void 0;
5432
5513
  } catch {
5433
5514
  return void 0;
@@ -5601,7 +5682,7 @@ function planCutover(input) {
5601
5682
  const diagnostics = [];
5602
5683
  let variables = 0;
5603
5684
  for (const file of selected) {
5604
- const parsed = parseDotenv(readFileSync8(join9(root, file.name), "utf8"));
5685
+ const parsed = parseDotenv(readFileSync9(join9(root, file.name), "utf8"));
5605
5686
  const fileRefs = refsForEntries(parsed.entries, file.name, config);
5606
5687
  adopted.push({ file, entries: parsed.entries, refs: fileRefs, scope: scopeOf(file) });
5607
5688
  refs.push(...fileRefs);
@@ -5789,7 +5870,7 @@ function renderCutoverPlan(plan2) {
5789
5870
  ]);
5790
5871
  rows.push([
5791
5872
  ` ${out.dim("values")}`,
5792
- `${RECORDS_PATH2}/`,
5873
+ `${RECORDS_PATH3}/`,
5793
5874
  out.dim(`\u2190 from ${plan2.variables} variables`)
5794
5875
  ]);
5795
5876
  rows.push([
@@ -5825,7 +5906,7 @@ function renderCutover(result2) {
5825
5906
  {
5826
5907
  glyph: CHECK,
5827
5908
  text: `Imported ${plan2.fields.length} parameters`,
5828
- note: `into ${RECORDS_PATH2}/`
5909
+ note: `into ${RECORDS_PATH3}/`
5829
5910
  },
5830
5911
  { glyph: CHECK, text: `Validated ${result2.validated.join(", ")}` },
5831
5912
  {
@@ -5850,7 +5931,7 @@ function devScript(root) {
5850
5931
  return "dev";
5851
5932
  }
5852
5933
  try {
5853
- const scripts = JSON.parse(readFileSync8(file, "utf8")).scripts;
5934
+ const scripts = JSON.parse(readFileSync9(file, "utf8")).scripts;
5854
5935
  if (scripts !== null && typeof scripts === "object" && !Array.isArray(scripts)) {
5855
5936
  const named = Object.keys(scripts);
5856
5937
  return ["dev", "start"].find((script) => named.includes(script)) ?? named[0] ?? "dev";
@@ -6084,7 +6165,7 @@ function runUndoAction(root, action) {
6084
6165
  ]),
6085
6166
  "",
6086
6167
  result2.missing.length === 0 ? `${out.green(CHECK)} ${out.bold("Undone.")} Your dotenv files are back exactly as they were, and ${CUTOVER_PATH3} is gone.` : `${out.yellow(WARN)} ${out.bold("Undone as far as penv could.")} Everything still in the bundle is back, and ${CUTOVER_PATH3} is gone.`,
6087
- `penv's records are still in ${RECORDS_PATH2}/ \u2014 nothing penv scaffolded is yours to lose.`
6168
+ `penv's records are still in ${RECORDS_PATH3}/ \u2014 nothing penv scaffolded is yours to lose.`
6088
6169
  ]);
6089
6170
  }
6090
6171
 
@@ -6226,7 +6307,7 @@ function importDotenv(options) {
6226
6307
  "Point `penv import` at an existing dotenv file, e.g. `penv import .env`."
6227
6308
  );
6228
6309
  }
6229
- const parsed = parseDotenv2(readFileSync9(file, "utf8"));
6310
+ const parsed = parseDotenv2(readFileSync10(file, "utf8"));
6230
6311
  const { config, decisions } = configInEffect(cwd, environmentNamed(file, options.environment));
6231
6312
  const source = displayPath3(cwd, file);
6232
6313
  const named = scopeFromFilename(file, config);
@@ -6497,7 +6578,7 @@ var keyCommand = defineCommand15({
6497
6578
  });
6498
6579
 
6499
6580
  // src/commands/list.ts
6500
- import { assertNever as assertNever3, RECORDS_PATH as RECORDS_PATH3, resolveAll as resolveAll3, variableName as variableName8 } from "@penvhq/core";
6581
+ import { assertNever as assertNever3, RECORDS_PATH as RECORDS_PATH4, resolveAll as resolveAll3, variableName as variableName8 } from "@penvhq/core";
6501
6582
  import { defineCommand as defineCommand16 } from "citty";
6502
6583
  function scopeLabel2(scope) {
6503
6584
  switch (scope.kind) {
@@ -6541,7 +6622,7 @@ function paintScope(entry) {
6541
6622
  function renderList(result2) {
6542
6623
  if (result2.parameters.length === 0) {
6543
6624
  return [
6544
- `No parameters in ${RECORDS_PATH3}/ for environment ${result2.environment}.`,
6625
+ `No parameters in ${RECORDS_PATH4}/ for environment ${result2.environment}.`,
6545
6626
  tip(`penv set <key> --env ${result2.environment}`)
6546
6627
  ];
6547
6628
  }
@@ -6580,7 +6661,7 @@ import {
6580
6661
  existsSync as existsSync10,
6581
6662
  mkdirSync as mkdirSync5,
6582
6663
  readdirSync as readdirSync6,
6583
- readFileSync as readFileSync10,
6664
+ readFileSync as readFileSync11,
6584
6665
  renameSync as renameSync2,
6585
6666
  rmSync as rmSync2,
6586
6667
  writeFileSync as writeFileSync6
@@ -6592,7 +6673,7 @@ import {
6592
6673
  oldLayoutEntries,
6593
6674
  PENV_DIR as PENV_DIR3,
6594
6675
  PenvError as PenvError22,
6595
- RECORDS_PATH as RECORDS_PATH4,
6676
+ RECORDS_PATH as RECORDS_PATH5,
6596
6677
  recordsDir as recordsDir3,
6597
6678
  renderStateGitignore as renderStateGitignore2,
6598
6679
  STATE_GITIGNORE_PATH as STATE_GITIGNORE_PATH2
@@ -6608,13 +6689,13 @@ function planMigrate(cwd) {
6608
6689
  if (collisions.length > 0) {
6609
6690
  throw new PenvError22(
6610
6691
  "HALF_MIGRATED",
6611
- `${describe2(collisions)} in both \`${PENV_DIR3}/\` and \`${RECORDS_PATH4}/\`, and penv cannot tell which copy is current`,
6612
- `Move what is left under \`${PENV_DIR3}/\` into \`${RECORDS_PATH4}/\` yourself, keeping the copy you want, then run \`penv validate\`.`
6692
+ `${describe2(collisions)} in both \`${PENV_DIR3}/\` and \`${RECORDS_PATH5}/\`, and penv cannot tell which copy is current`,
6693
+ `Move what is left under \`${PENV_DIR3}/\` into \`${RECORDS_PATH5}/\` yourself, keeping the copy you want, then run \`penv validate\`.`
6613
6694
  );
6614
6695
  }
6615
6696
  const creates = [];
6616
6697
  if (entries.length > 0 && !existsSync10(tree)) {
6617
- creates.push(`${RECORDS_PATH4}/`);
6698
+ creates.push(`${RECORDS_PATH5}/`);
6618
6699
  }
6619
6700
  if (readIfPresent(join10(root, ...STATE_GITIGNORE_PATH2.split("/"))) !== renderStateGitignore2(config)) {
6620
6701
  creates.push(STATE_GITIGNORE_PATH2);
@@ -6623,14 +6704,14 @@ function planMigrate(cwd) {
6623
6704
  root,
6624
6705
  moves: entries.map((entry) => ({
6625
6706
  from: `${PENV_DIR3}/${entry}`,
6626
- to: `${RECORDS_PATH4}/${entry}`
6707
+ to: `${RECORDS_PATH5}/${entry}`
6627
6708
  })),
6628
6709
  creates,
6629
6710
  removes: existsSync10(join10(root, ...OLD_GITIGNORE.split("/"))) ? [OLD_GITIGNORE] : []
6630
6711
  };
6631
6712
  }
6632
6713
  function readIfPresent(file) {
6633
- return existsSync10(file) ? readFileSync10(file, "utf8") : void 0;
6714
+ return existsSync10(file) ? readFileSync11(file, "utf8") : void 0;
6634
6715
  }
6635
6716
  function collidingEntries(entries, tree) {
6636
6717
  let held;
@@ -6678,7 +6759,7 @@ function runMigrate(options) {
6678
6759
  }
6679
6760
  function renderMigrate(result2) {
6680
6761
  if (result2.status === "current") {
6681
- return [`${out.green(CHECK)} Already on ${RECORDS_PATH4}/ \u2014 nothing to migrate.`];
6762
+ return [`${out.green(CHECK)} Already on ${RECORDS_PATH5}/ \u2014 nothing to migrate.`];
6682
6763
  }
6683
6764
  const done = result2.status === "migrated";
6684
6765
  const glyph = done ? CHECK : "\u2192";
@@ -6719,7 +6800,7 @@ async function approveOnTty() {
6719
6800
  var migrateCommand = defineCommand17({
6720
6801
  meta: {
6721
6802
  name: "migrate",
6722
- description: `Move a project written under an earlier layout to ${RECORDS_PATH4}/`
6803
+ description: `Move a project written under an earlier layout to ${RECORDS_PATH5}/`
6723
6804
  },
6724
6805
  args: {
6725
6806
  yes: { type: "boolean", description: "Apply the previewed move without asking" }