@pixpilot/scaffoldfy 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- const e=require(`./src-BcQJMu0M.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(`Automate project setup and configuration with customizable tasks`).version(c),o.option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force execution even if checks fail`).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,s,c;if(i.tasksTs!=null&&i.tasksTs!==``){let o=n.default.resolve(r.default.cwd(),i.tasksTs);if(t.default.existsSync(o)){e.G(`Loading tasks from TypeScript file: ${i.tasksTs}`,`info`),c=o;try{let t=await import(o);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 l=n.default.resolve(r.default.cwd(),i.tasksFile);if(t.default.existsSync(l)){c=l;try{let t=await e.f(l);a=t.tasks,o=t.variables,s=t.prompts,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`)}let l=s!=null&&s.length>0||o!=null&&o.length>0;a.length===0&&!l&&(e.G(`❌ No tasks defined`,`error`),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`),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)),r.default.exit(1)),a.length===0?e.G(`Loaded template with 0 tasks (template may only provide prompts/variables for extending)`,`info`):e.G(`Loaded ${a.length} task(s)`,`success`),await e.n(a,{dryRun:i.dryRun,force:i.force,tasksFilePath:c,globalVariables:o,globalPrompts:s})}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-H4TTRLK0.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(`Automate project setup and configuration with customizable tasks`).version(c),o.option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force execution even if checks fail`).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,s,c;if(i.tasksTs!=null&&i.tasksTs!==``){let o=n.default.resolve(r.default.cwd(),i.tasksTs);if(t.default.existsSync(o)){e.G(`Loading tasks from TypeScript file: ${i.tasksTs}`,`info`),c=o;try{let t=await import(o);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 l=n.default.resolve(r.default.cwd(),i.tasksFile);if(t.default.existsSync(l)){c=l;try{let t=await e.f(l);a=t.tasks,o=t.variables,s=t.prompts,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`)}let l=s!=null&&s.length>0||o!=null&&o.length>0;a.length===0&&!l&&(e.G(`❌ No tasks defined`,`error`),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`),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)),r.default.exit(1)),a.length===0?e.G(`Loaded template with 0 tasks (template may only provide prompts/variables for extending)`,`info`):e.G(`Loaded ${a.length} task(s)`,`success`),await e.n(a,{dryRun:i.dryRun,force:i.force,tasksFilePath:c,globalVariables:o,globalPrompts:s})}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,f as t,n}from"./src-gsac5lFQ.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(`Automate project setup and configuration with customizable tasks`).version(f),u.option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force execution even if checks fail`).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,l,u;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`),u=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)){u=n;try{let r=await t(n);s=r.tasks,c=r.variables,l=r.prompts,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`)}let d=l!=null&&l.length>0||c!=null&&c.length>0;s.length===0&&!d&&(e(`❌ No tasks defined`,`error`),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`),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)),o.exit(1)),s.length===0?e(`Loaded template with 0 tasks (template may only provide prompts/variables for extending)`,`info`):e(`Loaded ${s.length} task(s)`,`success`),await n(s,{dryRun:i.dryRun,force:i.force,tasksFilePath:u,globalVariables:c,globalPrompts:l})}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,f as t,n}from"./src-Zwjd02yN.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(`Automate project setup and configuration with customizable tasks`).version(f),u.option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force execution even if checks fail`).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,l,u;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`),u=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)){u=n;try{let r=await t(n);s=r.tasks,c=r.variables,l=r.prompts,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`)}let d=l!=null&&l.length>0||c!=null&&c.length>0;s.length===0&&!d&&(e(`❌ No tasks defined`,`error`),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`),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)),o.exit(1)),s.length===0?e(`Loaded template with 0 tasks (template may only provide prompts/variables for extending)`,`info`):e(`Loaded ${s.length} task(s)`,`success`),await n(s,{dryRun:i.dryRun,force:i.force,tasksFilePath:u,globalVariables:c,globalPrompts:l})}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-BcQJMu0M.cjs`);exports.callHook=e.y,exports.clearPlugins=e.b,exports.clearTemplateCache=e.u,exports.collectPrompts=e.v,exports.collectVariables=e.o,exports.createPlugin=e.x,exports.displayTasksDiff=e.M,exports.evaluateCondition=e.H,exports.executePluginTask=e.S,exports.executeTask=e.c,exports.getDeleteDiff=e.N,exports.getExecDiff=e.P,exports.getGitInitDiff=e.F,exports.getGitRepoInfo=e.U,exports.getPlugin=e.C,exports.getPluginForTaskType=e.w,exports.getPluginTaskDiff=e.T,exports.getRegexReplaceDiff=e.I,exports.getRenameDiff=e.L,exports.getReplaceInFileDiff=e.R,exports.getTaskDiff=e.z,exports.getTemplateDiff=e.B,exports.getUpdateJsonDiff=e.V,exports.interpolateTemplate=e.W,exports.isPluginTaskType=e.E,exports.listPlugins=e.D,exports.loadAndMergeTemplate=e.d,exports.loadTasksWithInheritance=e.f,exports.loadTemplate=e.p,exports.log=e.G,exports.main=e.t,exports.mergeTemplates=e.m,exports.prompt=e.K,exports.promptYesNo=e.q,exports.registerHooks=e.O,exports.registerPlugin=e.k,exports.resolveAllDefaultValues=e.g,exports.resolveAllVariableValues=e.i,exports.resolveDefaultValue=e._,exports.resolveVariableValue=e.a,exports.runTask=e.l,exports.runWithTasks=e.n,exports.setNestedProperty=e.J,exports.topologicalSort=e.s,exports.unregisterPlugin=e.A,exports.validatePluginTask=e.j,exports.validatePrompts=e.h,exports.validateVariables=e.r;
1
+ const e=require(`./src-H4TTRLK0.cjs`);exports.callHook=e.y,exports.clearPlugins=e.b,exports.clearTemplateCache=e.u,exports.collectPrompts=e.v,exports.collectVariables=e.o,exports.createPlugin=e.x,exports.displayTasksDiff=e.M,exports.evaluateCondition=e.H,exports.executePluginTask=e.S,exports.executeTask=e.c,exports.getDeleteDiff=e.N,exports.getExecDiff=e.P,exports.getGitInitDiff=e.F,exports.getGitRepoInfo=e.U,exports.getPlugin=e.C,exports.getPluginForTaskType=e.w,exports.getPluginTaskDiff=e.T,exports.getRegexReplaceDiff=e.I,exports.getRenameDiff=e.L,exports.getReplaceInFileDiff=e.R,exports.getTaskDiff=e.z,exports.getTemplateDiff=e.B,exports.getUpdateJsonDiff=e.V,exports.interpolateTemplate=e.W,exports.isPluginTaskType=e.E,exports.listPlugins=e.D,exports.loadAndMergeTemplate=e.d,exports.loadTasksWithInheritance=e.f,exports.loadTemplate=e.p,exports.log=e.G,exports.main=e.t,exports.mergeTemplates=e.m,exports.prompt=e.K,exports.promptYesNo=e.q,exports.registerHooks=e.O,exports.registerPlugin=e.k,exports.resolveAllDefaultValues=e.g,exports.resolveAllVariableValues=e.i,exports.resolveDefaultValue=e._,exports.resolveVariableValue=e.a,exports.runTask=e.l,exports.runWithTasks=e.n,exports.setNestedProperty=e.J,exports.topologicalSort=e.s,exports.unregisterPlugin=e.A,exports.validatePluginTask=e.j,exports.validatePrompts=e.h,exports.validateVariables=e.r;
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-gsac5lFQ.js";export{K as callHook,w as clearPlugins,H as clearTemplateCache,U as collectPrompts,I as collectVariables,G as createPlugin,f as displayTasksDiff,s as evaluateCondition,_ as executePluginTask,T as executeTask,p as getDeleteDiff,h as getExecDiff,a as getGitInitDiff,y as getGitRepoInfo,n as getPlugin,W as getPluginForTaskType,v as getPluginTaskDiff,c as getRegexReplaceDiff,d as getRenameDiff,g as getReplaceInFileDiff,q as getTaskDiff,t as getTemplateDiff,b as getUpdateJsonDiff,x as interpolateTemplate,i as isPluginTaskType,r as listPlugins,E as loadAndMergeTemplate,D as loadTasksWithInheritance,L as loadTemplate,o as log,V as main,P as mergeTemplates,u as prompt,R as promptYesNo,m as registerHooks,M as registerPlugin,O as resolveAllDefaultValues,A as resolveAllVariableValues,S as resolveDefaultValue,C as resolveVariableValue,N as runTask,F as runWithTasks,l as setNestedProperty,B as topologicalSort,e as unregisterPlugin,j as validatePluginTask,k as validatePrompts,z as validateVariables};
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-Zwjd02yN.js";export{K as callHook,w as clearPlugins,H as clearTemplateCache,U as collectPrompts,I as collectVariables,G as createPlugin,f as displayTasksDiff,s as evaluateCondition,_ as executePluginTask,T as executeTask,p as getDeleteDiff,h as getExecDiff,a as getGitInitDiff,y as getGitRepoInfo,n as getPlugin,W as getPluginForTaskType,v as getPluginTaskDiff,c as getRegexReplaceDiff,d as getRenameDiff,g as getReplaceInFileDiff,q as getTaskDiff,t as getTemplateDiff,b as getUpdateJsonDiff,x as interpolateTemplate,i as isPluginTaskType,r as listPlugins,E as loadAndMergeTemplate,D as loadTasksWithInheritance,L as loadTemplate,o as log,V as main,P as mergeTemplates,u as prompt,R as promptYesNo,m as registerHooks,M as registerPlugin,O as resolveAllDefaultValues,A as resolveAllVariableValues,S as resolveDefaultValue,C as resolveVariableValue,N as runTask,F as runWithTasks,l as setNestedProperty,B as topologicalSort,e as unregisterPlugin,j as validatePluginTask,k as validatePrompts,z as validateVariables};
@@ -0,0 +1,17 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`node:fs`);c=s(c);let l=require(`node:path`);l=s(l);let u=require(`node:process`);u=s(u);let d=require(`node:util`);d=s(d);let f=require(`node:child_process`);f=s(f);let p=require(`node:readline`);p=s(p);let m=require(`handlebars`);m=s(m);let h=require(`@inquirer/prompts`);h=s(h);function g(){return{}}function _(e,t){return e===void 0?!0:typeof e==`boolean`?e:typeof e==`object`&&`condition`in e?C(e.condition,t):!1}function v(){try{let e=(0,f.execSync)(`git remote get-url origin`,{encoding:`utf-8`}).trim(),t=e.match(/github\.com[:/](?<owner>[^/]+)\/(?<name>[^/]+)$/u);if(t?.groups){let{owner:n,name:r}=t.groups,i=r;return i.endsWith(`.git`)&&(i=i.slice(0,-4)),{owner:n,name:i,url:e}}return null}catch{return null}}async function y(e,t){let n=p.default.createInterface({input:u.default.stdin,output:u.default.stdout});return new Promise(r=>{let i;i=t==null?`${e}: `:`${e} (${t}): `,n.question(i,e=>{n.close(),r(e.trim()||(t??``))})})}async function ee(e,t=!1){return y(`${e} (${t?`Y/n`:`y/N`})`,t?`y`:`n`).then(e=>e.toLowerCase()===`y`||e.toLowerCase()===`yes`)}function b(e,t=`info`){console.log(`${{info:`\x1B[36m`,success:`\x1B[32m`,error:`\x1B[31m`,warn:`\x1B[33m`}[t]}${{info:`ℹ`,success:`✓`,error:`✗`,warn:`⚠`}[t]} ${e}`)}function x(e,t){return e.replace(/\{\{(?<key>\w+)\}\}/gu,(e,n)=>t[n]?.toString()??``)}function S(e,t,n){let r=t.split(`.`),i=e;for(let e=0;e<r.length-1;e++){let t=r[e];t!=null&&t!==``&&((!(t in i)||typeof i[t]!=`object`||i[t]===null)&&(i[t]={}),i=i[t])}let a=r[r.length-1];a!=null&&a!==``&&(i[a]=n)}function C(e,t){try{let n={...t};return Function(...Object.keys(n),`'use strict'; return (${e})`)(...Object.values(n))}catch(t){return b(`Failed to evaluate condition: ${e}`,`warn`),t instanceof Error&&b(` Error: ${t.message}`,`warn`),!1}}function te(e,t){try{let n=l.default.isAbsolute(e)?e:l.default.join(u.default.cwd(),e);if(!c.default.existsSync(n))throw Error(`Template file not found: ${e}`);return ne(c.default.readFileSync(n,`utf-8`),t)}catch(t){throw b(`Failed to read template file: ${e}`,`error`),t instanceof Error&&b(` Error: ${t.message}`,`error`),t}}function ne(e,t){try{return m.default.compile(e)(t)}catch(e){throw b(`Failed to compile Handlebars template`,`error`),e instanceof Error&&b(` Error: ${e.message}`,`error`),e}}const w=(0,d.promisify)(c.default.readFile),re=2,ie=10,ae=55,T={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,cyan:`\x1B[36m`,gray:`\x1B[90m`};function E(e,t){switch(t){case`add`:return`${T.green}+ ${e}${T.reset}`;case`remove`:return`${T.red}- ${e}${T.reset}`;case`context`:return`${T.gray} ${e}${T.reset}`;default:return e}}function D(e,t){let n=e.split(`
2
+ `),r=t.split(`
3
+ `),i=[],a=Math.max(n.length,r.length);for(let e=0;e<a;e++){let t=n[e],a=r[e];t===a?t!==void 0&&i.push(E(t,`context`)):(t!==void 0&&i.push(E(t,`remove`)),a!==void 0&&i.push(E(a,`add`)))}return i}async function oe(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t))return`${T.yellow}⊘ Condition not met - task would be skipped${T.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${T.red}✗ File not found: ${e.file}${T.reset}`;try{let r=await w(n,`utf-8`),i=JSON.parse(r),a={...i};function o(e){if(typeof e==`string`)return x(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[t,n]of Object.entries(e.updates)){let e=o(n);t.includes(`.`)?S(i,t,e):i[t]=e}let s=JSON.stringify(a,null,2),c=JSON.stringify(i,null,2);if(s===c)return`${T.cyan}→ No changes${T.reset}`;let l=D(s,c);return`${T.blue}File: ${e.file}${T.reset}\n${l.join(`
4
+ `)}`}catch(e){return`${T.red}✗ Error: ${e instanceof Error?e.message:String(e)}${T.reset}`}}async function se(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t))return`${T.yellow}⊘ Condition not met - task would be skipped${T.reset}`;if(e.template==null||e.template===``)return`${T.red}✗ No template content provided for file: ${e.file}${T.reset}`;let n=l.default.join(u.default.cwd(),e.file),r=x(e.template,t);if(!c.default.existsSync(n)){let t=r.split(`
5
+ `).slice(0,10).join(`
6
+ `),n=r.split(`
7
+ `).length>10;return`${T.blue}File: ${e.file}${T.reset}\n${T.green}+ New file would be created${T.reset}\n${T.gray}Content preview:${T.reset}\n${t}${n?`
8
+ ...`:``}`}try{let t=await w(n,`utf-8`);if(t===r)return`${T.cyan}→ No changes${T.reset}`;let i=D(t,r);return`${T.blue}File: ${e.file}${T.reset}\n${i.join(`
9
+ `)}`}catch(e){return`${T.red}✗ Error: ${e instanceof Error?e.message:String(e)}${T.reset}`}}async function ce(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t))return`${T.yellow}⊘ Condition not met - task would be skipped${T.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(c.default.existsSync(n))return`${T.cyan}→ File already exists, would be skipped: ${e.file}${T.reset}`;let r=e.template!=null&&e.template!==``,i=e.templateFile!=null&&e.templateFile!==``;if(!r&&!i)return`${T.red}✗ No template content provided for file: ${e.file}${T.reset}`;try{let n;if(r)n=x(e.template,t);else return`${T.blue}File: ${e.file}${T.reset}\n${T.green}+ New file would be created from template: ${e.templateFile}${T.reset}`;let i=n.split(`
10
+ `).slice(0,10).join(`
11
+ `),a=n.split(`
12
+ `).length>10;return`${T.blue}File: ${e.file}${T.reset}\n${T.green}+ New file would be created${T.reset}\n${T.gray}Content preview:${T.reset}\n${i}${a?`
13
+ ...`:``}`}catch(e){return`${T.red}✗ Error: ${e instanceof Error?e.message:String(e)}${T.reset}`}}async function O(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t))return`${T.yellow}⊘ Condition not met - task would be skipped${T.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${T.red}✗ File not found: ${e.file}${T.reset}`;try{let r=await w(n,`utf-8`),i=new RegExp(e.pattern,e.flags??`g`),a=x(e.replacement,t),o=r.replace(i,a);if(r===o)return`${T.cyan}→ No matches found${T.reset}`;let s=D(r,o);return`${T.blue}File: ${e.file}${T.reset}\n${s.join(`
14
+ `)}`}catch(e){return`${T.red}✗ Error: ${e instanceof Error?e.message:String(e)}${T.reset}`}}async function k(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t))return`${T.yellow}⊘ Condition not met - task would be skipped${T.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${T.red}✗ File not found: ${e.file}${T.reset}`;try{let r=await w(n,`utf-8`),i=r;for(let{find:n,replace:i}of e.replacements){let e=x(n,t),a=x(i,t);r=r.replace(e,a)}if(i===r)return`${T.cyan}→ No changes${T.reset}`;let a=D(i,r);return`${T.blue}File: ${e.file}${T.reset}\n${a.join(`
15
+ `)}`}catch(e){return`${T.red}✗ Error: ${e instanceof Error?e.message:String(e)}${T.reset}`}}function A(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t))return`${T.yellow}⊘ Condition not met - task would be skipped${T.reset}`;let n=e.paths.map(e=>x(e,t)).filter(e=>c.default.existsSync(l.default.join(u.default.cwd(),e)));return n.length===0?`${T.cyan}→ No files/directories to delete${T.reset}`:`${T.red}Would delete:${T.reset}\n${n.map(e=>`${T.red} - ${e}${T.reset}`).join(`
16
+ `)}`}function le(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t))return`${T.yellow}⊘ Condition not met - task would be skipped${T.reset}`;let n=x(e.from,t),r=x(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)?`${T.yellow}⚠ Destination already exists: ${r}${T.reset}\n${T.cyan}Would rename: ${n} → ${r}${T.reset}`:`${T.cyan}Would rename: ${n} → ${r}${T.reset}`:`${T.red}✗ Source not found: ${n}${T.reset}`}function j(e){if(e.condition!=null&&e.condition!==``)return`${T.yellow}⊘ Condition check skipped in dry-run${T.reset}`;let t=l.default.join(u.default.cwd(),`.git`),n=c.default.existsSync(t),r=[];if(e.removeExisting&&n&&r.push(`${T.red}Would remove existing .git directory${T.reset}`),r.push(`${T.green}Would initialize git repository${T.reset}`),e.initialCommit){let t=e.message??`Initial commit`;r.push(`${T.green}Would create initial commit: "${t}"${T.reset}`)}return r.join(`
17
+ `)}function M(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t))return`${T.yellow}⊘ Condition not met - task would be skipped${T.reset}`;let n=x(e.command,t),r=e.cwd==null?u.default.cwd():x(e.cwd,t);return`${T.yellow}Would execute:${T.reset}\n${T.cyan} Command: ${n}${T.reset}\n${T.cyan} Working directory: ${r}${T.reset}`}async function N(e,t){try{switch(e.type){case`update-json`:return await oe(e.config,t);case`template`:return await se(e.config,t);case`create`:return await ce(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 le(e.config,t);case`git-init`:return j(e.config);case`exec`:return M(e.config,t);default:{let t=e.type;return`${T.yellow}⚠ Diff not available for task type: ${t}${T.reset}`}}}catch(e){return`${T.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${T.reset}`}}async function P(e,t){console.log(`${T.blue}═══════════════════════════════════════════════════════${T.reset}`),console.log(`${T.blue} DRY RUN - Preview of changes${T.reset}`),console.log(`${T.blue}═══════════════════════════════════════════════════════${T.reset}`);for(let n of e){console.log(`${T.cyan}▶ Task: ${n.name}${T.reset}`),console.log(`${T.gray} ${n.description}${T.reset}`);let e=await N(n,t);console.log(e),console.log(`${T.gray}${`─`.repeat(55)}${T.reset}`)}console.log(`${T.blue}═══════════════════════════════════════════════════════${T.reset}`),console.log(`${T.yellow} No changes were applied (dry-run mode)${T.reset}`),console.log(`${T.blue}═══════════════════════════════════════════════════════${T.reset}`)}const F=new Map,I={},L=new Map;function R(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);b(`✓ 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 z(e){let t=L.get(e);if(t!=null)return F.get(t)}function B(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 V(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){b(`Error in ${e} hook: ${t instanceof Error?t.message:String(t)}`,`error`)}}async function H(e,t,n){let r=z(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=z(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function ge(e){let t=z(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 U(e,t=new Map,n={}){let r={};if(e.length===0)return r;for(let i of e){let e={...n,...r};if(_(i.enabled,e))try{let e,n=t.get(i.id);switch(i.type){case`input`:{let t={message:i.message};if(n!==void 0&&(t.default=String(n)),i.required!==void 0&&(t.required=i.required),e=await(0,h.input)(t),i.required&&(e==null||typeof e==`string`&&e.trim()===``))throw b(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break}case`password`:if(e=await(0,h.password)({message:i.message,mask:`*`}),i.required&&(e==null||typeof e==`string`&&e.trim()===``))throw b(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break;case`number`:{let t={message:i.message};if(n!==void 0&&(t.default=Number(n)),i.required!==void 0&&(t.required=i.required),i.min!==void 0&&(t.min=i.min),i.max!==void 0&&(t.max=i.max),e=await(0,h.number)(t),i.required&&e==null)throw b(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break}case`select`:{let t={message:i.message,choices:i.choices.map(e=>({name:e.name,value:e.value}))};n!==void 0&&(t.default=n),e=await(0,h.select)(t);break}case`confirm`:{let t=n===void 0?!1:!!n;e=await(0,h.confirm)({message:i.message,default:t});break}default:throw b(`Unknown prompt type: ${i.type}`,`error`),Error(`Unknown prompt type: ${i.type}`)}r[i.id]=e}catch(e){throw e instanceof Error&&b(`Failed to collect prompt "${i.id}": ${e.message}`,`error`),e}}return r}async function W(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`exec`){let e=n.value;if(typeof e!=`string`){b(`Prompt "${t}": exec default value must have a string command`,`error`);return}try{let t=(0,f.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){b(`Prompt "${t}": failed to execute default value command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`static`)return n.value;return e}async function G(e){let t=new Map,n=e.map(async e=>{if(e.default!==void 0){let n=await W(e.default,e.id);n!==void 0&&t.set(e.id,n)}});return await Promise.all(n),t}function K(e){let t=[],n=new Set;for(let r of e){if(n.has(r.id)&&t.push(`Duplicate prompt ID: ${r.id}`),n.add(r.id),/^[\w-]+$/u.test(r.id)||t.push(`Invalid prompt ID "${r.id}": must contain only alphanumeric characters, underscores, and hyphens`),(!r.message||r.message.trim()===``)&&t.push(`Prompt "${r.id}" must have a non-empty message`),r.type===`select`){r.choices.length===0&&t.push(`Select prompt "${r.id}" must have at least one choice`);for(let e of r.choices)(!e.name||e.name.trim()===``)&&t.push(`Select prompt "${r.id}" has a choice with empty name`),e.value===void 0&&t.push(`Select prompt "${r.id}" has a choice with undefined value`)}r.type===`number`&&r.min!==void 0&&r.max!==void 0&&r.min>r.max&&t.push(`Number prompt "${r.id}" has min greater than max`)}return t}const ve=(0,d.promisify)(c.default.writeFile);async function ye(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t)){b(`Condition not met, skipping create task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file);if(c.default.existsSync(n)){b(`File already exists, skipping: ${e.file}`,`info`);return}let r=e.template!=null&&e.template!==``,i=e.templateFile!=null&&e.templateFile!==``;if(!r&&!i)throw Error(`Create task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(r&&i)throw Error(`Create task cannot have both "template" and "templateFile" specified. Use one or the other.`);let a;if(i&&e.templateFile.endsWith(`.hbs`))a=te(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=x(c.default.readFileSync(r,`utf-8`),t)}else a=x(e.template,t);let o=l.default.dirname(n);c.default.existsSync(o)||c.default.mkdirSync(o,{recursive:!0}),await ve(n,a),b(`Created file: ${e.file}`,`success`)}const be={name:`create`,version:`1.0.0`,taskTypes:[`create`],execute:async(e,t,n)=>{n.dryRun||await ye(e.config,t)}};async function xe(e,t){let{paths:n,condition:r}=e;if(r!=null&&r!==``){if(!t){b(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!C(r,t)){b(`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})}}const Se={name:`delete`,version:`1.0.0`,taskTypes:[`delete`],execute:async(e,t,n)=>{n.dryRun||await xe(e.config,t)}};async function Ce(e,t){if(e.condition!=null&&e.condition!==``){if(!t){b(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!C(e.condition,t)){b(`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,f.execSync)(e.command,{cwd:n,stdio:`inherit`})}const we={name:`exec`,version:`1.0.0`,taskTypes:[`exec`],execute:async(e,t,n)=>{n.dryRun||await Ce(e.config,t)}};async function Te(e,t){if(e.condition!=null&&e.condition!==``){if(!t){b(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!C(e.condition,t)){b(`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,f.execSync)(`git init`,{stdio:`inherit`}),e.initialCommit){let t=e.message??`Initial commit`;(0,f.execSync)(`git add .`,{stdio:`inherit`}),(0,f.execSync)(`git commit -m "${t}"`,{stdio:`inherit`})}}const Ee={name:`git-init`,version:`1.0.0`,taskTypes:[`git-init`],execute:async(e,t,n)=>{n.dryRun||await Te(e.config,t)}},De=(0,d.promisify)(c.default.readFile),Oe=(0,d.promisify)(c.default.writeFile);async function ke(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t)){b(`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 De(n,`utf-8`),s=new RegExp(r,i);o=o.replace(s,x(a,t)),await Oe(n,o)}const Ae={name:`regex-replace`,version:`1.0.0`,taskTypes:[`regex-replace`],execute:async(e,t,n)=>{n.dryRun||await ke(e.config,t)}},je=(0,d.promisify)(c.default.rename);async function Me(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t)){b(`Condition not met, skipping rename task`,`info`);return}let n=l.default.join(u.default.cwd(),x(e.from,t)),r=l.default.join(u.default.cwd(),x(e.to,t));if(!c.default.existsSync(n)){b(`Source path does not exist: ${n}`,`warn`);return}await je(n,r)}const Ne={name:`rename`,version:`1.0.0`,taskTypes:[`rename`],execute:async(e,t,n)=>{n.dryRun||await Me(e.config,t)}},Pe=(0,d.promisify)(c.default.readFile),Fe=(0,d.promisify)(c.default.writeFile);async function Ie(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t)){b(`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)){b(`File not found: ${n}, skipping`,`warn`);return}let i=await Pe(n,`utf-8`);for(let{find:e,replace:n}of r){let r=x(n,t);i=i.replace(new RegExp(e,`gu`),r)}await Fe(n,i)}const Le={name:`replace-in-file`,version:`1.0.0`,taskTypes:[`replace-in-file`],execute:async(e,t,n)=>{n.dryRun||await Ie(e.config,t)}},q=(0,d.promisify)(c.default.readFile);function J(e){try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}}function Y(e,t){if(J(e))return e;if(t==null||t===``)return l.default.isAbsolute(e)?e:l.default.resolve(u.default.cwd(),e);if(J(t))try{let n=new URL(`.`,t);return new URL(e,n).href}catch{throw Error(`Failed to resolve templateFile "${e}" relative to remote template "${t}"`)}let n=l.default.dirname(t);return l.default.isAbsolute(e)?e:l.default.resolve(n,e)}async function X(e){if(J(e))return Re(e);if(!c.default.existsSync(e))throw Error(`Template file not found: ${e}`);return q(e,`utf-8`)}async function Re(e){try{let t=await fetch(e);if(!t.ok)throw Error(`Failed to fetch template from ${e}: ${t.status} ${t.statusText}`);return await t.text()}catch(t){throw t instanceof Error&&t.message.includes(`Failed to fetch`)?t:Error(`Failed to fetch template from ${e}: ${t instanceof Error?t.message:String(t)}`)}}const Z=new Map;async function ze(e,t=new Set){let n=J(e),r;if(r=n||l.default.isAbsolute(e)?e:l.default.resolve(u.default.cwd(),e),Z.has(r))return Z.get(r);if(t.has(r))throw Error(`Circular dependency detected: ${Array.from(t).join(` -> `)} -> ${r}`);t.add(r);let i;if(n)i=await Re(r);else{if(!c.default.existsSync(r))throw Error(`Template file not found: ${r}`);i=await q(r,`utf-8`)}let a;try{a=JSON.parse(i)}catch(e){throw Error(`Failed to parse template file ${r}: ${e instanceof Error?e.message:String(e)}`)}if(a.tasks!==void 0&&!Array.isArray(a.tasks))throw TypeError(`Invalid template file ${r}: 'tasks' must be an array if provided`);a.tasks===void 0&&(a.tasks=[]);for(let e of a.tasks)e.$sourceUrl=r;return Z.set(r,a),a}async function Q(e,t,n=new Set){let r=J(e),i;if(i=r||l.default.isAbsolute(e)?e:t==null?l.default.resolve(u.default.cwd(),e):J(t)?new URL(e,t).href:l.default.resolve(t,e),n.has(i))throw Error(`Circular dependency detected: ${Array.from(n).join(` -> `)} -> ${i}`);n.add(i);let a=await ze(i);if(a.extends==null||a.extends===``)return a;let o=J(i)?new URL(`.`,i).href:l.default.dirname(i),s=Array.isArray(a.extends)?a.extends:[a.extends],c=[];for(let e of s){let t=await Q(e,o,n);c.push(t)}return Ve([...c,a])}function Be(e,t,n){let r=new Map;for(let t of e){if(r.has(t.id))throw Error(`Duplicate ID "${t.id}" found in task. This ID is already used in ${r.get(t.id)}`);r.set(t.id,`task`)}if(t!=null)for(let e of t){if(r.has(e.id))throw Error(`Duplicate ID "${e.id}" found in variable. This ID is already used in ${r.get(e.id)}`);r.set(e.id,`variable`)}if(n!=null)for(let e of n){if(r.has(e.id))throw Error(`Duplicate ID "${e.id}" found in prompt. This ID is already used in ${r.get(e.id)}`);r.set(e.id,`prompt`)}}function Ve(e){if(e.length===0)return{tasks:[]};if(e.length===1){let t=e[0];return Be(t.tasks??[],t.variables,t.prompts),t}let t=new Map,n=new Map,r=new Map;for(let i of e){if(i.prompts!=null)for(let e of i.prompts)r.set(e.id,{...e});if(i.variables!=null)for(let e of i.variables)n.set(e.id,{...e});for(let e of i.tasks??[])if(t.has(e.id)){let n=t.get(e.id);t.set(e.id,He(n,e))}else t.set(e.id,{...e})}let i=Array.from(t.values()),a=r.size>0?Array.from(r.values()):void 0,o=n.size>0?Array.from(n.values()):void 0;Be(i,o,a);let s={tasks:i};return a!=null&&(s.prompts=a),o!=null&&(s.variables=o),s}function He(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.variables?[...e.variables]:void 0;if(t.variables&&t.variables.length>0)if(!i)i=[...t.variables];else{let e=new Map(i.map(e=>[e.id,e]));for(let n of t.variables)e.set(n.id,n);i=Array.from(e.values())}let a=[...e.dependencies??[],...t.dependencies??[]],o=a.length>0?[...new Set(a)]:void 0,s=t.$sourceUrl??e.$sourceUrl;return{...e,...t,config:n,...r!=null&&{prompts:r},...i!=null&&{variables:i},...o!=null&&{dependencies:o},...s!=null&&{$sourceUrl:s}}}function Ue(){Z.clear()}async function We(e){b(`Loading tasks from ${e}...`,`info`);let t=await Q(e);b(`Loaded ${t.tasks?.length??0} task(s)`,`info`),t.extends!=null&&t.extends!==``&&b(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.prompts!=null&&t.prompts.length>0&&b(`Found ${t.prompts.length} top-level prompt(s)`,`info`),t.variables!=null&&t.variables.length>0&&b(`Found ${t.variables.length} top-level variable(s)`,`info`);let n={tasks:t.tasks??[]};return t.prompts!=null&&(n.prompts=t.prompts),t.variables!=null&&(n.variables=t.variables),n}const Ge=(0,d.promisify)(c.default.writeFile);async function Ke(e,t,n){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t)){b(`Condition not met, skipping template task`,`info`);return}let r=l.default.join(u.default.cwd(),e.file),i=e.template!=null&&e.template!==``,a=e.templateFile!=null&&e.templateFile!==``;if(!i&&!a)throw Error(`Template task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(i&&a)throw Error(`Template task cannot have both "template" and "templateFile" specified. Use one or the other.`);let o;if(a&&e.templateFile.endsWith(`.hbs`)){let r=await X(Y(e.templateFile,n?.$sourceUrl));o=(await import(`handlebars`)).default.compile(r)(t)}else o=x(a?await X(Y(e.templateFile,n?.$sourceUrl)):e.template,t);await Ge(r,o)}const qe={name:`template`,version:`1.0.0`,taskTypes:[`template`],execute:async(e,t,n)=>{n.dryRun||await Ke(e.config,t,e)}},Je=(0,d.promisify)(c.default.readFile),Ye=(0,d.promisify)(c.default.writeFile),Xe=2;async function Ze(e,t){if(e.condition!=null&&e.condition!==``&&!C(e.condition,t)){b(`Condition not met, skipping update-json task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{updates:r}=e,i=await Je(n,`utf-8`),a=JSON.parse(i);function o(e){if(typeof e==`string`)return x(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(`.`)?S(a,e,n):a[e]=n}await Ye(n,`${JSON.stringify(a,null,2)}\n`)}const Qe={name:`update-json`,version:`1.0.0`,taskTypes:[`update-json`],execute:async(e,t,n)=>{n.dryRun||await Ze(e.config,t)}};let $e=!1;function et(){$e||=(R(Qe),R(qe),R(be),R(Ae),R(Le),R(Se),R(Ne),R(Ee),R(we),!0)}async function tt(e,t,n=!1){if(et(),n){b(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(B(e.type)){await H(e,t,{dryRun:n});return}throw TypeError(`Unknown task type: ${e.type}`)}async function $(e,t,n,r,i=!1){try{return b(`[${n}/${r}] Running: ${e.name}...`,`info`),await tt(e,t,i),b(`✓ ${e.name}`,`success`),!0}catch(t){return b(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(b(` Reason: ${t.message}`,`error`),t.stack!=null&&u.default.env.DEBUG!=null&&console.error(t.stack)),e.required&&b(` This is a required task. Initialization cannot continue.`,`error`),!1}}function nt(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}function rt(e,t=new Map){let n={};for(let r of e){let e=t.get(r.id);e!==void 0&&(n[r.id]=e)}return n}async function it(e,t){if(e==null)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`exec`){let e=n.value;if(typeof e!=`string`){b(`Variable "${t}": exec value must have a string command`,`error`);return}try{let t=(0,f.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){b(`Variable "${t}": failed to execute command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`static`)return n.value;return e}async function at(e){let t=new Map,n=e.map(async e=>{let t=await it(e.value,e.id);return{id:e.id,value:t}}),r=await Promise.all(n);for(let e of r)e.value!==void 0&&t.set(e.id,e.value);return t}function ot(e){let t=[],n=new Set;for(let r of e)if(n.has(r.id)&&t.push(`Duplicate variable ID: "${r.id}"`),n.add(r.id),/^[\w$]+$/u.test(r.id)||t.push(`Variable ID "${r.id}" is invalid. Must contain only letters, numbers, underscore, or dollar sign.`),r.value===void 0||r.value===null)t.push(`Variable "${r.id}" must have a value`);else if(typeof r.value==`object`&&!Array.isArray(r.value)&&r.value!==null){let e=r.value;e.type==null||e.type===``?t.push(`Variable "${r.id}": value object must have a "type" field ("static" or "exec")`):e.type!==`static`&&e.type!==`exec`&&t.push(`Variable "${r.id}": type must be "static" or "exec", got "${e.type}"`),(e.value===void 0||e.value===null)&&t.push(`Variable "${r.id}": value config must have a "value" field`),e.type===`exec`&&typeof e.value!=`string`&&t.push(`Variable "${r.id}": exec type must have a string command as value`)}return t}async function st(e,t){let n=e.filter(e=>_(e.enabled,g()));b(`Resolving task dependencies...`,`info`);let r=nt(n);b(`Welcome! Let's execute your tasks.`,`info`),t.dryRun&&b(`🔍 DRY RUN MODE - No changes will be made`,`warn`),b(`This will execute your project tasks based on the defined configuration.`,`info`);let i=g(),a=t.globalVariables??[],o=[],s=[...a];for(let e of r)if(e.variables&&e.variables.length>0)for(let t of e.variables)o.push(t),s.push(t);if(s.length>0){let e=ot(s);e.length>0&&(b(`❌ Variable validation errors:`,`error`),e.forEach(e=>b(` - ${e}`,`error`)),u.default.exit(1)),b(`Resolving variable values...`,`info`);let t=rt(s,await at(s));Object.assign(i,t),Object.keys(t).length>0&&b(`✓ Resolved ${Object.keys(t).length} variable(s)`,`success`)}let c=t.globalPrompts??[],l=[],d=[...c];for(let e of r)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)l.push(t),d.push(t);if(d.length>0){let e=K(d);e.length>0&&(b(`❌ Prompt validation errors:`,`error`),e.forEach(e=>b(` - ${e}`,`error`)),u.default.exit(1)),b(`Resolving prompt default values...`,`info`);let t=await G(d),n={};if(c.length>0&&(b(`📋 Top-level prompts (available to all tasks):`,`info`),n=await U(c,t,i),Object.assign(i,n)),l.length>0){c.length>0&&b(`📋 Task-specific prompts:`,`info`);let e=await U(l,t,i);Object.assign(i,e)}}let f=r.filter(e=>_(e.enabled,i));if(b(`${f.length} of ${r.length} task(s) enabled for execution`,`info`),t.dryRun){await P(f,i),b(`🔍 Dry run completed - no changes were made`,`info`),b(`Run without --dry-run to apply changes`,`info`);return}b(`Starting task execution...`,`info`),await V(`beforeAll`,i);let p=f.length,m=0,h=0,v=[];for(let e=0;e<f.length;e++){let n=f[e];if(n!=null)if(await V(`beforeTask`,n,i),await $(n,i,e+1,p,t.dryRun))m++,v.push(n.id),await V(`afterTask`,n,i);else if(n.required){h++,await V(`onError`,Error(`Task ${n.name} failed`),n);break}else b(`⚠️ Non-critical task failed, continuing...`,`warn`),await V(`onError`,Error(`Task ${n.name} failed`),n)}h>0&&(b(`❌ Task execution failed with ${h} critical error(s)`,`error`),b(`✓ Completed: ${m}/${p} tasks`,`info`),u.default.exit(1)),await V(`afterAll`,i),b(`✅ All tasks completed successfully!`,`success`),b(`✓ Completed: ${m}/${p} tasks`,`success`),t.dryRun||(b(`Next steps:`,`info`),b(`1. Review the changes made to your project`,`info`),b(`2. Commit the changes to git`,`info`))}const ct=u.default.argv.includes(`--dry-run`),lt=u.default.argv.includes(`--force`);async function ut(e){try{let t=e||[];t.length===0&&(b(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),b(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),u.default.exit(1)),await st(t,{dryRun:ct,force:lt,tasksFilePath:void 0})}catch(e){b(`❌ Task execution failed`,`error`),e instanceof Error?(b(`Error: ${e.message}`,`error`),u.default.env.DEBUG!=null&&console.error(e.stack)):console.error(e),u.default.exit(1)}}async function dt(e,t){try{await st(e,{dryRun:t?.dryRun??ct,force:t?.force??lt,tasksFilePath:t?.tasksFilePath??void 0,...t?.globalVariables!=null&&{globalVariables:t.globalVariables},...t?.globalPrompts!=null&&{globalPrompts:t.globalPrompts}})}catch(e){b(`❌ Task execution failed`,`error`),e instanceof Error?(b(`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 ue}}),Object.defineProperty(exports,`B`,{enumerable:!0,get:function(){return se}}),Object.defineProperty(exports,`C`,{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,`D`,{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,`E`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`F`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`G`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`H`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`I`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`J`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`K`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`L`,{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,`M`,{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,`N`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`O`,{enumerable:!0,get:function(){return me}}),Object.defineProperty(exports,`P`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`R`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`T`,{enumerable:!0,get:function(){return he}}),Object.defineProperty(exports,`U`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`V`,{enumerable:!0,get:function(){return oe}}),Object.defineProperty(exports,`W`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`Y`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return it}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return pe}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return tt}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return We}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return at}}),Object.defineProperty(exports,`j`,{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,`k`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return Ve}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return dt}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return rt}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return ze}}),Object.defineProperty(exports,`q`,{enumerable:!0,get:function(){return ee}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return ot}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return nt}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return ut}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return Ue}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`w`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`z`,{enumerable:!0,get:function(){return N}});
@@ -0,0 +1,17 @@
1
+ import e from"node:path";import t from"node:fs";import n from"node:process";import{promisify as r}from"node:util";import{execSync as i}from"node:child_process";import a from"node:readline";import o from"handlebars";import{confirm as s,input as c,number as l,password as u,select as d}from"@inquirer/prompts";function f(){return{}}function p(e,t){return e===void 0?!0:typeof e==`boolean`?e:typeof e==`object`&&`condition`in e?b(e.condition,t):!1}function m(){try{let e=i(`git remote get-url origin`,{encoding:`utf-8`}).trim(),t=e.match(/github\.com[:/](?<owner>[^/]+)\/(?<name>[^/]+)$/u);if(t?.groups){let{owner:n,name:r}=t.groups,i=r;return i.endsWith(`.git`)&&(i=i.slice(0,-4)),{owner:n,name:i,url:e}}return null}catch{return null}}async function h(e,t){let r=a.createInterface({input:n.stdin,output:n.stdout});return new Promise(n=>{let i;i=t==null?`${e}: `:`${e} (${t}): `,r.question(i,e=>{r.close(),n(e.trim()||(t??``))})})}async function g(e,t=!1){return h(`${e} (${t?`Y/n`:`y/N`})`,t?`y`:`n`).then(e=>e.toLowerCase()===`y`||e.toLowerCase()===`yes`)}function _(e,t=`info`){console.log(`${{info:`\x1B[36m`,success:`\x1B[32m`,error:`\x1B[31m`,warn:`\x1B[33m`}[t]}${{info:`ℹ`,success:`✓`,error:`✗`,warn:`⚠`}[t]} ${e}`)}function v(e,t){return e.replace(/\{\{(?<key>\w+)\}\}/gu,(e,n)=>t[n]?.toString()??``)}function y(e,t,n){let r=t.split(`.`),i=e;for(let e=0;e<r.length-1;e++){let t=r[e];t!=null&&t!==``&&((!(t in i)||typeof i[t]!=`object`||i[t]===null)&&(i[t]={}),i=i[t])}let a=r[r.length-1];a!=null&&a!==``&&(i[a]=n)}function b(e,t){try{let n={...t};return Function(...Object.keys(n),`'use strict'; return (${e})`)(...Object.values(n))}catch(t){return _(`Failed to evaluate condition: ${e}`,`warn`),t instanceof Error&&_(` Error: ${t.message}`,`warn`),!1}}function ee(r,i){try{let a=e.isAbsolute(r)?r:e.join(n.cwd(),r);if(!t.existsSync(a))throw Error(`Template file not found: ${r}`);return te(t.readFileSync(a,`utf-8`),i)}catch(e){throw _(`Failed to read template file: ${r}`,`error`),e instanceof Error&&_(` Error: ${e.message}`,`error`),e}}function te(e,t){try{return o.compile(e)(t)}catch(e){throw _(`Failed to compile Handlebars template`,`error`),e instanceof Error&&_(` Error: ${e.message}`,`error`),e}}const x=r(t.readFile),S={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,cyan:`\x1B[36m`,gray:`\x1B[90m`};function C(e,t){switch(t){case`add`:return`${S.green}+ ${e}${S.reset}`;case`remove`:return`${S.red}- ${e}${S.reset}`;case`context`:return`${S.gray} ${e}${S.reset}`;default:return e}}function w(e,t){let n=e.split(`
2
+ `),r=t.split(`
3
+ `),i=[],a=Math.max(n.length,r.length);for(let e=0;e<a;e++){let t=n[e],a=r[e];t===a?t!==void 0&&i.push(C(t,`context`)):(t!==void 0&&i.push(C(t,`remove`)),a!==void 0&&i.push(C(a,`add`)))}return i}async function T(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${S.yellow}⊘ Condition not met - task would be skipped${S.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${S.red}✗ File not found: ${r.file}${S.reset}`;try{let e=await x(a,`utf-8`),t=JSON.parse(e),n={...t};function o(e){if(typeof e==`string`)return v(e,i);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,n]of Object.entries(r.updates)){let r=o(n);e.includes(`.`)?y(t,e,r):t[e]=r}let s=JSON.stringify(n,null,2),c=JSON.stringify(t,null,2);if(s===c)return`${S.cyan}→ No changes${S.reset}`;let l=w(s,c);return`${S.blue}File: ${r.file}${S.reset}\n${l.join(`
4
+ `)}`}catch(e){return`${S.red}✗ Error: ${e instanceof Error?e.message:String(e)}${S.reset}`}}async function E(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${S.yellow}⊘ Condition not met - task would be skipped${S.reset}`;if(r.template==null||r.template===``)return`${S.red}✗ No template content provided for file: ${r.file}${S.reset}`;let a=e.join(n.cwd(),r.file),o=v(r.template,i);if(!t.existsSync(a)){let e=o.split(`
5
+ `).slice(0,10).join(`
6
+ `),t=o.split(`
7
+ `).length>10;return`${S.blue}File: ${r.file}${S.reset}\n${S.green}+ New file would be created${S.reset}\n${S.gray}Content preview:${S.reset}\n${e}${t?`
8
+ ...`:``}`}try{let e=await x(a,`utf-8`);if(e===o)return`${S.cyan}→ No changes${S.reset}`;let t=w(e,o);return`${S.blue}File: ${r.file}${S.reset}\n${t.join(`
9
+ `)}`}catch(e){return`${S.red}✗ Error: ${e instanceof Error?e.message:String(e)}${S.reset}`}}async function ne(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${S.yellow}⊘ Condition not met - task would be skipped${S.reset}`;let a=e.join(n.cwd(),r.file);if(t.existsSync(a))return`${S.cyan}→ File already exists, would be skipped: ${r.file}${S.reset}`;let o=r.template!=null&&r.template!==``,s=r.templateFile!=null&&r.templateFile!==``;if(!o&&!s)return`${S.red}✗ No template content provided for file: ${r.file}${S.reset}`;try{let e;if(o)e=v(r.template,i);else return`${S.blue}File: ${r.file}${S.reset}\n${S.green}+ New file would be created from template: ${r.templateFile}${S.reset}`;let t=e.split(`
10
+ `).slice(0,10).join(`
11
+ `),n=e.split(`
12
+ `).length>10;return`${S.blue}File: ${r.file}${S.reset}\n${S.green}+ New file would be created${S.reset}\n${S.gray}Content preview:${S.reset}\n${t}${n?`
13
+ ...`:``}`}catch(e){return`${S.red}✗ Error: ${e instanceof Error?e.message:String(e)}${S.reset}`}}async function D(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${S.yellow}⊘ Condition not met - task would be skipped${S.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${S.red}✗ File not found: ${r.file}${S.reset}`;try{let e=await x(a,`utf-8`),t=new RegExp(r.pattern,r.flags??`g`),n=v(r.replacement,i),o=e.replace(t,n);if(e===o)return`${S.cyan}→ No matches found${S.reset}`;let s=w(e,o);return`${S.blue}File: ${r.file}${S.reset}\n${s.join(`
14
+ `)}`}catch(e){return`${S.red}✗ Error: ${e instanceof Error?e.message:String(e)}${S.reset}`}}async function O(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${S.yellow}⊘ Condition not met - task would be skipped${S.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${S.red}✗ File not found: ${r.file}${S.reset}`;try{let e=await x(a,`utf-8`),t=e;for(let{find:t,replace:n}of r.replacements){let r=v(t,i),a=v(n,i);e=e.replace(r,a)}if(t===e)return`${S.cyan}→ No changes${S.reset}`;let n=w(t,e);return`${S.blue}File: ${r.file}${S.reset}\n${n.join(`
15
+ `)}`}catch(e){return`${S.red}✗ Error: ${e instanceof Error?e.message:String(e)}${S.reset}`}}function k(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${S.yellow}⊘ Condition not met - task would be skipped${S.reset}`;let a=r.paths.map(e=>v(e,i)).filter(r=>t.existsSync(e.join(n.cwd(),r)));return a.length===0?`${S.cyan}→ No files/directories to delete${S.reset}`:`${S.red}Would delete:${S.reset}\n${a.map(e=>`${S.red} - ${e}${S.reset}`).join(`
16
+ `)}`}function re(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${S.yellow}⊘ Condition not met - task would be skipped${S.reset}`;let a=v(r.from,i),o=v(r.to,i),s=e.join(n.cwd(),a),c=e.join(n.cwd(),o);return t.existsSync(s)?t.existsSync(c)?`${S.yellow}⚠ Destination already exists: ${o}${S.reset}\n${S.cyan}Would rename: ${a} → ${o}${S.reset}`:`${S.cyan}Would rename: ${a} → ${o}${S.reset}`:`${S.red}✗ Source not found: ${a}${S.reset}`}function ie(r){if(r.condition!=null&&r.condition!==``)return`${S.yellow}⊘ Condition check skipped in dry-run${S.reset}`;let i=e.join(n.cwd(),`.git`),a=t.existsSync(i),o=[];if(r.removeExisting&&a&&o.push(`${S.red}Would remove existing .git directory${S.reset}`),o.push(`${S.green}Would initialize git repository${S.reset}`),r.initialCommit){let e=r.message??`Initial commit`;o.push(`${S.green}Would create initial commit: "${e}"${S.reset}`)}return o.join(`
17
+ `)}function A(e,t){if(e.condition!=null&&e.condition!==``&&!b(e.condition,t))return`${S.yellow}⊘ Condition not met - task would be skipped${S.reset}`;let r=v(e.command,t),i=e.cwd==null?n.cwd():v(e.cwd,t);return`${S.yellow}Would execute:${S.reset}\n${S.cyan} Command: ${r}${S.reset}\n${S.cyan} Working directory: ${i}${S.reset}`}async function j(e,t){try{switch(e.type){case`update-json`:return await T(e.config,t);case`template`:return await E(e.config,t);case`create`:return await ne(e.config,t);case`regex-replace`:return await D(e.config,t);case`replace-in-file`:return await O(e.config,t);case`delete`:return k(e.config,t);case`rename`:return re(e.config,t);case`git-init`:return ie(e.config);case`exec`:return A(e.config,t);default:{let t=e.type;return`${S.yellow}⚠ Diff not available for task type: ${t}${S.reset}`}}}catch(e){return`${S.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${S.reset}`}}async function M(e,t){console.log(`${S.blue}═══════════════════════════════════════════════════════${S.reset}`),console.log(`${S.blue} DRY RUN - Preview of changes${S.reset}`),console.log(`${S.blue}═══════════════════════════════════════════════════════${S.reset}`);for(let n of e){console.log(`${S.cyan}▶ Task: ${n.name}${S.reset}`),console.log(`${S.gray} ${n.description}${S.reset}`);let e=await j(n,t);console.log(e),console.log(`${S.gray}${`─`.repeat(55)}${S.reset}`)}console.log(`${S.blue}═══════════════════════════════════════════════════════${S.reset}`),console.log(`${S.yellow} No changes were applied (dry-run mode)${S.reset}`),console.log(`${S.blue}═══════════════════════════════════════════════════════${S.reset}`)}const N=new Map,P={},F=new Map;function I(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);_(`✓ 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 L(e){let t=F.get(e);if(t!=null)return N.get(t)}function R(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 z(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){_(`Error in ${e} hook: ${t instanceof Error?t.message:String(t)}`,`error`)}}async function B(e,t,n){let r=L(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=L(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function de(e){let t=L(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 V(e,t=new Map,n={}){let r={};if(e.length===0)return r;for(let i of e){let e={...n,...r};if(p(i.enabled,e))try{let e,n=t.get(i.id);switch(i.type){case`input`:{let t={message:i.message};if(n!==void 0&&(t.default=String(n)),i.required!==void 0&&(t.required=i.required),e=await c(t),i.required&&(e==null||typeof e==`string`&&e.trim()===``))throw _(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break}case`password`:if(e=await u({message:i.message,mask:`*`}),i.required&&(e==null||typeof e==`string`&&e.trim()===``))throw _(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break;case`number`:{let t={message:i.message};if(n!==void 0&&(t.default=Number(n)),i.required!==void 0&&(t.required=i.required),i.min!==void 0&&(t.min=i.min),i.max!==void 0&&(t.max=i.max),e=await l(t),i.required&&e==null)throw _(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break}case`select`:{let t={message:i.message,choices:i.choices.map(e=>({name:e.name,value:e.value}))};n!==void 0&&(t.default=n),e=await d(t);break}case`confirm`:{let t=n===void 0?!1:!!n;e=await s({message:i.message,default:t});break}default:throw _(`Unknown prompt type: ${i.type}`,`error`),Error(`Unknown prompt type: ${i.type}`)}r[i.id]=e}catch(e){throw e instanceof Error&&_(`Failed to collect prompt "${i.id}": ${e.message}`,`error`),e}}return r}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===`exec`){let e=n.value;if(typeof e!=`string`){_(`Prompt "${t}": exec default value must have a string command`,`error`);return}try{let t=i(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){_(`Prompt "${t}": failed to execute default value command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`static`)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}function W(e){let t=[],n=new Set;for(let r of e){if(n.has(r.id)&&t.push(`Duplicate prompt ID: ${r.id}`),n.add(r.id),/^[\w-]+$/u.test(r.id)||t.push(`Invalid prompt ID "${r.id}": must contain only alphanumeric characters, underscores, and hyphens`),(!r.message||r.message.trim()===``)&&t.push(`Prompt "${r.id}" must have a non-empty message`),r.type===`select`){r.choices.length===0&&t.push(`Select prompt "${r.id}" must have at least one choice`);for(let e of r.choices)(!e.name||e.name.trim()===``)&&t.push(`Select prompt "${r.id}" has a choice with empty name`),e.value===void 0&&t.push(`Select prompt "${r.id}" has a choice with undefined value`)}r.type===`number`&&r.min!==void 0&&r.max!==void 0&&r.min>r.max&&t.push(`Number prompt "${r.id}" has min greater than max`)}return t}const pe=r(t.writeFile);async function me(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i)){_(`Condition not met, skipping create task`,`info`);return}let a=e.join(n.cwd(),r.file);if(t.existsSync(a)){_(`File already exists, skipping: ${r.file}`,`info`);return}let o=r.template!=null&&r.template!==``,s=r.templateFile!=null&&r.templateFile!==``;if(!o&&!s)throw Error(`Create task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(o&&s)throw Error(`Create task cannot have both "template" and "templateFile" specified. Use one or the other.`);let c;if(s&&r.templateFile.endsWith(`.hbs`))c=ee(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=v(t.readFileSync(o,`utf-8`),i)}else c=v(r.template,i);let l=e.dirname(a);t.existsSync(l)||t.mkdirSync(l,{recursive:!0}),await pe(a,c),_(`Created file: ${r.file}`,`success`)}const he={name:`create`,version:`1.0.0`,taskTypes:[`create`],execute:async(e,t,n)=>{n.dryRun||await me(e.config,t)}};async function ge(r,i){let{paths:a,condition:o}=r;if(o!=null&&o!==``){if(!i){_(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!b(o,i)){_(`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})}}const _e={name:`delete`,version:`1.0.0`,taskTypes:[`delete`],execute:async(e,t,n)=>{n.dryRun||await ge(e.config,t)}};async function ve(t,r){if(t.condition!=null&&t.condition!==``){if(!r){_(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!b(t.condition,r)){_(`Condition not met, skipping exec task`,`info`);return}}let a=t.cwd==null?n.cwd():e.join(n.cwd(),t.cwd);i(t.command,{cwd:a,stdio:`inherit`})}const ye={name:`exec`,version:`1.0.0`,taskTypes:[`exec`],execute:async(e,t,n)=>{n.dryRun||await ve(e.config,t)}};async function be(r,a){if(r.condition!=null&&r.condition!==``){if(!a){_(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!b(r.condition,a)){_(`Condition not met, skipping git-init task`,`info`);return}}if(r.removeExisting){let r=e.join(n.cwd(),`.git`);t.existsSync(r)&&t.rmSync(r,{recursive:!0,force:!0})}if(i(`git init`,{stdio:`inherit`}),r.initialCommit){let e=r.message??`Initial commit`;i(`git add .`,{stdio:`inherit`}),i(`git commit -m "${e}"`,{stdio:`inherit`})}}const xe={name:`git-init`,version:`1.0.0`,taskTypes:[`git-init`],execute:async(e,t,n)=>{n.dryRun||await be(e.config,t)}},Se=r(t.readFile),Ce=r(t.writeFile);async function we(t,r){if(t.condition!=null&&t.condition!==``&&!b(t.condition,r)){_(`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 Se(i,`utf-8`),l=new RegExp(a,o);c=c.replace(l,v(s,r)),await Ce(i,c)}const Te={name:`regex-replace`,version:`1.0.0`,taskTypes:[`regex-replace`],execute:async(e,t,n)=>{n.dryRun||await we(e.config,t)}},Ee=r(t.rename);async function De(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i)){_(`Condition not met, skipping rename task`,`info`);return}let a=e.join(n.cwd(),v(r.from,i)),o=e.join(n.cwd(),v(r.to,i));if(!t.existsSync(a)){_(`Source path does not exist: ${a}`,`warn`);return}await Ee(a,o)}const Oe={name:`rename`,version:`1.0.0`,taskTypes:[`rename`],execute:async(e,t,n)=>{n.dryRun||await De(e.config,t)}},ke=r(t.readFile),Ae=r(t.writeFile);async function je(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i)){_(`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)){_(`File not found: ${a}, skipping`,`warn`);return}let s=await ke(a,`utf-8`);for(let{find:e,replace:t}of o){let n=v(t,i);s=s.replace(new RegExp(e,`gu`),n)}await Ae(a,s)}const Me={name:`replace-in-file`,version:`1.0.0`,taskTypes:[`replace-in-file`],execute:async(e,t,n)=>{n.dryRun||await je(e.config,t)}},G=r(t.readFile);function K(e){try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}}function q(t,r){if(K(t))return t;if(r==null||r===``)return e.isAbsolute(t)?t:e.resolve(n.cwd(),t);if(K(r))try{let e=new URL(`.`,r);return new URL(t,e).href}catch{throw Error(`Failed to resolve templateFile "${t}" relative to remote template "${r}"`)}let i=e.dirname(r);return e.isAbsolute(t)?t:e.resolve(i,t)}async function J(e){if(K(e))return Y(e);if(!t.existsSync(e))throw Error(`Template file not found: ${e}`);return G(e,`utf-8`)}async function Y(e){try{let t=await fetch(e);if(!t.ok)throw Error(`Failed to fetch template from ${e}: ${t.status} ${t.statusText}`);return await t.text()}catch(t){throw t instanceof Error&&t.message.includes(`Failed to fetch`)?t:Error(`Failed to fetch template from ${e}: ${t instanceof Error?t.message:String(t)}`)}}const X=new Map;async function Z(r,i=new Set){let a=K(r),o;if(o=a||e.isAbsolute(r)?r:e.resolve(n.cwd(),r),X.has(o))return X.get(o);if(i.has(o))throw Error(`Circular dependency detected: ${Array.from(i).join(` -> `)} -> ${o}`);i.add(o);let s;if(a)s=await Y(o);else{if(!t.existsSync(o))throw Error(`Template file not found: ${o}`);s=await G(o,`utf-8`)}let c;try{c=JSON.parse(s)}catch(e){throw Error(`Failed to parse template file ${o}: ${e instanceof Error?e.message:String(e)}`)}if(c.tasks!==void 0&&!Array.isArray(c.tasks))throw TypeError(`Invalid template file ${o}: 'tasks' must be an array if provided`);c.tasks===void 0&&(c.tasks=[]);for(let e of c.tasks)e.$sourceUrl=o;return X.set(o,c),c}async function Q(t,r,i=new Set){let a=K(t),o;if(o=a||e.isAbsolute(t)?t:r==null?e.resolve(n.cwd(),t):K(r)?new URL(t,r).href:e.resolve(r,t),i.has(o))throw Error(`Circular dependency detected: ${Array.from(i).join(` -> `)} -> ${o}`);i.add(o);let s=await Z(o);if(s.extends==null||s.extends===``)return s;let c=K(o)?new URL(`.`,o).href:e.dirname(o),l=Array.isArray(s.extends)?s.extends:[s.extends],u=[];for(let e of l){let t=await Q(e,c,i);u.push(t)}return Pe([...u,s])}function Ne(e,t,n){let r=new Map;for(let t of e){if(r.has(t.id))throw Error(`Duplicate ID "${t.id}" found in task. This ID is already used in ${r.get(t.id)}`);r.set(t.id,`task`)}if(t!=null)for(let e of t){if(r.has(e.id))throw Error(`Duplicate ID "${e.id}" found in variable. This ID is already used in ${r.get(e.id)}`);r.set(e.id,`variable`)}if(n!=null)for(let e of n){if(r.has(e.id))throw Error(`Duplicate ID "${e.id}" found in prompt. This ID is already used in ${r.get(e.id)}`);r.set(e.id,`prompt`)}}function Pe(e){if(e.length===0)return{tasks:[]};if(e.length===1){let t=e[0];return Ne(t.tasks??[],t.variables,t.prompts),t}let t=new Map,n=new Map,r=new Map;for(let i of e){if(i.prompts!=null)for(let e of i.prompts)r.set(e.id,{...e});if(i.variables!=null)for(let e of i.variables)n.set(e.id,{...e});for(let e of i.tasks??[])if(t.has(e.id)){let n=t.get(e.id);t.set(e.id,Fe(n,e))}else t.set(e.id,{...e})}let i=Array.from(t.values()),a=r.size>0?Array.from(r.values()):void 0,o=n.size>0?Array.from(n.values()):void 0;Ne(i,o,a);let s={tasks:i};return a!=null&&(s.prompts=a),o!=null&&(s.variables=o),s}function Fe(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.variables?[...e.variables]:void 0;if(t.variables&&t.variables.length>0)if(!i)i=[...t.variables];else{let e=new Map(i.map(e=>[e.id,e]));for(let n of t.variables)e.set(n.id,n);i=Array.from(e.values())}let a=[...e.dependencies??[],...t.dependencies??[]],o=a.length>0?[...new Set(a)]:void 0,s=t.$sourceUrl??e.$sourceUrl;return{...e,...t,config:n,...r!=null&&{prompts:r},...i!=null&&{variables:i},...o!=null&&{dependencies:o},...s!=null&&{$sourceUrl:s}}}function Ie(){X.clear()}async function Le(e){_(`Loading tasks from ${e}...`,`info`);let t=await Q(e);_(`Loaded ${t.tasks?.length??0} task(s)`,`info`),t.extends!=null&&t.extends!==``&&_(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.prompts!=null&&t.prompts.length>0&&_(`Found ${t.prompts.length} top-level prompt(s)`,`info`),t.variables!=null&&t.variables.length>0&&_(`Found ${t.variables.length} top-level variable(s)`,`info`);let n={tasks:t.tasks??[]};return t.prompts!=null&&(n.prompts=t.prompts),t.variables!=null&&(n.variables=t.variables),n}const Re=r(t.writeFile);async function ze(t,r,i){if(t.condition!=null&&t.condition!==``&&!b(t.condition,r)){_(`Condition not met, skipping template task`,`info`);return}let a=e.join(n.cwd(),t.file),o=t.template!=null&&t.template!==``,s=t.templateFile!=null&&t.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&&t.templateFile.endsWith(`.hbs`)){let e=await J(q(t.templateFile,i?.$sourceUrl));c=(await import(`handlebars`)).default.compile(e)(r)}else c=v(s?await J(q(t.templateFile,i?.$sourceUrl)):t.template,r);await Re(a,c)}const Be={name:`template`,version:`1.0.0`,taskTypes:[`template`],execute:async(e,t,n)=>{n.dryRun||await ze(e.config,t,e)}},Ve=r(t.readFile),He=r(t.writeFile);async function Ue(t,r){if(t.condition!=null&&t.condition!==``&&!b(t.condition,r)){_(`Condition not met, skipping update-json task`,`info`);return}let i=e.join(n.cwd(),t.file),{updates:a}=t,o=await Ve(i,`utf-8`),s=JSON.parse(o);function c(e){if(typeof e==`string`)return v(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(`.`)?y(s,e,n):s[e]=n}await He(i,`${JSON.stringify(s,null,2)}\n`)}const We={name:`update-json`,version:`1.0.0`,taskTypes:[`update-json`],execute:async(e,t,n)=>{n.dryRun||await Ue(e.config,t)}};let Ge=!1;function Ke(){Ge||=(I(We),I(Be),I(he),I(Te),I(Me),I(_e),I(Oe),I(xe),I(ye),!0)}async function qe(e,t,n=!1){if(Ke(),n){_(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(R(e.type)){await B(e,t,{dryRun:n});return}throw TypeError(`Unknown task type: ${e.type}`)}async function Je(e,t,r,i,a=!1){try{return _(`[${r}/${i}] Running: ${e.name}...`,`info`),await qe(e,t,a),_(`✓ ${e.name}`,`success`),!0}catch(t){return _(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(_(` Reason: ${t.message}`,`error`),t.stack!=null&&n.env.DEBUG!=null&&console.error(t.stack)),e.required&&_(` This is a required task. Initialization cannot continue.`,`error`),!1}}function $(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}function Ye(e,t=new Map){let n={};for(let r of e){let e=t.get(r.id);e!==void 0&&(n[r.id]=e)}return n}async function Xe(e,t){if(e==null)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`exec`){let e=n.value;if(typeof e!=`string`){_(`Variable "${t}": exec value must have a string command`,`error`);return}try{let t=i(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){_(`Variable "${t}": failed to execute command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`static`)return n.value;return e}async function Ze(e){let t=new Map,n=e.map(async e=>{let t=await Xe(e.value,e.id);return{id:e.id,value:t}}),r=await Promise.all(n);for(let e of r)e.value!==void 0&&t.set(e.id,e.value);return t}function Qe(e){let t=[],n=new Set;for(let r of e)if(n.has(r.id)&&t.push(`Duplicate variable ID: "${r.id}"`),n.add(r.id),/^[\w$]+$/u.test(r.id)||t.push(`Variable ID "${r.id}" is invalid. Must contain only letters, numbers, underscore, or dollar sign.`),r.value===void 0||r.value===null)t.push(`Variable "${r.id}" must have a value`);else if(typeof r.value==`object`&&!Array.isArray(r.value)&&r.value!==null){let e=r.value;e.type==null||e.type===``?t.push(`Variable "${r.id}": value object must have a "type" field ("static" or "exec")`):e.type!==`static`&&e.type!==`exec`&&t.push(`Variable "${r.id}": type must be "static" or "exec", got "${e.type}"`),(e.value===void 0||e.value===null)&&t.push(`Variable "${r.id}": value config must have a "value" field`),e.type===`exec`&&typeof e.value!=`string`&&t.push(`Variable "${r.id}": exec type must have a string command as value`)}return t}async function $e(e,t){let r=e.filter(e=>p(e.enabled,f()));_(`Resolving task dependencies...`,`info`);let i=$(r);_(`Welcome! Let's execute your tasks.`,`info`),t.dryRun&&_(`🔍 DRY RUN MODE - No changes will be made`,`warn`),_(`This will execute your project tasks based on the defined configuration.`,`info`);let a=f(),o=t.globalVariables??[],s=[],c=[...o];for(let e of i)if(e.variables&&e.variables.length>0)for(let t of e.variables)s.push(t),c.push(t);if(c.length>0){let e=Qe(c);e.length>0&&(_(`❌ Variable validation errors:`,`error`),e.forEach(e=>_(` - ${e}`,`error`)),n.exit(1)),_(`Resolving variable values...`,`info`);let t=Ye(c,await Ze(c));Object.assign(a,t),Object.keys(t).length>0&&_(`✓ Resolved ${Object.keys(t).length} variable(s)`,`success`)}let l=t.globalPrompts??[],u=[],d=[...l];for(let e of i)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)u.push(t),d.push(t);if(d.length>0){let e=W(d);e.length>0&&(_(`❌ Prompt validation errors:`,`error`),e.forEach(e=>_(` - ${e}`,`error`)),n.exit(1)),_(`Resolving prompt default values...`,`info`);let t=await U(d),r={};if(l.length>0&&(_(`📋 Top-level prompts (available to all tasks):`,`info`),r=await V(l,t,a),Object.assign(a,r)),u.length>0){l.length>0&&_(`📋 Task-specific prompts:`,`info`);let e=await V(u,t,a);Object.assign(a,e)}}let m=i.filter(e=>p(e.enabled,a));if(_(`${m.length} of ${i.length} task(s) enabled for execution`,`info`),t.dryRun){await M(m,a),_(`🔍 Dry run completed - no changes were made`,`info`),_(`Run without --dry-run to apply changes`,`info`);return}_(`Starting task execution...`,`info`),await z(`beforeAll`,a);let h=m.length,g=0,v=0,y=[];for(let e=0;e<m.length;e++){let n=m[e];if(n!=null)if(await z(`beforeTask`,n,a),await Je(n,a,e+1,h,t.dryRun))g++,y.push(n.id),await z(`afterTask`,n,a);else if(n.required){v++,await z(`onError`,Error(`Task ${n.name} failed`),n);break}else _(`⚠️ Non-critical task failed, continuing...`,`warn`),await z(`onError`,Error(`Task ${n.name} failed`),n)}v>0&&(_(`❌ Task execution failed with ${v} critical error(s)`,`error`),_(`✓ Completed: ${g}/${h} tasks`,`info`),n.exit(1)),await z(`afterAll`,a),_(`✅ All tasks completed successfully!`,`success`),_(`✓ Completed: ${g}/${h} tasks`,`success`),t.dryRun||(_(`Next steps:`,`info`),_(`1. Review the changes made to your project`,`info`),_(`2. Commit the changes to git`,`info`))}const et=n.argv.includes(`--dry-run`),tt=n.argv.includes(`--force`);async function nt(e){try{let t=e||[];t.length===0&&(_(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),_(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),n.exit(1)),await $e(t,{dryRun:et,force:tt,tasksFilePath:void 0})}catch(e){_(`❌ Task execution failed`,`error`),e instanceof Error?(_(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}async function rt(e,t){try{await $e(e,{dryRun:t?.dryRun??et,force:t?.force??tt,tasksFilePath:t?.tasksFilePath??void 0,...t?.globalVariables!=null&&{globalVariables:t.globalVariables},...t?.globalPrompts!=null&&{globalPrompts:t.globalPrompts}})}catch(e){_(`❌ Task execution failed`,`error`),e instanceof Error?(_(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}export{ae as A,E as B,oe as C,se as D,R as E,ie as F,_ as G,b as H,D as I,y as J,h as K,re as L,M,k as N,le as O,A as P,O as R,B as S,ue as T,m as U,T as V,v as W,H as _,Xe as a,ce as b,qe as c,Q as d,Le as f,U as g,W as h,Ze as i,de as j,I as k,Je as l,Pe as m,rt as n,Ye as o,Z as p,g as q,Qe as r,$ as s,nt as t,Ie as u,V as v,L as w,fe as x,z as y,j as z};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pixpilot/scaffoldfy",
3
3
  "type": "module",
4
- "version": "0.10.0",
4
+ "version": "0.12.0",
5
5
  "author": "PixPilot <m.doaie@hotmail.com>",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -46,10 +46,10 @@
46
46
  "eslint": "^9.38.0",
47
47
  "tsdown": "^0.15.8",
48
48
  "typescript": "^5.9.3",
49
+ "@internal/tsconfig": "0.1.0",
49
50
  "@internal/eslint-config": "0.3.0",
50
51
  "@internal/prettier-config": "0.0.1",
51
52
  "@internal/tsdown-config": "0.1.0",
52
- "@internal/tsconfig": "0.1.0",
53
53
  "@internal/vitest-config": "0.1.0"
54
54
  },
55
55
  "prettier": "@internal/prettier-config",
@@ -1,17 +0,0 @@
1
- var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`node:fs`);c=s(c);let l=require(`node:path`);l=s(l);let u=require(`node:process`);u=s(u);let d=require(`node:child_process`);d=s(d);let f=require(`node:util`);f=s(f);let p=require(`node:readline`);p=s(p);let m=require(`handlebars`);m=s(m);let h=require(`@inquirer/prompts`);h=s(h);function g(){return{}}function _(e,t){return e===void 0?!0:typeof e==`boolean`?e:typeof e==`object`&&`condition`in e?w(e.condition,t):!1}function v(){try{let e=(0,d.execSync)(`git remote get-url origin`,{encoding:`utf-8`}).trim(),t=e.match(/github\.com[:/](?<owner>[^/]+)\/(?<name>[^/]+)$/u);if(t?.groups){let{owner:n,name:r}=t.groups,i=r;return i.endsWith(`.git`)&&(i=i.slice(0,-4)),{owner:n,name:i,url:e}}return null}catch{return null}}async function y(e,t){let n=p.default.createInterface({input:u.default.stdin,output:u.default.stdout});return new Promise(r=>{let i;i=t==null?`${e}: `:`${e} (${t}): `,n.question(i,e=>{n.close(),r(e.trim()||(t??``))})})}async function b(e,t=!1){return y(`${e} (${t?`Y/n`:`y/N`})`,t?`y`:`n`).then(e=>e.toLowerCase()===`y`||e.toLowerCase()===`yes`)}function x(e,t=`info`){console.log(`${{info:`\x1B[36m`,success:`\x1B[32m`,error:`\x1B[31m`,warn:`\x1B[33m`}[t]}${{info:`ℹ`,success:`✓`,error:`✗`,warn:`⚠`}[t]} ${e}`)}function S(e,t){return e.replace(/\{\{(?<key>\w+)\}\}/gu,(e,n)=>t[n]?.toString()??``)}function C(e,t,n){let r=t.split(`.`),i=e;for(let e=0;e<r.length-1;e++){let t=r[e];t!=null&&t!==``&&((!(t in i)||typeof i[t]!=`object`||i[t]===null)&&(i[t]={}),i=i[t])}let a=r[r.length-1];a!=null&&a!==``&&(i[a]=n)}function w(e,t){try{let n={...t};return Function(...Object.keys(n),`'use strict'; return (${e})`)(...Object.values(n))}catch(t){return x(`Failed to evaluate condition: ${e}`,`warn`),t instanceof Error&&x(` Error: ${t.message}`,`warn`),!1}}function ee(e,t){try{let n=l.default.isAbsolute(e)?e:l.default.join(u.default.cwd(),e);if(!c.default.existsSync(n))throw Error(`Template file not found: ${e}`);return te(c.default.readFileSync(n,`utf-8`),t)}catch(t){throw x(`Failed to read template file: ${e}`,`error`),t instanceof Error&&x(` Error: ${t.message}`,`error`),t}}function te(e,t){try{return m.default.compile(e)(t)}catch(e){throw x(`Failed to compile Handlebars template`,`error`),e instanceof Error&&x(` Error: ${e.message}`,`error`),e}}const T=(0,f.promisify)(c.default.readFile),ne=2,re=10,ie=55,E={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,cyan:`\x1B[36m`,gray:`\x1B[90m`};function D(e,t){switch(t){case`add`:return`${E.green}+ ${e}${E.reset}`;case`remove`:return`${E.red}- ${e}${E.reset}`;case`context`:return`${E.gray} ${e}${E.reset}`;default:return e}}function O(e,t){let n=e.split(`
2
- `),r=t.split(`
3
- `),i=[],a=Math.max(n.length,r.length);for(let e=0;e<a;e++){let t=n[e],a=r[e];t===a?t!==void 0&&i.push(D(t,`context`)):(t!==void 0&&i.push(D(t,`remove`)),a!==void 0&&i.push(D(a,`add`)))}return i}async function k(e,t){if(e.condition!=null&&e.condition!==``&&!w(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=JSON.parse(r),a={...i};function o(e){if(typeof e==`string`)return S(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[t,n]of Object.entries(e.updates)){let e=o(n);t.includes(`.`)?C(i,t,e):i[t]=e}let s=JSON.stringify(a,null,2),c=JSON.stringify(i,null,2);if(s===c)return`${E.cyan}→ No changes${E.reset}`;let l=O(s,c);return`${E.blue}File: ${e.file}${E.reset}\n${l.join(`
4
- `)}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function ae(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;if(e.template==null||e.template===``)return`${E.red}✗ No template content provided for file: ${e.file}${E.reset}`;let n=l.default.join(u.default.cwd(),e.file),r=S(e.template,t);if(!c.default.existsSync(n)){let t=r.split(`
5
- `).slice(0,10).join(`
6
- `),n=r.split(`
7
- `).length>10;return`${E.blue}File: ${e.file}${E.reset}\n${E.green}+ New file would be created${E.reset}\n${E.gray}Content preview:${E.reset}\n${t}${n?`
8
- ...`:``}`}try{let t=await T(n,`utf-8`);if(t===r)return`${E.cyan}→ No changes${E.reset}`;let i=O(t,r);return`${E.blue}File: ${e.file}${E.reset}\n${i.join(`
9
- `)}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function oe(e,t){if(e.condition!=null&&e.condition!==``&&!w(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.cyan}→ File already exists, would be skipped: ${e.file}${E.reset}`;let r=e.template!=null&&e.template!==``,i=e.templateFile!=null&&e.templateFile!==``;if(!r&&!i)return`${E.red}✗ No template content provided for file: ${e.file}${E.reset}`;try{let n;if(r)n=S(e.template,t);else return`${E.blue}File: ${e.file}${E.reset}\n${E.green}+ New file would be created from template: ${e.templateFile}${E.reset}`;let i=n.split(`
10
- `).slice(0,10).join(`
11
- `),a=n.split(`
12
- `).length>10;return`${E.blue}File: ${e.file}${E.reset}\n${E.green}+ New file would be created${E.reset}\n${E.gray}Content preview:${E.reset}\n${i}${a?`
13
- ...`:``}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function se(e,t){if(e.condition!=null&&e.condition!==``&&!w(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=new RegExp(e.pattern,e.flags??`g`),a=S(e.replacement,t),o=r.replace(i,a);if(r===o)return`${E.cyan}→ No matches found${E.reset}`;let s=O(r,o);return`${E.blue}File: ${e.file}${E.reset}\n${s.join(`
14
- `)}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function A(e,t){if(e.condition!=null&&e.condition!==``&&!w(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=S(n,t),a=S(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(`
15
- `)}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}function j(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=e.paths.map(e=>S(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(`
16
- `)}`}function M(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=S(e.from,t),r=S(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 N(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(`
17
- `)}function ce(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=S(e.command,t),r=e.cwd==null?u.default.cwd():S(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 P(e,t){try{switch(e.type){case`update-json`:return await k(e.config,t);case`template`:return await ae(e.config,t);case`create`:return await oe(e.config,t);case`regex-replace`:return await se(e.config,t);case`replace-in-file`:return await A(e.config,t);case`delete`:return j(e.config,t);case`rename`:return M(e.config,t);case`git-init`:return N(e.config);case`exec`:return ce(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 F(e,t){console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(`${E.blue} DRY RUN - Preview of changes${E.reset}`),console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`);for(let n of e){console.log(`${E.cyan}▶ Task: ${n.name}${E.reset}`),console.log(`${E.gray} ${n.description}${E.reset}`);let e=await P(n,t);console.log(e),console.log(`${E.gray}${`─`.repeat(55)}${E.reset}`)}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}`)}const I=new Map,L={},R=new Map;function z(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(I.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(R.has(t)){let e=R.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}I.set(e.name,e);for(let t of e.taskTypes)R.set(t,e.name);x(`✓ Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`,`info`)}function le(e){let t=I.get(e);if(t!=null){for(let e of t.taskTypes)R.delete(e);I.delete(e)}}function ue(e){return I.get(e)}function B(e){let t=R.get(e);if(t!=null)return I.get(t)}function V(e){return R.has(e)}function de(){return Array.from(I.keys())}function fe(){I.clear(),R.clear()}function pe(e){e.beforeAll!=null&&(L.beforeAll=e.beforeAll),e.afterAll!=null&&(L.afterAll=e.afterAll),e.beforeTask!=null&&(L.beforeTask=e.beforeTask),e.afterTask!=null&&(L.afterTask=e.afterTask),e.onError!=null&&(L.onError=e.onError)}async function H(e,...t){let n=L[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){x(`Error in ${e} hook: ${t instanceof Error?t.message:String(t)}`,`error`)}}async function U(e,t,n){let r=B(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}async function me(e,t){let n=B(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function he(e){let t=B(e.type);return t==null?[`No plugin found for task type: ${e.type}`]:t.validate==null?[]:t.validate(e)}function ge(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 W(e,t=new Map,n={}){let r={};if(e.length===0)return r;for(let i of e){let e={...n,...r};if(_(i.enabled,e))try{let e,n=t.get(i.id);switch(i.type){case`input`:{let t={message:i.message};if(n!==void 0&&(t.default=String(n)),i.required!==void 0&&(t.required=i.required),e=await(0,h.input)(t),i.required&&(e==null||typeof e==`string`&&e.trim()===``))throw x(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break}case`password`:if(e=await(0,h.password)({message:i.message,mask:`*`}),i.required&&(e==null||typeof e==`string`&&e.trim()===``))throw x(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break;case`number`:{let t={message:i.message};if(n!==void 0&&(t.default=Number(n)),i.required!==void 0&&(t.required=i.required),i.min!==void 0&&(t.min=i.min),i.max!==void 0&&(t.max=i.max),e=await(0,h.number)(t),i.required&&e==null)throw x(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break}case`select`:{let t={message:i.message,choices:i.choices.map(e=>({name:e.name,value:e.value}))};n!==void 0&&(t.default=n),e=await(0,h.select)(t);break}case`confirm`:{let t=n===void 0?!1:!!n;e=await(0,h.confirm)({message:i.message,default:t});break}default:throw x(`Unknown prompt type: ${i.type}`,`error`),Error(`Unknown prompt type: ${i.type}`)}r[i.id]=e}catch(e){throw e instanceof Error&&x(`Failed to collect prompt "${i.id}": ${e.message}`,`error`),e}}return r}async function G(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`exec`){let e=n.value;if(typeof e!=`string`){x(`Prompt "${t}": exec 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){x(`Prompt "${t}": failed to execute default value command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`static`)return n.value;return e}async function K(e){let t=new Map,n=e.map(async e=>{if(e.default!==void 0){let n=await G(e.default,e.id);n!==void 0&&t.set(e.id,n)}});return await Promise.all(n),t}function q(e){let t=[],n=new Set;for(let r of e){if(n.has(r.id)&&t.push(`Duplicate prompt ID: ${r.id}`),n.add(r.id),/^[\w-]+$/u.test(r.id)||t.push(`Invalid prompt ID "${r.id}": must contain only alphanumeric characters, underscores, and hyphens`),(!r.message||r.message.trim()===``)&&t.push(`Prompt "${r.id}" must have a non-empty message`),r.type===`select`){r.choices.length===0&&t.push(`Select prompt "${r.id}" must have at least one choice`);for(let e of r.choices)(!e.name||e.name.trim()===``)&&t.push(`Select prompt "${r.id}" has a choice with empty name`),e.value===void 0&&t.push(`Select prompt "${r.id}" has a choice with undefined value`)}r.type===`number`&&r.min!==void 0&&r.max!==void 0&&r.min>r.max&&t.push(`Number prompt "${r.id}" has min greater than max`)}return t}const _e=(0,f.promisify)(c.default.writeFile);async function ve(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`Condition not met, skipping create task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file);if(c.default.existsSync(n)){x(`File already exists, skipping: ${e.file}`,`info`);return}let r=e.template!=null&&e.template!==``,i=e.templateFile!=null&&e.templateFile!==``;if(!r&&!i)throw Error(`Create task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(r&&i)throw Error(`Create 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=S(c.default.readFileSync(r,`utf-8`),t)}else a=S(e.template,t);let o=l.default.dirname(n);c.default.existsSync(o)||c.default.mkdirSync(o,{recursive:!0}),await _e(n,a),x(`Created file: ${e.file}`,`success`)}const ye={name:`create`,version:`1.0.0`,taskTypes:[`create`],execute:async(e,t,n)=>{n.dryRun||await ve(e.config,t)}};async function be(e,t){let{paths:n,condition:r}=e;if(r!=null&&r!==``){if(!t){x(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!w(r,t)){x(`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})}}const xe={name:`delete`,version:`1.0.0`,taskTypes:[`delete`],execute:async(e,t,n)=>{n.dryRun||await be(e.config,t)}};async function Se(e,t){if(e.condition!=null&&e.condition!==``){if(!t){x(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!w(e.condition,t)){x(`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`})}const Ce={name:`exec`,version:`1.0.0`,taskTypes:[`exec`],execute:async(e,t,n)=>{n.dryRun||await Se(e.config,t)}};async function we(e,t){if(e.condition!=null&&e.condition!==``){if(!t){x(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!w(e.condition,t)){x(`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`})}}const Te={name:`git-init`,version:`1.0.0`,taskTypes:[`git-init`],execute:async(e,t,n)=>{n.dryRun||await we(e.config,t)}},Ee=(0,f.promisify)(c.default.readFile),De=(0,f.promisify)(c.default.writeFile);async function Oe(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`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 Ee(n,`utf-8`),s=new RegExp(r,i);o=o.replace(s,S(a,t)),await De(n,o)}const ke={name:`regex-replace`,version:`1.0.0`,taskTypes:[`regex-replace`],execute:async(e,t,n)=>{n.dryRun||await Oe(e.config,t)}},Ae=(0,f.promisify)(c.default.rename);async function je(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`Condition not met, skipping rename task`,`info`);return}let n=l.default.join(u.default.cwd(),S(e.from,t)),r=l.default.join(u.default.cwd(),S(e.to,t));if(!c.default.existsSync(n)){x(`Source path does not exist: ${n}`,`warn`);return}await Ae(n,r)}const Me={name:`rename`,version:`1.0.0`,taskTypes:[`rename`],execute:async(e,t,n)=>{n.dryRun||await je(e.config,t)}},Ne=(0,f.promisify)(c.default.readFile),Pe=(0,f.promisify)(c.default.writeFile);async function Fe(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`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)){x(`File not found: ${n}, skipping`,`warn`);return}let i=await Ne(n,`utf-8`);for(let{find:e,replace:n}of r){let r=S(n,t);i=i.replace(new RegExp(e,`gu`),r)}await Pe(n,i)}const Ie={name:`replace-in-file`,version:`1.0.0`,taskTypes:[`replace-in-file`],execute:async(e,t,n)=>{n.dryRun||await Fe(e.config,t)}},J=(0,f.promisify)(c.default.readFile);function Y(e){try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}}function X(e,t){if(Y(e))return e;if(t==null||t===``)return l.default.isAbsolute(e)?e:l.default.resolve(u.default.cwd(),e);if(Y(t))try{let n=new URL(`.`,t);return new URL(e,n).href}catch{throw Error(`Failed to resolve templateFile "${e}" relative to remote template "${t}"`)}let n=l.default.dirname(t);return l.default.isAbsolute(e)?e:l.default.resolve(n,e)}async function Le(e){if(Y(e))return Re(e);if(!c.default.existsSync(e))throw Error(`Template file not found: ${e}`);return J(e,`utf-8`)}async function Re(e){try{let t=await fetch(e);if(!t.ok)throw Error(`Failed to fetch template from ${e}: ${t.status} ${t.statusText}`);return await t.text()}catch(t){throw t instanceof Error&&t.message.includes(`Failed to fetch`)?t:Error(`Failed to fetch template from ${e}: ${t instanceof Error?t.message:String(t)}`)}}const Z=new Map;async function ze(e,t=new Set){let n=Y(e),r;if(r=n||l.default.isAbsolute(e)?e:l.default.resolve(u.default.cwd(),e),Z.has(r))return Z.get(r);if(t.has(r))throw Error(`Circular dependency detected: ${Array.from(t).join(` -> `)} -> ${r}`);t.add(r);let i;if(n)i=await Re(r);else{if(!c.default.existsSync(r))throw Error(`Template file not found: ${r}`);i=await J(r,`utf-8`)}let a;try{a=JSON.parse(i)}catch(e){throw Error(`Failed to parse template file ${r}: ${e instanceof Error?e.message:String(e)}`)}if(a.tasks!==void 0&&!Array.isArray(a.tasks))throw TypeError(`Invalid template file ${r}: 'tasks' must be an array if provided`);a.tasks===void 0&&(a.tasks=[]);for(let e of a.tasks)e.$sourceUrl=r;return Z.set(r,a),a}async function Q(e,t,n=new Set){let r=Y(e),i;if(i=r||l.default.isAbsolute(e)?e:t==null?l.default.resolve(u.default.cwd(),e):Y(t)?new URL(e,t).href:l.default.resolve(t,e),n.has(i))throw Error(`Circular dependency detected: ${Array.from(n).join(` -> `)} -> ${i}`);n.add(i);let a=await ze(i);if(a.extends==null||a.extends===``)return a;let o=Y(i)?new URL(`.`,i).href:l.default.dirname(i),s=Array.isArray(a.extends)?a.extends:[a.extends],c=[];for(let e of s){let t=await Q(e,o,n);c.push(t)}return Be([...c,a])}function Be(e){if(e.length===0)return{tasks:[]};if(e.length===1)return e[0];let t=new Map,n=new Map,r=new Map;for(let i of e){if(i.prompts!=null)for(let e of i.prompts)r.set(e.id,{...e});if(i.variables!=null)for(let e of i.variables)n.set(e.id,{...e});for(let e of i.tasks??[])if(t.has(e.id)){let n=t.get(e.id);t.set(e.id,Ve(n,e))}else t.set(e.id,{...e})}let i={tasks:Array.from(t.values())};return r.size>0&&(i.prompts=Array.from(r.values())),n.size>0&&(i.variables=Array.from(n.values())),i}function Ve(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.variables?[...e.variables]:void 0;if(t.variables&&t.variables.length>0)if(!i)i=[...t.variables];else{let e=new Map(i.map(e=>[e.id,e]));for(let n of t.variables)e.set(n.id,n);i=Array.from(e.values())}let a=[...e.dependencies??[],...t.dependencies??[]],o=a.length>0?[...new Set(a)]:void 0,s=t.$sourceUrl??e.$sourceUrl;return{...e,...t,config:n,...r!=null&&{prompts:r},...i!=null&&{variables:i},...o!=null&&{dependencies:o},...s!=null&&{$sourceUrl:s}}}function He(){Z.clear()}async function Ue(e){x(`Loading tasks from ${e}...`,`info`);let t=await Q(e);x(`Loaded ${t.tasks?.length??0} task(s)`,`info`),t.extends!=null&&t.extends!==``&&x(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.prompts!=null&&t.prompts.length>0&&x(`Found ${t.prompts.length} top-level prompt(s)`,`info`),t.variables!=null&&t.variables.length>0&&x(`Found ${t.variables.length} top-level variable(s)`,`info`);let n={tasks:t.tasks??[]};return t.prompts!=null&&(n.prompts=t.prompts),t.variables!=null&&(n.variables=t.variables),n}const We=(0,f.promisify)(c.default.writeFile);async function Ge(e,t,n){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`Condition not met, skipping template task`,`info`);return}let r=l.default.join(u.default.cwd(),e.file),i=e.template!=null&&e.template!==``,a=e.templateFile!=null&&e.templateFile!==``;if(!i&&!a)throw Error(`Template task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(i&&a)throw Error(`Template task cannot have both "template" and "templateFile" specified. Use one or the other.`);let o;if(a&&e.templateFile.endsWith(`.hbs`)){let r=await Le(X(e.templateFile,n?.$sourceUrl));o=(await import(`handlebars`)).default.compile(r)(t)}else o=S(a?await Le(X(e.templateFile,n?.$sourceUrl)):e.template,t);await We(r,o)}const Ke={name:`template`,version:`1.0.0`,taskTypes:[`template`],execute:async(e,t,n)=>{n.dryRun||await Ge(e.config,t,e)}},qe=(0,f.promisify)(c.default.readFile),Je=(0,f.promisify)(c.default.writeFile),Ye=2;async function Xe(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`Condition not met, skipping update-json task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{updates:r}=e,i=await qe(n,`utf-8`),a=JSON.parse(i);function o(e){if(typeof e==`string`)return S(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(`.`)?C(a,e,n):a[e]=n}await Je(n,`${JSON.stringify(a,null,2)}\n`)}const Ze={name:`update-json`,version:`1.0.0`,taskTypes:[`update-json`],execute:async(e,t,n)=>{n.dryRun||await Xe(e.config,t)}};let Qe=!1;function $e(){Qe||=(z(Ze),z(Ke),z(ye),z(ke),z(Ie),z(xe),z(Me),z(Te),z(Ce),!0)}async function et(e,t,n=!1){if($e(),n){x(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(V(e.type)){await U(e,t,{dryRun:n});return}throw TypeError(`Unknown task type: ${e.type}`)}async function tt(e,t,n,r,i=!1){try{return x(`[${n}/${r}] Running: ${e.name}...`,`info`),await et(e,t,i),x(`✓ ${e.name}`,`success`),!0}catch(t){return x(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(x(` Reason: ${t.message}`,`error`),t.stack!=null&&u.default.env.DEBUG!=null&&console.error(t.stack)),e.required&&x(` This is a required task. Initialization cannot continue.`,`error`),!1}}function $(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}function nt(e,t=new Map){let n={};for(let r of e){let e=t.get(r.id);e!==void 0&&(n[r.id]=e)}return n}async function rt(e,t){if(e==null)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`exec`){let e=n.value;if(typeof e!=`string`){x(`Variable "${t}": exec 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){x(`Variable "${t}": failed to execute command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`static`)return n.value;return e}async function it(e){let t=new Map,n=e.map(async e=>{let t=await rt(e.value,e.id);return{id:e.id,value:t}}),r=await Promise.all(n);for(let e of r)e.value!==void 0&&t.set(e.id,e.value);return t}function at(e){let t=[],n=new Set;for(let r of e)if(n.has(r.id)&&t.push(`Duplicate variable ID: "${r.id}"`),n.add(r.id),/^[\w$]+$/u.test(r.id)||t.push(`Variable ID "${r.id}" is invalid. Must contain only letters, numbers, underscore, or dollar sign.`),r.value===void 0||r.value===null)t.push(`Variable "${r.id}" must have a value`);else if(typeof r.value==`object`&&!Array.isArray(r.value)&&r.value!==null){let e=r.value;e.type==null||e.type===``?t.push(`Variable "${r.id}": value object must have a "type" field ("static" or "exec")`):e.type!==`static`&&e.type!==`exec`&&t.push(`Variable "${r.id}": type must be "static" or "exec", got "${e.type}"`),(e.value===void 0||e.value===null)&&t.push(`Variable "${r.id}": value config must have a "value" field`),e.type===`exec`&&typeof e.value!=`string`&&t.push(`Variable "${r.id}": exec type must have a string command as value`)}return t}const ot=(0,f.promisify)(c.default.readFile);async function st(e,t){let n=e.filter(e=>_(e.enabled,g()));x(`Resolving task dependencies...`,`info`);let r=$(n);x(`Welcome! Let's execute your tasks.`,`info`),t.dryRun&&x(`🔍 DRY RUN MODE - No changes will be made`,`warn`),x(`This will execute your project tasks based on the defined configuration.`,`info`);let i=g(),a=t.globalVariables??[],o=[],s=[...a];for(let e of r)if(e.variables&&e.variables.length>0)for(let t of e.variables)o.push(t),s.push(t);if(s.length>0){let e=at(s);e.length>0&&(x(`❌ Variable validation errors:`,`error`),e.forEach(e=>x(` - ${e}`,`error`)),u.default.exit(1)),x(`Resolving variable values...`,`info`);let t=nt(s,await it(s));Object.assign(i,t),Object.keys(t).length>0&&x(`✓ Resolved ${Object.keys(t).length} variable(s)`,`success`)}let f=t.globalPrompts??[],p=[],m=[...f];for(let e of r)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)p.push(t),m.push(t);if(m.length>0){let e=q(m);e.length>0&&(x(`❌ Prompt validation errors:`,`error`),e.forEach(e=>x(` - ${e}`,`error`)),u.default.exit(1)),x(`Resolving prompt default values...`,`info`);let t=await K(m),n={};if(f.length>0&&(x(`📋 Top-level prompts (available to all tasks):`,`info`),n=await W(f,t,i),Object.assign(i,n)),p.length>0){f.length>0&&x(`📋 Task-specific prompts:`,`info`);let e=await W(p,t,i);Object.assign(i,e)}}let h=r.filter(e=>_(e.enabled,i));if(x(`${h.length} of ${r.length} task(s) enabled for execution`,`info`),t.dryRun){await F(h,i),x(`🔍 Dry run completed - no changes were made`,`info`),x(`Run without --dry-run to apply changes`,`info`);return}x(`Starting task execution...`,`info`),await H(`beforeAll`,i);let v=h.length,y=0,S=0,C=[];for(let e=0;e<h.length;e++){let n=h[e];if(n!=null)if(await H(`beforeTask`,n,i),await tt(n,i,e+1,v,t.dryRun))y++,C.push(n.id),await H(`afterTask`,n,i);else if(n.required){S++,await H(`onError`,Error(`Task ${n.name} failed`),n);break}else x(`⚠️ Non-critical task failed, continuing...`,`warn`),await H(`onError`,Error(`Task ${n.name} failed`),n)}if(S>0&&(x(`❌ Task execution failed with ${S} critical error(s)`,`error`),x(`✓ Completed: ${y}/${v} tasks`,`info`),u.default.exit(1)),await H(`afterAll`,i),x(`✅ All tasks completed successfully!`,`success`),x(`✓ Completed: ${y}/${v} tasks`,`success`),!t.dryRun){x(`Next steps:`,`info`),x(`1. Review the changes made to your project`,`info`),x(`2. Commit the changes to git`,`info`);let e=l.default.join(u.default.cwd(),`package.json`);c.default.existsSync(e)&&JSON.parse(await ot(e,`utf-8`)).scripts?.[`turbo:gen:init`]!=null&&(x(`3. Run "pnpm run turbo:gen:init" to create your first package`,`info`),await b(`Would you like to run turbo:gen:init now?`,!0)&&(x(`Running turbo:gen:init...`,`info`),(0,d.execSync)(`pnpm run turbo:gen:init`,{stdio:`inherit`})))}}const ct=u.default.argv.includes(`--dry-run`),lt=u.default.argv.includes(`--force`);async function ut(e){try{let t=e||[];t.length===0&&(x(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),x(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),u.default.exit(1)),await st(t,{dryRun:ct,force:lt,tasksFilePath:void 0})}catch(e){x(`❌ Task execution failed`,`error`),e instanceof Error?(x(`Error: ${e.message}`,`error`),u.default.env.DEBUG!=null&&console.error(e.stack)):console.error(e),u.default.exit(1)}}async function dt(e,t){try{await st(e,{dryRun:t?.dryRun??ct,force:t?.force??lt,tasksFilePath:t?.tasksFilePath??void 0,...t?.globalVariables!=null&&{globalVariables:t.globalVariables},...t?.globalPrompts!=null&&{globalPrompts:t.globalPrompts}})}catch(e){x(`❌ Task execution failed`,`error`),e instanceof Error?(x(`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 le}}),Object.defineProperty(exports,`B`,{enumerable:!0,get:function(){return ae}}),Object.defineProperty(exports,`C`,{enumerable:!0,get:function(){return ue}}),Object.defineProperty(exports,`D`,{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,`E`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`F`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`G`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`H`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`I`,{enumerable:!0,get:function(){return se}}),Object.defineProperty(exports,`J`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`K`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`L`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`M`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`N`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`O`,{enumerable:!0,get:function(){return pe}}),Object.defineProperty(exports,`P`,{enumerable:!0,get:function(){return ce}}),Object.defineProperty(exports,`R`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`T`,{enumerable:!0,get:function(){return me}}),Object.defineProperty(exports,`U`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`V`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`W`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`Y`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return rt}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return et}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return Ue}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return it}}),Object.defineProperty(exports,`j`,{enumerable:!0,get:function(){return he}}),Object.defineProperty(exports,`k`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return tt}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return Be}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return dt}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return nt}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return ze}}),Object.defineProperty(exports,`q`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return at}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return ut}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return He}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`w`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`z`,{enumerable:!0,get:function(){return P}});
@@ -1,17 +0,0 @@
1
- import e from"node:path";import t from"node:fs";import n from"node:process";import{execSync as r}from"node:child_process";import{promisify as i}from"node:util";import a from"node:readline";import o from"handlebars";import{confirm as s,input as c,number as l,password as u,select as d}from"@inquirer/prompts";function f(){return{}}function p(e,t){return e===void 0?!0:typeof e==`boolean`?e:typeof e==`object`&&`condition`in e?b(e.condition,t):!1}function m(){try{let e=r(`git remote get-url origin`,{encoding:`utf-8`}).trim(),t=e.match(/github\.com[:/](?<owner>[^/]+)\/(?<name>[^/]+)$/u);if(t?.groups){let{owner:n,name:r}=t.groups,i=r;return i.endsWith(`.git`)&&(i=i.slice(0,-4)),{owner:n,name:i,url:e}}return null}catch{return null}}async function h(e,t){let r=a.createInterface({input:n.stdin,output:n.stdout});return new Promise(n=>{let i;i=t==null?`${e}: `:`${e} (${t}): `,r.question(i,e=>{r.close(),n(e.trim()||(t??``))})})}async function g(e,t=!1){return h(`${e} (${t?`Y/n`:`y/N`})`,t?`y`:`n`).then(e=>e.toLowerCase()===`y`||e.toLowerCase()===`yes`)}function _(e,t=`info`){console.log(`${{info:`\x1B[36m`,success:`\x1B[32m`,error:`\x1B[31m`,warn:`\x1B[33m`}[t]}${{info:`ℹ`,success:`✓`,error:`✗`,warn:`⚠`}[t]} ${e}`)}function v(e,t){return e.replace(/\{\{(?<key>\w+)\}\}/gu,(e,n)=>t[n]?.toString()??``)}function y(e,t,n){let r=t.split(`.`),i=e;for(let e=0;e<r.length-1;e++){let t=r[e];t!=null&&t!==``&&((!(t in i)||typeof i[t]!=`object`||i[t]===null)&&(i[t]={}),i=i[t])}let a=r[r.length-1];a!=null&&a!==``&&(i[a]=n)}function b(e,t){try{let n={...t};return Function(...Object.keys(n),`'use strict'; return (${e})`)(...Object.values(n))}catch(t){return _(`Failed to evaluate condition: ${e}`,`warn`),t instanceof Error&&_(` Error: ${t.message}`,`warn`),!1}}function x(r,i){try{let a=e.isAbsolute(r)?r:e.join(n.cwd(),r);if(!t.existsSync(a))throw Error(`Template file not found: ${r}`);return S(t.readFileSync(a,`utf-8`),i)}catch(e){throw _(`Failed to read template file: ${r}`,`error`),e instanceof Error&&_(` Error: ${e.message}`,`error`),e}}function S(e,t){try{return o.compile(e)(t)}catch(e){throw _(`Failed to compile Handlebars template`,`error`),e instanceof Error&&_(` Error: ${e.message}`,`error`),e}}const C=i(t.readFile),w={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,cyan:`\x1B[36m`,gray:`\x1B[90m`};function T(e,t){switch(t){case`add`:return`${w.green}+ ${e}${w.reset}`;case`remove`:return`${w.red}- ${e}${w.reset}`;case`context`:return`${w.gray} ${e}${w.reset}`;default:return e}}function E(e,t){let n=e.split(`
2
- `),r=t.split(`
3
- `),i=[],a=Math.max(n.length,r.length);for(let e=0;e<a;e++){let t=n[e],a=r[e];t===a?t!==void 0&&i.push(T(t,`context`)):(t!==void 0&&i.push(T(t,`remove`)),a!==void 0&&i.push(T(a,`add`)))}return i}async function D(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${w.red}✗ File not found: ${r.file}${w.reset}`;try{let e=await C(a,`utf-8`),t=JSON.parse(e),n={...t};function o(e){if(typeof e==`string`)return v(e,i);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,n]of Object.entries(r.updates)){let r=o(n);e.includes(`.`)?y(t,e,r):t[e]=r}let s=JSON.stringify(n,null,2),c=JSON.stringify(t,null,2);if(s===c)return`${w.cyan}→ No changes${w.reset}`;let l=E(s,c);return`${w.blue}File: ${r.file}${w.reset}\n${l.join(`
4
- `)}`}catch(e){return`${w.red}✗ Error: ${e instanceof Error?e.message:String(e)}${w.reset}`}}async function O(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;if(r.template==null||r.template===``)return`${w.red}✗ No template content provided for file: ${r.file}${w.reset}`;let a=e.join(n.cwd(),r.file),o=v(r.template,i);if(!t.existsSync(a)){let e=o.split(`
5
- `).slice(0,10).join(`
6
- `),t=o.split(`
7
- `).length>10;return`${w.blue}File: ${r.file}${w.reset}\n${w.green}+ New file would be created${w.reset}\n${w.gray}Content preview:${w.reset}\n${e}${t?`
8
- ...`:``}`}try{let e=await C(a,`utf-8`);if(e===o)return`${w.cyan}→ No changes${w.reset}`;let t=E(e,o);return`${w.blue}File: ${r.file}${w.reset}\n${t.join(`
9
- `)}`}catch(e){return`${w.red}✗ Error: ${e instanceof Error?e.message:String(e)}${w.reset}`}}async function ee(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let a=e.join(n.cwd(),r.file);if(t.existsSync(a))return`${w.cyan}→ File already exists, would be skipped: ${r.file}${w.reset}`;let o=r.template!=null&&r.template!==``,s=r.templateFile!=null&&r.templateFile!==``;if(!o&&!s)return`${w.red}✗ No template content provided for file: ${r.file}${w.reset}`;try{let e;if(o)e=v(r.template,i);else return`${w.blue}File: ${r.file}${w.reset}\n${w.green}+ New file would be created from template: ${r.templateFile}${w.reset}`;let t=e.split(`
10
- `).slice(0,10).join(`
11
- `),n=e.split(`
12
- `).length>10;return`${w.blue}File: ${r.file}${w.reset}\n${w.green}+ New file would be created${w.reset}\n${w.gray}Content preview:${w.reset}\n${t}${n?`
13
- ...`:``}`}catch(e){return`${w.red}✗ Error: ${e instanceof Error?e.message:String(e)}${w.reset}`}}async function k(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${w.red}✗ File not found: ${r.file}${w.reset}`;try{let e=await C(a,`utf-8`),t=new RegExp(r.pattern,r.flags??`g`),n=v(r.replacement,i),o=e.replace(t,n);if(e===o)return`${w.cyan}→ No matches found${w.reset}`;let s=E(e,o);return`${w.blue}File: ${r.file}${w.reset}\n${s.join(`
14
- `)}`}catch(e){return`${w.red}✗ Error: ${e instanceof Error?e.message:String(e)}${w.reset}`}}async function A(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${w.red}✗ File not found: ${r.file}${w.reset}`;try{let e=await C(a,`utf-8`),t=e;for(let{find:t,replace:n}of r.replacements){let r=v(t,i),a=v(n,i);e=e.replace(r,a)}if(t===e)return`${w.cyan}→ No changes${w.reset}`;let n=E(t,e);return`${w.blue}File: ${r.file}${w.reset}\n${n.join(`
15
- `)}`}catch(e){return`${w.red}✗ Error: ${e instanceof Error?e.message:String(e)}${w.reset}`}}function j(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let a=r.paths.map(e=>v(e,i)).filter(r=>t.existsSync(e.join(n.cwd(),r)));return a.length===0?`${w.cyan}→ No files/directories to delete${w.reset}`:`${w.red}Would delete:${w.reset}\n${a.map(e=>`${w.red} - ${e}${w.reset}`).join(`
16
- `)}`}function M(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let a=v(r.from,i),o=v(r.to,i),s=e.join(n.cwd(),a),c=e.join(n.cwd(),o);return t.existsSync(s)?t.existsSync(c)?`${w.yellow}⚠ Destination already exists: ${o}${w.reset}\n${w.cyan}Would rename: ${a} → ${o}${w.reset}`:`${w.cyan}Would rename: ${a} → ${o}${w.reset}`:`${w.red}✗ Source not found: ${a}${w.reset}`}function te(r){if(r.condition!=null&&r.condition!==``)return`${w.yellow}⊘ Condition check skipped in dry-run${w.reset}`;let i=e.join(n.cwd(),`.git`),a=t.existsSync(i),o=[];if(r.removeExisting&&a&&o.push(`${w.red}Would remove existing .git directory${w.reset}`),o.push(`${w.green}Would initialize git repository${w.reset}`),r.initialCommit){let e=r.message??`Initial commit`;o.push(`${w.green}Would create initial commit: "${e}"${w.reset}`)}return o.join(`
17
- `)}function ne(e,t){if(e.condition!=null&&e.condition!==``&&!b(e.condition,t))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let r=v(e.command,t),i=e.cwd==null?n.cwd():v(e.cwd,t);return`${w.yellow}Would execute:${w.reset}\n${w.cyan} Command: ${r}${w.reset}\n${w.cyan} Working directory: ${i}${w.reset}`}async function re(e,t){try{switch(e.type){case`update-json`:return await D(e.config,t);case`template`:return await O(e.config,t);case`create`:return await ee(e.config,t);case`regex-replace`:return await k(e.config,t);case`replace-in-file`:return await A(e.config,t);case`delete`:return j(e.config,t);case`rename`:return M(e.config,t);case`git-init`:return te(e.config);case`exec`:return ne(e.config,t);default:{let t=e.type;return`${w.yellow}⚠ Diff not available for task type: ${t}${w.reset}`}}}catch(e){return`${w.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${w.reset}`}}async function N(e,t){console.log(`${w.blue}═══════════════════════════════════════════════════════${w.reset}`),console.log(`${w.blue} DRY RUN - Preview of changes${w.reset}`),console.log(`${w.blue}═══════════════════════════════════════════════════════${w.reset}`);for(let n of e){console.log(`${w.cyan}▶ Task: ${n.name}${w.reset}`),console.log(`${w.gray} ${n.description}${w.reset}`);let e=await re(n,t);console.log(e),console.log(`${w.gray}${`─`.repeat(55)}${w.reset}`)}console.log(`${w.blue}═══════════════════════════════════════════════════════${w.reset}`),console.log(`${w.yellow} No changes were applied (dry-run mode)${w.reset}`),console.log(`${w.blue}═══════════════════════════════════════════════════════${w.reset}`)}const P=new Map,F={},I=new Map;function L(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(P.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(I.has(t)){let e=I.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}P.set(e.name,e);for(let t of e.taskTypes)I.set(t,e.name);_(`✓ Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`,`info`)}function ie(e){let t=P.get(e);if(t!=null){for(let e of t.taskTypes)I.delete(e);P.delete(e)}}function ae(e){return P.get(e)}function R(e){let t=I.get(e);if(t!=null)return P.get(t)}function z(e){return I.has(e)}function oe(){return Array.from(P.keys())}function se(){P.clear(),I.clear()}function ce(e){e.beforeAll!=null&&(F.beforeAll=e.beforeAll),e.afterAll!=null&&(F.afterAll=e.afterAll),e.beforeTask!=null&&(F.beforeTask=e.beforeTask),e.afterTask!=null&&(F.afterTask=e.afterTask),e.onError!=null&&(F.onError=e.onError)}async function B(e,...t){let n=F[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){_(`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 le(e,t){let n=R(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function ue(e){let t=R(e.type);return t==null?[`No plugin found for task type: ${e.type}`]:t.validate==null?[]:t.validate(e)}function de(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,n={}){let r={};if(e.length===0)return r;for(let i of e){let e={...n,...r};if(p(i.enabled,e))try{let e,n=t.get(i.id);switch(i.type){case`input`:{let t={message:i.message};if(n!==void 0&&(t.default=String(n)),i.required!==void 0&&(t.required=i.required),e=await c(t),i.required&&(e==null||typeof e==`string`&&e.trim()===``))throw _(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break}case`password`:if(e=await u({message:i.message,mask:`*`}),i.required&&(e==null||typeof e==`string`&&e.trim()===``))throw _(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break;case`number`:{let t={message:i.message};if(n!==void 0&&(t.default=Number(n)),i.required!==void 0&&(t.required=i.required),i.min!==void 0&&(t.min=i.min),i.max!==void 0&&(t.max=i.max),e=await l(t),i.required&&e==null)throw _(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break}case`select`:{let t={message:i.message,choices:i.choices.map(e=>({name:e.name,value:e.value}))};n!==void 0&&(t.default=n),e=await d(t);break}case`confirm`:{let t=n===void 0?!1:!!n;e=await s({message:i.message,default:t});break}default:throw _(`Unknown prompt type: ${i.type}`,`error`),Error(`Unknown prompt type: ${i.type}`)}r[i.id]=e}catch(e){throw e instanceof Error&&_(`Failed to collect prompt "${i.id}": ${e.message}`,`error`),e}}return r}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===`exec`){let e=n.value;if(typeof e!=`string`){_(`Prompt "${t}": exec 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){_(`Prompt "${t}": failed to execute default value command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`static`)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;for(let r of e){if(n.has(r.id)&&t.push(`Duplicate prompt ID: ${r.id}`),n.add(r.id),/^[\w-]+$/u.test(r.id)||t.push(`Invalid prompt ID "${r.id}": must contain only alphanumeric characters, underscores, and hyphens`),(!r.message||r.message.trim()===``)&&t.push(`Prompt "${r.id}" must have a non-empty message`),r.type===`select`){r.choices.length===0&&t.push(`Select prompt "${r.id}" must have at least one choice`);for(let e of r.choices)(!e.name||e.name.trim()===``)&&t.push(`Select prompt "${r.id}" has a choice with empty name`),e.value===void 0&&t.push(`Select prompt "${r.id}" has a choice with undefined value`)}r.type===`number`&&r.min!==void 0&&r.max!==void 0&&r.min>r.max&&t.push(`Number prompt "${r.id}" has min greater than max`)}return t}const fe=i(t.writeFile);async function pe(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i)){_(`Condition not met, skipping create task`,`info`);return}let a=e.join(n.cwd(),r.file);if(t.existsSync(a)){_(`File already exists, skipping: ${r.file}`,`info`);return}let o=r.template!=null&&r.template!==``,s=r.templateFile!=null&&r.templateFile!==``;if(!o&&!s)throw Error(`Create task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(o&&s)throw Error(`Create task cannot have both "template" and "templateFile" specified. Use one or the other.`);let c;if(s&&r.templateFile.endsWith(`.hbs`))c=x(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=v(t.readFileSync(o,`utf-8`),i)}else c=v(r.template,i);let l=e.dirname(a);t.existsSync(l)||t.mkdirSync(l,{recursive:!0}),await fe(a,c),_(`Created file: ${r.file}`,`success`)}const me={name:`create`,version:`1.0.0`,taskTypes:[`create`],execute:async(e,t,n)=>{n.dryRun||await pe(e.config,t)}};async function he(r,i){let{paths:a,condition:o}=r;if(o!=null&&o!==``){if(!i){_(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!b(o,i)){_(`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})}}const ge={name:`delete`,version:`1.0.0`,taskTypes:[`delete`],execute:async(e,t,n)=>{n.dryRun||await he(e.config,t)}};async function _e(t,i){if(t.condition!=null&&t.condition!==``){if(!i){_(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!b(t.condition,i)){_(`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`})}const ve={name:`exec`,version:`1.0.0`,taskTypes:[`exec`],execute:async(e,t,n)=>{n.dryRun||await _e(e.config,t)}};async function ye(i,a){if(i.condition!=null&&i.condition!==``){if(!a){_(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!b(i.condition,a)){_(`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`})}}const be={name:`git-init`,version:`1.0.0`,taskTypes:[`git-init`],execute:async(e,t,n)=>{n.dryRun||await ye(e.config,t)}},xe=i(t.readFile),Se=i(t.writeFile);async function Ce(t,r){if(t.condition!=null&&t.condition!==``&&!b(t.condition,r)){_(`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 xe(i,`utf-8`),l=new RegExp(a,o);c=c.replace(l,v(s,r)),await Se(i,c)}const we={name:`regex-replace`,version:`1.0.0`,taskTypes:[`regex-replace`],execute:async(e,t,n)=>{n.dryRun||await Ce(e.config,t)}},Te=i(t.rename);async function Ee(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i)){_(`Condition not met, skipping rename task`,`info`);return}let a=e.join(n.cwd(),v(r.from,i)),o=e.join(n.cwd(),v(r.to,i));if(!t.existsSync(a)){_(`Source path does not exist: ${a}`,`warn`);return}await Te(a,o)}const De={name:`rename`,version:`1.0.0`,taskTypes:[`rename`],execute:async(e,t,n)=>{n.dryRun||await Ee(e.config,t)}},Oe=i(t.readFile),ke=i(t.writeFile);async function Ae(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i)){_(`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)){_(`File not found: ${a}, skipping`,`warn`);return}let s=await Oe(a,`utf-8`);for(let{find:e,replace:t}of o){let n=v(t,i);s=s.replace(new RegExp(e,`gu`),n)}await ke(a,s)}const je={name:`replace-in-file`,version:`1.0.0`,taskTypes:[`replace-in-file`],execute:async(e,t,n)=>{n.dryRun||await Ae(e.config,t)}},K=i(t.readFile);function q(e){try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}}function J(t,r){if(q(t))return t;if(r==null||r===``)return e.isAbsolute(t)?t:e.resolve(n.cwd(),t);if(q(r))try{let e=new URL(`.`,r);return new URL(t,e).href}catch{throw Error(`Failed to resolve templateFile "${t}" relative to remote template "${r}"`)}let i=e.dirname(r);return e.isAbsolute(t)?t:e.resolve(i,t)}async function Y(e){if(q(e))return X(e);if(!t.existsSync(e))throw Error(`Template file not found: ${e}`);return K(e,`utf-8`)}async function X(e){try{let t=await fetch(e);if(!t.ok)throw Error(`Failed to fetch template from ${e}: ${t.status} ${t.statusText}`);return await t.text()}catch(t){throw t instanceof Error&&t.message.includes(`Failed to fetch`)?t:Error(`Failed to fetch template from ${e}: ${t instanceof Error?t.message:String(t)}`)}}const Z=new Map;async function Me(r,i=new Set){let a=q(r),o;if(o=a||e.isAbsolute(r)?r:e.resolve(n.cwd(),r),Z.has(o))return Z.get(o);if(i.has(o))throw Error(`Circular dependency detected: ${Array.from(i).join(` -> `)} -> ${o}`);i.add(o);let s;if(a)s=await X(o);else{if(!t.existsSync(o))throw Error(`Template file not found: ${o}`);s=await K(o,`utf-8`)}let c;try{c=JSON.parse(s)}catch(e){throw Error(`Failed to parse template file ${o}: ${e instanceof Error?e.message:String(e)}`)}if(c.tasks!==void 0&&!Array.isArray(c.tasks))throw TypeError(`Invalid template file ${o}: 'tasks' must be an array if provided`);c.tasks===void 0&&(c.tasks=[]);for(let e of c.tasks)e.$sourceUrl=o;return Z.set(o,c),c}async function Q(t,r,i=new Set){let a=q(t),o;if(o=a||e.isAbsolute(t)?t:r==null?e.resolve(n.cwd(),t):q(r)?new URL(t,r).href:e.resolve(r,t),i.has(o))throw Error(`Circular dependency detected: ${Array.from(i).join(` -> `)} -> ${o}`);i.add(o);let s=await Me(o);if(s.extends==null||s.extends===``)return s;let c=q(o)?new URL(`.`,o).href:e.dirname(o),l=Array.isArray(s.extends)?s.extends:[s.extends],u=[];for(let e of l){let t=await Q(e,c,i);u.push(t)}return Ne([...u,s])}function Ne(e){if(e.length===0)return{tasks:[]};if(e.length===1)return e[0];let t=new Map,n=new Map,r=new Map;for(let i of e){if(i.prompts!=null)for(let e of i.prompts)r.set(e.id,{...e});if(i.variables!=null)for(let e of i.variables)n.set(e.id,{...e});for(let e of i.tasks??[])if(t.has(e.id)){let n=t.get(e.id);t.set(e.id,Pe(n,e))}else t.set(e.id,{...e})}let i={tasks:Array.from(t.values())};return r.size>0&&(i.prompts=Array.from(r.values())),n.size>0&&(i.variables=Array.from(n.values())),i}function Pe(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.variables?[...e.variables]:void 0;if(t.variables&&t.variables.length>0)if(!i)i=[...t.variables];else{let e=new Map(i.map(e=>[e.id,e]));for(let n of t.variables)e.set(n.id,n);i=Array.from(e.values())}let a=[...e.dependencies??[],...t.dependencies??[]],o=a.length>0?[...new Set(a)]:void 0,s=t.$sourceUrl??e.$sourceUrl;return{...e,...t,config:n,...r!=null&&{prompts:r},...i!=null&&{variables:i},...o!=null&&{dependencies:o},...s!=null&&{$sourceUrl:s}}}function Fe(){Z.clear()}async function Ie(e){_(`Loading tasks from ${e}...`,`info`);let t=await Q(e);_(`Loaded ${t.tasks?.length??0} task(s)`,`info`),t.extends!=null&&t.extends!==``&&_(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.prompts!=null&&t.prompts.length>0&&_(`Found ${t.prompts.length} top-level prompt(s)`,`info`),t.variables!=null&&t.variables.length>0&&_(`Found ${t.variables.length} top-level variable(s)`,`info`);let n={tasks:t.tasks??[]};return t.prompts!=null&&(n.prompts=t.prompts),t.variables!=null&&(n.variables=t.variables),n}const Le=i(t.writeFile);async function Re(t,r,i){if(t.condition!=null&&t.condition!==``&&!b(t.condition,r)){_(`Condition not met, skipping template task`,`info`);return}let a=e.join(n.cwd(),t.file),o=t.template!=null&&t.template!==``,s=t.templateFile!=null&&t.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&&t.templateFile.endsWith(`.hbs`)){let e=await Y(J(t.templateFile,i?.$sourceUrl));c=(await import(`handlebars`)).default.compile(e)(r)}else c=v(s?await Y(J(t.templateFile,i?.$sourceUrl)):t.template,r);await Le(a,c)}const ze={name:`template`,version:`1.0.0`,taskTypes:[`template`],execute:async(e,t,n)=>{n.dryRun||await Re(e.config,t,e)}},Be=i(t.readFile),Ve=i(t.writeFile);async function He(t,r){if(t.condition!=null&&t.condition!==``&&!b(t.condition,r)){_(`Condition not met, skipping update-json task`,`info`);return}let i=e.join(n.cwd(),t.file),{updates:a}=t,o=await Be(i,`utf-8`),s=JSON.parse(o);function c(e){if(typeof e==`string`)return v(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(`.`)?y(s,e,n):s[e]=n}await Ve(i,`${JSON.stringify(s,null,2)}\n`)}const Ue={name:`update-json`,version:`1.0.0`,taskTypes:[`update-json`],execute:async(e,t,n)=>{n.dryRun||await He(e.config,t)}};let We=!1;function Ge(){We||=(L(Ue),L(ze),L(me),L(we),L(je),L(ge),L(De),L(be),L(ve),!0)}async function Ke(e,t,n=!1){if(Ge(),n){_(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(z(e.type)){await V(e,t,{dryRun:n});return}throw TypeError(`Unknown task type: ${e.type}`)}async function qe(e,t,r,i,a=!1){try{return _(`[${r}/${i}] Running: ${e.name}...`,`info`),await Ke(e,t,a),_(`✓ ${e.name}`,`success`),!0}catch(t){return _(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(_(` Reason: ${t.message}`,`error`),t.stack!=null&&n.env.DEBUG!=null&&console.error(t.stack)),e.required&&_(` This is a required task. Initialization cannot continue.`,`error`),!1}}function Je(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}function $(e,t=new Map){let n={};for(let r of e){let e=t.get(r.id);e!==void 0&&(n[r.id]=e)}return n}async function Ye(e,t){if(e==null)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`exec`){let e=n.value;if(typeof e!=`string`){_(`Variable "${t}": exec 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){_(`Variable "${t}": failed to execute command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`static`)return n.value;return e}async function Xe(e){let t=new Map,n=e.map(async e=>{let t=await Ye(e.value,e.id);return{id:e.id,value:t}}),r=await Promise.all(n);for(let e of r)e.value!==void 0&&t.set(e.id,e.value);return t}function Ze(e){let t=[],n=new Set;for(let r of e)if(n.has(r.id)&&t.push(`Duplicate variable ID: "${r.id}"`),n.add(r.id),/^[\w$]+$/u.test(r.id)||t.push(`Variable ID "${r.id}" is invalid. Must contain only letters, numbers, underscore, or dollar sign.`),r.value===void 0||r.value===null)t.push(`Variable "${r.id}" must have a value`);else if(typeof r.value==`object`&&!Array.isArray(r.value)&&r.value!==null){let e=r.value;e.type==null||e.type===``?t.push(`Variable "${r.id}": value object must have a "type" field ("static" or "exec")`):e.type!==`static`&&e.type!==`exec`&&t.push(`Variable "${r.id}": type must be "static" or "exec", got "${e.type}"`),(e.value===void 0||e.value===null)&&t.push(`Variable "${r.id}": value config must have a "value" field`),e.type===`exec`&&typeof e.value!=`string`&&t.push(`Variable "${r.id}": exec type must have a string command as value`)}return t}const Qe=i(t.readFile);async function $e(i,a){let o=i.filter(e=>p(e.enabled,f()));_(`Resolving task dependencies...`,`info`);let s=Je(o);_(`Welcome! Let's execute your tasks.`,`info`),a.dryRun&&_(`🔍 DRY RUN MODE - No changes will be made`,`warn`),_(`This will execute your project tasks based on the defined configuration.`,`info`);let c=f(),l=a.globalVariables??[],u=[],d=[...l];for(let e of s)if(e.variables&&e.variables.length>0)for(let t of e.variables)u.push(t),d.push(t);if(d.length>0){let e=Ze(d);e.length>0&&(_(`❌ Variable validation errors:`,`error`),e.forEach(e=>_(` - ${e}`,`error`)),n.exit(1)),_(`Resolving variable values...`,`info`);let t=$(d,await Xe(d));Object.assign(c,t),Object.keys(t).length>0&&_(`✓ Resolved ${Object.keys(t).length} variable(s)`,`success`)}let m=a.globalPrompts??[],h=[],v=[...m];for(let e of s)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)h.push(t),v.push(t);if(v.length>0){let e=G(v);e.length>0&&(_(`❌ Prompt validation errors:`,`error`),e.forEach(e=>_(` - ${e}`,`error`)),n.exit(1)),_(`Resolving prompt default values...`,`info`);let t=await W(v),r={};if(m.length>0&&(_(`📋 Top-level prompts (available to all tasks):`,`info`),r=await H(m,t,c),Object.assign(c,r)),h.length>0){m.length>0&&_(`📋 Task-specific prompts:`,`info`);let e=await H(h,t,c);Object.assign(c,e)}}let y=s.filter(e=>p(e.enabled,c));if(_(`${y.length} of ${s.length} task(s) enabled for execution`,`info`),a.dryRun){await N(y,c),_(`🔍 Dry run completed - no changes were made`,`info`),_(`Run without --dry-run to apply changes`,`info`);return}_(`Starting task execution...`,`info`),await B(`beforeAll`,c);let b=y.length,x=0,S=0,C=[];for(let e=0;e<y.length;e++){let t=y[e];if(t!=null)if(await B(`beforeTask`,t,c),await qe(t,c,e+1,b,a.dryRun))x++,C.push(t.id),await B(`afterTask`,t,c);else if(t.required){S++,await B(`onError`,Error(`Task ${t.name} failed`),t);break}else _(`⚠️ Non-critical task failed, continuing...`,`warn`),await B(`onError`,Error(`Task ${t.name} failed`),t)}if(S>0&&(_(`❌ Task execution failed with ${S} critical error(s)`,`error`),_(`✓ Completed: ${x}/${b} tasks`,`info`),n.exit(1)),await B(`afterAll`,c),_(`✅ All tasks completed successfully!`,`success`),_(`✓ Completed: ${x}/${b} tasks`,`success`),!a.dryRun){_(`Next steps:`,`info`),_(`1. Review the changes made to your project`,`info`),_(`2. Commit the changes to git`,`info`);let i=e.join(n.cwd(),`package.json`);t.existsSync(i)&&JSON.parse(await Qe(i,`utf-8`)).scripts?.[`turbo:gen:init`]!=null&&(_(`3. Run "pnpm run turbo:gen:init" to create your first package`,`info`),await g(`Would you like to run turbo:gen:init now?`,!0)&&(_(`Running turbo:gen:init...`,`info`),r(`pnpm run turbo:gen:init`,{stdio:`inherit`})))}}const et=n.argv.includes(`--dry-run`),tt=n.argv.includes(`--force`);async function nt(e){try{let t=e||[];t.length===0&&(_(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),_(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),n.exit(1)),await $e(t,{dryRun:et,force:tt,tasksFilePath:void 0})}catch(e){_(`❌ Task execution failed`,`error`),e instanceof Error?(_(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}async function rt(e,t){try{await $e(e,{dryRun:t?.dryRun??et,force:t?.force??tt,tasksFilePath:t?.tasksFilePath??void 0,...t?.globalVariables!=null&&{globalVariables:t.globalVariables},...t?.globalPrompts!=null&&{globalPrompts:t.globalPrompts}})}catch(e){_(`❌ Task execution failed`,`error`),e instanceof Error?(_(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}export{ie as A,O as B,ae as C,oe as D,z as E,te as F,_ as G,b as H,k as I,y as J,h as K,M as L,N as M,j as N,ce as O,ne as P,A as R,V as S,le as T,m as U,D as V,v as W,U as _,Ye as a,se as b,Ke as c,Q as d,Ie as f,W as g,G as h,Xe as i,ue as j,L as k,qe as l,Ne as m,rt as n,$ as o,Me as p,g as q,Ze as r,Je as s,nt as t,Fe as u,H as v,R as w,de as x,B as y,re as z};