@pixpilot/scaffoldfy 0.4.0 → 0.5.1

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/README.md CHANGED
@@ -63,7 +63,6 @@ import { runWithTasks } from '@pixpilot/scaffoldfy';
63
63
  await runWithTasks(tasks, {
64
64
  dryRun: false,
65
65
  force: false,
66
- keepTasksFile: true,
67
66
  tasksFilePath: './my-tasks.json',
68
67
  });
69
68
  ```
package/dist/cli.cjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- const e=require(`./src-eu70b3xC.cjs`);let t=require(`node:fs`);t=e.Y(t);let n=require(`node:path`);n=e.Y(n);let r=require(`node:process`);r=e.Y(r);let i=require(`commander`);i=e.Y(i);const a=1,o=new i.Command,s=n.default.join(__dirname,`..`,`package.json`);let c=`0.0.0`;try{c=JSON.parse(t.default.readFileSync(s,`utf-8`)).version??`0.0.0`}catch{}o.name(`scaffoldfy`).description(`Initialize and configure project templates with customizable tasks`).version(c),o.option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force re-initialization even if already initialized`).option(`--keep-tasks-file`,`Keep the tasks file after successful initialization (default: remove)`,!1).option(`--tasks-file <path>`,`Path to JSON file containing task definitions`,`./template-tasks.json`).option(`--tasks-ts <path>`,`Path to TypeScript file exporting tasks`,`./template-tasks.ts`).action(async i=>{try{let a=[],o;if(i.tasksTs!=null&&i.tasksTs!==``){let s=n.default.resolve(r.default.cwd(),i.tasksTs);if(t.default.existsSync(s)){e.G(`Loading tasks from TypeScript file: ${i.tasksTs}`,`info`),o=s;try{let t=await import(s);a=t.default??t.tasks??[],(!Array.isArray(a)||a.length===0)&&(e.G(`⚠️ No tasks found in TypeScript file or invalid format`,`warn`),e.G(`Expected default export or named export "tasks" with TaskDefinition[]`,`info`))}catch(t){e.G(`Failed to load TypeScript tasks file: ${i.tasksTs}`,`error`),t instanceof Error&&e.G(` Error: ${t.message}`,`error`),r.default.exit(1)}}}if(a.length===0&&i.tasksFile!=null&&i.tasksFile!==``){let s=n.default.resolve(r.default.cwd(),i.tasksFile);if(t.default.existsSync(s)){o=s;try{a=await e.a(s),Array.isArray(a)||(e.G(`❌ Invalid tasks file format`,`error`),e.G(`Expected JSON with { "tasks": [...] } structure`,`info`),r.default.exit(1))}catch(t){e.G(`Failed to load JSON tasks file: ${i.tasksFile}`,`error`),t instanceof Error&&e.G(` Error: ${t.message}`,`error`),r.default.exit(1)}}else e.G(`Tasks file not found: ${i.tasksFile}`,`warn`)}a.length===0&&(e.G(`❌ No tasks defined`,`error`),console.log(``),e.G(`Please provide tasks using one of these methods:`,`info`),e.G(` 1. Create a template-tasks.json file in the current directory`,`info`),e.G(` 2. Create a template-tasks.ts file in the current directory`,`info`),e.G(` 3. Use --tasks-file option to specify a different JSON file`,`info`),e.G(` 4. Use --tasks-ts option to specify a different TypeScript file`,`info`),console.log(``),e.G(`Example JSON structure:`,`info`),console.log(JSON.stringify({tasks:[{id:`update-package`,name:`Update package.json`,description:`Update package.json with repository information`,required:!0,enabled:!0,type:`update-json`,prompts:[{id:`projectName`,type:`input`,message:`What is your project name?`,default:`my-project`,required:!0},{id:`includeTests`,type:`confirm`,message:`Include test files?`,default:!0}],config:{file:`package.json`,updates:{name:`{{projectName}}`,author:`{{author}}`}}}]},null,2)),console.log(``),r.default.exit(1)),console.log(``),e.G(`Loaded ${a.length} task(s)`,`success`),console.log(``),await e.n(a,{dryRun:i.dryRun,force:i.force,keepTasksFile:i.keepTasksFile,tasksFilePath:o})}catch(t){if(e.G(`❌ CLI execution failed`,`error`),t instanceof Error){e.G(`Error: ${t.message}`,`error`);let n=r.default.env.DEBUG;n!=null&&n!==``&&console.error(t.stack)}else console.error(t);r.default.exit(1)}}),o.parse(r.default.argv);
2
+ const e=require(`./src-BMRBpfq6.cjs`);let t=require(`node:fs`);t=e.Y(t);let n=require(`node:path`);n=e.Y(n);let r=require(`node:process`);r=e.Y(r);let i=require(`commander`);i=e.Y(i);const a=1,o=new i.Command,s=n.default.join(__dirname,`..`,`package.json`);let c=`0.0.0`;try{c=JSON.parse(t.default.readFileSync(s,`utf-8`)).version??`0.0.0`}catch{}o.name(`scaffoldfy`).description(`Initialize and configure project templates with customizable tasks`).version(c),o.option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force re-initialization even if already initialized`).option(`--tasks-file <path>`,`Path to JSON file containing task definitions`,`./template-tasks.json`).option(`--tasks-ts <path>`,`Path to TypeScript file exporting tasks`,`./template-tasks.ts`).action(async i=>{try{let a=[],o;if(i.tasksTs!=null&&i.tasksTs!==``){let s=n.default.resolve(r.default.cwd(),i.tasksTs);if(t.default.existsSync(s)){e.G(`Loading tasks from TypeScript file: ${i.tasksTs}`,`info`),o=s;try{let t=await import(s);a=t.default??t.tasks??[],(!Array.isArray(a)||a.length===0)&&(e.G(`⚠️ No tasks found in TypeScript file or invalid format`,`warn`),e.G(`Expected default export or named export "tasks" with TaskDefinition[]`,`info`))}catch(t){e.G(`Failed to load TypeScript tasks file: ${i.tasksTs}`,`error`),t instanceof Error&&e.G(` Error: ${t.message}`,`error`),r.default.exit(1)}}}if(a.length===0&&i.tasksFile!=null&&i.tasksFile!==``){let s=n.default.resolve(r.default.cwd(),i.tasksFile);if(t.default.existsSync(s)){o=s;try{a=await e.a(s),Array.isArray(a)||(e.G(`❌ Invalid tasks file format`,`error`),e.G(`Expected JSON with { "tasks": [...] } structure`,`info`),r.default.exit(1))}catch(t){e.G(`Failed to load JSON tasks file: ${i.tasksFile}`,`error`),t instanceof Error&&e.G(` Error: ${t.message}`,`error`),r.default.exit(1)}}else e.G(`Tasks file not found: ${i.tasksFile}`,`warn`)}a.length===0&&(e.G(`❌ No tasks defined`,`error`),console.log(``),e.G(`Please provide tasks using one of these methods:`,`info`),e.G(` 1. Create a template-tasks.json file in the current directory`,`info`),e.G(` 2. Create a template-tasks.ts file in the current directory`,`info`),e.G(` 3. Use --tasks-file option to specify a different JSON file`,`info`),e.G(` 4. Use --tasks-ts option to specify a different TypeScript file`,`info`),console.log(``),e.G(`Example JSON structure:`,`info`),console.log(JSON.stringify({tasks:[{id:`update-package`,name:`Update package.json`,description:`Update package.json with repository information`,required:!0,enabled:!0,type:`update-json`,prompts:[{id:`projectName`,type:`input`,message:`What is your project name?`,default:`my-project`,required:!0},{id:`includeTests`,type:`confirm`,message:`Include test files?`,default:!0}],config:{file:`package.json`,updates:{name:`{{projectName}}`,author:`{{author}}`}}}]},null,2)),console.log(``),r.default.exit(1)),console.log(``),e.G(`Loaded ${a.length} task(s)`,`success`),console.log(``),await e.n(a,{dryRun:i.dryRun,force:i.force,tasksFilePath:o})}catch(t){if(e.G(`❌ CLI execution failed`,`error`),t instanceof Error){e.G(`Error: ${t.message}`,`error`);let n=r.default.env.DEBUG;n!=null&&n!==``&&console.error(t.stack)}else console.error(t);r.default.exit(1)}}),o.parse(r.default.argv);
package/dist/cli.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{G as e,a as t,n}from"./src-Cn-rEwSc.js";import r from"node:path";import{fileURLToPath as i}from"node:url";import a from"node:fs";import o from"node:process";import{Command as s}from"commander";const c=()=>i(import.meta.url),l=(()=>r.dirname(c()))(),u=new s,d=r.join(l,`..`,`package.json`);let f=`0.0.0`;try{f=JSON.parse(a.readFileSync(d,`utf-8`)).version??`0.0.0`}catch{}u.name(`scaffoldfy`).description(`Initialize and configure project templates with customizable tasks`).version(f),u.option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force re-initialization even if already initialized`).option(`--keep-tasks-file`,`Keep the tasks file after successful initialization (default: remove)`,!1).option(`--tasks-file <path>`,`Path to JSON file containing task definitions`,`./template-tasks.json`).option(`--tasks-ts <path>`,`Path to TypeScript file exporting tasks`,`./template-tasks.ts`).action(async i=>{try{let s=[],c;if(i.tasksTs!=null&&i.tasksTs!==``){let t=r.resolve(o.cwd(),i.tasksTs);if(a.existsSync(t)){e(`Loading tasks from TypeScript file: ${i.tasksTs}`,`info`),c=t;try{let n=await import(t);s=n.default??n.tasks??[],(!Array.isArray(s)||s.length===0)&&(e(`⚠️ No tasks found in TypeScript file or invalid format`,`warn`),e(`Expected default export or named export "tasks" with TaskDefinition[]`,`info`))}catch(t){e(`Failed to load TypeScript tasks file: ${i.tasksTs}`,`error`),t instanceof Error&&e(` Error: ${t.message}`,`error`),o.exit(1)}}}if(s.length===0&&i.tasksFile!=null&&i.tasksFile!==``){let n=r.resolve(o.cwd(),i.tasksFile);if(a.existsSync(n)){c=n;try{s=await t(n),Array.isArray(s)||(e(`❌ Invalid tasks file format`,`error`),e(`Expected JSON with { "tasks": [...] } structure`,`info`),o.exit(1))}catch(t){e(`Failed to load JSON tasks file: ${i.tasksFile}`,`error`),t instanceof Error&&e(` Error: ${t.message}`,`error`),o.exit(1)}}else e(`Tasks file not found: ${i.tasksFile}`,`warn`)}s.length===0&&(e(`❌ No tasks defined`,`error`),console.log(``),e(`Please provide tasks using one of these methods:`,`info`),e(` 1. Create a template-tasks.json file in the current directory`,`info`),e(` 2. Create a template-tasks.ts file in the current directory`,`info`),e(` 3. Use --tasks-file option to specify a different JSON file`,`info`),e(` 4. Use --tasks-ts option to specify a different TypeScript file`,`info`),console.log(``),e(`Example JSON structure:`,`info`),console.log(JSON.stringify({tasks:[{id:`update-package`,name:`Update package.json`,description:`Update package.json with repository information`,required:!0,enabled:!0,type:`update-json`,prompts:[{id:`projectName`,type:`input`,message:`What is your project name?`,default:`my-project`,required:!0},{id:`includeTests`,type:`confirm`,message:`Include test files?`,default:!0}],config:{file:`package.json`,updates:{name:`{{projectName}}`,author:`{{author}}`}}}]},null,2)),console.log(``),o.exit(1)),console.log(``),e(`Loaded ${s.length} task(s)`,`success`),console.log(``),await n(s,{dryRun:i.dryRun,force:i.force,keepTasksFile:i.keepTasksFile,tasksFilePath:c})}catch(t){if(e(`❌ CLI execution failed`,`error`),t instanceof Error){e(`Error: ${t.message}`,`error`);let n=o.env.DEBUG;n!=null&&n!==``&&console.error(t.stack)}else console.error(t);o.exit(1)}}),u.parse(o.argv);export{};
2
+ import{G as e,a as t,n}from"./src-ACohe65o.js";import r from"node:path";import{fileURLToPath as i}from"node:url";import a from"node:fs";import o from"node:process";import{Command as s}from"commander";const c=()=>i(import.meta.url),l=(()=>r.dirname(c()))(),u=new s,d=r.join(l,`..`,`package.json`);let f=`0.0.0`;try{f=JSON.parse(a.readFileSync(d,`utf-8`)).version??`0.0.0`}catch{}u.name(`scaffoldfy`).description(`Initialize and configure project templates with customizable tasks`).version(f),u.option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force re-initialization even if already initialized`).option(`--tasks-file <path>`,`Path to JSON file containing task definitions`,`./template-tasks.json`).option(`--tasks-ts <path>`,`Path to TypeScript file exporting tasks`,`./template-tasks.ts`).action(async i=>{try{let s=[],c;if(i.tasksTs!=null&&i.tasksTs!==``){let t=r.resolve(o.cwd(),i.tasksTs);if(a.existsSync(t)){e(`Loading tasks from TypeScript file: ${i.tasksTs}`,`info`),c=t;try{let n=await import(t);s=n.default??n.tasks??[],(!Array.isArray(s)||s.length===0)&&(e(`⚠️ No tasks found in TypeScript file or invalid format`,`warn`),e(`Expected default export or named export "tasks" with TaskDefinition[]`,`info`))}catch(t){e(`Failed to load TypeScript tasks file: ${i.tasksTs}`,`error`),t instanceof Error&&e(` Error: ${t.message}`,`error`),o.exit(1)}}}if(s.length===0&&i.tasksFile!=null&&i.tasksFile!==``){let n=r.resolve(o.cwd(),i.tasksFile);if(a.existsSync(n)){c=n;try{s=await t(n),Array.isArray(s)||(e(`❌ Invalid tasks file format`,`error`),e(`Expected JSON with { "tasks": [...] } structure`,`info`),o.exit(1))}catch(t){e(`Failed to load JSON tasks file: ${i.tasksFile}`,`error`),t instanceof Error&&e(` Error: ${t.message}`,`error`),o.exit(1)}}else e(`Tasks file not found: ${i.tasksFile}`,`warn`)}s.length===0&&(e(`❌ No tasks defined`,`error`),console.log(``),e(`Please provide tasks using one of these methods:`,`info`),e(` 1. Create a template-tasks.json file in the current directory`,`info`),e(` 2. Create a template-tasks.ts file in the current directory`,`info`),e(` 3. Use --tasks-file option to specify a different JSON file`,`info`),e(` 4. Use --tasks-ts option to specify a different TypeScript file`,`info`),console.log(``),e(`Example JSON structure:`,`info`),console.log(JSON.stringify({tasks:[{id:`update-package`,name:`Update package.json`,description:`Update package.json with repository information`,required:!0,enabled:!0,type:`update-json`,prompts:[{id:`projectName`,type:`input`,message:`What is your project name?`,default:`my-project`,required:!0},{id:`includeTests`,type:`confirm`,message:`Include test files?`,default:!0}],config:{file:`package.json`,updates:{name:`{{projectName}}`,author:`{{author}}`}}}]},null,2)),console.log(``),o.exit(1)),console.log(``),e(`Loaded ${s.length} task(s)`,`success`),console.log(``),await n(s,{dryRun:i.dryRun,force:i.force,tasksFilePath:c})}catch(t){if(e(`❌ CLI execution failed`,`error`),t instanceof Error){e(`Error: ${t.message}`,`error`);let n=o.env.DEBUG;n!=null&&n!==``&&console.error(t.stack)}else console.error(t);o.exit(1)}}),u.parse(o.argv);export{};
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- const e=require(`./src-eu70b3xC.cjs`);exports.callHook=e._,exports.clearPlugins=e.v,exports.clearTemplateCache=e.r,exports.collectConfig=e.B,exports.collectPrompts=e.p,exports.createPlugin=e.y,exports.displayTasksDiff=e.A,exports.evaluateCondition=e.H,exports.executePluginTask=e.b,exports.executeTask=e.l,exports.getDeleteDiff=e.j,exports.getExecDiff=e.M,exports.getGitInitDiff=e.N,exports.getGitRepoInfo=e.U,exports.getPlugin=e.x,exports.getPluginForTaskType=e.S,exports.getPluginTaskDiff=e.C,exports.getRegexReplaceDiff=e.P,exports.getRenameDiff=e.F,exports.getReplaceInFileDiff=e.I,exports.getTaskDiff=e.L,exports.getTemplateDiff=e.R,exports.getUpdateJsonDiff=e.z,exports.interpolateTemplate=e.W,exports.isPluginTaskType=e.w,exports.listPlugins=e.T,exports.loadAndMergeTemplate=e.i,exports.loadInitializationState=e.d,exports.loadTasksWithInheritance=e.a,exports.loadTemplate=e.o,exports.log=e.G,exports.main=e.t,exports.mergeTemplates=e.s,exports.prompt=e.K,exports.promptYesNo=e.q,exports.registerHooks=e.E,exports.registerPlugin=e.D,exports.resolveAllDefaultValues=e.m,exports.resolveDefaultValue=e.h,exports.runTask=e.u,exports.runWithTasks=e.n,exports.saveInitializationState=e.f,exports.setNestedProperty=e.J,exports.topologicalSort=e.c,exports.unregisterPlugin=e.O,exports.validateConfig=e.V,exports.validatePluginTask=e.k,exports.validatePrompts=e.g;
1
+ const e=require(`./src-BMRBpfq6.cjs`);exports.callHook=e._,exports.clearPlugins=e.v,exports.clearTemplateCache=e.r,exports.collectConfig=e.B,exports.collectPrompts=e.g,exports.createPlugin=e.y,exports.displayTasksDiff=e.A,exports.evaluateCondition=e.H,exports.executePluginTask=e.b,exports.executeTask=e.l,exports.getDeleteDiff=e.j,exports.getExecDiff=e.M,exports.getGitInitDiff=e.N,exports.getGitRepoInfo=e.U,exports.getPlugin=e.x,exports.getPluginForTaskType=e.S,exports.getPluginTaskDiff=e.C,exports.getRegexReplaceDiff=e.P,exports.getRenameDiff=e.F,exports.getReplaceInFileDiff=e.I,exports.getTaskDiff=e.L,exports.getTemplateDiff=e.R,exports.getUpdateJsonDiff=e.z,exports.interpolateTemplate=e.W,exports.isPluginTaskType=e.w,exports.listPlugins=e.T,exports.loadAndMergeTemplate=e.i,exports.loadInitializationState=e.d,exports.loadTasksWithInheritance=e.a,exports.loadTemplate=e.o,exports.log=e.G,exports.main=e.t,exports.mergeTemplates=e.s,exports.prompt=e.K,exports.promptYesNo=e.q,exports.registerHooks=e.E,exports.registerPlugin=e.D,exports.resolveAllDefaultValues=e.m,exports.resolveDefaultValue=e.h,exports.runTask=e.u,exports.runWithTasks=e.n,exports.saveInitializationState=e.f,exports.setNestedProperty=e.J,exports.topologicalSort=e.c,exports.unregisterPlugin=e.O,exports.validateConfig=e.V,exports.validatePluginTask=e.k,exports.validatePrompts=e.p;
package/dist/index.d.cts CHANGED
@@ -321,27 +321,33 @@ declare function createPlugin(name: string, taskType: string, execute: (task: Ta
321
321
  validate?: (task: TaskDefinition) => string[];
322
322
  }): TaskPlugin;
323
323
  //#endregion
324
- //#region src/prompts.d.ts
324
+ //#region src/prompts/collect-prompts.d.ts
325
325
  /**
326
- * Resolve a default value that may be static or executable
327
- * @param defaultValue - The default value configuration
328
- * @param promptId - The prompt ID for error reporting
329
- * @returns The resolved default value
326
+ * Collect prompt answers from task-defined prompts
327
+ * @param prompts - Array of prompt definitions from tasks
328
+ * @param resolvedDefaults - Map of pre-resolved default values
329
+ * @returns Object mapping prompt IDs to their values
330
330
  */
331
- declare function resolveDefaultValue<T = string | number | boolean>(defaultValue: DefaultValue<T> | undefined, promptId: string): Promise<T | undefined>;
331
+ declare function collectPrompts(prompts: PromptDefinition[], resolvedDefaults?: Map<string, unknown>): Promise<Record<string, unknown>>;
332
+ //#endregion
333
+ //#region src/prompts/resolve-all-default-values.d.ts
332
334
  /**
333
335
  * Pre-resolve all executable default values in parallel
334
336
  * @param prompts - Array of prompt definitions
335
337
  * @returns Map of prompt IDs to their resolved default values
336
338
  */
337
339
  declare function resolveAllDefaultValues(prompts: PromptDefinition[]): Promise<Map<string, unknown>>;
340
+ //#endregion
341
+ //#region src/prompts/resolve-default-value.d.ts
338
342
  /**
339
- * Collect prompt answers from task-defined prompts
340
- * @param prompts - Array of prompt definitions from tasks
341
- * @param resolvedDefaults - Map of pre-resolved default values
342
- * @returns Object mapping prompt IDs to their values
343
+ * Resolve a default value that may be static or executable
344
+ * @param defaultValue - The default value configuration
345
+ * @param promptId - The prompt ID for error reporting
346
+ * @returns The resolved default value
343
347
  */
344
- declare function collectPrompts(prompts: PromptDefinition[], resolvedDefaults?: Map<string, unknown>): Promise<Record<string, unknown>>;
348
+ declare function resolveDefaultValue<T = string | number | boolean>(defaultValue: DefaultValue<T> | undefined, promptId: string): Promise<T | undefined>;
349
+ //#endregion
350
+ //#region src/prompts/validate-prompts.d.ts
345
351
  /**
346
352
  * Validate prompt definitions
347
353
  * @param prompts - Array of prompt definitions to validate
@@ -455,13 +461,12 @@ declare function main(customTasks?: TaskDefinition[]): Promise<void>;
455
461
  * @param options - Optional configuration
456
462
  * @param options.dryRun - Preview changes without applying them
457
463
  * @param options.force - Force re-initialization even if already initialized
458
- * @param options.keepTasksFile - Whether to keep the tasks file after initialization
464
+
459
465
  * @param options.tasksFilePath - Path to the tasks file
460
466
  */
461
467
  declare function runWithTasks(customTasks: TaskDefinition[], options?: {
462
468
  dryRun?: boolean | undefined;
463
469
  force?: boolean | undefined;
464
- keepTasksFile?: boolean | undefined;
465
470
  tasksFilePath?: string | undefined;
466
471
  }): Promise<void>;
467
472
  //#endregion
package/dist/index.d.ts CHANGED
@@ -321,27 +321,33 @@ declare function createPlugin(name: string, taskType: string, execute: (task: Ta
321
321
  validate?: (task: TaskDefinition) => string[];
322
322
  }): TaskPlugin;
323
323
  //#endregion
324
- //#region src/prompts.d.ts
324
+ //#region src/prompts/collect-prompts.d.ts
325
325
  /**
326
- * Resolve a default value that may be static or executable
327
- * @param defaultValue - The default value configuration
328
- * @param promptId - The prompt ID for error reporting
329
- * @returns The resolved default value
326
+ * Collect prompt answers from task-defined prompts
327
+ * @param prompts - Array of prompt definitions from tasks
328
+ * @param resolvedDefaults - Map of pre-resolved default values
329
+ * @returns Object mapping prompt IDs to their values
330
330
  */
331
- declare function resolveDefaultValue<T = string | number | boolean>(defaultValue: DefaultValue<T> | undefined, promptId: string): Promise<T | undefined>;
331
+ declare function collectPrompts(prompts: PromptDefinition[], resolvedDefaults?: Map<string, unknown>): Promise<Record<string, unknown>>;
332
+ //#endregion
333
+ //#region src/prompts/resolve-all-default-values.d.ts
332
334
  /**
333
335
  * Pre-resolve all executable default values in parallel
334
336
  * @param prompts - Array of prompt definitions
335
337
  * @returns Map of prompt IDs to their resolved default values
336
338
  */
337
339
  declare function resolveAllDefaultValues(prompts: PromptDefinition[]): Promise<Map<string, unknown>>;
340
+ //#endregion
341
+ //#region src/prompts/resolve-default-value.d.ts
338
342
  /**
339
- * Collect prompt answers from task-defined prompts
340
- * @param prompts - Array of prompt definitions from tasks
341
- * @param resolvedDefaults - Map of pre-resolved default values
342
- * @returns Object mapping prompt IDs to their values
343
+ * Resolve a default value that may be static or executable
344
+ * @param defaultValue - The default value configuration
345
+ * @param promptId - The prompt ID for error reporting
346
+ * @returns The resolved default value
343
347
  */
344
- declare function collectPrompts(prompts: PromptDefinition[], resolvedDefaults?: Map<string, unknown>): Promise<Record<string, unknown>>;
348
+ declare function resolveDefaultValue<T = string | number | boolean>(defaultValue: DefaultValue<T> | undefined, promptId: string): Promise<T | undefined>;
349
+ //#endregion
350
+ //#region src/prompts/validate-prompts.d.ts
345
351
  /**
346
352
  * Validate prompt definitions
347
353
  * @param prompts - Array of prompt definitions to validate
@@ -455,13 +461,12 @@ declare function main(customTasks?: TaskDefinition[]): Promise<void>;
455
461
  * @param options - Optional configuration
456
462
  * @param options.dryRun - Preview changes without applying them
457
463
  * @param options.force - Force re-initialization even if already initialized
458
- * @param options.keepTasksFile - Whether to keep the tasks file after initialization
464
+
459
465
  * @param options.tasksFilePath - Path to the tasks file
460
466
  */
461
467
  declare function runWithTasks(customTasks: TaskDefinition[], options?: {
462
468
  dryRun?: boolean | undefined;
463
469
  force?: boolean | undefined;
464
- keepTasksFile?: boolean | undefined;
465
470
  tasksFilePath?: string | undefined;
466
471
  }): Promise<void>;
467
472
  //#endregion
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{A as e,B as t,C as n,D as r,E as i,F as a,G as o,H as s,I as c,J as l,K as u,L as d,M as f,N as p,O as m,P as h,R as g,S as _,T as v,U as y,V as b,W as x,_ as S,a as C,b as w,c as T,d as E,f as D,g as O,h as k,i as A,j,k as M,l as N,m as P,n as F,o as I,p as L,q as R,r as z,s as B,t as V,u as H,v as U,w as W,x as G,y as K,z as q}from"./src-Cn-rEwSc.js";export{S as callHook,U as clearPlugins,z as clearTemplateCache,t as collectConfig,L as collectPrompts,K as createPlugin,e as displayTasksDiff,s as evaluateCondition,w as executePluginTask,N as executeTask,j as getDeleteDiff,f as getExecDiff,p as getGitInitDiff,y as getGitRepoInfo,G as getPlugin,_ as getPluginForTaskType,n as getPluginTaskDiff,h as getRegexReplaceDiff,a as getRenameDiff,c as getReplaceInFileDiff,d as getTaskDiff,g as getTemplateDiff,q as getUpdateJsonDiff,x as interpolateTemplate,W as isPluginTaskType,v as listPlugins,A as loadAndMergeTemplate,E as loadInitializationState,C as loadTasksWithInheritance,I as loadTemplate,o as log,V as main,B as mergeTemplates,u as prompt,R as promptYesNo,i as registerHooks,r as registerPlugin,P as resolveAllDefaultValues,k as resolveDefaultValue,H as runTask,F as runWithTasks,D as saveInitializationState,l as setNestedProperty,T as topologicalSort,m as unregisterPlugin,b as validateConfig,M as validatePluginTask,O as validatePrompts};
1
+ import{A as e,B as t,C as n,D as r,E as i,F as a,G as o,H as s,I as c,J as l,K as u,L as d,M as f,N as p,O as m,P as h,R as g,S as _,T as v,U as y,V as b,W as x,_ as S,a as C,b as w,c as T,d as E,f as D,g as O,h as k,i as A,j,k as M,l as N,m as P,n as F,o as I,p as L,q as R,r as z,s as B,t as V,u as H,v as U,w as W,x as G,y as K,z as q}from"./src-ACohe65o.js";export{S as callHook,U as clearPlugins,z as clearTemplateCache,t as collectConfig,O as collectPrompts,K as createPlugin,e as displayTasksDiff,s as evaluateCondition,w as executePluginTask,N as executeTask,j as getDeleteDiff,f as getExecDiff,p as getGitInitDiff,y as getGitRepoInfo,G as getPlugin,_ as getPluginForTaskType,n as getPluginTaskDiff,h as getRegexReplaceDiff,a as getRenameDiff,c as getReplaceInFileDiff,d as getTaskDiff,g as getTemplateDiff,q as getUpdateJsonDiff,x as interpolateTemplate,W as isPluginTaskType,v as listPlugins,A as loadAndMergeTemplate,E as loadInitializationState,C as loadTasksWithInheritance,I as loadTemplate,o as log,V as main,B as mergeTemplates,u as prompt,R as promptYesNo,i as registerHooks,r as registerPlugin,P as resolveAllDefaultValues,k as resolveDefaultValue,H as runTask,F as runWithTasks,D as saveInitializationState,l as setNestedProperty,T as topologicalSort,m as unregisterPlugin,b as validateConfig,M as validatePluginTask,L as validatePrompts};
@@ -10,4 +10,4 @@ import e from"node:path";import t from"node:fs";import n from"node:process";impo
10
10
  `)}`}catch(e){return`${C.red}✗ Error: ${e instanceof Error?e.message:String(e)}${C.reset}`}}async function k(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i))return`${C.yellow}⊘ Condition not met - task would be skipped${C.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${C.red}✗ File not found: ${r.file}${C.reset}`;try{let e=await S(a,`utf-8`),t=e;for(let{find:t,replace:n}of r.replacements){let r=g(t,i),a=g(n,i);e=e.replace(r,a)}if(t===e)return`${C.cyan}→ No changes${C.reset}`;let n=T(t,e);return`${C.blue}File: ${r.file}${C.reset}\n${n.join(`
11
11
  `)}`}catch(e){return`${C.red}✗ Error: ${e instanceof Error?e.message:String(e)}${C.reset}`}}function A(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i))return`${C.yellow}⊘ Condition not met - task would be skipped${C.reset}`;let a=r.paths.map(e=>g(e,i)).filter(r=>t.existsSync(e.join(n.cwd(),r)));return a.length===0?`${C.cyan}→ No files/directories to delete${C.reset}`:`${C.red}Would delete:${C.reset}\n${a.map(e=>`${C.red} - ${e}${C.reset}`).join(`
12
12
  `)}`}function te(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i))return`${C.yellow}⊘ Condition not met - task would be skipped${C.reset}`;let a=g(r.from,i),o=g(r.to,i),s=e.join(n.cwd(),a),c=e.join(n.cwd(),o);return t.existsSync(s)?t.existsSync(c)?`${C.yellow}⚠ Destination already exists: ${o}${C.reset}\n${C.cyan}Would rename: ${a} → ${o}${C.reset}`:`${C.cyan}Would rename: ${a} → ${o}${C.reset}`:`${C.red}✗ Source not found: ${a}${C.reset}`}function ne(r){if(r.condition!=null&&r.condition!==``)return`${C.yellow}⊘ Condition check skipped in dry-run${C.reset}`;let i=e.join(n.cwd(),`.git`),a=t.existsSync(i),o=[];if(r.removeExisting&&a&&o.push(`${C.red}Would remove existing .git directory${C.reset}`),o.push(`${C.green}Would initialize git repository${C.reset}`),r.initialCommit){let e=r.message??`Initial commit`;o.push(`${C.green}Would create initial commit: "${e}"${C.reset}`)}return o.join(`
13
- `)}function re(e,t){if(e.condition!=null&&e.condition!==``&&!v(e.condition,t))return`${C.yellow}⊘ Condition not met - task would be skipped${C.reset}`;let r=g(e.command,t),i=e.cwd==null?n.cwd():g(e.cwd,t);return`${C.yellow}Would execute:${C.reset}\n${C.cyan} Command: ${r}${C.reset}\n${C.cyan} Working directory: ${i}${C.reset}`}async function j(e,t){try{switch(e.type){case`update-json`:return await E(e.config,t);case`template`:return await D(e.config,t);case`regex-replace`:return await O(e.config,t);case`replace-in-file`:return await k(e.config,t);case`delete`:return A(e.config,t);case`rename`:return te(e.config,t);case`git-init`:return ne(e.config);case`exec`:return re(e.config,t);default:{let t=e.type;return`${C.yellow}⚠ Diff not available for task type: ${t}${C.reset}`}}}catch(e){return`${C.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${C.reset}`}}async function M(e,t){console.log(``),console.log(`${C.blue}═══════════════════════════════════════════════════════${C.reset}`),console.log(`${C.blue} DRY RUN - Preview of changes${C.reset}`),console.log(`${C.blue}═══════════════════════════════════════════════════════${C.reset}`),console.log(``);for(let n of e){console.log(`${C.cyan}▶ Task: ${n.name}${C.reset}`),console.log(`${C.gray} ${n.description}${C.reset}`),console.log(``);let e=await j(n,t);console.log(e),console.log(``),console.log(`${C.gray}${`─`.repeat(55)}${C.reset}`),console.log(``)}console.log(`${C.blue}═══════════════════════════════════════════════════════${C.reset}`),console.log(`${C.yellow} No changes were applied (dry-run mode)${C.reset}`),console.log(`${C.blue}═══════════════════════════════════════════════════════${C.reset}`),console.log(``)}const N=new Map,P={},F=new Map;function ie(e){if(e.name==null||e.name===``)throw TypeError(`Plugin name is required`);if(!Array.isArray(e.taskTypes)||e.taskTypes.length===0)throw TypeError(`Plugin ${e.name} must define at least one task type`);if(typeof e.execute!=`function`)throw TypeError(`Plugin ${e.name} must provide an execute function`);if(N.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(F.has(t)){let e=F.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}N.set(e.name,e);for(let t of e.taskTypes)F.set(t,e.name);h(`✓ Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`,`info`)}function ae(e){let t=N.get(e);if(t!=null){for(let e of t.taskTypes)F.delete(e);N.delete(e)}}function oe(e){return N.get(e)}function I(e){let t=F.get(e);if(t!=null)return N.get(t)}function L(e){return F.has(e)}function se(){return Array.from(N.keys())}function ce(){N.clear(),F.clear()}function le(e){e.beforeAll!=null&&(P.beforeAll=e.beforeAll),e.afterAll!=null&&(P.afterAll=e.afterAll),e.beforeTask!=null&&(P.beforeTask=e.beforeTask),e.afterTask!=null&&(P.afterTask=e.afterTask),e.onError!=null&&(P.onError=e.onError)}async function R(e,...t){let n=P[e];if(n!=null)try{e===`beforeAll`||e===`afterAll`?await n(t[0]):(e===`beforeTask`||e===`afterTask`||e===`onError`)&&await n(t[0],t[1])}catch(t){h(`Error in ${e} hook: ${t instanceof Error?t.message:String(t)}`,`error`)}}async function z(e,t,n){let r=I(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}async function ue(e,t){let n=I(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function de(e){let t=I(e.type);return t==null?[`No plugin found for task type: ${e.type}`]:t.validate==null?[]:t.validate(e)}function fe(e,t,n,r){return{name:e,...r?.version!=null&&{version:r.version},taskTypes:[t],execute:n,...r?.getDiff!=null&&{getDiff:r.getDiff},...r?.validate!=null&&{validate:r.validate}}}async function B(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`execute`){let e=n.value;if(typeof e!=`string`){h(`Prompt "${t}": execute default value must have a string command`,`error`);return}try{let t=r(e,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:1e4}).trim();if(t.startsWith(`{`)||t.startsWith(`[`))try{return JSON.parse(t)}catch{return t}if(/^-?\d+(?:\.\d+)?$/u.test(t)){let e=Number.parseFloat(t);if(!Number.isNaN(e))return e}return t===`true`||t===`false`?t===`true`:t}catch(e){h(`Prompt "${t}": failed to execute default value command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`value`)return n.value;return e}async function V(e){let t=new Map,n=e.map(async e=>{if(e.default!==void 0){let n=await B(e.default,e.id);n!==void 0&&t.set(e.id,n)}});return await Promise.all(n),t}async function H(e,t=new Map){let n={};if(e.length===0)return n;for(let r of e)try{let e,i=t.get(r.id);switch(r.type){case`input`:{let t={message:r.message};if(i!==void 0&&(t.default=String(i)),r.required!==void 0&&(t.required=r.required),e=await o(t),r.required&&(e==null||typeof e==`string`&&e.trim()===``))throw h(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break}case`password`:if(e=await c({message:r.message,mask:`*`}),r.required&&(e==null||typeof e==`string`&&e.trim()===``))throw h(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break;case`number`:{let t={message:r.message};if(i!==void 0&&(t.default=Number(i)),r.required!==void 0&&(t.required=r.required),r.min!==void 0&&(t.min=r.min),r.max!==void 0&&(t.max=r.max),e=await s(t),r.required&&e==null)throw h(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break}case`select`:{let t={message:r.message,choices:r.choices.map(e=>({name:e.name,value:e.value}))};i!==void 0&&(t.default=i),e=await l(t);break}case`confirm`:{let t=i===void 0?!1:!!i;e=await a({message:r.message,default:t});break}default:throw h(`Unknown prompt type: ${r.type}`,`error`),Error(`Unknown prompt type: ${r.type}`)}n[r.id]=e}catch(e){throw e instanceof Error&&h(`Failed to collect prompt "${r.id}": ${e.message}`,`error`),e}return console.log(``),n}function U(e){let t=[],n=new Set,r=new Set,i=new Set;for(let a of e){if(n.has(a.id)&&t.push(`Duplicate prompt ID: ${a.id}`),n.add(a.id),a.global?r.add(a.id):(r.has(a.id)&&t.push(`Prompt ID "${a.id}" is used as both global and task-specific. Use unique IDs or mark all instances as global.`),i.add(a.id)),a.global&&i.has(a.id)&&t.push(`Prompt ID "${a.id}" is used as both global and task-specific. Use unique IDs or mark all instances as global.`),/^[\w-]+$/u.test(a.id)||t.push(`Invalid prompt ID "${a.id}": must contain only alphanumeric characters, underscores, and hyphens`),(!a.message||a.message.trim()===``)&&t.push(`Prompt "${a.id}" must have a non-empty message`),a.type===`select`){a.choices.length===0&&t.push(`Select prompt "${a.id}" must have at least one choice`);for(let e of a.choices)(!e.name||e.name.trim()===``)&&t.push(`Select prompt "${a.id}" has a choice with empty name`),e.value===void 0&&t.push(`Select prompt "${a.id}" has a choice with undefined value`)}a.type===`number`&&a.min!==void 0&&a.max!==void 0&&a.min>a.max&&t.push(`Number prompt "${a.id}" has min greater than max`)}return t}const W=`.scaffoldfyialized`;function G(){let r=e.join(n.cwd(),W);if(!t.existsSync(r))return null;try{let e=t.readFileSync(r,`utf-8`);return JSON.parse(e)}catch{return null}}function pe(r,i,a=!1){if(a)return;let o=e.join(n.cwd(),`package.json`),s=`0.0.0`;try{s=JSON.parse(t.readFileSync(o,`utf-8`)).version??`0.0.0`}catch{}let c={initializedAt:new Date().toISOString(),config:r,completedTasks:i,version:s},l=e.join(n.cwd(),W);t.writeFileSync(l,JSON.stringify(c,null,2))}const K=i(t.readFile),q=i(t.writeFile),me=i(t.rename);async function he(t,r){if(t.condition!=null&&t.condition!==``&&!v(t.condition,r)){h(`Condition not met, skipping update-json task`,`info`);return}let i=e.join(n.cwd(),t.file),{updates:a}=t,o=await K(i,`utf-8`),s=JSON.parse(o);function c(e){if(typeof e==`string`)return g(e,r);if(Array.isArray(e))return e.map(e=>c(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=c(r);return t}return e}for(let[e,t]of Object.entries(a)){let n=c(t);e.includes(`.`)?_(s,e,n):s[e]=n}await q(i,`${JSON.stringify(s,null,2)}\n`)}async function ge(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i)){h(`Condition not met, skipping template task`,`info`);return}let a=e.join(n.cwd(),r.file),o=r.template!=null&&r.template!==``,s=r.templateFile!=null&&r.templateFile!==``;if(!o&&!s)throw Error(`Template task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(o&&s)throw Error(`Template task cannot have both "template" and "templateFile" specified. Use one or the other.`);let c;if(s&&r.templateFile.endsWith(`.hbs`))c=y(r.templateFile,i);else if(s){let a=r.templateFile,o=e.isAbsolute(a)?a:e.join(n.cwd(),a);if(!t.existsSync(o))throw Error(`Template file not found: ${a}`);c=g(t.readFileSync(o,`utf-8`),i)}else c=g(r.template,i);await q(a,c)}async function _e(t,r){if(t.condition!=null&&t.condition!==``&&!v(t.condition,r)){h(`Condition not met, skipping regex-replace task`,`info`);return}let i=e.join(n.cwd(),t.file),{pattern:a}=t,o=t.flags??``,s=t.replacement||``,c=await K(i,`utf-8`),l=new RegExp(a,o);c=c.replace(l,g(s,r)),await q(i,c)}async function ve(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i)){h(`Condition not met, skipping replace-in-file task`,`info`);return}let a=e.join(n.cwd(),r.file),{replacements:o}=r;if(!t.existsSync(a)){h(`File not found: ${a}, skipping`,`warn`);return}let s=await K(a,`utf-8`);for(let{find:e,replace:t}of o){let n=g(t,i);s=s.replace(new RegExp(e,`gu`),n)}await q(a,s)}async function ye(r,i){let{paths:a,condition:o}=r;if(o!=null&&o!==``){if(!i){h(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!v(o,i)){h(`Condition not met, skipping deletion`,`info`);return}}for(let r of a){let i=e.join(n.cwd(),r);t.existsSync(i)&&t.rmSync(i,{recursive:!0,force:!0})}}async function be(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i)){h(`Condition not met, skipping rename task`,`info`);return}let a=e.join(n.cwd(),g(r.from,i)),o=e.join(n.cwd(),g(r.to,i));if(!t.existsSync(a)){h(`Source path does not exist: ${a}`,`warn`);return}await me(a,o)}async function xe(i,a){if(i.condition!=null&&i.condition!==``){if(!a){h(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!v(i.condition,a)){h(`Condition not met, skipping git-init task`,`info`);return}}if(i.removeExisting){let r=e.join(n.cwd(),`.git`);t.existsSync(r)&&t.rmSync(r,{recursive:!0,force:!0})}if(r(`git init`,{stdio:`inherit`}),i.initialCommit){let e=i.message??`Initial commit`;r(`git add .`,{stdio:`inherit`}),r(`git commit -m "${e}"`,{stdio:`inherit`})}}async function Se(t,i){if(t.condition!=null&&t.condition!==``){if(!i){h(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!v(t.condition,i)){h(`Condition not met, skipping exec task`,`info`);return}}let a=t.cwd==null?n.cwd():e.join(n.cwd(),t.cwd);r(t.command,{cwd:a,stdio:`inherit`})}async function J(e,t,n=!1){if(n){h(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(L(e.type)){await z(e,t,{dryRun:n});return}switch(e.type){case`update-json`:await he(e.config,t);break;case`template`:await ge(e.config,t);break;case`regex-replace`:await _e(e.config,t);break;case`replace-in-file`:await ve(e.config,t);break;case`delete`:await ye(e.config,t);break;case`rename`:await be(e.config,t);break;case`git-init`:await xe(e.config,t);break;case`exec`:await Se(e.config,t);break;default:{let t=e.type;throw TypeError(`Unknown task type: ${t}`)}}}async function Y(e,t,r,i,a=!1){try{return h(`[${r}/${i}] Running: ${e.name}...`,`info`),await J(e,t,a),h(`✓ ${e.name}`,`success`),!0}catch(t){return h(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(h(` Reason: ${t.message}`,`error`),t.stack!=null&&n.env.DEBUG!=null&&console.error(t.stack)),e.required&&h(` This is a required task. Initialization cannot continue.`,`error`),!1}}function X(e){let t=[],n=new Set,r=new Set,i=new Map(e.map(e=>[e.id,e]));function a(e){if(n.has(e))return;if(r.has(e))throw Error(`Circular dependency detected involving task: ${e}`);r.add(e);let o=i.get(e);if(!o)throw Error(`Task not found: ${e}`);if(o.dependencies)for(let e of o.dependencies)a(e);r.delete(e),n.add(e),t.push(o)}for(let t of e)n.has(t.id)||a(t.id);return t}const Ce=i(t.readFile);async function we(i,a){let o=G();o&&!a.force&&(console.log(``),h(`⚠️ This template has already been initialized!`,`warn`),console.log(``),h(` Initialized at: ${new Date(o.initializedAt).toLocaleString()}`,`info`),h(` Repo: ${o.config.repoName}`,`info`),console.log(``),await m(`Do you want to re-initialize? This may cause issues`,!1)||(h(`Initialization cancelled`,`info`),n.exit(0)),console.log(``),h(`⚠️ Proceeding with re-initialization...`,`warn`),console.log(``));let s=i.filter(e=>e.enabled);h(`Resolving task dependencies...`,`info`);let c=X(s);console.log(``);let l=await x(a.dryRun),u=b(l);u.length>0&&(h(`❌ Configuration errors:`,`error`),u.forEach(e=>h(` - ${e}`,`error`)),console.log(``),n.exit(1));let d=[],f=[],p=[];for(let e of c)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)t.global?d.some(e=>e.id===t.id)||(d.push(t),p.push(t)):(f.push(t),p.push(t));if(p.length>0){let e=U(p);e.length>0&&(h(`❌ Prompt validation errors:`,`error`),e.forEach(e=>h(` - ${e}`,`error`)),console.log(``),n.exit(1)),h(`Resolving prompt default values...`,`info`);let t=await V(p);console.log(``);let r={};if(d.length>0&&(console.log(``),h(`📋 Global prompts (available to all tasks):`,`info`),console.log(``),r=await H(d,t),Object.assign(l,r)),f.length>0){d.length>0&&(h(`📋 Task-specific prompts:`,`info`),console.log(``));let e=await H(f,t);Object.assign(l,e)}}if(a.dryRun){await M(c,l),h(`🔍 Dry run completed - no changes were made`,`info`),h(`Run without --dry-run to apply changes`,`info`);return}console.log(``),h(`Starting initialization tasks...`,`info`),console.log(``),await R(`beforeAll`,l);let g=c.length,_=0,v=0,y=[];for(let e=0;e<c.length;e++){let t=c[e];if(t!=null){if(await R(`beforeTask`,t,l),await Y(t,l,e+1,g,a.dryRun))_++,y.push(t.id),await R(`afterTask`,t,l);else if(t.required){v++,await R(`onError`,Error(`Task ${t.name} failed`),t);break}else h(`⚠️ Non-critical task failed, continuing...`,`warn`),await R(`onError`,Error(`Task ${t.name} failed`),t);console.log(``)}}if(v>0&&(h(`❌ Initialization failed with ${v} critical error(s)`,`error`),h(`✓ Completed: ${_}/${g} tasks`,`info`),n.exit(1)),await R(`afterAll`,l),pe(l,y,a.dryRun),h(`✅ Initialization completed successfully!`,`success`),console.log(``),h(`✓ Completed: ${_}/${g} tasks`,`success`),console.log(``),!a.dryRun&&!a.keepTasksFile&&a.tasksFilePath!=null&&t.existsSync(a.tasksFilePath))try{t.unlinkSync(a.tasksFilePath),h(`🗑️ Removed tasks file: ${e.basename(a.tasksFilePath)}`,`info`),console.log(``)}catch(e){h(`⚠️ Failed to remove tasks file: ${e instanceof Error?e.message:`Unknown error`}`,`warn`)}if(!a.dryRun){h(`Next steps:`,`info`),h(`1. Review the changes made to your project`,`info`),h(`2. Commit the changes to git`,`info`);let i=e.join(n.cwd(),`package.json`);t.existsSync(i)&&JSON.parse(await Ce(i,`utf-8`)).scripts?.[`turbo:gen:init`]!=null&&(h(`3. Run "pnpm run turbo:gen:init" to create your first package`,`info`),console.log(``),await m(`Would you like to run turbo:gen:init now?`,!0)&&(console.log(``),h(`Running turbo:gen:init...`,`info`),r(`pnpm run turbo:gen:init`,{stdio:`inherit`})))}console.log(``)}const Te=i(t.readFile),Z=new Map;async function Ee(r,i=new Set){let a=e.isAbsolute(r)?r:e.resolve(n.cwd(),r);if(Z.has(a))return Z.get(a);if(i.has(a))throw Error(`Circular dependency detected: ${Array.from(i).join(` -> `)} -> ${a}`);if(!t.existsSync(a))throw Error(`Template file not found: ${a}`);i.add(a);let o=await Te(a,`utf-8`),s;try{s=JSON.parse(o)}catch(e){throw Error(`Failed to parse template file ${a}: ${e instanceof Error?e.message:String(e)}`)}if(!Array.isArray(s.tasks))throw TypeError(`Invalid template file ${a}: 'tasks' array is required`);return Z.set(a,s),s}async function Q(t,r,i=new Set){let a=e.isAbsolute(t)?t:e.resolve(r??n.cwd(),t);if(i.has(a))throw Error(`Circular dependency detected: ${Array.from(i).join(` -> `)} -> ${a}`);i.add(a);let o=await Ee(a);if(o.extends==null||o.extends===``)return o;let s=e.dirname(a),c=Array.isArray(o.extends)?o.extends:[o.extends],l=[];for(let e of c){let t=await Q(e,s,i);l.push(t)}return De([...l,o])}function De(e){if(e.length===0)return{tasks:[]};if(e.length===1)return e[0];let t=new Map;for(let n of e)for(let e of n.tasks)if(t.has(e.id)){let n=t.get(e.id);t.set(e.id,Oe(n,e))}else t.set(e.id,{...e});return{tasks:Array.from(t.values())}}function Oe(e,t){let n=typeof e.config==`object`&&e.config!==null&&typeof t.config==`object`&&t.config!==null?{...e.config,...t.config}:t.config,r=e.prompts?[...e.prompts]:void 0;if(t.prompts&&t.prompts.length>0)if(!r)r=[...t.prompts];else{let e=new Map(r.map(e=>[e.id,e]));for(let n of t.prompts)e.set(n.id,n);r=Array.from(e.values())}let i=[...e.dependencies??[],...t.dependencies??[]],a=i.length>0?[...new Set(i)]:void 0;return{...e,...t,config:n,...r!=null&&{prompts:r},...a!=null&&{dependencies:a}}}function ke(){Z.clear()}async function Ae(e){h(`Loading tasks from ${e}...`,`info`);let t=await Q(e);return h(`Loaded ${t.tasks.length} task(s)`,`info`),t.extends!=null&&t.extends!==``&&h(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.tasks}const $=n.argv.includes(`--dry-run`),je=n.argv.includes(`--force`);async function Me(e){try{let t=e||[];t.length===0&&(h(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),console.log(``),h(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),console.log(``),n.exit(1)),await we(t,{dryRun:$,force:je,keepTasksFile:void 0,tasksFilePath:void 0})}catch(e){h(`❌ Initialization failed`,`error`),e instanceof Error?(h(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}async function Ne(e,t){try{await we(e,{dryRun:t?.dryRun??$,force:t?.force??je,keepTasksFile:t?.keepTasksFile??void 0,tasksFilePath:t?.tasksFilePath??void 0})}catch(e){h(`❌ Initialization failed`,`error`),e instanceof Error?(h(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}export{M as A,x as B,ue as C,ie as D,le as E,te as F,h as G,v as H,k as I,_ as J,p as K,j as L,re as M,ne as N,ae as O,O as P,D as R,I as S,se as T,f as U,b as V,g as W,R as _,Ae as a,z as b,X as c,G as d,pe as f,U as g,B as h,Q as i,A as j,de as k,J as l,V as m,Ne as n,Ee as o,H as p,m as q,ke as r,De as s,Me as t,Y as u,ce as v,L as w,oe as x,fe as y,E as z};
13
+ `)}function re(e,t){if(e.condition!=null&&e.condition!==``&&!v(e.condition,t))return`${C.yellow}⊘ Condition not met - task would be skipped${C.reset}`;let r=g(e.command,t),i=e.cwd==null?n.cwd():g(e.cwd,t);return`${C.yellow}Would execute:${C.reset}\n${C.cyan} Command: ${r}${C.reset}\n${C.cyan} Working directory: ${i}${C.reset}`}async function j(e,t){try{switch(e.type){case`update-json`:return await E(e.config,t);case`template`:return await D(e.config,t);case`regex-replace`:return await O(e.config,t);case`replace-in-file`:return await k(e.config,t);case`delete`:return A(e.config,t);case`rename`:return te(e.config,t);case`git-init`:return ne(e.config);case`exec`:return re(e.config,t);default:{let t=e.type;return`${C.yellow}⚠ Diff not available for task type: ${t}${C.reset}`}}}catch(e){return`${C.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${C.reset}`}}async function M(e,t){console.log(``),console.log(`${C.blue}═══════════════════════════════════════════════════════${C.reset}`),console.log(`${C.blue} DRY RUN - Preview of changes${C.reset}`),console.log(`${C.blue}═══════════════════════════════════════════════════════${C.reset}`),console.log(``);for(let n of e){console.log(`${C.cyan}▶ Task: ${n.name}${C.reset}`),console.log(`${C.gray} ${n.description}${C.reset}`),console.log(``);let e=await j(n,t);console.log(e),console.log(``),console.log(`${C.gray}${`─`.repeat(55)}${C.reset}`),console.log(``)}console.log(`${C.blue}═══════════════════════════════════════════════════════${C.reset}`),console.log(`${C.yellow} No changes were applied (dry-run mode)${C.reset}`),console.log(`${C.blue}═══════════════════════════════════════════════════════${C.reset}`),console.log(``)}const N=new Map,P={},F=new Map;function ie(e){if(e.name==null||e.name===``)throw TypeError(`Plugin name is required`);if(!Array.isArray(e.taskTypes)||e.taskTypes.length===0)throw TypeError(`Plugin ${e.name} must define at least one task type`);if(typeof e.execute!=`function`)throw TypeError(`Plugin ${e.name} must provide an execute function`);if(N.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(F.has(t)){let e=F.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}N.set(e.name,e);for(let t of e.taskTypes)F.set(t,e.name);h(`✓ Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`,`info`)}function ae(e){let t=N.get(e);if(t!=null){for(let e of t.taskTypes)F.delete(e);N.delete(e)}}function oe(e){return N.get(e)}function I(e){let t=F.get(e);if(t!=null)return N.get(t)}function L(e){return F.has(e)}function se(){return Array.from(N.keys())}function ce(){N.clear(),F.clear()}function le(e){e.beforeAll!=null&&(P.beforeAll=e.beforeAll),e.afterAll!=null&&(P.afterAll=e.afterAll),e.beforeTask!=null&&(P.beforeTask=e.beforeTask),e.afterTask!=null&&(P.afterTask=e.afterTask),e.onError!=null&&(P.onError=e.onError)}async function R(e,...t){let n=P[e];if(n!=null)try{e===`beforeAll`||e===`afterAll`?await n(t[0]):(e===`beforeTask`||e===`afterTask`||e===`onError`)&&await n(t[0],t[1])}catch(t){h(`Error in ${e} hook: ${t instanceof Error?t.message:String(t)}`,`error`)}}async function z(e,t,n){let r=I(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}async function ue(e,t){let n=I(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function de(e){let t=I(e.type);return t==null?[`No plugin found for task type: ${e.type}`]:t.validate==null?[]:t.validate(e)}function fe(e,t,n,r){return{name:e,...r?.version!=null&&{version:r.version},taskTypes:[t],execute:n,...r?.getDiff!=null&&{getDiff:r.getDiff},...r?.validate!=null&&{validate:r.validate}}}async function B(e,t=new Map){let n={};if(e.length===0)return n;for(let r of e)try{let e,i=t.get(r.id);switch(r.type){case`input`:{let t={message:r.message};if(i!==void 0&&(t.default=String(i)),r.required!==void 0&&(t.required=r.required),e=await o(t),r.required&&(e==null||typeof e==`string`&&e.trim()===``))throw h(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break}case`password`:if(e=await c({message:r.message,mask:`*`}),r.required&&(e==null||typeof e==`string`&&e.trim()===``))throw h(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break;case`number`:{let t={message:r.message};if(i!==void 0&&(t.default=Number(i)),r.required!==void 0&&(t.required=r.required),r.min!==void 0&&(t.min=r.min),r.max!==void 0&&(t.max=r.max),e=await s(t),r.required&&e==null)throw h(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break}case`select`:{let t={message:r.message,choices:r.choices.map(e=>({name:e.name,value:e.value}))};i!==void 0&&(t.default=i),e=await l(t);break}case`confirm`:{let t=i===void 0?!1:!!i;e=await a({message:r.message,default:t});break}default:throw h(`Unknown prompt type: ${r.type}`,`error`),Error(`Unknown prompt type: ${r.type}`)}n[r.id]=e}catch(e){throw e instanceof Error&&h(`Failed to collect prompt "${r.id}": ${e.message}`,`error`),e}return console.log(``),n}async function V(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`execute`){let e=n.value;if(typeof e!=`string`){h(`Prompt "${t}": execute default value must have a string command`,`error`);return}try{let t=r(e,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:1e4}).trim();if(t.startsWith(`{`)||t.startsWith(`[`))try{return JSON.parse(t)}catch{return t}if(/^-?\d+(?:\.\d+)?$/u.test(t)){let e=Number.parseFloat(t);if(!Number.isNaN(e))return e}return t===`true`||t===`false`?t===`true`:t}catch(e){h(`Prompt "${t}": failed to execute default value command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`value`)return n.value;return e}async function H(e){let t=new Map,n=e.map(async e=>{if(e.default!==void 0){let n=await V(e.default,e.id);n!==void 0&&t.set(e.id,n)}});return await Promise.all(n),t}function U(e){let t=[],n=new Set,r=new Set,i=new Set;for(let a of e){if(n.has(a.id)&&t.push(`Duplicate prompt ID: ${a.id}`),n.add(a.id),a.global?r.add(a.id):(r.has(a.id)&&t.push(`Prompt ID "${a.id}" is used as both global and task-specific. Use unique IDs or mark all instances as global.`),i.add(a.id)),a.global&&i.has(a.id)&&t.push(`Prompt ID "${a.id}" is used as both global and task-specific. Use unique IDs or mark all instances as global.`),/^[\w-]+$/u.test(a.id)||t.push(`Invalid prompt ID "${a.id}": must contain only alphanumeric characters, underscores, and hyphens`),(!a.message||a.message.trim()===``)&&t.push(`Prompt "${a.id}" must have a non-empty message`),a.type===`select`){a.choices.length===0&&t.push(`Select prompt "${a.id}" must have at least one choice`);for(let e of a.choices)(!e.name||e.name.trim()===``)&&t.push(`Select prompt "${a.id}" has a choice with empty name`),e.value===void 0&&t.push(`Select prompt "${a.id}" has a choice with undefined value`)}a.type===`number`&&a.min!==void 0&&a.max!==void 0&&a.min>a.max&&t.push(`Number prompt "${a.id}" has min greater than max`)}return t}const W=`.scaffoldfyialized`;function G(){let r=e.join(n.cwd(),W);if(!t.existsSync(r))return null;try{let e=t.readFileSync(r,`utf-8`);return JSON.parse(e)}catch{return null}}function pe(r,i,a=!1){if(a)return;let o=e.join(n.cwd(),`package.json`),s=`0.0.0`;try{s=JSON.parse(t.readFileSync(o,`utf-8`)).version??`0.0.0`}catch{}let c={initializedAt:new Date().toISOString(),config:r,completedTasks:i,version:s},l=e.join(n.cwd(),W);t.writeFileSync(l,JSON.stringify(c,null,2))}const K=i(t.readFile),q=i(t.writeFile),me=i(t.rename);async function he(t,r){if(t.condition!=null&&t.condition!==``&&!v(t.condition,r)){h(`Condition not met, skipping update-json task`,`info`);return}let i=e.join(n.cwd(),t.file),{updates:a}=t,o=await K(i,`utf-8`),s=JSON.parse(o);function c(e){if(typeof e==`string`)return g(e,r);if(Array.isArray(e))return e.map(e=>c(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=c(r);return t}return e}for(let[e,t]of Object.entries(a)){let n=c(t);e.includes(`.`)?_(s,e,n):s[e]=n}await q(i,`${JSON.stringify(s,null,2)}\n`)}async function ge(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i)){h(`Condition not met, skipping template task`,`info`);return}let a=e.join(n.cwd(),r.file),o=r.template!=null&&r.template!==``,s=r.templateFile!=null&&r.templateFile!==``;if(!o&&!s)throw Error(`Template task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(o&&s)throw Error(`Template task cannot have both "template" and "templateFile" specified. Use one or the other.`);let c;if(s&&r.templateFile.endsWith(`.hbs`))c=y(r.templateFile,i);else if(s){let a=r.templateFile,o=e.isAbsolute(a)?a:e.join(n.cwd(),a);if(!t.existsSync(o))throw Error(`Template file not found: ${a}`);c=g(t.readFileSync(o,`utf-8`),i)}else c=g(r.template,i);await q(a,c)}async function _e(t,r){if(t.condition!=null&&t.condition!==``&&!v(t.condition,r)){h(`Condition not met, skipping regex-replace task`,`info`);return}let i=e.join(n.cwd(),t.file),{pattern:a}=t,o=t.flags??``,s=t.replacement||``,c=await K(i,`utf-8`),l=new RegExp(a,o);c=c.replace(l,g(s,r)),await q(i,c)}async function ve(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i)){h(`Condition not met, skipping replace-in-file task`,`info`);return}let a=e.join(n.cwd(),r.file),{replacements:o}=r;if(!t.existsSync(a)){h(`File not found: ${a}, skipping`,`warn`);return}let s=await K(a,`utf-8`);for(let{find:e,replace:t}of o){let n=g(t,i);s=s.replace(new RegExp(e,`gu`),n)}await q(a,s)}async function ye(r,i){let{paths:a,condition:o}=r;if(o!=null&&o!==``){if(!i){h(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!v(o,i)){h(`Condition not met, skipping deletion`,`info`);return}}for(let r of a){let i=e.join(n.cwd(),r);t.existsSync(i)&&t.rmSync(i,{recursive:!0,force:!0})}}async function be(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i)){h(`Condition not met, skipping rename task`,`info`);return}let a=e.join(n.cwd(),g(r.from,i)),o=e.join(n.cwd(),g(r.to,i));if(!t.existsSync(a)){h(`Source path does not exist: ${a}`,`warn`);return}await me(a,o)}async function xe(i,a){if(i.condition!=null&&i.condition!==``){if(!a){h(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!v(i.condition,a)){h(`Condition not met, skipping git-init task`,`info`);return}}if(i.removeExisting){let r=e.join(n.cwd(),`.git`);t.existsSync(r)&&t.rmSync(r,{recursive:!0,force:!0})}if(r(`git init`,{stdio:`inherit`}),i.initialCommit){let e=i.message??`Initial commit`;r(`git add .`,{stdio:`inherit`}),r(`git commit -m "${e}"`,{stdio:`inherit`})}}async function Se(t,i){if(t.condition!=null&&t.condition!==``){if(!i){h(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!v(t.condition,i)){h(`Condition not met, skipping exec task`,`info`);return}}let a=t.cwd==null?n.cwd():e.join(n.cwd(),t.cwd);r(t.command,{cwd:a,stdio:`inherit`})}async function J(e,t,n=!1){if(n){h(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(L(e.type)){await z(e,t,{dryRun:n});return}switch(e.type){case`update-json`:await he(e.config,t);break;case`template`:await ge(e.config,t);break;case`regex-replace`:await _e(e.config,t);break;case`replace-in-file`:await ve(e.config,t);break;case`delete`:await ye(e.config,t);break;case`rename`:await be(e.config,t);break;case`git-init`:await xe(e.config,t);break;case`exec`:await Se(e.config,t);break;default:{let t=e.type;throw TypeError(`Unknown task type: ${t}`)}}}async function Y(e,t,r,i,a=!1){try{return h(`[${r}/${i}] Running: ${e.name}...`,`info`),await J(e,t,a),h(`✓ ${e.name}`,`success`),!0}catch(t){return h(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(h(` Reason: ${t.message}`,`error`),t.stack!=null&&n.env.DEBUG!=null&&console.error(t.stack)),e.required&&h(` This is a required task. Initialization cannot continue.`,`error`),!1}}function X(e){let t=[],n=new Set,r=new Set,i=new Map(e.map(e=>[e.id,e]));function a(e){if(n.has(e))return;if(r.has(e))throw Error(`Circular dependency detected involving task: ${e}`);r.add(e);let o=i.get(e);if(!o)throw Error(`Task not found: ${e}`);if(o.dependencies)for(let e of o.dependencies)a(e);r.delete(e),n.add(e),t.push(o)}for(let t of e)n.has(t.id)||a(t.id);return t}const Ce=i(t.readFile);async function we(i,a){let o=G();o&&!a.force&&(console.log(``),h(`⚠️ This template has already been initialized!`,`warn`),console.log(``),h(` Initialized at: ${new Date(o.initializedAt).toLocaleString()}`,`info`),h(` Repo: ${o.config.repoName}`,`info`),console.log(``),await m(`Do you want to re-initialize? This may cause issues`,!1)||(h(`Initialization cancelled`,`info`),n.exit(0)),console.log(``),h(`⚠️ Proceeding with re-initialization...`,`warn`),console.log(``));let s=i.filter(e=>e.enabled);h(`Resolving task dependencies...`,`info`);let c=X(s);console.log(``);let l=await x(a.dryRun),u=b(l);u.length>0&&(h(`❌ Configuration errors:`,`error`),u.forEach(e=>h(` - ${e}`,`error`)),console.log(``),n.exit(1));let d=[],f=[],p=[];for(let e of c)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)t.global?d.some(e=>e.id===t.id)||(d.push(t),p.push(t)):(f.push(t),p.push(t));if(p.length>0){let e=U(p);e.length>0&&(h(`❌ Prompt validation errors:`,`error`),e.forEach(e=>h(` - ${e}`,`error`)),console.log(``),n.exit(1)),h(`Resolving prompt default values...`,`info`);let t=await H(p);console.log(``);let r={};if(d.length>0&&(console.log(``),h(`📋 Global prompts (available to all tasks):`,`info`),console.log(``),r=await B(d,t),Object.assign(l,r)),f.length>0){d.length>0&&(h(`📋 Task-specific prompts:`,`info`),console.log(``));let e=await B(f,t);Object.assign(l,e)}}if(a.dryRun){await M(c,l),h(`🔍 Dry run completed - no changes were made`,`info`),h(`Run without --dry-run to apply changes`,`info`);return}console.log(``),h(`Starting initialization tasks...`,`info`),console.log(``),await R(`beforeAll`,l);let g=c.length,_=0,v=0,y=[];for(let e=0;e<c.length;e++){let t=c[e];if(t!=null){if(await R(`beforeTask`,t,l),await Y(t,l,e+1,g,a.dryRun))_++,y.push(t.id),await R(`afterTask`,t,l);else if(t.required){v++,await R(`onError`,Error(`Task ${t.name} failed`),t);break}else h(`⚠️ Non-critical task failed, continuing...`,`warn`),await R(`onError`,Error(`Task ${t.name} failed`),t);console.log(``)}}if(v>0&&(h(`❌ Initialization failed with ${v} critical error(s)`,`error`),h(`✓ Completed: ${_}/${g} tasks`,`info`),n.exit(1)),await R(`afterAll`,l),pe(l,y,a.dryRun),h(`✅ Initialization completed successfully!`,`success`),console.log(``),h(`✓ Completed: ${_}/${g} tasks`,`success`),console.log(``),!a.dryRun&&a.tasksFilePath!=null&&t.existsSync(a.tasksFilePath))try{t.unlinkSync(a.tasksFilePath),h(`🗑️ Removed tasks file: ${e.basename(a.tasksFilePath)}`,`info`),console.log(``)}catch(e){h(`⚠️ Failed to remove tasks file: ${e instanceof Error?e.message:`Unknown error`}`,`warn`)}if(!a.dryRun){h(`Next steps:`,`info`),h(`1. Review the changes made to your project`,`info`),h(`2. Commit the changes to git`,`info`);let i=e.join(n.cwd(),`package.json`);t.existsSync(i)&&JSON.parse(await Ce(i,`utf-8`)).scripts?.[`turbo:gen:init`]!=null&&(h(`3. Run "pnpm run turbo:gen:init" to create your first package`,`info`),console.log(``),await m(`Would you like to run turbo:gen:init now?`,!0)&&(console.log(``),h(`Running turbo:gen:init...`,`info`),r(`pnpm run turbo:gen:init`,{stdio:`inherit`})))}console.log(``)}const Te=i(t.readFile),Z=new Map;async function Ee(r,i=new Set){let a=e.isAbsolute(r)?r:e.resolve(n.cwd(),r);if(Z.has(a))return Z.get(a);if(i.has(a))throw Error(`Circular dependency detected: ${Array.from(i).join(` -> `)} -> ${a}`);if(!t.existsSync(a))throw Error(`Template file not found: ${a}`);i.add(a);let o=await Te(a,`utf-8`),s;try{s=JSON.parse(o)}catch(e){throw Error(`Failed to parse template file ${a}: ${e instanceof Error?e.message:String(e)}`)}if(!Array.isArray(s.tasks))throw TypeError(`Invalid template file ${a}: 'tasks' array is required`);return Z.set(a,s),s}async function Q(t,r,i=new Set){let a=e.isAbsolute(t)?t:e.resolve(r??n.cwd(),t);if(i.has(a))throw Error(`Circular dependency detected: ${Array.from(i).join(` -> `)} -> ${a}`);i.add(a);let o=await Ee(a);if(o.extends==null||o.extends===``)return o;let s=e.dirname(a),c=Array.isArray(o.extends)?o.extends:[o.extends],l=[];for(let e of c){let t=await Q(e,s,i);l.push(t)}return De([...l,o])}function De(e){if(e.length===0)return{tasks:[]};if(e.length===1)return e[0];let t=new Map;for(let n of e)for(let e of n.tasks)if(t.has(e.id)){let n=t.get(e.id);t.set(e.id,Oe(n,e))}else t.set(e.id,{...e});return{tasks:Array.from(t.values())}}function Oe(e,t){let n=typeof e.config==`object`&&e.config!==null&&typeof t.config==`object`&&t.config!==null?{...e.config,...t.config}:t.config,r=e.prompts?[...e.prompts]:void 0;if(t.prompts&&t.prompts.length>0)if(!r)r=[...t.prompts];else{let e=new Map(r.map(e=>[e.id,e]));for(let n of t.prompts)e.set(n.id,n);r=Array.from(e.values())}let i=[...e.dependencies??[],...t.dependencies??[]],a=i.length>0?[...new Set(i)]:void 0;return{...e,...t,config:n,...r!=null&&{prompts:r},...a!=null&&{dependencies:a}}}function ke(){Z.clear()}async function Ae(e){h(`Loading tasks from ${e}...`,`info`);let t=await Q(e);return h(`Loaded ${t.tasks.length} task(s)`,`info`),t.extends!=null&&t.extends!==``&&h(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.tasks}const $=n.argv.includes(`--dry-run`),je=n.argv.includes(`--force`);async function Me(e){try{let t=e||[];t.length===0&&(h(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),console.log(``),h(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),console.log(``),n.exit(1)),await we(t,{dryRun:$,force:je,tasksFilePath:void 0})}catch(e){h(`❌ Initialization failed`,`error`),e instanceof Error?(h(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}async function Ne(e,t){try{await we(e,{dryRun:t?.dryRun??$,force:t?.force??je,tasksFilePath:t?.tasksFilePath??void 0})}catch(e){h(`❌ Initialization failed`,`error`),e instanceof Error?(h(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}export{M as A,x as B,ue as C,ie as D,le as E,te as F,h as G,v as H,k as I,_ as J,p as K,j as L,re as M,ne as N,ae as O,O as P,D as R,I as S,se as T,f as U,b as V,g as W,R as _,Ae as a,z as b,X as c,G as d,pe as f,B as g,V as h,Q as i,A as j,de as k,J as l,H as m,Ne as n,Ee as o,U as p,m as q,ke as r,De as s,Me as t,Y as u,ce as v,L as w,oe as x,fe as y,E as z};
@@ -10,4 +10,4 @@ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=
10
10
  `)}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function M(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${E.red}✗ File not found: ${e.file}${E.reset}`;try{let r=await T(n,`utf-8`),i=r;for(let{find:n,replace:i}of e.replacements){let e=b(n,t),a=b(i,t);r=r.replace(e,a)}if(i===r)return`${E.cyan}→ No changes${E.reset}`;let a=O(i,r);return`${E.blue}File: ${e.file}${E.reset}\n${a.join(`
11
11
  `)}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}function N(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=e.paths.map(e=>b(e,t)).filter(e=>c.default.existsSync(l.default.join(u.default.cwd(),e)));return n.length===0?`${E.cyan}→ No files/directories to delete${E.reset}`:`${E.red}Would delete:${E.reset}\n${n.map(e=>`${E.red} - ${e}${E.reset}`).join(`
12
12
  `)}`}function P(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=b(e.from,t),r=b(e.to,t),i=l.default.join(u.default.cwd(),n),a=l.default.join(u.default.cwd(),r);return c.default.existsSync(i)?c.default.existsSync(a)?`${E.yellow}⚠ Destination already exists: ${r}${E.reset}\n${E.cyan}Would rename: ${n} → ${r}${E.reset}`:`${E.cyan}Would rename: ${n} → ${r}${E.reset}`:`${E.red}✗ Source not found: ${n}${E.reset}`}function ae(e){if(e.condition!=null&&e.condition!==``)return`${E.yellow}⊘ Condition check skipped in dry-run${E.reset}`;let t=l.default.join(u.default.cwd(),`.git`),n=c.default.existsSync(t),r=[];if(e.removeExisting&&n&&r.push(`${E.red}Would remove existing .git directory${E.reset}`),r.push(`${E.green}Would initialize git repository${E.reset}`),e.initialCommit){let t=e.message??`Initial commit`;r.push(`${E.green}Would create initial commit: "${t}"${E.reset}`)}return r.join(`
13
- `)}function oe(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=b(e.command,t),r=e.cwd==null?u.default.cwd():b(e.cwd,t);return`${E.yellow}Would execute:${E.reset}\n${E.cyan} Command: ${n}${E.reset}\n${E.cyan} Working directory: ${r}${E.reset}`}async function se(e,t){try{switch(e.type){case`update-json`:return await k(e.config,t);case`template`:return await A(e.config,t);case`regex-replace`:return await j(e.config,t);case`replace-in-file`:return await M(e.config,t);case`delete`:return N(e.config,t);case`rename`:return P(e.config,t);case`git-init`:return ae(e.config);case`exec`:return oe(e.config,t);default:{let t=e.type;return`${E.yellow}⚠ Diff not available for task type: ${t}${E.reset}`}}}catch(e){return`${E.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function ce(e,t){console.log(``),console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(`${E.blue} DRY RUN - Preview of changes${E.reset}`),console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(``);for(let n of e){console.log(`${E.cyan}▶ Task: ${n.name}${E.reset}`),console.log(`${E.gray} ${n.description}${E.reset}`),console.log(``);let e=await se(n,t);console.log(e),console.log(``),console.log(`${E.gray}${`─`.repeat(55)}${E.reset}`),console.log(``)}console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(`${E.yellow} No changes were applied (dry-run mode)${E.reset}`),console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(``)}const F=new Map,I={},L=new Map;function le(e){if(e.name==null||e.name===``)throw TypeError(`Plugin name is required`);if(!Array.isArray(e.taskTypes)||e.taskTypes.length===0)throw TypeError(`Plugin ${e.name} must define at least one task type`);if(typeof e.execute!=`function`)throw TypeError(`Plugin ${e.name} must provide an execute function`);if(F.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(L.has(t)){let e=L.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}F.set(e.name,e);for(let t of e.taskTypes)L.set(t,e.name);y(`✓ Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`,`info`)}function ue(e){let t=F.get(e);if(t!=null){for(let e of t.taskTypes)L.delete(e);F.delete(e)}}function de(e){return F.get(e)}function R(e){let t=L.get(e);if(t!=null)return F.get(t)}function z(e){return L.has(e)}function fe(){return Array.from(F.keys())}function pe(){F.clear(),L.clear()}function me(e){e.beforeAll!=null&&(I.beforeAll=e.beforeAll),e.afterAll!=null&&(I.afterAll=e.afterAll),e.beforeTask!=null&&(I.beforeTask=e.beforeTask),e.afterTask!=null&&(I.afterTask=e.afterTask),e.onError!=null&&(I.onError=e.onError)}async function B(e,...t){let n=I[e];if(n!=null)try{e===`beforeAll`||e===`afterAll`?await n(t[0]):(e===`beforeTask`||e===`afterTask`||e===`onError`)&&await n(t[0],t[1])}catch(t){y(`Error in ${e} hook: ${t instanceof Error?t.message:String(t)}`,`error`)}}async function V(e,t,n){let r=R(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}async function he(e,t){let n=R(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function ge(e){let t=R(e.type);return t==null?[`No plugin found for task type: ${e.type}`]:t.validate==null?[]:t.validate(e)}function _e(e,t,n,r){return{name:e,...r?.version!=null&&{version:r.version},taskTypes:[t],execute:n,...r?.getDiff!=null&&{getDiff:r.getDiff},...r?.validate!=null&&{validate:r.validate}}}async function H(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`execute`){let e=n.value;if(typeof e!=`string`){y(`Prompt "${t}": execute default value must have a string command`,`error`);return}try{let t=(0,d.execSync)(e,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:1e4}).trim();if(t.startsWith(`{`)||t.startsWith(`[`))try{return JSON.parse(t)}catch{return t}if(/^-?\d+(?:\.\d+)?$/u.test(t)){let e=Number.parseFloat(t);if(!Number.isNaN(e))return e}return t===`true`||t===`false`?t===`true`:t}catch(e){y(`Prompt "${t}": failed to execute default value command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`value`)return n.value;return e}async function U(e){let t=new Map,n=e.map(async e=>{if(e.default!==void 0){let n=await H(e.default,e.id);n!==void 0&&t.set(e.id,n)}});return await Promise.all(n),t}async function W(e,t=new Map){let n={};if(e.length===0)return n;for(let r of e)try{let e,i=t.get(r.id);switch(r.type){case`input`:{let t={message:r.message};if(i!==void 0&&(t.default=String(i)),r.required!==void 0&&(t.required=r.required),e=await(0,p.input)(t),r.required&&(e==null||typeof e==`string`&&e.trim()===``))throw y(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break}case`password`:if(e=await(0,p.password)({message:r.message,mask:`*`}),r.required&&(e==null||typeof e==`string`&&e.trim()===``))throw y(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break;case`number`:{let t={message:r.message};if(i!==void 0&&(t.default=Number(i)),r.required!==void 0&&(t.required=r.required),r.min!==void 0&&(t.min=r.min),r.max!==void 0&&(t.max=r.max),e=await(0,p.number)(t),r.required&&e==null)throw y(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break}case`select`:{let t={message:r.message,choices:r.choices.map(e=>({name:e.name,value:e.value}))};i!==void 0&&(t.default=i),e=await(0,p.select)(t);break}case`confirm`:{let t=i===void 0?!1:!!i;e=await(0,p.confirm)({message:r.message,default:t});break}default:throw y(`Unknown prompt type: ${r.type}`,`error`),Error(`Unknown prompt type: ${r.type}`)}n[r.id]=e}catch(e){throw e instanceof Error&&y(`Failed to collect prompt "${r.id}": ${e.message}`,`error`),e}return console.log(``),n}function G(e){let t=[],n=new Set,r=new Set,i=new Set;for(let a of e){if(n.has(a.id)&&t.push(`Duplicate prompt ID: ${a.id}`),n.add(a.id),a.global?r.add(a.id):(r.has(a.id)&&t.push(`Prompt ID "${a.id}" is used as both global and task-specific. Use unique IDs or mark all instances as global.`),i.add(a.id)),a.global&&i.has(a.id)&&t.push(`Prompt ID "${a.id}" is used as both global and task-specific. Use unique IDs or mark all instances as global.`),/^[\w-]+$/u.test(a.id)||t.push(`Invalid prompt ID "${a.id}": must contain only alphanumeric characters, underscores, and hyphens`),(!a.message||a.message.trim()===``)&&t.push(`Prompt "${a.id}" must have a non-empty message`),a.type===`select`){a.choices.length===0&&t.push(`Select prompt "${a.id}" must have at least one choice`);for(let e of a.choices)(!e.name||e.name.trim()===``)&&t.push(`Select prompt "${a.id}" has a choice with empty name`),e.value===void 0&&t.push(`Select prompt "${a.id}" has a choice with undefined value`)}a.type===`number`&&a.min!==void 0&&a.max!==void 0&&a.min>a.max&&t.push(`Number prompt "${a.id}" has min greater than max`)}return t}const K=`.scaffoldfyialized`;function q(){let e=l.default.join(u.default.cwd(),K);if(!c.default.existsSync(e))return null;try{let t=c.default.readFileSync(e,`utf-8`);return JSON.parse(t)}catch{return null}}function J(e,t,n=!1){if(n)return;let r=l.default.join(u.default.cwd(),`package.json`),i=`0.0.0`;try{i=JSON.parse(c.default.readFileSync(r,`utf-8`)).version??`0.0.0`}catch{}let a={initializedAt:new Date().toISOString(),config:e,completedTasks:t,version:i},o=l.default.join(u.default.cwd(),K);c.default.writeFileSync(o,JSON.stringify(a,null,2))}const Y=(0,f.promisify)(c.default.readFile),X=(0,f.promisify)(c.default.writeFile),ve=(0,f.promisify)(c.default.rename),ye=2;async function be(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping update-json task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{updates:r}=e,i=await Y(n,`utf-8`),a=JSON.parse(i);function o(e){if(typeof e==`string`)return b(e,t);if(Array.isArray(e))return e.map(e=>o(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=o(r);return t}return e}for(let[e,t]of Object.entries(r)){let n=o(t);e.includes(`.`)?x(a,e,n):a[e]=n}await X(n,`${JSON.stringify(a,null,2)}\n`)}async function xe(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping template task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),r=e.template!=null&&e.template!==``,i=e.templateFile!=null&&e.templateFile!==``;if(!r&&!i)throw Error(`Template task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(r&&i)throw Error(`Template task cannot have both "template" and "templateFile" specified. Use one or the other.`);let a;if(i&&e.templateFile.endsWith(`.hbs`))a=ee(e.templateFile,t);else if(i){let n=e.templateFile,r=l.default.isAbsolute(n)?n:l.default.join(u.default.cwd(),n);if(!c.default.existsSync(r))throw Error(`Template file not found: ${n}`);a=b(c.default.readFileSync(r,`utf-8`),t)}else a=b(e.template,t);await X(n,a)}async function Se(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping regex-replace task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{pattern:r}=e,i=e.flags??``,a=e.replacement||``,o=await Y(n,`utf-8`),s=new RegExp(r,i);o=o.replace(s,b(a,t)),await X(n,o)}async function Ce(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping replace-in-file task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{replacements:r}=e;if(!c.default.existsSync(n)){y(`File not found: ${n}, skipping`,`warn`);return}let i=await Y(n,`utf-8`);for(let{find:e,replace:n}of r){let r=b(n,t);i=i.replace(new RegExp(e,`gu`),r)}await X(n,i)}async function we(e,t){let{paths:n,condition:r}=e;if(r!=null&&r!==``){if(!t){y(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!S(r,t)){y(`Condition not met, skipping deletion`,`info`);return}}for(let e of n){let t=l.default.join(u.default.cwd(),e);c.default.existsSync(t)&&c.default.rmSync(t,{recursive:!0,force:!0})}}async function Te(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping rename task`,`info`);return}let n=l.default.join(u.default.cwd(),b(e.from,t)),r=l.default.join(u.default.cwd(),b(e.to,t));if(!c.default.existsSync(n)){y(`Source path does not exist: ${n}`,`warn`);return}await ve(n,r)}async function Ee(e,t){if(e.condition!=null&&e.condition!==``){if(!t){y(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!S(e.condition,t)){y(`Condition not met, skipping git-init task`,`info`);return}}if(e.removeExisting){let e=l.default.join(u.default.cwd(),`.git`);c.default.existsSync(e)&&c.default.rmSync(e,{recursive:!0,force:!0})}if((0,d.execSync)(`git init`,{stdio:`inherit`}),e.initialCommit){let t=e.message??`Initial commit`;(0,d.execSync)(`git add .`,{stdio:`inherit`}),(0,d.execSync)(`git commit -m "${t}"`,{stdio:`inherit`})}}async function De(e,t){if(e.condition!=null&&e.condition!==``){if(!t){y(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!S(e.condition,t)){y(`Condition not met, skipping exec task`,`info`);return}}let n=e.cwd==null?u.default.cwd():l.default.join(u.default.cwd(),e.cwd);(0,d.execSync)(e.command,{cwd:n,stdio:`inherit`})}async function Oe(e,t,n=!1){if(n){y(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(z(e.type)){await V(e,t,{dryRun:n});return}switch(e.type){case`update-json`:await be(e.config,t);break;case`template`:await xe(e.config,t);break;case`regex-replace`:await Se(e.config,t);break;case`replace-in-file`:await Ce(e.config,t);break;case`delete`:await we(e.config,t);break;case`rename`:await Te(e.config,t);break;case`git-init`:await Ee(e.config,t);break;case`exec`:await De(e.config,t);break;default:{let t=e.type;throw TypeError(`Unknown task type: ${t}`)}}}async function ke(e,t,n,r,i=!1){try{return y(`[${n}/${r}] Running: ${e.name}...`,`info`),await Oe(e,t,i),y(`✓ ${e.name}`,`success`),!0}catch(t){return y(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(y(` Reason: ${t.message}`,`error`),t.stack!=null&&u.default.env.DEBUG!=null&&console.error(t.stack)),e.required&&y(` This is a required task. Initialization cannot continue.`,`error`),!1}}function Ae(e){let t=[],n=new Set,r=new Set,i=new Map(e.map(e=>[e.id,e]));function a(e){if(n.has(e))return;if(r.has(e))throw Error(`Circular dependency detected involving task: ${e}`);r.add(e);let o=i.get(e);if(!o)throw Error(`Task not found: ${e}`);if(o.dependencies)for(let e of o.dependencies)a(e);r.delete(e),n.add(e),t.push(o)}for(let t of e)n.has(t.id)||a(t.id);return t}const je=(0,f.promisify)(c.default.readFile);async function Me(e,t){let n=q();n&&!t.force&&(console.log(``),y(`⚠️ This template has already been initialized!`,`warn`),console.log(``),y(` Initialized at: ${new Date(n.initializedAt).toLocaleString()}`,`info`),y(` Repo: ${n.config.repoName}`,`info`),console.log(``),await v(`Do you want to re-initialize? This may cause issues`,!1)||(y(`Initialization cancelled`,`info`),u.default.exit(0)),console.log(``),y(`⚠️ Proceeding with re-initialization...`,`warn`),console.log(``));let r=e.filter(e=>e.enabled);y(`Resolving task dependencies...`,`info`);let i=Ae(r);console.log(``);let a=await w(t.dryRun),o=C(a);o.length>0&&(y(`❌ Configuration errors:`,`error`),o.forEach(e=>y(` - ${e}`,`error`)),console.log(``),u.default.exit(1));let s=[],f=[],p=[];for(let e of i)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)t.global?s.some(e=>e.id===t.id)||(s.push(t),p.push(t)):(f.push(t),p.push(t));if(p.length>0){let e=G(p);e.length>0&&(y(`❌ Prompt validation errors:`,`error`),e.forEach(e=>y(` - ${e}`,`error`)),console.log(``),u.default.exit(1)),y(`Resolving prompt default values...`,`info`);let t=await U(p);console.log(``);let n={};if(s.length>0&&(console.log(``),y(`📋 Global prompts (available to all tasks):`,`info`),console.log(``),n=await W(s,t),Object.assign(a,n)),f.length>0){s.length>0&&(y(`📋 Task-specific prompts:`,`info`),console.log(``));let e=await W(f,t);Object.assign(a,e)}}if(t.dryRun){await ce(i,a),y(`🔍 Dry run completed - no changes were made`,`info`),y(`Run without --dry-run to apply changes`,`info`);return}console.log(``),y(`Starting initialization tasks...`,`info`),console.log(``),await B(`beforeAll`,a);let m=i.length,h=0,g=0,_=[];for(let e=0;e<i.length;e++){let n=i[e];if(n!=null){if(await B(`beforeTask`,n,a),await ke(n,a,e+1,m,t.dryRun))h++,_.push(n.id),await B(`afterTask`,n,a);else if(n.required){g++,await B(`onError`,Error(`Task ${n.name} failed`),n);break}else y(`⚠️ Non-critical task failed, continuing...`,`warn`),await B(`onError`,Error(`Task ${n.name} failed`),n);console.log(``)}}if(g>0&&(y(`❌ Initialization failed with ${g} critical error(s)`,`error`),y(`✓ Completed: ${h}/${m} tasks`,`info`),u.default.exit(1)),await B(`afterAll`,a),J(a,_,t.dryRun),y(`✅ Initialization completed successfully!`,`success`),console.log(``),y(`✓ Completed: ${h}/${m} tasks`,`success`),console.log(``),!t.dryRun&&!t.keepTasksFile&&t.tasksFilePath!=null&&c.default.existsSync(t.tasksFilePath))try{c.default.unlinkSync(t.tasksFilePath),y(`🗑️ Removed tasks file: ${l.default.basename(t.tasksFilePath)}`,`info`),console.log(``)}catch(e){y(`⚠️ Failed to remove tasks file: ${e instanceof Error?e.message:`Unknown error`}`,`warn`)}if(!t.dryRun){y(`Next steps:`,`info`),y(`1. Review the changes made to your project`,`info`),y(`2. Commit the changes to git`,`info`);let e=l.default.join(u.default.cwd(),`package.json`);c.default.existsSync(e)&&JSON.parse(await je(e,`utf-8`)).scripts?.[`turbo:gen:init`]!=null&&(y(`3. Run "pnpm run turbo:gen:init" to create your first package`,`info`),console.log(``),await v(`Would you like to run turbo:gen:init now?`,!0)&&(console.log(``),y(`Running turbo:gen:init...`,`info`),(0,d.execSync)(`pnpm run turbo:gen:init`,{stdio:`inherit`})))}console.log(``)}const Ne=(0,f.promisify)(c.default.readFile),Z=new Map;async function Pe(e,t=new Set){let n=l.default.isAbsolute(e)?e:l.default.resolve(u.default.cwd(),e);if(Z.has(n))return Z.get(n);if(t.has(n))throw Error(`Circular dependency detected: ${Array.from(t).join(` -> `)} -> ${n}`);if(!c.default.existsSync(n))throw Error(`Template file not found: ${n}`);t.add(n);let r=await Ne(n,`utf-8`),i;try{i=JSON.parse(r)}catch(e){throw Error(`Failed to parse template file ${n}: ${e instanceof Error?e.message:String(e)}`)}if(!Array.isArray(i.tasks))throw TypeError(`Invalid template file ${n}: 'tasks' array is required`);return Z.set(n,i),i}async function Q(e,t,n=new Set){let r=l.default.isAbsolute(e)?e:l.default.resolve(t??u.default.cwd(),e);if(n.has(r))throw Error(`Circular dependency detected: ${Array.from(n).join(` -> `)} -> ${r}`);n.add(r);let i=await Pe(r);if(i.extends==null||i.extends===``)return i;let a=l.default.dirname(r),o=Array.isArray(i.extends)?i.extends:[i.extends],s=[];for(let e of o){let t=await Q(e,a,n);s.push(t)}return Fe([...s,i])}function Fe(e){if(e.length===0)return{tasks:[]};if(e.length===1)return e[0];let t=new Map;for(let n of e)for(let e of n.tasks)if(t.has(e.id)){let n=t.get(e.id);t.set(e.id,Ie(n,e))}else t.set(e.id,{...e});return{tasks:Array.from(t.values())}}function Ie(e,t){let n=typeof e.config==`object`&&e.config!==null&&typeof t.config==`object`&&t.config!==null?{...e.config,...t.config}:t.config,r=e.prompts?[...e.prompts]:void 0;if(t.prompts&&t.prompts.length>0)if(!r)r=[...t.prompts];else{let e=new Map(r.map(e=>[e.id,e]));for(let n of t.prompts)e.set(n.id,n);r=Array.from(e.values())}let i=[...e.dependencies??[],...t.dependencies??[]],a=i.length>0?[...new Set(i)]:void 0;return{...e,...t,config:n,...r!=null&&{prompts:r},...a!=null&&{dependencies:a}}}function Le(){Z.clear()}async function Re(e){y(`Loading tasks from ${e}...`,`info`);let t=await Q(e);return y(`Loaded ${t.tasks.length} task(s)`,`info`),t.extends!=null&&t.extends!==``&&y(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.tasks}const $=u.default.argv.includes(`--dry-run`),ze=u.default.argv.includes(`--force`);async function Be(e){try{let t=e||[];t.length===0&&(y(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),console.log(``),y(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),console.log(``),u.default.exit(1)),await Me(t,{dryRun:$,force:ze,keepTasksFile:void 0,tasksFilePath:void 0})}catch(e){y(`❌ Initialization failed`,`error`),e instanceof Error?(y(`Error: ${e.message}`,`error`),u.default.env.DEBUG!=null&&console.error(e.stack)):console.error(e),u.default.exit(1)}}async function Ve(e,t){try{await Me(e,{dryRun:t?.dryRun??$,force:t?.force??ze,keepTasksFile:t?.keepTasksFile??void 0,tasksFilePath:t?.tasksFilePath??void 0})}catch(e){y(`❌ Initialization failed`,`error`),e instanceof Error?(y(`Error: ${e.message}`,`error`),u.default.env.DEBUG!=null&&console.error(e.stack)):console.error(e),u.default.exit(1)}}Object.defineProperty(exports,`A`,{enumerable:!0,get:function(){return ce}}),Object.defineProperty(exports,`B`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`C`,{enumerable:!0,get:function(){return he}}),Object.defineProperty(exports,`D`,{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,`E`,{enumerable:!0,get:function(){return me}}),Object.defineProperty(exports,`F`,{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,`G`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`H`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`I`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`J`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`K`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`L`,{enumerable:!0,get:function(){return se}}),Object.defineProperty(exports,`M`,{enumerable:!0,get:function(){return oe}}),Object.defineProperty(exports,`N`,{enumerable:!0,get:function(){return ae}}),Object.defineProperty(exports,`O`,{enumerable:!0,get:function(){return ue}}),Object.defineProperty(exports,`P`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`R`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`T`,{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,`U`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`V`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`W`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`Y`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return Re}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return Ae}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,`j`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`k`,{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return Oe}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return Ve}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`q`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return Le}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return Fe}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Be}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return ke}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return pe}}),Object.defineProperty(exports,`w`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,`z`,{enumerable:!0,get:function(){return k}});
13
+ `)}function oe(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=b(e.command,t),r=e.cwd==null?u.default.cwd():b(e.cwd,t);return`${E.yellow}Would execute:${E.reset}\n${E.cyan} Command: ${n}${E.reset}\n${E.cyan} Working directory: ${r}${E.reset}`}async function se(e,t){try{switch(e.type){case`update-json`:return await k(e.config,t);case`template`:return await A(e.config,t);case`regex-replace`:return await j(e.config,t);case`replace-in-file`:return await M(e.config,t);case`delete`:return N(e.config,t);case`rename`:return P(e.config,t);case`git-init`:return ae(e.config);case`exec`:return oe(e.config,t);default:{let t=e.type;return`${E.yellow}⚠ Diff not available for task type: ${t}${E.reset}`}}}catch(e){return`${E.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function ce(e,t){console.log(``),console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(`${E.blue} DRY RUN - Preview of changes${E.reset}`),console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(``);for(let n of e){console.log(`${E.cyan}▶ Task: ${n.name}${E.reset}`),console.log(`${E.gray} ${n.description}${E.reset}`),console.log(``);let e=await se(n,t);console.log(e),console.log(``),console.log(`${E.gray}${`─`.repeat(55)}${E.reset}`),console.log(``)}console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(`${E.yellow} No changes were applied (dry-run mode)${E.reset}`),console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(``)}const F=new Map,I={},L=new Map;function le(e){if(e.name==null||e.name===``)throw TypeError(`Plugin name is required`);if(!Array.isArray(e.taskTypes)||e.taskTypes.length===0)throw TypeError(`Plugin ${e.name} must define at least one task type`);if(typeof e.execute!=`function`)throw TypeError(`Plugin ${e.name} must provide an execute function`);if(F.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(L.has(t)){let e=L.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}F.set(e.name,e);for(let t of e.taskTypes)L.set(t,e.name);y(`✓ Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`,`info`)}function ue(e){let t=F.get(e);if(t!=null){for(let e of t.taskTypes)L.delete(e);F.delete(e)}}function de(e){return F.get(e)}function R(e){let t=L.get(e);if(t!=null)return F.get(t)}function z(e){return L.has(e)}function fe(){return Array.from(F.keys())}function pe(){F.clear(),L.clear()}function me(e){e.beforeAll!=null&&(I.beforeAll=e.beforeAll),e.afterAll!=null&&(I.afterAll=e.afterAll),e.beforeTask!=null&&(I.beforeTask=e.beforeTask),e.afterTask!=null&&(I.afterTask=e.afterTask),e.onError!=null&&(I.onError=e.onError)}async function B(e,...t){let n=I[e];if(n!=null)try{e===`beforeAll`||e===`afterAll`?await n(t[0]):(e===`beforeTask`||e===`afterTask`||e===`onError`)&&await n(t[0],t[1])}catch(t){y(`Error in ${e} hook: ${t instanceof Error?t.message:String(t)}`,`error`)}}async function V(e,t,n){let r=R(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}async function he(e,t){let n=R(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function ge(e){let t=R(e.type);return t==null?[`No plugin found for task type: ${e.type}`]:t.validate==null?[]:t.validate(e)}function _e(e,t,n,r){return{name:e,...r?.version!=null&&{version:r.version},taskTypes:[t],execute:n,...r?.getDiff!=null&&{getDiff:r.getDiff},...r?.validate!=null&&{validate:r.validate}}}async function H(e,t=new Map){let n={};if(e.length===0)return n;for(let r of e)try{let e,i=t.get(r.id);switch(r.type){case`input`:{let t={message:r.message};if(i!==void 0&&(t.default=String(i)),r.required!==void 0&&(t.required=r.required),e=await(0,p.input)(t),r.required&&(e==null||typeof e==`string`&&e.trim()===``))throw y(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break}case`password`:if(e=await(0,p.password)({message:r.message,mask:`*`}),r.required&&(e==null||typeof e==`string`&&e.trim()===``))throw y(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break;case`number`:{let t={message:r.message};if(i!==void 0&&(t.default=Number(i)),r.required!==void 0&&(t.required=r.required),r.min!==void 0&&(t.min=r.min),r.max!==void 0&&(t.max=r.max),e=await(0,p.number)(t),r.required&&e==null)throw y(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break}case`select`:{let t={message:r.message,choices:r.choices.map(e=>({name:e.name,value:e.value}))};i!==void 0&&(t.default=i),e=await(0,p.select)(t);break}case`confirm`:{let t=i===void 0?!1:!!i;e=await(0,p.confirm)({message:r.message,default:t});break}default:throw y(`Unknown prompt type: ${r.type}`,`error`),Error(`Unknown prompt type: ${r.type}`)}n[r.id]=e}catch(e){throw e instanceof Error&&y(`Failed to collect prompt "${r.id}": ${e.message}`,`error`),e}return console.log(``),n}async function U(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`execute`){let e=n.value;if(typeof e!=`string`){y(`Prompt "${t}": execute default value must have a string command`,`error`);return}try{let t=(0,d.execSync)(e,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:1e4}).trim();if(t.startsWith(`{`)||t.startsWith(`[`))try{return JSON.parse(t)}catch{return t}if(/^-?\d+(?:\.\d+)?$/u.test(t)){let e=Number.parseFloat(t);if(!Number.isNaN(e))return e}return t===`true`||t===`false`?t===`true`:t}catch(e){y(`Prompt "${t}": failed to execute default value command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`value`)return n.value;return e}async function W(e){let t=new Map,n=e.map(async e=>{if(e.default!==void 0){let n=await U(e.default,e.id);n!==void 0&&t.set(e.id,n)}});return await Promise.all(n),t}function G(e){let t=[],n=new Set,r=new Set,i=new Set;for(let a of e){if(n.has(a.id)&&t.push(`Duplicate prompt ID: ${a.id}`),n.add(a.id),a.global?r.add(a.id):(r.has(a.id)&&t.push(`Prompt ID "${a.id}" is used as both global and task-specific. Use unique IDs or mark all instances as global.`),i.add(a.id)),a.global&&i.has(a.id)&&t.push(`Prompt ID "${a.id}" is used as both global and task-specific. Use unique IDs or mark all instances as global.`),/^[\w-]+$/u.test(a.id)||t.push(`Invalid prompt ID "${a.id}": must contain only alphanumeric characters, underscores, and hyphens`),(!a.message||a.message.trim()===``)&&t.push(`Prompt "${a.id}" must have a non-empty message`),a.type===`select`){a.choices.length===0&&t.push(`Select prompt "${a.id}" must have at least one choice`);for(let e of a.choices)(!e.name||e.name.trim()===``)&&t.push(`Select prompt "${a.id}" has a choice with empty name`),e.value===void 0&&t.push(`Select prompt "${a.id}" has a choice with undefined value`)}a.type===`number`&&a.min!==void 0&&a.max!==void 0&&a.min>a.max&&t.push(`Number prompt "${a.id}" has min greater than max`)}return t}const K=`.scaffoldfyialized`;function q(){let e=l.default.join(u.default.cwd(),K);if(!c.default.existsSync(e))return null;try{let t=c.default.readFileSync(e,`utf-8`);return JSON.parse(t)}catch{return null}}function J(e,t,n=!1){if(n)return;let r=l.default.join(u.default.cwd(),`package.json`),i=`0.0.0`;try{i=JSON.parse(c.default.readFileSync(r,`utf-8`)).version??`0.0.0`}catch{}let a={initializedAt:new Date().toISOString(),config:e,completedTasks:t,version:i},o=l.default.join(u.default.cwd(),K);c.default.writeFileSync(o,JSON.stringify(a,null,2))}const Y=(0,f.promisify)(c.default.readFile),X=(0,f.promisify)(c.default.writeFile),ve=(0,f.promisify)(c.default.rename),ye=2;async function be(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping update-json task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{updates:r}=e,i=await Y(n,`utf-8`),a=JSON.parse(i);function o(e){if(typeof e==`string`)return b(e,t);if(Array.isArray(e))return e.map(e=>o(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=o(r);return t}return e}for(let[e,t]of Object.entries(r)){let n=o(t);e.includes(`.`)?x(a,e,n):a[e]=n}await X(n,`${JSON.stringify(a,null,2)}\n`)}async function xe(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping template task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),r=e.template!=null&&e.template!==``,i=e.templateFile!=null&&e.templateFile!==``;if(!r&&!i)throw Error(`Template task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(r&&i)throw Error(`Template task cannot have both "template" and "templateFile" specified. Use one or the other.`);let a;if(i&&e.templateFile.endsWith(`.hbs`))a=ee(e.templateFile,t);else if(i){let n=e.templateFile,r=l.default.isAbsolute(n)?n:l.default.join(u.default.cwd(),n);if(!c.default.existsSync(r))throw Error(`Template file not found: ${n}`);a=b(c.default.readFileSync(r,`utf-8`),t)}else a=b(e.template,t);await X(n,a)}async function Se(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping regex-replace task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{pattern:r}=e,i=e.flags??``,a=e.replacement||``,o=await Y(n,`utf-8`),s=new RegExp(r,i);o=o.replace(s,b(a,t)),await X(n,o)}async function Ce(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping replace-in-file task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{replacements:r}=e;if(!c.default.existsSync(n)){y(`File not found: ${n}, skipping`,`warn`);return}let i=await Y(n,`utf-8`);for(let{find:e,replace:n}of r){let r=b(n,t);i=i.replace(new RegExp(e,`gu`),r)}await X(n,i)}async function we(e,t){let{paths:n,condition:r}=e;if(r!=null&&r!==``){if(!t){y(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!S(r,t)){y(`Condition not met, skipping deletion`,`info`);return}}for(let e of n){let t=l.default.join(u.default.cwd(),e);c.default.existsSync(t)&&c.default.rmSync(t,{recursive:!0,force:!0})}}async function Te(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping rename task`,`info`);return}let n=l.default.join(u.default.cwd(),b(e.from,t)),r=l.default.join(u.default.cwd(),b(e.to,t));if(!c.default.existsSync(n)){y(`Source path does not exist: ${n}`,`warn`);return}await ve(n,r)}async function Ee(e,t){if(e.condition!=null&&e.condition!==``){if(!t){y(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!S(e.condition,t)){y(`Condition not met, skipping git-init task`,`info`);return}}if(e.removeExisting){let e=l.default.join(u.default.cwd(),`.git`);c.default.existsSync(e)&&c.default.rmSync(e,{recursive:!0,force:!0})}if((0,d.execSync)(`git init`,{stdio:`inherit`}),e.initialCommit){let t=e.message??`Initial commit`;(0,d.execSync)(`git add .`,{stdio:`inherit`}),(0,d.execSync)(`git commit -m "${t}"`,{stdio:`inherit`})}}async function De(e,t){if(e.condition!=null&&e.condition!==``){if(!t){y(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!S(e.condition,t)){y(`Condition not met, skipping exec task`,`info`);return}}let n=e.cwd==null?u.default.cwd():l.default.join(u.default.cwd(),e.cwd);(0,d.execSync)(e.command,{cwd:n,stdio:`inherit`})}async function Oe(e,t,n=!1){if(n){y(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(z(e.type)){await V(e,t,{dryRun:n});return}switch(e.type){case`update-json`:await be(e.config,t);break;case`template`:await xe(e.config,t);break;case`regex-replace`:await Se(e.config,t);break;case`replace-in-file`:await Ce(e.config,t);break;case`delete`:await we(e.config,t);break;case`rename`:await Te(e.config,t);break;case`git-init`:await Ee(e.config,t);break;case`exec`:await De(e.config,t);break;default:{let t=e.type;throw TypeError(`Unknown task type: ${t}`)}}}async function ke(e,t,n,r,i=!1){try{return y(`[${n}/${r}] Running: ${e.name}...`,`info`),await Oe(e,t,i),y(`✓ ${e.name}`,`success`),!0}catch(t){return y(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(y(` Reason: ${t.message}`,`error`),t.stack!=null&&u.default.env.DEBUG!=null&&console.error(t.stack)),e.required&&y(` This is a required task. Initialization cannot continue.`,`error`),!1}}function Ae(e){let t=[],n=new Set,r=new Set,i=new Map(e.map(e=>[e.id,e]));function a(e){if(n.has(e))return;if(r.has(e))throw Error(`Circular dependency detected involving task: ${e}`);r.add(e);let o=i.get(e);if(!o)throw Error(`Task not found: ${e}`);if(o.dependencies)for(let e of o.dependencies)a(e);r.delete(e),n.add(e),t.push(o)}for(let t of e)n.has(t.id)||a(t.id);return t}const je=(0,f.promisify)(c.default.readFile);async function Me(e,t){let n=q();n&&!t.force&&(console.log(``),y(`⚠️ This template has already been initialized!`,`warn`),console.log(``),y(` Initialized at: ${new Date(n.initializedAt).toLocaleString()}`,`info`),y(` Repo: ${n.config.repoName}`,`info`),console.log(``),await v(`Do you want to re-initialize? This may cause issues`,!1)||(y(`Initialization cancelled`,`info`),u.default.exit(0)),console.log(``),y(`⚠️ Proceeding with re-initialization...`,`warn`),console.log(``));let r=e.filter(e=>e.enabled);y(`Resolving task dependencies...`,`info`);let i=Ae(r);console.log(``);let a=await w(t.dryRun),o=C(a);o.length>0&&(y(`❌ Configuration errors:`,`error`),o.forEach(e=>y(` - ${e}`,`error`)),console.log(``),u.default.exit(1));let s=[],f=[],p=[];for(let e of i)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)t.global?s.some(e=>e.id===t.id)||(s.push(t),p.push(t)):(f.push(t),p.push(t));if(p.length>0){let e=G(p);e.length>0&&(y(`❌ Prompt validation errors:`,`error`),e.forEach(e=>y(` - ${e}`,`error`)),console.log(``),u.default.exit(1)),y(`Resolving prompt default values...`,`info`);let t=await W(p);console.log(``);let n={};if(s.length>0&&(console.log(``),y(`📋 Global prompts (available to all tasks):`,`info`),console.log(``),n=await H(s,t),Object.assign(a,n)),f.length>0){s.length>0&&(y(`📋 Task-specific prompts:`,`info`),console.log(``));let e=await H(f,t);Object.assign(a,e)}}if(t.dryRun){await ce(i,a),y(`🔍 Dry run completed - no changes were made`,`info`),y(`Run without --dry-run to apply changes`,`info`);return}console.log(``),y(`Starting initialization tasks...`,`info`),console.log(``),await B(`beforeAll`,a);let m=i.length,h=0,g=0,_=[];for(let e=0;e<i.length;e++){let n=i[e];if(n!=null){if(await B(`beforeTask`,n,a),await ke(n,a,e+1,m,t.dryRun))h++,_.push(n.id),await B(`afterTask`,n,a);else if(n.required){g++,await B(`onError`,Error(`Task ${n.name} failed`),n);break}else y(`⚠️ Non-critical task failed, continuing...`,`warn`),await B(`onError`,Error(`Task ${n.name} failed`),n);console.log(``)}}if(g>0&&(y(`❌ Initialization failed with ${g} critical error(s)`,`error`),y(`✓ Completed: ${h}/${m} tasks`,`info`),u.default.exit(1)),await B(`afterAll`,a),J(a,_,t.dryRun),y(`✅ Initialization completed successfully!`,`success`),console.log(``),y(`✓ Completed: ${h}/${m} tasks`,`success`),console.log(``),!t.dryRun&&t.tasksFilePath!=null&&c.default.existsSync(t.tasksFilePath))try{c.default.unlinkSync(t.tasksFilePath),y(`🗑️ Removed tasks file: ${l.default.basename(t.tasksFilePath)}`,`info`),console.log(``)}catch(e){y(`⚠️ Failed to remove tasks file: ${e instanceof Error?e.message:`Unknown error`}`,`warn`)}if(!t.dryRun){y(`Next steps:`,`info`),y(`1. Review the changes made to your project`,`info`),y(`2. Commit the changes to git`,`info`);let e=l.default.join(u.default.cwd(),`package.json`);c.default.existsSync(e)&&JSON.parse(await je(e,`utf-8`)).scripts?.[`turbo:gen:init`]!=null&&(y(`3. Run "pnpm run turbo:gen:init" to create your first package`,`info`),console.log(``),await v(`Would you like to run turbo:gen:init now?`,!0)&&(console.log(``),y(`Running turbo:gen:init...`,`info`),(0,d.execSync)(`pnpm run turbo:gen:init`,{stdio:`inherit`})))}console.log(``)}const Ne=(0,f.promisify)(c.default.readFile),Z=new Map;async function Pe(e,t=new Set){let n=l.default.isAbsolute(e)?e:l.default.resolve(u.default.cwd(),e);if(Z.has(n))return Z.get(n);if(t.has(n))throw Error(`Circular dependency detected: ${Array.from(t).join(` -> `)} -> ${n}`);if(!c.default.existsSync(n))throw Error(`Template file not found: ${n}`);t.add(n);let r=await Ne(n,`utf-8`),i;try{i=JSON.parse(r)}catch(e){throw Error(`Failed to parse template file ${n}: ${e instanceof Error?e.message:String(e)}`)}if(!Array.isArray(i.tasks))throw TypeError(`Invalid template file ${n}: 'tasks' array is required`);return Z.set(n,i),i}async function Q(e,t,n=new Set){let r=l.default.isAbsolute(e)?e:l.default.resolve(t??u.default.cwd(),e);if(n.has(r))throw Error(`Circular dependency detected: ${Array.from(n).join(` -> `)} -> ${r}`);n.add(r);let i=await Pe(r);if(i.extends==null||i.extends===``)return i;let a=l.default.dirname(r),o=Array.isArray(i.extends)?i.extends:[i.extends],s=[];for(let e of o){let t=await Q(e,a,n);s.push(t)}return Fe([...s,i])}function Fe(e){if(e.length===0)return{tasks:[]};if(e.length===1)return e[0];let t=new Map;for(let n of e)for(let e of n.tasks)if(t.has(e.id)){let n=t.get(e.id);t.set(e.id,Ie(n,e))}else t.set(e.id,{...e});return{tasks:Array.from(t.values())}}function Ie(e,t){let n=typeof e.config==`object`&&e.config!==null&&typeof t.config==`object`&&t.config!==null?{...e.config,...t.config}:t.config,r=e.prompts?[...e.prompts]:void 0;if(t.prompts&&t.prompts.length>0)if(!r)r=[...t.prompts];else{let e=new Map(r.map(e=>[e.id,e]));for(let n of t.prompts)e.set(n.id,n);r=Array.from(e.values())}let i=[...e.dependencies??[],...t.dependencies??[]],a=i.length>0?[...new Set(i)]:void 0;return{...e,...t,config:n,...r!=null&&{prompts:r},...a!=null&&{dependencies:a}}}function Le(){Z.clear()}async function Re(e){y(`Loading tasks from ${e}...`,`info`);let t=await Q(e);return y(`Loaded ${t.tasks.length} task(s)`,`info`),t.extends!=null&&t.extends!==``&&y(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.tasks}const $=u.default.argv.includes(`--dry-run`),ze=u.default.argv.includes(`--force`);async function Be(e){try{let t=e||[];t.length===0&&(y(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),console.log(``),y(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),console.log(``),u.default.exit(1)),await Me(t,{dryRun:$,force:ze,tasksFilePath:void 0})}catch(e){y(`❌ Initialization failed`,`error`),e instanceof Error?(y(`Error: ${e.message}`,`error`),u.default.env.DEBUG!=null&&console.error(e.stack)):console.error(e),u.default.exit(1)}}async function Ve(e,t){try{await Me(e,{dryRun:t?.dryRun??$,force:t?.force??ze,tasksFilePath:t?.tasksFilePath??void 0})}catch(e){y(`❌ Initialization failed`,`error`),e instanceof Error?(y(`Error: ${e.message}`,`error`),u.default.env.DEBUG!=null&&console.error(e.stack)):console.error(e),u.default.exit(1)}}Object.defineProperty(exports,`A`,{enumerable:!0,get:function(){return ce}}),Object.defineProperty(exports,`B`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`C`,{enumerable:!0,get:function(){return he}}),Object.defineProperty(exports,`D`,{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,`E`,{enumerable:!0,get:function(){return me}}),Object.defineProperty(exports,`F`,{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,`G`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`H`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`I`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`J`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`K`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`L`,{enumerable:!0,get:function(){return se}}),Object.defineProperty(exports,`M`,{enumerable:!0,get:function(){return oe}}),Object.defineProperty(exports,`N`,{enumerable:!0,get:function(){return ae}}),Object.defineProperty(exports,`O`,{enumerable:!0,get:function(){return ue}}),Object.defineProperty(exports,`P`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`R`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`T`,{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,`U`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`V`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`W`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`Y`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return Re}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return Ae}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,`j`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`k`,{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return Oe}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return Ve}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,`q`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return Le}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return Fe}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Be}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return ke}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return pe}}),Object.defineProperty(exports,`w`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,`z`,{enumerable:!0,get:function(){return k}});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pixpilot/scaffoldfy",
3
3
  "type": "module",
4
- "version": "0.4.0",
4
+ "version": "0.5.1",
5
5
  "author": "PixPilot <m.doaie@hotmail.com>",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -46,11 +46,11 @@
46
46
  "eslint": "^9.38.0",
47
47
  "tsdown": "^0.15.8",
48
48
  "typescript": "^5.9.3",
49
- "@internal/tsconfig": "0.1.0",
50
- "@internal/vitest-config": "0.1.0",
51
- "@internal/prettier-config": "0.0.1",
52
49
  "@internal/eslint-config": "0.3.0",
53
- "@internal/tsdown-config": "0.1.0"
50
+ "@internal/tsdown-config": "0.1.0",
51
+ "@internal/vitest-config": "0.1.0",
52
+ "@internal/tsconfig": "0.1.0",
53
+ "@internal/prettier-config": "0.0.1"
54
54
  },
55
55
  "prettier": "@internal/prettier-config",
56
56
  "scripts": {