@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.cjs CHANGED
@@ -69,7 +69,7 @@ var import_core35 = require("@penvhq/core");
69
69
  var import_citty22 = require("citty");
70
70
 
71
71
  // src/commands/artifact.ts
72
- var import_node_fs6 = require("fs");
72
+ var import_node_fs7 = require("fs");
73
73
  var import_node_path7 = require("path");
74
74
  var import_core12 = require("@penvhq/core");
75
75
  var import_runtime2 = require("@penvhq/runtime");
@@ -381,7 +381,7 @@ function installFailed(plan2) {
381
381
  }
382
382
 
383
383
  // src/project.ts
384
- var import_node_fs3 = require("fs");
384
+ var import_node_fs4 = require("fs");
385
385
  var import_node_path4 = require("path");
386
386
  var import_core5 = require("@penvhq/core");
387
387
  var import_provider_filesystem2 = require("@penvhq/provider-filesystem");
@@ -445,6 +445,7 @@ function environmentFromShorthand(config, candidates, explicit) {
445
445
  }
446
446
 
447
447
  // src/registry.ts
448
+ var import_node_fs3 = require("fs");
448
449
  var import_node_module = require("module");
449
450
  var import_node_path3 = require("path");
450
451
  var import_node_url = require("url");
@@ -517,16 +518,40 @@ async function loadPluginProvider(type, context) {
517
518
  assertSatisfiesContract(provider, type);
518
519
  return provider;
519
520
  }
520
- function assertProvidersRegistered(config, projectRoot) {
521
+ function assertProvidersRegistered(config, projectRoot, options) {
522
+ const local = localExtensions(projectRoot);
523
+ const ci = options?.ci ?? isCi(process.env.CI);
521
524
  for (const [environment, provider] of Object.entries(config.providers)) {
522
525
  if (isProviderRegistered(provider.type)) {
523
526
  continue;
524
527
  }
528
+ if (ci && local.includes(provider.type)) {
529
+ throw localExtensionInCi(provider.type, environment);
530
+ }
525
531
  if (resolvePlugin(provider.type, projectRoot) === void 0) {
526
532
  throw unknownProvider(provider.type, environment);
527
533
  }
528
534
  }
529
535
  }
536
+ function localExtensions(projectRoot) {
537
+ let text;
538
+ try {
539
+ text = (0, import_node_fs3.readFileSync)((0, import_core4.localExtensionsFile)(projectRoot), "utf8");
540
+ } catch {
541
+ return [];
542
+ }
543
+ return (0, import_core4.parseLocalExtensions)(text);
544
+ }
545
+ function isCi(value) {
546
+ return value !== void 0 && value !== "" && value !== "0" && value.toLowerCase() !== "false";
547
+ }
548
+ function localExtensionInCi(type, environment) {
549
+ return new import_core4.PenvError(
550
+ "LOCAL_EXTENSION_IN_CI",
551
+ `The provider \`${type}\` for environment ${environment} is a local extension, and this is CI`,
552
+ `${import_core4.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.`
553
+ );
554
+ }
530
555
  function resolvePlugin(specifier, fromDir) {
531
556
  try {
532
557
  const require2 = (0, import_node_module.createRequire)((0, import_node_path3.resolve)(fromDir, "noop.js"));
@@ -564,7 +589,7 @@ function unknownProvider(type, environment) {
564
589
  return new import_core4.PenvError(
565
590
  "UNKNOWN_PROVIDER",
566
591
  `The provider \`${type}\`${where} in penv.config.ts is not installed in this project`,
567
- `Install it with \`npm i ${type}\` \u2014 a provider's \`type\` is the package penv imports. The CLI ships ${preinstalled} pre-installed.`
592
+ `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.`
568
593
  );
569
594
  }
570
595
 
@@ -594,10 +619,10 @@ function localTree(project) {
594
619
  }
595
620
  function selfContainedSchemaModule(root, schemaFile) {
596
621
  const file = (0, import_node_path4.join)(root, ...schemaFile.split("/"));
597
- if (!(0, import_node_fs3.existsSync)(file)) {
622
+ if (!(0, import_node_fs4.existsSync)(file)) {
598
623
  return void 0;
599
624
  }
600
- const source = (0, import_node_fs3.readFileSync)(file, "utf8");
625
+ const source = (0, import_node_fs4.readFileSync)(file, "utf8");
601
626
  return source.includes("PenvSchemaShape") || source.includes("z.object") ? schemaFile : void 0;
602
627
  }
603
628
  function schemaShapeFileOf(project) {
@@ -833,10 +858,7 @@ function writeError(lines) {
833
858
  }
834
859
  function reportError(error) {
835
860
  if (error instanceof import_core6.PenvError) {
836
- const suffix = error.remedy === void 0 ? void 0 : `
837
- ${error.remedy}`;
838
- const message = suffix !== void 0 && error.message.endsWith(suffix) ? error.message.slice(0, -suffix.length) : error.message;
839
- process.stderr.write(`${err.red(CROSS)} ${message}
861
+ process.stderr.write(`${err.red(CROSS)} ${error.summary}
840
862
  `);
841
863
  if (error.remedy !== void 0) {
842
864
  process.stderr.write(` ${err.cyan("\u2192")} ${error.remedy}
@@ -866,7 +888,7 @@ async function guard(run) {
866
888
  }
867
889
 
868
890
  // src/commands/run.ts
869
- var import_node_fs5 = require("fs");
891
+ var import_node_fs6 = require("fs");
870
892
  var import_node_module2 = require("module");
871
893
  var import_node_path6 = require("path");
872
894
  var import_core11 = require("@penvhq/core");
@@ -874,7 +896,7 @@ var import_runtime = require("@penvhq/runtime");
874
896
  var import_citty3 = require("citty");
875
897
 
876
898
  // src/dotenv-files.ts
877
- var import_node_fs4 = require("fs");
899
+ var import_node_fs5 = require("fs");
878
900
  var import_core7 = require("@penvhq/core");
879
901
  var SHARED = ".env";
880
902
  var LOCAL = "local";
@@ -934,7 +956,7 @@ function order(file) {
934
956
  function discoverDotenvFiles(root) {
935
957
  let entries;
936
958
  try {
937
- entries = (0, import_node_fs4.readdirSync)(root, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name);
959
+ entries = (0, import_node_fs5.readdirSync)(root, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name);
938
960
  } catch {
939
961
  return [];
940
962
  }
@@ -1671,9 +1693,9 @@ function packageManifest(specifier, root) {
1671
1693
  }
1672
1694
  for (; ; ) {
1673
1695
  const file = (0, import_node_path6.join)(directory, "package.json");
1674
- if ((0, import_node_fs5.existsSync)(file)) {
1696
+ if ((0, import_node_fs6.existsSync)(file)) {
1675
1697
  try {
1676
- const parsed = JSON.parse((0, import_node_fs5.readFileSync)(file, "utf8"));
1698
+ const parsed = JSON.parse((0, import_node_fs6.readFileSync)(file, "utf8"));
1677
1699
  if (isPlainObject(parsed) && parsed.name === specifier) {
1678
1700
  return parsed;
1679
1701
  }
@@ -1746,7 +1768,7 @@ function snapshotPath(host) {
1746
1768
  }
1747
1769
  function readSnapshot(path) {
1748
1770
  try {
1749
- return (0, import_node_fs5.readFileSync)(path, "utf8");
1771
+ return (0, import_node_fs6.readFileSync)(path, "utf8");
1750
1772
  } catch {
1751
1773
  throw new import_core11.PenvError(
1752
1774
  "RUN_SNAPSHOT_MISSING",
@@ -1825,11 +1847,11 @@ function watchProject(project, onChange) {
1825
1847
  timer = setTimeout(onChange, DEBOUNCE_MS);
1826
1848
  };
1827
1849
  const add = (target, recursive, only) => {
1828
- if (!(0, import_node_fs5.existsSync)(target)) {
1850
+ if (!(0, import_node_fs6.existsSync)(target)) {
1829
1851
  return;
1830
1852
  }
1831
1853
  try {
1832
- const watcher = (0, import_node_fs5.watch)(target, { recursive }, (_event, filename) => {
1854
+ const watcher = (0, import_node_fs6.watch)(target, { recursive }, (_event, filename) => {
1833
1855
  if (only !== void 0 && (filename === null || (0, import_node_path6.basename)(filename) !== only)) {
1834
1856
  return;
1835
1857
  }
@@ -2092,8 +2114,8 @@ ${lines}`,
2092
2114
  keySource: (0, import_core12.keySourceIdentifier)(project.config, environment),
2093
2115
  values
2094
2116
  };
2095
- (0, import_node_fs6.mkdirSync)((0, import_node_path7.dirname)(file), { recursive: true });
2096
- (0, import_node_fs6.writeFileSync)(file, (0, import_core12.serializeArtifact)(artifact), "utf8");
2117
+ (0, import_node_fs7.mkdirSync)((0, import_node_path7.dirname)(file), { recursive: true });
2118
+ (0, import_node_fs7.writeFileSync)(file, (0, import_core12.serializeArtifact)(artifact), "utf8");
2097
2119
  const inside = (0, import_node_path7.relative)(project.root, file);
2098
2120
  return {
2099
2121
  file,
@@ -2163,7 +2185,7 @@ var import_core14 = require("@penvhq/core");
2163
2185
  var import_citty5 = require("citty");
2164
2186
 
2165
2187
  // src/cutover.ts
2166
- var import_node_fs7 = require("fs");
2188
+ var import_node_fs8 = require("fs");
2167
2189
  var import_node_path8 = require("path");
2168
2190
  var import_core13 = require("@penvhq/core");
2169
2191
  var CUTOVER_FORMAT = 1;
@@ -2182,7 +2204,7 @@ function cutoverRoot(cwd) {
2182
2204
  }
2183
2205
  function bundledFiles(root) {
2184
2206
  try {
2185
- return (0, import_node_fs7.readdirSync)(bundleDir(root)).sort();
2207
+ return (0, import_node_fs8.readdirSync)(bundleDir(root)).sort();
2186
2208
  } catch {
2187
2209
  return [];
2188
2210
  }
@@ -2192,12 +2214,12 @@ function bundleUnresolved(root) {
2192
2214
  }
2193
2215
  function readCutover(root) {
2194
2216
  const file = cutoverFile(root);
2195
- if (!(0, import_node_fs7.existsSync)(file)) {
2217
+ if (!(0, import_node_fs8.existsSync)(file)) {
2196
2218
  return void 0;
2197
2219
  }
2198
2220
  let parsed;
2199
2221
  try {
2200
- parsed = JSON.parse((0, import_node_fs7.readFileSync)(file, "utf8"));
2222
+ parsed = JSON.parse((0, import_node_fs8.readFileSync)(file, "utf8"));
2201
2223
  } catch {
2202
2224
  throw unreadable("it is not JSON");
2203
2225
  }
@@ -2250,12 +2272,12 @@ function bundleDotenvFiles(root, files, environments, now = /* @__PURE__ */ new
2250
2272
  environments: [...environments]
2251
2273
  };
2252
2274
  const file = cutoverFile(root);
2253
- (0, import_node_fs7.mkdirSync)((0, import_node_path8.dirname)(file), { recursive: true });
2254
- (0, import_node_fs7.writeFileSync)(file, serializeCutover(cutover), "utf8");
2275
+ (0, import_node_fs8.mkdirSync)((0, import_node_path8.dirname)(file), { recursive: true });
2276
+ (0, import_node_fs8.writeFileSync)(file, serializeCutover(cutover), "utf8");
2255
2277
  const bundle = bundleDir(root);
2256
- (0, import_node_fs7.mkdirSync)(bundle, { recursive: true });
2278
+ (0, import_node_fs8.mkdirSync)(bundle, { recursive: true });
2257
2279
  for (const name of files) {
2258
- (0, import_node_fs7.renameSync)((0, import_node_path8.join)(root, name), (0, import_node_path8.join)(bundle, name));
2280
+ (0, import_node_fs8.renameSync)((0, import_node_path8.join)(root, name), (0, import_node_path8.join)(bundle, name));
2259
2281
  }
2260
2282
  return cutover;
2261
2283
  }
@@ -2274,7 +2296,7 @@ function runUndo(options) {
2274
2296
  const names = [...recorded, ...bundled.filter((name) => !recorded.includes(name))];
2275
2297
  const bundle = bundleDir(root);
2276
2298
  const held = new Set(bundled);
2277
- const occupied2 = names.filter((name) => held.has(name) && (0, import_node_fs7.existsSync)((0, import_node_path8.join)(root, name)));
2299
+ const occupied2 = names.filter((name) => held.has(name) && (0, import_node_fs8.existsSync)((0, import_node_path8.join)(root, name)));
2278
2300
  if (occupied2.length > 0) {
2279
2301
  const listed = occupied2.join(", ");
2280
2302
  const many = occupied2.length > 1;
@@ -2289,9 +2311,9 @@ function runUndo(options) {
2289
2311
  const missing = [];
2290
2312
  for (const name of names) {
2291
2313
  if (held.has(name)) {
2292
- (0, import_node_fs7.renameSync)((0, import_node_path8.join)(bundle, name), (0, import_node_path8.join)(root, name));
2314
+ (0, import_node_fs8.renameSync)((0, import_node_path8.join)(bundle, name), (0, import_node_path8.join)(root, name));
2293
2315
  restored.push(name);
2294
- } else if ((0, import_node_fs7.existsSync)((0, import_node_path8.join)(root, name))) {
2316
+ } else if ((0, import_node_fs8.existsSync)((0, import_node_path8.join)(root, name))) {
2295
2317
  alreadyBack.push(name);
2296
2318
  } else {
2297
2319
  missing.push(name);
@@ -2303,13 +2325,13 @@ function runUndo(options) {
2303
2325
  function runCleanup(options) {
2304
2326
  const root = cutoverRoot(options.cwd);
2305
2327
  const held = bundledFiles(root);
2306
- const cleaned = held.length > 0 || (0, import_node_fs7.existsSync)(cutoverFile(root)) || (0, import_node_fs7.existsSync)(fileFor(root, import_core13.ROLLBACK_PATH));
2328
+ const cleaned = held.length > 0 || (0, import_node_fs8.existsSync)(cutoverFile(root)) || (0, import_node_fs8.existsSync)(fileFor(root, import_core13.ROLLBACK_PATH));
2307
2329
  removeBundle(root);
2308
2330
  return { root, removed: held, cleaned };
2309
2331
  }
2310
2332
  function removeBundle(root) {
2311
- (0, import_node_fs7.rmSync)(fileFor(root, import_core13.ROLLBACK_PATH), { recursive: true, force: true });
2312
- (0, import_node_fs7.rmSync)(cutoverFile(root), { force: true });
2333
+ (0, import_node_fs8.rmSync)(fileFor(root, import_core13.ROLLBACK_PATH), { recursive: true, force: true });
2334
+ (0, import_node_fs8.rmSync)(cutoverFile(root), { force: true });
2313
2335
  }
2314
2336
 
2315
2337
  // src/commands/cleanup.ts
@@ -2344,7 +2366,7 @@ var cleanupCommand = (0, import_citty5.defineCommand)({
2344
2366
  });
2345
2367
 
2346
2368
  // src/commands/doctor.ts
2347
- var import_node_fs8 = require("fs");
2369
+ var import_node_fs9 = require("fs");
2348
2370
  var import_node_path9 = require("path");
2349
2371
  var import_core16 = require("@penvhq/core");
2350
2372
  var import_citty7 = require("citty");
@@ -2790,6 +2812,7 @@ async function runDoctor(options) {
2790
2812
  findings.push(...unusedFindings(drift));
2791
2813
  }
2792
2814
  findings.push(...fallbackFindings(subjects, environment));
2815
+ findings.push(...secrecyFindings(subjects, environment));
2793
2816
  findings.push(...plaintextSecretFindings(subjects, environment));
2794
2817
  findings.push(...publicSecretFindings(subjects, environment, project.config));
2795
2818
  findings.push(...encryptionFindings(subjects, environment));
@@ -2802,6 +2825,7 @@ async function runDoctor(options) {
2802
2825
  }
2803
2826
  findings.push(...await providerDriftFindings(project, environment, options.source));
2804
2827
  findings.push(...await projectionFindings(project, environment, options.projection));
2828
+ findings.push(...localExtensionFindings(project));
2805
2829
  findings.push(...artifactFindings(project));
2806
2830
  findings.push({
2807
2831
  check: "provider",
@@ -2939,6 +2963,31 @@ function fallbackFindings(subjects, environment) {
2939
2963
  }
2940
2964
  ];
2941
2965
  }
2966
+ function secrecyFindings(subjects, environment) {
2967
+ const undeclared = subjects.filter(
2968
+ ({ meta }) => (0, import_core16.effectiveMeta)(meta, environment).secret === void 0
2969
+ );
2970
+ if (undeclared.length === 0) {
2971
+ return [
2972
+ {
2973
+ check: "secrecy-undeclared",
2974
+ severity: "pass",
2975
+ label: "Secrecy policy",
2976
+ subject: subjects.length === 0 ? `no parameter resolves for ${environment}` : `every parameter declares whether it is secret for ${environment}`
2977
+ }
2978
+ ];
2979
+ }
2980
+ return [
2981
+ {
2982
+ check: "secrecy-undeclared",
2983
+ severity: "unknown",
2984
+ label: "Secrecy policy",
2985
+ subject: `${undeclared.length} of ${subjects.length} declare neither way for ${environment}`,
2986
+ detail: "penv was never told which of these values must be encrypted",
2987
+ remedy: `declare \`"secret": true\` or \`"secret": false\` in a parameter's meta file, ${import_core16.RECORDS_PATH}/<name>.json`
2988
+ }
2989
+ ];
2990
+ }
2942
2991
  function plaintextSecretFindings(subjects, environment) {
2943
2992
  const secrets = subjects.filter(({ meta }) => (0, import_core16.isSecret)(meta, environment));
2944
2993
  const findings = [];
@@ -3242,7 +3291,7 @@ function looksLikeArtifact(text) {
3242
3291
  function scannableFiles(directory, out2) {
3243
3292
  let entries;
3244
3293
  try {
3245
- entries = (0, import_node_fs8.readdirSync)(directory, { withFileTypes: true });
3294
+ entries = (0, import_node_fs9.readdirSync)(directory, { withFileTypes: true });
3246
3295
  } catch {
3247
3296
  return;
3248
3297
  }
@@ -3259,6 +3308,29 @@ function scannableFiles(directory, out2) {
3259
3308
  }
3260
3309
  }
3261
3310
  }
3311
+ function localExtensionFindings(project) {
3312
+ const names = localExtensions(project.root);
3313
+ if (names.length === 0) {
3314
+ return [
3315
+ {
3316
+ check: "local-extension",
3317
+ severity: "pass",
3318
+ label: "Extensions",
3319
+ subject: "every extension this project names is pinned"
3320
+ }
3321
+ ];
3322
+ }
3323
+ return [
3324
+ {
3325
+ check: "local-extension",
3326
+ severity: "unknown",
3327
+ label: "Extensions",
3328
+ subject: names.join(", "),
3329
+ detail: "resolved from this project's node_modules \u2014 no release, no pinned bytes",
3330
+ remedy: `publish it and run \`penv add ${names[0]}\` when this stops being a development path`
3331
+ }
3332
+ ];
3333
+ }
3262
3334
  function artifactFindings(project) {
3263
3335
  const files = [];
3264
3336
  scannableFiles(project.root, files);
@@ -3266,10 +3338,10 @@ function artifactFindings(project) {
3266
3338
  for (const file of files) {
3267
3339
  let text;
3268
3340
  try {
3269
- if ((0, import_node_fs8.statSync)(file).size > ARTIFACT_SCAN_LIMIT) {
3341
+ if ((0, import_node_fs9.statSync)(file).size > ARTIFACT_SCAN_LIMIT) {
3270
3342
  continue;
3271
3343
  }
3272
- text = (0, import_node_fs8.readFileSync)(file, "utf8");
3344
+ text = (0, import_node_fs9.readFileSync)(file, "utf8");
3273
3345
  } catch {
3274
3346
  continue;
3275
3347
  }
@@ -4029,7 +4101,7 @@ var fillCommand = (0, import_citty10.defineCommand)({
4029
4101
  });
4030
4102
 
4031
4103
  // src/commands/generate.ts
4032
- var import_node_fs9 = require("fs");
4104
+ var import_node_fs10 = require("fs");
4033
4105
  var import_node_path10 = require("path");
4034
4106
  var import_core20 = require("@penvhq/core");
4035
4107
  var import_citty11 = require("citty");
@@ -4083,7 +4155,7 @@ function runGenerate(options) {
4083
4155
  const environment = targetEnvironment(project, options.environment, options.envFlags);
4084
4156
  const { entries, decrypted } = entriesFor(project, environment, options.allowDecrypt === true);
4085
4157
  const file = options.out === void 0 ? (0, import_node_path10.resolve)(project.root, DEFAULT_OUTPUT) : (0, import_node_path10.isAbsolute)(options.out) ? options.out : (0, import_node_path10.resolve)(options.cwd, options.out);
4086
- (0, import_node_fs9.writeFileSync)(file, (0, import_core20.serializeDotenv)(entries), "utf8");
4158
+ (0, import_node_fs10.writeFileSync)(file, (0, import_core20.serializeDotenv)(entries), "utf8");
4087
4159
  return { file, environment, entries: entries.length, decrypted };
4088
4160
  }
4089
4161
  function displayPath2(cwd, file) {
@@ -4221,7 +4293,7 @@ var getCommand = (0, import_citty12.defineCommand)({
4221
4293
  });
4222
4294
 
4223
4295
  // src/commands/import.ts
4224
- var import_node_fs13 = require("fs");
4296
+ var import_node_fs14 = require("fs");
4225
4297
  var import_node_path14 = require("path");
4226
4298
  var import_core26 = require("@penvhq/core");
4227
4299
  var import_citty14 = require("citty");
@@ -4292,7 +4364,7 @@ function writeEntries(tree, entries, refs, scope) {
4292
4364
  }
4293
4365
 
4294
4366
  // src/detect.ts
4295
- var import_node_fs10 = require("fs");
4367
+ var import_node_fs11 = require("fs");
4296
4368
  var import_node_path11 = require("path");
4297
4369
  var import_core23 = require("@penvhq/core");
4298
4370
  var SIGNATURES = [
@@ -4310,7 +4382,7 @@ var SIGNATURES = [
4310
4382
  function exportsSchema(file) {
4311
4383
  let source;
4312
4384
  try {
4313
- source = (0, import_node_fs10.readFileSync)(file, "utf8");
4385
+ source = (0, import_node_fs11.readFileSync)(file, "utf8");
4314
4386
  } catch {
4315
4387
  return false;
4316
4388
  }
@@ -4322,7 +4394,7 @@ function exportsSchema(file) {
4322
4394
  }
4323
4395
  function occupied(cwd, relative5) {
4324
4396
  const file = (0, import_node_path11.join)(cwd, ...relative5.split("/"));
4325
- return (0, import_node_fs10.existsSync)(file) && !exportsSchema(file);
4397
+ return (0, import_node_fs11.existsSync)(file) && !exportsSchema(file);
4326
4398
  }
4327
4399
  function schemaFileFor(cwd) {
4328
4400
  const dir = srcPrefix(cwd);
@@ -4337,7 +4409,7 @@ function schemaFileFor(cwd) {
4337
4409
  return { file: import_core23.DEFAULT_SCHEMA_FILE, displaced: preferred };
4338
4410
  }
4339
4411
  function srcPrefix(cwd) {
4340
- return (0, import_node_fs10.existsSync)((0, import_node_path11.join)(cwd, "src")) ? "src/" : "";
4412
+ return (0, import_node_fs11.existsSync)((0, import_node_path11.join)(cwd, "src")) ? "src/" : "";
4341
4413
  }
4342
4414
  function dependenciesOf(cwd) {
4343
4415
  const manifest = manifestOf2(cwd);
@@ -4357,12 +4429,12 @@ function dependenciesOf(cwd) {
4357
4429
  }
4358
4430
  function manifestOf2(cwd) {
4359
4431
  const file = (0, import_node_path11.join)(cwd, "package.json");
4360
- if (!(0, import_node_fs10.existsSync)(file)) {
4432
+ if (!(0, import_node_fs11.existsSync)(file)) {
4361
4433
  return void 0;
4362
4434
  }
4363
4435
  let manifest;
4364
4436
  try {
4365
- manifest = JSON.parse((0, import_node_fs10.readFileSync)(file, "utf8"));
4437
+ manifest = JSON.parse((0, import_node_fs11.readFileSync)(file, "utf8"));
4366
4438
  } catch {
4367
4439
  return void 0;
4368
4440
  }
@@ -4378,7 +4450,7 @@ function detectFramework(cwd) {
4378
4450
  return detectedFrom(cwd, signature.name, signature.publicPrefixes);
4379
4451
  }
4380
4452
  }
4381
- if ((0, import_node_fs10.existsSync)((0, import_node_path11.join)(cwd, "bunfig.toml")) || dependencies.has("bun-types")) {
4453
+ if ((0, import_node_fs11.existsSync)((0, import_node_path11.join)(cwd, "bunfig.toml")) || dependencies.has("bun-types")) {
4382
4454
  return detectedFrom(cwd, "Bun", []);
4383
4455
  }
4384
4456
  return void 0;
@@ -4457,31 +4529,31 @@ function draftFieldsAcross(sources, environments) {
4457
4529
  }
4458
4530
 
4459
4531
  // src/commands/init.ts
4460
- var import_node_fs12 = require("fs");
4532
+ var import_node_fs13 = require("fs");
4461
4533
  var import_node_path13 = require("path");
4462
4534
  var import_promises = require("readline/promises");
4463
4535
  var import_core25 = require("@penvhq/core");
4464
4536
  var import_citty13 = require("citty");
4465
4537
 
4466
4538
  // src/scaffold-undo.ts
4467
- var import_node_fs11 = require("fs");
4539
+ var import_node_fs12 = require("fs");
4468
4540
  var import_node_path12 = require("path");
4469
4541
  function record(path, files, dirs) {
4470
4542
  let stats;
4471
4543
  try {
4472
- stats = (0, import_node_fs11.statSync)(path);
4544
+ stats = (0, import_node_fs12.statSync)(path);
4473
4545
  } catch {
4474
4546
  return;
4475
4547
  }
4476
4548
  if (stats.isDirectory()) {
4477
4549
  dirs.add(path);
4478
- for (const entry of (0, import_node_fs11.readdirSync)(path)) {
4550
+ for (const entry of (0, import_node_fs12.readdirSync)(path)) {
4479
4551
  record((0, import_node_path12.join)(path, entry), files, dirs);
4480
4552
  }
4481
4553
  return;
4482
4554
  }
4483
4555
  if (stats.isFile()) {
4484
- files.set(path, (0, import_node_fs11.readFileSync)(path));
4556
+ files.set(path, (0, import_node_fs12.readFileSync)(path));
4485
4557
  }
4486
4558
  }
4487
4559
  function captureScaffold(root, paths) {
@@ -4489,7 +4561,7 @@ function captureScaffold(root, paths) {
4489
4561
  const dirs = /* @__PURE__ */ new Set();
4490
4562
  for (const path of paths) {
4491
4563
  for (let dir = (0, import_node_path12.dirname)(path); dir.startsWith(root) && dir !== root; dir = (0, import_node_path12.dirname)(dir)) {
4492
- if ((0, import_node_fs11.existsSync)(dir)) {
4564
+ if ((0, import_node_fs12.existsSync)(dir)) {
4493
4565
  dirs.add(dir);
4494
4566
  }
4495
4567
  }
@@ -4505,31 +4577,31 @@ function restoreScaffold(undo) {
4505
4577
  pruneAncestors(path, undo);
4506
4578
  }
4507
4579
  for (const [file, contents] of undo.files) {
4508
- (0, import_node_fs11.mkdirSync)((0, import_node_path12.dirname)(file), { recursive: true });
4509
- (0, import_node_fs11.writeFileSync)(file, contents);
4580
+ (0, import_node_fs12.mkdirSync)((0, import_node_path12.dirname)(file), { recursive: true });
4581
+ (0, import_node_fs12.writeFileSync)(file, contents);
4510
4582
  }
4511
4583
  }
4512
4584
  function removeAdded(path, undo) {
4513
4585
  let stats;
4514
4586
  try {
4515
- stats = (0, import_node_fs11.statSync)(path);
4587
+ stats = (0, import_node_fs12.statSync)(path);
4516
4588
  } catch {
4517
4589
  return;
4518
4590
  }
4519
4591
  if (stats.isFile()) {
4520
4592
  if (!undo.files.has(path)) {
4521
- (0, import_node_fs11.unlinkSync)(path);
4593
+ (0, import_node_fs12.unlinkSync)(path);
4522
4594
  }
4523
4595
  return;
4524
4596
  }
4525
4597
  if (!stats.isDirectory()) {
4526
4598
  return;
4527
4599
  }
4528
- for (const entry of (0, import_node_fs11.readdirSync)(path)) {
4600
+ for (const entry of (0, import_node_fs12.readdirSync)(path)) {
4529
4601
  removeAdded((0, import_node_path12.join)(path, entry), undo);
4530
4602
  }
4531
- if (!undo.dirs.has(path) && (0, import_node_fs11.readdirSync)(path).length === 0) {
4532
- (0, import_node_fs11.rmdirSync)(path);
4603
+ if (!undo.dirs.has(path) && (0, import_node_fs12.readdirSync)(path).length === 0) {
4604
+ (0, import_node_fs12.rmdirSync)(path);
4533
4605
  }
4534
4606
  }
4535
4607
  function pruneAncestors(path, undo) {
@@ -4538,7 +4610,7 @@ function pruneAncestors(path, undo) {
4538
4610
  return;
4539
4611
  }
4540
4612
  try {
4541
- (0, import_node_fs11.rmdirSync)(dir);
4613
+ (0, import_node_fs12.rmdirSync)(dir);
4542
4614
  } catch {
4543
4615
  return;
4544
4616
  }
@@ -4700,7 +4772,7 @@ var NOT_ENVIRONMENTS2 = [...import_core25.RESERVED_TOKENS, "example", "sample",
4700
4772
  function suggestEnvironments(root) {
4701
4773
  let entries;
4702
4774
  try {
4703
- entries = (0, import_node_fs12.readdirSync)(root);
4775
+ entries = (0, import_node_fs13.readdirSync)(root);
4704
4776
  } catch {
4705
4777
  return [];
4706
4778
  }
@@ -4745,7 +4817,7 @@ function configOf(decisions) {
4745
4817
  }
4746
4818
  function declaredIn(root) {
4747
4819
  const file = (0, import_node_path13.join)(root, CONFIG_FILE);
4748
- if (!(0, import_node_fs12.existsSync)(file)) {
4820
+ if (!(0, import_node_fs13.existsSync)(file)) {
4749
4821
  return void 0;
4750
4822
  }
4751
4823
  return (0, import_core25.loadConfigFrom)(file);
@@ -5188,15 +5260,15 @@ function renderTsconfig(target, alias) {
5188
5260
  }
5189
5261
  function ensurePenvDir(root) {
5190
5262
  const dir = (0, import_node_path13.resolve)(root, import_core25.PENV_DIR);
5191
- if ((0, import_node_fs12.existsSync)(dir)) {
5263
+ if ((0, import_node_fs13.existsSync)(dir)) {
5192
5264
  return { target: "penv-dir", action: "kept", text: `Found ${import_core25.PENV_DIR}/` };
5193
5265
  }
5194
- (0, import_node_fs12.mkdirSync)(dir, { recursive: true });
5266
+ (0, import_node_fs13.mkdirSync)(dir, { recursive: true });
5195
5267
  return { target: "penv-dir", action: "created", text: `Created ${import_core25.PENV_DIR}/` };
5196
5268
  }
5197
5269
  function writeSchemaShapeFile(root, fields, draft, decisions = DEFAULT_DECISIONS) {
5198
5270
  const file = (0, import_node_path13.join)(root, import_core25.SCHEMA_SHAPE_FILE);
5199
- if ((0, import_node_fs12.existsSync)(file)) {
5271
+ if ((0, import_node_fs13.existsSync)(file)) {
5200
5272
  return {
5201
5273
  target: "schema",
5202
5274
  action: "kept",
@@ -5213,7 +5285,7 @@ function writeSchemaShapeFile(root, fields, draft, decisions = DEFAULT_DECISIONS
5213
5285
  note: `(the shape lives there, from before the ${import_core25.SCHEMA_SHAPE_FILE} split \u2014 penv did not add a second one. To adopt the split: move the \`z.object\` (and any \`declare module\` block) into ${import_core25.SCHEMA_SHAPE_FILE}, leaving ${oldLayout} importing \`schema\` from it and calling \`load\`.)`
5214
5286
  };
5215
5287
  }
5216
- (0, import_node_fs12.writeFileSync)(file, renderSchemaShapeModule(fields, draft), "utf8");
5288
+ (0, import_node_fs13.writeFileSync)(file, renderSchemaShapeModule(fields, draft), "utf8");
5217
5289
  return {
5218
5290
  target: "schema",
5219
5291
  action: "created",
@@ -5223,7 +5295,7 @@ function writeSchemaShapeFile(root, fields, draft, decisions = DEFAULT_DECISIONS
5223
5295
  }
5224
5296
  function writeEnvFile(root, decisions = DEFAULT_DECISIONS) {
5225
5297
  const file = (0, import_node_path13.join)(root, ...decisions.schemaFile.split("/"));
5226
- if ((0, import_node_fs12.existsSync)(file)) {
5298
+ if ((0, import_node_fs13.existsSync)(file)) {
5227
5299
  return {
5228
5300
  target: "env",
5229
5301
  action: "kept",
@@ -5231,8 +5303,8 @@ function writeEnvFile(root, decisions = DEFAULT_DECISIONS) {
5231
5303
  note: "(yours \u2014 penv never regenerates it)"
5232
5304
  };
5233
5305
  }
5234
- (0, import_node_fs12.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
5235
- (0, import_node_fs12.writeFileSync)(file, renderEnvModule(decisions.schemaFile, decisions.inject), "utf8");
5306
+ (0, import_node_fs13.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
5307
+ (0, import_node_fs13.writeFileSync)(file, renderEnvModule(decisions.schemaFile, decisions.inject), "utf8");
5236
5308
  return {
5237
5309
  target: "env",
5238
5310
  action: "created",
@@ -5242,10 +5314,10 @@ function writeEnvFile(root, decisions = DEFAULT_DECISIONS) {
5242
5314
  }
5243
5315
  function writeConfigFile(root, decisions = DEFAULT_DECISIONS) {
5244
5316
  const file = (0, import_node_path13.join)(root, CONFIG_FILE);
5245
- if ((0, import_node_fs12.existsSync)(file)) {
5317
+ if ((0, import_node_fs13.existsSync)(file)) {
5246
5318
  return { target: "config", action: "kept", text: `Kept ${CONFIG_FILE}` };
5247
5319
  }
5248
- (0, import_node_fs12.writeFileSync)(file, renderConfigModule(decisions), "utf8");
5320
+ (0, import_node_fs13.writeFileSync)(file, renderConfigModule(decisions), "utf8");
5249
5321
  return { target: "config", action: "created", text: `Generated ${CONFIG_FILE}` };
5250
5322
  }
5251
5323
  function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
@@ -5253,7 +5325,7 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
5253
5325
  const imports = alias.startsWith(IMPORTS_PREFIX);
5254
5326
  const file = (0, import_node_path13.join)(root, imports ? PACKAGE_FILE : TSCONFIG_FILE);
5255
5327
  const where = imports ? PACKAGE_FILE : TSCONFIG_FILE;
5256
- if (!(0, import_node_fs12.existsSync)(file)) {
5328
+ if (!(0, import_node_fs13.existsSync)(file)) {
5257
5329
  if (imports) {
5258
5330
  return {
5259
5331
  target: "tsconfig",
@@ -5262,14 +5334,14 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
5262
5334
  note: `(run \`npm init\` first, or use \`--alias @env\` to alias through ${TSCONFIG_FILE})`
5263
5335
  };
5264
5336
  }
5265
- (0, import_node_fs12.writeFileSync)(file, renderTsconfig(decisions.schemaFile, alias), "utf8");
5337
+ (0, import_node_fs13.writeFileSync)(file, renderTsconfig(decisions.schemaFile, alias), "utf8");
5266
5338
  return {
5267
5339
  target: "tsconfig",
5268
5340
  action: "created",
5269
5341
  text: `Created ${TSCONFIG_FILE} with the ${alias} path alias`
5270
5342
  };
5271
5343
  }
5272
- const source = (0, import_node_fs12.readFileSync)(file, "utf8");
5344
+ const source = (0, import_node_fs13.readFileSync)(file, "utf8");
5273
5345
  const edit = imports ? insertImportsAlias(source, decisions.schemaFile, alias) : insertEnvAlias(source, decisions.schemaFile, alias);
5274
5346
  if (edit.conflict !== void 0) {
5275
5347
  return {
@@ -5286,7 +5358,7 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
5286
5358
  text: `Kept the ${alias} alias in ${where}`
5287
5359
  };
5288
5360
  }
5289
- (0, import_node_fs12.writeFileSync)(file, edit.source, "utf8");
5361
+ (0, import_node_fs13.writeFileSync)(file, edit.source, "utf8");
5290
5362
  return {
5291
5363
  target: "tsconfig",
5292
5364
  action: "updated",
@@ -5296,12 +5368,12 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
5296
5368
  function writeGitignore(root, decisions = DEFAULT_DECISIONS) {
5297
5369
  const file = (0, import_node_path13.join)(root, ...import_core25.STATE_GITIGNORE_PATH.split("/"));
5298
5370
  const wanted = (0, import_core25.renderStateGitignore)(configOf(decisions));
5299
- const existing = (0, import_node_fs12.existsSync)(file) ? (0, import_node_fs12.readFileSync)(file, "utf8") : void 0;
5371
+ const existing = (0, import_node_fs13.existsSync)(file) ? (0, import_node_fs13.readFileSync)(file, "utf8") : void 0;
5300
5372
  if (existing === wanted) {
5301
5373
  return { target: "gitignore", action: "kept", text: `Kept ${import_core25.STATE_GITIGNORE_PATH}` };
5302
5374
  }
5303
- (0, import_node_fs12.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
5304
- (0, import_node_fs12.writeFileSync)(file, wanted, "utf8");
5375
+ (0, import_node_fs13.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
5376
+ (0, import_node_fs13.writeFileSync)(file, wanted, "utf8");
5305
5377
  return {
5306
5378
  target: "gitignore",
5307
5379
  action: existing === void 0 ? "created" : "updated",
@@ -5318,11 +5390,11 @@ function outdatedRuntimeWarning(root) {
5318
5390
  }
5319
5391
  function installedPenvVersion(root) {
5320
5392
  const file = (0, import_node_path13.join)(root, "node_modules", "@penvhq", "penv", "package.json");
5321
- if (!(0, import_node_fs12.existsSync)(file)) {
5393
+ if (!(0, import_node_fs13.existsSync)(file)) {
5322
5394
  return void 0;
5323
5395
  }
5324
5396
  try {
5325
- const version = JSON.parse((0, import_node_fs12.readFileSync)(file, "utf8")).version;
5397
+ const version = JSON.parse((0, import_node_fs13.readFileSync)(file, "utf8")).version;
5326
5398
  return typeof version === "string" ? version : void 0;
5327
5399
  } catch {
5328
5400
  return void 0;
@@ -5366,7 +5438,7 @@ function writeSeam(root, decisions = DEFAULT_DECISIONS, framework = detectFramew
5366
5438
  const baseNotes = [...seam.notes, ...alsoNote === void 0 ? [] : [alsoNote]];
5367
5439
  const notes = baseNotes.length === 0 ? "" : `
5368
5440
  ${baseNotes.map((n) => ` ${n}`).join("\n")}`;
5369
- if ((0, import_node_fs12.existsSync)(file)) {
5441
+ if ((0, import_node_fs13.existsSync)(file)) {
5370
5442
  return {
5371
5443
  target: "seam",
5372
5444
  action: "info",
@@ -5374,8 +5446,8 @@ ${baseNotes.map((n) => ` ${n}`).join("\n")}`;
5374
5446
  note: withWarning(`${seam.ifPresent}${notes}`, outdated)
5375
5447
  };
5376
5448
  }
5377
- (0, import_node_fs12.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
5378
- (0, import_node_fs12.writeFileSync)(file, seam.content, "utf8");
5449
+ (0, import_node_fs13.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
5450
+ (0, import_node_fs13.writeFileSync)(file, seam.content, "utf8");
5379
5451
  return {
5380
5452
  target: "seam",
5381
5453
  action: outdated === void 0 ? "created" : "info",
@@ -5388,11 +5460,11 @@ function writeAlso(root, also) {
5388
5460
  return void 0;
5389
5461
  }
5390
5462
  const file = (0, import_node_path13.join)(root, ...also.file.split("/"));
5391
- if ((0, import_node_fs12.existsSync)(file)) {
5463
+ if ((0, import_node_fs13.existsSync)(file)) {
5392
5464
  return also.ifPresent;
5393
5465
  }
5394
- (0, import_node_fs12.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
5395
- (0, import_node_fs12.writeFileSync)(file, also.content, "utf8");
5466
+ (0, import_node_fs13.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
5467
+ (0, import_node_fs13.writeFileSync)(file, also.content, "utf8");
5396
5468
  return `Wrote ${also.file} to register it.`;
5397
5469
  }
5398
5470
  function withWarning(note, warning) {
@@ -5496,7 +5568,7 @@ function planCutover(input) {
5496
5568
  const diagnostics = [];
5497
5569
  let variables = 0;
5498
5570
  for (const file of selected) {
5499
- const parsed = (0, import_core25.parseDotenv)((0, import_node_fs12.readFileSync)((0, import_node_path13.join)(root, file.name), "utf8"));
5571
+ const parsed = (0, import_core25.parseDotenv)((0, import_node_fs13.readFileSync)((0, import_node_path13.join)(root, file.name), "utf8"));
5500
5572
  const fileRefs = refsForEntries(parsed.entries, file.name, config);
5501
5573
  adopted.push({ file, entries: parsed.entries, refs: fileRefs, scope: scopeOf(file) });
5502
5574
  refs.push(...fileRefs);
@@ -5741,11 +5813,11 @@ function dailyCommand(root) {
5741
5813
  }
5742
5814
  function devScript(root) {
5743
5815
  const file = (0, import_node_path13.join)(root, PACKAGE_FILE);
5744
- if (!(0, import_node_fs12.existsSync)(file)) {
5816
+ if (!(0, import_node_fs13.existsSync)(file)) {
5745
5817
  return "dev";
5746
5818
  }
5747
5819
  try {
5748
- const scripts = JSON.parse((0, import_node_fs12.readFileSync)(file, "utf8")).scripts;
5820
+ const scripts = JSON.parse((0, import_node_fs13.readFileSync)(file, "utf8")).scripts;
5749
5821
  if (scripts !== null && typeof scripts === "object" && !Array.isArray(scripts)) {
5750
5822
  const named = Object.keys(scripts);
5751
5823
  return ["dev", "start"].find((script) => named.includes(script)) ?? named[0] ?? "dev";
@@ -6114,14 +6186,14 @@ function configInEffect(cwd, environment) {
6114
6186
  function importDotenv(options) {
6115
6187
  const cwd = (0, import_node_path14.resolve)(options.cwd);
6116
6188
  const file = (0, import_node_path14.isAbsolute)(options.file) ? options.file : (0, import_node_path14.resolve)(cwd, options.file);
6117
- if (!(0, import_node_fs13.existsSync)(file)) {
6189
+ if (!(0, import_node_fs14.existsSync)(file)) {
6118
6190
  throw new import_core26.PenvError(
6119
6191
  "IMPORT_FILE_MISSING",
6120
6192
  `There is no file at ${file} to import`,
6121
6193
  "Point `penv import` at an existing dotenv file, e.g. `penv import .env`."
6122
6194
  );
6123
6195
  }
6124
- const parsed = (0, import_core26.parseDotenv)((0, import_node_fs13.readFileSync)(file, "utf8"));
6196
+ const parsed = (0, import_core26.parseDotenv)((0, import_node_fs14.readFileSync)(file, "utf8"));
6125
6197
  const { config, decisions } = configInEffect(cwd, environmentNamed(file, options.environment));
6126
6198
  const source = displayPath3(cwd, file);
6127
6199
  const named = scopeFromFilename(file, config);
@@ -6137,7 +6209,7 @@ function importDotenv(options) {
6137
6209
  const tree = localTree(project);
6138
6210
  writeEntries(tree, parsed.entries, refs, scope);
6139
6211
  const backup = `${file}${BACKUP_SUFFIX}`;
6140
- (0, import_node_fs13.copyFileSync)(file, backup);
6212
+ (0, import_node_fs14.copyFileSync)(file, backup);
6141
6213
  return {
6142
6214
  root: project.root,
6143
6215
  file,
@@ -6472,7 +6544,7 @@ var listCommand = (0, import_citty16.defineCommand)({
6472
6544
  });
6473
6545
 
6474
6546
  // src/commands/migrate.ts
6475
- var import_node_fs14 = require("fs");
6547
+ var import_node_fs15 = require("fs");
6476
6548
  var import_node_path15 = require("path");
6477
6549
  var import_promises2 = require("readline/promises");
6478
6550
  var import_core30 = require("@penvhq/core");
@@ -6492,7 +6564,7 @@ function planMigrate(cwd) {
6492
6564
  );
6493
6565
  }
6494
6566
  const creates = [];
6495
- if (entries.length > 0 && !(0, import_node_fs14.existsSync)(tree)) {
6567
+ if (entries.length > 0 && !(0, import_node_fs15.existsSync)(tree)) {
6496
6568
  creates.push(`${import_core30.RECORDS_PATH}/`);
6497
6569
  }
6498
6570
  if (readIfPresent((0, import_node_path15.join)(root, ...import_core30.STATE_GITIGNORE_PATH.split("/"))) !== (0, import_core30.renderStateGitignore)(config)) {
@@ -6505,16 +6577,16 @@ function planMigrate(cwd) {
6505
6577
  to: `${import_core30.RECORDS_PATH}/${entry}`
6506
6578
  })),
6507
6579
  creates,
6508
- removes: (0, import_node_fs14.existsSync)((0, import_node_path15.join)(root, ...OLD_GITIGNORE.split("/"))) ? [OLD_GITIGNORE] : []
6580
+ removes: (0, import_node_fs15.existsSync)((0, import_node_path15.join)(root, ...OLD_GITIGNORE.split("/"))) ? [OLD_GITIGNORE] : []
6509
6581
  };
6510
6582
  }
6511
6583
  function readIfPresent(file) {
6512
- return (0, import_node_fs14.existsSync)(file) ? (0, import_node_fs14.readFileSync)(file, "utf8") : void 0;
6584
+ return (0, import_node_fs15.existsSync)(file) ? (0, import_node_fs15.readFileSync)(file, "utf8") : void 0;
6513
6585
  }
6514
6586
  function collidingEntries(entries, tree) {
6515
6587
  let held;
6516
6588
  try {
6517
- held = (0, import_node_fs14.readdirSync)(tree);
6589
+ held = (0, import_node_fs15.readdirSync)(tree);
6518
6590
  } catch {
6519
6591
  return [];
6520
6592
  }
@@ -6533,18 +6605,18 @@ function applyMigrate(plan2) {
6533
6605
  }
6534
6606
  const { config } = (0, import_core30.loadConfig)(plan2.root);
6535
6607
  if (plan2.moves.length > 0) {
6536
- (0, import_node_fs14.mkdirSync)((0, import_core30.recordsDir)(plan2.root), { recursive: true });
6608
+ (0, import_node_fs15.mkdirSync)((0, import_core30.recordsDir)(plan2.root), { recursive: true });
6537
6609
  for (const move of plan2.moves) {
6538
- (0, import_node_fs14.renameSync)((0, import_node_path15.join)(plan2.root, ...move.from.split("/")), (0, import_node_path15.join)(plan2.root, ...move.to.split("/")));
6610
+ (0, import_node_fs15.renameSync)((0, import_node_path15.join)(plan2.root, ...move.from.split("/")), (0, import_node_path15.join)(plan2.root, ...move.to.split("/")));
6539
6611
  }
6540
6612
  }
6541
6613
  if (plan2.creates.includes(import_core30.STATE_GITIGNORE_PATH)) {
6542
6614
  const ignore = (0, import_node_path15.join)(plan2.root, ...import_core30.STATE_GITIGNORE_PATH.split("/"));
6543
- (0, import_node_fs14.mkdirSync)((0, import_node_path15.dirname)(ignore), { recursive: true });
6544
- (0, import_node_fs14.writeFileSync)(ignore, (0, import_core30.renderStateGitignore)(config), "utf8");
6615
+ (0, import_node_fs15.mkdirSync)((0, import_node_path15.dirname)(ignore), { recursive: true });
6616
+ (0, import_node_fs15.writeFileSync)(ignore, (0, import_core30.renderStateGitignore)(config), "utf8");
6545
6617
  }
6546
6618
  for (const removed of plan2.removes) {
6547
- (0, import_node_fs14.rmSync)((0, import_node_path15.join)(plan2.root, ...removed.split("/")), { force: true });
6619
+ (0, import_node_fs15.rmSync)((0, import_node_path15.join)(plan2.root, ...removed.split("/")), { force: true });
6548
6620
  }
6549
6621
  return { ...plan2, status: "migrated" };
6550
6622
  }
@@ -7030,7 +7102,7 @@ var rotateCommand = (0, import_citty20.defineCommand)({
7030
7102
  });
7031
7103
 
7032
7104
  // src/commands/watch.ts
7033
- var import_node_fs15 = require("fs");
7105
+ var import_node_fs16 = require("fs");
7034
7106
  var import_node_path16 = require("path");
7035
7107
  var import_core34 = require("@penvhq/core");
7036
7108
  var import_citty21 = require("citty");
@@ -7094,18 +7166,18 @@ function runWatch(options) {
7094
7166
  const name = (0, import_node_path16.basename)(target);
7095
7167
  let recovery;
7096
7168
  try {
7097
- recovery = (0, import_node_fs15.watch)(parent, { recursive: false }, (_event, filename) => {
7169
+ recovery = (0, import_node_fs16.watch)(parent, { recursive: false }, (_event, filename) => {
7098
7170
  if (closed || recovery === void 0) {
7099
7171
  return;
7100
7172
  }
7101
- if (!(0, import_node_fs15.existsSync)(parent)) {
7173
+ if (!(0, import_node_fs16.existsSync)(parent)) {
7102
7174
  stop2(recovery);
7103
7175
  return;
7104
7176
  }
7105
7177
  if (filename !== null && (0, import_node_path16.basename)(filename) !== name) {
7106
7178
  return;
7107
7179
  }
7108
- if (!(0, import_node_fs15.existsSync)(target)) {
7180
+ if (!(0, import_node_fs16.existsSync)(target)) {
7109
7181
  return;
7110
7182
  }
7111
7183
  stop2(recovery);
@@ -7125,11 +7197,11 @@ function runWatch(options) {
7125
7197
  }
7126
7198
  function addWatcher(target, recursive, only) {
7127
7199
  let watcher;
7128
- const listen = (useRecursive) => (0, import_node_fs15.watch)(target, { recursive: useRecursive }, (_event, filename) => {
7200
+ const listen = (useRecursive) => (0, import_node_fs16.watch)(target, { recursive: useRecursive }, (_event, filename) => {
7129
7201
  if (closed) {
7130
7202
  return;
7131
7203
  }
7132
- if (!(0, import_node_fs15.existsSync)(target)) {
7204
+ if (!(0, import_node_fs16.existsSync)(target)) {
7133
7205
  if (watcher !== void 0) {
7134
7206
  stop2(watcher);
7135
7207
  }