@pixpilot/scaffoldfy 0.9.0 → 0.11.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/README.md +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +6 -21
- package/dist/index.d.ts +6 -21
- package/dist/index.js +1 -1
- package/dist/src-DNF_Vtpw.cjs +17 -0
- package/dist/src-YxoIABRA.js +17 -0
- package/package.json +3 -3
- package/schema/tasks.schema.json +5 -6
- package/dist/src-DxvGGX8s.cjs +0 -17
- package/dist/src-IzX9FHaO.js +0 -17
package/README.md
CHANGED
package/dist/cli.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const e=require(`./src-
|
|
2
|
+
const e=require(`./src-DNF_Vtpw.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{
|
|
2
|
+
import{G as e,f as t,n}from"./src-YxoIABRA.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-
|
|
1
|
+
const e=require(`./src-DNF_Vtpw.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.d.cts
CHANGED
|
@@ -175,12 +175,7 @@ interface TaskDefinition {
|
|
|
175
175
|
rollback?: RollbackConfig;
|
|
176
176
|
prompts?: PromptDefinition[];
|
|
177
177
|
variables?: VariableDefinition[];
|
|
178
|
-
|
|
179
|
-
interface InitializationMetadata {
|
|
180
|
-
initializedAt: string;
|
|
181
|
-
config: InitConfig;
|
|
182
|
-
completedTasks: string[];
|
|
183
|
-
version: string;
|
|
178
|
+
$sourceUrl?: string;
|
|
184
179
|
}
|
|
185
180
|
/**
|
|
186
181
|
* Configuration file structure for template tasks
|
|
@@ -189,7 +184,7 @@ interface TasksConfiguration {
|
|
|
189
184
|
extends?: string | string[];
|
|
190
185
|
variables?: VariableDefinition[];
|
|
191
186
|
prompts?: PromptDefinition[];
|
|
192
|
-
tasks
|
|
187
|
+
tasks?: TaskDefinition[];
|
|
193
188
|
}
|
|
194
189
|
/**
|
|
195
190
|
* Plugin interface for custom task types
|
|
@@ -399,16 +394,6 @@ declare function resolveDefaultValue<T = string | number | boolean>(defaultValue
|
|
|
399
394
|
*/
|
|
400
395
|
declare function validatePrompts(prompts: PromptDefinition[]): string[];
|
|
401
396
|
//#endregion
|
|
402
|
-
//#region src/state.d.ts
|
|
403
|
-
/**
|
|
404
|
-
* Load initialization state from file
|
|
405
|
-
*/
|
|
406
|
-
declare function loadInitializationState(): InitializationMetadata | null;
|
|
407
|
-
/**
|
|
408
|
-
* Save initialization state to file
|
|
409
|
-
*/
|
|
410
|
-
declare function saveInitializationState(config: InitConfig, completedTasks: string[], dryRun?: boolean): void;
|
|
411
|
-
//#endregion
|
|
412
397
|
//#region src/task-executors.d.ts
|
|
413
398
|
/**
|
|
414
399
|
* Execute a task based on its type
|
|
@@ -536,16 +521,16 @@ declare function validateVariables(variables: VariableDefinition[]): string[];
|
|
|
536
521
|
//#endregion
|
|
537
522
|
//#region src/index.d.ts
|
|
538
523
|
/**
|
|
539
|
-
* Main function for
|
|
524
|
+
* Main function for executing tasks with default/empty tasks array
|
|
540
525
|
* For most use cases, you should use runWithTasks() with your custom tasks
|
|
541
526
|
*/
|
|
542
527
|
declare function main(customTasks?: TaskDefinition[]): Promise<void>;
|
|
543
528
|
/**
|
|
544
|
-
*
|
|
529
|
+
* Execute tasks with custom task definitions
|
|
545
530
|
* @param customTasks - Array of task definitions to execute
|
|
546
531
|
* @param options - Optional configuration
|
|
547
532
|
* @param options.dryRun - Preview changes without applying them
|
|
548
|
-
* @param options.force - Force
|
|
533
|
+
* @param options.force - Force execution even if checks fail
|
|
549
534
|
* @param options.tasksFilePath - Path to the tasks file
|
|
550
535
|
* @param options.globalVariables - Optional top-level global variables
|
|
551
536
|
* @param options.globalPrompts - Optional top-level global prompts
|
|
@@ -558,4 +543,4 @@ declare function runWithTasks(customTasks: TaskDefinition[], options?: {
|
|
|
558
543
|
globalPrompts?: PromptDefinition[] | undefined;
|
|
559
544
|
}): Promise<void>;
|
|
560
545
|
//#endregion
|
|
561
|
-
export { BasePrompt, ConditionExpression, ConditionalEnabled, ConfirmPrompt, type CreateConfig, DefaultValue, DefaultValueConfig, DefaultValueType, type DeleteConfig, EnabledValue, type ExecConfig, type GitInitConfig, InitConfig,
|
|
546
|
+
export { BasePrompt, ConditionExpression, ConditionalEnabled, ConfirmPrompt, type CreateConfig, DefaultValue, DefaultValueConfig, DefaultValueType, type DeleteConfig, EnabledValue, type ExecConfig, type GitInitConfig, InitConfig, InputPrompt, NumberPrompt, PluginHooks, PromptDefinition, PromptType, type RegexReplaceConfig, type RenameConfig, type ReplaceInFileConfig, RollbackConfig, SelectPrompt, TaskDefinition, TaskPlugin, TaskType, TasksConfiguration, type TemplateConfig, type UpdateJsonConfig, VariableDefinition, callHook, clearPlugins, clearTemplateCache, collectPrompts, collectVariables, createPlugin, displayTasksDiff, evaluateCondition, executePluginTask, executeTask, getDeleteDiff, getExecDiff, getGitInitDiff, getGitRepoInfo, getPlugin, getPluginForTaskType, getPluginTaskDiff, getRegexReplaceDiff, getRenameDiff, getReplaceInFileDiff, getTaskDiff, getTemplateDiff, getUpdateJsonDiff, interpolateTemplate, isPluginTaskType, listPlugins, loadAndMergeTemplate, loadTasksWithInheritance, loadTemplate, log, main, mergeTemplates, prompt, promptYesNo, registerHooks, registerPlugin, resolveAllDefaultValues, resolveAllVariableValues, resolveDefaultValue, resolveVariableValue, runTask, runWithTasks, setNestedProperty, topologicalSort, unregisterPlugin, validatePluginTask, validatePrompts, validateVariables };
|
package/dist/index.d.ts
CHANGED
|
@@ -175,12 +175,7 @@ interface TaskDefinition {
|
|
|
175
175
|
rollback?: RollbackConfig;
|
|
176
176
|
prompts?: PromptDefinition[];
|
|
177
177
|
variables?: VariableDefinition[];
|
|
178
|
-
|
|
179
|
-
interface InitializationMetadata {
|
|
180
|
-
initializedAt: string;
|
|
181
|
-
config: InitConfig;
|
|
182
|
-
completedTasks: string[];
|
|
183
|
-
version: string;
|
|
178
|
+
$sourceUrl?: string;
|
|
184
179
|
}
|
|
185
180
|
/**
|
|
186
181
|
* Configuration file structure for template tasks
|
|
@@ -189,7 +184,7 @@ interface TasksConfiguration {
|
|
|
189
184
|
extends?: string | string[];
|
|
190
185
|
variables?: VariableDefinition[];
|
|
191
186
|
prompts?: PromptDefinition[];
|
|
192
|
-
tasks
|
|
187
|
+
tasks?: TaskDefinition[];
|
|
193
188
|
}
|
|
194
189
|
/**
|
|
195
190
|
* Plugin interface for custom task types
|
|
@@ -399,16 +394,6 @@ declare function resolveDefaultValue<T = string | number | boolean>(defaultValue
|
|
|
399
394
|
*/
|
|
400
395
|
declare function validatePrompts(prompts: PromptDefinition[]): string[];
|
|
401
396
|
//#endregion
|
|
402
|
-
//#region src/state.d.ts
|
|
403
|
-
/**
|
|
404
|
-
* Load initialization state from file
|
|
405
|
-
*/
|
|
406
|
-
declare function loadInitializationState(): InitializationMetadata | null;
|
|
407
|
-
/**
|
|
408
|
-
* Save initialization state to file
|
|
409
|
-
*/
|
|
410
|
-
declare function saveInitializationState(config: InitConfig, completedTasks: string[], dryRun?: boolean): void;
|
|
411
|
-
//#endregion
|
|
412
397
|
//#region src/task-executors.d.ts
|
|
413
398
|
/**
|
|
414
399
|
* Execute a task based on its type
|
|
@@ -536,16 +521,16 @@ declare function validateVariables(variables: VariableDefinition[]): string[];
|
|
|
536
521
|
//#endregion
|
|
537
522
|
//#region src/index.d.ts
|
|
538
523
|
/**
|
|
539
|
-
* Main function for
|
|
524
|
+
* Main function for executing tasks with default/empty tasks array
|
|
540
525
|
* For most use cases, you should use runWithTasks() with your custom tasks
|
|
541
526
|
*/
|
|
542
527
|
declare function main(customTasks?: TaskDefinition[]): Promise<void>;
|
|
543
528
|
/**
|
|
544
|
-
*
|
|
529
|
+
* Execute tasks with custom task definitions
|
|
545
530
|
* @param customTasks - Array of task definitions to execute
|
|
546
531
|
* @param options - Optional configuration
|
|
547
532
|
* @param options.dryRun - Preview changes without applying them
|
|
548
|
-
* @param options.force - Force
|
|
533
|
+
* @param options.force - Force execution even if checks fail
|
|
549
534
|
* @param options.tasksFilePath - Path to the tasks file
|
|
550
535
|
* @param options.globalVariables - Optional top-level global variables
|
|
551
536
|
* @param options.globalPrompts - Optional top-level global prompts
|
|
@@ -558,4 +543,4 @@ declare function runWithTasks(customTasks: TaskDefinition[], options?: {
|
|
|
558
543
|
globalPrompts?: PromptDefinition[] | undefined;
|
|
559
544
|
}): Promise<void>;
|
|
560
545
|
//#endregion
|
|
561
|
-
export { BasePrompt, ConditionExpression, ConditionalEnabled, ConfirmPrompt, type CreateConfig, DefaultValue, DefaultValueConfig, DefaultValueType, type DeleteConfig, EnabledValue, type ExecConfig, type GitInitConfig, InitConfig,
|
|
546
|
+
export { BasePrompt, ConditionExpression, ConditionalEnabled, ConfirmPrompt, type CreateConfig, DefaultValue, DefaultValueConfig, DefaultValueType, type DeleteConfig, EnabledValue, type ExecConfig, type GitInitConfig, InitConfig, InputPrompt, NumberPrompt, PluginHooks, PromptDefinition, PromptType, type RegexReplaceConfig, type RenameConfig, type ReplaceInFileConfig, RollbackConfig, SelectPrompt, TaskDefinition, TaskPlugin, TaskType, TasksConfiguration, type TemplateConfig, type UpdateJsonConfig, VariableDefinition, callHook, clearPlugins, clearTemplateCache, collectPrompts, collectVariables, createPlugin, displayTasksDiff, evaluateCondition, executePluginTask, executeTask, getDeleteDiff, getExecDiff, getGitInitDiff, getGitRepoInfo, getPlugin, getPluginForTaskType, getPluginTaskDiff, getRegexReplaceDiff, getRenameDiff, getReplaceInFileDiff, getTaskDiff, getTemplateDiff, getUpdateJsonDiff, interpolateTemplate, isPluginTaskType, listPlugins, loadAndMergeTemplate, loadTasksWithInheritance, loadTemplate, log, main, mergeTemplates, prompt, promptYesNo, registerHooks, registerPlugin, resolveAllDefaultValues, resolveAllVariableValues, resolveDefaultValue, resolveVariableValue, runTask, runWithTasks, setNestedProperty, topologicalSort, unregisterPlugin, validatePluginTask, validatePrompts, validateVariables };
|
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,
|
|
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-YxoIABRA.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}[0m`)}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 Z(e);if(!c.default.existsSync(e))throw Error(`Template file not found: ${e}`);return q(e,`utf-8`)}async function Z(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 Q=new Map;async function Re(e,t=new Set){let n=J(e),r;if(r=n||l.default.isAbsolute(e)?e:l.default.resolve(u.default.cwd(),e),Q.has(r))return Q.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 Z(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 Q.set(r,a),a}async function $(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 Re(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 $(e,o,n);c.push(t)}return ze([...c,a])}function ze(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,Be(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 Be(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 Ve(){Q.clear()}async function He(e){b(`Loading tasks from ${e}...`,`info`);let t=await $(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 Ue=(0,d.promisify)(c.default.writeFile);async function We(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 Ue(r,o)}const Ge={name:`template`,version:`1.0.0`,taskTypes:[`template`],execute:async(e,t,n)=>{n.dryRun||await We(e.config,t,e)}},Ke=(0,d.promisify)(c.default.readFile),qe=(0,d.promisify)(c.default.writeFile),Je=2;async function Ye(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 Ke(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 qe(n,`${JSON.stringify(a,null,2)}\n`)}const Xe={name:`update-json`,version:`1.0.0`,taskTypes:[`update-json`],execute:async(e,t,n)=>{n.dryRun||await Ye(e.config,t)}};let Ze=!1;function Qe(){Ze||=(R(Xe),R(Ge),R(be),R(Ae),R(Le),R(Se),R(Ne),R(Ee),R(we),!0)}async function $e(e,t,n=!1){if(Qe(),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 et(e,t,n,r,i=!1){try{return b(`[${n}/${r}] Running: ${e.name}...`,`info`),await $e(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 tt(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`){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 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}async function ot(e,t){let n=e.filter(e=>_(e.enabled,g()));b(`Resolving task dependencies...`,`info`);let r=tt(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=at(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=nt(s,await it(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 et(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 st=u.default.argv.includes(`--dry-run`),ct=u.default.argv.includes(`--force`);async function lt(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 ot(t,{dryRun:st,force:ct,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 ut(e,t){try{await ot(e,{dryRun:t?.dryRun??st,force:t?.force??ct,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 rt}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return pe}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return $e}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return He}}),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 it}}),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 et}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return ze}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return ut}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return nt}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return Re}}),Object.defineProperty(exports,`q`,{enumerable:!0,get:function(){return ee}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return at}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return tt}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return lt}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return Ve}}),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 ee(){return{}}function f(e,t){return e===void 0?!0:typeof e==`boolean`?e:typeof e==`object`&&`condition`in e?y(e.condition,t):!1}function p(){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 m(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 h(e,t=!1){return m(`${e} (${t?`Y/n`:`y/N`})`,t?`y`:`n`).then(e=>e.toLowerCase()===`y`||e.toLowerCase()===`yes`)}function g(e,t=`info`){console.log(`${{info:`\x1B[36m`,success:`\x1B[32m`,error:`\x1B[31m`,warn:`\x1B[33m`}[t]}${{info:`ℹ`,success:`✓`,error:`✗`,warn:`⚠`}[t]} ${e}[0m`)}function _(e,t){return e.replace(/\{\{(?<key>\w+)\}\}/gu,(e,n)=>t[n]?.toString()??``)}function v(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 y(e,t){try{let n={...t};return Function(...Object.keys(n),`'use strict'; return (${e})`)(...Object.values(n))}catch(t){return g(`Failed to evaluate condition: ${e}`,`warn`),t instanceof Error&&g(` Error: ${t.message}`,`warn`),!1}}function te(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 ne(t.readFileSync(a,`utf-8`),i)}catch(e){throw g(`Failed to read template file: ${r}`,`error`),e instanceof Error&&g(` Error: ${e.message}`,`error`),e}}function ne(e,t){try{return o.compile(e)(t)}catch(e){throw g(`Failed to compile Handlebars template`,`error`),e instanceof Error&&g(` Error: ${e.message}`,`error`),e}}const b=r(t.readFile),x={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,cyan:`\x1B[36m`,gray:`\x1B[90m`};function S(e,t){switch(t){case`add`:return`${x.green}+ ${e}${x.reset}`;case`remove`:return`${x.red}- ${e}${x.reset}`;case`context`:return`${x.gray} ${e}${x.reset}`;default:return e}}function C(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(S(t,`context`)):(t!==void 0&&i.push(S(t,`remove`)),a!==void 0&&i.push(S(a,`add`)))}return i}async function w(r,i){if(r.condition!=null&&r.condition!==``&&!y(r.condition,i))return`${x.yellow}⊘ Condition not met - task would be skipped${x.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${x.red}✗ File not found: ${r.file}${x.reset}`;try{let e=await b(a,`utf-8`),t=JSON.parse(e),n={...t};function o(e){if(typeof e==`string`)return _(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(`.`)?v(t,e,r):t[e]=r}let s=JSON.stringify(n,null,2),c=JSON.stringify(t,null,2);if(s===c)return`${x.cyan}→ No changes${x.reset}`;let l=C(s,c);return`${x.blue}File: ${r.file}${x.reset}\n${l.join(`
|
|
4
|
+
`)}`}catch(e){return`${x.red}✗ Error: ${e instanceof Error?e.message:String(e)}${x.reset}`}}async function T(r,i){if(r.condition!=null&&r.condition!==``&&!y(r.condition,i))return`${x.yellow}⊘ Condition not met - task would be skipped${x.reset}`;if(r.template==null||r.template===``)return`${x.red}✗ No template content provided for file: ${r.file}${x.reset}`;let a=e.join(n.cwd(),r.file),o=_(r.template,i);if(!t.existsSync(a)){let e=o.split(`
|
|
5
|
+
`).slice(0,10).join(`
|
|
6
|
+
`),t=o.split(`
|
|
7
|
+
`).length>10;return`${x.blue}File: ${r.file}${x.reset}\n${x.green}+ New file would be created${x.reset}\n${x.gray}Content preview:${x.reset}\n${e}${t?`
|
|
8
|
+
...`:``}`}try{let e=await b(a,`utf-8`);if(e===o)return`${x.cyan}→ No changes${x.reset}`;let t=C(e,o);return`${x.blue}File: ${r.file}${x.reset}\n${t.join(`
|
|
9
|
+
`)}`}catch(e){return`${x.red}✗ Error: ${e instanceof Error?e.message:String(e)}${x.reset}`}}async function re(r,i){if(r.condition!=null&&r.condition!==``&&!y(r.condition,i))return`${x.yellow}⊘ Condition not met - task would be skipped${x.reset}`;let a=e.join(n.cwd(),r.file);if(t.existsSync(a))return`${x.cyan}→ File already exists, would be skipped: ${r.file}${x.reset}`;let o=r.template!=null&&r.template!==``,s=r.templateFile!=null&&r.templateFile!==``;if(!o&&!s)return`${x.red}✗ No template content provided for file: ${r.file}${x.reset}`;try{let e;if(o)e=_(r.template,i);else return`${x.blue}File: ${r.file}${x.reset}\n${x.green}+ New file would be created from template: ${r.templateFile}${x.reset}`;let t=e.split(`
|
|
10
|
+
`).slice(0,10).join(`
|
|
11
|
+
`),n=e.split(`
|
|
12
|
+
`).length>10;return`${x.blue}File: ${r.file}${x.reset}\n${x.green}+ New file would be created${x.reset}\n${x.gray}Content preview:${x.reset}\n${t}${n?`
|
|
13
|
+
...`:``}`}catch(e){return`${x.red}✗ Error: ${e instanceof Error?e.message:String(e)}${x.reset}`}}async function E(r,i){if(r.condition!=null&&r.condition!==``&&!y(r.condition,i))return`${x.yellow}⊘ Condition not met - task would be skipped${x.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${x.red}✗ File not found: ${r.file}${x.reset}`;try{let e=await b(a,`utf-8`),t=new RegExp(r.pattern,r.flags??`g`),n=_(r.replacement,i),o=e.replace(t,n);if(e===o)return`${x.cyan}→ No matches found${x.reset}`;let s=C(e,o);return`${x.blue}File: ${r.file}${x.reset}\n${s.join(`
|
|
14
|
+
`)}`}catch(e){return`${x.red}✗ Error: ${e instanceof Error?e.message:String(e)}${x.reset}`}}async function D(r,i){if(r.condition!=null&&r.condition!==``&&!y(r.condition,i))return`${x.yellow}⊘ Condition not met - task would be skipped${x.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${x.red}✗ File not found: ${r.file}${x.reset}`;try{let e=await b(a,`utf-8`),t=e;for(let{find:t,replace:n}of r.replacements){let r=_(t,i),a=_(n,i);e=e.replace(r,a)}if(t===e)return`${x.cyan}→ No changes${x.reset}`;let n=C(t,e);return`${x.blue}File: ${r.file}${x.reset}\n${n.join(`
|
|
15
|
+
`)}`}catch(e){return`${x.red}✗ Error: ${e instanceof Error?e.message:String(e)}${x.reset}`}}function O(r,i){if(r.condition!=null&&r.condition!==``&&!y(r.condition,i))return`${x.yellow}⊘ Condition not met - task would be skipped${x.reset}`;let a=r.paths.map(e=>_(e,i)).filter(r=>t.existsSync(e.join(n.cwd(),r)));return a.length===0?`${x.cyan}→ No files/directories to delete${x.reset}`:`${x.red}Would delete:${x.reset}\n${a.map(e=>`${x.red} - ${e}${x.reset}`).join(`
|
|
16
|
+
`)}`}function k(r,i){if(r.condition!=null&&r.condition!==``&&!y(r.condition,i))return`${x.yellow}⊘ Condition not met - task would be skipped${x.reset}`;let a=_(r.from,i),o=_(r.to,i),s=e.join(n.cwd(),a),c=e.join(n.cwd(),o);return t.existsSync(s)?t.existsSync(c)?`${x.yellow}⚠ Destination already exists: ${o}${x.reset}\n${x.cyan}Would rename: ${a} → ${o}${x.reset}`:`${x.cyan}Would rename: ${a} → ${o}${x.reset}`:`${x.red}✗ Source not found: ${a}${x.reset}`}function A(r){if(r.condition!=null&&r.condition!==``)return`${x.yellow}⊘ Condition check skipped in dry-run${x.reset}`;let i=e.join(n.cwd(),`.git`),a=t.existsSync(i),o=[];if(r.removeExisting&&a&&o.push(`${x.red}Would remove existing .git directory${x.reset}`),o.push(`${x.green}Would initialize git repository${x.reset}`),r.initialCommit){let e=r.message??`Initial commit`;o.push(`${x.green}Would create initial commit: "${e}"${x.reset}`)}return o.join(`
|
|
17
|
+
`)}function j(e,t){if(e.condition!=null&&e.condition!==``&&!y(e.condition,t))return`${x.yellow}⊘ Condition not met - task would be skipped${x.reset}`;let r=_(e.command,t),i=e.cwd==null?n.cwd():_(e.cwd,t);return`${x.yellow}Would execute:${x.reset}\n${x.cyan} Command: ${r}${x.reset}\n${x.cyan} Working directory: ${i}${x.reset}`}async function M(e,t){try{switch(e.type){case`update-json`:return await w(e.config,t);case`template`:return await T(e.config,t);case`create`:return await re(e.config,t);case`regex-replace`:return await E(e.config,t);case`replace-in-file`:return await D(e.config,t);case`delete`:return O(e.config,t);case`rename`:return k(e.config,t);case`git-init`:return A(e.config);case`exec`:return j(e.config,t);default:{let t=e.type;return`${x.yellow}⚠ Diff not available for task type: ${t}${x.reset}`}}}catch(e){return`${x.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${x.reset}`}}async function ie(e,t){console.log(`${x.blue}═══════════════════════════════════════════════════════${x.reset}`),console.log(`${x.blue} DRY RUN - Preview of changes${x.reset}`),console.log(`${x.blue}═══════════════════════════════════════════════════════${x.reset}`);for(let n of e){console.log(`${x.cyan}▶ Task: ${n.name}${x.reset}`),console.log(`${x.gray} ${n.description}${x.reset}`);let e=await M(n,t);console.log(e),console.log(`${x.gray}${`─`.repeat(55)}${x.reset}`)}console.log(`${x.blue}═══════════════════════════════════════════════════════${x.reset}`),console.log(`${x.yellow} No changes were applied (dry-run mode)${x.reset}`),console.log(`${x.blue}═══════════════════════════════════════════════════════${x.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);g(`✓ 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){g(`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(f(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 g(`${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 g(`${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 g(`${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 g(`Unknown prompt type: ${i.type}`,`error`),Error(`Unknown prompt type: ${i.type}`)}r[i.id]=e}catch(e){throw e instanceof Error&&g(`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`){g(`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){g(`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!==``&&!y(r.condition,i)){g(`Condition not met, skipping create task`,`info`);return}let a=e.join(n.cwd(),r.file);if(t.existsSync(a)){g(`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=te(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=_(t.readFileSync(o,`utf-8`),i)}else c=_(r.template,i);let l=e.dirname(a);t.existsSync(l)||t.mkdirSync(l,{recursive:!0}),await pe(a,c),g(`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){g(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!y(o,i)){g(`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){g(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!y(t.condition,r)){g(`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){g(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!y(r.condition,a)){g(`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!==``&&!y(t.condition,r)){g(`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,_(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!==``&&!y(r.condition,i)){g(`Condition not met, skipping rename task`,`info`);return}let a=e.join(n.cwd(),_(r.from,i)),o=e.join(n.cwd(),_(r.to,i));if(!t.existsSync(a)){g(`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!==``&&!y(r.condition,i)){g(`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)){g(`File not found: ${a}, skipping`,`warn`);return}let s=await ke(a,`utf-8`);for(let{find:e,replace:t}of o){let n=_(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 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(){X.clear()}async function Ie(e){g(`Loading tasks from ${e}...`,`info`);let t=await Q(e);g(`Loaded ${t.tasks?.length??0} task(s)`,`info`),t.extends!=null&&t.extends!==``&&g(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.prompts!=null&&t.prompts.length>0&&g(`Found ${t.prompts.length} top-level prompt(s)`,`info`),t.variables!=null&&t.variables.length>0&&g(`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=r(t.writeFile);async function Re(t,r,i){if(t.condition!=null&&t.condition!==``&&!y(t.condition,r)){g(`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=_(s?await J(q(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=r(t.readFile),Ve=r(t.writeFile);async function He(t,r){if(t.condition!=null&&t.condition!==``&&!y(t.condition,r)){g(`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 _(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(`.`)?v(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||=(I(Ue),I(ze),I(he),I(Te),I(Me),I(_e),I(Oe),I(xe),I(ye),!0)}async function Ke(e,t,n=!1){if(Ge(),n){g(`[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 qe(e,t,r,i,a=!1){try{return g(`[${r}/${i}] Running: ${e.name}...`,`info`),await Ke(e,t,a),g(`✓ ${e.name}`,`success`),!0}catch(t){return g(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(g(` Reason: ${t.message}`,`error`),t.stack!=null&&n.env.DEBUG!=null&&console.error(t.stack)),e.required&&g(` 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 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 $(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`){g(`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){g(`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 $(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}async function Qe(e,t){let r=e.filter(e=>f(e.enabled,ee()));g(`Resolving task dependencies...`,`info`);let i=Je(r);g(`Welcome! Let's execute your tasks.`,`info`),t.dryRun&&g(`🔍 DRY RUN MODE - No changes will be made`,`warn`),g(`This will execute your project tasks based on the defined configuration.`,`info`);let a=ee(),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=Ze(c);e.length>0&&(g(`❌ Variable validation errors:`,`error`),e.forEach(e=>g(` - ${e}`,`error`)),n.exit(1)),g(`Resolving variable values...`,`info`);let t=Ye(c,await Xe(c));Object.assign(a,t),Object.keys(t).length>0&&g(`✓ 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&&(g(`❌ Prompt validation errors:`,`error`),e.forEach(e=>g(` - ${e}`,`error`)),n.exit(1)),g(`Resolving prompt default values...`,`info`);let t=await U(d),r={};if(l.length>0&&(g(`📋 Top-level prompts (available to all tasks):`,`info`),r=await V(l,t,a),Object.assign(a,r)),u.length>0){l.length>0&&g(`📋 Task-specific prompts:`,`info`);let e=await V(u,t,a);Object.assign(a,e)}}let p=i.filter(e=>f(e.enabled,a));if(g(`${p.length} of ${i.length} task(s) enabled for execution`,`info`),t.dryRun){await ie(p,a),g(`🔍 Dry run completed - no changes were made`,`info`),g(`Run without --dry-run to apply changes`,`info`);return}g(`Starting task execution...`,`info`),await z(`beforeAll`,a);let m=p.length,h=0,_=0,v=[];for(let e=0;e<p.length;e++){let n=p[e];if(n!=null)if(await z(`beforeTask`,n,a),await qe(n,a,e+1,m,t.dryRun))h++,v.push(n.id),await z(`afterTask`,n,a);else if(n.required){_++,await z(`onError`,Error(`Task ${n.name} failed`),n);break}else g(`⚠️ Non-critical task failed, continuing...`,`warn`),await z(`onError`,Error(`Task ${n.name} failed`),n)}_>0&&(g(`❌ Task execution failed with ${_} critical error(s)`,`error`),g(`✓ Completed: ${h}/${m} tasks`,`info`),n.exit(1)),await z(`afterAll`,a),g(`✅ All tasks completed successfully!`,`success`),g(`✓ Completed: ${h}/${m} tasks`,`success`),t.dryRun||(g(`Next steps:`,`info`),g(`1. Review the changes made to your project`,`info`),g(`2. Commit the changes to git`,`info`))}const $e=n.argv.includes(`--dry-run`),et=n.argv.includes(`--force`);async function tt(e){try{let t=e||[];t.length===0&&(g(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),g(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),n.exit(1)),await Qe(t,{dryRun:$e,force:et,tasksFilePath:void 0})}catch(e){g(`❌ Task execution failed`,`error`),e instanceof Error?(g(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}async function nt(e,t){try{await Qe(e,{dryRun:t?.dryRun??$e,force:t?.force??et,tasksFilePath:t?.tasksFilePath??void 0,...t?.globalVariables!=null&&{globalVariables:t.globalVariables},...t?.globalPrompts!=null&&{globalPrompts:t.globalPrompts}})}catch(e){g(`❌ Task execution failed`,`error`),e instanceof Error?(g(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}export{ae as A,T as B,oe as C,se as D,R as E,A as F,g as G,y as H,E as I,v as J,m as K,k as L,ie as M,O as N,le as O,j as P,D as R,B as S,ue as T,p as U,w as V,_ as W,H as _,$ as a,ce as b,Ke as c,Q as d,Ie as f,U as g,W as h,Xe as i,de as j,I as k,qe as l,Ne as m,nt as n,Ye as o,Z as p,h as q,Ze as r,Je as s,tt as t,Fe as u,V as v,L as w,fe as x,z as y,M as z};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixpilot/scaffoldfy",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.11.0",
|
|
5
5
|
"author": "PixPilot <m.doaie@hotmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -47,10 +47,10 @@
|
|
|
47
47
|
"tsdown": "^0.15.8",
|
|
48
48
|
"typescript": "^5.9.3",
|
|
49
49
|
"@internal/eslint-config": "0.3.0",
|
|
50
|
-
"@internal/prettier-config": "0.0.1",
|
|
51
50
|
"@internal/tsconfig": "0.1.0",
|
|
52
51
|
"@internal/tsdown-config": "0.1.0",
|
|
53
|
-
"@internal/vitest-config": "0.1.0"
|
|
52
|
+
"@internal/vitest-config": "0.1.0",
|
|
53
|
+
"@internal/prettier-config": "0.0.1"
|
|
54
54
|
},
|
|
55
55
|
"prettier": "@internal/prettier-config",
|
|
56
56
|
"scripts": {
|
package/schema/tasks.schema.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"title": "Template
|
|
4
|
-
"description": "Configuration for template
|
|
3
|
+
"title": "Template Tasks Configuration",
|
|
4
|
+
"description": "Configuration for template task automation and cleanup",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"properties": {
|
|
7
7
|
"extends": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"variables": {
|
|
24
24
|
"type": "array",
|
|
25
|
-
"description": "Top-level global variables available to all tasks. Variables are resolved once at
|
|
25
|
+
"description": "Top-level global variables available to all tasks. Variables are resolved once at startup and do not require user interaction.",
|
|
26
26
|
"items": {
|
|
27
27
|
"type": "object",
|
|
28
28
|
"required": ["id", "value"],
|
|
@@ -309,7 +309,7 @@
|
|
|
309
309
|
},
|
|
310
310
|
"variables": {
|
|
311
311
|
"type": "array",
|
|
312
|
-
"description": "Task-scoped variables available only to this specific task. Variables are resolved once at
|
|
312
|
+
"description": "Task-scoped variables available only to this specific task. Variables are resolved once at startup and do not require user interaction. For variables shared across tasks, use top-level variables instead.",
|
|
313
313
|
"items": {
|
|
314
314
|
"type": "object",
|
|
315
315
|
"required": ["id", "value"],
|
|
@@ -579,6 +579,5 @@
|
|
|
579
579
|
}
|
|
580
580
|
}
|
|
581
581
|
}
|
|
582
|
-
}
|
|
583
|
-
"required": ["tasks"]
|
|
582
|
+
}
|
|
584
583
|
}
|
package/dist/src-DxvGGX8s.cjs
DELETED
|
@@ -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}[0m`)}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 T(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 ee(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 ee(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 E=(0,f.promisify)(c.default.readFile),te=2,ne=10,re=55,D={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,cyan:`\x1B[36m`,gray:`\x1B[90m`};function O(e,t){switch(t){case`add`:return`${D.green}+ ${e}${D.reset}`;case`remove`:return`${D.red}- ${e}${D.reset}`;case`context`:return`${D.gray} ${e}${D.reset}`;default:return e}}function k(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(O(t,`context`)):(t!==void 0&&i.push(O(t,`remove`)),a!==void 0&&i.push(O(a,`add`)))}return i}async function A(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${D.yellow}⊘ Condition not met - task would be skipped${D.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${D.red}✗ File not found: ${e.file}${D.reset}`;try{let r=await E(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`${D.cyan}→ No changes${D.reset}`;let l=k(s,c);return`${D.blue}File: ${e.file}${D.reset}\n${l.join(`
|
|
4
|
-
`)}`}catch(e){return`${D.red}✗ Error: ${e instanceof Error?e.message:String(e)}${D.reset}`}}async function j(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${D.yellow}⊘ Condition not met - task would be skipped${D.reset}`;if(e.template==null||e.template===``)return`${D.red}✗ No template content provided for file: ${e.file}${D.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`${D.blue}File: ${e.file}${D.reset}\n${D.green}+ New file would be created${D.reset}\n${D.gray}Content preview:${D.reset}\n${t}${n?`
|
|
8
|
-
...`:``}`}try{let t=await E(n,`utf-8`);if(t===r)return`${D.cyan}→ No changes${D.reset}`;let i=k(t,r);return`${D.blue}File: ${e.file}${D.reset}\n${i.join(`
|
|
9
|
-
`)}`}catch(e){return`${D.red}✗ Error: ${e instanceof Error?e.message:String(e)}${D.reset}`}}async function ie(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${D.yellow}⊘ Condition not met - task would be skipped${D.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(c.default.existsSync(n))return`${D.cyan}→ File already exists, would be skipped: ${e.file}${D.reset}`;let r=e.template!=null&&e.template!==``,i=e.templateFile!=null&&e.templateFile!==``;if(!r&&!i)return`${D.red}✗ No template content provided for file: ${e.file}${D.reset}`;try{let n;if(r)n=S(e.template,t);else return`${D.blue}File: ${e.file}${D.reset}\n${D.green}+ New file would be created from template: ${e.templateFile}${D.reset}`;let i=n.split(`
|
|
10
|
-
`).slice(0,10).join(`
|
|
11
|
-
`),a=n.split(`
|
|
12
|
-
`).length>10;return`${D.blue}File: ${e.file}${D.reset}\n${D.green}+ New file would be created${D.reset}\n${D.gray}Content preview:${D.reset}\n${i}${a?`
|
|
13
|
-
...`:``}`}catch(e){return`${D.red}✗ Error: ${e instanceof Error?e.message:String(e)}${D.reset}`}}async function ae(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${D.yellow}⊘ Condition not met - task would be skipped${D.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${D.red}✗ File not found: ${e.file}${D.reset}`;try{let r=await E(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`${D.cyan}→ No matches found${D.reset}`;let s=k(r,o);return`${D.blue}File: ${e.file}${D.reset}\n${s.join(`
|
|
14
|
-
`)}`}catch(e){return`${D.red}✗ Error: ${e instanceof Error?e.message:String(e)}${D.reset}`}}async function oe(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${D.yellow}⊘ Condition not met - task would be skipped${D.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${D.red}✗ File not found: ${e.file}${D.reset}`;try{let r=await E(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`${D.cyan}→ No changes${D.reset}`;let a=k(i,r);return`${D.blue}File: ${e.file}${D.reset}\n${a.join(`
|
|
15
|
-
`)}`}catch(e){return`${D.red}✗ Error: ${e instanceof Error?e.message:String(e)}${D.reset}`}}function se(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${D.yellow}⊘ Condition not met - task would be skipped${D.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?`${D.cyan}→ No files/directories to delete${D.reset}`:`${D.red}Would delete:${D.reset}\n${n.map(e=>`${D.red} - ${e}${D.reset}`).join(`
|
|
16
|
-
`)}`}function M(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${D.yellow}⊘ Condition not met - task would be skipped${D.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)?`${D.yellow}⚠ Destination already exists: ${r}${D.reset}\n${D.cyan}Would rename: ${n} → ${r}${D.reset}`:`${D.cyan}Would rename: ${n} → ${r}${D.reset}`:`${D.red}✗ Source not found: ${n}${D.reset}`}function N(e){if(e.condition!=null&&e.condition!==``)return`${D.yellow}⊘ Condition check skipped in dry-run${D.reset}`;let t=l.default.join(u.default.cwd(),`.git`),n=c.default.existsSync(t),r=[];if(e.removeExisting&&n&&r.push(`${D.red}Would remove existing .git directory${D.reset}`),r.push(`${D.green}Would initialize git repository${D.reset}`),e.initialCommit){let t=e.message??`Initial commit`;r.push(`${D.green}Would create initial commit: "${t}"${D.reset}`)}return r.join(`
|
|
17
|
-
`)}function P(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${D.yellow}⊘ Condition not met - task would be skipped${D.reset}`;let n=S(e.command,t),r=e.cwd==null?u.default.cwd():S(e.cwd,t);return`${D.yellow}Would execute:${D.reset}\n${D.cyan} Command: ${n}${D.reset}\n${D.cyan} Working directory: ${r}${D.reset}`}async function F(e,t){try{switch(e.type){case`update-json`:return await A(e.config,t);case`template`:return await j(e.config,t);case`create`:return await ie(e.config,t);case`regex-replace`:return await ae(e.config,t);case`replace-in-file`:return await oe(e.config,t);case`delete`:return se(e.config,t);case`rename`:return M(e.config,t);case`git-init`:return N(e.config);case`exec`:return P(e.config,t);default:{let t=e.type;return`${D.yellow}⚠ Diff not available for task type: ${t}${D.reset}`}}}catch(e){return`${D.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${D.reset}`}}async function I(e,t){console.log(``),console.log(`${D.blue}═══════════════════════════════════════════════════════${D.reset}`),console.log(`${D.blue} DRY RUN - Preview of changes${D.reset}`),console.log(`${D.blue}═══════════════════════════════════════════════════════${D.reset}`),console.log(``);for(let n of e){console.log(`${D.cyan}▶ Task: ${n.name}${D.reset}`),console.log(`${D.gray} ${n.description}${D.reset}`),console.log(``);let e=await F(n,t);console.log(e),console.log(``),console.log(`${D.gray}${`─`.repeat(55)}${D.reset}`),console.log(``)}console.log(`${D.blue}═══════════════════════════════════════════════════════${D.reset}`),console.log(`${D.yellow} No changes were applied (dry-run mode)${D.reset}`),console.log(`${D.blue}═══════════════════════════════════════════════════════${D.reset}`),console.log(``)}const L=new Map,R={},z=new Map;function B(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(L.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(z.has(t)){let e=z.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}L.set(e.name,e);for(let t of e.taskTypes)z.set(t,e.name);x(`✓ Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`,`info`)}function ce(e){let t=L.get(e);if(t!=null){for(let e of t.taskTypes)z.delete(e);L.delete(e)}}function le(e){return L.get(e)}function V(e){let t=z.get(e);if(t!=null)return L.get(t)}function H(e){return z.has(e)}function ue(){return Array.from(L.keys())}function de(){L.clear(),z.clear()}function fe(e){e.beforeAll!=null&&(R.beforeAll=e.beforeAll),e.afterAll!=null&&(R.afterAll=e.afterAll),e.beforeTask!=null&&(R.beforeTask=e.beforeTask),e.afterTask!=null&&(R.afterTask=e.afterTask),e.onError!=null&&(R.onError=e.onError)}async function U(e,...t){let n=R[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 W(e,t,n){let r=V(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}async function pe(e,t){let n=V(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function me(e){let t=V(e.type);return t==null?[`No plugin found for task type: ${e.type}`]:t.validate==null?[]:t.validate(e)}function he(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 G(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 console.log(``),r}async function K(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 q(e){let t=new Map,n=e.map(async e=>{if(e.default!==void 0){let n=await K(e.default,e.id);n!==void 0&&t.set(e.id,n)}});return await Promise.all(n),t}function J(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 Y=`.scaffoldfyialized`;function X(){let e=l.default.join(u.default.cwd(),Y);if(!c.default.existsSync(e))return null;try{let t=c.default.readFileSync(e,`utf-8`);return JSON.parse(t)}catch{return null}}function ge(e,t,n=!1){if(n)return;let r=l.default.join(u.default.cwd(),`package.json`),i=`0.0.0`;try{i=JSON.parse(c.default.readFileSync(r,`utf-8`)).version??`0.0.0`}catch{}let a={initializedAt:new Date().toISOString(),config:e,completedTasks:t,version:i},o=l.default.join(u.default.cwd(),Y);c.default.writeFileSync(o,JSON.stringify(a,null,2))}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=T(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)}},Le=(0,f.promisify)(c.default.writeFile);async function Re(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`Condition not met, skipping template task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),r=e.template!=null&&e.template!==``,i=e.templateFile!=null&&e.templateFile!==``;if(!r&&!i)throw Error(`Template task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(r&&i)throw Error(`Template task cannot have both "template" and "templateFile" specified. Use one or the other.`);let a;if(i&&e.templateFile.endsWith(`.hbs`))a=T(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);await Le(n,a)}const ze={name:`template`,version:`1.0.0`,taskTypes:[`template`],execute:async(e,t,n)=>{n.dryRun||await Re(e.config,t)}},Be=(0,f.promisify)(c.default.readFile),Ve=(0,f.promisify)(c.default.writeFile),He=2;async function Ue(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 Be(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 Ve(n,`${JSON.stringify(a,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||=(B(We),B(ze),B(ye),B(ke),B(Ie),B(xe),B(Me),B(Te),B(Ce),!0)}async function qe(e,t,n=!1){if(Ke(),n){x(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(H(e.type)){await W(e,t,{dryRun:n});return}throw TypeError(`Unknown task type: ${e.type}`)}async function Je(e,t,n,r,i=!1){try{return x(`[${n}/${r}] Running: ${e.name}...`,`info`),await qe(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 Ye(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 Xe(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 Ze(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 Qe(e){let t=new Map,n=e.map(async e=>{let t=await Ze(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 $e(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 et=(0,f.promisify)(c.default.readFile);async function tt(e,t){let n=X();n&&!t.force&&(console.log(``),x(`⚠️ This template has already been initialized!`,`warn`),console.log(``),x(` Initialized at: ${new Date(n.initializedAt).toLocaleString()}`,`info`),console.log(``),await b(`Do you want to re-initialize? This may cause issues`,!1)||(x(`Initialization cancelled`,`info`),u.default.exit(0)),console.log(``),x(`⚠️ Proceeding with re-initialization...`,`warn`),console.log(``));let r=e.filter(e=>_(e.enabled,g()));x(`Resolving task dependencies...`,`info`);let i=Ye(r);console.log(``),x(`Welcome to the template initialization script!`,`info`),console.log(``),t.dryRun&&(x(`🔍 DRY RUN MODE - No changes will be made`,`warn`),console.log(``)),x(`This will initialize your project based on the defined tasks.`,`info`),console.log(``);let a=g(),o=t.globalVariables??[],s=[],f=[...o];for(let e of i)if(e.variables&&e.variables.length>0)for(let t of e.variables)s.push(t),f.push(t);if(f.length>0){let e=$e(f);e.length>0&&(x(`❌ Variable validation errors:`,`error`),e.forEach(e=>x(` - ${e}`,`error`)),console.log(``),u.default.exit(1)),x(`Resolving variable values...`,`info`);let t=await Qe(f);console.log(``);let n=Xe(f,t);Object.assign(a,n),Object.keys(n).length>0&&(x(`✓ Resolved ${Object.keys(n).length} variable(s)`,`success`),console.log(``))}let p=t.globalPrompts??[],m=[],h=[...p];for(let e of i)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)m.push(t),h.push(t);if(h.length>0){let e=J(h);e.length>0&&(x(`❌ Prompt validation errors:`,`error`),e.forEach(e=>x(` - ${e}`,`error`)),console.log(``),u.default.exit(1)),x(`Resolving prompt default values...`,`info`);let t=await q(h);console.log(``);let n={};if(p.length>0&&(console.log(``),x(`📋 Top-level prompts (available to all tasks):`,`info`),console.log(``),n=await G(p,t,a),Object.assign(a,n)),m.length>0){p.length>0&&(x(`📋 Task-specific prompts:`,`info`),console.log(``));let e=await G(m,t,a);Object.assign(a,e)}}let v=i.filter(e=>_(e.enabled,a));if(console.log(``),x(`${v.length} of ${i.length} task(s) enabled for execution`,`info`),t.dryRun){await I(v,a),x(`🔍 Dry run completed - no changes were made`,`info`),x(`Run without --dry-run to apply changes`,`info`);return}console.log(``),x(`Starting initialization tasks...`,`info`),console.log(``),await U(`beforeAll`,a);let y=v.length,S=0,C=0,w=[];for(let e=0;e<v.length;e++){let n=v[e];if(n!=null){if(await U(`beforeTask`,n,a),await Je(n,a,e+1,y,t.dryRun))S++,w.push(n.id),await U(`afterTask`,n,a);else if(n.required){C++,await U(`onError`,Error(`Task ${n.name} failed`),n);break}else x(`⚠️ Non-critical task failed, continuing...`,`warn`),await U(`onError`,Error(`Task ${n.name} failed`),n);console.log(``)}}if(C>0&&(x(`❌ Initialization failed with ${C} critical error(s)`,`error`),x(`✓ Completed: ${S}/${y} tasks`,`info`),u.default.exit(1)),await U(`afterAll`,a),ge(a,w,t.dryRun),x(`✅ Initialization completed successfully!`,`success`),console.log(``),x(`✓ Completed: ${S}/${y} tasks`,`success`),console.log(``),!t.dryRun&&t.tasksFilePath!=null&&c.default.existsSync(t.tasksFilePath))try{c.default.unlinkSync(t.tasksFilePath),x(`🗑️ Removed tasks file: ${l.default.basename(t.tasksFilePath)}`,`info`),console.log(``)}catch(e){x(`⚠️ Failed to remove tasks file: ${e instanceof Error?e.message:`Unknown error`}`,`warn`)}if(!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 et(e,`utf-8`)).scripts?.[`turbo:gen:init`]!=null&&(x(`3. Run "pnpm run turbo:gen:init" to create your first package`,`info`),console.log(``),await b(`Would you like to run turbo:gen:init now?`,!0)&&(console.log(``),x(`Running turbo:gen:init...`,`info`),(0,d.execSync)(`pnpm run turbo:gen:init`,{stdio:`inherit`})))}console.log(``)}const nt=(0,f.promisify)(c.default.readFile);function Z(e){try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}}async function rt(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 Q=new Map;async function it(e,t=new Set){let n=Z(e),r;if(r=n||l.default.isAbsolute(e)?e:l.default.resolve(u.default.cwd(),e),Q.has(r))return Q.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 rt(r);else{if(!c.default.existsSync(r))throw Error(`Template file not found: ${r}`);i=await nt(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(!Array.isArray(a.tasks))throw TypeError(`Invalid template file ${r}: 'tasks' array is required`);return Q.set(r,a),a}async function $(e,t,n=new Set){let r=Z(e),i;if(i=r||l.default.isAbsolute(e)?e:t==null?l.default.resolve(u.default.cwd(),e):Z(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 it(i);if(a.extends==null||a.extends===``)return a;let o=Z(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 $(e,o,n);c.push(t)}return at([...c,a])}function at(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,ot(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 ot(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;return{...e,...t,config:n,...r!=null&&{prompts:r},...i!=null&&{variables:i},...o!=null&&{dependencies:o}}}function st(){Q.clear()}async function ct(e){x(`Loading tasks from ${e}...`,`info`);let t=await $(e);x(`Loaded ${t.tasks.length} 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 lt=u.default.argv.includes(`--dry-run`),ut=u.default.argv.includes(`--force`);async function dt(e){try{let t=e||[];t.length===0&&(x(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),console.log(``),x(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),console.log(``),u.default.exit(1)),await tt(t,{dryRun:lt,force:ut,tasksFilePath:void 0})}catch(e){x(`❌ Initialization 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 ft(e,t){try{await tt(e,{dryRun:t?.dryRun??lt,force:t?.force??ut,tasksFilePath:t?.tasksFilePath??void 0,...t?.globalVariables!=null&&{globalVariables:t.globalVariables},...t?.globalPrompts!=null&&{globalPrompts:t.globalPrompts}})}catch(e){x(`❌ Initialization 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 fe}}),Object.defineProperty(exports,`B`,{enumerable:!0,get:function(){return oe}}),Object.defineProperty(exports,`C`,{enumerable:!0,get:function(){return he}}),Object.defineProperty(exports,`D`,{enumerable:!0,get:function(){return pe}}),Object.defineProperty(exports,`E`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`F`,{enumerable:!0,get:function(){return se}}),Object.defineProperty(exports,`G`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`H`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`I`,{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,`J`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`K`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`L`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`M`,{enumerable:!0,get:function(){return ce}}),Object.defineProperty(exports,`N`,{enumerable:!0,get:function(){return me}}),Object.defineProperty(exports,`O`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`P`,{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,`R`,{enumerable:!0,get:function(){return ae}}),Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,`T`,{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,`U`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`V`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`W`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`X`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`Y`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`Z`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return ct}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return $e}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return Xe}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return Ye}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return X}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`j`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`k`,{enumerable:!0,get:function(){return ue}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return Qe}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return Je}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return ft}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return it}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return qe}}),Object.defineProperty(exports,`q`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return st}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return at}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return dt}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return Ze}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`w`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,`z`,{enumerable:!0,get:function(){return M}});
|
package/dist/src-IzX9FHaO.js
DELETED
|
@@ -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}[0m`)}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 te(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 ne(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 re(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 ie(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 ae(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 te(e.config,t);case`rename`:return ne(e.config,t);case`git-init`:return re(e.config);case`exec`:return ie(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 j(e,t){console.log(``),console.log(`${w.blue}═══════════════════════════════════════════════════════${w.reset}`),console.log(`${w.blue} DRY RUN - Preview of changes${w.reset}`),console.log(`${w.blue}═══════════════════════════════════════════════════════${w.reset}`),console.log(``);for(let n of e){console.log(`${w.cyan}▶ Task: ${n.name}${w.reset}`),console.log(`${w.gray} ${n.description}${w.reset}`),console.log(``);let e=await ae(n,t);console.log(e),console.log(``),console.log(`${w.gray}${`─`.repeat(55)}${w.reset}`),console.log(``)}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}`),console.log(``)}const M=new Map,N={},P=new Map;function F(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(M.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(P.has(t)){let e=P.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}M.set(e.name,e);for(let t of e.taskTypes)P.set(t,e.name);_(`✓ Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`,`info`)}function oe(e){let t=M.get(e);if(t!=null){for(let e of t.taskTypes)P.delete(e);M.delete(e)}}function se(e){return M.get(e)}function I(e){let t=P.get(e);if(t!=null)return M.get(t)}function L(e){return P.has(e)}function ce(){return Array.from(M.keys())}function le(){M.clear(),P.clear()}function ue(e){e.beforeAll!=null&&(N.beforeAll=e.beforeAll),e.afterAll!=null&&(N.afterAll=e.afterAll),e.beforeTask!=null&&(N.beforeTask=e.beforeTask),e.afterTask!=null&&(N.afterTask=e.afterTask),e.onError!=null&&(N.onError=e.onError)}async function R(e,...t){let n=N[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 z(e,t,n){let r=I(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}async function de(e,t){let n=I(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function fe(e){let t=I(e.type);return t==null?[`No plugin found for task type: ${e.type}`]:t.validate==null?[]:t.validate(e)}function pe(e,t,n,r){return{name:e,...r?.version!=null&&{version:r.version},taskTypes:[t],execute:n,...r?.getDiff!=null&&{getDiff:r.getDiff},...r?.validate!=null&&{validate:r.validate}}}async function B(e,t=new Map,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 console.log(``),r}async function V(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`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 H(e){let t=new Map,n=e.map(async e=>{if(e.default!==void 0){let n=await V(e.default,e.id);n!==void 0&&t.set(e.id,n)}});return await Promise.all(n),t}function U(e){let t=[],n=new Set;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 W=`.scaffoldfyialized`;function G(){let r=e.join(n.cwd(),W);if(!t.existsSync(r))return null;try{let e=t.readFileSync(r,`utf-8`);return JSON.parse(e)}catch{return null}}function K(r,i,a=!1){if(a)return;let o=e.join(n.cwd(),`package.json`),s=`0.0.0`;try{s=JSON.parse(t.readFileSync(o,`utf-8`)).version??`0.0.0`}catch{}let c={initializedAt:new Date().toISOString(),config:r,completedTasks:i,version:s},l=e.join(n.cwd(),W);t.writeFileSync(l,JSON.stringify(c,null,2))}const me=i(t.writeFile);async function he(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 me(a,c),_(`Created file: ${r.file}`,`success`)}const ge={name:`create`,version:`1.0.0`,taskTypes:[`create`],execute:async(e,t,n)=>{n.dryRun||await he(e.config,t)}};async function _e(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 ve={name:`delete`,version:`1.0.0`,taskTypes:[`delete`],execute:async(e,t,n)=>{n.dryRun||await _e(e.config,t)}};async function ye(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 be={name:`exec`,version:`1.0.0`,taskTypes:[`exec`],execute:async(e,t,n)=>{n.dryRun||await ye(e.config,t)}};async function xe(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 Se={name:`git-init`,version:`1.0.0`,taskTypes:[`git-init`],execute:async(e,t,n)=>{n.dryRun||await xe(e.config,t)}},Ce=i(t.readFile),we=i(t.writeFile);async function Te(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 Ce(i,`utf-8`),l=new RegExp(a,o);c=c.replace(l,v(s,r)),await we(i,c)}const Ee={name:`regex-replace`,version:`1.0.0`,taskTypes:[`regex-replace`],execute:async(e,t,n)=>{n.dryRun||await Te(e.config,t)}},De=i(t.rename);async function Oe(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 De(a,o)}const ke={name:`rename`,version:`1.0.0`,taskTypes:[`rename`],execute:async(e,t,n)=>{n.dryRun||await Oe(e.config,t)}},Ae=i(t.readFile),je=i(t.writeFile);async function Me(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 Ae(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 je(a,s)}const Ne={name:`replace-in-file`,version:`1.0.0`,taskTypes:[`replace-in-file`],execute:async(e,t,n)=>{n.dryRun||await Me(e.config,t)}},Pe=i(t.writeFile);async function Fe(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i)){_(`Condition not met, skipping template task`,`info`);return}let a=e.join(n.cwd(),r.file),o=r.template!=null&&r.template!==``,s=r.templateFile!=null&&r.templateFile!==``;if(!o&&!s)throw Error(`Template task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(o&&s)throw Error(`Template task cannot have both "template" and "templateFile" specified. Use one or the other.`);let c;if(s&&r.templateFile.endsWith(`.hbs`))c=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);await Pe(a,c)}const Ie={name:`template`,version:`1.0.0`,taskTypes:[`template`],execute:async(e,t,n)=>{n.dryRun||await Fe(e.config,t)}},Le=i(t.readFile),Re=i(t.writeFile);async function ze(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 Le(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 Re(i,`${JSON.stringify(s,null,2)}\n`)}const Be={name:`update-json`,version:`1.0.0`,taskTypes:[`update-json`],execute:async(e,t,n)=>{n.dryRun||await ze(e.config,t)}};let Ve=!1;function He(){Ve||=(F(Be),F(Ie),F(ge),F(Ee),F(Ne),F(ve),F(ke),F(Se),F(be),!0)}async function q(e,t,n=!1){if(He(),n){_(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(L(e.type)){await z(e,t,{dryRun:n});return}throw TypeError(`Unknown task type: ${e.type}`)}async function J(e,t,r,i,a=!1){try{return _(`[${r}/${i}] Running: ${e.name}...`,`info`),await q(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 Y(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 Ue(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 We(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 Ge(e){let t=new Map,n=e.map(async e=>{let t=await We(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 Ke(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 Je(i,a){let o=G();o&&!a.force&&(console.log(``),_(`⚠️ This template has already been initialized!`,`warn`),console.log(``),_(` Initialized at: ${new Date(o.initializedAt).toLocaleString()}`,`info`),console.log(``),await g(`Do you want to re-initialize? This may cause issues`,!1)||(_(`Initialization cancelled`,`info`),n.exit(0)),console.log(``),_(`⚠️ Proceeding with re-initialization...`,`warn`),console.log(``));let s=i.filter(e=>p(e.enabled,f()));_(`Resolving task dependencies...`,`info`);let c=Y(s);console.log(``),_(`Welcome to the template initialization script!`,`info`),console.log(``),a.dryRun&&(_(`🔍 DRY RUN MODE - No changes will be made`,`warn`),console.log(``)),_(`This will initialize your project based on the defined tasks.`,`info`),console.log(``);let l=f(),u=a.globalVariables??[],d=[],m=[...u];for(let e of c)if(e.variables&&e.variables.length>0)for(let t of e.variables)d.push(t),m.push(t);if(m.length>0){let e=Ke(m);e.length>0&&(_(`❌ Variable validation errors:`,`error`),e.forEach(e=>_(` - ${e}`,`error`)),console.log(``),n.exit(1)),_(`Resolving variable values...`,`info`);let t=await Ge(m);console.log(``);let r=Ue(m,t);Object.assign(l,r),Object.keys(r).length>0&&(_(`✓ Resolved ${Object.keys(r).length} variable(s)`,`success`),console.log(``))}let h=a.globalPrompts??[],v=[],y=[...h];for(let e of c)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)v.push(t),y.push(t);if(y.length>0){let e=U(y);e.length>0&&(_(`❌ Prompt validation errors:`,`error`),e.forEach(e=>_(` - ${e}`,`error`)),console.log(``),n.exit(1)),_(`Resolving prompt default values...`,`info`);let t=await H(y);console.log(``);let r={};if(h.length>0&&(console.log(``),_(`📋 Top-level prompts (available to all tasks):`,`info`),console.log(``),r=await B(h,t,l),Object.assign(l,r)),v.length>0){h.length>0&&(_(`📋 Task-specific prompts:`,`info`),console.log(``));let e=await B(v,t,l);Object.assign(l,e)}}let b=c.filter(e=>p(e.enabled,l));if(console.log(``),_(`${b.length} of ${c.length} task(s) enabled for execution`,`info`),a.dryRun){await j(b,l),_(`🔍 Dry run completed - no changes were made`,`info`),_(`Run without --dry-run to apply changes`,`info`);return}console.log(``),_(`Starting initialization tasks...`,`info`),console.log(``),await R(`beforeAll`,l);let x=b.length,S=0,C=0,w=[];for(let e=0;e<b.length;e++){let t=b[e];if(t!=null){if(await R(`beforeTask`,t,l),await J(t,l,e+1,x,a.dryRun))S++,w.push(t.id),await R(`afterTask`,t,l);else if(t.required){C++,await R(`onError`,Error(`Task ${t.name} failed`),t);break}else _(`⚠️ Non-critical task failed, continuing...`,`warn`),await R(`onError`,Error(`Task ${t.name} failed`),t);console.log(``)}}if(C>0&&(_(`❌ Initialization failed with ${C} critical error(s)`,`error`),_(`✓ Completed: ${S}/${x} tasks`,`info`),n.exit(1)),await R(`afterAll`,l),K(l,w,a.dryRun),_(`✅ Initialization completed successfully!`,`success`),console.log(``),_(`✓ Completed: ${S}/${x} tasks`,`success`),console.log(``),!a.dryRun&&a.tasksFilePath!=null&&t.existsSync(a.tasksFilePath))try{t.unlinkSync(a.tasksFilePath),_(`🗑️ Removed tasks file: ${e.basename(a.tasksFilePath)}`,`info`),console.log(``)}catch(e){_(`⚠️ Failed to remove tasks file: ${e instanceof Error?e.message:`Unknown error`}`,`warn`)}if(!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`),console.log(``),await g(`Would you like to run turbo:gen:init now?`,!0)&&(console.log(``),_(`Running turbo:gen:init...`,`info`),r(`pnpm run turbo:gen:init`,{stdio:`inherit`})))}console.log(``)}const Ye=i(t.readFile);function X(e){try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}}async function Xe(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(r,i=new Set){let a=X(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 Xe(o);else{if(!t.existsSync(o))throw Error(`Template file not found: ${o}`);s=await Ye(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(!Array.isArray(c.tasks))throw TypeError(`Invalid template file ${o}: 'tasks' array is required`);return Z.set(o,c),c}async function Q(t,r,i=new Set){let a=X(t),o;if(o=a||e.isAbsolute(t)?t:r==null?e.resolve(n.cwd(),t):X(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 Ze(o);if(s.extends==null||s.extends===``)return s;let c=X(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 $([...u,s])}function $(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,Qe(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 Qe(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;return{...e,...t,config:n,...r!=null&&{prompts:r},...i!=null&&{variables:i},...o!=null&&{dependencies:o}}}function $e(){Z.clear()}async function et(e){_(`Loading tasks from ${e}...`,`info`);let t=await Q(e);_(`Loaded ${t.tasks.length} 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 tt=n.argv.includes(`--dry-run`),nt=n.argv.includes(`--force`);async function rt(e){try{let t=e||[];t.length===0&&(_(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),console.log(``),_(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),console.log(``),n.exit(1)),await Je(t,{dryRun:tt,force:nt,tasksFilePath:void 0})}catch(e){_(`❌ Initialization 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 it(e,t){try{await Je(e,{dryRun:t?.dryRun??tt,force:t?.force??nt,tasksFilePath:t?.tasksFilePath??void 0,...t?.globalVariables!=null&&{globalVariables:t.globalVariables},...t?.globalPrompts!=null&&{globalPrompts:t.globalPrompts}})}catch(e){_(`❌ Initialization failed`,`error`),e instanceof Error?(_(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}export{ue as A,A as B,pe as C,de as D,I as E,te as F,m as G,O as H,ie as I,h as J,v as K,re as L,oe as M,fe as N,L as O,j as P,k as R,le as S,se as T,D as U,ae as V,b as W,y as X,g as Y,U as _,et as a,B as b,Ke as c,Ue as d,Y as f,K as g,G as h,Q as i,F as j,ce as k,Ge as l,J as m,it as n,Ze as o,q as p,_ as q,$e as r,$ as s,rt as t,We as u,H as v,z as w,R as x,V as y,ne as z};
|