ultraenv 1.0.0 → 1.0.2

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.
Files changed (71) hide show
  1. package/README.md +67 -1857
  2. package/dist/{chunk-GC7RXHLA.js → chunk-2MBSLURI.js} +16 -17
  3. package/dist/{chunk-IGFVP24Q.js → chunk-3AF476D7.js} +1 -1
  4. package/dist/{chunk-N5PAV4NM.js → chunk-5WUBB633.js} +17 -26
  5. package/dist/{chunk-2USZPWLZ.js → chunk-6NFA23AY.js} +28 -39
  6. package/dist/{chunk-AWN6ADV7.js → chunk-6X3BUE5S.js} +45 -54
  7. package/dist/{chunk-NBOABPHM.js → chunk-72UKVOO5.js} +24 -40
  8. package/dist/{chunk-JB7RKV3C.js → chunk-7AHG2IP4.js} +1 -7
  9. package/dist/{chunk-6KS56D6E.js → chunk-7VJ7LK2M.js} +1 -1
  10. package/dist/{chunk-CIFMBJ4H.js → chunk-BNUHE2ZI.js} +57 -21
  11. package/dist/{chunk-HFXQGJY3.js → chunk-CVJPO3QY.js} +13 -27
  12. package/dist/{chunk-IKPTKALB.js → chunk-F7YSINGU.js} +1 -3
  13. package/dist/{chunk-3VYXPTYV.js → chunk-FSKVYBEP.js} +1 -1
  14. package/dist/{chunk-4XUYMRK5.js → chunk-GJC64ZG7.js} +4 -3
  15. package/dist/{chunk-YMMP4VQL.js → chunk-H3QEGEZ6.js} +1 -1
  16. package/dist/{chunk-CHVO6NWI.js → chunk-LFIKYFPS.js} +2 -2
  17. package/dist/{chunk-3UV2QNJL.js → chunk-LJSCUOD4.js} +19 -21
  18. package/dist/{chunk-YVWLXFUT.js → chunk-LQZK6BBQ.js} +2 -2
  19. package/dist/{chunk-5G2DU52U.js → chunk-N7GOHQBF.js} +7 -1
  20. package/dist/{chunk-MSXMESFP.js → chunk-OBLMAUCF.js} +8 -14
  21. package/dist/{chunk-UEWYFN6A.js → chunk-RJTUAMK3.js} +16 -29
  22. package/dist/{chunk-MNVFG7H4.js → chunk-XPZC32UY.js} +16 -25
  23. package/dist/{chunk-WMHN5RW2.js → chunk-YLGJQOMM.js} +3 -9
  24. package/dist/{ci-check-sync-VBMSVWIV.js → ci-check-sync-UO5PARKO.js} +4 -4
  25. package/dist/{ci-scan-24MT5XGS.js → ci-scan-5D7QBN5X.js} +2 -5
  26. package/dist/{ci-setup-C2NKEFRD.js → ci-setup-J34DS6KD.js} +2 -2
  27. package/dist/{ci-validate-7AW24LSQ.js → ci-validate-LWP5NBDN.js} +4 -4
  28. package/dist/cli/index.cjs +470 -390
  29. package/dist/cli/index.js +130 -55
  30. package/dist/comparator-AIRTWBOL.js +13 -0
  31. package/dist/{config-O5YRQP5Z.js → config-67GDO3CW.js} +3 -3
  32. package/dist/{debug-PTPXAF3K.js → debug-6VCX3QSP.js} +6 -6
  33. package/dist/{declaration-LEME4AFZ.js → declaration-YGOVZOXG.js} +3 -3
  34. package/dist/{doctor-FZAUPKHS.js → doctor-FF7QOTP2.js} +7 -5
  35. package/dist/{envs-compare-5K3HESX5.js → envs-compare-P7GPKGQX.js} +4 -4
  36. package/dist/{envs-create-2XXHXMGA.js → envs-create-ISG4SECU.js} +4 -4
  37. package/dist/{envs-list-NQM5252B.js → envs-list-PUW67HOC.js} +5 -5
  38. package/dist/{envs-switch-6L2AQYID.js → envs-switch-P4YDJ6LG.js} +4 -4
  39. package/dist/{envs-validate-FL73Q76T.js → envs-validate-VNKBKYO3.js} +6 -9
  40. package/dist/{fs-VH7ATUS3.js → fs-7HKOZY5K.js} +2 -2
  41. package/dist/{generator-LFZBMZZS.js → generator-O23ATCIY.js} +4 -4
  42. package/dist/{help-3XJBXEHE.js → help-THFLI6YT.js} +108 -26
  43. package/dist/index.cjs +295 -381
  44. package/dist/index.d.cts +1 -1
  45. package/dist/index.d.ts +1 -1
  46. package/dist/index.js +81 -100
  47. package/dist/{init-Y7JQ2KYJ.js → init-KBLVTHQW.js} +15 -11
  48. package/dist/{install-hook-SKXIV6NV.js → install-hook-42F22BLY.js} +2 -2
  49. package/dist/{json-schema-I26YNQBH.js → json-schema-YULPWDKA.js} +3 -3
  50. package/dist/{key-manager-O3G55WPU.js → key-manager-WDWPX3IQ.js} +3 -3
  51. package/dist/middleware/express.cjs +1 -3
  52. package/dist/middleware/express.js +1 -1
  53. package/dist/middleware/fastify.cjs +1 -7
  54. package/dist/middleware/fastify.js +1 -1
  55. package/dist/{module-IDIZPP4M.js → module-FGH2V6N2.js} +3 -3
  56. package/dist/{protect-NCWPM6VC.js → protect-A4G7LQFJ.js} +26 -24
  57. package/dist/{scan-TRLY36TT.js → scan-4BXGHR33.js} +1 -1
  58. package/dist/schema/index.cjs +57 -21
  59. package/dist/schema/index.js +1 -1
  60. package/dist/{sync-TMHMTLH2.js → sync-MYLMDDY6.js} +23 -14
  61. package/dist/{typegen-SQOSXBWM.js → typegen-GLBRHWSK.js} +17 -23
  62. package/dist/{validate-IOAM5HWS.js → validate-J73ETKXD.js} +5 -5
  63. package/dist/{vault-decrypt-U6HJZNBV.js → vault-decrypt-V3GY5HES.js} +7 -7
  64. package/dist/{vault-diff-B3ZOQTWI.js → vault-diff-QVE6S6KP.js} +5 -5
  65. package/dist/{vault-encrypt-GUSLCSKS.js → vault-encrypt-WUBY3OVF.js} +7 -7
  66. package/dist/{vault-init-GUBOTOUL.js → vault-init-EWSAED44.js} +5 -5
  67. package/dist/{vault-rekey-DAHT7JCN.js → vault-rekey-VODMGCNA.js} +7 -7
  68. package/dist/{vault-status-GDLRU2OK.js → vault-status-YXDK6O7X.js} +4 -4
  69. package/dist/{vault-verify-CD76FJSF.js → vault-verify-SSXGTVBK.js} +7 -7
  70. package/package.json +1 -1
  71. package/dist/comparator-RDKX3OI7.js +0 -13
@@ -306,7 +306,13 @@ var init_errors = __esm({
306
306
  code;
307
307
  constructor(message, options = {}) {
308
308
  const fsCode = options.code ?? options.cause?.code ?? "UNKNOWN";
309
- const opHint = options.path !== void 0 ? `Could not ${options.operation ?? "access"} "${options.path}".` : "";
309
+ const opHint = options.path !== void 0 ? (
310
+ /* v8 ignore start */
311
+ `Could not ${options.operation ?? "access"} "${options.path}".`
312
+ ) : (
313
+ /* v8 ignore stop */
314
+ ""
315
+ );
310
316
  super(message, {
311
317
  code: `FS_${fsCode}`,
312
318
  hint: options.hint ?? `${opHint} Ensure the file exists and you have the necessary permissions.`,
@@ -773,7 +779,8 @@ function parseYamlScalar(value) {
773
779
  if (cleanValue === "") return "";
774
780
  if (cleanValue === "true" || cleanValue === "True" || cleanValue === "TRUE") return true;
775
781
  if (cleanValue === "false" || cleanValue === "False" || cleanValue === "FALSE") return false;
776
- if (cleanValue === "null" || cleanValue === "Null" || cleanValue === "NULL" || cleanValue === "~") return null;
782
+ if (cleanValue === "null" || cleanValue === "Null" || cleanValue === "NULL" || cleanValue === "~")
783
+ return null;
777
784
  if (/^-?\d+$/.test(cleanValue)) return parseInt(cleanValue, 10);
778
785
  if (/^-?\d+\.\d+$/.test(cleanValue)) return parseFloat(cleanValue);
779
786
  if (cleanValue.startsWith('"') && cleanValue.endsWith('"') || cleanValue.startsWith("'") && cleanValue.endsWith("'")) {
@@ -958,14 +965,18 @@ async function run(args, ctx) {
958
965
  const envDir = await prompt(" Environment directory", { default: "." });
959
966
  writeLine("");
960
967
  writeLine(cyan(" Creating configuration..."));
961
- const configContent = JSON.stringify({
962
- envDir,
963
- expandVariables: true,
964
- overrideProcessEnv: false,
965
- mergeStrategy: "last-wins",
966
- outputFormat: "terminal",
967
- debug: false
968
- }, null, 2) + "\n";
968
+ const configContent = JSON.stringify(
969
+ {
970
+ envDir,
971
+ expandVariables: true,
972
+ overrideProcessEnv: false,
973
+ mergeStrategy: "last-wins",
974
+ outputFormat: "terminal",
975
+ debug: false
976
+ },
977
+ null,
978
+ 2
979
+ ) + "\n";
969
980
  await writeFile(configPath, configContent);
970
981
  writeLine(green(` \u2713 Created ${configPath}`));
971
982
  if (!await exists(envPath)) {
@@ -1104,14 +1115,11 @@ function resolveEscapeSequence(chars, startIndex, filePath, lineNumber) {
1104
1115
  }
1105
1116
  return { resolved: String.fromCodePoint(codePoint), charsConsumed: 4 };
1106
1117
  }
1107
- throw new ParseError(
1108
- `Invalid hex escape sequence: ${"\\"}x${hex}`,
1109
- {
1110
- line: lineNumber,
1111
- filePath,
1112
- hint: "Hex escapes must be exactly 2 hex digits, e.g. \\x0A for newline."
1113
- }
1114
- );
1118
+ throw new ParseError(`Invalid hex escape sequence: ${"\\"}x${hex}`, {
1119
+ line: lineNumber,
1120
+ filePath,
1121
+ hint: "Hex escapes must be exactly 2 hex digits, e.g. \\x0A for newline."
1122
+ });
1115
1123
  }
1116
1124
  case "u":
1117
1125
  case "U": {
@@ -1126,14 +1134,11 @@ function resolveEscapeSequence(chars, startIndex, filePath, lineNumber) {
1126
1134
  }
1127
1135
  return { resolved: String.fromCodePoint(codePoint), charsConsumed: 6 };
1128
1136
  }
1129
- throw new ParseError(
1130
- `Invalid unicode escape sequence: ${"\\"}u${hexDigits}`,
1131
- {
1132
- line: lineNumber,
1133
- filePath,
1134
- hint: 'Unicode escapes must be exactly 4 hex digits, e.g. \\u0041 for "A".'
1135
- }
1136
- );
1137
+ throw new ParseError(`Invalid unicode escape sequence: ${"\\"}u${hexDigits}`, {
1138
+ line: lineNumber,
1139
+ filePath,
1140
+ hint: 'Unicode escapes must be exactly 4 hex digits, e.g. \\u0041 for "A".'
1141
+ });
1137
1142
  }
1138
1143
  /* v8 ignore start */
1139
1144
  default: {
@@ -1415,11 +1420,7 @@ function parseEnvFile(content, filePath) {
1415
1420
  comment = trimmedAfter.slice(1).trim();
1416
1421
  }
1417
1422
  } else if (firstChar === "'") {
1418
- const result = parseSingleQuotedValue(
1419
- lines,
1420
- lineIndex,
1421
- valueStartIndex + 1
1422
- );
1423
+ const result = parseSingleQuotedValue(lines, lineIndex, valueStartIndex + 1);
1423
1424
  if (!result.closed) {
1424
1425
  throw new ParseError("Unterminated single-quoted string", {
1425
1426
  line: oneBasedLine,
@@ -1440,11 +1441,7 @@ function parseEnvFile(content, filePath) {
1440
1441
  comment = trimmedAfter.slice(1).trim();
1441
1442
  }
1442
1443
  } else if (firstChar === "`") {
1443
- const result = parseBacktickQuotedValue(
1444
- lines,
1445
- lineIndex,
1446
- valueStartIndex + 1
1447
- );
1444
+ const result = parseBacktickQuotedValue(lines, lineIndex, valueStartIndex + 1);
1448
1445
  if (!result.closed) {
1449
1446
  throw new ParseError("Unterminated backtick-quoted string", {
1450
1447
  line: oneBasedLine,
@@ -1676,12 +1673,9 @@ function expandVariables(vars, env, options) {
1676
1673
  const resolving = /* @__PURE__ */ new Set();
1677
1674
  function expandValue(raw, depth) {
1678
1675
  if (depth > maxDepth) {
1679
- throw new InterpolationError(
1680
- `Maximum interpolation depth (${maxDepth}) exceeded`,
1681
- {
1682
- hint: "Check for deeply nested variable references. Consider simplifying your variable definitions."
1683
- }
1684
- );
1676
+ throw new InterpolationError(`Maximum interpolation depth (${maxDepth}) exceeded`, {
1677
+ hint: "Check for deeply nested variable references. Consider simplifying your variable definitions."
1678
+ });
1685
1679
  }
1686
1680
  const result2 = [];
1687
1681
  let i = 0;
@@ -1717,14 +1711,11 @@ function expandVariables(vars, env, options) {
1717
1711
  const parsed = parseExpression(inner);
1718
1712
  if (resolving.has(parsed.varName)) {
1719
1713
  const chain = Array.from(resolving).concat(parsed.varName).join(" \u2192 ");
1720
- throw new InterpolationError(
1721
- `Circular variable reference detected: ${chain}`,
1722
- {
1723
- variable: parsed.varName,
1724
- circular: true,
1725
- hint: "Break the cycle by removing one of the circular references."
1726
- }
1727
- );
1714
+ throw new InterpolationError(`Circular variable reference detected: ${chain}`, {
1715
+ variable: parsed.varName,
1716
+ circular: true,
1717
+ hint: "Break the cycle by removing one of the circular references."
1718
+ });
1728
1719
  }
1729
1720
  resolving.add(parsed.varName);
1730
1721
  if (parsed.varName in vars && !(parsed.varName in resolvedMap)) {
@@ -1755,14 +1746,11 @@ function expandVariables(vars, env, options) {
1755
1746
  const varName = raw.slice(i, nameEnd);
1756
1747
  if (resolving.has(varName)) {
1757
1748
  const chain = Array.from(resolving).concat(varName).join(" \u2192 ");
1758
- throw new InterpolationError(
1759
- `Circular variable reference detected: ${chain}`,
1760
- {
1761
- variable: varName,
1762
- circular: true,
1763
- hint: "Break the cycle by removing one of the circular references."
1764
- }
1765
- );
1749
+ throw new InterpolationError(`Circular variable reference detected: ${chain}`, {
1750
+ variable: varName,
1751
+ circular: true,
1752
+ hint: "Break the cycle by removing one of the circular references."
1753
+ });
1766
1754
  }
1767
1755
  resolving.add(varName);
1768
1756
  if (varName in vars && !(varName in resolvedMap)) {
@@ -2181,18 +2169,12 @@ function drawTable(headers, rows, options) {
2181
2169
  colWidths = naturalWidths.map((w) => Math.min(w, Math.max(avgWidth, 4)));
2182
2170
  }
2183
2171
  }
2184
- const wrappedHeaders = headers.map(
2185
- (h, i) => wrapText(h, colWidths[i] ?? 8)
2186
- );
2172
+ const wrappedHeaders = headers.map((h, i) => wrapText(h, colWidths[i] ?? 8));
2187
2173
  const wrappedRows = rows.map(
2188
- (row) => row.map(
2189
- (cell, i) => wrapText(cell, colWidths[i] ?? 8)
2190
- )
2174
+ (row) => row.map((cell, i) => wrapText(cell, colWidths[i] ?? 8))
2191
2175
  );
2192
2176
  const maxHeaderLines = Math.max(...wrappedHeaders.map((lines2) => lines2.length));
2193
- const maxRowLines = rows.length > 0 ? Math.max(...wrappedRows.map(
2194
- (row) => Math.max(...row.map((cell) => cell.length))
2195
- )) : 1;
2177
+ const maxRowLines = rows.length > 0 ? Math.max(...wrappedRows.map((row) => Math.max(...row.map((cell) => cell.length)))) : 1;
2196
2178
  const maxLines = Math.max(maxHeaderLines, maxRowLines);
2197
2179
  const lines = [];
2198
2180
  const separatorParts = colWidths.map((w) => "\u2500".repeat(w + opts.padding * 2));
@@ -2734,8 +2716,8 @@ async function run3(args, ctx) {
2734
2716
  const format = args.flags["--format"] ?? "declaration";
2735
2717
  const outFlag = args.flags["--out"];
2736
2718
  const defaultOutPaths = {
2737
- "declaration": "src/env.d.ts",
2738
- "module": "src/env.ts",
2719
+ declaration: "src/env.d.ts",
2720
+ module: "src/env.ts",
2739
2721
  "json-schema": "env.schema.json"
2740
2722
  };
2741
2723
  const outputPath = outFlag ? (0, import_node_path6.resolve)(cwd, outFlag) : (0, import_node_path6.resolve)(cwd, defaultOutPaths[format] ?? "src/env.d.ts");
@@ -2747,27 +2729,21 @@ async function run3(args, ctx) {
2747
2729
  let content = "";
2748
2730
  if (format === "declaration") {
2749
2731
  const { generateDeclarationContent: generateDeclarationContent2 } = await Promise.resolve().then(() => (init_declaration(), declaration_exports));
2750
- content = generateDeclarationContent2(
2751
- result.env,
2752
- schema,
2753
- { interfaceName, jsdoc: true, indent: 4 }
2754
- );
2732
+ content = generateDeclarationContent2(result.env, schema, {
2733
+ interfaceName,
2734
+ jsdoc: true,
2735
+ indent: 4
2736
+ });
2755
2737
  } else if (format === "module") {
2756
2738
  const { generateModuleContent: generateModuleContent2 } = await Promise.resolve().then(() => (init_module(), module_exports));
2757
2739
  if (!schema) {
2758
2740
  writeError(yellow(" Warning: No schema defined. Generating empty module."));
2759
2741
  writeError(yellow(" Add a schema to your .ultraenvrc.json for typed output."));
2760
2742
  }
2761
- content = generateModuleContent2(
2762
- schema ?? {},
2763
- { interfaceName, jsdoc: true, indent: 2 }
2764
- );
2743
+ content = generateModuleContent2(schema ?? {}, { interfaceName, jsdoc: true, indent: 2 });
2765
2744
  } else if (format === "json-schema") {
2766
2745
  const { generateJsonSchemaContent: generateJsonSchemaContent2 } = await Promise.resolve().then(() => (init_json_schema(), json_schema_exports));
2767
- content = generateJsonSchemaContent2(
2768
- schema ?? {},
2769
- { includeDescriptions: true, indent: 2 }
2770
- );
2746
+ content = generateJsonSchemaContent2(schema ?? {}, { includeDescriptions: true, indent: 2 });
2771
2747
  }
2772
2748
  const { writeFile: writeFile2, ensureDir: ensureDir2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
2773
2749
  await ensureDir2((0, import_node_path6.resolve)(outputPath, ".."));
@@ -3319,7 +3295,11 @@ async function checkSync(envPath, examplePath, ctx) {
3319
3295
  if (ctx.outputFormat === "json") {
3320
3296
  writeJson({ inSync: false, error: ".env file not found" });
3321
3297
  } else {
3322
- writeError(yellow(' \u26A0 .env file not found. Run "ultraenv sync --mode generate" to create .env.example.'));
3298
+ writeError(
3299
+ yellow(
3300
+ ' \u26A0 .env file not found. Run "ultraenv sync --mode generate" to create .env.example.'
3301
+ )
3302
+ );
3323
3303
  }
3324
3304
  return 1;
3325
3305
  }
@@ -3327,7 +3307,9 @@ async function checkSync(envPath, examplePath, ctx) {
3327
3307
  if (ctx.outputFormat === "json") {
3328
3308
  writeJson({ inSync: false, error: ".env.example not found" });
3329
3309
  } else {
3330
- writeError(yellow(' \u26A0 .env.example not found. Run "ultraenv sync --mode generate" to create it.'));
3310
+ writeError(
3311
+ yellow(' \u26A0 .env.example not found. Run "ultraenv sync --mode generate" to create it.')
3312
+ );
3331
3313
  }
3332
3314
  return 1;
3333
3315
  }
@@ -3348,11 +3330,14 @@ async function checkSync(envPath, examplePath, ctx) {
3348
3330
  writeLine(formatSyncDiff2(diff));
3349
3331
  writeLine("");
3350
3332
  if (!diff.inSync) {
3351
- const box = drawBox([
3352
- "Your .env is out of sync with .env.example.",
3353
- 'Run "ultraenv sync --mode generate" to update .env.example',
3354
- 'or "ultraenv sync --mode interactive" to review changes.'
3355
- ], { title: "ACTION NEEDED", border: "rounded" });
3333
+ const box = drawBox(
3334
+ [
3335
+ "Your .env is out of sync with .env.example.",
3336
+ 'Run "ultraenv sync --mode generate" to update .env.example',
3337
+ 'or "ultraenv sync --mode interactive" to review changes.'
3338
+ ],
3339
+ { title: "ACTION NEEDED", border: "rounded" }
3340
+ );
3356
3341
  writeLine(box);
3357
3342
  writeLine("");
3358
3343
  return 1;
@@ -3671,7 +3656,7 @@ var init_secret_patterns = __esm({
3671
3656
  {
3672
3657
  id: "google-oauth-client-secret",
3673
3658
  name: "Google OAuth Client Secret",
3674
- pattern: /(?:^|["'\s:=,`]GOCSPX-[A-Za-z0-9_-]{28,})(?:["'\s,`;]|$)/gm,
3659
+ pattern: /(?:^|["'\s:=,`])(GOCSPX-[A-Za-z0-9_-]{28,})(?:["'\s,`;]|$)/gm,
3675
3660
  confidence: 0.9,
3676
3661
  severity: "critical",
3677
3662
  description: "Google OAuth Client Secret (new format). Used for OAuth authentication flows.",
@@ -4435,9 +4420,7 @@ function extractCandidates(line) {
4435
4420
  const captured = tokenMatch[1];
4436
4421
  if (captured === void 0) continue;
4437
4422
  const tokenIndex = tokenMatch.index + 1;
4438
- const existing = candidates.some(
4439
- (c) => c.value === captured && c.column === tokenIndex
4440
- );
4423
+ const existing = candidates.some((c) => c.value === captured && c.column === tokenIndex);
4441
4424
  if (!existing) {
4442
4425
  candidates.push({ value: captured, column: tokenMatch.index + 1 });
4443
4426
  }
@@ -5143,15 +5126,9 @@ function getSeverity(pattern) {
5143
5126
  function formatTerminal(result) {
5144
5127
  const lines = [];
5145
5128
  const totalCount = result.secrets.length;
5146
- const criticalCount = result.secrets.filter(
5147
- (s) => getSeverity(s.pattern) === "critical"
5148
- ).length;
5149
- const highCount = result.secrets.filter(
5150
- (s) => getSeverity(s.pattern) === "high"
5151
- ).length;
5152
- const mediumCount = result.secrets.filter(
5153
- (s) => getSeverity(s.pattern) === "medium"
5154
- ).length;
5129
+ const criticalCount = result.secrets.filter((s) => getSeverity(s.pattern) === "critical").length;
5130
+ const highCount = result.secrets.filter((s) => getSeverity(s.pattern) === "high").length;
5131
+ const mediumCount = result.secrets.filter((s) => getSeverity(s.pattern) === "medium").length;
5155
5132
  lines.push("");
5156
5133
  lines.push(`${BOLD}=== ultraenv Secret Scan Report ===${RESET}`);
5157
5134
  lines.push("");
@@ -5167,7 +5144,9 @@ function formatTerminal(result) {
5167
5144
  }
5168
5145
  const summaryParts = [];
5169
5146
  if (criticalCount > 0) {
5170
- summaryParts.push(`${SEVERITY_CONFIG.critical.terminalColor}${BOLD}${criticalCount} critical${RESET}`);
5147
+ summaryParts.push(
5148
+ `${SEVERITY_CONFIG.critical.terminalColor}${BOLD}${criticalCount} critical${RESET}`
5149
+ );
5171
5150
  }
5172
5151
  if (highCount > 0) {
5173
5152
  summaryParts.push(`${SEVERITY_CONFIG.high.terminalColor}${BOLD}${highCount} high${RESET}`);
@@ -5693,13 +5672,16 @@ async function run7(args, ctx) {
5693
5672
  if (!gitignoreExists) {
5694
5673
  writeError(red(" \u2717 No .gitignore file found!"));
5695
5674
  writeLine("");
5696
- const box = drawBox([
5697
- "Your project has no .gitignore file.",
5698
- "Secrets in .env files could be committed to version control.",
5699
- "Create a .gitignore with ultraenv entries:",
5700
- "",
5701
- " ultraenv init"
5702
- ], { title: "DANGER", border: "double" });
5675
+ const box = drawBox(
5676
+ [
5677
+ "Your project has no .gitignore file.",
5678
+ "Secrets in .env files could be committed to version control.",
5679
+ "Create a .gitignore with ultraenv entries:",
5680
+ "",
5681
+ " ultraenv init"
5682
+ ],
5683
+ { title: "DANGER", border: "double" }
5684
+ );
5703
5685
  writeLine(box);
5704
5686
  writeLine("");
5705
5687
  return 1;
@@ -5715,7 +5697,9 @@ async function run7(args, ctx) {
5715
5697
  issues.push(pattern);
5716
5698
  }
5717
5699
  }
5718
- writeLine(green(` \u2713 ${protectedEntries.length}/${PROTECTED_PATTERNS.length} patterns protected`));
5700
+ writeLine(
5701
+ green(` \u2713 ${protectedEntries.length}/${PROTECTED_PATTERNS.length} patterns protected`)
5702
+ );
5719
5703
  const envFiles = [".env", ".env.local", ".env.production", ".env.development"];
5720
5704
  const notIgnored = [];
5721
5705
  for (const envFile of envFiles) {
@@ -5746,13 +5730,16 @@ async function run7(args, ctx) {
5746
5730
  writeError(red(` - ${f}`));
5747
5731
  }
5748
5732
  writeLine("");
5749
- const warnBox = drawBox([
5750
- "Tracked .env files may contain secrets.",
5751
- "Remove them from version control immediately:",
5752
- "",
5753
- " git rm --cached .env*",
5754
- ' git commit -m "Remove tracked .env files"'
5755
- ], { title: "WARNING", border: "double" });
5733
+ const warnBox = drawBox(
5734
+ [
5735
+ "Tracked .env files may contain secrets.",
5736
+ "Remove them from version control immediately:",
5737
+ "",
5738
+ " git rm --cached .env*",
5739
+ ' git commit -m "Remove tracked .env files"'
5740
+ ],
5741
+ { title: "WARNING", border: "double" }
5742
+ );
5756
5743
  writeLine(warnBox);
5757
5744
  writeLine("");
5758
5745
  return 1;
@@ -5808,13 +5795,7 @@ var init_protect = __esm({
5808
5795
  import_node_path11 = require("path");
5809
5796
  init_fs();
5810
5797
  init_git();
5811
- PROTECTED_PATTERNS = [
5812
- ".env",
5813
- ".env.local",
5814
- ".env.*.local",
5815
- ".env.vault",
5816
- ".env.keys"
5817
- ];
5798
+ PROTECTED_PATTERNS = [".env", ".env.local", ".env.*.local", ".env.vault", ".env.keys"];
5818
5799
  }
5819
5800
  });
5820
5801
 
@@ -5841,11 +5822,7 @@ function manualHkdf(ikm, salt, info, length) {
5841
5822
  const okm = Buffer.alloc(length);
5842
5823
  let previous = Buffer.alloc(0);
5843
5824
  for (let i = 1; i <= n; i++) {
5844
- const hmacData = Buffer.concat([
5845
- previous,
5846
- infoBuffer,
5847
- Buffer.from([i])
5848
- ]);
5825
+ const hmacData = Buffer.concat([previous, infoBuffer, Buffer.from([i])]);
5849
5826
  previous = (0, import_node_crypto.createHmac)("sha256", prk).update(hmacData).digest();
5850
5827
  const offset = (i - 1) * hashLen;
5851
5828
  const copyLen = Math.min(hashLen, length - offset);
@@ -5862,10 +5839,7 @@ function encrypt(key, plaintext) {
5862
5839
  const iv = (0, import_node_crypto.randomBytes)(12);
5863
5840
  const algo = `aes-${key.length * 8}-gcm`;
5864
5841
  const cipher = (0, import_node_crypto.createCipheriv)(algo, key, iv);
5865
- const ciphertext = Buffer.concat([
5866
- cipher.update(plaintext),
5867
- cipher.final()
5868
- ]);
5842
+ const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
5869
5843
  const authTag = cipher.getAuthTag();
5870
5844
  return { iv, authTag, ciphertext };
5871
5845
  }
@@ -5879,10 +5853,7 @@ function decrypt(key, iv, authTag, ciphertext) {
5879
5853
  const decipher = (0, import_node_crypto.createDecipheriv)(algo, key, iv);
5880
5854
  decipher.setAuthTag(authTag);
5881
5855
  try {
5882
- return Buffer.concat([
5883
- decipher.update(ciphertext),
5884
- decipher.final()
5885
- ]);
5856
+ return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
5886
5857
  } catch (error) {
5887
5858
  const message = error instanceof Error ? error.message : String(error);
5888
5859
  throw new Error(
@@ -5934,12 +5905,9 @@ function decryptValue(encrypted, key) {
5934
5905
  );
5935
5906
  }
5936
5907
  if (!encrypted.startsWith(ENCRYPTED_PREFIX)) {
5937
- throw new EncryptionError(
5938
- "Invalid encrypted value format: missing required prefix",
5939
- {
5940
- hint: `Expected the value to start with "${ENCRYPTED_PREFIX}". This value may not have been encrypted by ultraenv.`
5941
- }
5942
- );
5908
+ throw new EncryptionError("Invalid encrypted value format: missing required prefix", {
5909
+ hint: `Expected the value to start with "${ENCRYPTED_PREFIX}". This value may not have been encrypted by ultraenv.`
5910
+ });
5943
5911
  }
5944
5912
  const payload = encrypted.slice(ENCRYPTED_PREFIX.length);
5945
5913
  const parts = payload.split(":");
@@ -5955,16 +5923,14 @@ function decryptValue(encrypted, key) {
5955
5923
  const authTagB64 = parts[1];
5956
5924
  const ciphertextB64 = parts[2];
5957
5925
  if (ivB64 === void 0 || authTagB64 === void 0 || ciphertextB64 === void 0) {
5958
- throw new EncryptionError(
5959
- "Invalid encrypted value: unexpected component structure",
5960
- { hint: "The encrypted data may be corrupted. Try re-encrypting the value." }
5961
- );
5926
+ throw new EncryptionError("Invalid encrypted value: unexpected component structure", {
5927
+ hint: "The encrypted data may be corrupted. Try re-encrypting the value."
5928
+ });
5962
5929
  }
5963
5930
  if (ivB64.length === 0 || authTagB64.length === 0 || ciphertextB64.length === 0) {
5964
- throw new EncryptionError(
5965
- "Invalid encrypted value: one or more base64 components are empty",
5966
- { hint: "The encrypted data may be corrupted. Try re-encrypting the value." }
5967
- );
5931
+ throw new EncryptionError("Invalid encrypted value: one or more base64 components are empty", {
5932
+ hint: "The encrypted data may be corrupted. Try re-encrypting the value."
5933
+ });
5968
5934
  }
5969
5935
  try {
5970
5936
  const iv = base64ToBuffer(ivB64);
@@ -5973,7 +5939,9 @@ function decryptValue(encrypted, key) {
5973
5939
  if (iv.length !== IV_LENGTH) {
5974
5940
  throw new EncryptionError(
5975
5941
  `Invalid IV length: expected ${IV_LENGTH} bytes, got ${iv.length}`,
5976
- { hint: "The encrypted data may be corrupted or was produced by a different version of ultraenv." }
5942
+ {
5943
+ hint: "The encrypted data may be corrupted or was produced by a different version of ultraenv."
5944
+ }
5977
5945
  );
5978
5946
  }
5979
5947
  if (authTag.length !== AUTH_TAG_LENGTH) {
@@ -5988,10 +5956,9 @@ function decryptValue(encrypted, key) {
5988
5956
  if (error instanceof EncryptionError) throw error;
5989
5957
  const message = error instanceof Error ? error.message : String(error);
5990
5958
  if (message.includes("Invalid") || message.includes("base64")) {
5991
- throw new EncryptionError(
5992
- "Invalid base64 encoding in encrypted value",
5993
- { hint: "The encrypted data may be corrupted. Ensure the value was not modified." }
5994
- );
5959
+ throw new EncryptionError("Invalid base64 encoding in encrypted value", {
5960
+ hint: "The encrypted data may be corrupted. Ensure the value was not modified."
5961
+ });
5995
5962
  }
5996
5963
  throw new EncryptionError(
5997
5964
  "Failed to decrypt value. The key may be incorrect or the ciphertext was tampered with.",
@@ -6041,10 +6008,9 @@ function deriveEnvironmentKey(masterKey, environment) {
6041
6008
  );
6042
6009
  }
6043
6010
  if (environment.length === 0) {
6044
- throw new EncryptionError(
6045
- "Environment name cannot be empty",
6046
- { hint: 'Provide a valid environment name (e.g., "development", "production").' }
6047
- );
6011
+ throw new EncryptionError("Environment name cannot be empty", {
6012
+ hint: 'Provide a valid environment name (e.g., "development", "production").'
6013
+ });
6048
6014
  }
6049
6015
  if (HKDF_SALT.length < DEFAULT_SALT_LENGTH) {
6050
6016
  const paddedSalt = Buffer.alloc(DEFAULT_SALT_LENGTH);
@@ -6056,12 +6022,7 @@ function deriveEnvironmentKey(masterKey, environment) {
6056
6022
  DEFAULT_KEY_LENGTH
6057
6023
  );
6058
6024
  }
6059
- return deriveKey(
6060
- masterKey,
6061
- HKDF_SALT,
6062
- `${HKDF_INFO_PREFIX}${environment}`,
6063
- DEFAULT_KEY_LENGTH
6064
- );
6025
+ return deriveKey(masterKey, HKDF_SALT, `${HKDF_INFO_PREFIX}${environment}`, DEFAULT_KEY_LENGTH);
6065
6026
  }
6066
6027
  function formatKey(key) {
6067
6028
  if (key.length === 0) {
@@ -6081,21 +6042,17 @@ function parseKey2(formatted) {
6081
6042
  }
6082
6043
  const base64Part = formatted.slice(KEY_PREFIX.length);
6083
6044
  if (base64Part.length === 0) {
6084
- throw new EncryptionError(
6085
- "Invalid key format: base64 payload is empty after prefix",
6086
- { hint: "The key appears to be truncated. Generate a new key." }
6087
- );
6045
+ throw new EncryptionError("Invalid key format: base64 payload is empty after prefix", {
6046
+ hint: "The key appears to be truncated. Generate a new key."
6047
+ });
6088
6048
  }
6089
6049
  try {
6090
6050
  return base64ToBuffer(base64Part);
6091
6051
  } catch (error) {
6092
- throw new EncryptionError(
6093
- "Failed to decode key: invalid base64 encoding",
6094
- {
6095
- cause: error instanceof Error ? error : void 0,
6096
- hint: 'The key may be corrupted. Generate a new key with "ultraenv key generate".'
6097
- }
6098
- );
6052
+ throw new EncryptionError("Failed to decode key: invalid base64 encoding", {
6053
+ cause: error instanceof Error ? error : void 0,
6054
+ hint: 'The key may be corrupted. Generate a new key with "ultraenv key generate".'
6055
+ });
6099
6056
  }
6100
6057
  }
6101
6058
  function isValidKeyFormat(formatted) {
@@ -6157,12 +6114,9 @@ function parseKeysFile(content) {
6157
6114
  if (!eqMatch) {
6158
6115
  const plainMatch = line.match(/^ULTRAENV_KEY_([A-Za-z0-9_]+)=(.*)$/);
6159
6116
  if (!plainMatch) {
6160
- throw new EncryptionError(
6161
- `Invalid keys file format at line ${i + 1}: "${line}"`,
6162
- {
6163
- hint: 'Each key entry should be in the format: ULTRAENV_KEY_{ENVIRONMENT}="ultraenv_key_v1_..."'
6164
- }
6165
- );
6117
+ throw new EncryptionError(`Invalid keys file format at line ${i + 1}: "${line}"`, {
6118
+ hint: 'Each key entry should be in the format: ULTRAENV_KEY_{ENVIRONMENT}="ultraenv_key_v1_..."'
6119
+ });
6166
6120
  }
6167
6121
  const envName2 = plainMatch[1].toLowerCase();
6168
6122
  const keyValue2 = plainMatch[2];
@@ -6308,21 +6262,14 @@ function parseVaultFile(content) {
6308
6262
  if (rawLine === void 0) continue;
6309
6263
  const line = rawLine.trim();
6310
6264
  if (line.length === 0 || line.startsWith("#")) continue;
6311
- const match = line.match(
6312
- new RegExp(`^${VAULT_VAR_PREFIX}([A-Za-z0-9_]+)="(.*)"$`)
6313
- );
6265
+ const match = line.match(new RegExp(`^${VAULT_VAR_PREFIX}([A-Za-z0-9_]+)="(.*)"$`));
6314
6266
  if (!match) {
6315
- const plainMatch = line.match(
6316
- new RegExp(`^${VAULT_VAR_PREFIX}([A-Za-z0-9_]+)=(.*)$`)
6317
- );
6267
+ const plainMatch = line.match(new RegExp(`^${VAULT_VAR_PREFIX}([A-Za-z0-9_]+)=(.*)$`));
6318
6268
  if (!plainMatch) {
6319
- throw new VaultError(
6320
- `Invalid vault file format at line ${lineNumber}: "${line}"`,
6321
- {
6322
- operation: "parse",
6323
- hint: `Each environment entry should be in the format: ${VAULT_VAR_PREFIX}{ENVIRONMENT}="encrypted:..."`
6324
- }
6325
- );
6269
+ throw new VaultError(`Invalid vault file format at line ${lineNumber}: "${line}"`, {
6270
+ operation: "parse",
6271
+ hint: `Each environment entry should be in the format: ${VAULT_VAR_PREFIX}{ENVIRONMENT}="encrypted:..."`
6272
+ });
6326
6273
  }
6327
6274
  const envName2 = plainMatch[1].toLowerCase();
6328
6275
  const encryptedValue2 = plainMatch[2];
@@ -6375,41 +6322,32 @@ async function readVaultFile(path) {
6375
6322
  return parseVaultFile(content);
6376
6323
  } catch (error) {
6377
6324
  if (error instanceof VaultError) throw error;
6378
- throw new VaultError(
6379
- `Failed to read vault file "${path}"`,
6380
- {
6381
- operation: "read",
6382
- /* v8 ignore start */
6383
- cause: error instanceof Error ? error : void 0
6384
- /* v8 ignore stop */
6385
- }
6386
- );
6325
+ throw new VaultError(`Failed to read vault file "${path}"`, {
6326
+ operation: "read",
6327
+ /* v8 ignore start */
6328
+ cause: error instanceof Error ? error : void 0
6329
+ /* v8 ignore stop */
6330
+ });
6387
6331
  }
6388
6332
  }
6389
6333
  async function writeVaultFile(path, environments) {
6390
6334
  if (environments.size === 0) {
6391
- throw new VaultError(
6392
- "Cannot write an empty vault file",
6393
- {
6394
- operation: "write",
6395
- hint: "Add at least one environment to the vault before writing."
6396
- }
6397
- );
6335
+ throw new VaultError("Cannot write an empty vault file", {
6336
+ operation: "write",
6337
+ hint: "Add at least one environment to the vault before writing."
6338
+ });
6398
6339
  }
6399
6340
  try {
6400
6341
  const content = serializeVaultFile(environments);
6401
6342
  await writeFile(path, content, "utf-8");
6402
6343
  } catch (error) {
6403
6344
  if (error instanceof VaultError) throw error;
6404
- throw new VaultError(
6405
- `Failed to write vault file "${path}"`,
6406
- {
6407
- operation: "write",
6408
- /* v8 ignore start */
6409
- cause: error instanceof Error ? error : void 0
6410
- /* v8 ignore stop */
6411
- }
6412
- );
6345
+ throw new VaultError(`Failed to write vault file "${path}"`, {
6346
+ operation: "write",
6347
+ /* v8 ignore start */
6348
+ cause: error instanceof Error ? error : void 0
6349
+ /* v8 ignore stop */
6350
+ });
6413
6351
  }
6414
6352
  }
6415
6353
  function countEncryptedVars(encrypted) {
@@ -6942,16 +6880,14 @@ var init_vault_diff = __esm({
6942
6880
  // src/vault/integrity.ts
6943
6881
  function computeIntegrity(data, key) {
6944
6882
  if (key.length === 0) {
6945
- throw new EncryptionError(
6946
- "Cannot compute integrity with an empty key",
6947
- { hint: "Provide a valid encryption key for integrity computation." }
6948
- );
6883
+ throw new EncryptionError("Cannot compute integrity with an empty key", {
6884
+ hint: "Provide a valid encryption key for integrity computation."
6885
+ });
6949
6886
  }
6950
6887
  if (data.length === 0) {
6951
- throw new EncryptionError(
6952
- "Cannot compute integrity for empty data",
6953
- { hint: "Provide non-empty data for integrity computation." }
6954
- );
6888
+ throw new EncryptionError("Cannot compute integrity for empty data", {
6889
+ hint: "Provide non-empty data for integrity computation."
6890
+ });
6955
6891
  }
6956
6892
  const hmac = (0, import_node_crypto3.createHmac)(HMAC_ALGORITHM, key);
6957
6893
  hmac.update(data, "utf-8");
@@ -7183,12 +7119,14 @@ async function validateAllEnvironments(schema, cwd) {
7183
7119
  const message = error instanceof Error ? error.message : String(error);
7184
7120
  results.set(envName ?? pattern, {
7185
7121
  valid: false,
7186
- errors: [{
7187
- field: "",
7188
- value: "",
7189
- message: `Failed to read/parse file: ${message}`,
7190
- hint: "Check that the file is a valid .env file."
7191
- }],
7122
+ errors: [
7123
+ {
7124
+ field: "",
7125
+ value: "",
7126
+ message: `Failed to read/parse file: ${message}`,
7127
+ hint: "Check that the file is a valid .env file."
7128
+ }
7129
+ ],
7192
7130
  warnings: []
7193
7131
  });
7194
7132
  }
@@ -7199,14 +7137,11 @@ async function switchEnvironment(envName, cwd) {
7199
7137
  const baseDir = (0, import_node_path19.resolve)(cwd ?? process.cwd());
7200
7138
  const envFile = (0, import_node_path19.join)(baseDir, `.env.${envName}`);
7201
7139
  if (!await exists(envFile)) {
7202
- throw new FileSystemError(
7203
- `Environment file ".env.${envName}" not found`,
7204
- {
7205
- path: envFile,
7206
- operation: "read",
7207
- hint: `Create a ".env.${envName}" file first, or use "ultraenv env create ${envName}".`
7208
- }
7209
- );
7140
+ throw new FileSystemError(`Environment file ".env.${envName}" not found`, {
7141
+ path: envFile,
7142
+ operation: "read",
7143
+ hint: `Create a ".env.${envName}" file first, or use "ultraenv env create ${envName}".`
7144
+ });
7210
7145
  }
7211
7146
  const content = await readFile(envFile);
7212
7147
  const header = [
@@ -7392,24 +7327,18 @@ async function compareEnvironments(env1, env2, cwd, _schema) {
7392
7327
  const resolvedEnv1Path = env1.includes("/") || env1.includes("\\") ? (0, import_node_path20.resolve)(env1) : env1Path;
7393
7328
  const resolvedEnv2Path = env2.includes("/") || env2.includes("\\") ? (0, import_node_path20.resolve)(env2) : env2Path;
7394
7329
  if (!await exists(resolvedEnv1Path)) {
7395
- throw new FileSystemError(
7396
- `Environment file not found: "${resolvedEnv1Path}"`,
7397
- {
7398
- path: resolvedEnv1Path,
7399
- operation: "read",
7400
- hint: `Ensure ".env.${env1}" exists in the project directory.`
7401
- }
7402
- );
7330
+ throw new FileSystemError(`Environment file not found: "${resolvedEnv1Path}"`, {
7331
+ path: resolvedEnv1Path,
7332
+ operation: "read",
7333
+ hint: `Ensure ".env.${env1}" exists in the project directory.`
7334
+ });
7403
7335
  }
7404
7336
  if (!await exists(resolvedEnv2Path)) {
7405
- throw new FileSystemError(
7406
- `Environment file not found: "${resolvedEnv2Path}"`,
7407
- {
7408
- path: resolvedEnv2Path,
7409
- operation: "read",
7410
- hint: `Ensure ".env.${env2}" exists in the project directory.`
7411
- }
7412
- );
7337
+ throw new FileSystemError(`Environment file not found: "${resolvedEnv2Path}"`, {
7338
+ path: resolvedEnv2Path,
7339
+ operation: "read",
7340
+ hint: `Ensure ".env.${env2}" exists in the project directory.`
7341
+ });
7413
7342
  }
7414
7343
  const env1Content = await readFile(resolvedEnv1Path);
7415
7344
  const env2Content = await readFile(resolvedEnv2Path);
@@ -7502,14 +7431,18 @@ function formatComparison(comparison) {
7502
7431
  lines.push("");
7503
7432
  lines.push(`Only in ${comparison.env1Name} (${comparison.onlyInEnv1.length}):`);
7504
7433
  for (const diff of comparison.onlyInEnv1) {
7505
- lines.push(` - ${diff.key}${diff.isSecret ? " [SECRET]" : ""} = ${diff.value1 || "(empty)"}`);
7434
+ lines.push(
7435
+ ` - ${diff.key}${diff.isSecret ? " [SECRET]" : ""} = ${diff.value1 || "(empty)"}`
7436
+ );
7506
7437
  }
7507
7438
  }
7508
7439
  if (comparison.onlyInEnv2.length > 0) {
7509
7440
  lines.push("");
7510
7441
  lines.push(`Only in ${comparison.env2Name} (${comparison.onlyInEnv2.length}):`);
7511
7442
  for (const diff of comparison.onlyInEnv2) {
7512
- lines.push(` + ${diff.key}${diff.isSecret ? " [SECRET]" : ""} = ${diff.value2 || "(empty)"}`);
7443
+ lines.push(
7444
+ ` + ${diff.key}${diff.isSecret ? " [SECRET]" : ""} = ${diff.value2 || "(empty)"}`
7445
+ );
7513
7446
  }
7514
7447
  }
7515
7448
  if (comparison.different.length > 0) {
@@ -7643,10 +7576,7 @@ async function run17(args, ctx) {
7643
7576
  writeLine(yellow(" No schema defined in configuration. Basic validation only."));
7644
7577
  writeLine("");
7645
7578
  }
7646
- const results = await validateAllEnvironments(
7647
- ctx.config.schema?.definitions ?? {},
7648
- cwd
7649
- );
7579
+ const results = await validateAllEnvironments(ctx.config.schema?.definitions ?? {}, cwd);
7650
7580
  if (ctx.outputFormat === "json") {
7651
7581
  const jsonResults = {};
7652
7582
  for (const [name, result] of results) {
@@ -7799,14 +7729,11 @@ function validateEnvironmentName(name) {
7799
7729
  });
7800
7730
  }
7801
7731
  if (name.length > 64) {
7802
- throw new FileSystemError(
7803
- `Environment name too long: ${name.length} characters (max 64)`,
7804
- {
7805
- path: "",
7806
- operation: "validate",
7807
- hint: "Use a shorter environment name."
7808
- }
7809
- );
7732
+ throw new FileSystemError(`Environment name too long: ${name.length} characters (max 64)`, {
7733
+ path: "",
7734
+ operation: "validate",
7735
+ hint: "Use a shorter environment name."
7736
+ });
7810
7737
  }
7811
7738
  if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
7812
7739
  throw new FileSystemError(
@@ -7820,14 +7747,11 @@ function validateEnvironmentName(name) {
7820
7747
  }
7821
7748
  const reserved = ["local", "example", "template", "bak", "backup", "old", "tmp", "temp"];
7822
7749
  if (reserved.includes(name.toLowerCase())) {
7823
- throw new FileSystemError(
7824
- `Reserved environment name: "${name}"`,
7825
- {
7826
- path: "",
7827
- operation: "validate",
7828
- hint: `The name "${name}" is reserved. Choose a different name.`
7829
- }
7830
- );
7750
+ throw new FileSystemError(`Reserved environment name: "${name}"`, {
7751
+ path: "",
7752
+ operation: "validate",
7753
+ hint: `The name "${name}" is reserved. Choose a different name.`
7754
+ });
7831
7755
  }
7832
7756
  }
7833
7757
  async function createEnvironment(name, options) {
@@ -7835,28 +7759,22 @@ async function createEnvironment(name, options) {
7835
7759
  const baseDir = (0, import_node_path21.resolve)(options?.cwd ?? process.cwd());
7836
7760
  const outputPath = (0, import_node_path21.join)(baseDir, `.env.${name}`);
7837
7761
  if (await exists(outputPath)) {
7838
- throw new FileSystemError(
7839
- `Environment file already exists: ".env.${name}"`,
7840
- {
7841
- path: outputPath,
7842
- operation: "create",
7843
- hint: "Delete the existing file first, or use a different environment name."
7844
- }
7845
- );
7762
+ throw new FileSystemError(`Environment file already exists: ".env.${name}"`, {
7763
+ path: outputPath,
7764
+ operation: "create",
7765
+ hint: "Delete the existing file first, or use a different environment name."
7766
+ });
7846
7767
  }
7847
7768
  let content;
7848
7769
  let variables = [];
7849
7770
  if (options?.copyFrom !== void 0) {
7850
7771
  const sourcePath = (0, import_node_path21.join)(baseDir, `.env.${options.copyFrom}`);
7851
7772
  if (!await exists(sourcePath)) {
7852
- throw new FileSystemError(
7853
- `Source environment not found: ".env.${options.copyFrom}"`,
7854
- {
7855
- path: sourcePath,
7856
- operation: "read",
7857
- hint: `Ensure ".env.${options.copyFrom}" exists before copying.`
7858
- }
7859
- );
7773
+ throw new FileSystemError(`Source environment not found: ".env.${options.copyFrom}"`, {
7774
+ path: sourcePath,
7775
+ operation: "read",
7776
+ hint: `Ensure ".env.${options.copyFrom}" exists before copying.`
7777
+ });
7860
7778
  }
7861
7779
  content = await readFile(sourcePath);
7862
7780
  variables = extractVariables(content, options?.schema);
@@ -7877,14 +7795,11 @@ async function createEnvironment(name, options) {
7877
7795
  } else if (await exists(templatePath)) {
7878
7796
  content = await readFile(templatePath);
7879
7797
  } else {
7880
- throw new FileSystemError(
7881
- `Template not found: "${options.fromTemplate}"`,
7882
- {
7883
- path: templatePath,
7884
- operation: "read",
7885
- hint: "Use a built-in template name (nodejs, nextjs, docker) or a valid file path."
7886
- }
7887
- );
7798
+ throw new FileSystemError(`Template not found: "${options.fromTemplate}"`, {
7799
+ path: templatePath,
7800
+ operation: "read",
7801
+ hint: "Use a built-in template name (nodejs, nextjs, docker) or a valid file path."
7802
+ });
7888
7803
  }
7889
7804
  variables = extractVariables(content, options?.schema);
7890
7805
  const values = collectValues(variables, options?.values);
@@ -7919,9 +7834,18 @@ async function createEnvironment(name, options) {
7919
7834
  }
7920
7835
  function listTemplates() {
7921
7836
  return [
7922
- { name: "nodejs", description: "Node.js backend environment (PORT, DATABASE_URL, JWT, CORS, etc.)" },
7923
- { name: "nextjs", description: "Next.js frontend environment (NEXT_PUBLIC_* variables, analytics, etc.)" },
7924
- { name: "docker", description: "Docker deployment environment (container ports, Postgres, Redis, etc.)" }
7837
+ {
7838
+ name: "nodejs",
7839
+ description: "Node.js backend environment (PORT, DATABASE_URL, JWT, CORS, etc.)"
7840
+ },
7841
+ {
7842
+ name: "nextjs",
7843
+ description: "Next.js frontend environment (NEXT_PUBLIC_* variables, analytics, etc.)"
7844
+ },
7845
+ {
7846
+ name: "docker",
7847
+ description: "Docker deployment environment (container ports, Postgres, Redis, etc.)"
7848
+ }
7925
7849
  ];
7926
7850
  }
7927
7851
  var import_node_path21, NODEJS_TEMPLATE, NEXTJS_TEMPLATE, DOCKER_TEMPLATE, BUILTIN_TEMPLATES;
@@ -8213,10 +8137,7 @@ async function run22(args, ctx) {
8213
8137
  failFast: args.flags["--fail-fast"] ?? true,
8214
8138
  outputFormat
8215
8139
  });
8216
- const formatted = formatScanResult(
8217
- result,
8218
- outputFormat
8219
- );
8140
+ const formatted = formatScanResult(result, outputFormat);
8220
8141
  process.stdout.write(formatted + "\n");
8221
8142
  return result.found ? 1 : 0;
8222
8143
  } catch (error) {
@@ -8560,7 +8481,9 @@ async function run25(args, ctx) {
8560
8481
  writeJson({ checks, summary: { passed, warnings, failed, total: checks.length } });
8561
8482
  return failed > 0 ? 1 : 0;
8562
8483
  }
8563
- writeLine(cyan(` ${passed}/${checks.length} passed, ${warnings} warning(s), ${failed} failure(s)`));
8484
+ writeLine(
8485
+ cyan(` ${passed}/${checks.length} passed, ${warnings} warning(s), ${failed} failure(s)`)
8486
+ );
8564
8487
  writeLine("");
8565
8488
  if (failed > 0) {
8566
8489
  writeLine(red(bold(" Some checks failed. Fix the issues above.")));
@@ -8776,11 +8699,11 @@ async function run27(args, _ctx) {
8776
8699
  writeLine(` Usage: ${cmd.usage}`);
8777
8700
  writeLine("");
8778
8701
  const optionsMap = {
8779
- "init": ["--force", "--cwd <path>"],
8780
- "validate": ["--env-dir <path>", "--quiet"],
8781
- "typegen": ["--format <type>", "--out <path>", "--interface <name>"],
8782
- "sync": ["--mode <mode>", "--file <path>", "--out <path>", "--watch"],
8783
- "scan": ["--scope <scope>", "--format <type>", "--include <glob>", "--exclude <glob>"],
8702
+ init: ["--force", "--cwd <path>"],
8703
+ validate: ["--env-dir <path>", "--quiet"],
8704
+ typegen: ["--format <type>", "--out <path>", "--interface <name>"],
8705
+ sync: ["--mode <mode>", "--file <path>", "--out <path>", "--watch"],
8706
+ scan: ["--scope <scope>", "--format <type>", "--include <glob>", "--exclude <glob>"],
8784
8707
  "vault init": ["--env <name>", "--force", "--key <key>"],
8785
8708
  "vault encrypt": ["--env <name>", "--key <key>"],
8786
8709
  "vault decrypt": ["--env <name>", "--key <key>"],
@@ -8809,7 +8732,9 @@ async function run27(args, _ctx) {
8809
8732
  writeLine("");
8810
8733
  writeLine(" COMMANDS:");
8811
8734
  writeLine("");
8812
- const core = COMMANDS.filter((c) => !c.name.startsWith("vault") && !c.name.startsWith("envs") && !c.name.startsWith("ci"));
8735
+ const core = COMMANDS.filter(
8736
+ (c) => !c.name.startsWith("vault") && !c.name.startsWith("envs") && !c.name.startsWith("ci")
8737
+ );
8813
8738
  const vault = COMMANDS.filter((c) => c.name.startsWith("vault"));
8814
8739
  const envs = COMMANDS.filter((c) => c.name.startsWith("envs"));
8815
8740
  const ci = COMMANDS.filter((c) => c.name.startsWith("ci"));
@@ -8848,32 +8773,112 @@ var init_help = __esm({
8848
8773
  init_colors();
8849
8774
  init_constants();
8850
8775
  COMMANDS = [
8851
- { name: "init", description: "Initialize ultraenv in a project", usage: "ultraenv init [options]" },
8852
- { name: "validate", description: "Validate environment against schema", usage: "ultraenv validate [options]" },
8853
- { name: "typegen", description: "Generate TypeScript types", usage: "ultraenv typegen [options]" },
8776
+ {
8777
+ name: "init",
8778
+ description: "Initialize ultraenv in a project",
8779
+ usage: "ultraenv init [options]"
8780
+ },
8781
+ {
8782
+ name: "validate",
8783
+ description: "Validate environment against schema",
8784
+ usage: "ultraenv validate [options]"
8785
+ },
8786
+ {
8787
+ name: "typegen",
8788
+ description: "Generate TypeScript types",
8789
+ usage: "ultraenv typegen [options]"
8790
+ },
8854
8791
  { name: "sync", description: "Sync .env.example", usage: "ultraenv sync [options]" },
8855
8792
  { name: "scan", description: "Scan for leaked secrets", usage: "ultraenv scan [options]" },
8856
8793
  { name: "debug", description: "Show environment diagnostics", usage: "ultraenv debug [options]" },
8857
- { name: "protect", description: "Verify .gitignore protection", usage: "ultraenv protect [options]" },
8858
- { name: "vault init", description: "Initialize encrypted vault", usage: "ultraenv vault init [options]" },
8859
- { name: "vault encrypt", description: "Encrypt .env \u2192 vault", usage: "ultraenv vault encrypt [options]" },
8860
- { name: "vault decrypt", description: "Decrypt vault \u2192 .env", usage: "ultraenv vault decrypt [options]" },
8861
- { name: "vault rekey", description: "Rotate encryption keys", usage: "ultraenv vault rekey [options]" },
8862
- { name: "vault status", description: "Show vault status", usage: "ultraenv vault status [options]" },
8863
- { name: "vault diff", description: "Compare .env vs vault", usage: "ultraenv vault diff [options]" },
8864
- { name: "vault verify", description: "Verify vault integrity", usage: "ultraenv vault verify [options]" },
8865
- { name: "envs list", description: "List all environments", usage: "ultraenv envs list [options]" },
8866
- { name: "envs compare", description: "Compare two environments", usage: "ultraenv envs compare <env1> <env2>" },
8867
- { name: "envs validate", description: "Validate all environments", usage: "ultraenv envs validate [options]" },
8868
- { name: "envs create", description: "Create new environment", usage: "ultraenv envs create <name> [options]" },
8869
- { name: "envs switch", description: "Switch current environment", usage: "ultraenv envs switch <name>" },
8870
- { name: "ci validate", description: "CI validation mode", usage: "ultraenv ci validate [options]" },
8871
- { name: "ci check-sync", description: "CI sync check", usage: "ultraenv ci check-sync [options]" },
8794
+ {
8795
+ name: "protect",
8796
+ description: "Verify .gitignore protection",
8797
+ usage: "ultraenv protect [options]"
8798
+ },
8799
+ {
8800
+ name: "vault init",
8801
+ description: "Initialize encrypted vault",
8802
+ usage: "ultraenv vault init [options]"
8803
+ },
8804
+ {
8805
+ name: "vault encrypt",
8806
+ description: "Encrypt .env \u2192 vault",
8807
+ usage: "ultraenv vault encrypt [options]"
8808
+ },
8809
+ {
8810
+ name: "vault decrypt",
8811
+ description: "Decrypt vault \u2192 .env",
8812
+ usage: "ultraenv vault decrypt [options]"
8813
+ },
8814
+ {
8815
+ name: "vault rekey",
8816
+ description: "Rotate encryption keys",
8817
+ usage: "ultraenv vault rekey [options]"
8818
+ },
8819
+ {
8820
+ name: "vault status",
8821
+ description: "Show vault status",
8822
+ usage: "ultraenv vault status [options]"
8823
+ },
8824
+ {
8825
+ name: "vault diff",
8826
+ description: "Compare .env vs vault",
8827
+ usage: "ultraenv vault diff [options]"
8828
+ },
8829
+ {
8830
+ name: "vault verify",
8831
+ description: "Verify vault integrity",
8832
+ usage: "ultraenv vault verify [options]"
8833
+ },
8834
+ {
8835
+ name: "envs list",
8836
+ description: "List all environments",
8837
+ usage: "ultraenv envs list [options]"
8838
+ },
8839
+ {
8840
+ name: "envs compare",
8841
+ description: "Compare two environments",
8842
+ usage: "ultraenv envs compare <env1> <env2>"
8843
+ },
8844
+ {
8845
+ name: "envs validate",
8846
+ description: "Validate all environments",
8847
+ usage: "ultraenv envs validate [options]"
8848
+ },
8849
+ {
8850
+ name: "envs create",
8851
+ description: "Create new environment",
8852
+ usage: "ultraenv envs create <name> [options]"
8853
+ },
8854
+ {
8855
+ name: "envs switch",
8856
+ description: "Switch current environment",
8857
+ usage: "ultraenv envs switch <name>"
8858
+ },
8859
+ {
8860
+ name: "ci validate",
8861
+ description: "CI validation mode",
8862
+ usage: "ultraenv ci validate [options]"
8863
+ },
8864
+ {
8865
+ name: "ci check-sync",
8866
+ description: "CI sync check",
8867
+ usage: "ultraenv ci check-sync [options]"
8868
+ },
8872
8869
  { name: "ci scan", description: "CI secret scan", usage: "ultraenv ci scan [options]" },
8873
8870
  { name: "ci setup", description: "Generate CI config", usage: "ultraenv ci setup [options]" },
8874
- { name: "install-hook", description: "Install git pre-commit hook", usage: "ultraenv install-hook [options]" },
8871
+ {
8872
+ name: "install-hook",
8873
+ description: "Install git pre-commit hook",
8874
+ usage: "ultraenv install-hook [options]"
8875
+ },
8875
8876
  { name: "doctor", description: "Self-check installation", usage: "ultraenv doctor [options]" },
8876
- { name: "completion", description: "Generate shell completions", usage: "ultraenv completion <shell>" },
8877
+ {
8878
+ name: "completion",
8879
+ description: "Generate shell completions",
8880
+ usage: "ultraenv completion <shell>"
8881
+ },
8877
8882
  { name: "version", description: "Show version", usage: "ultraenv version" }
8878
8883
  ];
8879
8884
  }
@@ -8913,19 +8918,8 @@ var VAULT_SUBCOMMANDS = /* @__PURE__ */ new Set([
8913
8918
  "diff",
8914
8919
  "verify"
8915
8920
  ]);
8916
- var ENVS_SUBCOMMANDS = /* @__PURE__ */ new Set([
8917
- "list",
8918
- "compare",
8919
- "validate",
8920
- "create",
8921
- "switch"
8922
- ]);
8923
- var CI_SUBCOMMANDS = /* @__PURE__ */ new Set([
8924
- "validate",
8925
- "check-sync",
8926
- "scan",
8927
- "setup"
8928
- ]);
8921
+ var ENVS_SUBCOMMANDS = /* @__PURE__ */ new Set(["list", "compare", "validate", "create", "switch"]);
8922
+ var CI_SUBCOMMANDS = /* @__PURE__ */ new Set(["validate", "check-sync", "scan", "setup"]);
8929
8923
  var OPTIONS_WITH_VALUES = /* @__PURE__ */ new Set([
8930
8924
  "--config",
8931
8925
  "--format",
@@ -9068,37 +9062,97 @@ init_errors();
9068
9062
  var import_node_path27 = require("path");
9069
9063
  var COMMAND_REGISTRY = {
9070
9064
  // Core commands
9071
- "init": () => Promise.resolve().then(() => (init_init(), init_exports)).then((m) => ({ runner: m.run, description: "Initialize project" })),
9072
- "validate": () => Promise.resolve().then(() => (init_validate(), validate_exports)).then((m) => ({ runner: m.run, description: "Validate environment" })),
9073
- "typegen": () => Promise.resolve().then(() => (init_typegen(), typegen_exports)).then((m) => ({ runner: m.run, description: "Generate TypeScript types" })),
9074
- "sync": () => Promise.resolve().then(() => (init_sync(), sync_exports)).then((m) => ({ runner: m.run, description: "Sync .env.example" })),
9075
- "scan": () => Promise.resolve().then(() => (init_scan(), scan_exports)).then((m) => ({ runner: m.run, description: "Scan for secrets" })),
9076
- "debug": () => Promise.resolve().then(() => (init_debug(), debug_exports)).then((m) => ({ runner: m.run, description: "Show diagnostics" })),
9077
- "protect": () => Promise.resolve().then(() => (init_protect(), protect_exports)).then((m) => ({ runner: m.run, description: "Check .gitignore" })),
9065
+ init: () => Promise.resolve().then(() => (init_init(), init_exports)).then((m) => ({
9066
+ runner: m.run,
9067
+ description: "Initialize project"
9068
+ })),
9069
+ validate: () => Promise.resolve().then(() => (init_validate(), validate_exports)).then((m) => ({
9070
+ runner: m.run,
9071
+ description: "Validate environment"
9072
+ })),
9073
+ typegen: () => Promise.resolve().then(() => (init_typegen(), typegen_exports)).then((m) => ({
9074
+ runner: m.run,
9075
+ description: "Generate TypeScript types"
9076
+ })),
9077
+ sync: () => Promise.resolve().then(() => (init_sync(), sync_exports)).then((m) => ({ runner: m.run, description: "Sync .env.example" })),
9078
+ scan: () => Promise.resolve().then(() => (init_scan(), scan_exports)).then((m) => ({ runner: m.run, description: "Scan for secrets" })),
9079
+ debug: () => Promise.resolve().then(() => (init_debug(), debug_exports)).then((m) => ({ runner: m.run, description: "Show diagnostics" })),
9080
+ protect: () => Promise.resolve().then(() => (init_protect(), protect_exports)).then((m) => ({
9081
+ runner: m.run,
9082
+ description: "Check .gitignore"
9083
+ })),
9078
9084
  // Vault subcommands
9079
- "vault.init": () => Promise.resolve().then(() => (init_vault_init(), vault_init_exports)).then((m) => ({ runner: m.run, description: "Initialize vault" })),
9080
- "vault.encrypt": () => Promise.resolve().then(() => (init_vault_encrypt(), vault_encrypt_exports)).then((m) => ({ runner: m.run, description: "Encrypt to vault" })),
9081
- "vault.decrypt": () => Promise.resolve().then(() => (init_vault_decrypt(), vault_decrypt_exports)).then((m) => ({ runner: m.run, description: "Decrypt from vault" })),
9082
- "vault.rekey": () => Promise.resolve().then(() => (init_vault_rekey(), vault_rekey_exports)).then((m) => ({ runner: m.run, description: "Rotate keys" })),
9083
- "vault.status": () => Promise.resolve().then(() => (init_vault_status(), vault_status_exports)).then((m) => ({ runner: m.run, description: "Vault status" })),
9084
- "vault.diff": () => Promise.resolve().then(() => (init_vault_diff(), vault_diff_exports)).then((m) => ({ runner: m.run, description: "Compare vs vault" })),
9085
- "vault.verify": () => Promise.resolve().then(() => (init_vault_verify(), vault_verify_exports)).then((m) => ({ runner: m.run, description: "Verify integrity" })),
9085
+ "vault.init": () => Promise.resolve().then(() => (init_vault_init(), vault_init_exports)).then((m) => ({
9086
+ runner: m.run,
9087
+ description: "Initialize vault"
9088
+ })),
9089
+ "vault.encrypt": () => Promise.resolve().then(() => (init_vault_encrypt(), vault_encrypt_exports)).then((m) => ({
9090
+ runner: m.run,
9091
+ description: "Encrypt to vault"
9092
+ })),
9093
+ "vault.decrypt": () => Promise.resolve().then(() => (init_vault_decrypt(), vault_decrypt_exports)).then((m) => ({
9094
+ runner: m.run,
9095
+ description: "Decrypt from vault"
9096
+ })),
9097
+ "vault.rekey": () => Promise.resolve().then(() => (init_vault_rekey(), vault_rekey_exports)).then((m) => ({
9098
+ runner: m.run,
9099
+ description: "Rotate keys"
9100
+ })),
9101
+ "vault.status": () => Promise.resolve().then(() => (init_vault_status(), vault_status_exports)).then((m) => ({
9102
+ runner: m.run,
9103
+ description: "Vault status"
9104
+ })),
9105
+ "vault.diff": () => Promise.resolve().then(() => (init_vault_diff(), vault_diff_exports)).then((m) => ({
9106
+ runner: m.run,
9107
+ description: "Compare vs vault"
9108
+ })),
9109
+ "vault.verify": () => Promise.resolve().then(() => (init_vault_verify(), vault_verify_exports)).then((m) => ({
9110
+ runner: m.run,
9111
+ description: "Verify integrity"
9112
+ })),
9086
9113
  // Environment subcommands
9087
- "envs.list": () => Promise.resolve().then(() => (init_envs_list(), envs_list_exports)).then((m) => ({ runner: m.run, description: "List environments" })),
9088
- "envs.compare": () => Promise.resolve().then(() => (init_envs_compare(), envs_compare_exports)).then((m) => ({ runner: m.run, description: "Compare envs" })),
9089
- "envs.validate": () => Promise.resolve().then(() => (init_envs_validate(), envs_validate_exports)).then((m) => ({ runner: m.run, description: "Validate envs" })),
9090
- "envs.create": () => Promise.resolve().then(() => (init_envs_create(), envs_create_exports)).then((m) => ({ runner: m.run, description: "Create environment" })),
9091
- "envs.switch": () => Promise.resolve().then(() => (init_envs_switch(), envs_switch_exports)).then((m) => ({ runner: m.run, description: "Switch environment" })),
9114
+ "envs.list": () => Promise.resolve().then(() => (init_envs_list(), envs_list_exports)).then((m) => ({
9115
+ runner: m.run,
9116
+ description: "List environments"
9117
+ })),
9118
+ "envs.compare": () => Promise.resolve().then(() => (init_envs_compare(), envs_compare_exports)).then((m) => ({
9119
+ runner: m.run,
9120
+ description: "Compare envs"
9121
+ })),
9122
+ "envs.validate": () => Promise.resolve().then(() => (init_envs_validate(), envs_validate_exports)).then((m) => ({
9123
+ runner: m.run,
9124
+ description: "Validate envs"
9125
+ })),
9126
+ "envs.create": () => Promise.resolve().then(() => (init_envs_create(), envs_create_exports)).then((m) => ({
9127
+ runner: m.run,
9128
+ description: "Create environment"
9129
+ })),
9130
+ "envs.switch": () => Promise.resolve().then(() => (init_envs_switch(), envs_switch_exports)).then((m) => ({
9131
+ runner: m.run,
9132
+ description: "Switch environment"
9133
+ })),
9092
9134
  // CI subcommands
9093
- "ci.validate": () => Promise.resolve().then(() => (init_ci_validate(), ci_validate_exports)).then((m) => ({ runner: m.run, description: "CI validate" })),
9094
- "ci.check-sync": () => Promise.resolve().then(() => (init_ci_check_sync(), ci_check_sync_exports)).then((m) => ({ runner: m.run, description: "CI sync check" })),
9135
+ "ci.validate": () => Promise.resolve().then(() => (init_ci_validate(), ci_validate_exports)).then((m) => ({
9136
+ runner: m.run,
9137
+ description: "CI validate"
9138
+ })),
9139
+ "ci.check-sync": () => Promise.resolve().then(() => (init_ci_check_sync(), ci_check_sync_exports)).then((m) => ({
9140
+ runner: m.run,
9141
+ description: "CI sync check"
9142
+ })),
9095
9143
  "ci.scan": () => Promise.resolve().then(() => (init_ci_scan(), ci_scan_exports)).then((m) => ({ runner: m.run, description: "CI scan" })),
9096
9144
  "ci.setup": () => Promise.resolve().then(() => (init_ci_setup(), ci_setup_exports)).then((m) => ({ runner: m.run, description: "CI setup" })),
9097
9145
  // Utility commands
9098
- "install-hook": () => Promise.resolve().then(() => (init_install_hook(), install_hook_exports)).then((m) => ({ runner: m.run, description: "Install git hook" })),
9099
- "doctor": () => Promise.resolve().then(() => (init_doctor(), doctor_exports)).then((m) => ({ runner: m.run, description: "Self-check" })),
9100
- "completion": () => Promise.resolve().then(() => (init_completion(), completion_exports)).then((m) => ({ runner: m.run, description: "Shell completions" })),
9101
- "help": () => Promise.resolve().then(() => (init_help(), help_exports)).then((m) => ({ runner: m.run, description: "Show help" }))
9146
+ "install-hook": () => Promise.resolve().then(() => (init_install_hook(), install_hook_exports)).then((m) => ({
9147
+ runner: m.run,
9148
+ description: "Install git hook"
9149
+ })),
9150
+ doctor: () => Promise.resolve().then(() => (init_doctor(), doctor_exports)).then((m) => ({ runner: m.run, description: "Self-check" })),
9151
+ completion: () => Promise.resolve().then(() => (init_completion(), completion_exports)).then((m) => ({
9152
+ runner: m.run,
9153
+ description: "Shell completions"
9154
+ })),
9155
+ help: () => Promise.resolve().then(() => (init_help(), help_exports)).then((m) => ({ runner: m.run, description: "Show help" }))
9102
9156
  };
9103
9157
  function handleVersion() {
9104
9158
  writeLine(`ultraenv v${VERSION}`);
@@ -9129,14 +9183,28 @@ async function run28(argv) {
9129
9183
  const helpCmd2 = COMMAND_REGISTRY["help"];
9130
9184
  if (helpCmd2) {
9131
9185
  const entry = await helpCmd2();
9132
- return entry.runner(args, { config: config2.config, cwd: config2.cwd, colorEnabled: true, debug: config2.debug, quiet: config2.quiet, outputFormat: config2.outputFormat });
9186
+ return entry.runner(args, {
9187
+ config: config2.config,
9188
+ cwd: config2.cwd,
9189
+ colorEnabled: true,
9190
+ debug: config2.debug,
9191
+ quiet: config2.quiet,
9192
+ outputFormat: config2.outputFormat
9193
+ });
9133
9194
  }
9134
9195
  return 1;
9135
9196
  }
9136
9197
  const helpCmd = COMMAND_REGISTRY["help"];
9137
9198
  if (helpCmd) {
9138
9199
  const entry = await helpCmd();
9139
- return entry.runner(args, { config: config2.config, cwd: config2.cwd, colorEnabled: true, debug: config2.debug, quiet: config2.quiet, outputFormat: config2.outputFormat });
9200
+ return entry.runner(args, {
9201
+ config: config2.config,
9202
+ cwd: config2.cwd,
9203
+ colorEnabled: true,
9204
+ debug: config2.debug,
9205
+ quiet: config2.quiet,
9206
+ outputFormat: config2.outputFormat
9207
+ });
9140
9208
  }
9141
9209
  return 1;
9142
9210
  }
@@ -9176,12 +9244,18 @@ async function run28(argv) {
9176
9244
  } catch (error) {
9177
9245
  if (error instanceof UltraenvError) {
9178
9246
  if (outputFormat === "json") {
9179
- writeError(JSON.stringify({
9180
- error: true,
9181
- code: error.code,
9182
- message: error.message,
9183
- hint: error.hint
9184
- }, null, 2));
9247
+ writeError(
9248
+ JSON.stringify(
9249
+ {
9250
+ error: true,
9251
+ code: error.code,
9252
+ message: error.message,
9253
+ hint: error.hint
9254
+ },
9255
+ null,
9256
+ 2
9257
+ )
9258
+ );
9185
9259
  } else {
9186
9260
  writeError("");
9187
9261
  writeError(red(bold(` [${error.code}] ${error.message}`)));
@@ -9194,10 +9268,16 @@ async function run28(argv) {
9194
9268
  return 1;
9195
9269
  }
9196
9270
  if (outputFormat === "json") {
9197
- writeError(JSON.stringify({
9198
- error: true,
9199
- message: error instanceof Error ? error.message : String(error)
9200
- }, null, 2));
9271
+ writeError(
9272
+ JSON.stringify(
9273
+ {
9274
+ error: true,
9275
+ message: error instanceof Error ? error.message : String(error)
9276
+ },
9277
+ null,
9278
+ 2
9279
+ )
9280
+ );
9201
9281
  } else {
9202
9282
  writeError("");
9203
9283
  writeError(red(bold(" Unexpected error:")));