@solid-stack/mason 1.0.25 → 1.0.27

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
@@ -2,8 +2,8 @@
2
2
 
3
3
  var fs4 = require('fs');
4
4
  var path2 = require('path');
5
- var p15 = require('@clack/prompts');
6
- var pc15 = require('picocolors');
5
+ var p19 = require('@clack/prompts');
6
+ var pc14 = require('picocolors');
7
7
  var url = require('url');
8
8
  var child_process = require('child_process');
9
9
  var crypto = require('crypto');
@@ -33,8 +33,8 @@ function _interopNamespace(e) {
33
33
 
34
34
  var fs4__default = /*#__PURE__*/_interopDefault(fs4);
35
35
  var path2__default = /*#__PURE__*/_interopDefault(path2);
36
- var p15__namespace = /*#__PURE__*/_interopNamespace(p15);
37
- var pc15__default = /*#__PURE__*/_interopDefault(pc15);
36
+ var p19__namespace = /*#__PURE__*/_interopNamespace(p19);
37
+ var pc14__default = /*#__PURE__*/_interopDefault(pc14);
38
38
  var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
39
39
 
40
40
  // src/utils/formatting.ts
@@ -141,17 +141,17 @@ function writeFileSafely(absolutePath, content, options = {}) {
141
141
  function printGeneratedFiles(files, isDryRun = false) {
142
142
  console.log("");
143
143
  if (isDryRun) {
144
- p15__namespace.log.warn(pc15__default.default.yellow(pc15__default.default.bold("[DRY RUN PREVIEW] No files were written to disk.")));
144
+ p19__namespace.log.warn(pc14__default.default.yellow(pc14__default.default.bold("[DRY RUN PREVIEW] No files were written to disk.")));
145
145
  }
146
146
  for (const f of files) {
147
147
  if (f.action === "created") {
148
- p15__namespace.log.success(`${pc15__default.default.bold(f.relativePath)} ${pc15__default.default.dim("(created)")}`);
148
+ p19__namespace.log.success(`${pc14__default.default.bold(f.relativePath)} ${pc14__default.default.dim("(created)")}`);
149
149
  } else if (f.action === "overwritten") {
150
- p15__namespace.log.warn(`${pc15__default.default.bold(f.relativePath)} ${pc15__default.default.dim("(overwritten)")}`);
150
+ p19__namespace.log.warn(`${pc14__default.default.bold(f.relativePath)} ${pc14__default.default.dim("(overwritten)")}`);
151
151
  } else if (f.action === "skipped") {
152
- p15__namespace.log.info(`${pc15__default.default.dim(f.relativePath)} ${pc15__default.default.dim("(skipped - already exists, pass -o to overwrite)")}`);
152
+ p19__namespace.log.info(`${pc14__default.default.dim(f.relativePath)} ${pc14__default.default.dim("(skipped - already exists, pass -o to overwrite)")}`);
153
153
  } else {
154
- p15__namespace.log.info(`${pc15__default.default.bold(f.relativePath)} ${pc15__default.default.dim("(preview)")}`);
154
+ p19__namespace.log.info(`${pc14__default.default.bold(f.relativePath)} ${pc14__default.default.dim("(preview)")}`);
155
155
  }
156
156
  }
157
157
  }
@@ -353,23 +353,23 @@ var PromptCancelledError = class extends Error {
353
353
  }
354
354
  };
355
355
  function handleCancel(result) {
356
- if (p15__namespace.isCancel(result)) {
357
- p15__namespace.cancel("Operation cancelled.");
356
+ if (p19__namespace.isCancel(result)) {
357
+ p19__namespace.cancel("Operation cancelled.");
358
358
  throw new PromptCancelledError();
359
359
  }
360
360
  return result;
361
361
  }
362
362
  function printBanner() {
363
363
  console.log("");
364
- p15__namespace.intro(pc15__default.default.bgCyan(pc15__default.default.black(" @solid-stack/mason ")));
364
+ p19__namespace.intro(pc14__default.default.bgCyan(pc14__default.default.black(" @solid-stack/mason ")));
365
365
  }
366
366
  async function promptProperties(options = {}) {
367
367
  const properties = options.defaults ? [...options.defaults] : [];
368
368
  if (properties.length > 0) {
369
- const summary = properties.map((p18) => `${p18.name}: ${p18.type}${p18.optional ? "?" : ""}`).join(", ");
370
- p15__namespace.log.info(pc15__default.default.dim(`Pre-configured fields: ${summary}`));
369
+ const summary = properties.map((p22) => `${p22.name}: ${p22.type}${p22.optional ? "?" : ""}`).join(", ");
370
+ p19__namespace.log.info(pc14__default.default.dim(`Pre-configured fields: ${summary}`));
371
371
  const addMore = handleCancel(
372
- await p15__namespace.confirm({
372
+ await p19__namespace.confirm({
373
373
  message: "Would you like to add custom fields/properties?",
374
374
  initialValue: false
375
375
  })
@@ -378,10 +378,10 @@ async function promptProperties(options = {}) {
378
378
  return properties;
379
379
  }
380
380
  }
381
- p15__namespace.log.info(pc15__default.default.cyan("Enter properties (leave name blank when finished):"));
381
+ p19__namespace.log.info(pc14__default.default.cyan("Enter properties (leave name blank when finished):"));
382
382
  while (true) {
383
383
  const name = handleCancel(
384
- await p15__namespace.text({
384
+ await p19__namespace.text({
385
385
  message: "Property name (or press Enter to finish):",
386
386
  placeholder: "e.g. title, email, status"
387
387
  })
@@ -390,7 +390,7 @@ async function promptProperties(options = {}) {
390
390
  break;
391
391
  }
392
392
  const type = handleCancel(
393
- await p15__namespace.select({
393
+ await p19__namespace.select({
394
394
  message: `Type for property "${name.trim()}":`,
395
395
  options: [
396
396
  { value: "string", label: "string" },
@@ -407,7 +407,7 @@ async function promptProperties(options = {}) {
407
407
  let finalType = type;
408
408
  if (type === "custom") {
409
409
  finalType = handleCancel(
410
- await p15__namespace.text({
410
+ await p19__namespace.text({
411
411
  message: `Enter custom type for "${name.trim()}":`,
412
412
  placeholder: "e.g. UserRole, string | null",
413
413
  validate: (val) => val && val.trim() ? void 0 : "Type cannot be empty"
@@ -415,7 +415,7 @@ async function promptProperties(options = {}) {
415
415
  );
416
416
  }
417
417
  const optional = handleCancel(
418
- await p15__namespace.confirm({
418
+ await p19__namespace.confirm({
419
419
  message: `Is "${name.trim()}" optional?`,
420
420
  initialValue: false
421
421
  })
@@ -425,8 +425,8 @@ async function promptProperties(options = {}) {
425
425
  type: finalType.trim(),
426
426
  optional
427
427
  });
428
- p15__namespace.log.success(
429
- pc15__default.default.green(`Added: ${name.trim()}${optional ? "?" : ""}: ${finalType.trim()}`)
428
+ p19__namespace.log.success(
429
+ pc14__default.default.green(`Added: ${name.trim()}${optional ? "?" : ""}: ${finalType.trim()}`)
430
430
  );
431
431
  }
432
432
  return properties;
@@ -634,8 +634,8 @@ function getMissingNpmPackages(projectRoot, requiredPackages) {
634
634
  ...Object.keys(pkg.devDependencies || {}),
635
635
  ...Object.keys(pkg.peerDependencies || {})
636
636
  ]);
637
- return requiredPackages.filter((p18) => {
638
- const nameOnly = p18.startsWith("@") ? `@${p18.slice(1).split("@")[0] || ""}` : p18.split("@")[0] || p18;
637
+ return requiredPackages.filter((p22) => {
638
+ const nameOnly = p22.startsWith("@") ? `@${p22.slice(1).split("@")[0] || ""}` : p22.split("@")[0] || p22;
639
639
  return !installed.has(nameOnly);
640
640
  });
641
641
  } catch {
@@ -660,7 +660,7 @@ function installNpmPackages(projectRoot, packages, pm) {
660
660
  installCmd = `npm install ${packages.join(" ")}`;
661
661
  break;
662
662
  }
663
- p15__namespace.log.info(`Installing missing dependencies with ${manager}: ${pc15__default.default.cyan(packages.join(", "))}`);
663
+ p19__namespace.log.info(`Installing missing dependencies with ${manager}: ${pc14__default.default.cyan(packages.join(", "))}`);
664
664
  child_process.execSync(installCmd, {
665
665
  cwd: projectRoot,
666
666
  stdio: "inherit"
@@ -862,7 +862,7 @@ function generateInterfaceCode(ifaceName, kind = "abstractClass", entityName, me
862
862
  const idKey = `${entityKey}Id`;
863
863
  const listKey = `${entityKey}s`;
864
864
  const formattedCustomMethods = customMethods.map((m) => {
865
- const params = m.params && m.params.length > 0 ? m.params.map((p18) => `${p18.name}: ${p18.type}`).join("; ") : "";
865
+ const params = m.params && m.params.length > 0 ? m.params.map((p22) => `${p22.name}: ${p22.type}`).join("; ") : "";
866
866
  const returnType = m.returnType ? `Promise<${m.returnType}>` : "Promise<void>";
867
867
  return {
868
868
  name: m.name,
@@ -1443,22 +1443,22 @@ function generateUseCaseCode(useCaseName, dependencies = [], inputProps = [], ou
1443
1443
  from: /^I[A-Z]/.test(dep) ? `../domain/${dep}.js` : `./${dep}.js`
1444
1444
  }));
1445
1445
  const domainTypesToImport = new Set(domainImports);
1446
- for (const p18 of [...inputProps, ...outputProps]) {
1447
- const rawType = p18.type.trim();
1446
+ for (const p22 of [...inputProps, ...outputProps]) {
1447
+ const rawType = p22.type.trim();
1448
1448
  const baseType = rawType.replace(/\[\]$/, "").trim();
1449
1449
  if (!primitiveTypes.has(baseType) && /^[A-Z][A-Za-z0-9_]*$/.test(baseType) && !dependencies.includes(baseType)) {
1450
1450
  domainTypesToImport.add(baseType);
1451
1451
  }
1452
1452
  }
1453
- const formattedInputProps = inputProps.map((p18) => ({
1454
- name: p18.name,
1455
- optional: p18.optional,
1456
- type: p18.optional && !p18.type.includes("undefined") ? `${p18.type} | undefined` : p18.type
1453
+ const formattedInputProps = inputProps.map((p22) => ({
1454
+ name: p22.name,
1455
+ optional: p22.optional,
1456
+ type: p22.optional && !p22.type.includes("undefined") ? `${p22.type} | undefined` : p22.type
1457
1457
  }));
1458
- const formattedOutputProps = outputProps.map((p18) => ({
1459
- name: p18.name,
1460
- optional: p18.optional,
1461
- type: p18.optional && !p18.type.includes("undefined") ? `${p18.type} | undefined` : p18.type
1458
+ const formattedOutputProps = outputProps.map((p22) => ({
1459
+ name: p22.name,
1460
+ optional: p22.optional,
1461
+ type: p22.optional && !p22.type.includes("undefined") ? `${p22.type} | undefined` : p22.type
1462
1462
  }));
1463
1463
  const formattedDeps = dependencies.map((dep) => ({
1464
1464
  key: toCamelCase(dep),
@@ -2133,7 +2133,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2133
2133
  }
2134
2134
  if (!name) {
2135
2135
  name = handleCancel(
2136
- await p15__namespace.text({
2136
+ await p19__namespace.text({
2137
2137
  message: "What is the feature name?",
2138
2138
  placeholder: "e.g. users, auth, orders, billing",
2139
2139
  validate: (val) => {
@@ -2149,7 +2149,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2149
2149
  let targetDirRel = defaultDir;
2150
2150
  if (!flags.yes && !flags.target && !flags.dest) {
2151
2151
  targetDirRel = handleCancel(
2152
- await p15__namespace.text({
2152
+ await p19__namespace.text({
2153
2153
  message: "Target directory for the feature:",
2154
2154
  initialValue: defaultDir,
2155
2155
  defaultValue: defaultDir
@@ -2171,14 +2171,14 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2171
2171
  const customUseCases = [];
2172
2172
  if (!flags.yes) {
2173
2173
  includeExpress = handleCancel(
2174
- await p15__namespace.confirm({
2174
+ await p19__namespace.confirm({
2175
2175
  message: "Include Express Presentation layer (pxExpress routes & handlers)?",
2176
2176
  initialValue: true
2177
2177
  })
2178
2178
  );
2179
2179
  if (includeExpress) {
2180
2180
  routePath = handleCancel(
2181
- await p15__namespace.text({
2181
+ await p19__namespace.text({
2182
2182
  message: "Express route prefix:",
2183
2183
  initialValue: `/${normalizedName}`,
2184
2184
  defaultValue: `/${normalizedName}`
@@ -2186,14 +2186,14 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2186
2186
  ).trim();
2187
2187
  }
2188
2188
  includeDomain = handleCancel(
2189
- await p15__namespace.confirm({
2189
+ await p19__namespace.confirm({
2190
2190
  message: "Include Domain Entity/Entities?",
2191
2191
  initialValue: true
2192
2192
  })
2193
2193
  );
2194
2194
  if (includeDomain) {
2195
2195
  const domainInput = handleCancel(
2196
- await p15__namespace.text({
2196
+ await p19__namespace.text({
2197
2197
  message: "Domain entity name(s) (comma-separated):",
2198
2198
  initialValue: defaultEntity,
2199
2199
  defaultValue: defaultEntity,
@@ -2212,21 +2212,21 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2212
2212
  entityNames = [defaultEntity];
2213
2213
  }
2214
2214
  includeInterface = handleCancel(
2215
- await p15__namespace.confirm({
2215
+ await p19__namespace.confirm({
2216
2216
  message: `Include Domain Repository interface(s) for ${entityNames.join(", ")}?`,
2217
2217
  initialValue: true
2218
2218
  })
2219
2219
  );
2220
2220
  if (includeInterface) {
2221
2221
  includeInfra = handleCancel(
2222
- await p15__namespace.confirm({
2222
+ await p19__namespace.confirm({
2223
2223
  message: `Include Infrastructure Stub implementation(s) for ${entityNames.join(", ")}?`,
2224
2224
  initialValue: true
2225
2225
  })
2226
2226
  );
2227
2227
  }
2228
2228
  includeUseCase = handleCancel(
2229
- await p15__namespace.confirm({
2229
+ await p19__namespace.confirm({
2230
2230
  message: "Include Domain Use Cases?",
2231
2231
  initialValue: true
2232
2232
  })
@@ -2240,7 +2240,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2240
2240
  { value: "delete", label: "Delete (Delete<Entity>)", hint: "DELETE /:id" }
2241
2241
  ];
2242
2242
  crudOperations = handleCancel(
2243
- await p15__namespace.multiselect({
2243
+ await p19__namespace.multiselect({
2244
2244
  message: "Select standard CRUD use cases to generate:",
2245
2245
  options: crudChoices,
2246
2246
  initialValues: ["create", "read", "list", "update", "delete"],
@@ -2248,13 +2248,13 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2248
2248
  })
2249
2249
  );
2250
2250
  includeTests = handleCancel(
2251
- await p15__namespace.confirm({
2251
+ await p19__namespace.confirm({
2252
2252
  message: "Generate Vitest unit tests for use cases?",
2253
2253
  initialValue: true
2254
2254
  })
2255
2255
  );
2256
2256
  const wantCustom = handleCancel(
2257
- await p15__namespace.confirm({
2257
+ await p19__namespace.confirm({
2258
2258
  message: "Do you want to add any custom use cases to this feature?",
2259
2259
  initialValue: false
2260
2260
  })
@@ -2264,7 +2264,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2264
2264
  const availableIfaces = entityNames.map((e) => `I${e}Repository`);
2265
2265
  while (addMore) {
2266
2266
  const customName = handleCancel(
2267
- await p15__namespace.text({
2267
+ await p19__namespace.text({
2268
2268
  message: "Custom Use Case name:",
2269
2269
  placeholder: "e.g. ResetPassword, VerifyEmail, AssignRole",
2270
2270
  validate: (v) => v && v.trim() ? void 0 : "Use Case name cannot be empty"
@@ -2274,7 +2274,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2274
2274
  let selectedDeps = [];
2275
2275
  if (availableIfaces.length > 0) {
2276
2276
  selectedDeps = handleCancel(
2277
- await p15__namespace.multiselect({
2277
+ await p19__namespace.multiselect({
2278
2278
  message: `Select domain interfaces to inject into ${customUcName}:`,
2279
2279
  options: availableIfaces.map((i) => ({ value: i, label: i })),
2280
2280
  required: false
@@ -2283,7 +2283,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2283
2283
  }
2284
2284
  let customInputProps = [];
2285
2285
  const hasInput = handleCancel(
2286
- await p15__namespace.confirm({
2286
+ await p19__namespace.confirm({
2287
2287
  message: `Does ${customUcName} accept input arguments?`,
2288
2288
  initialValue: true
2289
2289
  })
@@ -2294,7 +2294,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2294
2294
  }
2295
2295
  let customOutputProps = [];
2296
2296
  const hasCustomOutput = handleCancel(
2297
- await p15__namespace.confirm({
2297
+ await p19__namespace.confirm({
2298
2298
  message: `Does ${customUcName} return custom output data?`,
2299
2299
  initialValue: false
2300
2300
  })
@@ -2304,7 +2304,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2304
2304
  });
2305
2305
  }
2306
2306
  const customIncludeTest = handleCancel(
2307
- await p15__namespace.confirm({
2307
+ await p19__namespace.confirm({
2308
2308
  message: `Generate Vitest unit test for ${customUcName}?`,
2309
2309
  initialValue: true
2310
2310
  })
@@ -2314,14 +2314,14 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2314
2314
  let customHttpPath = `/${toKebabCase(customUcName)}`;
2315
2315
  if (includeExpress) {
2316
2316
  customCreateHttp = handleCancel(
2317
- await p15__namespace.confirm({
2317
+ await p19__namespace.confirm({
2318
2318
  message: `Generate a matching ExpressRoute HTTP handler for ${customUcName}?`,
2319
2319
  initialValue: true
2320
2320
  })
2321
2321
  );
2322
2322
  if (customCreateHttp) {
2323
2323
  customHttpMethod = handleCancel(
2324
- await p15__namespace.select({
2324
+ await p19__namespace.select({
2325
2325
  message: "HTTP method for route:",
2326
2326
  options: [
2327
2327
  { value: "post", label: "POST" },
@@ -2334,7 +2334,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2334
2334
  })
2335
2335
  );
2336
2336
  customHttpPath = handleCancel(
2337
- await p15__namespace.text({
2337
+ await p19__namespace.text({
2338
2338
  message: "Route subpath (relative to feature prefix):",
2339
2339
  initialValue: `/${toKebabCase(customUcName)}`,
2340
2340
  defaultValue: `/${toKebabCase(customUcName)}`
@@ -2355,7 +2355,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2355
2355
  validationFields: customInputProps
2356
2356
  });
2357
2357
  addMore = handleCancel(
2358
- await p15__namespace.confirm({
2358
+ await p19__namespace.confirm({
2359
2359
  message: "Add another custom use case?",
2360
2360
  initialValue: false
2361
2361
  })
@@ -2364,7 +2364,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2364
2364
  }
2365
2365
  }
2366
2366
  includeDiProvider = handleCancel(
2367
- await p15__namespace.confirm({
2367
+ await p19__namespace.confirm({
2368
2368
  message: "Generate / update feature DI provider (diProvider.ts)?",
2369
2369
  initialValue: true
2370
2370
  })
@@ -2376,8 +2376,8 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2376
2376
  entityNames = [defaultEntity];
2377
2377
  }
2378
2378
  }
2379
- const s = p15__namespace.spinner();
2380
- s.start(`Generating feature '${pc15__default.default.cyan(normalizedName)}'...`);
2379
+ const s = p19__namespace.spinner();
2380
+ s.start(`Generating feature '${pc14__default.default.cyan(normalizedName)}'...`);
2381
2381
  const options = {
2382
2382
  name: normalizedName,
2383
2383
  projectRoot,
@@ -2423,8 +2423,8 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2423
2423
  }
2424
2424
  s.stop("Feature scaffolded successfully!");
2425
2425
  printGeneratedFiles(files, options.dryRun);
2426
- p15__namespace.outro(
2427
- pc15__default.default.green(
2426
+ p19__namespace.outro(
2427
+ pc14__default.default.green(
2428
2428
  `\u2713 Feature '${normalizedName}' initialized in ${path2__default.default.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2429
2429
  )
2430
2430
  );
@@ -2538,7 +2538,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2538
2538
  }
2539
2539
  if (!name) {
2540
2540
  name = handleCancel(
2541
- await p15__namespace.text({
2541
+ await p19__namespace.text({
2542
2542
  message: "What is the shared module name?",
2543
2543
  placeholder: "e.g. hasher, time, uuid, cache, logger",
2544
2544
  validate: (val) => {
@@ -2554,7 +2554,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2554
2554
  let targetDirRel = defaultDir;
2555
2555
  if (!flags.yes && !flags.target && !flags.dest) {
2556
2556
  targetDirRel = handleCancel(
2557
- await p15__namespace.text({
2557
+ await p19__namespace.text({
2558
2558
  message: "Target directory for the shared module:",
2559
2559
  initialValue: defaultDir,
2560
2560
  defaultValue: defaultDir
@@ -2566,21 +2566,21 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2566
2566
  let includeStub = true;
2567
2567
  if (!flags.yes) {
2568
2568
  description = handleCancel(
2569
- await p15__namespace.text({
2569
+ await p19__namespace.text({
2570
2570
  message: "Module description (optional):",
2571
2571
  placeholder: "e.g. In-memory caching and Redis port abstraction",
2572
2572
  initialValue: ""
2573
2573
  })
2574
2574
  ).trim();
2575
2575
  includeStub = handleCancel(
2576
- await p15__namespace.confirm({
2576
+ await p19__namespace.confirm({
2577
2577
  message: "Include stub implementation in infrastructure/?",
2578
2578
  initialValue: true
2579
2579
  })
2580
2580
  );
2581
2581
  }
2582
- const s = p15__namespace.spinner();
2583
- s.start(`Generating shared module '${pc15__default.default.cyan(normalizedName)}'...`);
2582
+ const s = p19__namespace.spinner();
2583
+ s.start(`Generating shared module '${pc14__default.default.cyan(normalizedName)}'...`);
2584
2584
  const files = generateShared({
2585
2585
  name: normalizedName,
2586
2586
  description,
@@ -2593,8 +2593,8 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2593
2593
  });
2594
2594
  s.stop("Shared module generated successfully!");
2595
2595
  printGeneratedFiles(files, Boolean(flags.dryRun));
2596
- p15__namespace.outro(
2597
- pc15__default.default.green(
2596
+ p19__namespace.outro(
2597
+ pc14__default.default.green(
2598
2598
  `\u2713 Shared module '${normalizedName}' initialized in ${path2__default.default.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2599
2599
  )
2600
2600
  );
@@ -2608,14 +2608,14 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2608
2608
  const featureOptions = existingFeatures.map((f) => ({ value: f, label: f }));
2609
2609
  featureOptions.push({ value: "__custom__", label: "\u270F\uFE0F Enter custom feature name..." });
2610
2610
  const selected = handleCancel(
2611
- await p15__namespace.select({
2611
+ await p19__namespace.select({
2612
2612
  message: "Select target feature:",
2613
2613
  options: featureOptions
2614
2614
  })
2615
2615
  );
2616
2616
  if (selected === "__custom__") {
2617
2617
  feature = handleCancel(
2618
- await p15__namespace.text({
2618
+ await p19__namespace.text({
2619
2619
  message: "Enter feature name:",
2620
2620
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2621
2621
  })
@@ -2625,7 +2625,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2625
2625
  }
2626
2626
  } else {
2627
2627
  feature = handleCancel(
2628
- await p15__namespace.text({
2628
+ await p19__namespace.text({
2629
2629
  message: "Enter target feature name:",
2630
2630
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2631
2631
  })
@@ -2636,7 +2636,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2636
2636
  let name = useCaseNameArg?.trim();
2637
2637
  if (!name) {
2638
2638
  name = handleCancel(
2639
- await p15__namespace.text({
2639
+ await p19__namespace.text({
2640
2640
  message: "Use Case name:",
2641
2641
  placeholder: "e.g. CreateUser, GetUser, CancelOrder",
2642
2642
  validate: (v) => v && v.trim() ? void 0 : "Use Case name cannot be empty"
@@ -2652,7 +2652,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2652
2652
  label: i.name
2653
2653
  }));
2654
2654
  selectedDeps = handleCancel(
2655
- await p15__namespace.multiselect({
2655
+ await p19__namespace.multiselect({
2656
2656
  message: "Select domain interfaces to inject into use case:",
2657
2657
  options: multiOptions,
2658
2658
  required: false
@@ -2667,7 +2667,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2667
2667
  let httpPath = "/";
2668
2668
  if (!flags.yes) {
2669
2669
  const hasInput = handleCancel(
2670
- await p15__namespace.confirm({
2670
+ await p19__namespace.confirm({
2671
2671
  message: "Does this use case accept input arguments?",
2672
2672
  initialValue: true
2673
2673
  })
@@ -2677,7 +2677,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2677
2677
  });
2678
2678
  }
2679
2679
  const hasCustomOutput = handleCancel(
2680
- await p15__namespace.confirm({
2680
+ await p19__namespace.confirm({
2681
2681
  message: "Does this use case return custom output data?",
2682
2682
  initialValue: false
2683
2683
  })
@@ -2687,20 +2687,20 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2687
2687
  });
2688
2688
  }
2689
2689
  includeTest = handleCancel(
2690
- await p15__namespace.confirm({
2690
+ await p19__namespace.confirm({
2691
2691
  message: "Generate Vitest unit test skeleton (.test.ts)?",
2692
2692
  initialValue: true
2693
2693
  })
2694
2694
  );
2695
2695
  createHttp = handleCancel(
2696
- await p15__namespace.confirm({
2696
+ await p19__namespace.confirm({
2697
2697
  message: "Generate a matching ExpressRoute HTTP handler?",
2698
2698
  initialValue: false
2699
2699
  })
2700
2700
  );
2701
2701
  if (createHttp) {
2702
2702
  httpMethod = handleCancel(
2703
- await p15__namespace.select({
2703
+ await p19__namespace.select({
2704
2704
  message: "HTTP method for route:",
2705
2705
  options: [
2706
2706
  { value: "post", label: "POST" },
@@ -2713,7 +2713,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2713
2713
  })
2714
2714
  );
2715
2715
  httpPath = handleCancel(
2716
- await p15__namespace.text({
2716
+ await p19__namespace.text({
2717
2717
  message: "Route subpath (relative to feature prefix):",
2718
2718
  initialValue: "/",
2719
2719
  defaultValue: "/"
@@ -2721,8 +2721,8 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2721
2721
  ).trim();
2722
2722
  }
2723
2723
  }
2724
- const s = p15__namespace.spinner();
2725
- s.start(`Generating use case '${pc15__default.default.cyan(ucName)}'...`);
2724
+ const s = p19__namespace.spinner();
2725
+ s.start(`Generating use case '${pc14__default.default.cyan(ucName)}'...`);
2726
2726
  const options = {
2727
2727
  name: ucName,
2728
2728
  feature,
@@ -2754,7 +2754,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2754
2754
  }
2755
2755
  s.stop("Use case generated successfully!");
2756
2756
  printGeneratedFiles(files, options.dryRun);
2757
- p15__namespace.outro(pc15__default.default.green(`Use case '${ucName}' created in feature '${feature}'!`));
2757
+ p19__namespace.outro(pc14__default.default.green(`Use case '${ucName}' created in feature '${feature}'!`));
2758
2758
  }
2759
2759
  async function runDomainCommand(domainNameArg, flags = {}) {
2760
2760
  const projectRoot = findProjectRoot();
@@ -2765,14 +2765,14 @@ async function runDomainCommand(domainNameArg, flags = {}) {
2765
2765
  const featureOptions = existingFeatures.map((f) => ({ value: f, label: f }));
2766
2766
  featureOptions.push({ value: "__custom__", label: "\u270F\uFE0F Enter custom feature name..." });
2767
2767
  const selected = handleCancel(
2768
- await p15__namespace.select({
2768
+ await p19__namespace.select({
2769
2769
  message: "Select target feature:",
2770
2770
  options: featureOptions
2771
2771
  })
2772
2772
  );
2773
2773
  if (selected === "__custom__") {
2774
2774
  feature = handleCancel(
2775
- await p15__namespace.text({
2775
+ await p19__namespace.text({
2776
2776
  message: "Enter feature name:",
2777
2777
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2778
2778
  })
@@ -2782,7 +2782,7 @@ async function runDomainCommand(domainNameArg, flags = {}) {
2782
2782
  }
2783
2783
  } else {
2784
2784
  feature = handleCancel(
2785
- await p15__namespace.text({
2785
+ await p19__namespace.text({
2786
2786
  message: "Enter target feature name:",
2787
2787
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2788
2788
  })
@@ -2793,7 +2793,7 @@ async function runDomainCommand(domainNameArg, flags = {}) {
2793
2793
  let name = domainNameArg?.trim();
2794
2794
  if (!name) {
2795
2795
  name = handleCancel(
2796
- await p15__namespace.text({
2796
+ await p19__namespace.text({
2797
2797
  message: "Domain model / entity name:",
2798
2798
  placeholder: "e.g. User, Order, Product, Address",
2799
2799
  validate: (v) => v && v.trim() ? void 0 : "Domain name cannot be empty"
@@ -2805,7 +2805,7 @@ async function runDomainCommand(domainNameArg, flags = {}) {
2805
2805
  let properties = [];
2806
2806
  if (!flags.yes) {
2807
2807
  kind = handleCancel(
2808
- await p15__namespace.select({
2808
+ await p19__namespace.select({
2809
2809
  message: "Select domain model type:",
2810
2810
  options: [
2811
2811
  { value: "interface", label: "TypeScript Interface (pure data structure)" },
@@ -2824,8 +2824,8 @@ async function runDomainCommand(domainNameArg, flags = {}) {
2824
2824
  defaults: kind === "valueObject" ? [{ name: "value", type: "string" }] : defaultProps
2825
2825
  });
2826
2826
  }
2827
- const s = p15__namespace.spinner();
2828
- s.start(`Generating domain model '${pc15__default.default.cyan(entityName)}'...`);
2827
+ const s = p19__namespace.spinner();
2828
+ s.start(`Generating domain model '${pc14__default.default.cyan(entityName)}'...`);
2829
2829
  const options = {
2830
2830
  name: entityName,
2831
2831
  feature,
@@ -2838,7 +2838,7 @@ async function runDomainCommand(domainNameArg, flags = {}) {
2838
2838
  const file = generateDomain(options);
2839
2839
  s.stop("Domain model generated successfully!");
2840
2840
  printGeneratedFiles([file], options.dryRun);
2841
- p15__namespace.outro(pc15__default.default.green(`Domain model '${entityName}' created in feature '${feature}'!`));
2841
+ p19__namespace.outro(pc14__default.default.green(`Domain model '${entityName}' created in feature '${feature}'!`));
2842
2842
  }
2843
2843
  async function runInfrastructureCommand(classNameArg, flags = {}) {
2844
2844
  const projectRoot = findProjectRoot();
@@ -2847,7 +2847,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2847
2847
  let feature = flags.feature?.trim();
2848
2848
  if (!flags.yes && !flags.global && !flags.feature) {
2849
2849
  scope = handleCancel(
2850
- await p15__namespace.select({
2850
+ await p19__namespace.select({
2851
2851
  message: "Where should this infrastructure implementation be placed?",
2852
2852
  options: [
2853
2853
  { value: "feature", label: "Feature-level (features/<feature>/infrastructure)" },
@@ -2862,14 +2862,14 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2862
2862
  const featureOptions = existingFeatures.map((f) => ({ value: f, label: f }));
2863
2863
  featureOptions.push({ value: "__custom__", label: "\u270F\uFE0F Enter custom feature name..." });
2864
2864
  const selected = handleCancel(
2865
- await p15__namespace.select({
2865
+ await p19__namespace.select({
2866
2866
  message: "Select target feature:",
2867
2867
  options: featureOptions
2868
2868
  })
2869
2869
  );
2870
2870
  if (selected === "__custom__") {
2871
2871
  feature = handleCancel(
2872
- await p15__namespace.text({
2872
+ await p19__namespace.text({
2873
2873
  message: "Enter feature name:",
2874
2874
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2875
2875
  })
@@ -2879,7 +2879,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2879
2879
  }
2880
2880
  } else {
2881
2881
  feature = handleCancel(
2882
- await p15__namespace.text({
2882
+ await p19__namespace.text({
2883
2883
  message: "Enter target feature name:",
2884
2884
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2885
2885
  })
@@ -2892,7 +2892,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2892
2892
  let name = classNameArg?.trim();
2893
2893
  if (!name) {
2894
2894
  name = handleCancel(
2895
- await p15__namespace.text({
2895
+ await p19__namespace.text({
2896
2896
  message: "Infrastructure class name:",
2897
2897
  placeholder: "e.g. StubUserRepository, PostgresUserRepository, S3FileStorage",
2898
2898
  validate: (v) => v && v.trim() ? void 0 : "Class name cannot be empty"
@@ -2911,7 +2911,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2911
2911
  (i) => className.toLowerCase().includes(removeInterfacePrefix(i.name).toLowerCase())
2912
2912
  );
2913
2913
  const ifaceChoice = handleCancel(
2914
- await p15__namespace.select({
2914
+ await p19__namespace.select({
2915
2915
  message: "Does this class implement a domain interface or abstract class?",
2916
2916
  options: [
2917
2917
  ...interfaces.map((i) => ({ value: i.name, label: i.name })),
@@ -2923,7 +2923,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2923
2923
  );
2924
2924
  if (ifaceChoice === "__custom__") {
2925
2925
  implementsInterface = handleCancel(
2926
- await p15__namespace.text({
2926
+ await p19__namespace.text({
2927
2927
  message: "Enter interface or abstract class name:",
2928
2928
  placeholder: "e.g. IUserRepository, BaseStorageAdapter",
2929
2929
  validate: (v) => v && v.trim() ? void 0 : "Name cannot be empty"
@@ -2934,14 +2934,14 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2934
2934
  }
2935
2935
  } else {
2936
2936
  const wantImpl = handleCancel(
2937
- await p15__namespace.confirm({
2937
+ await p19__namespace.confirm({
2938
2938
  message: "Does this class implement a domain interface or abstract class?",
2939
2939
  initialValue: false
2940
2940
  })
2941
2941
  );
2942
2942
  if (wantImpl) {
2943
2943
  implementsInterface = handleCancel(
2944
- await p15__namespace.text({
2944
+ await p19__namespace.text({
2945
2945
  message: "Enter interface or abstract class name:",
2946
2946
  placeholder: "e.g. IUserRepository, BaseStorageAdapter",
2947
2947
  validate: (v) => v && v.trim() ? void 0 : "Name cannot be empty"
@@ -2961,7 +2961,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2961
2961
  const allInterfaces = listDomainInterfaces(projectRoot);
2962
2962
  if (allInterfaces.length > 0) {
2963
2963
  const ifaceChoice = handleCancel(
2964
- await p15__namespace.select({
2964
+ await p19__namespace.select({
2965
2965
  message: "Does this class implement an interface or abstract class?",
2966
2966
  options: [
2967
2967
  ...allInterfaces.map((i) => ({ value: i.name, label: `${i.name} (${i.feature})` })),
@@ -2973,7 +2973,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2973
2973
  );
2974
2974
  if (ifaceChoice === "__custom__") {
2975
2975
  implementsInterface = handleCancel(
2976
- await p15__namespace.text({
2976
+ await p19__namespace.text({
2977
2977
  message: "Enter interface or abstract class name:",
2978
2978
  placeholder: "e.g. IAuthRepository",
2979
2979
  validate: (v) => v && v.trim() ? void 0 : "Name cannot be empty"
@@ -2986,7 +2986,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2986
2986
  }
2987
2987
  if (!flags.yes && !flags.kind) {
2988
2988
  kind = handleCancel(
2989
- await p15__namespace.select({
2989
+ await p19__namespace.select({
2990
2990
  message: "Select implementation kind:",
2991
2991
  options: [
2992
2992
  { value: "stub", label: "In-Memory Stub (with in-memory store and test helper methods)" },
@@ -2997,7 +2997,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2997
2997
  );
2998
2998
  if (scope === "feature" && feature && implementsInterface) {
2999
2999
  registerInProvider = handleCancel(
3000
- await p15__namespace.confirm({
3000
+ await p19__namespace.confirm({
3001
3001
  message: "Register this implementation in feature diProvider.ts?",
3002
3002
  initialValue: true
3003
3003
  })
@@ -3006,8 +3006,8 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
3006
3006
  } else if (flags.yes && scope === "feature" && feature && implementsInterface) {
3007
3007
  registerInProvider = !flags.noProvider;
3008
3008
  }
3009
- const s = p15__namespace.spinner();
3010
- s.start(`Generating infrastructure class '${pc15__default.default.cyan(className)}'...`);
3009
+ const s = p19__namespace.spinner();
3010
+ s.start(`Generating infrastructure class '${pc14__default.default.cyan(className)}'...`);
3011
3011
  const files = [];
3012
3012
  const options = {
3013
3013
  name: className,
@@ -3042,7 +3042,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
3042
3042
  }
3043
3043
  s.stop("Infrastructure class generated successfully!");
3044
3044
  printGeneratedFiles(files, options.dryRun);
3045
- p15__namespace.outro(pc15__default.default.green(`Infrastructure class '${className}' created!`));
3045
+ p19__namespace.outro(pc14__default.default.green(`Infrastructure class '${className}' created!`));
3046
3046
  }
3047
3047
  async function runInterfaceCommand(interfaceNameArg, flags = {}) {
3048
3048
  const projectRoot = findProjectRoot();
@@ -3053,14 +3053,14 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
3053
3053
  const featureOptions = existingFeatures.map((f) => ({ value: f, label: f }));
3054
3054
  featureOptions.push({ value: "__custom__", label: "\u270F\uFE0F Enter custom feature name..." });
3055
3055
  const selected = handleCancel(
3056
- await p15__namespace.select({
3056
+ await p19__namespace.select({
3057
3057
  message: "Select target feature:",
3058
3058
  options: featureOptions
3059
3059
  })
3060
3060
  );
3061
3061
  if (selected === "__custom__") {
3062
3062
  feature = handleCancel(
3063
- await p15__namespace.text({
3063
+ await p19__namespace.text({
3064
3064
  message: "Enter feature name:",
3065
3065
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
3066
3066
  })
@@ -3070,7 +3070,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
3070
3070
  }
3071
3071
  } else {
3072
3072
  feature = handleCancel(
3073
- await p15__namespace.text({
3073
+ await p19__namespace.text({
3074
3074
  message: "Enter target feature name:",
3075
3075
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
3076
3076
  })
@@ -3081,7 +3081,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
3081
3081
  let name = interfaceNameArg?.trim();
3082
3082
  if (!name) {
3083
3083
  name = handleCancel(
3084
- await p15__namespace.text({
3084
+ await p19__namespace.text({
3085
3085
  message: "Domain interface name:",
3086
3086
  placeholder: "e.g. IUserRepository, IPaymentService",
3087
3087
  validate: (v) => v && v.trim() ? void 0 : "Interface name cannot be empty"
@@ -3099,7 +3099,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
3099
3099
  if (!flags.yes) {
3100
3100
  if (existingEntities.length > 0) {
3101
3101
  const selectedEntity = handleCancel(
3102
- await p15__namespace.select({
3102
+ await p19__namespace.select({
3103
3103
  message: "Select domain entity associated with this interface:",
3104
3104
  options: [
3105
3105
  ...existingEntities.map((e) => ({ value: e.name, label: e.name })),
@@ -3110,7 +3110,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
3110
3110
  );
3111
3111
  if (selectedEntity === "__custom__") {
3112
3112
  entityName = handleCancel(
3113
- await p15__namespace.text({
3113
+ await p19__namespace.text({
3114
3114
  message: "Enter entity name:",
3115
3115
  defaultValue: removeInterfacePrefix(ifaceName).replace(/Repository$|Service$/, "")
3116
3116
  })
@@ -3120,7 +3120,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
3120
3120
  }
3121
3121
  }
3122
3122
  kind = handleCancel(
3123
- await p15__namespace.select({
3123
+ await p19__namespace.select({
3124
3124
  message: "Interface definition style:",
3125
3125
  options: [
3126
3126
  { value: "abstractClass", label: "Abstract Class (Recommended - acts as DI token & type)" },
@@ -3130,7 +3130,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
3130
3130
  })
3131
3131
  );
3132
3132
  methodsPreset = handleCancel(
3133
- await p15__namespace.select({
3133
+ await p19__namespace.select({
3134
3134
  message: "Method signature preset:",
3135
3135
  options: [
3136
3136
  { value: "crud", label: "Standard CRUD (GetById, List, Create, Update, Delete)" },
@@ -3140,22 +3140,22 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
3140
3140
  })
3141
3141
  );
3142
3142
  generateStub = handleCancel(
3143
- await p15__namespace.confirm({
3143
+ await p19__namespace.confirm({
3144
3144
  message: "Auto-generate Infrastructure Stub implementation?",
3145
3145
  initialValue: true
3146
3146
  })
3147
3147
  );
3148
3148
  if (generateStub) {
3149
3149
  registerInProvider = handleCancel(
3150
- await p15__namespace.confirm({
3150
+ await p19__namespace.confirm({
3151
3151
  message: "Auto-register interface & stub in feature diProvider.ts?",
3152
3152
  initialValue: true
3153
3153
  })
3154
3154
  );
3155
3155
  }
3156
3156
  }
3157
- const s = p15__namespace.spinner();
3158
- s.start(`Generating interface '${pc15__default.default.cyan(ifaceName)}'...`);
3157
+ const s = p19__namespace.spinner();
3158
+ s.start(`Generating interface '${pc14__default.default.cyan(ifaceName)}'...`);
3159
3159
  const files = [];
3160
3160
  const options = {
3161
3161
  name: ifaceName,
@@ -3204,7 +3204,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
3204
3204
  }
3205
3205
  s.stop("Interface generated successfully!");
3206
3206
  printGeneratedFiles(files, options.dryRun);
3207
- p15__namespace.outro(pc15__default.default.green(`Interface '${ifaceName}' created in feature '${feature}'!`));
3207
+ p19__namespace.outro(pc14__default.default.green(`Interface '${ifaceName}' created in feature '${feature}'!`));
3208
3208
  }
3209
3209
  async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3210
3210
  const projectRoot = findProjectRoot();
@@ -3215,14 +3215,14 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3215
3215
  const featureOptions = existingFeatures.map((f) => ({ value: f, label: f }));
3216
3216
  featureOptions.push({ value: "__custom__", label: "\u270F\uFE0F Enter custom feature name..." });
3217
3217
  const selected = handleCancel(
3218
- await p15__namespace.select({
3218
+ await p19__namespace.select({
3219
3219
  message: "Select target feature:",
3220
3220
  options: featureOptions
3221
3221
  })
3222
3222
  );
3223
3223
  if (selected === "__custom__") {
3224
3224
  feature = handleCancel(
3225
- await p15__namespace.text({
3225
+ await p19__namespace.text({
3226
3226
  message: "Enter feature name:",
3227
3227
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
3228
3228
  })
@@ -3232,7 +3232,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3232
3232
  }
3233
3233
  } else {
3234
3234
  feature = handleCancel(
3235
- await p15__namespace.text({
3235
+ await p19__namespace.text({
3236
3236
  message: "Enter target feature name:",
3237
3237
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
3238
3238
  })
@@ -3243,7 +3243,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3243
3243
  let name = handlerNameArg?.trim();
3244
3244
  if (!name) {
3245
3245
  name = handleCancel(
3246
- await p15__namespace.text({
3246
+ await p19__namespace.text({
3247
3247
  message: "HTTP Route Handler class name:",
3248
3248
  placeholder: "e.g. CreateUserHttp, GetUserHttp, HealthHttp",
3249
3249
  validate: (v) => v && v.trim() ? void 0 : "Handler name cannot be empty"
@@ -3262,7 +3262,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3262
3262
  let validationFields = [];
3263
3263
  if (!flags.yes) {
3264
3264
  method = handleCancel(
3265
- await p15__namespace.select({
3265
+ await p19__namespace.select({
3266
3266
  message: "HTTP Method:",
3267
3267
  options: [
3268
3268
  { value: "get", label: "GET" },
@@ -3276,7 +3276,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3276
3276
  );
3277
3277
  const defaultPath = method === "get" ? "/" : "/";
3278
3278
  subPath = handleCancel(
3279
- await p15__namespace.text({
3279
+ await p19__namespace.text({
3280
3280
  message: "Route subpath (relative to feature prefix):",
3281
3281
  initialValue: defaultPath,
3282
3282
  defaultValue: defaultPath
@@ -3287,7 +3287,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3287
3287
  const ucOptions = useCases.map((u) => ({ value: u.name, label: u.name }));
3288
3288
  ucOptions.push({ value: "__none__", label: "None / Standalone Handler" });
3289
3289
  const chosenUc = handleCancel(
3290
- await p15__namespace.select({
3290
+ await p19__namespace.select({
3291
3291
  message: "Connect this handler to a domain Use Case?",
3292
3292
  options: ucOptions,
3293
3293
  initialValue: ucOptions[0]?.value
@@ -3298,7 +3298,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3298
3298
  }
3299
3299
  }
3300
3300
  includeValidation = handleCancel(
3301
- await p15__namespace.confirm({
3301
+ await p19__namespace.confirm({
3302
3302
  message: "Include Zod inbound request validation?",
3303
3303
  initialValue: method !== "delete"
3304
3304
  })
@@ -3306,7 +3306,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3306
3306
  if (includeValidation) {
3307
3307
  const defaultSource = method === "get" ? "query" : "body";
3308
3308
  validationSource = handleCancel(
3309
- await p15__namespace.select({
3309
+ await p19__namespace.select({
3310
3310
  message: "Validation data source:",
3311
3311
  options: [
3312
3312
  { value: "body", label: "req.body (for POST / PUT / PATCH payloads)" },
@@ -3320,8 +3320,8 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3320
3320
  });
3321
3321
  }
3322
3322
  }
3323
- const s = p15__namespace.spinner();
3324
- s.start(`Generating HTTP handler '${pc15__default.default.cyan(className)}'...`);
3323
+ const s = p19__namespace.spinner();
3324
+ s.start(`Generating HTTP handler '${pc14__default.default.cyan(className)}'...`);
3325
3325
  const options = {
3326
3326
  name: className,
3327
3327
  feature,
@@ -3339,7 +3339,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3339
3339
  const files = generateHttpHandler(options);
3340
3340
  s.stop("HTTP handler generated successfully!");
3341
3341
  printGeneratedFiles(files, options.dryRun);
3342
- p15__namespace.outro(pc15__default.default.green(`HTTP handler '${className}' created in feature '${feature}'!`));
3342
+ p19__namespace.outro(pc14__default.default.green(`HTTP handler '${className}' created in feature '${feature}'!`));
3343
3343
  }
3344
3344
  function generateInjectableCode(className, dependencies = [], methods = [], implementsInterface) {
3345
3345
  const formattedDeps = dependencies.map((dep) => ({
@@ -3349,7 +3349,7 @@ function generateInjectableCode(className, dependencies = [], methods = [], impl
3349
3349
  const formattedMethods = methods.map((m) => {
3350
3350
  const isAsync = m.async !== false;
3351
3351
  const retType = m.returnType ? isAsync ? `Promise<${m.returnType}>` : m.returnType : isAsync ? "Promise<void>" : "void";
3352
- const params = m.params && m.params.length > 0 ? m.params.map((p18) => `${p18.name}: ${p18.type}`).join(", ") : "";
3352
+ const params = m.params && m.params.length > 0 ? m.params.map((p22) => `${p22.name}: ${p22.type}`).join(", ") : "";
3353
3353
  return {
3354
3354
  name: m.name,
3355
3355
  isAsync,
@@ -3419,7 +3419,7 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3419
3419
  let name = classNameArg?.trim();
3420
3420
  if (!name) {
3421
3421
  name = handleCancel(
3422
- await p15__namespace.text({
3422
+ await p19__namespace.text({
3423
3423
  message: "Injectable class name:",
3424
3424
  placeholder: "e.g. PasswordHasher, TokenService, UserTransformer",
3425
3425
  validate: (v) => v && v.trim() ? void 0 : "Class name cannot be empty"
@@ -3432,7 +3432,7 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3432
3432
  let customPath;
3433
3433
  if (!flags.yes) {
3434
3434
  location = handleCancel(
3435
- await p15__namespace.select({
3435
+ await p19__namespace.select({
3436
3436
  message: "Select target architectural location:",
3437
3437
  options: [
3438
3438
  { value: "feature-service", label: "Feature Service (features/<feature>/services/)" },
@@ -3450,14 +3450,14 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3450
3450
  const featureOptions = existingFeatures.map((f) => ({ value: f, label: f }));
3451
3451
  featureOptions.push({ value: "__custom__", label: "\u270F\uFE0F Enter custom feature name..." });
3452
3452
  const selected = handleCancel(
3453
- await p15__namespace.select({
3453
+ await p19__namespace.select({
3454
3454
  message: "Select target feature:",
3455
3455
  options: featureOptions
3456
3456
  })
3457
3457
  );
3458
3458
  if (selected === "__custom__") {
3459
3459
  feature = handleCancel(
3460
- await p15__namespace.text({
3460
+ await p19__namespace.text({
3461
3461
  message: "Enter feature name:",
3462
3462
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
3463
3463
  })
@@ -3467,7 +3467,7 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3467
3467
  }
3468
3468
  } else {
3469
3469
  feature = handleCancel(
3470
- await p15__namespace.text({
3470
+ await p19__namespace.text({
3471
3471
  message: "Enter target feature name:",
3472
3472
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
3473
3473
  })
@@ -3477,7 +3477,7 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3477
3477
  feature = toCamelCase(feature);
3478
3478
  } else if (location === "custom") {
3479
3479
  customPath = handleCancel(
3480
- await p15__namespace.text({
3480
+ await p19__namespace.text({
3481
3481
  message: "Enter destination directory path:",
3482
3482
  placeholder: "e.g. src/services or lib/utils",
3483
3483
  validate: (v) => v && v.trim() ? void 0 : "Path cannot be empty"
@@ -3488,14 +3488,14 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3488
3488
  let generateInterface2 = false;
3489
3489
  if (!flags.yes) {
3490
3490
  generateInterface2 = handleCancel(
3491
- await p15__namespace.confirm({
3491
+ await p19__namespace.confirm({
3492
3492
  message: `Generate abstract class interface (I${className}) as runtime DI token?`,
3493
3493
  initialValue: false
3494
3494
  })
3495
3495
  );
3496
3496
  }
3497
- const s = p15__namespace.spinner();
3498
- s.start(`Generating injectable '${pc15__default.default.cyan(className)}'...`);
3497
+ const s = p19__namespace.spinner();
3498
+ s.start(`Generating injectable '${pc14__default.default.cyan(className)}'...`);
3499
3499
  const options = {
3500
3500
  name: className,
3501
3501
  feature,
@@ -3509,17 +3509,17 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3509
3509
  const files = generateInjectable(options);
3510
3510
  s.stop("Injectable class generated successfully!");
3511
3511
  printGeneratedFiles(files, options.dryRun);
3512
- p15__namespace.outro(pc15__default.default.green(`Injectable '${className}' created successfully!`));
3512
+ p19__namespace.outro(pc14__default.default.green(`Injectable '${className}' created successfully!`));
3513
3513
  }
3514
- async function runEnvCommand(flags = {}) {
3514
+ async function runEnvInit(flags = {}) {
3515
3515
  const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3516
- const s = p15__namespace.spinner();
3516
+ const s = p19__namespace.spinner();
3517
3517
  s.start("Scanning for .example environment files...");
3518
3518
  const files = fs4__default.default.readdirSync(projectRoot);
3519
3519
  const exampleFiles = files.filter((file) => file.startsWith(".env") && file.endsWith(".example")).sort();
3520
3520
  if (exampleFiles.length === 0) {
3521
3521
  s.stop("No .example files found.");
3522
- p15__namespace.log.info(pc15__default.default.yellow(`No files matching '.env*.example' were found in ${projectRoot}`));
3522
+ p19__namespace.log.info(pc14__default.default.yellow(`No files matching '.env*.example' were found in ${projectRoot}`));
3523
3523
  return [];
3524
3524
  }
3525
3525
  s.message(`Found ${exampleFiles.length} template(s). Generating...`);
@@ -3528,25 +3528,669 @@ async function runEnvCommand(flags = {}) {
3528
3528
  const sourcePath = path2__default.default.join(projectRoot, exampleFile);
3529
3529
  const targetFile = exampleFile.replace(/\.example$/, "");
3530
3530
  const targetPath = path2__default.default.join(projectRoot, targetFile);
3531
+ let overwrite = flags.overwrite;
3532
+ if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs4__default.default.existsSync(targetPath)) {
3533
+ overwrite = await p19__namespace.confirm({
3534
+ message: `${targetFile} already exists. Overwrite?`,
3535
+ initialValue: false
3536
+ });
3537
+ if (p19__namespace.isCancel(overwrite)) {
3538
+ p19__namespace.cancel("Operation cancelled.");
3539
+ process.exit(0);
3540
+ }
3541
+ }
3531
3542
  const content = fs4__default.default.readFileSync(sourcePath, "utf-8");
3532
3543
  const genFile = writeFileSafely(targetPath, content, {
3533
3544
  projectRoot,
3534
3545
  dryRun: Boolean(flags.dryRun),
3535
- overwrite: Boolean(flags.overwrite)
3546
+ overwrite: Boolean(overwrite)
3536
3547
  });
3537
3548
  generatedFiles.push(genFile);
3538
3549
  }
3539
3550
  s.stop("Environment files processed!");
3540
3551
  printGeneratedFiles(generatedFiles, Boolean(flags.dryRun));
3541
- p15__namespace.outro(pc15__default.default.green("\u2713 Local environment files are ready!"));
3552
+ p19__namespace.outro(pc14__default.default.green("\u2713 Local environment files are ready!"));
3542
3553
  return generatedFiles;
3543
3554
  }
3555
+ var runEnvCommand = runEnvInit;
3556
+ var EnvEditor = class {
3557
+ lines;
3558
+ filePath;
3559
+ constructor(filePath) {
3560
+ this.filePath = filePath;
3561
+ this.lines = fs4__default.default.existsSync(filePath) ? fs4__default.default.readFileSync(filePath, "utf-8").split(/\r?\n/) : [];
3562
+ }
3563
+ getLines() {
3564
+ return [...this.lines];
3565
+ }
3566
+ getKeys() {
3567
+ return this.lines.filter((line) => line.trim() && !line.trim().startsWith("#")).map((line) => {
3568
+ const eqIdx = line.indexOf("=");
3569
+ return eqIdx !== -1 ? line.substring(0, eqIdx).trim() : line.trim();
3570
+ }).filter(Boolean);
3571
+ }
3572
+ getValue(key) {
3573
+ const line = this.lines.find((l) => {
3574
+ const trimmed = l.trim();
3575
+ if (trimmed.startsWith("#") || !trimmed) return false;
3576
+ const eqIdx = l.indexOf("=");
3577
+ const k = eqIdx !== -1 ? l.substring(0, eqIdx).trim() : l.trim();
3578
+ return k === key;
3579
+ });
3580
+ if (!line) return null;
3581
+ const eqIndex = line.indexOf("=");
3582
+ return eqIndex !== -1 ? line.substring(eqIndex + 1).trim() : "";
3583
+ }
3584
+ has(key) {
3585
+ return this.getKeys().includes(key);
3586
+ }
3587
+ set(key, value) {
3588
+ const newLine = `${key}=${value}`;
3589
+ const index = this.lines.findIndex((l) => {
3590
+ const trimmed = l.trim();
3591
+ if (trimmed.startsWith("#") || !trimmed) return false;
3592
+ const eqIdx = l.indexOf("=");
3593
+ const k = eqIdx !== -1 ? l.substring(0, eqIdx).trim() : l.trim();
3594
+ return k === key;
3595
+ });
3596
+ if (index !== -1) {
3597
+ this.lines[index] = newLine;
3598
+ } else {
3599
+ if (this.lines.length > 0 && this.lines[this.lines.length - 1] !== "") {
3600
+ this.lines.push("");
3601
+ }
3602
+ this.lines.push(newLine);
3603
+ }
3604
+ }
3605
+ delete(key) {
3606
+ const initialLen = this.lines.length;
3607
+ this.lines = this.lines.filter((l) => {
3608
+ const trimmed = l.trim();
3609
+ if (trimmed.startsWith("#") || !trimmed) return true;
3610
+ const eqIdx = l.indexOf("=");
3611
+ const k = eqIdx !== -1 ? l.substring(0, eqIdx).trim() : l.trim();
3612
+ return k !== key;
3613
+ });
3614
+ return this.lines.length !== initialLen;
3615
+ }
3616
+ redactAll() {
3617
+ this.lines = this.lines.map((line) => {
3618
+ const trimmed = line.trim();
3619
+ if (trimmed.startsWith("#") || !trimmed) return line;
3620
+ const eqIndex = line.indexOf("=");
3621
+ return eqIndex !== -1 ? line.substring(0, eqIndex + 1) : line;
3622
+ });
3623
+ }
3624
+ save() {
3625
+ const dir = path2__default.default.dirname(this.filePath);
3626
+ if (!fs4__default.default.existsSync(dir)) {
3627
+ fs4__default.default.mkdirSync(dir, { recursive: true });
3628
+ }
3629
+ fs4__default.default.writeFileSync(this.filePath, this.lines.join("\n"), "utf-8");
3630
+ }
3631
+ };
3632
+ function discoverEnvironments(projectRoot) {
3633
+ if (!fs4__default.default.existsSync(projectRoot)) {
3634
+ return ["local", "dev", "prod"];
3635
+ }
3636
+ const files = fs4__default.default.readdirSync(projectRoot);
3637
+ const envs = /* @__PURE__ */ new Set();
3638
+ for (const file of files) {
3639
+ if (file.startsWith(".env")) {
3640
+ const cleanName = file.replace(/\.example$/, "");
3641
+ const match = cleanName.match(/^\.env\.([a-zA-Z0-9_-]+)$/);
3642
+ if (match && match[1]) {
3643
+ envs.add(match[1]);
3644
+ } else if (cleanName === ".env") {
3645
+ envs.add("local");
3646
+ }
3647
+ }
3648
+ }
3649
+ return envs.size > 0 ? Array.from(envs) : ["local", "dev", "prod"];
3650
+ }
3651
+ function resolveEnvFilename(envName, isExample = false) {
3652
+ const base = envName === "local" ? ".env" : `.env.${envName}`;
3653
+ return isExample ? `${base}.example` : base;
3654
+ }
3655
+
3656
+ // src/commands/env/initExamples.ts
3657
+ async function runEnvInitExamples(flags = {}) {
3658
+ const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3659
+ const s = p19__namespace.spinner();
3660
+ s.start("Scanning for local environment files...");
3661
+ const files = fs4__default.default.readdirSync(projectRoot, { withFileTypes: true });
3662
+ const envFiles = files.filter((dirent) => dirent.isFile() && dirent.name.startsWith(".env") && !dirent.name.endsWith(".example")).map((dirent) => dirent.name).sort();
3663
+ if (envFiles.length === 0) {
3664
+ s.stop("No local .env files found.");
3665
+ p19__namespace.log.info(pc14__default.default.yellow(`No files matching '.env*' were found in ${projectRoot}`));
3666
+ return [];
3667
+ }
3668
+ s.message(`Found ${envFiles.length} local .env file(s). Generating templates...`);
3669
+ const generatedFiles = [];
3670
+ for (const envFile of envFiles) {
3671
+ const sourcePath = path2__default.default.join(projectRoot, envFile);
3672
+ const targetFile = `${envFile}.example`;
3673
+ const targetPath = path2__default.default.join(projectRoot, targetFile);
3674
+ let overwrite = flags.overwrite;
3675
+ if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs4__default.default.existsSync(targetPath)) {
3676
+ overwrite = await p19__namespace.confirm({
3677
+ message: `${targetFile} already exists. Overwrite with redacted values?`,
3678
+ initialValue: true
3679
+ });
3680
+ if (p19__namespace.isCancel(overwrite)) {
3681
+ p19__namespace.cancel("Operation cancelled.");
3682
+ process.exit(0);
3683
+ }
3684
+ }
3685
+ const editor = new EnvEditor(sourcePath);
3686
+ editor.redactAll();
3687
+ const redactedContent = editor.getLines().join("\n");
3688
+ const genFile = writeFileSafely(targetPath, redactedContent, {
3689
+ projectRoot,
3690
+ dryRun: Boolean(flags.dryRun),
3691
+ overwrite: Boolean(overwrite)
3692
+ });
3693
+ generatedFiles.push(genFile);
3694
+ }
3695
+ s.stop("Environment example templates generated!");
3696
+ printGeneratedFiles(generatedFiles, Boolean(flags.dryRun));
3697
+ p19__namespace.outro(pc14__default.default.green("\u2713 .env*.example files are up to date and safely redacted!"));
3698
+ return generatedFiles;
3699
+ }
3700
+ var runEnvExamplesCommand = runEnvInitExamples;
3701
+ function isInteractive(flags) {
3702
+ if (flags.yes || Boolean(flags.nonInteractive)) return false;
3703
+ if (process.env.VITEST) return false;
3704
+ return Boolean(process.stdin.isTTY);
3705
+ }
3706
+ function getAllExistingKeys(projectRoot, envs) {
3707
+ const keys = /* @__PURE__ */ new Set();
3708
+ for (const env of envs) {
3709
+ const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3710
+ const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3711
+ if (fs4__default.default.existsSync(localPath)) {
3712
+ new EnvEditor(localPath).getKeys().forEach((k) => keys.add(k));
3713
+ }
3714
+ if (fs4__default.default.existsSync(examplePath)) {
3715
+ new EnvEditor(examplePath).getKeys().forEach((k) => keys.add(k));
3716
+ }
3717
+ }
3718
+ return Array.from(keys).sort();
3719
+ }
3720
+ async function runEnvAdd(key, value, flags = {}) {
3721
+ const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3722
+ const allEnvs = discoverEnvironments(projectRoot);
3723
+ let targetKey = key?.trim();
3724
+ if (!targetKey) {
3725
+ if (!isInteractive(flags)) {
3726
+ throw new Error("Variable key is required for 'mason env add <key> [value]'");
3727
+ }
3728
+ targetKey = handleCancel(
3729
+ await p19__namespace.text({
3730
+ message: "Enter the variable key name:",
3731
+ placeholder: "e.g. DATABASE_URL, STRIPE_KEY, PORT",
3732
+ validate: (val) => {
3733
+ if (!val || !val.trim()) return "Variable key name cannot be empty";
3734
+ if (/\s/.test(val.trim())) return "Variable key cannot contain spaces";
3735
+ if (val.includes("=")) return "Variable key cannot contain '='";
3736
+ return void 0;
3737
+ }
3738
+ })
3739
+ ).trim();
3740
+ }
3741
+ let targetEnvs = [];
3742
+ if (flags.env) {
3743
+ targetEnvs = String(flags.env).split(",").map((s) => s.trim()).filter(Boolean);
3744
+ } else if (!isInteractive(flags)) {
3745
+ targetEnvs = allEnvs;
3746
+ } else {
3747
+ targetEnvs = handleCancel(
3748
+ await p19__namespace.multiselect({
3749
+ message: `Which environments should receive ${pc14__default.default.bold(targetKey)}?`,
3750
+ options: allEnvs.map((env) => ({
3751
+ value: env,
3752
+ label: env === "local" ? "local (.env)" : `${env} (.env.${env})`
3753
+ })),
3754
+ initialValues: allEnvs,
3755
+ required: true
3756
+ })
3757
+ );
3758
+ }
3759
+ if (targetEnvs.length === 0) {
3760
+ p19__namespace.log.warn("No environments selected. Nothing was changed.");
3761
+ return { key: targetKey, environments: [] };
3762
+ }
3763
+ for (const env of targetEnvs) {
3764
+ let envVal = value;
3765
+ if (envVal === void 0) {
3766
+ if (!isInteractive(flags)) {
3767
+ envVal = "";
3768
+ } else {
3769
+ envVal = handleCancel(
3770
+ await p19__namespace.text({
3771
+ message: `Value for ${pc14__default.default.cyan(targetKey)} in ${pc14__default.default.bold(env)} (${resolveEnvFilename(env)})?`,
3772
+ initialValue: "",
3773
+ placeholder: "Leave empty for blank value"
3774
+ })
3775
+ );
3776
+ }
3777
+ } else if (isInteractive(flags) && !flags.yes) {
3778
+ envVal = handleCancel(
3779
+ await p19__namespace.text({
3780
+ message: `Value for ${pc14__default.default.cyan(targetKey)} in ${pc14__default.default.bold(env)} (${resolveEnvFilename(env)})?`,
3781
+ initialValue: value ?? "",
3782
+ placeholder: "Leave empty for blank value"
3783
+ })
3784
+ );
3785
+ }
3786
+ const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3787
+ const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3788
+ if (flags.dryRun) {
3789
+ p19__namespace.log.info(
3790
+ pc14__default.default.cyan(`[DRY RUN] Would set ${targetKey}=${envVal} in ${resolveEnvFilename(env, false)}`)
3791
+ );
3792
+ p19__namespace.log.info(
3793
+ pc14__default.default.cyan(`[DRY RUN] Would add ${targetKey}= to ${resolveEnvFilename(env, true)}`)
3794
+ );
3795
+ } else {
3796
+ const localEditor = new EnvEditor(localPath);
3797
+ localEditor.set(targetKey, envVal);
3798
+ localEditor.save();
3799
+ const exampleEditor = new EnvEditor(examplePath);
3800
+ exampleEditor.set(targetKey, "");
3801
+ exampleEditor.save();
3802
+ }
3803
+ }
3804
+ if (!flags.dryRun) {
3805
+ p19__namespace.log.success(
3806
+ pc14__default.default.green(
3807
+ `\u2713 Added ${pc14__default.default.bold(targetKey)} to [${targetEnvs.join(", ")}] and updated .example templates.`
3808
+ )
3809
+ );
3810
+ }
3811
+ return { key: targetKey, environments: targetEnvs };
3812
+ }
3813
+ async function runEnvUpdate(key, value, flags = {}) {
3814
+ const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3815
+ const allEnvs = discoverEnvironments(projectRoot);
3816
+ const existingKeys = getAllExistingKeys(projectRoot, allEnvs);
3817
+ let targetKey = key?.trim();
3818
+ if (!targetKey) {
3819
+ if (!isInteractive(flags)) {
3820
+ throw new Error("Variable key is required for 'mason env update <key> [value]'");
3821
+ }
3822
+ if (existingKeys.length === 0) {
3823
+ p19__namespace.log.error(pc14__default.default.red("No environment variables found to update."));
3824
+ return { key: "", environments: [] };
3825
+ }
3826
+ targetKey = handleCancel(
3827
+ await p19__namespace.select({
3828
+ message: "Select a variable to update:",
3829
+ options: existingKeys.map((k) => ({ value: k, label: k }))
3830
+ })
3831
+ );
3832
+ }
3833
+ const envsWithKey = allEnvs.filter((env) => {
3834
+ const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3835
+ return fs4__default.default.existsSync(localPath) && new EnvEditor(localPath).has(targetKey);
3836
+ });
3837
+ let targetEnvs = [];
3838
+ if (flags.env) {
3839
+ targetEnvs = String(flags.env).split(",").map((s) => s.trim()).filter(Boolean);
3840
+ } else if (!isInteractive(flags)) {
3841
+ targetEnvs = envsWithKey.length > 0 ? envsWithKey : allEnvs;
3842
+ } else {
3843
+ targetEnvs = handleCancel(
3844
+ await p19__namespace.multiselect({
3845
+ message: `Which environments should be updated for ${pc14__default.default.bold(targetKey)}?`,
3846
+ options: allEnvs.map((env) => ({
3847
+ value: env,
3848
+ label: env === "local" ? "local (.env)" : `${env} (.env.${env})`,
3849
+ hint: envsWithKey.includes(env) ? "currently exists" : "not set"
3850
+ })),
3851
+ initialValues: envsWithKey.length > 0 ? envsWithKey : allEnvs,
3852
+ required: true
3853
+ })
3854
+ );
3855
+ }
3856
+ if (targetEnvs.length === 0) {
3857
+ p19__namespace.log.warn("No environments selected. Nothing was changed.");
3858
+ return { key: targetKey, environments: [] };
3859
+ }
3860
+ for (const env of targetEnvs) {
3861
+ const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3862
+ const localEditor = new EnvEditor(localPath);
3863
+ const currentVal = localEditor.getValue(targetKey);
3864
+ let newVal = value;
3865
+ if (newVal === void 0) {
3866
+ if (!isInteractive(flags)) {
3867
+ newVal = currentVal ?? "";
3868
+ } else {
3869
+ newVal = handleCancel(
3870
+ await p19__namespace.text({
3871
+ message: `New value for ${pc14__default.default.cyan(targetKey)} in ${pc14__default.default.bold(env)}? (Current: "${currentVal ?? ""}")`,
3872
+ initialValue: currentVal ?? ""
3873
+ })
3874
+ );
3875
+ }
3876
+ } else if (isInteractive(flags) && !flags.yes) {
3877
+ newVal = handleCancel(
3878
+ await p19__namespace.text({
3879
+ message: `New value for ${pc14__default.default.cyan(targetKey)} in ${pc14__default.default.bold(env)}? (Current: "${currentVal ?? ""}")`,
3880
+ initialValue: value ?? currentVal ?? ""
3881
+ })
3882
+ );
3883
+ }
3884
+ if (flags.dryRun) {
3885
+ p19__namespace.log.info(
3886
+ pc14__default.default.cyan(`[DRY RUN] Would update ${targetKey}=${newVal} in ${resolveEnvFilename(env, false)}`)
3887
+ );
3888
+ } else {
3889
+ localEditor.set(targetKey, newVal);
3890
+ localEditor.save();
3891
+ const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3892
+ const exampleEditor = new EnvEditor(examplePath);
3893
+ if (!exampleEditor.has(targetKey)) {
3894
+ exampleEditor.set(targetKey, "");
3895
+ exampleEditor.save();
3896
+ }
3897
+ }
3898
+ }
3899
+ if (!flags.dryRun) {
3900
+ p19__namespace.log.success(
3901
+ pc14__default.default.green(`\u2713 Updated ${pc14__default.default.bold(targetKey)} in [${targetEnvs.join(", ")}].`)
3902
+ );
3903
+ }
3904
+ return { key: targetKey, environments: targetEnvs };
3905
+ }
3906
+ async function runEnvDelete(key, flags = {}) {
3907
+ const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3908
+ const allEnvs = discoverEnvironments(projectRoot);
3909
+ const existingKeys = getAllExistingKeys(projectRoot, allEnvs);
3910
+ let targetKey = key?.trim();
3911
+ if (!targetKey) {
3912
+ if (!isInteractive(flags)) {
3913
+ throw new Error("Variable key is required for 'mason env delete <key>'");
3914
+ }
3915
+ if (existingKeys.length === 0) {
3916
+ p19__namespace.log.error(pc14__default.default.red("No environment variables found to delete."));
3917
+ return { key: "", environments: [] };
3918
+ }
3919
+ targetKey = handleCancel(
3920
+ await p19__namespace.select({
3921
+ message: "Select a variable to delete:",
3922
+ options: existingKeys.map((k) => ({ value: k, label: k }))
3923
+ })
3924
+ );
3925
+ }
3926
+ const envsWithKey = allEnvs.filter((env) => {
3927
+ const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3928
+ const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3929
+ return fs4__default.default.existsSync(localPath) && new EnvEditor(localPath).has(targetKey) || fs4__default.default.existsSync(examplePath) && new EnvEditor(examplePath).has(targetKey);
3930
+ });
3931
+ let targetEnvs = [];
3932
+ if (flags.env) {
3933
+ targetEnvs = String(flags.env).split(",").map((s) => s.trim()).filter(Boolean);
3934
+ } else if (!isInteractive(flags)) {
3935
+ targetEnvs = envsWithKey.length > 0 ? envsWithKey : allEnvs;
3936
+ } else {
3937
+ targetEnvs = handleCancel(
3938
+ await p19__namespace.multiselect({
3939
+ message: `Which environments should remove ${pc14__default.default.bold(targetKey)}?`,
3940
+ options: allEnvs.map((env) => ({
3941
+ value: env,
3942
+ label: env === "local" ? "local (.env)" : `${env} (.env.${env})`,
3943
+ ...envsWithKey.includes(env) ? { hint: "currently present" } : {}
3944
+ })),
3945
+ initialValues: envsWithKey.length > 0 ? envsWithKey : allEnvs,
3946
+ required: true
3947
+ })
3948
+ );
3949
+ }
3950
+ if (targetEnvs.length === 0) {
3951
+ p19__namespace.log.warn("No environments selected. Nothing was deleted.");
3952
+ return { key: targetKey, environments: [] };
3953
+ }
3954
+ if (isInteractive(flags) && !flags.yes) {
3955
+ const confirm13 = handleCancel(
3956
+ await p19__namespace.confirm({
3957
+ message: `Are you sure you want to delete ${pc14__default.default.bold(targetKey)} from ${targetEnvs.join(", ")} and their .example templates?`,
3958
+ initialValue: false
3959
+ })
3960
+ );
3961
+ if (!confirm13) {
3962
+ p19__namespace.log.warn("Operation cancelled.");
3963
+ return { key: targetKey, environments: [] };
3964
+ }
3965
+ }
3966
+ for (const env of targetEnvs) {
3967
+ const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3968
+ const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3969
+ if (flags.dryRun) {
3970
+ p19__namespace.log.info(
3971
+ pc14__default.default.cyan(`[DRY RUN] Would delete ${targetKey} from ${resolveEnvFilename(env, false)} and ${resolveEnvFilename(env, true)}`)
3972
+ );
3973
+ } else {
3974
+ if (fs4__default.default.existsSync(localPath)) {
3975
+ const localEditor = new EnvEditor(localPath);
3976
+ localEditor.delete(targetKey);
3977
+ localEditor.save();
3978
+ }
3979
+ if (fs4__default.default.existsSync(examplePath)) {
3980
+ const exampleEditor = new EnvEditor(examplePath);
3981
+ exampleEditor.delete(targetKey);
3982
+ exampleEditor.save();
3983
+ }
3984
+ }
3985
+ }
3986
+ if (!flags.dryRun) {
3987
+ p19__namespace.log.success(
3988
+ pc14__default.default.green(`\u2713 Deleted ${pc14__default.default.bold(targetKey)} from [${targetEnvs.join(", ")}] and .example templates.`)
3989
+ );
3990
+ }
3991
+ return { key: targetKey, environments: targetEnvs };
3992
+ }
3993
+ async function runEnvAudit(flags = {}) {
3994
+ const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3995
+ const envs = discoverEnvironments(projectRoot);
3996
+ p19__namespace.intro(pc14__default.default.bgCyan(pc14__default.default.black(" mason env audit ")));
3997
+ const items = [];
3998
+ let totalIssues = 0;
3999
+ let hasDrift = false;
4000
+ let hasErrors = false;
4001
+ for (const env of envs) {
4002
+ const localFile = resolveEnvFilename(env, false);
4003
+ const exampleFile = resolveEnvFilename(env, true);
4004
+ const localPath = path2__default.default.join(projectRoot, localFile);
4005
+ const examplePath = path2__default.default.join(projectRoot, exampleFile);
4006
+ const localExists = fs4__default.default.existsSync(localPath);
4007
+ const exampleExists = fs4__default.default.existsSync(examplePath);
4008
+ const localEditor = new EnvEditor(localPath);
4009
+ const exampleEditor = new EnvEditor(examplePath);
4010
+ const localKeys = localExists ? localEditor.getKeys() : [];
4011
+ const exampleKeys = exampleExists ? exampleEditor.getKeys() : [];
4012
+ const missingInLocal = exampleKeys.filter((k) => !localKeys.includes(k));
4013
+ const missingInExample = localKeys.filter((k) => !exampleKeys.includes(k));
4014
+ const emptyLocals = localKeys.filter((k) => {
4015
+ const val = localEditor.getValue(k);
4016
+ return val === "" || val === null;
4017
+ });
4018
+ const envIssues = (!localExists ? 1 : 0) + (!exampleExists ? 1 : 0) + missingInLocal.length + missingInExample.length + emptyLocals.length;
4019
+ totalIssues += envIssues;
4020
+ if (missingInExample.length > 0 || !exampleExists) hasDrift = true;
4021
+ if (missingInLocal.length > 0 || !localExists) hasErrors = true;
4022
+ items.push({
4023
+ env,
4024
+ localFile,
4025
+ exampleFile,
4026
+ localExists,
4027
+ exampleExists,
4028
+ missingInLocal,
4029
+ missingInExample,
4030
+ emptyLocals
4031
+ });
4032
+ if (!localExists && !exampleExists) {
4033
+ p19__namespace.log.warn(
4034
+ pc14__default.default.yellow(`\u25B2 ${pc14__default.default.bold(env)}: Neither '${localFile}' nor '${exampleFile}' exist.`)
4035
+ );
4036
+ continue;
4037
+ }
4038
+ if (!localExists) {
4039
+ p19__namespace.log.error(
4040
+ pc14__default.default.red(`\u2717 ${pc14__default.default.bold(env)}: Local file '${localFile}' is missing! Run 'mason env init' to create it.`)
4041
+ );
4042
+ continue;
4043
+ }
4044
+ if (!exampleExists) {
4045
+ p19__namespace.log.warn(
4046
+ pc14__default.default.yellow(`\u25B2 ${pc14__default.default.bold(env)}: Template '${exampleFile}' is missing! Run 'mason env init-examples' to generate it.`)
4047
+ );
4048
+ continue;
4049
+ }
4050
+ if (envIssues === 0) {
4051
+ p19__namespace.log.success(
4052
+ pc14__default.default.green(`\u2713 ${pc14__default.default.bold(env)} (${localFile} \u2194 ${exampleFile}): All ${localKeys.length} keys in sync!`)
4053
+ );
4054
+ } else {
4055
+ p19__namespace.log.step(
4056
+ pc14__default.default.bold(pc14__default.default.cyan(`Environment: ${env} (${localFile} \u2194 ${exampleFile})`))
4057
+ );
4058
+ if (missingInLocal.length > 0) {
4059
+ p19__namespace.log.error(
4060
+ pc14__default.default.red(` \u25CF Missing locally (${missingInLocal.length} in template but missing in ${localFile}):`)
4061
+ );
4062
+ for (const k of missingInLocal) {
4063
+ p19__namespace.log.message(pc14__default.default.red(` - ${k}`));
4064
+ }
4065
+ }
4066
+ if (missingInExample.length > 0) {
4067
+ p19__namespace.log.warn(
4068
+ pc14__default.default.yellow(` \u25CF Template drift (${missingInExample.length} local keys missing in ${exampleFile}):`)
4069
+ );
4070
+ for (const k of missingInExample) {
4071
+ p19__namespace.log.message(pc14__default.default.yellow(` - ${k}`));
4072
+ }
4073
+ }
4074
+ if (emptyLocals.length > 0) {
4075
+ p19__namespace.log.info(
4076
+ pc14__default.default.dim(` \u25B2 Empty values (${emptyLocals.length} defined with blank value in ${localFile}):`)
4077
+ );
4078
+ for (const k of emptyLocals) {
4079
+ p19__namespace.log.message(pc14__default.default.dim(` - ${k}`));
4080
+ }
4081
+ }
4082
+ }
4083
+ }
4084
+ if (totalIssues === 0) {
4085
+ p19__namespace.outro(pc14__default.default.green("\u2713 All environment files are in sync! No drift detected."));
4086
+ } else {
4087
+ p19__namespace.outro(
4088
+ pc14__default.default.yellow(`Found ${totalIssues} environment issue(s) across inspected environments.`)
4089
+ );
4090
+ }
4091
+ return {
4092
+ hasDrift,
4093
+ hasErrors,
4094
+ totalIssues,
4095
+ items
4096
+ };
4097
+ }
4098
+
4099
+ // src/commands/env/index.ts
4100
+ async function runEnvMenu(flags = {}) {
4101
+ const task = handleCancel(
4102
+ await p19__namespace.select({
4103
+ message: "What environment task do you want to run?",
4104
+ options: [
4105
+ {
4106
+ value: "add",
4107
+ label: "Add Variable",
4108
+ hint: "Add a new key across selected environments and sync .example templates"
4109
+ },
4110
+ {
4111
+ value: "update",
4112
+ label: "Update Variable",
4113
+ hint: "Update an existing variable value across environments"
4114
+ },
4115
+ {
4116
+ value: "delete",
4117
+ label: "Delete Variable",
4118
+ hint: "Delete a variable from .env and .example files"
4119
+ },
4120
+ {
4121
+ value: "audit",
4122
+ label: "Audit Drift",
4123
+ hint: "Scan for missing keys, uncommitted secrets, or template drift"
4124
+ },
4125
+ {
4126
+ value: "init",
4127
+ label: "Init Files (.env)",
4128
+ hint: "Clone .env*.example templates to local .env files"
4129
+ },
4130
+ {
4131
+ value: "init-examples",
4132
+ label: "Init Templates (.env.example)",
4133
+ hint: "Safely clone and redact local .env files to .example templates"
4134
+ }
4135
+ ]
4136
+ })
4137
+ );
4138
+ switch (task) {
4139
+ case "add":
4140
+ return await runEnvAdd(void 0, void 0, flags);
4141
+ case "update":
4142
+ return await runEnvUpdate(void 0, void 0, flags);
4143
+ case "delete":
4144
+ return await runEnvDelete(void 0, flags);
4145
+ case "audit":
4146
+ return await runEnvAudit(flags);
4147
+ case "init":
4148
+ return await runEnvInit(flags);
4149
+ case "init-examples":
4150
+ return await runEnvInitExamples(flags);
4151
+ }
4152
+ }
4153
+ async function handleEnv(subcommand, args = [], flags = {}) {
4154
+ if (!subcommand) {
4155
+ return await runEnvMenu(flags);
4156
+ }
4157
+ const normalized = subcommand.trim().toLowerCase();
4158
+ switch (normalized) {
4159
+ case "init":
4160
+ return await runEnvInit(flags);
4161
+ case "init-examples":
4162
+ case "initexamples":
4163
+ return await runEnvInitExamples(flags);
4164
+ case "add":
4165
+ return await runEnvAdd(args[0], args[1], flags);
4166
+ case "update":
4167
+ return await runEnvUpdate(args[0], args[1], flags);
4168
+ case "delete":
4169
+ case "remove":
4170
+ case "rm":
4171
+ return await runEnvDelete(args[0], flags);
4172
+ case "audit":
4173
+ return await runEnvAudit(flags);
4174
+ default:
4175
+ p19__namespace.log.error(
4176
+ pc14__default.default.red(
4177
+ `Unknown env subcommand: "${subcommand}". Allowed subcommands: init, init-examples, add, update, delete, audit.`
4178
+ )
4179
+ );
4180
+ if (process.env.VITEST) {
4181
+ throw new Error(
4182
+ `Unknown env subcommand: "${subcommand}". Allowed subcommands: init, init-examples, add, update, delete, audit.`
4183
+ );
4184
+ }
4185
+ process.exit(1);
4186
+ }
4187
+ }
3544
4188
 
3545
4189
  // src/commands/menu.ts
3546
4190
  async function runInteractiveMenu(flags = {}) {
3547
4191
  printBanner();
3548
4192
  const choice = handleCancel(
3549
- await p15__namespace.select({
4193
+ await p19__namespace.select({
3550
4194
  message: "What would you like to create in your architecture?",
3551
4195
  options: [
3552
4196
  {
@@ -3591,8 +4235,8 @@ async function runInteractiveMenu(flags = {}) {
3591
4235
  },
3592
4236
  {
3593
4237
  value: "env",
3594
- label: "Generate Env Files",
3595
- hint: "Clone .env*.example files to local .env equivalents"
4238
+ label: "Environment Variables",
4239
+ hint: "Manage .env files, add/delete keys, and sync templates"
3596
4240
  }
3597
4241
  ]
3598
4242
  })
@@ -3623,7 +4267,7 @@ async function runInteractiveMenu(flags = {}) {
3623
4267
  await runInjectableCommand(void 0, flags);
3624
4268
  break;
3625
4269
  case "env":
3626
- await runEnvCommand(flags);
4270
+ await runEnvMenu(flags);
3627
4271
  break;
3628
4272
  }
3629
4273
  }
@@ -3662,8 +4306,8 @@ async function handleCreate(type, name, flags = {}) {
3662
4306
  await runInjectableCommand(name, flags);
3663
4307
  break;
3664
4308
  default:
3665
- p15__namespace.log.error(
3666
- pc15__default.default.red(
4309
+ p19__namespace.log.error(
4310
+ pc14__default.default.red(
3667
4311
  `Unknown component type: "${type}". Allowed types: feature, shared, usecase, domain, infrastructure, interface, httpHandler, injectable.`
3668
4312
  )
3669
4313
  );
@@ -3671,9 +4315,9 @@ async function handleCreate(type, name, flags = {}) {
3671
4315
  }
3672
4316
  }
3673
4317
  var importPrompts = {
3674
- select: p15__namespace.select,
3675
- text: p15__namespace.text,
3676
- confirm: p15__namespace.confirm
4318
+ select: p19__namespace.select,
4319
+ text: p19__namespace.text,
4320
+ confirm: p19__namespace.confirm
3677
4321
  };
3678
4322
  function isTestFile(filePath) {
3679
4323
  const normalized = filePath.replace(/\\/g, "/");
@@ -3783,19 +4427,19 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3783
4427
  );
3784
4428
  }
3785
4429
  if (type !== "shared" && type !== "feature") {
3786
- p15__namespace.log.error(pc15__default.default.red(`Invalid module type: "${typeArg}". Must be "shared" or "feature".`));
4430
+ p19__namespace.log.error(pc14__default.default.red(`Invalid module type: "${typeArg}". Must be "shared" or "feature".`));
3787
4431
  process.exit(1);
3788
4432
  }
3789
4433
  const registryBase = getRegistryBase(projectRoot, flags.registry);
3790
- const s = p15__namespace.spinner();
3791
- s.start(`Connecting to registry at ${pc15__default.default.dim(registryBase)}...`);
4434
+ const s = p19__namespace.spinner();
4435
+ s.start(`Connecting to registry at ${pc14__default.default.dim(registryBase)}...`);
3792
4436
  let index;
3793
4437
  try {
3794
4438
  index = await fetchRegistryIndex(registryBase);
3795
4439
  s.stop("Registry index loaded.");
3796
4440
  } catch (err) {
3797
- s.stop(pc15__default.default.red("Failed to load registry index."));
3798
- p15__namespace.log.error(pc15__default.default.red(err.message || String(err)));
4441
+ s.stop(pc14__default.default.red("Failed to load registry index."));
4442
+ p19__namespace.log.error(pc14__default.default.red(err.message || String(err)));
3799
4443
  process.exit(1);
3800
4444
  }
3801
4445
  const availableList = type === "shared" ? index.shared : index.features;
@@ -3803,7 +4447,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3803
4447
  let name = nameArg?.trim();
3804
4448
  if (!name) {
3805
4449
  if (availableList.length === 0) {
3806
- p15__namespace.log.warn(`No ${type} modules available in the registry.`);
4450
+ p19__namespace.log.warn(`No ${type} modules available in the registry.`);
3807
4451
  return;
3808
4452
  }
3809
4453
  name = handleCancel(
@@ -3819,9 +4463,9 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3819
4463
  }
3820
4464
  if (!candidateNames.includes(name)) {
3821
4465
  const closest = findClosestMatch(name, candidateNames);
3822
- p15__namespace.log.error(pc15__default.default.red(`\u274C Module '${name}' not found in the ${type} registry.`));
4466
+ p19__namespace.log.error(pc14__default.default.red(`\u274C Module '${name}' not found in the ${type} registry.`));
3823
4467
  if (closest) {
3824
- p15__namespace.log.info(pc15__default.default.yellow(`Did you mean '${pc15__default.default.cyan(closest)}'?`));
4468
+ p19__namespace.log.info(pc14__default.default.yellow(`Did you mean '${pc14__default.default.cyan(closest)}'?`));
3825
4469
  }
3826
4470
  process.exit(1);
3827
4471
  }
@@ -3833,7 +4477,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3833
4477
  try {
3834
4478
  manifest = await fetchModuleManifest(registryBase, modType, modName);
3835
4479
  } catch (err) {
3836
- p15__namespace.log.error(pc15__default.default.red(`Failed to fetch manifest for ${modType} '${modName}': ${err.message}`));
4480
+ p19__namespace.log.error(pc14__default.default.red(`Failed to fetch manifest for ${modType} '${modName}': ${err.message}`));
3837
4481
  process.exit(1);
3838
4482
  }
3839
4483
  nodes.set(key, {
@@ -3873,7 +4517,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3873
4517
  buildTopologicalOrder(rootKey);
3874
4518
  const resolutions = /* @__PURE__ */ new Map();
3875
4519
  const globalAliasMap = /* @__PURE__ */ new Map();
3876
- p15__namespace.log.step(`Importing ${type}: ${pc15__default.default.cyan(name)}...`);
4520
+ p19__namespace.log.step(`Importing ${type}: ${pc14__default.default.cyan(name)}...`);
3877
4521
  for (const key of orderedKeys) {
3878
4522
  const node = nodes.get(key);
3879
4523
  const { type: modType, name: registryName, manifest } = node;
@@ -3905,8 +4549,8 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3905
4549
  const programmaticPointTo = pointToMap[registryName] || pointToMap[`${modType}/${registryName}`];
3906
4550
  if (programmaticPointTo) {
3907
4551
  if (!checkModuleExists(projectRoot, modType, programmaticPointTo)) {
3908
- p15__namespace.log.error(
3909
- pc15__default.default.red(
4552
+ p19__namespace.log.error(
4553
+ pc14__default.default.red(
3910
4554
  `Module '${programmaticPointTo}' specified in --point-to does not exist in ${folder}.`
3911
4555
  )
3912
4556
  );
@@ -3914,7 +4558,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3914
4558
  }
3915
4559
  globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${programmaticPointTo}/`);
3916
4560
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${programmaticPointTo}`);
3917
- p15__namespace.log.step(`Pointing '${modType}/${registryName}' to existing '${folder}/${programmaticPointTo}'`);
4561
+ p19__namespace.log.step(`Pointing '${modType}/${registryName}' to existing '${folder}/${programmaticPointTo}'`);
3918
4562
  resolutions.set(key, {
3919
4563
  type: modType,
3920
4564
  registryName,
@@ -3930,7 +4574,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3930
4574
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${programmaticAlias}`);
3931
4575
  const baseDir = getModuleBaseDir(projectRoot, modType);
3932
4576
  const displayDest = path2__default.default.relative(projectRoot, path2__default.default.join(baseDir, programmaticAlias));
3933
- p15__namespace.log.step(`Importing '${registryName}' into '${displayDest}'...`);
4577
+ p19__namespace.log.step(`Importing '${registryName}' into '${displayDest}'...`);
3934
4578
  resolutions.set(key, {
3935
4579
  type: modType,
3936
4580
  registryName,
@@ -3942,7 +4586,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3942
4586
  }
3943
4587
  const existingDir = getExistingModuleDir(projectRoot, modType, registryName);
3944
4588
  if (!existingDir) {
3945
- p15__namespace.log.info(` \u21B3 Resolving required ${modType} dependency: ${pc15__default.default.cyan(registryName)}`);
4589
+ p19__namespace.log.info(` \u21B3 Resolving required ${modType} dependency: ${pc14__default.default.cyan(registryName)}`);
3946
4590
  resolutions.set(key, {
3947
4591
  type: modType,
3948
4592
  registryName,
@@ -3958,7 +4602,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3958
4602
  const remoteIntegrity = manifest.integrity || entry?.integrity;
3959
4603
  const localHash = computeDirectoryHash(existingDir);
3960
4604
  if (remoteIntegrity && localHash === remoteIntegrity) {
3961
- p15__namespace.log.step(`\u2713 ${modType}/${registryName} is up to date (reusing existing)`);
4605
+ p19__namespace.log.step(`\u2713 ${modType}/${registryName} is up to date (reusing existing)`);
3962
4606
  resolutions.set(key, {
3963
4607
  type: modType,
3964
4608
  registryName,
@@ -3969,7 +4613,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3969
4613
  continue;
3970
4614
  }
3971
4615
  if (flags.overwrite) {
3972
- p15__namespace.log.step(`Overwriting '${modType}/${registryName}' with registry version (--overwrite)...`);
4616
+ p19__namespace.log.step(`Overwriting '${modType}/${registryName}' with registry version (--overwrite)...`);
3973
4617
  resolutions.set(key, {
3974
4618
  type: modType,
3975
4619
  registryName,
@@ -3980,7 +4624,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3980
4624
  continue;
3981
4625
  }
3982
4626
  if (flags.yes) {
3983
- p15__namespace.log.info(`Using existing '${modType}/${registryName}'`);
4627
+ p19__namespace.log.info(`Using existing '${modType}/${registryName}'`);
3984
4628
  resolutions.set(key, {
3985
4629
  type: modType,
3986
4630
  registryName,
@@ -4014,7 +4658,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4014
4658
  })
4015
4659
  );
4016
4660
  if (choice === "keep_existing" || choice === "use_existing") {
4017
- p15__namespace.log.step(`Skipping '${modType}/${registryName}' (keeping existing)`);
4661
+ p19__namespace.log.step(`Skipping '${modType}/${registryName}' (keeping existing)`);
4018
4662
  resolutions.set(key, {
4019
4663
  type: modType,
4020
4664
  registryName,
@@ -4086,7 +4730,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4086
4730
  chosenName = chosenName.replace(/^@\/(shared|features)\//, "").replace(/^(src\/)?(shared|features)\//, "").replace(/^\/+|\/+$/g, "").trim();
4087
4731
  globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${chosenName}/`);
4088
4732
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${chosenName}`);
4089
- p15__namespace.log.step(`Pointing '${modType}/${registryName}' to existing '${folder}/${chosenName}'`);
4733
+ p19__namespace.log.step(`Pointing '${modType}/${registryName}' to existing '${folder}/${chosenName}'`);
4090
4734
  resolutions.set(key, {
4091
4735
  type: modType,
4092
4736
  registryName,
@@ -4118,7 +4762,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4118
4762
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${newName}`);
4119
4763
  const baseDir = getModuleBaseDir(projectRoot, modType);
4120
4764
  const displayDest = path2__default.default.relative(projectRoot, path2__default.default.join(baseDir, newName));
4121
- p15__namespace.log.step(`Importing '${registryName}' into '${displayDest}'...`);
4765
+ p19__namespace.log.step(`Importing '${registryName}' into '${displayDest}'...`);
4122
4766
  resolutions.set(key, {
4123
4767
  type: modType,
4124
4768
  registryName,
@@ -4129,7 +4773,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4129
4773
  continue;
4130
4774
  }
4131
4775
  if (choice === "overwrite") {
4132
- p15__namespace.log.step(`Overwriting '${modType}/${registryName}' with registry version...`);
4776
+ p19__namespace.log.step(`Overwriting '${modType}/${registryName}' with registry version...`);
4133
4777
  resolutions.set(key, {
4134
4778
  type: modType,
4135
4779
  registryName,
@@ -4172,8 +4816,8 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4172
4816
  const targetDir = path2__default.default.join(getModuleBaseDir(projectRoot, res.type), res.targetName);
4173
4817
  const isOverwrite = Boolean(flags.overwrite || res.action === "overwrite");
4174
4818
  if (key !== rootKey) {
4175
- p15__namespace.log.step(
4176
- `Importing ${res.type}: ${pc15__default.default.cyan(res.targetName)}${res.targetName !== res.registryName ? pc15__default.default.dim(` (from ${res.registryName})`) : ""}...`
4819
+ p19__namespace.log.step(
4820
+ `Importing ${res.type}: ${pc14__default.default.cyan(res.targetName)}${res.targetName !== res.registryName ? pc14__default.default.dim(` (from ${res.registryName})`) : ""}...`
4177
4821
  );
4178
4822
  }
4179
4823
  if (res.action === "overwrite" && !flags.dryRun) {
@@ -4191,8 +4835,8 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4191
4835
  const remoteFilePath = `${folder}/${res.registryName}/${file}`;
4192
4836
  const localFilePath = path2__default.default.join(targetDir, file);
4193
4837
  if (fs4__default.default.existsSync(localFilePath) && !isOverwrite) {
4194
- p15__namespace.log.warn(
4195
- ` \u21B3 Skipping existing file: ${pc15__default.default.dim(path2__default.default.relative(projectRoot, localFilePath))} (use --overwrite to replace)`
4838
+ p19__namespace.log.warn(
4839
+ ` \u21B3 Skipping existing file: ${pc14__default.default.dim(path2__default.default.relative(projectRoot, localFilePath))} (use --overwrite to replace)`
4196
4840
  );
4197
4841
  continue;
4198
4842
  }
@@ -4204,18 +4848,18 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4204
4848
  }
4205
4849
  const displayPath = path2__default.default.relative(projectRoot, localFilePath);
4206
4850
  totalWrittenFiles.push(displayPath);
4207
- p15__namespace.log.message(` ${pc15__default.default.green("+")} ${displayPath}`);
4851
+ p19__namespace.log.message(` ${pc14__default.default.green("+")} ${displayPath}`);
4208
4852
  }
4209
4853
  }
4210
4854
  const missingNpm = getMissingNpmPackages(projectRoot, Array.from(requiredNpmPackages));
4211
4855
  if (missingNpm.length > 0) {
4212
4856
  if (flags.skipInstall || flags.dryRun) {
4213
- p15__namespace.log.info(`Required npm dependencies to install: ${pc15__default.default.cyan(missingNpm.join(", "))}`);
4857
+ p19__namespace.log.info(`Required npm dependencies to install: ${pc14__default.default.cyan(missingNpm.join(", "))}`);
4214
4858
  } else {
4215
4859
  try {
4216
4860
  installNpmPackages(projectRoot, missingNpm);
4217
4861
  } catch (err) {
4218
- p15__namespace.log.warn(
4862
+ p19__namespace.log.warn(
4219
4863
  `Could not automatically install packages (${err.message}). Please run: npm install ${missingNpm.join(
4220
4864
  " "
4221
4865
  )}`
@@ -4224,13 +4868,13 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4224
4868
  }
4225
4869
  }
4226
4870
  if (flags.dryRun) {
4227
- p15__namespace.log.info(pc15__default.default.yellow("Dry run complete: No files were written to disk."));
4871
+ p19__namespace.log.info(pc14__default.default.yellow("Dry run complete: No files were written to disk."));
4228
4872
  } else {
4229
4873
  const rootRes = resolutions.get(rootKey);
4230
4874
  const baseDir = getModuleBaseDir(projectRoot, type);
4231
4875
  const displayTarget = path2__default.default.relative(projectRoot, path2__default.default.join(baseDir, rootRes.targetName));
4232
- p15__namespace.log.success(
4233
- pc15__default.default.green(
4876
+ p19__namespace.log.success(
4877
+ pc14__default.default.green(
4234
4878
  `Successfully imported ${type} '${name}' (${totalWrittenFiles.length} file${totalWrittenFiles.length === 1 ? "" : "s"} placed in ${displayTarget})`
4235
4879
  )
4236
4880
  );
@@ -4453,10 +5097,10 @@ var FeatureDependencyGraph = class {
4453
5097
  if (cycle) return cycle;
4454
5098
  } else if (inStack.has(next)) {
4455
5099
  const cycle = [next];
4456
- let p18 = curr;
4457
- while (p18 !== next) {
4458
- cycle.push(p18);
4459
- p18 = parent.get(p18) || next;
5100
+ let p22 = curr;
5101
+ while (p22 !== next) {
5102
+ cycle.push(p22);
5103
+ p22 = parent.get(p22) || next;
4460
5104
  }
4461
5105
  cycle.push(next);
4462
5106
  cycle.reverse();
@@ -5358,15 +6002,15 @@ ${compiledDetails}
5358
6002
  // src/commands/lint.ts
5359
6003
  function formatViolation(v) {
5360
6004
  const lines = [];
5361
- lines.push(pc15__default.default.underline(pc15__default.default.cyan(v.relativePath)) + pc15__default.default.dim(":") + pc15__default.default.yellow(String(v.line)));
6005
+ lines.push(pc14__default.default.underline(pc14__default.default.cyan(v.relativePath)) + pc14__default.default.dim(":") + pc14__default.default.yellow(String(v.line)));
5362
6006
  const gutter = `${String(v.line).padStart(4, " ")} | `;
5363
- lines.push(pc15__default.default.dim(gutter) + v.code);
6007
+ lines.push(pc14__default.default.dim(gutter) + v.code);
5364
6008
  const categoryShort = v.category.replace(" Violation", "");
5365
6009
  lines.push(
5366
- " " + pc15__default.default.red(pc15__default.default.bold("\u2716")) + " " + pc15__default.default.red(`[${categoryShort}]`) + " " + v.advice
6010
+ " " + pc14__default.default.red(pc14__default.default.bold("\u2716")) + " " + pc14__default.default.red(`[${categoryShort}]`) + " " + v.advice
5367
6011
  );
5368
6012
  if (v.fixExample?.good) {
5369
- lines.push(" " + pc15__default.default.dim("\u2192") + " " + pc15__default.default.dim(v.fixExample.good));
6013
+ lines.push(" " + pc14__default.default.dim("\u2192") + " " + pc14__default.default.dim(v.fixExample.good));
5370
6014
  }
5371
6015
  return lines.join("\n");
5372
6016
  }
@@ -5391,7 +6035,7 @@ async function handleLint(flags = {}) {
5391
6035
  console.log("");
5392
6036
  }
5393
6037
  console.log(
5394
- pc15__default.default.red(
6038
+ pc14__default.default.red(
5395
6039
  `\u2716 Dependency rules check failed with ${summary.totalViolations} error${summary.totalViolations > 1 ? "s" : ""} across ${summary.violatedFeatures} feature${summary.violatedFeatures > 1 ? "s" : ""} (${summary.totalFeatures} features scanned).`
5396
6040
  )
5397
6041
  );
@@ -5410,7 +6054,7 @@ ${compiledDetails}
5410
6054
  }
5411
6055
  if (!quiet) {
5412
6056
  console.log(
5413
- pc15__default.default.green(
6057
+ pc14__default.default.green(
5414
6058
  `\u2714 Dependency rules verified across ${summary.totalFeatures} feature${summary.totalFeatures === 1 ? "" : "s"}.`
5415
6059
  )
5416
6060
  );
@@ -5425,7 +6069,7 @@ ${compiledDetails}
5425
6069
  console.log(formatViolation(v));
5426
6070
  console.log("");
5427
6071
  }
5428
- console.log(pc15__default.default.red(`\u2716 Dependency rules check failed (1 error).`));
6072
+ console.log(pc14__default.default.red(`\u2716 Dependency rules check failed (1 error).`));
5429
6073
  console.log("");
5430
6074
  }
5431
6075
  }
@@ -5435,33 +6079,42 @@ ${compiledDetails}
5435
6079
  async function handleInit(type, flags = {}) {
5436
6080
  if (!type) {
5437
6081
  const choice = handleCancel(
5438
- await p15__namespace.select({
6082
+ await p19__namespace.select({
5439
6083
  message: "What would you like to initialize?",
5440
6084
  options: [
5441
6085
  {
5442
6086
  value: "env",
5443
6087
  label: "Environment Files",
5444
6088
  hint: "Generate local .env files from .env*.example templates"
6089
+ },
6090
+ {
6091
+ value: "env-examples",
6092
+ label: "Sync Env Examples",
6093
+ hint: "Safely clone and redact local .env files to .example templates"
5445
6094
  }
5446
6095
  ]
5447
6096
  })
5448
6097
  );
5449
6098
  if (choice === "env") {
5450
- await runEnvCommand(flags);
6099
+ await runEnvInit(flags);
6100
+ } else if (choice === "env-examples") {
6101
+ await runEnvInitExamples(flags);
5451
6102
  }
5452
6103
  return;
5453
6104
  }
5454
6105
  const normalized = type.trim().toLowerCase();
5455
6106
  if (normalized === "env") {
5456
- await runEnvCommand(flags);
6107
+ await runEnvInit(flags);
6108
+ } else if (normalized === "env-examples" || normalized === "envexamples") {
6109
+ await runEnvInitExamples(flags);
5457
6110
  } else {
5458
- p15__namespace.log.error(
5459
- pc15__default.default.red(
5460
- `Unknown init target: "${type}". Allowed targets: env.`
6111
+ p19__namespace.log.error(
6112
+ pc14__default.default.red(
6113
+ `Unknown init target: "${type}". Allowed targets: env, env-examples.`
5461
6114
  )
5462
6115
  );
5463
6116
  if (process.env.VITEST) {
5464
- throw new Error(`Unknown init target: "${type}". Allowed targets: env.`);
6117
+ throw new Error(`Unknown init target: "${type}". Allowed targets: env, env-examples.`);
5465
6118
  }
5466
6119
  process.exit(1);
5467
6120
  }
@@ -5472,8 +6125,8 @@ function createCli() {
5472
6125
  const cli = cac.cac("mason");
5473
6126
  cli.command("[...args]", "Interactive scaffolding and import wizard").option("-d, --dry-run", "Preview changes without writing to disk").option("-o, --overwrite", "Overwrite existing files").option("-y, --yes", "Accept defaults and skip interactive prompts").option("--registry", "Run in registry mode").option("--point-to <mapping>", "Point a dependency to an existing local module (e.g. --point-to time:mytime)").option("--alias <mapping>", "Import a dependency fresh under an alias name (e.g. --alias time:time-mason)").option("--tests", "Include test files (use --no-tests to exclude)").action(async (args, flags) => {
5474
6127
  if (args && args.length > 0) {
5475
- p15__namespace.log.error(
5476
- pc15__default.default.red(
6128
+ p19__namespace.log.error(
6129
+ pc14__default.default.red(
5477
6130
  `Unknown command: "${args.join(" ")}". Use --help to list available commands.`
5478
6131
  )
5479
6132
  );
@@ -5484,7 +6137,7 @@ function createCli() {
5484
6137
  const mode = getEffectiveMode(projectRoot, flags);
5485
6138
  if (mode === "registry") {
5486
6139
  const choice2 = handleCancel(
5487
- await p15__namespace.select({
6140
+ await p19__namespace.select({
5488
6141
  message: "\u{1F3DB}\uFE0F Mason (Registry Mode): What would you like to scaffold?",
5489
6142
  options: [
5490
6143
  {
@@ -5527,7 +6180,7 @@ function createCli() {
5527
6180
  return;
5528
6181
  }
5529
6182
  const choice = handleCancel(
5530
- await p15__namespace.select({
6183
+ await p19__namespace.select({
5531
6184
  message: "\u{1F9F1} Mason: What would you like to do?",
5532
6185
  options: [
5533
6186
  {
@@ -5546,9 +6199,9 @@ function createCli() {
5546
6199
  hint: "Scan codebase and verify Clean Architecture dependency rules"
5547
6200
  },
5548
6201
  {
5549
- value: "init",
5550
- label: "Initialize environment",
5551
- hint: "Generate local .env files from .env*.example templates"
6202
+ value: "env",
6203
+ label: "Environment variables",
6204
+ hint: "Manage .env files, add/delete keys, and sync templates"
5552
6205
  }
5553
6206
  ]
5554
6207
  })
@@ -5559,8 +6212,8 @@ function createCli() {
5559
6212
  await handleImport(void 0, void 0, flags);
5560
6213
  } else if (choice === "lint") {
5561
6214
  await handleLint(flags);
5562
- } else if (choice === "init") {
5563
- await handleInit("env", flags);
6215
+ } else if (choice === "env") {
6216
+ await handleEnv(void 0, [], flags);
5564
6217
  }
5565
6218
  } catch (err) {
5566
6219
  handleCliError(err);
@@ -5608,16 +6261,36 @@ function createCli() {
5608
6261
  handleCliError(err);
5609
6262
  }
5610
6263
  });
6264
+ cli.command(
6265
+ "env [subcommand] [...args]",
6266
+ "Environment variable management and template synchronization (init, init-examples, add, update, delete, audit)"
6267
+ ).option("-d, --dry-run", "Preview changes without writing to disk").option("-o, --overwrite", "Overwrite existing files").option("-e, --env <environments>", "Comma-separated target environments (e.g. dev,prod)").example("mason env").example("mason env init").example("mason env init-examples").example("mason env add API_KEY secret123").example("mason env update API_KEY newsecret").example("mason env delete API_KEY").example("mason env audit").action(async (subcommand, args = [], flags = {}) => {
6268
+ try {
6269
+ await handleEnv(subcommand, args, flags);
6270
+ } catch (err) {
6271
+ handleCliError(err);
6272
+ }
6273
+ });
5611
6274
  cli.command(
5612
6275
  "init [type]",
5613
- "Initialize project configurations and resources (e.g. 'mason init env')"
5614
- ).option("-d, --dry-run", "Preview changes without writing to disk").option("-o, --overwrite", "Overwrite existing .env files").example("mason init env").example("mason init env --overwrite").example("mason init env --dry-run").action(async (type, flags = {}) => {
6276
+ "Initialize project configurations (legacy shorthand: use 'mason env init')"
6277
+ ).option("-d, --dry-run", "Preview changes without writing to disk").option("-o, --overwrite", "Overwrite existing files").example("mason init env").example("mason init env-examples").action(async (type, flags = {}) => {
5615
6278
  try {
5616
6279
  await handleInit(type, flags);
5617
6280
  } catch (err) {
5618
6281
  handleCliError(err);
5619
6282
  }
5620
6283
  });
6284
+ cli.command(
6285
+ "env-examples",
6286
+ "Shorthand for 'mason env init-examples'"
6287
+ ).option("-d, --dry-run", "Preview changes without writing to disk").option("-o, --overwrite", "Overwrite existing .env*.example files").action(async (flags = {}) => {
6288
+ try {
6289
+ await handleEnv("init-examples", [], flags);
6290
+ } catch (err) {
6291
+ handleCliError(err);
6292
+ }
6293
+ });
5621
6294
  const createSubtypes = [
5622
6295
  "feature",
5623
6296
  "shared",
@@ -5649,7 +6322,7 @@ function handleCliError(err) {
5649
6322
  process.exit(0);
5650
6323
  }
5651
6324
  const message = err instanceof Error ? err.message : String(err);
5652
- p15__namespace.log.error(pc15__default.default.red(`Error: ${message}`));
6325
+ p19__namespace.log.error(pc14__default.default.red(`Error: ${message}`));
5653
6326
  if (process.env.VITEST) {
5654
6327
  throw err;
5655
6328
  }
@@ -5662,6 +6335,7 @@ async function runCli(argv = process.argv) {
5662
6335
 
5663
6336
  exports.DEFAULT_REGISTRY_BASE = DEFAULT_REGISTRY_BASE;
5664
6337
  exports.DependencyRuleError = DependencyRuleError;
6338
+ exports.EnvEditor = EnvEditor;
5665
6339
  exports.FeatureDependencyGraph = FeatureDependencyGraph;
5666
6340
  exports.PromptCancelledError = PromptCancelledError;
5667
6341
  exports.computeDirectoryHash = computeDirectoryHash;
@@ -5669,6 +6343,7 @@ exports.concreteInfraTemplate = concreteInfraTemplate;
5669
6343
  exports.createCli = createCli;
5670
6344
  exports.detectPackageManager = detectPackageManager;
5671
6345
  exports.diProviderTemplate = diProviderTemplate;
6346
+ exports.discoverEnvironments = discoverEnvironments;
5672
6347
  exports.domainClassTemplate = domainClassTemplate;
5673
6348
  exports.domainInterfaceTemplate = domainInterfaceTemplate;
5674
6349
  exports.domainValueObjectTemplate = domainValueObjectTemplate;
@@ -5706,6 +6381,7 @@ exports.getRegistryBase = getRegistryBase;
5706
6381
  exports.getTemplatesDir = getTemplatesDir;
5707
6382
  exports.handleCancel = handleCancel;
5708
6383
  exports.handleCreate = handleCreate;
6384
+ exports.handleEnv = handleEnv;
5709
6385
  exports.handleImport = handleImport;
5710
6386
  exports.handleInit = handleInit;
5711
6387
  exports.handleLint = handleLint;
@@ -5734,10 +6410,19 @@ exports.promptProperties = promptProperties;
5734
6410
  exports.removeInterfacePrefix = removeInterfacePrefix;
5735
6411
  exports.renderTemplate = renderTemplate;
5736
6412
  exports.renderTemplateFile = renderTemplateFile;
6413
+ exports.resolveEnvFilename = resolveEnvFilename;
5737
6414
  exports.resolveFeaturesDir = resolveFeaturesDir;
5738
6415
  exports.resolveSharedDir = resolveSharedDir;
5739
6416
  exports.runCli = runCli;
6417
+ exports.runEnvAdd = runEnvAdd;
6418
+ exports.runEnvAudit = runEnvAudit;
5740
6419
  exports.runEnvCommand = runEnvCommand;
6420
+ exports.runEnvDelete = runEnvDelete;
6421
+ exports.runEnvExamplesCommand = runEnvExamplesCommand;
6422
+ exports.runEnvInit = runEnvInit;
6423
+ exports.runEnvInitExamples = runEnvInitExamples;
6424
+ exports.runEnvMenu = runEnvMenu;
6425
+ exports.runEnvUpdate = runEnvUpdate;
5741
6426
  exports.runSharedCommand = runSharedCommand;
5742
6427
  exports.stubInfraTemplate = stubInfraTemplate;
5743
6428
  exports.synthesizeCrudMethods = synthesizeCrudMethods;