@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/bin.cjs CHANGED
@@ -2,9 +2,9 @@
2
2
  'use strict';
3
3
 
4
4
  var cac = require('cac');
5
- var p15 = require('@clack/prompts');
6
- var pc15 = require('picocolors');
7
- var fs10 = require('fs');
5
+ var p19 = require('@clack/prompts');
6
+ var pc13 = require('picocolors');
7
+ var fs14 = require('fs');
8
8
  var path2 = require('path');
9
9
  var url = require('url');
10
10
  var Handlebars = require('handlebars');
@@ -32,16 +32,16 @@ function _interopNamespace(e) {
32
32
  return Object.freeze(n);
33
33
  }
34
34
 
35
- var p15__namespace = /*#__PURE__*/_interopNamespace(p15);
36
- var pc15__default = /*#__PURE__*/_interopDefault(pc15);
37
- var fs10__default = /*#__PURE__*/_interopDefault(fs10);
35
+ var p19__namespace = /*#__PURE__*/_interopNamespace(p19);
36
+ var pc13__default = /*#__PURE__*/_interopDefault(pc13);
37
+ var fs14__default = /*#__PURE__*/_interopDefault(fs14);
38
38
  var path2__default = /*#__PURE__*/_interopDefault(path2);
39
39
  var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
40
40
 
41
41
  function writeFileSafely(absolutePath, content, options = {}) {
42
42
  const projectRoot = options.projectRoot || process.cwd();
43
43
  const relPath = path2__default.default.relative(projectRoot, absolutePath).replace(/\\/g, "/");
44
- const existedBefore = fs10__default.default.existsSync(absolutePath);
44
+ const existedBefore = fs14__default.default.existsSync(absolutePath);
45
45
  if (options.dryRun) {
46
46
  return {
47
47
  relativePath: relPath,
@@ -61,10 +61,10 @@ function writeFileSafely(absolutePath, content, options = {}) {
61
61
  };
62
62
  }
63
63
  const dir = path2__default.default.dirname(absolutePath);
64
- if (!fs10__default.default.existsSync(dir)) {
65
- fs10__default.default.mkdirSync(dir, { recursive: true });
64
+ if (!fs14__default.default.existsSync(dir)) {
65
+ fs14__default.default.mkdirSync(dir, { recursive: true });
66
66
  }
67
- fs10__default.default.writeFileSync(absolutePath, content, "utf-8");
67
+ fs14__default.default.writeFileSync(absolutePath, content, "utf-8");
68
68
  return {
69
69
  relativePath: relPath,
70
70
  absolutePath,
@@ -76,17 +76,17 @@ function writeFileSafely(absolutePath, content, options = {}) {
76
76
  function printGeneratedFiles(files, isDryRun = false) {
77
77
  console.log("");
78
78
  if (isDryRun) {
79
- p15__namespace.log.warn(pc15__default.default.yellow(pc15__default.default.bold("[DRY RUN PREVIEW] No files were written to disk.")));
79
+ p19__namespace.log.warn(pc13__default.default.yellow(pc13__default.default.bold("[DRY RUN PREVIEW] No files were written to disk.")));
80
80
  }
81
81
  for (const f of files) {
82
82
  if (f.action === "created") {
83
- p15__namespace.log.success(`${pc15__default.default.bold(f.relativePath)} ${pc15__default.default.dim("(created)")}`);
83
+ p19__namespace.log.success(`${pc13__default.default.bold(f.relativePath)} ${pc13__default.default.dim("(created)")}`);
84
84
  } else if (f.action === "overwritten") {
85
- p15__namespace.log.warn(`${pc15__default.default.bold(f.relativePath)} ${pc15__default.default.dim("(overwritten)")}`);
85
+ p19__namespace.log.warn(`${pc13__default.default.bold(f.relativePath)} ${pc13__default.default.dim("(overwritten)")}`);
86
86
  } else if (f.action === "skipped") {
87
- p15__namespace.log.info(`${pc15__default.default.dim(f.relativePath)} ${pc15__default.default.dim("(skipped - already exists, pass -o to overwrite)")}`);
87
+ p19__namespace.log.info(`${pc13__default.default.dim(f.relativePath)} ${pc13__default.default.dim("(skipped - already exists, pass -o to overwrite)")}`);
88
88
  } else {
89
- p15__namespace.log.info(`${pc15__default.default.bold(f.relativePath)} ${pc15__default.default.dim("(preview)")}`);
89
+ p19__namespace.log.info(`${pc13__default.default.bold(f.relativePath)} ${pc13__default.default.dim("(preview)")}`);
90
90
  }
91
91
  }
92
92
  }
@@ -158,9 +158,9 @@ function loadMasonConfig(startDir = process.cwd()) {
158
158
  let current = path2__default.default.resolve(startDir);
159
159
  while (true) {
160
160
  const configPath = path2__default.default.join(current, "mason.config.json");
161
- if (fs10__default.default.existsSync(configPath)) {
161
+ if (fs14__default.default.existsSync(configPath)) {
162
162
  try {
163
- return JSON.parse(fs10__default.default.readFileSync(configPath, "utf-8"));
163
+ return JSON.parse(fs14__default.default.readFileSync(configPath, "utf-8"));
164
164
  } catch {
165
165
  return null;
166
166
  }
@@ -175,7 +175,7 @@ function getEffectiveMode(projectRoot, flags) {
175
175
  if (flags?.registry) return "registry";
176
176
  const config = loadMasonConfig(projectRoot);
177
177
  if (config?.mode) return config.mode;
178
- if (fs10__default.default.existsSync(path2__default.default.join(projectRoot, "index.json")) && (fs10__default.default.existsSync(path2__default.default.join(projectRoot, "features")) || fs10__default.default.existsSync(path2__default.default.join(projectRoot, "shared")) || fs10__default.default.existsSync(path2__default.default.join(projectRoot, "src/features")) || fs10__default.default.existsSync(path2__default.default.join(projectRoot, "src/shared")))) {
178
+ if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "index.json")) && (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "features")) || fs14__default.default.existsSync(path2__default.default.join(projectRoot, "shared")) || fs14__default.default.existsSync(path2__default.default.join(projectRoot, "src/features")) || fs14__default.default.existsSync(path2__default.default.join(projectRoot, "src/shared")))) {
179
179
  return "registry";
180
180
  }
181
181
  return "app";
@@ -189,12 +189,12 @@ function getConfiguredFeaturesDir(projectRoot, flags) {
189
189
  }
190
190
  const mode = getEffectiveMode(projectRoot, flags);
191
191
  if (mode === "registry") {
192
- if (fs10__default.default.existsSync(path2__default.default.join(projectRoot, "src/features"))) {
192
+ if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "src/features"))) {
193
193
  return path2__default.default.join(projectRoot, "src/features");
194
194
  }
195
195
  return path2__default.default.join(projectRoot, "features");
196
196
  }
197
- if (fs10__default.default.existsSync(path2__default.default.join(projectRoot, "src/features"))) {
197
+ if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "src/features"))) {
198
198
  return path2__default.default.join(projectRoot, "src/features");
199
199
  }
200
200
  return path2__default.default.join(projectRoot, "features");
@@ -208,12 +208,12 @@ function getConfiguredSharedDir(projectRoot, flags) {
208
208
  }
209
209
  const mode = getEffectiveMode(projectRoot, flags);
210
210
  if (mode === "registry") {
211
- if (fs10__default.default.existsSync(path2__default.default.join(projectRoot, "src/shared"))) {
211
+ if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "src/shared"))) {
212
212
  return path2__default.default.join(projectRoot, "src/shared");
213
213
  }
214
214
  return path2__default.default.join(projectRoot, "shared");
215
215
  }
216
- if (fs10__default.default.existsSync(path2__default.default.join(projectRoot, "src/shared"))) {
216
+ if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "src/shared"))) {
217
217
  return path2__default.default.join(projectRoot, "src/shared");
218
218
  }
219
219
  return path2__default.default.join(projectRoot, "shared");
@@ -223,7 +223,7 @@ function getConfiguredSharedDir(projectRoot, flags) {
223
223
  function findProjectRoot(startDir = process.cwd()) {
224
224
  let current = path2__default.default.resolve(startDir);
225
225
  while (true) {
226
- if (fs10__default.default.existsSync(path2__default.default.join(current, "package.json"))) {
226
+ if (fs14__default.default.existsSync(path2__default.default.join(current, "package.json"))) {
227
227
  return current;
228
228
  }
229
229
  const parent = path2__default.default.dirname(current);
@@ -241,9 +241,9 @@ function resolveSharedDir(projectRoot, flags) {
241
241
  }
242
242
  function listExistingFeatures(projectRoot) {
243
243
  const featuresDir = resolveFeaturesDir(projectRoot);
244
- if (!fs10__default.default.existsSync(featuresDir)) return [];
244
+ if (!fs14__default.default.existsSync(featuresDir)) return [];
245
245
  try {
246
- const entries = fs10__default.default.readdirSync(featuresDir, { withFileTypes: true });
246
+ const entries = fs14__default.default.readdirSync(featuresDir, { withFileTypes: true });
247
247
  return entries.filter((e) => e.isDirectory()).map((e) => e.name).sort();
248
248
  } catch {
249
249
  return [];
@@ -254,9 +254,9 @@ function listDomainInterfaces(projectRoot, featureName) {
254
254
  const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
255
255
  for (const feat of features) {
256
256
  const domainDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
257
- if (!fs10__default.default.existsSync(domainDir)) continue;
257
+ if (!fs14__default.default.existsSync(domainDir)) continue;
258
258
  try {
259
- const files = fs10__default.default.readdirSync(domainDir);
259
+ const files = fs14__default.default.readdirSync(domainDir);
260
260
  for (const file of files) {
261
261
  if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
262
262
  const name = file.replace(/\.ts$/, "");
@@ -269,7 +269,7 @@ function listDomainInterfaces(projectRoot, featureName) {
269
269
  });
270
270
  } else {
271
271
  try {
272
- const content = fs10__default.default.readFileSync(fullPath, "utf-8");
272
+ const content = fs14__default.default.readFileSync(fullPath, "utf-8");
273
273
  if (/export\s+(?:abstract\s+class|interface)\s+(\w+)/.test(content)) {
274
274
  results.push({
275
275
  name,
@@ -292,9 +292,9 @@ function listDomainEntities(projectRoot, featureName) {
292
292
  const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
293
293
  for (const feat of features) {
294
294
  const domainDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
295
- if (!fs10__default.default.existsSync(domainDir)) continue;
295
+ if (!fs14__default.default.existsSync(domainDir)) continue;
296
296
  try {
297
- const files = fs10__default.default.readdirSync(domainDir);
297
+ const files = fs14__default.default.readdirSync(domainDir);
298
298
  for (const file of files) {
299
299
  if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
300
300
  const name = file.replace(/\.ts$/, "");
@@ -317,9 +317,9 @@ function listUseCases(projectRoot, featureName) {
317
317
  const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
318
318
  for (const feat of features) {
319
319
  const useCasesDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feat, "useCases");
320
- if (!fs10__default.default.existsSync(useCasesDir)) continue;
320
+ if (!fs14__default.default.existsSync(useCasesDir)) continue;
321
321
  try {
322
- const files = fs10__default.default.readdirSync(useCasesDir);
322
+ const files = fs14__default.default.readdirSync(useCasesDir);
323
323
  for (const file of files) {
324
324
  if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
325
325
  const name = file.replace(/\.ts$/, "");
@@ -351,29 +351,29 @@ hbs.registerHelper("join", (arr, sep) => {
351
351
  });
352
352
  var cachedTemplatesDir = null;
353
353
  function getTemplatesDir() {
354
- if (cachedTemplatesDir && fs10__default.default.existsSync(cachedTemplatesDir)) {
354
+ if (cachedTemplatesDir && fs14__default.default.existsSync(cachedTemplatesDir)) {
355
355
  return cachedTemplatesDir;
356
356
  }
357
357
  const currentDir = typeof __dirname !== "undefined" ? __dirname : path2__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('bin.cjs', document.baseURI).href))));
358
358
  const cand1 = path2__default.default.resolve(currentDir, "../../templates");
359
- if (fs10__default.default.existsSync(cand1)) {
359
+ if (fs14__default.default.existsSync(cand1)) {
360
360
  cachedTemplatesDir = cand1;
361
361
  return cand1;
362
362
  }
363
363
  const cand2 = path2__default.default.resolve(currentDir, "../templates");
364
- if (fs10__default.default.existsSync(cand2)) {
364
+ if (fs14__default.default.existsSync(cand2)) {
365
365
  cachedTemplatesDir = cand2;
366
366
  return cand2;
367
367
  }
368
368
  const cand3 = path2__default.default.resolve(currentDir, "templates");
369
- if (fs10__default.default.existsSync(cand3)) {
369
+ if (fs14__default.default.existsSync(cand3)) {
370
370
  cachedTemplatesDir = cand3;
371
371
  return cand3;
372
372
  }
373
373
  let curr = currentDir;
374
374
  while (true) {
375
375
  const candTemplates = path2__default.default.join(curr, "templates");
376
- if (fs10__default.default.existsSync(candTemplates)) {
376
+ if (fs14__default.default.existsSync(candTemplates)) {
377
377
  cachedTemplatesDir = candTemplates;
378
378
  return candTemplates;
379
379
  }
@@ -386,7 +386,7 @@ function getTemplatesDir() {
386
386
  var templateCache = /* @__PURE__ */ new Map();
387
387
  function loadTemplate(relativePath) {
388
388
  const fullPath = path2__default.default.isAbsolute(relativePath) ? relativePath : path2__default.default.join(getTemplatesDir(), relativePath);
389
- return fs10__default.default.readFileSync(fullPath, "utf-8");
389
+ return fs14__default.default.readFileSync(fullPath, "utf-8");
390
390
  }
391
391
  function renderTemplateFile(relativePath, context) {
392
392
  let compiled = templateCache.get(relativePath);
@@ -498,7 +498,7 @@ function generateInterfaceCode(ifaceName, kind = "abstractClass", entityName, me
498
498
  const idKey = `${entityKey}Id`;
499
499
  const listKey = `${entityKey}s`;
500
500
  const formattedCustomMethods = customMethods.map((m) => {
501
- const params = m.params && m.params.length > 0 ? m.params.map((p18) => `${p18.name}: ${p18.type}`).join("; ") : "";
501
+ const params = m.params && m.params.length > 0 ? m.params.map((p22) => `${p22.name}: ${p22.type}`).join("; ") : "";
502
502
  const returnType = m.returnType ? `Promise<${m.returnType}>` : "Promise<void>";
503
503
  return {
504
504
  name: m.name,
@@ -759,7 +759,7 @@ function parseInterfaceMethodsAndImports(content, targetIfaceName) {
759
759
  };
760
760
  }
761
761
  function findInterfaceFile(projectRoot, ifaceName, featureName, customPath) {
762
- if (customPath && fs10__default.default.existsSync(customPath)) {
762
+ if (customPath && fs14__default.default.existsSync(customPath)) {
763
763
  return { filePath: customPath, ifaceName };
764
764
  }
765
765
  const candidateNames = [
@@ -770,21 +770,21 @@ function findInterfaceFile(projectRoot, ifaceName, featureName, customPath) {
770
770
  const features = featureName ? [featureName, ...listExistingFeatures(projectRoot).filter((f) => f !== featureName)] : listExistingFeatures(projectRoot);
771
771
  for (const feat of features) {
772
772
  const domainDir = path2__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
773
- if (!fs10__default.default.existsSync(domainDir)) continue;
773
+ if (!fs14__default.default.existsSync(domainDir)) continue;
774
774
  for (const cand of candidateNames) {
775
775
  const p1 = path2__default.default.join(domainDir, `${cand}.ts`);
776
- if (fs10__default.default.existsSync(p1)) {
776
+ if (fs14__default.default.existsSync(p1)) {
777
777
  return { filePath: p1, ifaceName: cand, feature: feat };
778
778
  }
779
779
  }
780
780
  }
781
781
  for (const cand of candidateNames) {
782
782
  const p1 = path2__default.default.join(projectRoot, "domain", `${cand}.ts`);
783
- if (fs10__default.default.existsSync(p1)) return { filePath: p1, ifaceName: cand };
783
+ if (fs14__default.default.existsSync(p1)) return { filePath: p1, ifaceName: cand };
784
784
  const p22 = path2__default.default.join(projectRoot, "src", "domain", `${cand}.ts`);
785
- if (fs10__default.default.existsSync(p22)) return { filePath: p22, ifaceName: cand };
785
+ if (fs14__default.default.existsSync(p22)) return { filePath: p22, ifaceName: cand };
786
786
  const p32 = path2__default.default.join(projectRoot, "interfaces", `${cand}.ts`);
787
- if (fs10__default.default.existsSync(p32)) return { filePath: p32, ifaceName: cand };
787
+ if (fs14__default.default.existsSync(p32)) return { filePath: p32, ifaceName: cand };
788
788
  }
789
789
  return null;
790
790
  }
@@ -807,7 +807,7 @@ function loadInterfaceHierarchy(projectRoot, initialIfaceName, featureName, cust
807
807
  while (currentFile && !visited.has(currentFile)) {
808
808
  visited.add(currentFile);
809
809
  try {
810
- const content = fs10__default.default.readFileSync(currentFile, "utf-8");
810
+ const content = fs14__default.default.readFileSync(currentFile, "utf-8");
811
811
  const parsed = parseInterfaceMethodsAndImports(content, currentName);
812
812
  for (const m of parsed.methods) {
813
813
  if (!allMethods.some((existing) => existing.name === m.name)) {
@@ -1079,22 +1079,22 @@ function generateUseCaseCode(useCaseName, dependencies = [], inputProps = [], ou
1079
1079
  from: /^I[A-Z]/.test(dep) ? `../domain/${dep}.js` : `./${dep}.js`
1080
1080
  }));
1081
1081
  const domainTypesToImport = new Set(domainImports);
1082
- for (const p18 of [...inputProps, ...outputProps]) {
1083
- const rawType = p18.type.trim();
1082
+ for (const p22 of [...inputProps, ...outputProps]) {
1083
+ const rawType = p22.type.trim();
1084
1084
  const baseType = rawType.replace(/\[\]$/, "").trim();
1085
1085
  if (!primitiveTypes.has(baseType) && /^[A-Z][A-Za-z0-9_]*$/.test(baseType) && !dependencies.includes(baseType)) {
1086
1086
  domainTypesToImport.add(baseType);
1087
1087
  }
1088
1088
  }
1089
- const formattedInputProps = inputProps.map((p18) => ({
1090
- name: p18.name,
1091
- optional: p18.optional,
1092
- type: p18.optional && !p18.type.includes("undefined") ? `${p18.type} | undefined` : p18.type
1089
+ const formattedInputProps = inputProps.map((p22) => ({
1090
+ name: p22.name,
1091
+ optional: p22.optional,
1092
+ type: p22.optional && !p22.type.includes("undefined") ? `${p22.type} | undefined` : p22.type
1093
1093
  }));
1094
- const formattedOutputProps = outputProps.map((p18) => ({
1095
- name: p18.name,
1096
- optional: p18.optional,
1097
- type: p18.optional && !p18.type.includes("undefined") ? `${p18.type} | undefined` : p18.type
1094
+ const formattedOutputProps = outputProps.map((p22) => ({
1095
+ name: p22.name,
1096
+ optional: p22.optional,
1097
+ type: p22.optional && !p22.type.includes("undefined") ? `${p22.type} | undefined` : p22.type
1098
1098
  }));
1099
1099
  const formattedDeps = dependencies.map((dep) => ({
1100
1100
  key: toCamelCase(dep),
@@ -1281,7 +1281,7 @@ function generateHttpHandler(options) {
1281
1281
  const pxDir = path2__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress");
1282
1282
  const handlersDir = path2__default.default.join(pxDir, "handlers");
1283
1283
  const pxIndexPath = path2__default.default.join(pxDir, "index.ts");
1284
- if (!fs10__default.default.existsSync(pxIndexPath)) {
1284
+ if (!fs14__default.default.existsSync(pxIndexPath)) {
1285
1285
  const featurePath = options.routePrefix || `/${options.feature.toLowerCase()}`;
1286
1286
  const pxIndexContent = renderTemplate(expressIndexTemplate, {
1287
1287
  routePath: featurePath
@@ -1318,8 +1318,8 @@ function updateOrGenerateDiProvider(featureDir, featureName, bindings = [], opti
1318
1318
  const providerPath = path2__default.default.join(featureDir, "diProvider.ts");
1319
1319
  const pascalFeature = toPascalCase(featureName);
1320
1320
  const providerModuleName = `${pascalFeature}Provider`;
1321
- if (fs10__default.default.existsSync(providerPath) && !options.overwrite) {
1322
- let content = fs10__default.default.readFileSync(providerPath, "utf-8");
1321
+ if (fs14__default.default.existsSync(providerPath) && !options.overwrite) {
1322
+ let content = fs14__default.default.readFileSync(providerPath, "utf-8");
1323
1323
  content = content.replace(/\n*export\s+const\s+ScaffoldProvider\s*=[^;]+;?/g, "");
1324
1324
  for (const b of bindings) {
1325
1325
  const ifaceImp = b.ifaceImportPath || `./domain/${b.ifaceName}.js`;
@@ -1765,23 +1765,23 @@ var PromptCancelledError = class extends Error {
1765
1765
  }
1766
1766
  };
1767
1767
  function handleCancel(result) {
1768
- if (p15__namespace.isCancel(result)) {
1769
- p15__namespace.cancel("Operation cancelled.");
1768
+ if (p19__namespace.isCancel(result)) {
1769
+ p19__namespace.cancel("Operation cancelled.");
1770
1770
  throw new PromptCancelledError();
1771
1771
  }
1772
1772
  return result;
1773
1773
  }
1774
1774
  function printBanner() {
1775
1775
  console.log("");
1776
- p15__namespace.intro(pc15__default.default.bgCyan(pc15__default.default.black(" @solid-stack/mason ")));
1776
+ p19__namespace.intro(pc13__default.default.bgCyan(pc13__default.default.black(" @solid-stack/mason ")));
1777
1777
  }
1778
1778
  async function promptProperties(options = {}) {
1779
1779
  const properties = options.defaults ? [...options.defaults] : [];
1780
1780
  if (properties.length > 0) {
1781
- const summary = properties.map((p18) => `${p18.name}: ${p18.type}${p18.optional ? "?" : ""}`).join(", ");
1782
- p15__namespace.log.info(pc15__default.default.dim(`Pre-configured fields: ${summary}`));
1781
+ const summary = properties.map((p22) => `${p22.name}: ${p22.type}${p22.optional ? "?" : ""}`).join(", ");
1782
+ p19__namespace.log.info(pc13__default.default.dim(`Pre-configured fields: ${summary}`));
1783
1783
  const addMore = handleCancel(
1784
- await p15__namespace.confirm({
1784
+ await p19__namespace.confirm({
1785
1785
  message: "Would you like to add custom fields/properties?",
1786
1786
  initialValue: false
1787
1787
  })
@@ -1790,10 +1790,10 @@ async function promptProperties(options = {}) {
1790
1790
  return properties;
1791
1791
  }
1792
1792
  }
1793
- p15__namespace.log.info(pc15__default.default.cyan("Enter properties (leave name blank when finished):"));
1793
+ p19__namespace.log.info(pc13__default.default.cyan("Enter properties (leave name blank when finished):"));
1794
1794
  while (true) {
1795
1795
  const name = handleCancel(
1796
- await p15__namespace.text({
1796
+ await p19__namespace.text({
1797
1797
  message: "Property name (or press Enter to finish):",
1798
1798
  placeholder: "e.g. title, email, status"
1799
1799
  })
@@ -1802,7 +1802,7 @@ async function promptProperties(options = {}) {
1802
1802
  break;
1803
1803
  }
1804
1804
  const type = handleCancel(
1805
- await p15__namespace.select({
1805
+ await p19__namespace.select({
1806
1806
  message: `Type for property "${name.trim()}":`,
1807
1807
  options: [
1808
1808
  { value: "string", label: "string" },
@@ -1819,7 +1819,7 @@ async function promptProperties(options = {}) {
1819
1819
  let finalType = type;
1820
1820
  if (type === "custom") {
1821
1821
  finalType = handleCancel(
1822
- await p15__namespace.text({
1822
+ await p19__namespace.text({
1823
1823
  message: `Enter custom type for "${name.trim()}":`,
1824
1824
  placeholder: "e.g. UserRole, string | null",
1825
1825
  validate: (val) => val && val.trim() ? void 0 : "Type cannot be empty"
@@ -1827,7 +1827,7 @@ async function promptProperties(options = {}) {
1827
1827
  );
1828
1828
  }
1829
1829
  const optional = handleCancel(
1830
- await p15__namespace.confirm({
1830
+ await p19__namespace.confirm({
1831
1831
  message: `Is "${name.trim()}" optional?`,
1832
1832
  initialValue: false
1833
1833
  })
@@ -1837,8 +1837,8 @@ async function promptProperties(options = {}) {
1837
1837
  type: finalType.trim(),
1838
1838
  optional
1839
1839
  });
1840
- p15__namespace.log.success(
1841
- pc15__default.default.green(`Added: ${name.trim()}${optional ? "?" : ""}: ${finalType.trim()}`)
1840
+ p19__namespace.log.success(
1841
+ pc13__default.default.green(`Added: ${name.trim()}${optional ? "?" : ""}: ${finalType.trim()}`)
1842
1842
  );
1843
1843
  }
1844
1844
  return properties;
@@ -1854,7 +1854,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
1854
1854
  }
1855
1855
  if (!name) {
1856
1856
  name = handleCancel(
1857
- await p15__namespace.text({
1857
+ await p19__namespace.text({
1858
1858
  message: "What is the feature name?",
1859
1859
  placeholder: "e.g. users, auth, orders, billing",
1860
1860
  validate: (val) => {
@@ -1870,7 +1870,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
1870
1870
  let targetDirRel = defaultDir;
1871
1871
  if (!flags.yes && !flags.target && !flags.dest) {
1872
1872
  targetDirRel = handleCancel(
1873
- await p15__namespace.text({
1873
+ await p19__namespace.text({
1874
1874
  message: "Target directory for the feature:",
1875
1875
  initialValue: defaultDir,
1876
1876
  defaultValue: defaultDir
@@ -1892,14 +1892,14 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
1892
1892
  const customUseCases = [];
1893
1893
  if (!flags.yes) {
1894
1894
  includeExpress = handleCancel(
1895
- await p15__namespace.confirm({
1895
+ await p19__namespace.confirm({
1896
1896
  message: "Include Express Presentation layer (pxExpress routes & handlers)?",
1897
1897
  initialValue: true
1898
1898
  })
1899
1899
  );
1900
1900
  if (includeExpress) {
1901
1901
  routePath = handleCancel(
1902
- await p15__namespace.text({
1902
+ await p19__namespace.text({
1903
1903
  message: "Express route prefix:",
1904
1904
  initialValue: `/${normalizedName}`,
1905
1905
  defaultValue: `/${normalizedName}`
@@ -1907,14 +1907,14 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
1907
1907
  ).trim();
1908
1908
  }
1909
1909
  includeDomain = handleCancel(
1910
- await p15__namespace.confirm({
1910
+ await p19__namespace.confirm({
1911
1911
  message: "Include Domain Entity/Entities?",
1912
1912
  initialValue: true
1913
1913
  })
1914
1914
  );
1915
1915
  if (includeDomain) {
1916
1916
  const domainInput = handleCancel(
1917
- await p15__namespace.text({
1917
+ await p19__namespace.text({
1918
1918
  message: "Domain entity name(s) (comma-separated):",
1919
1919
  initialValue: defaultEntity,
1920
1920
  defaultValue: defaultEntity,
@@ -1933,21 +1933,21 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
1933
1933
  entityNames = [defaultEntity];
1934
1934
  }
1935
1935
  includeInterface = handleCancel(
1936
- await p15__namespace.confirm({
1936
+ await p19__namespace.confirm({
1937
1937
  message: `Include Domain Repository interface(s) for ${entityNames.join(", ")}?`,
1938
1938
  initialValue: true
1939
1939
  })
1940
1940
  );
1941
1941
  if (includeInterface) {
1942
1942
  includeInfra = handleCancel(
1943
- await p15__namespace.confirm({
1943
+ await p19__namespace.confirm({
1944
1944
  message: `Include Infrastructure Stub implementation(s) for ${entityNames.join(", ")}?`,
1945
1945
  initialValue: true
1946
1946
  })
1947
1947
  );
1948
1948
  }
1949
1949
  includeUseCase = handleCancel(
1950
- await p15__namespace.confirm({
1950
+ await p19__namespace.confirm({
1951
1951
  message: "Include Domain Use Cases?",
1952
1952
  initialValue: true
1953
1953
  })
@@ -1961,7 +1961,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
1961
1961
  { value: "delete", label: "Delete (Delete<Entity>)", hint: "DELETE /:id" }
1962
1962
  ];
1963
1963
  crudOperations = handleCancel(
1964
- await p15__namespace.multiselect({
1964
+ await p19__namespace.multiselect({
1965
1965
  message: "Select standard CRUD use cases to generate:",
1966
1966
  options: crudChoices,
1967
1967
  initialValues: ["create", "read", "list", "update", "delete"],
@@ -1969,13 +1969,13 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
1969
1969
  })
1970
1970
  );
1971
1971
  includeTests = handleCancel(
1972
- await p15__namespace.confirm({
1972
+ await p19__namespace.confirm({
1973
1973
  message: "Generate Vitest unit tests for use cases?",
1974
1974
  initialValue: true
1975
1975
  })
1976
1976
  );
1977
1977
  const wantCustom = handleCancel(
1978
- await p15__namespace.confirm({
1978
+ await p19__namespace.confirm({
1979
1979
  message: "Do you want to add any custom use cases to this feature?",
1980
1980
  initialValue: false
1981
1981
  })
@@ -1985,7 +1985,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
1985
1985
  const availableIfaces = entityNames.map((e) => `I${e}Repository`);
1986
1986
  while (addMore) {
1987
1987
  const customName = handleCancel(
1988
- await p15__namespace.text({
1988
+ await p19__namespace.text({
1989
1989
  message: "Custom Use Case name:",
1990
1990
  placeholder: "e.g. ResetPassword, VerifyEmail, AssignRole",
1991
1991
  validate: (v) => v && v.trim() ? void 0 : "Use Case name cannot be empty"
@@ -1995,7 +1995,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
1995
1995
  let selectedDeps = [];
1996
1996
  if (availableIfaces.length > 0) {
1997
1997
  selectedDeps = handleCancel(
1998
- await p15__namespace.multiselect({
1998
+ await p19__namespace.multiselect({
1999
1999
  message: `Select domain interfaces to inject into ${customUcName}:`,
2000
2000
  options: availableIfaces.map((i) => ({ value: i, label: i })),
2001
2001
  required: false
@@ -2004,7 +2004,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2004
2004
  }
2005
2005
  let customInputProps = [];
2006
2006
  const hasInput = handleCancel(
2007
- await p15__namespace.confirm({
2007
+ await p19__namespace.confirm({
2008
2008
  message: `Does ${customUcName} accept input arguments?`,
2009
2009
  initialValue: true
2010
2010
  })
@@ -2015,7 +2015,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2015
2015
  }
2016
2016
  let customOutputProps = [];
2017
2017
  const hasCustomOutput = handleCancel(
2018
- await p15__namespace.confirm({
2018
+ await p19__namespace.confirm({
2019
2019
  message: `Does ${customUcName} return custom output data?`,
2020
2020
  initialValue: false
2021
2021
  })
@@ -2025,7 +2025,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2025
2025
  });
2026
2026
  }
2027
2027
  const customIncludeTest = handleCancel(
2028
- await p15__namespace.confirm({
2028
+ await p19__namespace.confirm({
2029
2029
  message: `Generate Vitest unit test for ${customUcName}?`,
2030
2030
  initialValue: true
2031
2031
  })
@@ -2035,14 +2035,14 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2035
2035
  let customHttpPath = `/${toKebabCase(customUcName)}`;
2036
2036
  if (includeExpress) {
2037
2037
  customCreateHttp = handleCancel(
2038
- await p15__namespace.confirm({
2038
+ await p19__namespace.confirm({
2039
2039
  message: `Generate a matching ExpressRoute HTTP handler for ${customUcName}?`,
2040
2040
  initialValue: true
2041
2041
  })
2042
2042
  );
2043
2043
  if (customCreateHttp) {
2044
2044
  customHttpMethod = handleCancel(
2045
- await p15__namespace.select({
2045
+ await p19__namespace.select({
2046
2046
  message: "HTTP method for route:",
2047
2047
  options: [
2048
2048
  { value: "post", label: "POST" },
@@ -2055,7 +2055,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2055
2055
  })
2056
2056
  );
2057
2057
  customHttpPath = handleCancel(
2058
- await p15__namespace.text({
2058
+ await p19__namespace.text({
2059
2059
  message: "Route subpath (relative to feature prefix):",
2060
2060
  initialValue: `/${toKebabCase(customUcName)}`,
2061
2061
  defaultValue: `/${toKebabCase(customUcName)}`
@@ -2076,7 +2076,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2076
2076
  validationFields: customInputProps
2077
2077
  });
2078
2078
  addMore = handleCancel(
2079
- await p15__namespace.confirm({
2079
+ await p19__namespace.confirm({
2080
2080
  message: "Add another custom use case?",
2081
2081
  initialValue: false
2082
2082
  })
@@ -2085,7 +2085,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2085
2085
  }
2086
2086
  }
2087
2087
  includeDiProvider = handleCancel(
2088
- await p15__namespace.confirm({
2088
+ await p19__namespace.confirm({
2089
2089
  message: "Generate / update feature DI provider (diProvider.ts)?",
2090
2090
  initialValue: true
2091
2091
  })
@@ -2097,8 +2097,8 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2097
2097
  entityNames = [defaultEntity];
2098
2098
  }
2099
2099
  }
2100
- const s = p15__namespace.spinner();
2101
- s.start(`Generating feature '${pc15__default.default.cyan(normalizedName)}'...`);
2100
+ const s = p19__namespace.spinner();
2101
+ s.start(`Generating feature '${pc13__default.default.cyan(normalizedName)}'...`);
2102
2102
  const options = {
2103
2103
  name: normalizedName,
2104
2104
  projectRoot,
@@ -2120,7 +2120,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2120
2120
  const files = generateFeature(options);
2121
2121
  if (isRegistry) {
2122
2122
  const registryPath = path2__default.default.join(targetDir, "registry.json");
2123
- if (!fs10__default.default.existsSync(registryPath)) {
2123
+ if (!fs14__default.default.existsSync(registryPath)) {
2124
2124
  const manifest = {
2125
2125
  name: toKebabCase(normalizedName),
2126
2126
  type: "feature",
@@ -2144,8 +2144,8 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
2144
2144
  }
2145
2145
  s.stop("Feature scaffolded successfully!");
2146
2146
  printGeneratedFiles(files, options.dryRun);
2147
- p15__namespace.outro(
2148
- pc15__default.default.green(
2147
+ p19__namespace.outro(
2148
+ pc13__default.default.green(
2149
2149
  `\u2713 Feature '${normalizedName}' initialized in ${path2__default.default.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2150
2150
  )
2151
2151
  );
@@ -2259,7 +2259,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2259
2259
  }
2260
2260
  if (!name) {
2261
2261
  name = handleCancel(
2262
- await p15__namespace.text({
2262
+ await p19__namespace.text({
2263
2263
  message: "What is the shared module name?",
2264
2264
  placeholder: "e.g. hasher, time, uuid, cache, logger",
2265
2265
  validate: (val) => {
@@ -2275,7 +2275,7 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2275
2275
  let targetDirRel = defaultDir;
2276
2276
  if (!flags.yes && !flags.target && !flags.dest) {
2277
2277
  targetDirRel = handleCancel(
2278
- await p15__namespace.text({
2278
+ await p19__namespace.text({
2279
2279
  message: "Target directory for the shared module:",
2280
2280
  initialValue: defaultDir,
2281
2281
  defaultValue: defaultDir
@@ -2287,21 +2287,21 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2287
2287
  let includeStub = true;
2288
2288
  if (!flags.yes) {
2289
2289
  description = handleCancel(
2290
- await p15__namespace.text({
2290
+ await p19__namespace.text({
2291
2291
  message: "Module description (optional):",
2292
2292
  placeholder: "e.g. In-memory caching and Redis port abstraction",
2293
2293
  initialValue: ""
2294
2294
  })
2295
2295
  ).trim();
2296
2296
  includeStub = handleCancel(
2297
- await p15__namespace.confirm({
2297
+ await p19__namespace.confirm({
2298
2298
  message: "Include stub implementation in infrastructure/?",
2299
2299
  initialValue: true
2300
2300
  })
2301
2301
  );
2302
2302
  }
2303
- const s = p15__namespace.spinner();
2304
- s.start(`Generating shared module '${pc15__default.default.cyan(normalizedName)}'...`);
2303
+ const s = p19__namespace.spinner();
2304
+ s.start(`Generating shared module '${pc13__default.default.cyan(normalizedName)}'...`);
2305
2305
  const files = generateShared({
2306
2306
  name: normalizedName,
2307
2307
  description,
@@ -2314,8 +2314,8 @@ async function runSharedCommand(sharedNameArg, flags = {}) {
2314
2314
  });
2315
2315
  s.stop("Shared module generated successfully!");
2316
2316
  printGeneratedFiles(files, Boolean(flags.dryRun));
2317
- p15__namespace.outro(
2318
- pc15__default.default.green(
2317
+ p19__namespace.outro(
2318
+ pc13__default.default.green(
2319
2319
  `\u2713 Shared module '${normalizedName}' initialized in ${path2__default.default.relative(projectRoot, targetDir)} (uncommitted, unregistered)`
2320
2320
  )
2321
2321
  );
@@ -2329,14 +2329,14 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2329
2329
  const featureOptions = existingFeatures.map((f) => ({ value: f, label: f }));
2330
2330
  featureOptions.push({ value: "__custom__", label: "\u270F\uFE0F Enter custom feature name..." });
2331
2331
  const selected = handleCancel(
2332
- await p15__namespace.select({
2332
+ await p19__namespace.select({
2333
2333
  message: "Select target feature:",
2334
2334
  options: featureOptions
2335
2335
  })
2336
2336
  );
2337
2337
  if (selected === "__custom__") {
2338
2338
  feature = handleCancel(
2339
- await p15__namespace.text({
2339
+ await p19__namespace.text({
2340
2340
  message: "Enter feature name:",
2341
2341
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2342
2342
  })
@@ -2346,7 +2346,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2346
2346
  }
2347
2347
  } else {
2348
2348
  feature = handleCancel(
2349
- await p15__namespace.text({
2349
+ await p19__namespace.text({
2350
2350
  message: "Enter target feature name:",
2351
2351
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2352
2352
  })
@@ -2357,7 +2357,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2357
2357
  let name = useCaseNameArg?.trim();
2358
2358
  if (!name) {
2359
2359
  name = handleCancel(
2360
- await p15__namespace.text({
2360
+ await p19__namespace.text({
2361
2361
  message: "Use Case name:",
2362
2362
  placeholder: "e.g. CreateUser, GetUser, CancelOrder",
2363
2363
  validate: (v) => v && v.trim() ? void 0 : "Use Case name cannot be empty"
@@ -2373,7 +2373,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2373
2373
  label: i.name
2374
2374
  }));
2375
2375
  selectedDeps = handleCancel(
2376
- await p15__namespace.multiselect({
2376
+ await p19__namespace.multiselect({
2377
2377
  message: "Select domain interfaces to inject into use case:",
2378
2378
  options: multiOptions,
2379
2379
  required: false
@@ -2388,7 +2388,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2388
2388
  let httpPath = "/";
2389
2389
  if (!flags.yes) {
2390
2390
  const hasInput = handleCancel(
2391
- await p15__namespace.confirm({
2391
+ await p19__namespace.confirm({
2392
2392
  message: "Does this use case accept input arguments?",
2393
2393
  initialValue: true
2394
2394
  })
@@ -2398,7 +2398,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2398
2398
  });
2399
2399
  }
2400
2400
  const hasCustomOutput = handleCancel(
2401
- await p15__namespace.confirm({
2401
+ await p19__namespace.confirm({
2402
2402
  message: "Does this use case return custom output data?",
2403
2403
  initialValue: false
2404
2404
  })
@@ -2408,20 +2408,20 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2408
2408
  });
2409
2409
  }
2410
2410
  includeTest = handleCancel(
2411
- await p15__namespace.confirm({
2411
+ await p19__namespace.confirm({
2412
2412
  message: "Generate Vitest unit test skeleton (.test.ts)?",
2413
2413
  initialValue: true
2414
2414
  })
2415
2415
  );
2416
2416
  createHttp = handleCancel(
2417
- await p15__namespace.confirm({
2417
+ await p19__namespace.confirm({
2418
2418
  message: "Generate a matching ExpressRoute HTTP handler?",
2419
2419
  initialValue: false
2420
2420
  })
2421
2421
  );
2422
2422
  if (createHttp) {
2423
2423
  httpMethod = handleCancel(
2424
- await p15__namespace.select({
2424
+ await p19__namespace.select({
2425
2425
  message: "HTTP method for route:",
2426
2426
  options: [
2427
2427
  { value: "post", label: "POST" },
@@ -2434,7 +2434,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2434
2434
  })
2435
2435
  );
2436
2436
  httpPath = handleCancel(
2437
- await p15__namespace.text({
2437
+ await p19__namespace.text({
2438
2438
  message: "Route subpath (relative to feature prefix):",
2439
2439
  initialValue: "/",
2440
2440
  defaultValue: "/"
@@ -2442,8 +2442,8 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2442
2442
  ).trim();
2443
2443
  }
2444
2444
  }
2445
- const s = p15__namespace.spinner();
2446
- s.start(`Generating use case '${pc15__default.default.cyan(ucName)}'...`);
2445
+ const s = p19__namespace.spinner();
2446
+ s.start(`Generating use case '${pc13__default.default.cyan(ucName)}'...`);
2447
2447
  const options = {
2448
2448
  name: ucName,
2449
2449
  feature,
@@ -2475,7 +2475,7 @@ async function runUseCaseCommand(useCaseNameArg, flags = {}) {
2475
2475
  }
2476
2476
  s.stop("Use case generated successfully!");
2477
2477
  printGeneratedFiles(files, options.dryRun);
2478
- p15__namespace.outro(pc15__default.default.green(`Use case '${ucName}' created in feature '${feature}'!`));
2478
+ p19__namespace.outro(pc13__default.default.green(`Use case '${ucName}' created in feature '${feature}'!`));
2479
2479
  }
2480
2480
  async function runDomainCommand(domainNameArg, flags = {}) {
2481
2481
  const projectRoot = findProjectRoot();
@@ -2486,14 +2486,14 @@ async function runDomainCommand(domainNameArg, flags = {}) {
2486
2486
  const featureOptions = existingFeatures.map((f) => ({ value: f, label: f }));
2487
2487
  featureOptions.push({ value: "__custom__", label: "\u270F\uFE0F Enter custom feature name..." });
2488
2488
  const selected = handleCancel(
2489
- await p15__namespace.select({
2489
+ await p19__namespace.select({
2490
2490
  message: "Select target feature:",
2491
2491
  options: featureOptions
2492
2492
  })
2493
2493
  );
2494
2494
  if (selected === "__custom__") {
2495
2495
  feature = handleCancel(
2496
- await p15__namespace.text({
2496
+ await p19__namespace.text({
2497
2497
  message: "Enter feature name:",
2498
2498
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2499
2499
  })
@@ -2503,7 +2503,7 @@ async function runDomainCommand(domainNameArg, flags = {}) {
2503
2503
  }
2504
2504
  } else {
2505
2505
  feature = handleCancel(
2506
- await p15__namespace.text({
2506
+ await p19__namespace.text({
2507
2507
  message: "Enter target feature name:",
2508
2508
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2509
2509
  })
@@ -2514,7 +2514,7 @@ async function runDomainCommand(domainNameArg, flags = {}) {
2514
2514
  let name = domainNameArg?.trim();
2515
2515
  if (!name) {
2516
2516
  name = handleCancel(
2517
- await p15__namespace.text({
2517
+ await p19__namespace.text({
2518
2518
  message: "Domain model / entity name:",
2519
2519
  placeholder: "e.g. User, Order, Product, Address",
2520
2520
  validate: (v) => v && v.trim() ? void 0 : "Domain name cannot be empty"
@@ -2526,7 +2526,7 @@ async function runDomainCommand(domainNameArg, flags = {}) {
2526
2526
  let properties = [];
2527
2527
  if (!flags.yes) {
2528
2528
  kind = handleCancel(
2529
- await p15__namespace.select({
2529
+ await p19__namespace.select({
2530
2530
  message: "Select domain model type:",
2531
2531
  options: [
2532
2532
  { value: "interface", label: "TypeScript Interface (pure data structure)" },
@@ -2545,8 +2545,8 @@ async function runDomainCommand(domainNameArg, flags = {}) {
2545
2545
  defaults: kind === "valueObject" ? [{ name: "value", type: "string" }] : defaultProps
2546
2546
  });
2547
2547
  }
2548
- const s = p15__namespace.spinner();
2549
- s.start(`Generating domain model '${pc15__default.default.cyan(entityName)}'...`);
2548
+ const s = p19__namespace.spinner();
2549
+ s.start(`Generating domain model '${pc13__default.default.cyan(entityName)}'...`);
2550
2550
  const options = {
2551
2551
  name: entityName,
2552
2552
  feature,
@@ -2559,7 +2559,7 @@ async function runDomainCommand(domainNameArg, flags = {}) {
2559
2559
  const file = generateDomain(options);
2560
2560
  s.stop("Domain model generated successfully!");
2561
2561
  printGeneratedFiles([file], options.dryRun);
2562
- p15__namespace.outro(pc15__default.default.green(`Domain model '${entityName}' created in feature '${feature}'!`));
2562
+ p19__namespace.outro(pc13__default.default.green(`Domain model '${entityName}' created in feature '${feature}'!`));
2563
2563
  }
2564
2564
  async function runInfrastructureCommand(classNameArg, flags = {}) {
2565
2565
  const projectRoot = findProjectRoot();
@@ -2568,7 +2568,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2568
2568
  let feature = flags.feature?.trim();
2569
2569
  if (!flags.yes && !flags.global && !flags.feature) {
2570
2570
  scope = handleCancel(
2571
- await p15__namespace.select({
2571
+ await p19__namespace.select({
2572
2572
  message: "Where should this infrastructure implementation be placed?",
2573
2573
  options: [
2574
2574
  { value: "feature", label: "Feature-level (features/<feature>/infrastructure)" },
@@ -2583,14 +2583,14 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2583
2583
  const featureOptions = existingFeatures.map((f) => ({ value: f, label: f }));
2584
2584
  featureOptions.push({ value: "__custom__", label: "\u270F\uFE0F Enter custom feature name..." });
2585
2585
  const selected = handleCancel(
2586
- await p15__namespace.select({
2586
+ await p19__namespace.select({
2587
2587
  message: "Select target feature:",
2588
2588
  options: featureOptions
2589
2589
  })
2590
2590
  );
2591
2591
  if (selected === "__custom__") {
2592
2592
  feature = handleCancel(
2593
- await p15__namespace.text({
2593
+ await p19__namespace.text({
2594
2594
  message: "Enter feature name:",
2595
2595
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2596
2596
  })
@@ -2600,7 +2600,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2600
2600
  }
2601
2601
  } else {
2602
2602
  feature = handleCancel(
2603
- await p15__namespace.text({
2603
+ await p19__namespace.text({
2604
2604
  message: "Enter target feature name:",
2605
2605
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2606
2606
  })
@@ -2613,7 +2613,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2613
2613
  let name = classNameArg?.trim();
2614
2614
  if (!name) {
2615
2615
  name = handleCancel(
2616
- await p15__namespace.text({
2616
+ await p19__namespace.text({
2617
2617
  message: "Infrastructure class name:",
2618
2618
  placeholder: "e.g. StubUserRepository, PostgresUserRepository, S3FileStorage",
2619
2619
  validate: (v) => v && v.trim() ? void 0 : "Class name cannot be empty"
@@ -2632,7 +2632,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2632
2632
  (i) => className.toLowerCase().includes(removeInterfacePrefix(i.name).toLowerCase())
2633
2633
  );
2634
2634
  const ifaceChoice = handleCancel(
2635
- await p15__namespace.select({
2635
+ await p19__namespace.select({
2636
2636
  message: "Does this class implement a domain interface or abstract class?",
2637
2637
  options: [
2638
2638
  ...interfaces.map((i) => ({ value: i.name, label: i.name })),
@@ -2644,7 +2644,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2644
2644
  );
2645
2645
  if (ifaceChoice === "__custom__") {
2646
2646
  implementsInterface = handleCancel(
2647
- await p15__namespace.text({
2647
+ await p19__namespace.text({
2648
2648
  message: "Enter interface or abstract class name:",
2649
2649
  placeholder: "e.g. IUserRepository, BaseStorageAdapter",
2650
2650
  validate: (v) => v && v.trim() ? void 0 : "Name cannot be empty"
@@ -2655,14 +2655,14 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2655
2655
  }
2656
2656
  } else {
2657
2657
  const wantImpl = handleCancel(
2658
- await p15__namespace.confirm({
2658
+ await p19__namespace.confirm({
2659
2659
  message: "Does this class implement a domain interface or abstract class?",
2660
2660
  initialValue: false
2661
2661
  })
2662
2662
  );
2663
2663
  if (wantImpl) {
2664
2664
  implementsInterface = handleCancel(
2665
- await p15__namespace.text({
2665
+ await p19__namespace.text({
2666
2666
  message: "Enter interface or abstract class name:",
2667
2667
  placeholder: "e.g. IUserRepository, BaseStorageAdapter",
2668
2668
  validate: (v) => v && v.trim() ? void 0 : "Name cannot be empty"
@@ -2682,7 +2682,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2682
2682
  const allInterfaces = listDomainInterfaces(projectRoot);
2683
2683
  if (allInterfaces.length > 0) {
2684
2684
  const ifaceChoice = handleCancel(
2685
- await p15__namespace.select({
2685
+ await p19__namespace.select({
2686
2686
  message: "Does this class implement an interface or abstract class?",
2687
2687
  options: [
2688
2688
  ...allInterfaces.map((i) => ({ value: i.name, label: `${i.name} (${i.feature})` })),
@@ -2694,7 +2694,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2694
2694
  );
2695
2695
  if (ifaceChoice === "__custom__") {
2696
2696
  implementsInterface = handleCancel(
2697
- await p15__namespace.text({
2697
+ await p19__namespace.text({
2698
2698
  message: "Enter interface or abstract class name:",
2699
2699
  placeholder: "e.g. IAuthRepository",
2700
2700
  validate: (v) => v && v.trim() ? void 0 : "Name cannot be empty"
@@ -2707,7 +2707,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2707
2707
  }
2708
2708
  if (!flags.yes && !flags.kind) {
2709
2709
  kind = handleCancel(
2710
- await p15__namespace.select({
2710
+ await p19__namespace.select({
2711
2711
  message: "Select implementation kind:",
2712
2712
  options: [
2713
2713
  { value: "stub", label: "In-Memory Stub (with in-memory store and test helper methods)" },
@@ -2718,7 +2718,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2718
2718
  );
2719
2719
  if (scope === "feature" && feature && implementsInterface) {
2720
2720
  registerInProvider = handleCancel(
2721
- await p15__namespace.confirm({
2721
+ await p19__namespace.confirm({
2722
2722
  message: "Register this implementation in feature diProvider.ts?",
2723
2723
  initialValue: true
2724
2724
  })
@@ -2727,8 +2727,8 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2727
2727
  } else if (flags.yes && scope === "feature" && feature && implementsInterface) {
2728
2728
  registerInProvider = !flags.noProvider;
2729
2729
  }
2730
- const s = p15__namespace.spinner();
2731
- s.start(`Generating infrastructure class '${pc15__default.default.cyan(className)}'...`);
2730
+ const s = p19__namespace.spinner();
2731
+ s.start(`Generating infrastructure class '${pc13__default.default.cyan(className)}'...`);
2732
2732
  const files = [];
2733
2733
  const options = {
2734
2734
  name: className,
@@ -2763,7 +2763,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
2763
2763
  }
2764
2764
  s.stop("Infrastructure class generated successfully!");
2765
2765
  printGeneratedFiles(files, options.dryRun);
2766
- p15__namespace.outro(pc15__default.default.green(`Infrastructure class '${className}' created!`));
2766
+ p19__namespace.outro(pc13__default.default.green(`Infrastructure class '${className}' created!`));
2767
2767
  }
2768
2768
  async function runInterfaceCommand(interfaceNameArg, flags = {}) {
2769
2769
  const projectRoot = findProjectRoot();
@@ -2774,14 +2774,14 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
2774
2774
  const featureOptions = existingFeatures.map((f) => ({ value: f, label: f }));
2775
2775
  featureOptions.push({ value: "__custom__", label: "\u270F\uFE0F Enter custom feature name..." });
2776
2776
  const selected = handleCancel(
2777
- await p15__namespace.select({
2777
+ await p19__namespace.select({
2778
2778
  message: "Select target feature:",
2779
2779
  options: featureOptions
2780
2780
  })
2781
2781
  );
2782
2782
  if (selected === "__custom__") {
2783
2783
  feature = handleCancel(
2784
- await p15__namespace.text({
2784
+ await p19__namespace.text({
2785
2785
  message: "Enter feature name:",
2786
2786
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2787
2787
  })
@@ -2791,7 +2791,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
2791
2791
  }
2792
2792
  } else {
2793
2793
  feature = handleCancel(
2794
- await p15__namespace.text({
2794
+ await p19__namespace.text({
2795
2795
  message: "Enter target feature name:",
2796
2796
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2797
2797
  })
@@ -2802,7 +2802,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
2802
2802
  let name = interfaceNameArg?.trim();
2803
2803
  if (!name) {
2804
2804
  name = handleCancel(
2805
- await p15__namespace.text({
2805
+ await p19__namespace.text({
2806
2806
  message: "Domain interface name:",
2807
2807
  placeholder: "e.g. IUserRepository, IPaymentService",
2808
2808
  validate: (v) => v && v.trim() ? void 0 : "Interface name cannot be empty"
@@ -2820,7 +2820,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
2820
2820
  if (!flags.yes) {
2821
2821
  if (existingEntities.length > 0) {
2822
2822
  const selectedEntity = handleCancel(
2823
- await p15__namespace.select({
2823
+ await p19__namespace.select({
2824
2824
  message: "Select domain entity associated with this interface:",
2825
2825
  options: [
2826
2826
  ...existingEntities.map((e) => ({ value: e.name, label: e.name })),
@@ -2831,7 +2831,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
2831
2831
  );
2832
2832
  if (selectedEntity === "__custom__") {
2833
2833
  entityName = handleCancel(
2834
- await p15__namespace.text({
2834
+ await p19__namespace.text({
2835
2835
  message: "Enter entity name:",
2836
2836
  defaultValue: removeInterfacePrefix(ifaceName).replace(/Repository$|Service$/, "")
2837
2837
  })
@@ -2841,7 +2841,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
2841
2841
  }
2842
2842
  }
2843
2843
  kind = handleCancel(
2844
- await p15__namespace.select({
2844
+ await p19__namespace.select({
2845
2845
  message: "Interface definition style:",
2846
2846
  options: [
2847
2847
  { value: "abstractClass", label: "Abstract Class (Recommended - acts as DI token & type)" },
@@ -2851,7 +2851,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
2851
2851
  })
2852
2852
  );
2853
2853
  methodsPreset = handleCancel(
2854
- await p15__namespace.select({
2854
+ await p19__namespace.select({
2855
2855
  message: "Method signature preset:",
2856
2856
  options: [
2857
2857
  { value: "crud", label: "Standard CRUD (GetById, List, Create, Update, Delete)" },
@@ -2861,22 +2861,22 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
2861
2861
  })
2862
2862
  );
2863
2863
  generateStub = handleCancel(
2864
- await p15__namespace.confirm({
2864
+ await p19__namespace.confirm({
2865
2865
  message: "Auto-generate Infrastructure Stub implementation?",
2866
2866
  initialValue: true
2867
2867
  })
2868
2868
  );
2869
2869
  if (generateStub) {
2870
2870
  registerInProvider = handleCancel(
2871
- await p15__namespace.confirm({
2871
+ await p19__namespace.confirm({
2872
2872
  message: "Auto-register interface & stub in feature diProvider.ts?",
2873
2873
  initialValue: true
2874
2874
  })
2875
2875
  );
2876
2876
  }
2877
2877
  }
2878
- const s = p15__namespace.spinner();
2879
- s.start(`Generating interface '${pc15__default.default.cyan(ifaceName)}'...`);
2878
+ const s = p19__namespace.spinner();
2879
+ s.start(`Generating interface '${pc13__default.default.cyan(ifaceName)}'...`);
2880
2880
  const files = [];
2881
2881
  const options = {
2882
2882
  name: ifaceName,
@@ -2925,7 +2925,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
2925
2925
  }
2926
2926
  s.stop("Interface generated successfully!");
2927
2927
  printGeneratedFiles(files, options.dryRun);
2928
- p15__namespace.outro(pc15__default.default.green(`Interface '${ifaceName}' created in feature '${feature}'!`));
2928
+ p19__namespace.outro(pc13__default.default.green(`Interface '${ifaceName}' created in feature '${feature}'!`));
2929
2929
  }
2930
2930
  async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
2931
2931
  const projectRoot = findProjectRoot();
@@ -2936,14 +2936,14 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
2936
2936
  const featureOptions = existingFeatures.map((f) => ({ value: f, label: f }));
2937
2937
  featureOptions.push({ value: "__custom__", label: "\u270F\uFE0F Enter custom feature name..." });
2938
2938
  const selected = handleCancel(
2939
- await p15__namespace.select({
2939
+ await p19__namespace.select({
2940
2940
  message: "Select target feature:",
2941
2941
  options: featureOptions
2942
2942
  })
2943
2943
  );
2944
2944
  if (selected === "__custom__") {
2945
2945
  feature = handleCancel(
2946
- await p15__namespace.text({
2946
+ await p19__namespace.text({
2947
2947
  message: "Enter feature name:",
2948
2948
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2949
2949
  })
@@ -2953,7 +2953,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
2953
2953
  }
2954
2954
  } else {
2955
2955
  feature = handleCancel(
2956
- await p15__namespace.text({
2956
+ await p19__namespace.text({
2957
2957
  message: "Enter target feature name:",
2958
2958
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
2959
2959
  })
@@ -2964,7 +2964,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
2964
2964
  let name = handlerNameArg?.trim();
2965
2965
  if (!name) {
2966
2966
  name = handleCancel(
2967
- await p15__namespace.text({
2967
+ await p19__namespace.text({
2968
2968
  message: "HTTP Route Handler class name:",
2969
2969
  placeholder: "e.g. CreateUserHttp, GetUserHttp, HealthHttp",
2970
2970
  validate: (v) => v && v.trim() ? void 0 : "Handler name cannot be empty"
@@ -2983,7 +2983,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
2983
2983
  let validationFields = [];
2984
2984
  if (!flags.yes) {
2985
2985
  method = handleCancel(
2986
- await p15__namespace.select({
2986
+ await p19__namespace.select({
2987
2987
  message: "HTTP Method:",
2988
2988
  options: [
2989
2989
  { value: "get", label: "GET" },
@@ -2997,7 +2997,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
2997
2997
  );
2998
2998
  const defaultPath = method === "get" ? "/" : "/";
2999
2999
  subPath = handleCancel(
3000
- await p15__namespace.text({
3000
+ await p19__namespace.text({
3001
3001
  message: "Route subpath (relative to feature prefix):",
3002
3002
  initialValue: defaultPath,
3003
3003
  defaultValue: defaultPath
@@ -3008,7 +3008,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3008
3008
  const ucOptions = useCases.map((u) => ({ value: u.name, label: u.name }));
3009
3009
  ucOptions.push({ value: "__none__", label: "None / Standalone Handler" });
3010
3010
  const chosenUc = handleCancel(
3011
- await p15__namespace.select({
3011
+ await p19__namespace.select({
3012
3012
  message: "Connect this handler to a domain Use Case?",
3013
3013
  options: ucOptions,
3014
3014
  initialValue: ucOptions[0]?.value
@@ -3019,7 +3019,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3019
3019
  }
3020
3020
  }
3021
3021
  includeValidation = handleCancel(
3022
- await p15__namespace.confirm({
3022
+ await p19__namespace.confirm({
3023
3023
  message: "Include Zod inbound request validation?",
3024
3024
  initialValue: method !== "delete"
3025
3025
  })
@@ -3027,7 +3027,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3027
3027
  if (includeValidation) {
3028
3028
  const defaultSource = method === "get" ? "query" : "body";
3029
3029
  validationSource = handleCancel(
3030
- await p15__namespace.select({
3030
+ await p19__namespace.select({
3031
3031
  message: "Validation data source:",
3032
3032
  options: [
3033
3033
  { value: "body", label: "req.body (for POST / PUT / PATCH payloads)" },
@@ -3041,8 +3041,8 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3041
3041
  });
3042
3042
  }
3043
3043
  }
3044
- const s = p15__namespace.spinner();
3045
- s.start(`Generating HTTP handler '${pc15__default.default.cyan(className)}'...`);
3044
+ const s = p19__namespace.spinner();
3045
+ s.start(`Generating HTTP handler '${pc13__default.default.cyan(className)}'...`);
3046
3046
  const options = {
3047
3047
  name: className,
3048
3048
  feature,
@@ -3060,7 +3060,7 @@ async function runHttpHandlerCommand(handlerNameArg, flags = {}) {
3060
3060
  const files = generateHttpHandler(options);
3061
3061
  s.stop("HTTP handler generated successfully!");
3062
3062
  printGeneratedFiles(files, options.dryRun);
3063
- p15__namespace.outro(pc15__default.default.green(`HTTP handler '${className}' created in feature '${feature}'!`));
3063
+ p19__namespace.outro(pc13__default.default.green(`HTTP handler '${className}' created in feature '${feature}'!`));
3064
3064
  }
3065
3065
  function generateInjectableCode(className, dependencies = [], methods = [], implementsInterface) {
3066
3066
  const formattedDeps = dependencies.map((dep) => ({
@@ -3070,7 +3070,7 @@ function generateInjectableCode(className, dependencies = [], methods = [], impl
3070
3070
  const formattedMethods = methods.map((m) => {
3071
3071
  const isAsync = m.async !== false;
3072
3072
  const retType = m.returnType ? isAsync ? `Promise<${m.returnType}>` : m.returnType : isAsync ? "Promise<void>" : "void";
3073
- const params = m.params && m.params.length > 0 ? m.params.map((p18) => `${p18.name}: ${p18.type}`).join(", ") : "";
3073
+ const params = m.params && m.params.length > 0 ? m.params.map((p22) => `${p22.name}: ${p22.type}`).join(", ") : "";
3074
3074
  return {
3075
3075
  name: m.name,
3076
3076
  isAsync,
@@ -3140,7 +3140,7 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3140
3140
  let name = classNameArg?.trim();
3141
3141
  if (!name) {
3142
3142
  name = handleCancel(
3143
- await p15__namespace.text({
3143
+ await p19__namespace.text({
3144
3144
  message: "Injectable class name:",
3145
3145
  placeholder: "e.g. PasswordHasher, TokenService, UserTransformer",
3146
3146
  validate: (v) => v && v.trim() ? void 0 : "Class name cannot be empty"
@@ -3153,7 +3153,7 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3153
3153
  let customPath;
3154
3154
  if (!flags.yes) {
3155
3155
  location = handleCancel(
3156
- await p15__namespace.select({
3156
+ await p19__namespace.select({
3157
3157
  message: "Select target architectural location:",
3158
3158
  options: [
3159
3159
  { value: "feature-service", label: "Feature Service (features/<feature>/services/)" },
@@ -3171,14 +3171,14 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3171
3171
  const featureOptions = existingFeatures.map((f) => ({ value: f, label: f }));
3172
3172
  featureOptions.push({ value: "__custom__", label: "\u270F\uFE0F Enter custom feature name..." });
3173
3173
  const selected = handleCancel(
3174
- await p15__namespace.select({
3174
+ await p19__namespace.select({
3175
3175
  message: "Select target feature:",
3176
3176
  options: featureOptions
3177
3177
  })
3178
3178
  );
3179
3179
  if (selected === "__custom__") {
3180
3180
  feature = handleCancel(
3181
- await p15__namespace.text({
3181
+ await p19__namespace.text({
3182
3182
  message: "Enter feature name:",
3183
3183
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
3184
3184
  })
@@ -3188,7 +3188,7 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3188
3188
  }
3189
3189
  } else {
3190
3190
  feature = handleCancel(
3191
- await p15__namespace.text({
3191
+ await p19__namespace.text({
3192
3192
  message: "Enter target feature name:",
3193
3193
  validate: (v) => v && v.trim() ? void 0 : "Feature name cannot be empty"
3194
3194
  })
@@ -3198,7 +3198,7 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3198
3198
  feature = toCamelCase(feature);
3199
3199
  } else if (location === "custom") {
3200
3200
  customPath = handleCancel(
3201
- await p15__namespace.text({
3201
+ await p19__namespace.text({
3202
3202
  message: "Enter destination directory path:",
3203
3203
  placeholder: "e.g. src/services or lib/utils",
3204
3204
  validate: (v) => v && v.trim() ? void 0 : "Path cannot be empty"
@@ -3209,14 +3209,14 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3209
3209
  let generateInterface2 = false;
3210
3210
  if (!flags.yes) {
3211
3211
  generateInterface2 = handleCancel(
3212
- await p15__namespace.confirm({
3212
+ await p19__namespace.confirm({
3213
3213
  message: `Generate abstract class interface (I${className}) as runtime DI token?`,
3214
3214
  initialValue: false
3215
3215
  })
3216
3216
  );
3217
3217
  }
3218
- const s = p15__namespace.spinner();
3219
- s.start(`Generating injectable '${pc15__default.default.cyan(className)}'...`);
3218
+ const s = p19__namespace.spinner();
3219
+ s.start(`Generating injectable '${pc13__default.default.cyan(className)}'...`);
3220
3220
  const options = {
3221
3221
  name: className,
3222
3222
  feature,
@@ -3230,17 +3230,17 @@ async function runInjectableCommand(classNameArg, flags = {}) {
3230
3230
  const files = generateInjectable(options);
3231
3231
  s.stop("Injectable class generated successfully!");
3232
3232
  printGeneratedFiles(files, options.dryRun);
3233
- p15__namespace.outro(pc15__default.default.green(`Injectable '${className}' created successfully!`));
3233
+ p19__namespace.outro(pc13__default.default.green(`Injectable '${className}' created successfully!`));
3234
3234
  }
3235
- async function runEnvCommand(flags = {}) {
3235
+ async function runEnvInit(flags = {}) {
3236
3236
  const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3237
- const s = p15__namespace.spinner();
3237
+ const s = p19__namespace.spinner();
3238
3238
  s.start("Scanning for .example environment files...");
3239
- const files = fs10__default.default.readdirSync(projectRoot);
3239
+ const files = fs14__default.default.readdirSync(projectRoot);
3240
3240
  const exampleFiles = files.filter((file) => file.startsWith(".env") && file.endsWith(".example")).sort();
3241
3241
  if (exampleFiles.length === 0) {
3242
3242
  s.stop("No .example files found.");
3243
- p15__namespace.log.info(pc15__default.default.yellow(`No files matching '.env*.example' were found in ${projectRoot}`));
3243
+ p19__namespace.log.info(pc13__default.default.yellow(`No files matching '.env*.example' were found in ${projectRoot}`));
3244
3244
  return [];
3245
3245
  }
3246
3246
  s.message(`Found ${exampleFiles.length} template(s). Generating...`);
@@ -3249,25 +3249,667 @@ async function runEnvCommand(flags = {}) {
3249
3249
  const sourcePath = path2__default.default.join(projectRoot, exampleFile);
3250
3250
  const targetFile = exampleFile.replace(/\.example$/, "");
3251
3251
  const targetPath = path2__default.default.join(projectRoot, targetFile);
3252
- const content = fs10__default.default.readFileSync(sourcePath, "utf-8");
3252
+ let overwrite = flags.overwrite;
3253
+ if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs14__default.default.existsSync(targetPath)) {
3254
+ overwrite = await p19__namespace.confirm({
3255
+ message: `${targetFile} already exists. Overwrite?`,
3256
+ initialValue: false
3257
+ });
3258
+ if (p19__namespace.isCancel(overwrite)) {
3259
+ p19__namespace.cancel("Operation cancelled.");
3260
+ process.exit(0);
3261
+ }
3262
+ }
3263
+ const content = fs14__default.default.readFileSync(sourcePath, "utf-8");
3253
3264
  const genFile = writeFileSafely(targetPath, content, {
3254
3265
  projectRoot,
3255
3266
  dryRun: Boolean(flags.dryRun),
3256
- overwrite: Boolean(flags.overwrite)
3267
+ overwrite: Boolean(overwrite)
3257
3268
  });
3258
3269
  generatedFiles.push(genFile);
3259
3270
  }
3260
3271
  s.stop("Environment files processed!");
3261
3272
  printGeneratedFiles(generatedFiles, Boolean(flags.dryRun));
3262
- p15__namespace.outro(pc15__default.default.green("\u2713 Local environment files are ready!"));
3273
+ p19__namespace.outro(pc13__default.default.green("\u2713 Local environment files are ready!"));
3274
+ return generatedFiles;
3275
+ }
3276
+ var EnvEditor = class {
3277
+ lines;
3278
+ filePath;
3279
+ constructor(filePath) {
3280
+ this.filePath = filePath;
3281
+ this.lines = fs14__default.default.existsSync(filePath) ? fs14__default.default.readFileSync(filePath, "utf-8").split(/\r?\n/) : [];
3282
+ }
3283
+ getLines() {
3284
+ return [...this.lines];
3285
+ }
3286
+ getKeys() {
3287
+ return this.lines.filter((line) => line.trim() && !line.trim().startsWith("#")).map((line) => {
3288
+ const eqIdx = line.indexOf("=");
3289
+ return eqIdx !== -1 ? line.substring(0, eqIdx).trim() : line.trim();
3290
+ }).filter(Boolean);
3291
+ }
3292
+ getValue(key) {
3293
+ const line = this.lines.find((l) => {
3294
+ const trimmed = l.trim();
3295
+ if (trimmed.startsWith("#") || !trimmed) return false;
3296
+ const eqIdx = l.indexOf("=");
3297
+ const k = eqIdx !== -1 ? l.substring(0, eqIdx).trim() : l.trim();
3298
+ return k === key;
3299
+ });
3300
+ if (!line) return null;
3301
+ const eqIndex = line.indexOf("=");
3302
+ return eqIndex !== -1 ? line.substring(eqIndex + 1).trim() : "";
3303
+ }
3304
+ has(key) {
3305
+ return this.getKeys().includes(key);
3306
+ }
3307
+ set(key, value) {
3308
+ const newLine = `${key}=${value}`;
3309
+ const index = this.lines.findIndex((l) => {
3310
+ const trimmed = l.trim();
3311
+ if (trimmed.startsWith("#") || !trimmed) return false;
3312
+ const eqIdx = l.indexOf("=");
3313
+ const k = eqIdx !== -1 ? l.substring(0, eqIdx).trim() : l.trim();
3314
+ return k === key;
3315
+ });
3316
+ if (index !== -1) {
3317
+ this.lines[index] = newLine;
3318
+ } else {
3319
+ if (this.lines.length > 0 && this.lines[this.lines.length - 1] !== "") {
3320
+ this.lines.push("");
3321
+ }
3322
+ this.lines.push(newLine);
3323
+ }
3324
+ }
3325
+ delete(key) {
3326
+ const initialLen = this.lines.length;
3327
+ this.lines = this.lines.filter((l) => {
3328
+ const trimmed = l.trim();
3329
+ if (trimmed.startsWith("#") || !trimmed) return true;
3330
+ const eqIdx = l.indexOf("=");
3331
+ const k = eqIdx !== -1 ? l.substring(0, eqIdx).trim() : l.trim();
3332
+ return k !== key;
3333
+ });
3334
+ return this.lines.length !== initialLen;
3335
+ }
3336
+ redactAll() {
3337
+ this.lines = this.lines.map((line) => {
3338
+ const trimmed = line.trim();
3339
+ if (trimmed.startsWith("#") || !trimmed) return line;
3340
+ const eqIndex = line.indexOf("=");
3341
+ return eqIndex !== -1 ? line.substring(0, eqIndex + 1) : line;
3342
+ });
3343
+ }
3344
+ save() {
3345
+ const dir = path2__default.default.dirname(this.filePath);
3346
+ if (!fs14__default.default.existsSync(dir)) {
3347
+ fs14__default.default.mkdirSync(dir, { recursive: true });
3348
+ }
3349
+ fs14__default.default.writeFileSync(this.filePath, this.lines.join("\n"), "utf-8");
3350
+ }
3351
+ };
3352
+ function discoverEnvironments(projectRoot) {
3353
+ if (!fs14__default.default.existsSync(projectRoot)) {
3354
+ return ["local", "dev", "prod"];
3355
+ }
3356
+ const files = fs14__default.default.readdirSync(projectRoot);
3357
+ const envs = /* @__PURE__ */ new Set();
3358
+ for (const file of files) {
3359
+ if (file.startsWith(".env")) {
3360
+ const cleanName = file.replace(/\.example$/, "");
3361
+ const match = cleanName.match(/^\.env\.([a-zA-Z0-9_-]+)$/);
3362
+ if (match && match[1]) {
3363
+ envs.add(match[1]);
3364
+ } else if (cleanName === ".env") {
3365
+ envs.add("local");
3366
+ }
3367
+ }
3368
+ }
3369
+ return envs.size > 0 ? Array.from(envs) : ["local", "dev", "prod"];
3370
+ }
3371
+ function resolveEnvFilename(envName, isExample = false) {
3372
+ const base = envName === "local" ? ".env" : `.env.${envName}`;
3373
+ return isExample ? `${base}.example` : base;
3374
+ }
3375
+
3376
+ // src/commands/env/initExamples.ts
3377
+ async function runEnvInitExamples(flags = {}) {
3378
+ const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3379
+ const s = p19__namespace.spinner();
3380
+ s.start("Scanning for local environment files...");
3381
+ const files = fs14__default.default.readdirSync(projectRoot, { withFileTypes: true });
3382
+ const envFiles = files.filter((dirent) => dirent.isFile() && dirent.name.startsWith(".env") && !dirent.name.endsWith(".example")).map((dirent) => dirent.name).sort();
3383
+ if (envFiles.length === 0) {
3384
+ s.stop("No local .env files found.");
3385
+ p19__namespace.log.info(pc13__default.default.yellow(`No files matching '.env*' were found in ${projectRoot}`));
3386
+ return [];
3387
+ }
3388
+ s.message(`Found ${envFiles.length} local .env file(s). Generating templates...`);
3389
+ const generatedFiles = [];
3390
+ for (const envFile of envFiles) {
3391
+ const sourcePath = path2__default.default.join(projectRoot, envFile);
3392
+ const targetFile = `${envFile}.example`;
3393
+ const targetPath = path2__default.default.join(projectRoot, targetFile);
3394
+ let overwrite = flags.overwrite;
3395
+ if (overwrite === void 0 && !flags.dryRun && !flags.yes && !process.env.VITEST && process.stdin.isTTY && fs14__default.default.existsSync(targetPath)) {
3396
+ overwrite = await p19__namespace.confirm({
3397
+ message: `${targetFile} already exists. Overwrite with redacted values?`,
3398
+ initialValue: true
3399
+ });
3400
+ if (p19__namespace.isCancel(overwrite)) {
3401
+ p19__namespace.cancel("Operation cancelled.");
3402
+ process.exit(0);
3403
+ }
3404
+ }
3405
+ const editor = new EnvEditor(sourcePath);
3406
+ editor.redactAll();
3407
+ const redactedContent = editor.getLines().join("\n");
3408
+ const genFile = writeFileSafely(targetPath, redactedContent, {
3409
+ projectRoot,
3410
+ dryRun: Boolean(flags.dryRun),
3411
+ overwrite: Boolean(overwrite)
3412
+ });
3413
+ generatedFiles.push(genFile);
3414
+ }
3415
+ s.stop("Environment example templates generated!");
3416
+ printGeneratedFiles(generatedFiles, Boolean(flags.dryRun));
3417
+ p19__namespace.outro(pc13__default.default.green("\u2713 .env*.example files are up to date and safely redacted!"));
3263
3418
  return generatedFiles;
3264
3419
  }
3420
+ function isInteractive(flags) {
3421
+ if (flags.yes || Boolean(flags.nonInteractive)) return false;
3422
+ if (process.env.VITEST) return false;
3423
+ return Boolean(process.stdin.isTTY);
3424
+ }
3425
+ function getAllExistingKeys(projectRoot, envs) {
3426
+ const keys = /* @__PURE__ */ new Set();
3427
+ for (const env of envs) {
3428
+ const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3429
+ const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3430
+ if (fs14__default.default.existsSync(localPath)) {
3431
+ new EnvEditor(localPath).getKeys().forEach((k) => keys.add(k));
3432
+ }
3433
+ if (fs14__default.default.existsSync(examplePath)) {
3434
+ new EnvEditor(examplePath).getKeys().forEach((k) => keys.add(k));
3435
+ }
3436
+ }
3437
+ return Array.from(keys).sort();
3438
+ }
3439
+ async function runEnvAdd(key, value, flags = {}) {
3440
+ const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3441
+ const allEnvs = discoverEnvironments(projectRoot);
3442
+ let targetKey = key?.trim();
3443
+ if (!targetKey) {
3444
+ if (!isInteractive(flags)) {
3445
+ throw new Error("Variable key is required for 'mason env add <key> [value]'");
3446
+ }
3447
+ targetKey = handleCancel(
3448
+ await p19__namespace.text({
3449
+ message: "Enter the variable key name:",
3450
+ placeholder: "e.g. DATABASE_URL, STRIPE_KEY, PORT",
3451
+ validate: (val) => {
3452
+ if (!val || !val.trim()) return "Variable key name cannot be empty";
3453
+ if (/\s/.test(val.trim())) return "Variable key cannot contain spaces";
3454
+ if (val.includes("=")) return "Variable key cannot contain '='";
3455
+ return void 0;
3456
+ }
3457
+ })
3458
+ ).trim();
3459
+ }
3460
+ let targetEnvs = [];
3461
+ if (flags.env) {
3462
+ targetEnvs = String(flags.env).split(",").map((s) => s.trim()).filter(Boolean);
3463
+ } else if (!isInteractive(flags)) {
3464
+ targetEnvs = allEnvs;
3465
+ } else {
3466
+ targetEnvs = handleCancel(
3467
+ await p19__namespace.multiselect({
3468
+ message: `Which environments should receive ${pc13__default.default.bold(targetKey)}?`,
3469
+ options: allEnvs.map((env) => ({
3470
+ value: env,
3471
+ label: env === "local" ? "local (.env)" : `${env} (.env.${env})`
3472
+ })),
3473
+ initialValues: allEnvs,
3474
+ required: true
3475
+ })
3476
+ );
3477
+ }
3478
+ if (targetEnvs.length === 0) {
3479
+ p19__namespace.log.warn("No environments selected. Nothing was changed.");
3480
+ return { key: targetKey, environments: [] };
3481
+ }
3482
+ for (const env of targetEnvs) {
3483
+ let envVal = value;
3484
+ if (envVal === void 0) {
3485
+ if (!isInteractive(flags)) {
3486
+ envVal = "";
3487
+ } else {
3488
+ envVal = handleCancel(
3489
+ await p19__namespace.text({
3490
+ message: `Value for ${pc13__default.default.cyan(targetKey)} in ${pc13__default.default.bold(env)} (${resolveEnvFilename(env)})?`,
3491
+ initialValue: "",
3492
+ placeholder: "Leave empty for blank value"
3493
+ })
3494
+ );
3495
+ }
3496
+ } else if (isInteractive(flags) && !flags.yes) {
3497
+ envVal = handleCancel(
3498
+ await p19__namespace.text({
3499
+ message: `Value for ${pc13__default.default.cyan(targetKey)} in ${pc13__default.default.bold(env)} (${resolveEnvFilename(env)})?`,
3500
+ initialValue: value ?? "",
3501
+ placeholder: "Leave empty for blank value"
3502
+ })
3503
+ );
3504
+ }
3505
+ const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3506
+ const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3507
+ if (flags.dryRun) {
3508
+ p19__namespace.log.info(
3509
+ pc13__default.default.cyan(`[DRY RUN] Would set ${targetKey}=${envVal} in ${resolveEnvFilename(env, false)}`)
3510
+ );
3511
+ p19__namespace.log.info(
3512
+ pc13__default.default.cyan(`[DRY RUN] Would add ${targetKey}= to ${resolveEnvFilename(env, true)}`)
3513
+ );
3514
+ } else {
3515
+ const localEditor = new EnvEditor(localPath);
3516
+ localEditor.set(targetKey, envVal);
3517
+ localEditor.save();
3518
+ const exampleEditor = new EnvEditor(examplePath);
3519
+ exampleEditor.set(targetKey, "");
3520
+ exampleEditor.save();
3521
+ }
3522
+ }
3523
+ if (!flags.dryRun) {
3524
+ p19__namespace.log.success(
3525
+ pc13__default.default.green(
3526
+ `\u2713 Added ${pc13__default.default.bold(targetKey)} to [${targetEnvs.join(", ")}] and updated .example templates.`
3527
+ )
3528
+ );
3529
+ }
3530
+ return { key: targetKey, environments: targetEnvs };
3531
+ }
3532
+ async function runEnvUpdate(key, value, flags = {}) {
3533
+ const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3534
+ const allEnvs = discoverEnvironments(projectRoot);
3535
+ const existingKeys = getAllExistingKeys(projectRoot, allEnvs);
3536
+ let targetKey = key?.trim();
3537
+ if (!targetKey) {
3538
+ if (!isInteractive(flags)) {
3539
+ throw new Error("Variable key is required for 'mason env update <key> [value]'");
3540
+ }
3541
+ if (existingKeys.length === 0) {
3542
+ p19__namespace.log.error(pc13__default.default.red("No environment variables found to update."));
3543
+ return { key: "", environments: [] };
3544
+ }
3545
+ targetKey = handleCancel(
3546
+ await p19__namespace.select({
3547
+ message: "Select a variable to update:",
3548
+ options: existingKeys.map((k) => ({ value: k, label: k }))
3549
+ })
3550
+ );
3551
+ }
3552
+ const envsWithKey = allEnvs.filter((env) => {
3553
+ const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3554
+ return fs14__default.default.existsSync(localPath) && new EnvEditor(localPath).has(targetKey);
3555
+ });
3556
+ let targetEnvs = [];
3557
+ if (flags.env) {
3558
+ targetEnvs = String(flags.env).split(",").map((s) => s.trim()).filter(Boolean);
3559
+ } else if (!isInteractive(flags)) {
3560
+ targetEnvs = envsWithKey.length > 0 ? envsWithKey : allEnvs;
3561
+ } else {
3562
+ targetEnvs = handleCancel(
3563
+ await p19__namespace.multiselect({
3564
+ message: `Which environments should be updated for ${pc13__default.default.bold(targetKey)}?`,
3565
+ options: allEnvs.map((env) => ({
3566
+ value: env,
3567
+ label: env === "local" ? "local (.env)" : `${env} (.env.${env})`,
3568
+ hint: envsWithKey.includes(env) ? "currently exists" : "not set"
3569
+ })),
3570
+ initialValues: envsWithKey.length > 0 ? envsWithKey : allEnvs,
3571
+ required: true
3572
+ })
3573
+ );
3574
+ }
3575
+ if (targetEnvs.length === 0) {
3576
+ p19__namespace.log.warn("No environments selected. Nothing was changed.");
3577
+ return { key: targetKey, environments: [] };
3578
+ }
3579
+ for (const env of targetEnvs) {
3580
+ const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3581
+ const localEditor = new EnvEditor(localPath);
3582
+ const currentVal = localEditor.getValue(targetKey);
3583
+ let newVal = value;
3584
+ if (newVal === void 0) {
3585
+ if (!isInteractive(flags)) {
3586
+ newVal = currentVal ?? "";
3587
+ } else {
3588
+ newVal = handleCancel(
3589
+ await p19__namespace.text({
3590
+ message: `New value for ${pc13__default.default.cyan(targetKey)} in ${pc13__default.default.bold(env)}? (Current: "${currentVal ?? ""}")`,
3591
+ initialValue: currentVal ?? ""
3592
+ })
3593
+ );
3594
+ }
3595
+ } else if (isInteractive(flags) && !flags.yes) {
3596
+ newVal = handleCancel(
3597
+ await p19__namespace.text({
3598
+ message: `New value for ${pc13__default.default.cyan(targetKey)} in ${pc13__default.default.bold(env)}? (Current: "${currentVal ?? ""}")`,
3599
+ initialValue: value ?? currentVal ?? ""
3600
+ })
3601
+ );
3602
+ }
3603
+ if (flags.dryRun) {
3604
+ p19__namespace.log.info(
3605
+ pc13__default.default.cyan(`[DRY RUN] Would update ${targetKey}=${newVal} in ${resolveEnvFilename(env, false)}`)
3606
+ );
3607
+ } else {
3608
+ localEditor.set(targetKey, newVal);
3609
+ localEditor.save();
3610
+ const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3611
+ const exampleEditor = new EnvEditor(examplePath);
3612
+ if (!exampleEditor.has(targetKey)) {
3613
+ exampleEditor.set(targetKey, "");
3614
+ exampleEditor.save();
3615
+ }
3616
+ }
3617
+ }
3618
+ if (!flags.dryRun) {
3619
+ p19__namespace.log.success(
3620
+ pc13__default.default.green(`\u2713 Updated ${pc13__default.default.bold(targetKey)} in [${targetEnvs.join(", ")}].`)
3621
+ );
3622
+ }
3623
+ return { key: targetKey, environments: targetEnvs };
3624
+ }
3625
+ async function runEnvDelete(key, flags = {}) {
3626
+ const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3627
+ const allEnvs = discoverEnvironments(projectRoot);
3628
+ const existingKeys = getAllExistingKeys(projectRoot, allEnvs);
3629
+ let targetKey = key?.trim();
3630
+ if (!targetKey) {
3631
+ if (!isInteractive(flags)) {
3632
+ throw new Error("Variable key is required for 'mason env delete <key>'");
3633
+ }
3634
+ if (existingKeys.length === 0) {
3635
+ p19__namespace.log.error(pc13__default.default.red("No environment variables found to delete."));
3636
+ return { key: "", environments: [] };
3637
+ }
3638
+ targetKey = handleCancel(
3639
+ await p19__namespace.select({
3640
+ message: "Select a variable to delete:",
3641
+ options: existingKeys.map((k) => ({ value: k, label: k }))
3642
+ })
3643
+ );
3644
+ }
3645
+ const envsWithKey = allEnvs.filter((env) => {
3646
+ const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3647
+ const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3648
+ return fs14__default.default.existsSync(localPath) && new EnvEditor(localPath).has(targetKey) || fs14__default.default.existsSync(examplePath) && new EnvEditor(examplePath).has(targetKey);
3649
+ });
3650
+ let targetEnvs = [];
3651
+ if (flags.env) {
3652
+ targetEnvs = String(flags.env).split(",").map((s) => s.trim()).filter(Boolean);
3653
+ } else if (!isInteractive(flags)) {
3654
+ targetEnvs = envsWithKey.length > 0 ? envsWithKey : allEnvs;
3655
+ } else {
3656
+ targetEnvs = handleCancel(
3657
+ await p19__namespace.multiselect({
3658
+ message: `Which environments should remove ${pc13__default.default.bold(targetKey)}?`,
3659
+ options: allEnvs.map((env) => ({
3660
+ value: env,
3661
+ label: env === "local" ? "local (.env)" : `${env} (.env.${env})`,
3662
+ ...envsWithKey.includes(env) ? { hint: "currently present" } : {}
3663
+ })),
3664
+ initialValues: envsWithKey.length > 0 ? envsWithKey : allEnvs,
3665
+ required: true
3666
+ })
3667
+ );
3668
+ }
3669
+ if (targetEnvs.length === 0) {
3670
+ p19__namespace.log.warn("No environments selected. Nothing was deleted.");
3671
+ return { key: targetKey, environments: [] };
3672
+ }
3673
+ if (isInteractive(flags) && !flags.yes) {
3674
+ const confirm13 = handleCancel(
3675
+ await p19__namespace.confirm({
3676
+ message: `Are you sure you want to delete ${pc13__default.default.bold(targetKey)} from ${targetEnvs.join(", ")} and their .example templates?`,
3677
+ initialValue: false
3678
+ })
3679
+ );
3680
+ if (!confirm13) {
3681
+ p19__namespace.log.warn("Operation cancelled.");
3682
+ return { key: targetKey, environments: [] };
3683
+ }
3684
+ }
3685
+ for (const env of targetEnvs) {
3686
+ const localPath = path2__default.default.join(projectRoot, resolveEnvFilename(env, false));
3687
+ const examplePath = path2__default.default.join(projectRoot, resolveEnvFilename(env, true));
3688
+ if (flags.dryRun) {
3689
+ p19__namespace.log.info(
3690
+ pc13__default.default.cyan(`[DRY RUN] Would delete ${targetKey} from ${resolveEnvFilename(env, false)} and ${resolveEnvFilename(env, true)}`)
3691
+ );
3692
+ } else {
3693
+ if (fs14__default.default.existsSync(localPath)) {
3694
+ const localEditor = new EnvEditor(localPath);
3695
+ localEditor.delete(targetKey);
3696
+ localEditor.save();
3697
+ }
3698
+ if (fs14__default.default.existsSync(examplePath)) {
3699
+ const exampleEditor = new EnvEditor(examplePath);
3700
+ exampleEditor.delete(targetKey);
3701
+ exampleEditor.save();
3702
+ }
3703
+ }
3704
+ }
3705
+ if (!flags.dryRun) {
3706
+ p19__namespace.log.success(
3707
+ pc13__default.default.green(`\u2713 Deleted ${pc13__default.default.bold(targetKey)} from [${targetEnvs.join(", ")}] and .example templates.`)
3708
+ );
3709
+ }
3710
+ return { key: targetKey, environments: targetEnvs };
3711
+ }
3712
+ async function runEnvAudit(flags = {}) {
3713
+ const projectRoot = flags.cwd || flags.targetDir || findProjectRoot();
3714
+ const envs = discoverEnvironments(projectRoot);
3715
+ p19__namespace.intro(pc13__default.default.bgCyan(pc13__default.default.black(" mason env audit ")));
3716
+ const items = [];
3717
+ let totalIssues = 0;
3718
+ let hasDrift = false;
3719
+ let hasErrors = false;
3720
+ for (const env of envs) {
3721
+ const localFile = resolveEnvFilename(env, false);
3722
+ const exampleFile = resolveEnvFilename(env, true);
3723
+ const localPath = path2__default.default.join(projectRoot, localFile);
3724
+ const examplePath = path2__default.default.join(projectRoot, exampleFile);
3725
+ const localExists = fs14__default.default.existsSync(localPath);
3726
+ const exampleExists = fs14__default.default.existsSync(examplePath);
3727
+ const localEditor = new EnvEditor(localPath);
3728
+ const exampleEditor = new EnvEditor(examplePath);
3729
+ const localKeys = localExists ? localEditor.getKeys() : [];
3730
+ const exampleKeys = exampleExists ? exampleEditor.getKeys() : [];
3731
+ const missingInLocal = exampleKeys.filter((k) => !localKeys.includes(k));
3732
+ const missingInExample = localKeys.filter((k) => !exampleKeys.includes(k));
3733
+ const emptyLocals = localKeys.filter((k) => {
3734
+ const val = localEditor.getValue(k);
3735
+ return val === "" || val === null;
3736
+ });
3737
+ const envIssues = (!localExists ? 1 : 0) + (!exampleExists ? 1 : 0) + missingInLocal.length + missingInExample.length + emptyLocals.length;
3738
+ totalIssues += envIssues;
3739
+ if (missingInExample.length > 0 || !exampleExists) hasDrift = true;
3740
+ if (missingInLocal.length > 0 || !localExists) hasErrors = true;
3741
+ items.push({
3742
+ env,
3743
+ localFile,
3744
+ exampleFile,
3745
+ localExists,
3746
+ exampleExists,
3747
+ missingInLocal,
3748
+ missingInExample,
3749
+ emptyLocals
3750
+ });
3751
+ if (!localExists && !exampleExists) {
3752
+ p19__namespace.log.warn(
3753
+ pc13__default.default.yellow(`\u25B2 ${pc13__default.default.bold(env)}: Neither '${localFile}' nor '${exampleFile}' exist.`)
3754
+ );
3755
+ continue;
3756
+ }
3757
+ if (!localExists) {
3758
+ p19__namespace.log.error(
3759
+ pc13__default.default.red(`\u2717 ${pc13__default.default.bold(env)}: Local file '${localFile}' is missing! Run 'mason env init' to create it.`)
3760
+ );
3761
+ continue;
3762
+ }
3763
+ if (!exampleExists) {
3764
+ p19__namespace.log.warn(
3765
+ pc13__default.default.yellow(`\u25B2 ${pc13__default.default.bold(env)}: Template '${exampleFile}' is missing! Run 'mason env init-examples' to generate it.`)
3766
+ );
3767
+ continue;
3768
+ }
3769
+ if (envIssues === 0) {
3770
+ p19__namespace.log.success(
3771
+ pc13__default.default.green(`\u2713 ${pc13__default.default.bold(env)} (${localFile} \u2194 ${exampleFile}): All ${localKeys.length} keys in sync!`)
3772
+ );
3773
+ } else {
3774
+ p19__namespace.log.step(
3775
+ pc13__default.default.bold(pc13__default.default.cyan(`Environment: ${env} (${localFile} \u2194 ${exampleFile})`))
3776
+ );
3777
+ if (missingInLocal.length > 0) {
3778
+ p19__namespace.log.error(
3779
+ pc13__default.default.red(` \u25CF Missing locally (${missingInLocal.length} in template but missing in ${localFile}):`)
3780
+ );
3781
+ for (const k of missingInLocal) {
3782
+ p19__namespace.log.message(pc13__default.default.red(` - ${k}`));
3783
+ }
3784
+ }
3785
+ if (missingInExample.length > 0) {
3786
+ p19__namespace.log.warn(
3787
+ pc13__default.default.yellow(` \u25CF Template drift (${missingInExample.length} local keys missing in ${exampleFile}):`)
3788
+ );
3789
+ for (const k of missingInExample) {
3790
+ p19__namespace.log.message(pc13__default.default.yellow(` - ${k}`));
3791
+ }
3792
+ }
3793
+ if (emptyLocals.length > 0) {
3794
+ p19__namespace.log.info(
3795
+ pc13__default.default.dim(` \u25B2 Empty values (${emptyLocals.length} defined with blank value in ${localFile}):`)
3796
+ );
3797
+ for (const k of emptyLocals) {
3798
+ p19__namespace.log.message(pc13__default.default.dim(` - ${k}`));
3799
+ }
3800
+ }
3801
+ }
3802
+ }
3803
+ if (totalIssues === 0) {
3804
+ p19__namespace.outro(pc13__default.default.green("\u2713 All environment files are in sync! No drift detected."));
3805
+ } else {
3806
+ p19__namespace.outro(
3807
+ pc13__default.default.yellow(`Found ${totalIssues} environment issue(s) across inspected environments.`)
3808
+ );
3809
+ }
3810
+ return {
3811
+ hasDrift,
3812
+ hasErrors,
3813
+ totalIssues,
3814
+ items
3815
+ };
3816
+ }
3817
+
3818
+ // src/commands/env/index.ts
3819
+ async function runEnvMenu(flags = {}) {
3820
+ const task = handleCancel(
3821
+ await p19__namespace.select({
3822
+ message: "What environment task do you want to run?",
3823
+ options: [
3824
+ {
3825
+ value: "add",
3826
+ label: "Add Variable",
3827
+ hint: "Add a new key across selected environments and sync .example templates"
3828
+ },
3829
+ {
3830
+ value: "update",
3831
+ label: "Update Variable",
3832
+ hint: "Update an existing variable value across environments"
3833
+ },
3834
+ {
3835
+ value: "delete",
3836
+ label: "Delete Variable",
3837
+ hint: "Delete a variable from .env and .example files"
3838
+ },
3839
+ {
3840
+ value: "audit",
3841
+ label: "Audit Drift",
3842
+ hint: "Scan for missing keys, uncommitted secrets, or template drift"
3843
+ },
3844
+ {
3845
+ value: "init",
3846
+ label: "Init Files (.env)",
3847
+ hint: "Clone .env*.example templates to local .env files"
3848
+ },
3849
+ {
3850
+ value: "init-examples",
3851
+ label: "Init Templates (.env.example)",
3852
+ hint: "Safely clone and redact local .env files to .example templates"
3853
+ }
3854
+ ]
3855
+ })
3856
+ );
3857
+ switch (task) {
3858
+ case "add":
3859
+ return await runEnvAdd(void 0, void 0, flags);
3860
+ case "update":
3861
+ return await runEnvUpdate(void 0, void 0, flags);
3862
+ case "delete":
3863
+ return await runEnvDelete(void 0, flags);
3864
+ case "audit":
3865
+ return await runEnvAudit(flags);
3866
+ case "init":
3867
+ return await runEnvInit(flags);
3868
+ case "init-examples":
3869
+ return await runEnvInitExamples(flags);
3870
+ }
3871
+ }
3872
+ async function handleEnv(subcommand, args = [], flags = {}) {
3873
+ if (!subcommand) {
3874
+ return await runEnvMenu(flags);
3875
+ }
3876
+ const normalized = subcommand.trim().toLowerCase();
3877
+ switch (normalized) {
3878
+ case "init":
3879
+ return await runEnvInit(flags);
3880
+ case "init-examples":
3881
+ case "initexamples":
3882
+ return await runEnvInitExamples(flags);
3883
+ case "add":
3884
+ return await runEnvAdd(args[0], args[1], flags);
3885
+ case "update":
3886
+ return await runEnvUpdate(args[0], args[1], flags);
3887
+ case "delete":
3888
+ case "remove":
3889
+ case "rm":
3890
+ return await runEnvDelete(args[0], flags);
3891
+ case "audit":
3892
+ return await runEnvAudit(flags);
3893
+ default:
3894
+ p19__namespace.log.error(
3895
+ pc13__default.default.red(
3896
+ `Unknown env subcommand: "${subcommand}". Allowed subcommands: init, init-examples, add, update, delete, audit.`
3897
+ )
3898
+ );
3899
+ if (process.env.VITEST) {
3900
+ throw new Error(
3901
+ `Unknown env subcommand: "${subcommand}". Allowed subcommands: init, init-examples, add, update, delete, audit.`
3902
+ );
3903
+ }
3904
+ process.exit(1);
3905
+ }
3906
+ }
3265
3907
 
3266
3908
  // src/commands/menu.ts
3267
3909
  async function runInteractiveMenu(flags = {}) {
3268
3910
  printBanner();
3269
3911
  const choice = handleCancel(
3270
- await p15__namespace.select({
3912
+ await p19__namespace.select({
3271
3913
  message: "What would you like to create in your architecture?",
3272
3914
  options: [
3273
3915
  {
@@ -3312,8 +3954,8 @@ async function runInteractiveMenu(flags = {}) {
3312
3954
  },
3313
3955
  {
3314
3956
  value: "env",
3315
- label: "Generate Env Files",
3316
- hint: "Clone .env*.example files to local .env equivalents"
3957
+ label: "Environment Variables",
3958
+ hint: "Manage .env files, add/delete keys, and sync templates"
3317
3959
  }
3318
3960
  ]
3319
3961
  })
@@ -3344,7 +3986,7 @@ async function runInteractiveMenu(flags = {}) {
3344
3986
  await runInjectableCommand(void 0, flags);
3345
3987
  break;
3346
3988
  case "env":
3347
- await runEnvCommand(flags);
3989
+ await runEnvMenu(flags);
3348
3990
  break;
3349
3991
  }
3350
3992
  }
@@ -3383,8 +4025,8 @@ async function handleCreate(type, name, flags = {}) {
3383
4025
  await runInjectableCommand(name, flags);
3384
4026
  break;
3385
4027
  default:
3386
- p15__namespace.log.error(
3387
- pc15__default.default.red(
4028
+ p19__namespace.log.error(
4029
+ pc13__default.default.red(
3388
4030
  `Unknown component type: "${type}". Allowed types: feature, shared, usecase, domain, infrastructure, interface, httpHandler, injectable.`
3389
4031
  )
3390
4032
  );
@@ -3416,7 +4058,7 @@ function findLocalRegistry(startDir = process.cwd()) {
3416
4058
  let current = path2__default.default.resolve(startDir);
3417
4059
  while (true) {
3418
4060
  const candidate = path2__default.default.join(current, "mason-registry");
3419
- if (fs10__default.default.existsSync(candidate) && fs10__default.default.existsSync(path2__default.default.join(candidate, "index.json"))) {
4061
+ if (fs14__default.default.existsSync(candidate) && fs14__default.default.existsSync(path2__default.default.join(candidate, "index.json"))) {
3420
4062
  return candidate;
3421
4063
  }
3422
4064
  const parent = path2__default.default.dirname(current);
@@ -3438,9 +4080,9 @@ function getRegistryBase(projectRoot, override) {
3438
4080
  path2__default.default.join(process.cwd(), "mason.config.json")
3439
4081
  ];
3440
4082
  for (const configPath of configLocations) {
3441
- if (fs10__default.default.existsSync(configPath)) {
4083
+ if (fs14__default.default.existsSync(configPath)) {
3442
4084
  try {
3443
- const config = JSON.parse(fs10__default.default.readFileSync(configPath, "utf-8"));
4085
+ const config = JSON.parse(fs14__default.default.readFileSync(configPath, "utf-8"));
3444
4086
  if (config.registry && typeof config.registry === "string") {
3445
4087
  return normalizeRegistryUrl(config.registry.trim(), path2__default.default.dirname(configPath));
3446
4088
  }
@@ -3453,9 +4095,9 @@ function getRegistryBase(projectRoot, override) {
3453
4095
  path2__default.default.join(process.cwd(), "package.json")
3454
4096
  ];
3455
4097
  for (const pkgPath of pkgLocations) {
3456
- if (fs10__default.default.existsSync(pkgPath)) {
4098
+ if (fs14__default.default.existsSync(pkgPath)) {
3457
4099
  try {
3458
- const pkg = JSON.parse(fs10__default.default.readFileSync(pkgPath, "utf-8"));
4100
+ const pkg = JSON.parse(fs14__default.default.readFileSync(pkgPath, "utf-8"));
3459
4101
  if (pkg.mason?.registry && typeof pkg.mason.registry === "string") {
3460
4102
  return normalizeRegistryUrl(pkg.mason.registry.trim(), path2__default.default.dirname(pkgPath));
3461
4103
  }
@@ -3506,15 +4148,15 @@ async function fetchRegistryFile(registryBase, relPath) {
3506
4148
  baseDir = url.fileURLToPath(baseDir);
3507
4149
  }
3508
4150
  let filePath = path2__default.default.resolve(baseDir, cleanRelPath);
3509
- if (!fs10__default.default.existsSync(filePath)) {
4151
+ if (!fs14__default.default.existsSync(filePath)) {
3510
4152
  const inSrcPath = path2__default.default.resolve(baseDir, "src", cleanRelPath);
3511
- if (fs10__default.default.existsSync(inSrcPath)) {
4153
+ if (fs14__default.default.existsSync(inSrcPath)) {
3512
4154
  filePath = inSrcPath;
3513
4155
  } else {
3514
4156
  throw new Error(`Registry file not found at ${filePath}`);
3515
4157
  }
3516
4158
  }
3517
- return fs10__default.default.promises.readFile(filePath, "utf-8");
4159
+ return fs14__default.default.promises.readFile(filePath, "utf-8");
3518
4160
  }
3519
4161
  async function fetchRegistryIndex(registryBase) {
3520
4162
  const content = await fetchRegistryFile(registryBase, "index.json");
@@ -3576,26 +4218,26 @@ function findClosestMatch(target, candidates) {
3576
4218
  return null;
3577
4219
  }
3578
4220
  function detectPackageManager(projectRoot) {
3579
- if (fs10__default.default.existsSync(path2__default.default.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
3580
- if (fs10__default.default.existsSync(path2__default.default.join(projectRoot, "yarn.lock"))) return "yarn";
3581
- if (fs10__default.default.existsSync(path2__default.default.join(projectRoot, "bun.lockb")) || fs10__default.default.existsSync(path2__default.default.join(projectRoot, "bun.lock"))) return "bun";
4221
+ if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
4222
+ if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "yarn.lock"))) return "yarn";
4223
+ if (fs14__default.default.existsSync(path2__default.default.join(projectRoot, "bun.lockb")) || fs14__default.default.existsSync(path2__default.default.join(projectRoot, "bun.lock"))) return "bun";
3582
4224
  return "npm";
3583
4225
  }
3584
4226
  function getMissingNpmPackages(projectRoot, requiredPackages) {
3585
4227
  if (!requiredPackages || requiredPackages.length === 0) return [];
3586
4228
  const pkgJsonPath = path2__default.default.join(projectRoot, "package.json");
3587
- if (!fs10__default.default.existsSync(pkgJsonPath)) {
4229
+ if (!fs14__default.default.existsSync(pkgJsonPath)) {
3588
4230
  return requiredPackages;
3589
4231
  }
3590
4232
  try {
3591
- const pkg = JSON.parse(fs10__default.default.readFileSync(pkgJsonPath, "utf-8"));
4233
+ const pkg = JSON.parse(fs14__default.default.readFileSync(pkgJsonPath, "utf-8"));
3592
4234
  const installed = /* @__PURE__ */ new Set([
3593
4235
  ...Object.keys(pkg.dependencies || {}),
3594
4236
  ...Object.keys(pkg.devDependencies || {}),
3595
4237
  ...Object.keys(pkg.peerDependencies || {})
3596
4238
  ]);
3597
- return requiredPackages.filter((p18) => {
3598
- const nameOnly = p18.startsWith("@") ? `@${p18.slice(1).split("@")[0] || ""}` : p18.split("@")[0] || p18;
4239
+ return requiredPackages.filter((p22) => {
4240
+ const nameOnly = p22.startsWith("@") ? `@${p22.slice(1).split("@")[0] || ""}` : p22.split("@")[0] || p22;
3599
4241
  return !installed.has(nameOnly);
3600
4242
  });
3601
4243
  } catch {
@@ -3620,15 +4262,15 @@ function installNpmPackages(projectRoot, packages, pm) {
3620
4262
  installCmd = `npm install ${packages.join(" ")}`;
3621
4263
  break;
3622
4264
  }
3623
- p15__namespace.log.info(`Installing missing dependencies with ${manager}: ${pc15__default.default.cyan(packages.join(", "))}`);
4265
+ p19__namespace.log.info(`Installing missing dependencies with ${manager}: ${pc13__default.default.cyan(packages.join(", "))}`);
3624
4266
  child_process.execSync(installCmd, {
3625
4267
  cwd: projectRoot,
3626
4268
  stdio: "inherit"
3627
4269
  });
3628
4270
  }
3629
4271
  function getAllFiles(dir, baseDir = dir) {
3630
- if (!fs10__default.default.existsSync(dir)) return [];
3631
- const entries = fs10__default.default.readdirSync(dir, { withFileTypes: true });
4272
+ if (!fs14__default.default.existsSync(dir)) return [];
4273
+ const entries = fs14__default.default.readdirSync(dir, { withFileTypes: true });
3632
4274
  const files = [];
3633
4275
  for (const entry of entries) {
3634
4276
  const fullPath = path2__default.default.join(dir, entry.name);
@@ -3648,13 +4290,13 @@ function getAllFiles(dir, baseDir = dir) {
3648
4290
  return files.sort();
3649
4291
  }
3650
4292
  function computeDirectoryHash(dirPath, files) {
3651
- if (!fs10__default.default.existsSync(dirPath)) return "";
4293
+ if (!fs14__default.default.existsSync(dirPath)) return "";
3652
4294
  const hash = crypto.createHash("sha256");
3653
4295
  const fileList = (getAllFiles(dirPath)).sort();
3654
4296
  for (const relativePath of fileList) {
3655
4297
  const absolutePath = path2__default.default.join(dirPath, relativePath);
3656
- if (!fs10__default.default.existsSync(absolutePath)) continue;
3657
- const content = fs10__default.default.readFileSync(absolutePath, "utf8");
4298
+ if (!fs14__default.default.existsSync(absolutePath)) continue;
4299
+ const content = fs14__default.default.readFileSync(absolutePath, "utf8");
3658
4300
  const normalizedContent = content.replace(/\r\n/g, "\n");
3659
4301
  hash.update(relativePath);
3660
4302
  hash.update(normalizedContent);
@@ -3664,9 +4306,9 @@ function computeDirectoryHash(dirPath, files) {
3664
4306
 
3665
4307
  // src/commands/import.ts
3666
4308
  var importPrompts = {
3667
- select: p15__namespace.select,
3668
- text: p15__namespace.text,
3669
- confirm: p15__namespace.confirm
4309
+ select: p19__namespace.select,
4310
+ text: p19__namespace.text,
4311
+ confirm: p19__namespace.confirm
3670
4312
  };
3671
4313
  function isTestFile(filePath) {
3672
4314
  const normalized = filePath.replace(/\\/g, "/");
@@ -3698,11 +4340,11 @@ function getExistingModuleDir(projectRoot, modType, modName) {
3698
4340
  const folder = modType === "shared" ? "shared" : "features";
3699
4341
  const configuredDir = modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
3700
4342
  const inConfigured = path2__default.default.join(configuredDir, modName);
3701
- if (fs10__default.default.existsSync(inConfigured)) return inConfigured;
4343
+ if (fs14__default.default.existsSync(inConfigured)) return inConfigured;
3702
4344
  const inSrc = path2__default.default.join(projectRoot, "src", folder, modName);
3703
- if (fs10__default.default.existsSync(inSrc)) return inSrc;
4345
+ if (fs14__default.default.existsSync(inSrc)) return inSrc;
3704
4346
  const inRoot = path2__default.default.join(projectRoot, folder, modName);
3705
- if (fs10__default.default.existsSync(inRoot)) return inRoot;
4347
+ if (fs14__default.default.existsSync(inRoot)) return inRoot;
3706
4348
  return null;
3707
4349
  }
3708
4350
  function checkModuleExists(projectRoot, modType, modName) {
@@ -3718,9 +4360,9 @@ function getAvailableLocalModules(projectRoot, modType) {
3718
4360
  ];
3719
4361
  const set = /* @__PURE__ */ new Set();
3720
4362
  for (const dir of dirs) {
3721
- if (fs10__default.default.existsSync(dir)) {
4363
+ if (fs14__default.default.existsSync(dir)) {
3722
4364
  try {
3723
- const entries = fs10__default.default.readdirSync(dir, { withFileTypes: true });
4365
+ const entries = fs14__default.default.readdirSync(dir, { withFileTypes: true });
3724
4366
  for (const e of entries) {
3725
4367
  if (e.isDirectory() && !e.name.startsWith(".")) {
3726
4368
  set.add(e.name);
@@ -3776,19 +4418,19 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3776
4418
  );
3777
4419
  }
3778
4420
  if (type !== "shared" && type !== "feature") {
3779
- p15__namespace.log.error(pc15__default.default.red(`Invalid module type: "${typeArg}". Must be "shared" or "feature".`));
4421
+ p19__namespace.log.error(pc13__default.default.red(`Invalid module type: "${typeArg}". Must be "shared" or "feature".`));
3780
4422
  process.exit(1);
3781
4423
  }
3782
4424
  const registryBase = getRegistryBase(projectRoot, flags.registry);
3783
- const s = p15__namespace.spinner();
3784
- s.start(`Connecting to registry at ${pc15__default.default.dim(registryBase)}...`);
4425
+ const s = p19__namespace.spinner();
4426
+ s.start(`Connecting to registry at ${pc13__default.default.dim(registryBase)}...`);
3785
4427
  let index;
3786
4428
  try {
3787
4429
  index = await fetchRegistryIndex(registryBase);
3788
4430
  s.stop("Registry index loaded.");
3789
4431
  } catch (err) {
3790
- s.stop(pc15__default.default.red("Failed to load registry index."));
3791
- p15__namespace.log.error(pc15__default.default.red(err.message || String(err)));
4432
+ s.stop(pc13__default.default.red("Failed to load registry index."));
4433
+ p19__namespace.log.error(pc13__default.default.red(err.message || String(err)));
3792
4434
  process.exit(1);
3793
4435
  }
3794
4436
  const availableList = type === "shared" ? index.shared : index.features;
@@ -3796,7 +4438,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3796
4438
  let name = nameArg?.trim();
3797
4439
  if (!name) {
3798
4440
  if (availableList.length === 0) {
3799
- p15__namespace.log.warn(`No ${type} modules available in the registry.`);
4441
+ p19__namespace.log.warn(`No ${type} modules available in the registry.`);
3800
4442
  return;
3801
4443
  }
3802
4444
  name = handleCancel(
@@ -3812,9 +4454,9 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3812
4454
  }
3813
4455
  if (!candidateNames.includes(name)) {
3814
4456
  const closest = findClosestMatch(name, candidateNames);
3815
- p15__namespace.log.error(pc15__default.default.red(`\u274C Module '${name}' not found in the ${type} registry.`));
4457
+ p19__namespace.log.error(pc13__default.default.red(`\u274C Module '${name}' not found in the ${type} registry.`));
3816
4458
  if (closest) {
3817
- p15__namespace.log.info(pc15__default.default.yellow(`Did you mean '${pc15__default.default.cyan(closest)}'?`));
4459
+ p19__namespace.log.info(pc13__default.default.yellow(`Did you mean '${pc13__default.default.cyan(closest)}'?`));
3818
4460
  }
3819
4461
  process.exit(1);
3820
4462
  }
@@ -3826,7 +4468,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3826
4468
  try {
3827
4469
  manifest = await fetchModuleManifest(registryBase, modType, modName);
3828
4470
  } catch (err) {
3829
- p15__namespace.log.error(pc15__default.default.red(`Failed to fetch manifest for ${modType} '${modName}': ${err.message}`));
4471
+ p19__namespace.log.error(pc13__default.default.red(`Failed to fetch manifest for ${modType} '${modName}': ${err.message}`));
3830
4472
  process.exit(1);
3831
4473
  }
3832
4474
  nodes.set(key, {
@@ -3866,7 +4508,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3866
4508
  buildTopologicalOrder(rootKey);
3867
4509
  const resolutions = /* @__PURE__ */ new Map();
3868
4510
  const globalAliasMap = /* @__PURE__ */ new Map();
3869
- p15__namespace.log.step(`Importing ${type}: ${pc15__default.default.cyan(name)}...`);
4511
+ p19__namespace.log.step(`Importing ${type}: ${pc13__default.default.cyan(name)}...`);
3870
4512
  for (const key of orderedKeys) {
3871
4513
  const node = nodes.get(key);
3872
4514
  const { type: modType, name: registryName, manifest } = node;
@@ -3898,8 +4540,8 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3898
4540
  const programmaticPointTo = pointToMap[registryName] || pointToMap[`${modType}/${registryName}`];
3899
4541
  if (programmaticPointTo) {
3900
4542
  if (!checkModuleExists(projectRoot, modType, programmaticPointTo)) {
3901
- p15__namespace.log.error(
3902
- pc15__default.default.red(
4543
+ p19__namespace.log.error(
4544
+ pc13__default.default.red(
3903
4545
  `Module '${programmaticPointTo}' specified in --point-to does not exist in ${folder}.`
3904
4546
  )
3905
4547
  );
@@ -3907,7 +4549,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3907
4549
  }
3908
4550
  globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${programmaticPointTo}/`);
3909
4551
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${programmaticPointTo}`);
3910
- p15__namespace.log.step(`Pointing '${modType}/${registryName}' to existing '${folder}/${programmaticPointTo}'`);
4552
+ p19__namespace.log.step(`Pointing '${modType}/${registryName}' to existing '${folder}/${programmaticPointTo}'`);
3911
4553
  resolutions.set(key, {
3912
4554
  type: modType,
3913
4555
  registryName,
@@ -3923,7 +4565,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3923
4565
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${programmaticAlias}`);
3924
4566
  const baseDir = getModuleBaseDir(projectRoot, modType);
3925
4567
  const displayDest = path2__default.default.relative(projectRoot, path2__default.default.join(baseDir, programmaticAlias));
3926
- p15__namespace.log.step(`Importing '${registryName}' into '${displayDest}'...`);
4568
+ p19__namespace.log.step(`Importing '${registryName}' into '${displayDest}'...`);
3927
4569
  resolutions.set(key, {
3928
4570
  type: modType,
3929
4571
  registryName,
@@ -3935,7 +4577,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3935
4577
  }
3936
4578
  const existingDir = getExistingModuleDir(projectRoot, modType, registryName);
3937
4579
  if (!existingDir) {
3938
- p15__namespace.log.info(` \u21B3 Resolving required ${modType} dependency: ${pc15__default.default.cyan(registryName)}`);
4580
+ p19__namespace.log.info(` \u21B3 Resolving required ${modType} dependency: ${pc13__default.default.cyan(registryName)}`);
3939
4581
  resolutions.set(key, {
3940
4582
  type: modType,
3941
4583
  registryName,
@@ -3951,7 +4593,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3951
4593
  const remoteIntegrity = manifest.integrity || entry?.integrity;
3952
4594
  const localHash = computeDirectoryHash(existingDir);
3953
4595
  if (remoteIntegrity && localHash === remoteIntegrity) {
3954
- p15__namespace.log.step(`\u2713 ${modType}/${registryName} is up to date (reusing existing)`);
4596
+ p19__namespace.log.step(`\u2713 ${modType}/${registryName} is up to date (reusing existing)`);
3955
4597
  resolutions.set(key, {
3956
4598
  type: modType,
3957
4599
  registryName,
@@ -3962,7 +4604,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3962
4604
  continue;
3963
4605
  }
3964
4606
  if (flags.overwrite) {
3965
- p15__namespace.log.step(`Overwriting '${modType}/${registryName}' with registry version (--overwrite)...`);
4607
+ p19__namespace.log.step(`Overwriting '${modType}/${registryName}' with registry version (--overwrite)...`);
3966
4608
  resolutions.set(key, {
3967
4609
  type: modType,
3968
4610
  registryName,
@@ -3973,7 +4615,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
3973
4615
  continue;
3974
4616
  }
3975
4617
  if (flags.yes) {
3976
- p15__namespace.log.info(`Using existing '${modType}/${registryName}'`);
4618
+ p19__namespace.log.info(`Using existing '${modType}/${registryName}'`);
3977
4619
  resolutions.set(key, {
3978
4620
  type: modType,
3979
4621
  registryName,
@@ -4007,7 +4649,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4007
4649
  })
4008
4650
  );
4009
4651
  if (choice === "keep_existing" || choice === "use_existing") {
4010
- p15__namespace.log.step(`Skipping '${modType}/${registryName}' (keeping existing)`);
4652
+ p19__namespace.log.step(`Skipping '${modType}/${registryName}' (keeping existing)`);
4011
4653
  resolutions.set(key, {
4012
4654
  type: modType,
4013
4655
  registryName,
@@ -4079,7 +4721,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4079
4721
  chosenName = chosenName.replace(/^@\/(shared|features)\//, "").replace(/^(src\/)?(shared|features)\//, "").replace(/^\/+|\/+$/g, "").trim();
4080
4722
  globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${chosenName}/`);
4081
4723
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${chosenName}`);
4082
- p15__namespace.log.step(`Pointing '${modType}/${registryName}' to existing '${folder}/${chosenName}'`);
4724
+ p19__namespace.log.step(`Pointing '${modType}/${registryName}' to existing '${folder}/${chosenName}'`);
4083
4725
  resolutions.set(key, {
4084
4726
  type: modType,
4085
4727
  registryName,
@@ -4111,7 +4753,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4111
4753
  globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${newName}`);
4112
4754
  const baseDir = getModuleBaseDir(projectRoot, modType);
4113
4755
  const displayDest = path2__default.default.relative(projectRoot, path2__default.default.join(baseDir, newName));
4114
- p15__namespace.log.step(`Importing '${registryName}' into '${displayDest}'...`);
4756
+ p19__namespace.log.step(`Importing '${registryName}' into '${displayDest}'...`);
4115
4757
  resolutions.set(key, {
4116
4758
  type: modType,
4117
4759
  registryName,
@@ -4122,7 +4764,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4122
4764
  continue;
4123
4765
  }
4124
4766
  if (choice === "overwrite") {
4125
- p15__namespace.log.step(`Overwriting '${modType}/${registryName}' with registry version...`);
4767
+ p19__namespace.log.step(`Overwriting '${modType}/${registryName}' with registry version...`);
4126
4768
  resolutions.set(key, {
4127
4769
  type: modType,
4128
4770
  registryName,
@@ -4165,17 +4807,17 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4165
4807
  const targetDir = path2__default.default.join(getModuleBaseDir(projectRoot, res.type), res.targetName);
4166
4808
  const isOverwrite = Boolean(flags.overwrite || res.action === "overwrite");
4167
4809
  if (key !== rootKey) {
4168
- p15__namespace.log.step(
4169
- `Importing ${res.type}: ${pc15__default.default.cyan(res.targetName)}${res.targetName !== res.registryName ? pc15__default.default.dim(` (from ${res.registryName})`) : ""}...`
4810
+ p19__namespace.log.step(
4811
+ `Importing ${res.type}: ${pc13__default.default.cyan(res.targetName)}${res.targetName !== res.registryName ? pc13__default.default.dim(` (from ${res.registryName})`) : ""}...`
4170
4812
  );
4171
4813
  }
4172
4814
  if (res.action === "overwrite" && !flags.dryRun) {
4173
4815
  const existingDir = getExistingModuleDir(projectRoot, res.type, res.targetName);
4174
4816
  if (existingDir && existingDir !== targetDir) {
4175
- fs10__default.default.rmSync(existingDir, { recursive: true, force: true });
4817
+ fs14__default.default.rmSync(existingDir, { recursive: true, force: true });
4176
4818
  }
4177
- if (fs10__default.default.existsSync(targetDir)) {
4178
- fs10__default.default.rmSync(targetDir, { recursive: true, force: true });
4819
+ if (fs14__default.default.existsSync(targetDir)) {
4820
+ fs14__default.default.rmSync(targetDir, { recursive: true, force: true });
4179
4821
  }
4180
4822
  }
4181
4823
  for (const file of res.manifest.files || []) {
@@ -4183,32 +4825,32 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4183
4825
  if (!includeTests && isTestFile(file)) continue;
4184
4826
  const remoteFilePath = `${folder}/${res.registryName}/${file}`;
4185
4827
  const localFilePath = path2__default.default.join(targetDir, file);
4186
- if (fs10__default.default.existsSync(localFilePath) && !isOverwrite) {
4187
- p15__namespace.log.warn(
4188
- ` \u21B3 Skipping existing file: ${pc15__default.default.dim(path2__default.default.relative(projectRoot, localFilePath))} (use --overwrite to replace)`
4828
+ if (fs14__default.default.existsSync(localFilePath) && !isOverwrite) {
4829
+ p19__namespace.log.warn(
4830
+ ` \u21B3 Skipping existing file: ${pc13__default.default.dim(path2__default.default.relative(projectRoot, localFilePath))} (use --overwrite to replace)`
4189
4831
  );
4190
4832
  continue;
4191
4833
  }
4192
4834
  let content = await fetchRegistryFile(registryBase, remoteFilePath);
4193
4835
  content = rewriteImports(content, globalAliasMap);
4194
4836
  if (!flags.dryRun) {
4195
- fs10__default.default.mkdirSync(path2__default.default.dirname(localFilePath), { recursive: true });
4196
- fs10__default.default.writeFileSync(localFilePath, content, "utf-8");
4837
+ fs14__default.default.mkdirSync(path2__default.default.dirname(localFilePath), { recursive: true });
4838
+ fs14__default.default.writeFileSync(localFilePath, content, "utf-8");
4197
4839
  }
4198
4840
  const displayPath = path2__default.default.relative(projectRoot, localFilePath);
4199
4841
  totalWrittenFiles.push(displayPath);
4200
- p15__namespace.log.message(` ${pc15__default.default.green("+")} ${displayPath}`);
4842
+ p19__namespace.log.message(` ${pc13__default.default.green("+")} ${displayPath}`);
4201
4843
  }
4202
4844
  }
4203
4845
  const missingNpm = getMissingNpmPackages(projectRoot, Array.from(requiredNpmPackages));
4204
4846
  if (missingNpm.length > 0) {
4205
4847
  if (flags.skipInstall || flags.dryRun) {
4206
- p15__namespace.log.info(`Required npm dependencies to install: ${pc15__default.default.cyan(missingNpm.join(", "))}`);
4848
+ p19__namespace.log.info(`Required npm dependencies to install: ${pc13__default.default.cyan(missingNpm.join(", "))}`);
4207
4849
  } else {
4208
4850
  try {
4209
4851
  installNpmPackages(projectRoot, missingNpm);
4210
4852
  } catch (err) {
4211
- p15__namespace.log.warn(
4853
+ p19__namespace.log.warn(
4212
4854
  `Could not automatically install packages (${err.message}). Please run: npm install ${missingNpm.join(
4213
4855
  " "
4214
4856
  )}`
@@ -4217,13 +4859,13 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4217
4859
  }
4218
4860
  }
4219
4861
  if (flags.dryRun) {
4220
- p15__namespace.log.info(pc15__default.default.yellow("Dry run complete: No files were written to disk."));
4862
+ p19__namespace.log.info(pc13__default.default.yellow("Dry run complete: No files were written to disk."));
4221
4863
  } else {
4222
4864
  const rootRes = resolutions.get(rootKey);
4223
4865
  const baseDir = getModuleBaseDir(projectRoot, type);
4224
4866
  const displayTarget = path2__default.default.relative(projectRoot, path2__default.default.join(baseDir, rootRes.targetName));
4225
- p15__namespace.log.success(
4226
- pc15__default.default.green(
4867
+ p19__namespace.log.success(
4868
+ pc13__default.default.green(
4227
4869
  `Successfully imported ${type} '${name}' (${totalWrittenFiles.length} file${totalWrittenFiles.length === 1 ? "" : "s"} placed in ${displayTarget})`
4228
4870
  )
4229
4871
  );
@@ -4245,8 +4887,8 @@ function isTestFile2(filePath, projectRoot) {
4245
4887
  return base.endsWith(".test.ts") || base.endsWith(".test.js") || base.endsWith(".spec.ts") || base.endsWith(".spec.js") || base.endsWith(".d.ts") || norm.includes("/__tests__/") || norm.startsWith("__tests__/") || /(?:^|\/)tests?\//.test(norm);
4246
4888
  }
4247
4889
  function scanDirFiles(dir, projectRoot) {
4248
- if (!fs10__default.default.existsSync(dir)) return [];
4249
- const entries = fs10__default.default.readdirSync(dir, { withFileTypes: true });
4890
+ if (!fs14__default.default.existsSync(dir)) return [];
4891
+ const entries = fs14__default.default.readdirSync(dir, { withFileTypes: true });
4250
4892
  const files = [];
4251
4893
  for (const entry of entries) {
4252
4894
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "__tests__" || entry.name.startsWith(".")) {
@@ -4446,10 +5088,10 @@ var FeatureDependencyGraph = class {
4446
5088
  if (cycle) return cycle;
4447
5089
  } else if (inStack.has(next)) {
4448
5090
  const cycle = [next];
4449
- let p18 = curr;
4450
- while (p18 !== next) {
4451
- cycle.push(p18);
4452
- p18 = parent.get(p18) || next;
5091
+ let p22 = curr;
5092
+ while (p22 !== next) {
5093
+ cycle.push(p22);
5094
+ p22 = parent.get(p22) || next;
4453
5095
  }
4454
5096
  cycle.push(next);
4455
5097
  cycle.reverse();
@@ -4465,8 +5107,8 @@ var FeatureDependencyGraph = class {
4465
5107
  };
4466
5108
  function discoverAllFeatures(projectRoot) {
4467
5109
  const featuresBase = resolveFeaturesDir(projectRoot);
4468
- if (!fs10__default.default.existsSync(featuresBase)) return [];
4469
- const entries = fs10__default.default.readdirSync(featuresBase, { withFileTypes: true });
5110
+ if (!fs14__default.default.existsSync(featuresBase)) return [];
5111
+ const entries = fs14__default.default.readdirSync(featuresBase, { withFileTypes: true });
4470
5112
  return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "__tests__" && e.name !== "tests").map((e) => ({
4471
5113
  name: e.name,
4472
5114
  dir: path2__default.default.join(featuresBase, e.name)
@@ -4857,7 +5499,7 @@ Code: ${v.code}`;
4857
5499
  const relPath = path2__default.default.relative(projectRoot, file).replace(/\\/g, "/");
4858
5500
  const { layer } = classifyFile(file, projectRoot);
4859
5501
  if (!layer) continue;
4860
- const content = fs10__default.default.readFileSync(file, "utf-8");
5502
+ const content = fs14__default.default.readFileSync(file, "utf-8");
4861
5503
  const statements = extractImportStatements(content);
4862
5504
  const baseName = path2__default.default.basename(file);
4863
5505
  const isBarrel = baseName === "index.ts" || baseName === "index.js";
@@ -5351,15 +5993,15 @@ ${compiledDetails}
5351
5993
  // src/commands/lint.ts
5352
5994
  function formatViolation(v) {
5353
5995
  const lines = [];
5354
- lines.push(pc15__default.default.underline(pc15__default.default.cyan(v.relativePath)) + pc15__default.default.dim(":") + pc15__default.default.yellow(String(v.line)));
5996
+ lines.push(pc13__default.default.underline(pc13__default.default.cyan(v.relativePath)) + pc13__default.default.dim(":") + pc13__default.default.yellow(String(v.line)));
5355
5997
  const gutter = `${String(v.line).padStart(4, " ")} | `;
5356
- lines.push(pc15__default.default.dim(gutter) + v.code);
5998
+ lines.push(pc13__default.default.dim(gutter) + v.code);
5357
5999
  const categoryShort = v.category.replace(" Violation", "");
5358
6000
  lines.push(
5359
- " " + pc15__default.default.red(pc15__default.default.bold("\u2716")) + " " + pc15__default.default.red(`[${categoryShort}]`) + " " + v.advice
6001
+ " " + pc13__default.default.red(pc13__default.default.bold("\u2716")) + " " + pc13__default.default.red(`[${categoryShort}]`) + " " + v.advice
5360
6002
  );
5361
6003
  if (v.fixExample?.good) {
5362
- lines.push(" " + pc15__default.default.dim("\u2192") + " " + pc15__default.default.dim(v.fixExample.good));
6004
+ lines.push(" " + pc13__default.default.dim("\u2192") + " " + pc13__default.default.dim(v.fixExample.good));
5363
6005
  }
5364
6006
  return lines.join("\n");
5365
6007
  }
@@ -5384,7 +6026,7 @@ async function handleLint(flags = {}) {
5384
6026
  console.log("");
5385
6027
  }
5386
6028
  console.log(
5387
- pc15__default.default.red(
6029
+ pc13__default.default.red(
5388
6030
  `\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).`
5389
6031
  )
5390
6032
  );
@@ -5403,7 +6045,7 @@ ${compiledDetails}
5403
6045
  }
5404
6046
  if (!quiet) {
5405
6047
  console.log(
5406
- pc15__default.default.green(
6048
+ pc13__default.default.green(
5407
6049
  `\u2714 Dependency rules verified across ${summary.totalFeatures} feature${summary.totalFeatures === 1 ? "" : "s"}.`
5408
6050
  )
5409
6051
  );
@@ -5418,7 +6060,7 @@ ${compiledDetails}
5418
6060
  console.log(formatViolation(v));
5419
6061
  console.log("");
5420
6062
  }
5421
- console.log(pc15__default.default.red(`\u2716 Dependency rules check failed (1 error).`));
6063
+ console.log(pc13__default.default.red(`\u2716 Dependency rules check failed (1 error).`));
5422
6064
  console.log("");
5423
6065
  }
5424
6066
  }
@@ -5428,33 +6070,42 @@ ${compiledDetails}
5428
6070
  async function handleInit(type, flags = {}) {
5429
6071
  if (!type) {
5430
6072
  const choice = handleCancel(
5431
- await p15__namespace.select({
6073
+ await p19__namespace.select({
5432
6074
  message: "What would you like to initialize?",
5433
6075
  options: [
5434
6076
  {
5435
6077
  value: "env",
5436
6078
  label: "Environment Files",
5437
6079
  hint: "Generate local .env files from .env*.example templates"
6080
+ },
6081
+ {
6082
+ value: "env-examples",
6083
+ label: "Sync Env Examples",
6084
+ hint: "Safely clone and redact local .env files to .example templates"
5438
6085
  }
5439
6086
  ]
5440
6087
  })
5441
6088
  );
5442
6089
  if (choice === "env") {
5443
- await runEnvCommand(flags);
6090
+ await runEnvInit(flags);
6091
+ } else if (choice === "env-examples") {
6092
+ await runEnvInitExamples(flags);
5444
6093
  }
5445
6094
  return;
5446
6095
  }
5447
6096
  const normalized = type.trim().toLowerCase();
5448
6097
  if (normalized === "env") {
5449
- await runEnvCommand(flags);
6098
+ await runEnvInit(flags);
6099
+ } else if (normalized === "env-examples" || normalized === "envexamples") {
6100
+ await runEnvInitExamples(flags);
5450
6101
  } else {
5451
- p15__namespace.log.error(
5452
- pc15__default.default.red(
5453
- `Unknown init target: "${type}". Allowed targets: env.`
6102
+ p19__namespace.log.error(
6103
+ pc13__default.default.red(
6104
+ `Unknown init target: "${type}". Allowed targets: env, env-examples.`
5454
6105
  )
5455
6106
  );
5456
6107
  if (process.env.VITEST) {
5457
- throw new Error(`Unknown init target: "${type}". Allowed targets: env.`);
6108
+ throw new Error(`Unknown init target: "${type}". Allowed targets: env, env-examples.`);
5458
6109
  }
5459
6110
  process.exit(1);
5460
6111
  }
@@ -5465,8 +6116,8 @@ function createCli() {
5465
6116
  const cli = cac.cac("mason");
5466
6117
  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) => {
5467
6118
  if (args && args.length > 0) {
5468
- p15__namespace.log.error(
5469
- pc15__default.default.red(
6119
+ p19__namespace.log.error(
6120
+ pc13__default.default.red(
5470
6121
  `Unknown command: "${args.join(" ")}". Use --help to list available commands.`
5471
6122
  )
5472
6123
  );
@@ -5477,7 +6128,7 @@ function createCli() {
5477
6128
  const mode = getEffectiveMode(projectRoot, flags);
5478
6129
  if (mode === "registry") {
5479
6130
  const choice2 = handleCancel(
5480
- await p15__namespace.select({
6131
+ await p19__namespace.select({
5481
6132
  message: "\u{1F3DB}\uFE0F Mason (Registry Mode): What would you like to scaffold?",
5482
6133
  options: [
5483
6134
  {
@@ -5520,7 +6171,7 @@ function createCli() {
5520
6171
  return;
5521
6172
  }
5522
6173
  const choice = handleCancel(
5523
- await p15__namespace.select({
6174
+ await p19__namespace.select({
5524
6175
  message: "\u{1F9F1} Mason: What would you like to do?",
5525
6176
  options: [
5526
6177
  {
@@ -5539,9 +6190,9 @@ function createCli() {
5539
6190
  hint: "Scan codebase and verify Clean Architecture dependency rules"
5540
6191
  },
5541
6192
  {
5542
- value: "init",
5543
- label: "Initialize environment",
5544
- hint: "Generate local .env files from .env*.example templates"
6193
+ value: "env",
6194
+ label: "Environment variables",
6195
+ hint: "Manage .env files, add/delete keys, and sync templates"
5545
6196
  }
5546
6197
  ]
5547
6198
  })
@@ -5552,8 +6203,8 @@ function createCli() {
5552
6203
  await handleImport(void 0, void 0, flags);
5553
6204
  } else if (choice === "lint") {
5554
6205
  await handleLint(flags);
5555
- } else if (choice === "init") {
5556
- await handleInit("env", flags);
6206
+ } else if (choice === "env") {
6207
+ await handleEnv(void 0, [], flags);
5557
6208
  }
5558
6209
  } catch (err) {
5559
6210
  handleCliError(err);
@@ -5601,16 +6252,36 @@ function createCli() {
5601
6252
  handleCliError(err);
5602
6253
  }
5603
6254
  });
6255
+ cli.command(
6256
+ "env [subcommand] [...args]",
6257
+ "Environment variable management and template synchronization (init, init-examples, add, update, delete, audit)"
6258
+ ).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 = {}) => {
6259
+ try {
6260
+ await handleEnv(subcommand, args, flags);
6261
+ } catch (err) {
6262
+ handleCliError(err);
6263
+ }
6264
+ });
5604
6265
  cli.command(
5605
6266
  "init [type]",
5606
- "Initialize project configurations and resources (e.g. 'mason init env')"
5607
- ).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 = {}) => {
6267
+ "Initialize project configurations (legacy shorthand: use 'mason env init')"
6268
+ ).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 = {}) => {
5608
6269
  try {
5609
6270
  await handleInit(type, flags);
5610
6271
  } catch (err) {
5611
6272
  handleCliError(err);
5612
6273
  }
5613
6274
  });
6275
+ cli.command(
6276
+ "env-examples",
6277
+ "Shorthand for 'mason env init-examples'"
6278
+ ).option("-d, --dry-run", "Preview changes without writing to disk").option("-o, --overwrite", "Overwrite existing .env*.example files").action(async (flags = {}) => {
6279
+ try {
6280
+ await handleEnv("init-examples", [], flags);
6281
+ } catch (err) {
6282
+ handleCliError(err);
6283
+ }
6284
+ });
5614
6285
  const createSubtypes = [
5615
6286
  "feature",
5616
6287
  "shared",
@@ -5642,7 +6313,7 @@ function handleCliError(err) {
5642
6313
  process.exit(0);
5643
6314
  }
5644
6315
  const message = err instanceof Error ? err.message : String(err);
5645
- p15__namespace.log.error(pc15__default.default.red(`Error: ${message}`));
6316
+ p19__namespace.log.error(pc13__default.default.red(`Error: ${message}`));
5646
6317
  if (process.env.VITEST) {
5647
6318
  throw err;
5648
6319
  }