@pixpilot/scaffoldfy 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,75 @@
1
+ //#region src/plugins/create/types.d.ts
2
+
3
+ interface CreateConfig {
4
+ file: string;
5
+ template?: string;
6
+ templateFile?: string;
7
+ condition?: ConditionExpression;
8
+ }
9
+ //#endregion
10
+ //#region src/plugins/delete/types.d.ts
11
+ interface DeleteConfig {
12
+ paths: string[];
13
+ condition?: ConditionExpression;
14
+ }
15
+ //#endregion
16
+ //#region src/plugins/exec/types.d.ts
17
+ interface ExecConfig {
18
+ command: string;
19
+ cwd?: string;
20
+ condition?: ConditionExpression;
21
+ }
22
+ //#endregion
23
+ //#region src/plugins/git-init/types.d.ts
24
+ interface GitInitConfig {
25
+ removeExisting: boolean;
26
+ initialCommit: boolean;
27
+ message?: string;
28
+ condition?: ConditionExpression;
29
+ }
30
+ //#endregion
31
+ //#region src/plugins/regex-replace/types.d.ts
32
+ interface RegexReplaceConfig {
33
+ file: string;
34
+ pattern: string;
35
+ flags?: string;
36
+ replacement: string;
37
+ condition?: ConditionExpression;
38
+ }
39
+ //#endregion
40
+ //#region src/plugins/rename/types.d.ts
41
+ interface RenameConfig {
42
+ from: string;
43
+ to: string;
44
+ condition?: ConditionExpression;
45
+ }
46
+ //#endregion
47
+ //#region src/plugins/replace-in-file/types.d.ts
48
+ interface ReplaceInFileConfig {
49
+ file: string;
50
+ replacements: Array<{
51
+ find: string;
52
+ replace: string;
53
+ }>;
54
+ condition?: ConditionExpression;
55
+ }
56
+ //#endregion
57
+ //#region src/plugins/template/types.d.ts
58
+ interface TemplateConfig {
59
+ file: string;
60
+ template?: string;
61
+ templateFile?: string;
62
+ condition?: ConditionExpression;
63
+ }
64
+ //#endregion
65
+ //#region src/plugins/update-json/types.d.ts
66
+ interface UpdateJsonConfig {
67
+ file: string;
68
+ updates: Record<string, unknown>;
69
+ condition?: ConditionExpression;
70
+ }
71
+ //#endregion
1
72
  //#region src/types.d.ts
2
- /**
3
- * Task Types and Interfaces for Template Initialization
4
- */
5
73
  interface InitConfig {
6
74
  [key: string]: unknown;
7
75
  }
@@ -29,12 +97,23 @@ interface DefaultValueConfig<T = string | number | boolean> {
29
97
  * - For explicit static values, use { type: 'static', value: yourValue }
30
98
  */
31
99
  type DefaultValue<T = string | number | boolean> = T | DefaultValueConfig<T>;
100
+ /**
101
+ * Conditional enabled configuration for prompts and tasks
102
+ * Allows dynamic enabling/disabling based on runtime conditions
103
+ */
104
+ interface ConditionalEnabled {
105
+ condition: ConditionExpression;
106
+ }
107
+ /**
108
+ * Type for enabled field that can be boolean or conditional
109
+ */
110
+ type EnabledValue = boolean | ConditionalEnabled;
32
111
  interface BasePrompt {
33
112
  id: string;
34
113
  type: PromptType;
35
114
  message: string;
36
115
  required?: boolean;
37
- global?: boolean;
116
+ enabled?: EnabledValue;
38
117
  }
39
118
  interface InputPrompt extends BasePrompt {
40
119
  type: 'input' | 'password';
@@ -60,15 +139,26 @@ interface ConfirmPrompt extends BasePrompt {
60
139
  default?: DefaultValue<boolean>;
61
140
  }
62
141
  type PromptDefinition = InputPrompt | NumberPrompt | SelectPrompt | ConfirmPrompt;
142
+ /**
143
+ * Variable value configuration for defining optional global or task-scoped variables
144
+ * Variables are similar to prompts but don't require user input - they can have static
145
+ * values or values resolved from executable commands
146
+ *
147
+ * Note: Top-level variables are always global. Task-level variables are task-scoped.
148
+ */
149
+ interface VariableDefinition {
150
+ id: string;
151
+ value: DefaultValue;
152
+ }
63
153
  /**
64
154
  * JavaScript expression evaluated at runtime to determine if a task or operation should execute.
65
- * Has access to all prompt values and config variables.
155
+ * Has access to all prompt values, variables, and config variables.
66
156
  * @example "useTypeScript === true"
67
157
  * @example "nodeVersion >= 16 && includeTests === true"
68
158
  * @example "packageManager === 'pnpm'"
69
159
  */
70
160
  type ConditionExpression = string;
71
- type TaskType = 'update-json' | 'template' | 'regex-replace' | 'replace-in-file' | 'delete' | 'rename' | 'git-init' | 'exec';
161
+ type TaskType = 'update-json' | 'template' | 'create' | 'regex-replace' | 'replace-in-file' | 'delete' | 'rename' | 'git-init' | 'exec';
72
162
  interface RollbackConfig {
73
163
  type: TaskType;
74
164
  config: unknown;
@@ -78,71 +168,23 @@ interface TaskDefinition {
78
168
  name: string;
79
169
  description: string;
80
170
  required: boolean;
81
- enabled: boolean;
171
+ enabled: EnabledValue;
82
172
  type: TaskType;
83
- config: UpdateJsonConfig | TemplateConfig | RegexReplaceConfig | ReplaceInFileConfig | DeleteConfig | RenameConfig | GitInitConfig | ExecConfig | Record<string, unknown>;
173
+ config: UpdateJsonConfig | TemplateConfig | CreateConfig | RegexReplaceConfig | ReplaceInFileConfig | DeleteConfig | RenameConfig | GitInitConfig | ExecConfig | Record<string, unknown>;
84
174
  dependencies?: string[];
85
175
  rollback?: RollbackConfig;
86
176
  prompts?: PromptDefinition[];
87
- }
88
- interface UpdateJsonConfig {
89
- file: string;
90
- updates: Record<string, unknown>;
91
- condition?: ConditionExpression;
92
- }
93
- interface TemplateConfig {
94
- file: string;
95
- template?: string;
96
- templateFile?: string;
97
- condition?: ConditionExpression;
98
- }
99
- interface RegexReplaceConfig {
100
- file: string;
101
- pattern: string;
102
- flags?: string;
103
- replacement: string;
104
- condition?: ConditionExpression;
105
- }
106
- interface ReplaceInFileConfig {
107
- file: string;
108
- replacements: Array<{
109
- find: string;
110
- replace: string;
111
- }>;
112
- condition?: ConditionExpression;
113
- }
114
- interface DeleteConfig {
115
- paths: string[];
116
- condition?: ConditionExpression;
117
- }
118
- interface RenameConfig {
119
- from: string;
120
- to: string;
121
- condition?: ConditionExpression;
122
- }
123
- interface GitInitConfig {
124
- removeExisting: boolean;
125
- initialCommit: boolean;
126
- message?: string;
127
- condition?: ConditionExpression;
128
- }
129
- interface ExecConfig {
130
- command: string;
131
- cwd?: string;
132
- condition?: ConditionExpression;
133
- }
134
- interface InitializationMetadata {
135
- initializedAt: string;
136
- config: InitConfig;
137
- completedTasks: string[];
138
- version: string;
177
+ variables?: VariableDefinition[];
178
+ $sourceUrl?: string;
139
179
  }
140
180
  /**
141
181
  * Configuration file structure for template tasks
142
182
  */
143
183
  interface TasksConfiguration {
144
184
  extends?: string | string[];
145
- tasks: TaskDefinition[];
185
+ variables?: VariableDefinition[];
186
+ prompts?: PromptDefinition[];
187
+ tasks?: TaskDefinition[];
146
188
  }
147
189
  /**
148
190
  * Plugin interface for custom task types
@@ -319,11 +361,13 @@ declare function createPlugin(name: string, taskType: string, execute: (task: Ta
319
361
  //#region src/prompts/collect-prompts.d.ts
320
362
  /**
321
363
  * Collect prompt answers from task-defined prompts
364
+ * Only prompts with enabled=true (or enabled condition that evaluates to true) will be shown
322
365
  * @param prompts - Array of prompt definitions from tasks
323
366
  * @param resolvedDefaults - Map of pre-resolved default values
367
+ * @param config - Current configuration context (for evaluating enabled conditions)
324
368
  * @returns Object mapping prompt IDs to their values
325
369
  */
326
- declare function collectPrompts(prompts: PromptDefinition[], resolvedDefaults?: Map<string, unknown>): Promise<Record<string, unknown>>;
370
+ declare function collectPrompts(prompts: PromptDefinition[], resolvedDefaults?: Map<string, unknown>, config?: InitConfig): Promise<Record<string, unknown>>;
327
371
  //#endregion
328
372
  //#region src/prompts/resolve-all-default-values.d.ts
329
373
  /**
@@ -350,16 +394,6 @@ declare function resolveDefaultValue<T = string | number | boolean>(defaultValue
350
394
  */
351
395
  declare function validatePrompts(prompts: PromptDefinition[]): string[];
352
396
  //#endregion
353
- //#region src/state.d.ts
354
- /**
355
- * Load initialization state from file
356
- */
357
- declare function loadInitializationState(): InitializationMetadata | null;
358
- /**
359
- * Save initialization state to file
360
- */
361
- declare function saveInitializationState(config: InitConfig, completedTasks: string[], dryRun?: boolean): void;
362
- //#endregion
363
397
  //#region src/task-executors.d.ts
364
398
  /**
365
399
  * Execute a task based on its type
@@ -406,9 +440,13 @@ declare function clearTemplateCache(): void;
406
440
  /**
407
441
  * Load tasks from a configuration file with template inheritance support
408
442
  * @param tasksFilePath - Path to the tasks configuration file
409
- * @returns Array of task definitions
443
+ * @returns Task configuration with tasks, optional variables, and optional prompts
410
444
  */
411
- declare function loadTasksWithInheritance(tasksFilePath: string): Promise<TaskDefinition[]>;
445
+ declare function loadTasksWithInheritance(tasksFilePath: string): Promise<{
446
+ tasks: TaskDefinition[];
447
+ variables?: VariableDefinition[];
448
+ prompts?: PromptDefinition[];
449
+ }>;
412
450
  //#endregion
413
451
  //#region src/utils.d.ts
414
452
  /**
@@ -444,24 +482,65 @@ declare function setNestedProperty(obj: Record<string, unknown>, propertyPath: s
444
482
  */
445
483
  declare function evaluateCondition(condition: string, config: InitConfig): boolean;
446
484
  //#endregion
485
+ //#region src/variables/collect-variables.d.ts
486
+ /**
487
+ * Collect variable values from resolved variables
488
+ * Variables don't require user interaction - they're just resolved from static
489
+ * values or executable commands
490
+ *
491
+ * @param variables - Array of variable definitions
492
+ * @param resolvedValues - Map of pre-resolved variable values
493
+ * @returns Object mapping variable IDs to their values
494
+ */
495
+ declare function collectVariables(variables: VariableDefinition[], resolvedValues?: Map<string, unknown>): Record<string, unknown>;
496
+ //#endregion
497
+ //#region src/variables/resolve-all-variable-values.d.ts
498
+ /**
499
+ * Pre-resolve all variable values (execute commands in parallel for efficiency)
500
+ * @param variables - Array of variable definitions
501
+ * @returns Map of variable IDs to their resolved values
502
+ */
503
+ declare function resolveAllVariableValues(variables: VariableDefinition[]): Promise<Map<string, unknown>>;
504
+ //#endregion
505
+ //#region src/variables/resolve-variable-value.d.ts
506
+ /**
507
+ * Resolve a variable value that may be static or executable
508
+ * @param value - The variable value configuration
509
+ * @param variableId - The variable ID for error reporting
510
+ * @returns The resolved variable value
511
+ */
512
+ declare function resolveVariableValue<T = string | number | boolean>(value: DefaultValue<T>, variableId: string): Promise<T | undefined>;
513
+ //#endregion
514
+ //#region src/variables/validate-variables.d.ts
515
+ /**
516
+ * Validate variable definitions for common errors
517
+ * @param variables - Array of variable definitions to validate
518
+ * @returns Array of error messages (empty if no errors)
519
+ */
520
+ declare function validateVariables(variables: VariableDefinition[]): string[];
521
+ //#endregion
447
522
  //#region src/index.d.ts
448
523
  /**
449
- * Main function for running initialization with default/empty tasks
524
+ * Main function for executing tasks with default/empty tasks array
450
525
  * For most use cases, you should use runWithTasks() with your custom tasks
451
526
  */
452
527
  declare function main(customTasks?: TaskDefinition[]): Promise<void>;
453
528
  /**
454
- * Run initialization with custom tasks
529
+ * Execute tasks with custom task definitions
455
530
  * @param customTasks - Array of task definitions to execute
456
531
  * @param options - Optional configuration
457
532
  * @param options.dryRun - Preview changes without applying them
458
- * @param options.force - Force re-initialization even if already initialized
533
+ * @param options.force - Force execution even if checks fail
459
534
  * @param options.tasksFilePath - Path to the tasks file
535
+ * @param options.globalVariables - Optional top-level global variables
536
+ * @param options.globalPrompts - Optional top-level global prompts
460
537
  */
461
538
  declare function runWithTasks(customTasks: TaskDefinition[], options?: {
462
539
  dryRun?: boolean | undefined;
463
540
  force?: boolean | undefined;
464
541
  tasksFilePath?: string | undefined;
542
+ globalVariables?: VariableDefinition[] | undefined;
543
+ globalPrompts?: PromptDefinition[] | undefined;
465
544
  }): Promise<void>;
466
545
  //#endregion
467
- export { BasePrompt, ConditionExpression, ConfirmPrompt, DefaultValue, DefaultValueConfig, DefaultValueType, DeleteConfig, ExecConfig, GitInitConfig, InitConfig, InitializationMetadata, InputPrompt, NumberPrompt, PluginHooks, PromptDefinition, PromptType, RegexReplaceConfig, RenameConfig, ReplaceInFileConfig, RollbackConfig, SelectPrompt, TaskDefinition, TaskPlugin, TaskType, TasksConfiguration, TemplateConfig, UpdateJsonConfig, callHook, clearPlugins, clearTemplateCache, collectPrompts, createPlugin, displayTasksDiff, evaluateCondition, executePluginTask, executeTask, getDeleteDiff, getExecDiff, getGitInitDiff, getGitRepoInfo, getPlugin, getPluginForTaskType, getPluginTaskDiff, getRegexReplaceDiff, getRenameDiff, getReplaceInFileDiff, getTaskDiff, getTemplateDiff, getUpdateJsonDiff, interpolateTemplate, isPluginTaskType, listPlugins, loadAndMergeTemplate, loadInitializationState, loadTasksWithInheritance, loadTemplate, log, main, mergeTemplates, prompt, promptYesNo, registerHooks, registerPlugin, resolveAllDefaultValues, resolveDefaultValue, runTask, runWithTasks, saveInitializationState, setNestedProperty, topologicalSort, unregisterPlugin, validatePluginTask, validatePrompts };
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,K as l,L as u,M as d,N as f,O as p,P as m,R as h,S as g,T as _,U as v,V as y,W as b,_ as x,a as S,b as C,c as w,d as T,f as E,g as D,h as O,i as k,j as A,k as j,l as M,m as N,n as P,o as F,p as I,r as L,s as R,t as z,u as B,v as V,w as H,x as U,y as W,z as G}from"./src-RfAsa6ai.js";export{x as callHook,V as clearPlugins,L as clearTemplateCache,D as collectPrompts,W as createPlugin,e as displayTasksDiff,t as evaluateCondition,C as executePluginTask,M as executeTask,A as getDeleteDiff,d as getExecDiff,f as getGitInitDiff,y as getGitRepoInfo,U as getPlugin,g as getPluginForTaskType,n as getPluginTaskDiff,m as getRegexReplaceDiff,a as getRenameDiff,c as getReplaceInFileDiff,u as getTaskDiff,h as getTemplateDiff,G as getUpdateJsonDiff,s as interpolateTemplate,H as isPluginTaskType,_ as listPlugins,k as loadAndMergeTemplate,T as loadInitializationState,S as loadTasksWithInheritance,F as loadTemplate,v as log,z as main,R as mergeTemplates,b as prompt,o as promptYesNo,i as registerHooks,r as registerPlugin,N as resolveAllDefaultValues,O as resolveDefaultValue,B as runTask,P as runWithTasks,E as saveInitializationState,l as setNestedProperty,w as topologicalSort,p as unregisterPlugin,j as validatePluginTask,I as validatePrompts};
1
+ import{A as e,B as t,C as n,D as r,E as i,F as a,G as o,H as s,I as c,J as l,K as u,L as d,M as f,N as p,O as m,P as h,R as g,S as _,T as v,U as y,V as b,W as x,_ as S,a as C,b as w,c as T,d as E,f as D,g as O,h as k,i as A,j,k as M,l as N,m as P,n as F,o as I,p as L,q as R,r as z,s as B,t as V,u as H,v as U,w as W,x as G,y as K,z as q}from"./src-gsac5lFQ.js";export{K as callHook,w as clearPlugins,H as clearTemplateCache,U as collectPrompts,I as collectVariables,G as createPlugin,f as displayTasksDiff,s as evaluateCondition,_ as executePluginTask,T as executeTask,p as getDeleteDiff,h as getExecDiff,a as getGitInitDiff,y as getGitRepoInfo,n as getPlugin,W as getPluginForTaskType,v as getPluginTaskDiff,c as getRegexReplaceDiff,d as getRenameDiff,g as getReplaceInFileDiff,q as getTaskDiff,t as getTemplateDiff,b as getUpdateJsonDiff,x as interpolateTemplate,i as isPluginTaskType,r as listPlugins,E as loadAndMergeTemplate,D as loadTasksWithInheritance,L as loadTemplate,o as log,V as main,P as mergeTemplates,u as prompt,R as promptYesNo,m as registerHooks,M as registerPlugin,O as resolveAllDefaultValues,A as resolveAllVariableValues,S as resolveDefaultValue,C as resolveVariableValue,N as runTask,F as runWithTasks,l as setNestedProperty,B as topologicalSort,e as unregisterPlugin,j as validatePluginTask,k as validatePrompts,z as validateVariables};
@@ -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:child_process`);d=s(d);let f=require(`node:util`);f=s(f);let p=require(`node:readline`);p=s(p);let m=require(`handlebars`);m=s(m);let h=require(`@inquirer/prompts`);h=s(h);function g(){return{}}function _(e,t){return e===void 0?!0:typeof e==`boolean`?e:typeof e==`object`&&`condition`in e?w(e.condition,t):!1}function v(){try{let e=(0,d.execSync)(`git remote get-url origin`,{encoding:`utf-8`}).trim(),t=e.match(/github\.com[:/](?<owner>[^/]+)\/(?<name>[^/]+)$/u);if(t?.groups){let{owner:n,name:r}=t.groups,i=r;return i.endsWith(`.git`)&&(i=i.slice(0,-4)),{owner:n,name:i,url:e}}return null}catch{return null}}async function y(e,t){let n=p.default.createInterface({input:u.default.stdin,output:u.default.stdout});return new Promise(r=>{let i;i=t==null?`${e}: `:`${e} (${t}): `,n.question(i,e=>{n.close(),r(e.trim()||(t??``))})})}async function b(e,t=!1){return y(`${e} (${t?`Y/n`:`y/N`})`,t?`y`:`n`).then(e=>e.toLowerCase()===`y`||e.toLowerCase()===`yes`)}function x(e,t=`info`){console.log(`${{info:`\x1B[36m`,success:`\x1B[32m`,error:`\x1B[31m`,warn:`\x1B[33m`}[t]}${{info:`ℹ`,success:`✓`,error:`✗`,warn:`⚠`}[t]} ${e}`)}function S(e,t){return e.replace(/\{\{(?<key>\w+)\}\}/gu,(e,n)=>t[n]?.toString()??``)}function C(e,t,n){let r=t.split(`.`),i=e;for(let e=0;e<r.length-1;e++){let t=r[e];t!=null&&t!==``&&((!(t in i)||typeof i[t]!=`object`||i[t]===null)&&(i[t]={}),i=i[t])}let a=r[r.length-1];a!=null&&a!==``&&(i[a]=n)}function w(e,t){try{let n={...t};return Function(...Object.keys(n),`'use strict'; return (${e})`)(...Object.values(n))}catch(t){return x(`Failed to evaluate condition: ${e}`,`warn`),t instanceof Error&&x(` Error: ${t.message}`,`warn`),!1}}function ee(e,t){try{let n=l.default.isAbsolute(e)?e:l.default.join(u.default.cwd(),e);if(!c.default.existsSync(n))throw Error(`Template file not found: ${e}`);return te(c.default.readFileSync(n,`utf-8`),t)}catch(t){throw x(`Failed to read template file: ${e}`,`error`),t instanceof Error&&x(` Error: ${t.message}`,`error`),t}}function te(e,t){try{return m.default.compile(e)(t)}catch(e){throw x(`Failed to compile Handlebars template`,`error`),e instanceof Error&&x(` Error: ${e.message}`,`error`),e}}const T=(0,f.promisify)(c.default.readFile),ne=2,re=10,ie=55,E={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,cyan:`\x1B[36m`,gray:`\x1B[90m`};function D(e,t){switch(t){case`add`:return`${E.green}+ ${e}${E.reset}`;case`remove`:return`${E.red}- ${e}${E.reset}`;case`context`:return`${E.gray} ${e}${E.reset}`;default:return e}}function O(e,t){let n=e.split(`
2
+ `),r=t.split(`
3
+ `),i=[],a=Math.max(n.length,r.length);for(let e=0;e<a;e++){let t=n[e],a=r[e];t===a?t!==void 0&&i.push(D(t,`context`)):(t!==void 0&&i.push(D(t,`remove`)),a!==void 0&&i.push(D(a,`add`)))}return i}async function k(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${E.red}✗ File not found: ${e.file}${E.reset}`;try{let r=await T(n,`utf-8`),i=JSON.parse(r),a={...i};function o(e){if(typeof e==`string`)return S(e,t);if(Array.isArray(e))return e.map(e=>o(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=o(r);return t}return e}for(let[t,n]of Object.entries(e.updates)){let e=o(n);t.includes(`.`)?C(i,t,e):i[t]=e}let s=JSON.stringify(a,null,2),c=JSON.stringify(i,null,2);if(s===c)return`${E.cyan}→ No changes${E.reset}`;let l=O(s,c);return`${E.blue}File: ${e.file}${E.reset}\n${l.join(`
4
+ `)}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function ae(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;if(e.template==null||e.template===``)return`${E.red}✗ No template content provided for file: ${e.file}${E.reset}`;let n=l.default.join(u.default.cwd(),e.file),r=S(e.template,t);if(!c.default.existsSync(n)){let t=r.split(`
5
+ `).slice(0,10).join(`
6
+ `),n=r.split(`
7
+ `).length>10;return`${E.blue}File: ${e.file}${E.reset}\n${E.green}+ New file would be created${E.reset}\n${E.gray}Content preview:${E.reset}\n${t}${n?`
8
+ ...`:``}`}try{let t=await T(n,`utf-8`);if(t===r)return`${E.cyan}→ No changes${E.reset}`;let i=O(t,r);return`${E.blue}File: ${e.file}${E.reset}\n${i.join(`
9
+ `)}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function oe(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(c.default.existsSync(n))return`${E.cyan}→ File already exists, would be skipped: ${e.file}${E.reset}`;let r=e.template!=null&&e.template!==``,i=e.templateFile!=null&&e.templateFile!==``;if(!r&&!i)return`${E.red}✗ No template content provided for file: ${e.file}${E.reset}`;try{let n;if(r)n=S(e.template,t);else return`${E.blue}File: ${e.file}${E.reset}\n${E.green}+ New file would be created from template: ${e.templateFile}${E.reset}`;let i=n.split(`
10
+ `).slice(0,10).join(`
11
+ `),a=n.split(`
12
+ `).length>10;return`${E.blue}File: ${e.file}${E.reset}\n${E.green}+ New file would be created${E.reset}\n${E.gray}Content preview:${E.reset}\n${i}${a?`
13
+ ...`:``}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function se(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${E.red}✗ File not found: ${e.file}${E.reset}`;try{let r=await T(n,`utf-8`),i=new RegExp(e.pattern,e.flags??`g`),a=S(e.replacement,t),o=r.replace(i,a);if(r===o)return`${E.cyan}→ No matches found${E.reset}`;let s=O(r,o);return`${E.blue}File: ${e.file}${E.reset}\n${s.join(`
14
+ `)}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function A(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${E.red}✗ File not found: ${e.file}${E.reset}`;try{let r=await T(n,`utf-8`),i=r;for(let{find:n,replace:i}of e.replacements){let e=S(n,t),a=S(i,t);r=r.replace(e,a)}if(i===r)return`${E.cyan}→ No changes${E.reset}`;let a=O(i,r);return`${E.blue}File: ${e.file}${E.reset}\n${a.join(`
15
+ `)}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}function j(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=e.paths.map(e=>S(e,t)).filter(e=>c.default.existsSync(l.default.join(u.default.cwd(),e)));return n.length===0?`${E.cyan}→ No files/directories to delete${E.reset}`:`${E.red}Would delete:${E.reset}\n${n.map(e=>`${E.red} - ${e}${E.reset}`).join(`
16
+ `)}`}function M(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=S(e.from,t),r=S(e.to,t),i=l.default.join(u.default.cwd(),n),a=l.default.join(u.default.cwd(),r);return c.default.existsSync(i)?c.default.existsSync(a)?`${E.yellow}⚠ Destination already exists: ${r}${E.reset}\n${E.cyan}Would rename: ${n} → ${r}${E.reset}`:`${E.cyan}Would rename: ${n} → ${r}${E.reset}`:`${E.red}✗ Source not found: ${n}${E.reset}`}function N(e){if(e.condition!=null&&e.condition!==``)return`${E.yellow}⊘ Condition check skipped in dry-run${E.reset}`;let t=l.default.join(u.default.cwd(),`.git`),n=c.default.existsSync(t),r=[];if(e.removeExisting&&n&&r.push(`${E.red}Would remove existing .git directory${E.reset}`),r.push(`${E.green}Would initialize git repository${E.reset}`),e.initialCommit){let t=e.message??`Initial commit`;r.push(`${E.green}Would create initial commit: "${t}"${E.reset}`)}return r.join(`
17
+ `)}function ce(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=S(e.command,t),r=e.cwd==null?u.default.cwd():S(e.cwd,t);return`${E.yellow}Would execute:${E.reset}\n${E.cyan} Command: ${n}${E.reset}\n${E.cyan} Working directory: ${r}${E.reset}`}async function P(e,t){try{switch(e.type){case`update-json`:return await k(e.config,t);case`template`:return await ae(e.config,t);case`create`:return await oe(e.config,t);case`regex-replace`:return await se(e.config,t);case`replace-in-file`:return await A(e.config,t);case`delete`:return j(e.config,t);case`rename`:return M(e.config,t);case`git-init`:return N(e.config);case`exec`:return ce(e.config,t);default:{let t=e.type;return`${E.yellow}⚠ Diff not available for task type: ${t}${E.reset}`}}}catch(e){return`${E.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function F(e,t){console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(`${E.blue} DRY RUN - Preview of changes${E.reset}`),console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`);for(let n of e){console.log(`${E.cyan}▶ Task: ${n.name}${E.reset}`),console.log(`${E.gray} ${n.description}${E.reset}`);let e=await P(n,t);console.log(e),console.log(`${E.gray}${`─`.repeat(55)}${E.reset}`)}console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(`${E.yellow} No changes were applied (dry-run mode)${E.reset}`),console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`)}const I=new Map,L={},R=new Map;function z(e){if(e.name==null||e.name===``)throw TypeError(`Plugin name is required`);if(!Array.isArray(e.taskTypes)||e.taskTypes.length===0)throw TypeError(`Plugin ${e.name} must define at least one task type`);if(typeof e.execute!=`function`)throw TypeError(`Plugin ${e.name} must provide an execute function`);if(I.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(R.has(t)){let e=R.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}I.set(e.name,e);for(let t of e.taskTypes)R.set(t,e.name);x(`✓ Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`,`info`)}function le(e){let t=I.get(e);if(t!=null){for(let e of t.taskTypes)R.delete(e);I.delete(e)}}function ue(e){return I.get(e)}function B(e){let t=R.get(e);if(t!=null)return I.get(t)}function V(e){return R.has(e)}function de(){return Array.from(I.keys())}function fe(){I.clear(),R.clear()}function pe(e){e.beforeAll!=null&&(L.beforeAll=e.beforeAll),e.afterAll!=null&&(L.afterAll=e.afterAll),e.beforeTask!=null&&(L.beforeTask=e.beforeTask),e.afterTask!=null&&(L.afterTask=e.afterTask),e.onError!=null&&(L.onError=e.onError)}async function H(e,...t){let n=L[e];if(n!=null)try{e===`beforeAll`||e===`afterAll`?await n(t[0]):(e===`beforeTask`||e===`afterTask`||e===`onError`)&&await n(t[0],t[1])}catch(t){x(`Error in ${e} hook: ${t instanceof Error?t.message:String(t)}`,`error`)}}async function U(e,t,n){let r=B(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}async function me(e,t){let n=B(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function he(e){let t=B(e.type);return t==null?[`No plugin found for task type: ${e.type}`]:t.validate==null?[]:t.validate(e)}function ge(e,t,n,r){return{name:e,...r?.version!=null&&{version:r.version},taskTypes:[t],execute:n,...r?.getDiff!=null&&{getDiff:r.getDiff},...r?.validate!=null&&{validate:r.validate}}}async function W(e,t=new Map,n={}){let r={};if(e.length===0)return r;for(let i of e){let e={...n,...r};if(_(i.enabled,e))try{let e,n=t.get(i.id);switch(i.type){case`input`:{let t={message:i.message};if(n!==void 0&&(t.default=String(n)),i.required!==void 0&&(t.required=i.required),e=await(0,h.input)(t),i.required&&(e==null||typeof e==`string`&&e.trim()===``))throw x(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break}case`password`:if(e=await(0,h.password)({message:i.message,mask:`*`}),i.required&&(e==null||typeof e==`string`&&e.trim()===``))throw x(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break;case`number`:{let t={message:i.message};if(n!==void 0&&(t.default=Number(n)),i.required!==void 0&&(t.required=i.required),i.min!==void 0&&(t.min=i.min),i.max!==void 0&&(t.max=i.max),e=await(0,h.number)(t),i.required&&e==null)throw x(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break}case`select`:{let t={message:i.message,choices:i.choices.map(e=>({name:e.name,value:e.value}))};n!==void 0&&(t.default=n),e=await(0,h.select)(t);break}case`confirm`:{let t=n===void 0?!1:!!n;e=await(0,h.confirm)({message:i.message,default:t});break}default:throw x(`Unknown prompt type: ${i.type}`,`error`),Error(`Unknown prompt type: ${i.type}`)}r[i.id]=e}catch(e){throw e instanceof Error&&x(`Failed to collect prompt "${i.id}": ${e.message}`,`error`),e}}return r}async function G(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`exec`){let e=n.value;if(typeof e!=`string`){x(`Prompt "${t}": exec default value must have a string command`,`error`);return}try{let t=(0,d.execSync)(e,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:1e4}).trim();if(t.startsWith(`{`)||t.startsWith(`[`))try{return JSON.parse(t)}catch{return t}if(/^-?\d+(?:\.\d+)?$/u.test(t)){let e=Number.parseFloat(t);if(!Number.isNaN(e))return e}return t===`true`||t===`false`?t===`true`:t}catch(e){x(`Prompt "${t}": failed to execute default value command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`static`)return n.value;return e}async function K(e){let t=new Map,n=e.map(async e=>{if(e.default!==void 0){let n=await G(e.default,e.id);n!==void 0&&t.set(e.id,n)}});return await Promise.all(n),t}function q(e){let t=[],n=new Set;for(let r of e){if(n.has(r.id)&&t.push(`Duplicate prompt ID: ${r.id}`),n.add(r.id),/^[\w-]+$/u.test(r.id)||t.push(`Invalid prompt ID "${r.id}": must contain only alphanumeric characters, underscores, and hyphens`),(!r.message||r.message.trim()===``)&&t.push(`Prompt "${r.id}" must have a non-empty message`),r.type===`select`){r.choices.length===0&&t.push(`Select prompt "${r.id}" must have at least one choice`);for(let e of r.choices)(!e.name||e.name.trim()===``)&&t.push(`Select prompt "${r.id}" has a choice with empty name`),e.value===void 0&&t.push(`Select prompt "${r.id}" has a choice with undefined value`)}r.type===`number`&&r.min!==void 0&&r.max!==void 0&&r.min>r.max&&t.push(`Number prompt "${r.id}" has min greater than max`)}return t}const _e=(0,f.promisify)(c.default.writeFile);async function ve(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`Condition not met, skipping create task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file);if(c.default.existsSync(n)){x(`File already exists, skipping: ${e.file}`,`info`);return}let r=e.template!=null&&e.template!==``,i=e.templateFile!=null&&e.templateFile!==``;if(!r&&!i)throw Error(`Create task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(r&&i)throw Error(`Create task cannot have both "template" and "templateFile" specified. Use one or the other.`);let a;if(i&&e.templateFile.endsWith(`.hbs`))a=ee(e.templateFile,t);else if(i){let n=e.templateFile,r=l.default.isAbsolute(n)?n:l.default.join(u.default.cwd(),n);if(!c.default.existsSync(r))throw Error(`Template file not found: ${n}`);a=S(c.default.readFileSync(r,`utf-8`),t)}else a=S(e.template,t);let o=l.default.dirname(n);c.default.existsSync(o)||c.default.mkdirSync(o,{recursive:!0}),await _e(n,a),x(`Created file: ${e.file}`,`success`)}const ye={name:`create`,version:`1.0.0`,taskTypes:[`create`],execute:async(e,t,n)=>{n.dryRun||await ve(e.config,t)}};async function be(e,t){let{paths:n,condition:r}=e;if(r!=null&&r!==``){if(!t){x(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!w(r,t)){x(`Condition not met, skipping deletion`,`info`);return}}for(let e of n){let t=l.default.join(u.default.cwd(),e);c.default.existsSync(t)&&c.default.rmSync(t,{recursive:!0,force:!0})}}const xe={name:`delete`,version:`1.0.0`,taskTypes:[`delete`],execute:async(e,t,n)=>{n.dryRun||await be(e.config,t)}};async function Se(e,t){if(e.condition!=null&&e.condition!==``){if(!t){x(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!w(e.condition,t)){x(`Condition not met, skipping exec task`,`info`);return}}let n=e.cwd==null?u.default.cwd():l.default.join(u.default.cwd(),e.cwd);(0,d.execSync)(e.command,{cwd:n,stdio:`inherit`})}const Ce={name:`exec`,version:`1.0.0`,taskTypes:[`exec`],execute:async(e,t,n)=>{n.dryRun||await Se(e.config,t)}};async function we(e,t){if(e.condition!=null&&e.condition!==``){if(!t){x(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!w(e.condition,t)){x(`Condition not met, skipping git-init task`,`info`);return}}if(e.removeExisting){let e=l.default.join(u.default.cwd(),`.git`);c.default.existsSync(e)&&c.default.rmSync(e,{recursive:!0,force:!0})}if((0,d.execSync)(`git init`,{stdio:`inherit`}),e.initialCommit){let t=e.message??`Initial commit`;(0,d.execSync)(`git add .`,{stdio:`inherit`}),(0,d.execSync)(`git commit -m "${t}"`,{stdio:`inherit`})}}const Te={name:`git-init`,version:`1.0.0`,taskTypes:[`git-init`],execute:async(e,t,n)=>{n.dryRun||await we(e.config,t)}},Ee=(0,f.promisify)(c.default.readFile),De=(0,f.promisify)(c.default.writeFile);async function Oe(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`Condition not met, skipping regex-replace task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{pattern:r}=e,i=e.flags??``,a=e.replacement||``,o=await Ee(n,`utf-8`),s=new RegExp(r,i);o=o.replace(s,S(a,t)),await De(n,o)}const ke={name:`regex-replace`,version:`1.0.0`,taskTypes:[`regex-replace`],execute:async(e,t,n)=>{n.dryRun||await Oe(e.config,t)}},Ae=(0,f.promisify)(c.default.rename);async function je(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`Condition not met, skipping rename task`,`info`);return}let n=l.default.join(u.default.cwd(),S(e.from,t)),r=l.default.join(u.default.cwd(),S(e.to,t));if(!c.default.existsSync(n)){x(`Source path does not exist: ${n}`,`warn`);return}await Ae(n,r)}const Me={name:`rename`,version:`1.0.0`,taskTypes:[`rename`],execute:async(e,t,n)=>{n.dryRun||await je(e.config,t)}},Ne=(0,f.promisify)(c.default.readFile),Pe=(0,f.promisify)(c.default.writeFile);async function Fe(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`Condition not met, skipping replace-in-file task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{replacements:r}=e;if(!c.default.existsSync(n)){x(`File not found: ${n}, skipping`,`warn`);return}let i=await Ne(n,`utf-8`);for(let{find:e,replace:n}of r){let r=S(n,t);i=i.replace(new RegExp(e,`gu`),r)}await Pe(n,i)}const Ie={name:`replace-in-file`,version:`1.0.0`,taskTypes:[`replace-in-file`],execute:async(e,t,n)=>{n.dryRun||await Fe(e.config,t)}},J=(0,f.promisify)(c.default.readFile);function Y(e){try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}}function X(e,t){if(Y(e))return e;if(t==null||t===``)return l.default.isAbsolute(e)?e:l.default.resolve(u.default.cwd(),e);if(Y(t))try{let n=new URL(`.`,t);return new URL(e,n).href}catch{throw Error(`Failed to resolve templateFile "${e}" relative to remote template "${t}"`)}let n=l.default.dirname(t);return l.default.isAbsolute(e)?e:l.default.resolve(n,e)}async function Le(e){if(Y(e))return Re(e);if(!c.default.existsSync(e))throw Error(`Template file not found: ${e}`);return J(e,`utf-8`)}async function Re(e){try{let t=await fetch(e);if(!t.ok)throw Error(`Failed to fetch template from ${e}: ${t.status} ${t.statusText}`);return await t.text()}catch(t){throw t instanceof Error&&t.message.includes(`Failed to fetch`)?t:Error(`Failed to fetch template from ${e}: ${t instanceof Error?t.message:String(t)}`)}}const Z=new Map;async function ze(e,t=new Set){let n=Y(e),r;if(r=n||l.default.isAbsolute(e)?e:l.default.resolve(u.default.cwd(),e),Z.has(r))return Z.get(r);if(t.has(r))throw Error(`Circular dependency detected: ${Array.from(t).join(` -> `)} -> ${r}`);t.add(r);let i;if(n)i=await Re(r);else{if(!c.default.existsSync(r))throw Error(`Template file not found: ${r}`);i=await J(r,`utf-8`)}let a;try{a=JSON.parse(i)}catch(e){throw Error(`Failed to parse template file ${r}: ${e instanceof Error?e.message:String(e)}`)}if(a.tasks!==void 0&&!Array.isArray(a.tasks))throw TypeError(`Invalid template file ${r}: 'tasks' must be an array if provided`);a.tasks===void 0&&(a.tasks=[]);for(let e of a.tasks)e.$sourceUrl=r;return Z.set(r,a),a}async function Q(e,t,n=new Set){let r=Y(e),i;if(i=r||l.default.isAbsolute(e)?e:t==null?l.default.resolve(u.default.cwd(),e):Y(t)?new URL(e,t).href:l.default.resolve(t,e),n.has(i))throw Error(`Circular dependency detected: ${Array.from(n).join(` -> `)} -> ${i}`);n.add(i);let a=await ze(i);if(a.extends==null||a.extends===``)return a;let o=Y(i)?new URL(`.`,i).href:l.default.dirname(i),s=Array.isArray(a.extends)?a.extends:[a.extends],c=[];for(let e of s){let t=await Q(e,o,n);c.push(t)}return Be([...c,a])}function Be(e){if(e.length===0)return{tasks:[]};if(e.length===1)return e[0];let t=new Map,n=new Map,r=new Map;for(let i of e){if(i.prompts!=null)for(let e of i.prompts)r.set(e.id,{...e});if(i.variables!=null)for(let e of i.variables)n.set(e.id,{...e});for(let e of i.tasks??[])if(t.has(e.id)){let n=t.get(e.id);t.set(e.id,Ve(n,e))}else t.set(e.id,{...e})}let i={tasks:Array.from(t.values())};return r.size>0&&(i.prompts=Array.from(r.values())),n.size>0&&(i.variables=Array.from(n.values())),i}function Ve(e,t){let n=typeof e.config==`object`&&e.config!==null&&typeof t.config==`object`&&t.config!==null?{...e.config,...t.config}:t.config,r=e.prompts?[...e.prompts]:void 0;if(t.prompts&&t.prompts.length>0)if(!r)r=[...t.prompts];else{let e=new Map(r.map(e=>[e.id,e]));for(let n of t.prompts)e.set(n.id,n);r=Array.from(e.values())}let i=e.variables?[...e.variables]:void 0;if(t.variables&&t.variables.length>0)if(!i)i=[...t.variables];else{let e=new Map(i.map(e=>[e.id,e]));for(let n of t.variables)e.set(n.id,n);i=Array.from(e.values())}let a=[...e.dependencies??[],...t.dependencies??[]],o=a.length>0?[...new Set(a)]:void 0,s=t.$sourceUrl??e.$sourceUrl;return{...e,...t,config:n,...r!=null&&{prompts:r},...i!=null&&{variables:i},...o!=null&&{dependencies:o},...s!=null&&{$sourceUrl:s}}}function He(){Z.clear()}async function Ue(e){x(`Loading tasks from ${e}...`,`info`);let t=await Q(e);x(`Loaded ${t.tasks?.length??0} task(s)`,`info`),t.extends!=null&&t.extends!==``&&x(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.prompts!=null&&t.prompts.length>0&&x(`Found ${t.prompts.length} top-level prompt(s)`,`info`),t.variables!=null&&t.variables.length>0&&x(`Found ${t.variables.length} top-level variable(s)`,`info`);let n={tasks:t.tasks??[]};return t.prompts!=null&&(n.prompts=t.prompts),t.variables!=null&&(n.variables=t.variables),n}const We=(0,f.promisify)(c.default.writeFile);async function Ge(e,t,n){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`Condition not met, skipping template task`,`info`);return}let r=l.default.join(u.default.cwd(),e.file),i=e.template!=null&&e.template!==``,a=e.templateFile!=null&&e.templateFile!==``;if(!i&&!a)throw Error(`Template task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(i&&a)throw Error(`Template task cannot have both "template" and "templateFile" specified. Use one or the other.`);let o;if(a&&e.templateFile.endsWith(`.hbs`)){let r=await Le(X(e.templateFile,n?.$sourceUrl));o=(await import(`handlebars`)).default.compile(r)(t)}else o=S(a?await Le(X(e.templateFile,n?.$sourceUrl)):e.template,t);await We(r,o)}const Ke={name:`template`,version:`1.0.0`,taskTypes:[`template`],execute:async(e,t,n)=>{n.dryRun||await Ge(e.config,t,e)}},qe=(0,f.promisify)(c.default.readFile),Je=(0,f.promisify)(c.default.writeFile),Ye=2;async function Xe(e,t){if(e.condition!=null&&e.condition!==``&&!w(e.condition,t)){x(`Condition not met, skipping update-json task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{updates:r}=e,i=await qe(n,`utf-8`),a=JSON.parse(i);function o(e){if(typeof e==`string`)return S(e,t);if(Array.isArray(e))return e.map(e=>o(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=o(r);return t}return e}for(let[e,t]of Object.entries(r)){let n=o(t);e.includes(`.`)?C(a,e,n):a[e]=n}await Je(n,`${JSON.stringify(a,null,2)}\n`)}const Ze={name:`update-json`,version:`1.0.0`,taskTypes:[`update-json`],execute:async(e,t,n)=>{n.dryRun||await Xe(e.config,t)}};let Qe=!1;function $e(){Qe||=(z(Ze),z(Ke),z(ye),z(ke),z(Ie),z(xe),z(Me),z(Te),z(Ce),!0)}async function et(e,t,n=!1){if($e(),n){x(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(V(e.type)){await U(e,t,{dryRun:n});return}throw TypeError(`Unknown task type: ${e.type}`)}async function tt(e,t,n,r,i=!1){try{return x(`[${n}/${r}] Running: ${e.name}...`,`info`),await et(e,t,i),x(`✓ ${e.name}`,`success`),!0}catch(t){return x(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(x(` Reason: ${t.message}`,`error`),t.stack!=null&&u.default.env.DEBUG!=null&&console.error(t.stack)),e.required&&x(` This is a required task. Initialization cannot continue.`,`error`),!1}}function $(e){let t=[],n=new Set,r=new Set,i=new Map(e.map(e=>[e.id,e]));function a(e){if(n.has(e))return;if(r.has(e))throw Error(`Circular dependency detected involving task: ${e}`);r.add(e);let o=i.get(e);if(!o)throw Error(`Task not found: ${e}`);if(o.dependencies)for(let e of o.dependencies)a(e);r.delete(e),n.add(e),t.push(o)}for(let t of e)n.has(t.id)||a(t.id);return t}function nt(e,t=new Map){let n={};for(let r of e){let e=t.get(r.id);e!==void 0&&(n[r.id]=e)}return n}async function rt(e,t){if(e==null)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`exec`){let e=n.value;if(typeof e!=`string`){x(`Variable "${t}": exec value must have a string command`,`error`);return}try{let t=(0,d.execSync)(e,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:1e4}).trim();if(t.startsWith(`{`)||t.startsWith(`[`))try{return JSON.parse(t)}catch{return t}if(/^-?\d+(?:\.\d+)?$/u.test(t)){let e=Number.parseFloat(t);if(!Number.isNaN(e))return e}return t===`true`||t===`false`?t===`true`:t}catch(e){x(`Variable "${t}": failed to execute command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`static`)return n.value;return e}async function it(e){let t=new Map,n=e.map(async e=>{let t=await rt(e.value,e.id);return{id:e.id,value:t}}),r=await Promise.all(n);for(let e of r)e.value!==void 0&&t.set(e.id,e.value);return t}function at(e){let t=[],n=new Set;for(let r of e)if(n.has(r.id)&&t.push(`Duplicate variable ID: "${r.id}"`),n.add(r.id),/^[\w$]+$/u.test(r.id)||t.push(`Variable ID "${r.id}" is invalid. Must contain only letters, numbers, underscore, or dollar sign.`),r.value===void 0||r.value===null)t.push(`Variable "${r.id}" must have a value`);else if(typeof r.value==`object`&&!Array.isArray(r.value)&&r.value!==null){let e=r.value;e.type==null||e.type===``?t.push(`Variable "${r.id}": value object must have a "type" field ("static" or "exec")`):e.type!==`static`&&e.type!==`exec`&&t.push(`Variable "${r.id}": type must be "static" or "exec", got "${e.type}"`),(e.value===void 0||e.value===null)&&t.push(`Variable "${r.id}": value config must have a "value" field`),e.type===`exec`&&typeof e.value!=`string`&&t.push(`Variable "${r.id}": exec type must have a string command as value`)}return t}const ot=(0,f.promisify)(c.default.readFile);async function st(e,t){let n=e.filter(e=>_(e.enabled,g()));x(`Resolving task dependencies...`,`info`);let r=$(n);x(`Welcome! Let's execute your tasks.`,`info`),t.dryRun&&x(`🔍 DRY RUN MODE - No changes will be made`,`warn`),x(`This will execute your project tasks based on the defined configuration.`,`info`);let i=g(),a=t.globalVariables??[],o=[],s=[...a];for(let e of r)if(e.variables&&e.variables.length>0)for(let t of e.variables)o.push(t),s.push(t);if(s.length>0){let e=at(s);e.length>0&&(x(`❌ Variable validation errors:`,`error`),e.forEach(e=>x(` - ${e}`,`error`)),u.default.exit(1)),x(`Resolving variable values...`,`info`);let t=nt(s,await it(s));Object.assign(i,t),Object.keys(t).length>0&&x(`✓ Resolved ${Object.keys(t).length} variable(s)`,`success`)}let f=t.globalPrompts??[],p=[],m=[...f];for(let e of r)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)p.push(t),m.push(t);if(m.length>0){let e=q(m);e.length>0&&(x(`❌ Prompt validation errors:`,`error`),e.forEach(e=>x(` - ${e}`,`error`)),u.default.exit(1)),x(`Resolving prompt default values...`,`info`);let t=await K(m),n={};if(f.length>0&&(x(`📋 Top-level prompts (available to all tasks):`,`info`),n=await W(f,t,i),Object.assign(i,n)),p.length>0){f.length>0&&x(`📋 Task-specific prompts:`,`info`);let e=await W(p,t,i);Object.assign(i,e)}}let h=r.filter(e=>_(e.enabled,i));if(x(`${h.length} of ${r.length} task(s) enabled for execution`,`info`),t.dryRun){await F(h,i),x(`🔍 Dry run completed - no changes were made`,`info`),x(`Run without --dry-run to apply changes`,`info`);return}x(`Starting task execution...`,`info`),await H(`beforeAll`,i);let v=h.length,y=0,S=0,C=[];for(let e=0;e<h.length;e++){let n=h[e];if(n!=null)if(await H(`beforeTask`,n,i),await tt(n,i,e+1,v,t.dryRun))y++,C.push(n.id),await H(`afterTask`,n,i);else if(n.required){S++,await H(`onError`,Error(`Task ${n.name} failed`),n);break}else x(`⚠️ Non-critical task failed, continuing...`,`warn`),await H(`onError`,Error(`Task ${n.name} failed`),n)}if(S>0&&(x(`❌ Task execution failed with ${S} critical error(s)`,`error`),x(`✓ Completed: ${y}/${v} tasks`,`info`),u.default.exit(1)),await H(`afterAll`,i),x(`✅ All tasks completed successfully!`,`success`),x(`✓ Completed: ${y}/${v} tasks`,`success`),!t.dryRun){x(`Next steps:`,`info`),x(`1. Review the changes made to your project`,`info`),x(`2. Commit the changes to git`,`info`);let e=l.default.join(u.default.cwd(),`package.json`);c.default.existsSync(e)&&JSON.parse(await ot(e,`utf-8`)).scripts?.[`turbo:gen:init`]!=null&&(x(`3. Run "pnpm run turbo:gen:init" to create your first package`,`info`),await b(`Would you like to run turbo:gen:init now?`,!0)&&(x(`Running turbo:gen:init...`,`info`),(0,d.execSync)(`pnpm run turbo:gen:init`,{stdio:`inherit`})))}}const ct=u.default.argv.includes(`--dry-run`),lt=u.default.argv.includes(`--force`);async function ut(e){try{let t=e||[];t.length===0&&(x(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),x(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),u.default.exit(1)),await st(t,{dryRun:ct,force:lt,tasksFilePath:void 0})}catch(e){x(`❌ Task execution failed`,`error`),e instanceof Error?(x(`Error: ${e.message}`,`error`),u.default.env.DEBUG!=null&&console.error(e.stack)):console.error(e),u.default.exit(1)}}async function dt(e,t){try{await st(e,{dryRun:t?.dryRun??ct,force:t?.force??lt,tasksFilePath:t?.tasksFilePath??void 0,...t?.globalVariables!=null&&{globalVariables:t.globalVariables},...t?.globalPrompts!=null&&{globalPrompts:t.globalPrompts}})}catch(e){x(`❌ Task execution failed`,`error`),e instanceof Error?(x(`Error: ${e.message}`,`error`),u.default.env.DEBUG!=null&&console.error(e.stack)):console.error(e),u.default.exit(1)}}Object.defineProperty(exports,`A`,{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,`B`,{enumerable:!0,get:function(){return ae}}),Object.defineProperty(exports,`C`,{enumerable:!0,get:function(){return ue}}),Object.defineProperty(exports,`D`,{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,`E`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`F`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`G`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`H`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`I`,{enumerable:!0,get:function(){return se}}),Object.defineProperty(exports,`J`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`K`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`L`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`M`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`N`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`O`,{enumerable:!0,get:function(){return pe}}),Object.defineProperty(exports,`P`,{enumerable:!0,get:function(){return ce}}),Object.defineProperty(exports,`R`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`T`,{enumerable:!0,get:function(){return me}}),Object.defineProperty(exports,`U`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`V`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`W`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`Y`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return rt}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return et}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return Ue}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return it}}),Object.defineProperty(exports,`j`,{enumerable:!0,get:function(){return he}}),Object.defineProperty(exports,`k`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return tt}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return Be}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return dt}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return nt}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return ze}}),Object.defineProperty(exports,`q`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return at}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return ut}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return He}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`w`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`z`,{enumerable:!0,get:function(){return P}});
@@ -0,0 +1,17 @@
1
+ import e from"node:path";import t from"node:fs";import n from"node:process";import{execSync as r}from"node:child_process";import{promisify as i}from"node:util";import a from"node:readline";import o from"handlebars";import{confirm as s,input as c,number as l,password as u,select as d}from"@inquirer/prompts";function f(){return{}}function p(e,t){return e===void 0?!0:typeof e==`boolean`?e:typeof e==`object`&&`condition`in e?b(e.condition,t):!1}function m(){try{let e=r(`git remote get-url origin`,{encoding:`utf-8`}).trim(),t=e.match(/github\.com[:/](?<owner>[^/]+)\/(?<name>[^/]+)$/u);if(t?.groups){let{owner:n,name:r}=t.groups,i=r;return i.endsWith(`.git`)&&(i=i.slice(0,-4)),{owner:n,name:i,url:e}}return null}catch{return null}}async function h(e,t){let r=a.createInterface({input:n.stdin,output:n.stdout});return new Promise(n=>{let i;i=t==null?`${e}: `:`${e} (${t}): `,r.question(i,e=>{r.close(),n(e.trim()||(t??``))})})}async function g(e,t=!1){return h(`${e} (${t?`Y/n`:`y/N`})`,t?`y`:`n`).then(e=>e.toLowerCase()===`y`||e.toLowerCase()===`yes`)}function _(e,t=`info`){console.log(`${{info:`\x1B[36m`,success:`\x1B[32m`,error:`\x1B[31m`,warn:`\x1B[33m`}[t]}${{info:`ℹ`,success:`✓`,error:`✗`,warn:`⚠`}[t]} ${e}`)}function v(e,t){return e.replace(/\{\{(?<key>\w+)\}\}/gu,(e,n)=>t[n]?.toString()??``)}function y(e,t,n){let r=t.split(`.`),i=e;for(let e=0;e<r.length-1;e++){let t=r[e];t!=null&&t!==``&&((!(t in i)||typeof i[t]!=`object`||i[t]===null)&&(i[t]={}),i=i[t])}let a=r[r.length-1];a!=null&&a!==``&&(i[a]=n)}function b(e,t){try{let n={...t};return Function(...Object.keys(n),`'use strict'; return (${e})`)(...Object.values(n))}catch(t){return _(`Failed to evaluate condition: ${e}`,`warn`),t instanceof Error&&_(` Error: ${t.message}`,`warn`),!1}}function x(r,i){try{let a=e.isAbsolute(r)?r:e.join(n.cwd(),r);if(!t.existsSync(a))throw Error(`Template file not found: ${r}`);return S(t.readFileSync(a,`utf-8`),i)}catch(e){throw _(`Failed to read template file: ${r}`,`error`),e instanceof Error&&_(` Error: ${e.message}`,`error`),e}}function S(e,t){try{return o.compile(e)(t)}catch(e){throw _(`Failed to compile Handlebars template`,`error`),e instanceof Error&&_(` Error: ${e.message}`,`error`),e}}const C=i(t.readFile),w={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,cyan:`\x1B[36m`,gray:`\x1B[90m`};function T(e,t){switch(t){case`add`:return`${w.green}+ ${e}${w.reset}`;case`remove`:return`${w.red}- ${e}${w.reset}`;case`context`:return`${w.gray} ${e}${w.reset}`;default:return e}}function E(e,t){let n=e.split(`
2
+ `),r=t.split(`
3
+ `),i=[],a=Math.max(n.length,r.length);for(let e=0;e<a;e++){let t=n[e],a=r[e];t===a?t!==void 0&&i.push(T(t,`context`)):(t!==void 0&&i.push(T(t,`remove`)),a!==void 0&&i.push(T(a,`add`)))}return i}async function D(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${w.red}✗ File not found: ${r.file}${w.reset}`;try{let e=await C(a,`utf-8`),t=JSON.parse(e),n={...t};function o(e){if(typeof e==`string`)return v(e,i);if(Array.isArray(e))return e.map(e=>o(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=o(r);return t}return e}for(let[e,n]of Object.entries(r.updates)){let r=o(n);e.includes(`.`)?y(t,e,r):t[e]=r}let s=JSON.stringify(n,null,2),c=JSON.stringify(t,null,2);if(s===c)return`${w.cyan}→ No changes${w.reset}`;let l=E(s,c);return`${w.blue}File: ${r.file}${w.reset}\n${l.join(`
4
+ `)}`}catch(e){return`${w.red}✗ Error: ${e instanceof Error?e.message:String(e)}${w.reset}`}}async function O(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;if(r.template==null||r.template===``)return`${w.red}✗ No template content provided for file: ${r.file}${w.reset}`;let a=e.join(n.cwd(),r.file),o=v(r.template,i);if(!t.existsSync(a)){let e=o.split(`
5
+ `).slice(0,10).join(`
6
+ `),t=o.split(`
7
+ `).length>10;return`${w.blue}File: ${r.file}${w.reset}\n${w.green}+ New file would be created${w.reset}\n${w.gray}Content preview:${w.reset}\n${e}${t?`
8
+ ...`:``}`}try{let e=await C(a,`utf-8`);if(e===o)return`${w.cyan}→ No changes${w.reset}`;let t=E(e,o);return`${w.blue}File: ${r.file}${w.reset}\n${t.join(`
9
+ `)}`}catch(e){return`${w.red}✗ Error: ${e instanceof Error?e.message:String(e)}${w.reset}`}}async function ee(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let a=e.join(n.cwd(),r.file);if(t.existsSync(a))return`${w.cyan}→ File already exists, would be skipped: ${r.file}${w.reset}`;let o=r.template!=null&&r.template!==``,s=r.templateFile!=null&&r.templateFile!==``;if(!o&&!s)return`${w.red}✗ No template content provided for file: ${r.file}${w.reset}`;try{let e;if(o)e=v(r.template,i);else return`${w.blue}File: ${r.file}${w.reset}\n${w.green}+ New file would be created from template: ${r.templateFile}${w.reset}`;let t=e.split(`
10
+ `).slice(0,10).join(`
11
+ `),n=e.split(`
12
+ `).length>10;return`${w.blue}File: ${r.file}${w.reset}\n${w.green}+ New file would be created${w.reset}\n${w.gray}Content preview:${w.reset}\n${t}${n?`
13
+ ...`:``}`}catch(e){return`${w.red}✗ Error: ${e instanceof Error?e.message:String(e)}${w.reset}`}}async function k(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${w.red}✗ File not found: ${r.file}${w.reset}`;try{let e=await C(a,`utf-8`),t=new RegExp(r.pattern,r.flags??`g`),n=v(r.replacement,i),o=e.replace(t,n);if(e===o)return`${w.cyan}→ No matches found${w.reset}`;let s=E(e,o);return`${w.blue}File: ${r.file}${w.reset}\n${s.join(`
14
+ `)}`}catch(e){return`${w.red}✗ Error: ${e instanceof Error?e.message:String(e)}${w.reset}`}}async function A(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${w.red}✗ File not found: ${r.file}${w.reset}`;try{let e=await C(a,`utf-8`),t=e;for(let{find:t,replace:n}of r.replacements){let r=v(t,i),a=v(n,i);e=e.replace(r,a)}if(t===e)return`${w.cyan}→ No changes${w.reset}`;let n=E(t,e);return`${w.blue}File: ${r.file}${w.reset}\n${n.join(`
15
+ `)}`}catch(e){return`${w.red}✗ Error: ${e instanceof Error?e.message:String(e)}${w.reset}`}}function j(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let a=r.paths.map(e=>v(e,i)).filter(r=>t.existsSync(e.join(n.cwd(),r)));return a.length===0?`${w.cyan}→ No files/directories to delete${w.reset}`:`${w.red}Would delete:${w.reset}\n${a.map(e=>`${w.red} - ${e}${w.reset}`).join(`
16
+ `)}`}function M(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let a=v(r.from,i),o=v(r.to,i),s=e.join(n.cwd(),a),c=e.join(n.cwd(),o);return t.existsSync(s)?t.existsSync(c)?`${w.yellow}⚠ Destination already exists: ${o}${w.reset}\n${w.cyan}Would rename: ${a} → ${o}${w.reset}`:`${w.cyan}Would rename: ${a} → ${o}${w.reset}`:`${w.red}✗ Source not found: ${a}${w.reset}`}function te(r){if(r.condition!=null&&r.condition!==``)return`${w.yellow}⊘ Condition check skipped in dry-run${w.reset}`;let i=e.join(n.cwd(),`.git`),a=t.existsSync(i),o=[];if(r.removeExisting&&a&&o.push(`${w.red}Would remove existing .git directory${w.reset}`),o.push(`${w.green}Would initialize git repository${w.reset}`),r.initialCommit){let e=r.message??`Initial commit`;o.push(`${w.green}Would create initial commit: "${e}"${w.reset}`)}return o.join(`
17
+ `)}function ne(e,t){if(e.condition!=null&&e.condition!==``&&!b(e.condition,t))return`${w.yellow}⊘ Condition not met - task would be skipped${w.reset}`;let r=v(e.command,t),i=e.cwd==null?n.cwd():v(e.cwd,t);return`${w.yellow}Would execute:${w.reset}\n${w.cyan} Command: ${r}${w.reset}\n${w.cyan} Working directory: ${i}${w.reset}`}async function re(e,t){try{switch(e.type){case`update-json`:return await D(e.config,t);case`template`:return await O(e.config,t);case`create`:return await ee(e.config,t);case`regex-replace`:return await k(e.config,t);case`replace-in-file`:return await A(e.config,t);case`delete`:return j(e.config,t);case`rename`:return M(e.config,t);case`git-init`:return te(e.config);case`exec`:return ne(e.config,t);default:{let t=e.type;return`${w.yellow}⚠ Diff not available for task type: ${t}${w.reset}`}}}catch(e){return`${w.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${w.reset}`}}async function N(e,t){console.log(`${w.blue}═══════════════════════════════════════════════════════${w.reset}`),console.log(`${w.blue} DRY RUN - Preview of changes${w.reset}`),console.log(`${w.blue}═══════════════════════════════════════════════════════${w.reset}`);for(let n of e){console.log(`${w.cyan}▶ Task: ${n.name}${w.reset}`),console.log(`${w.gray} ${n.description}${w.reset}`);let e=await re(n,t);console.log(e),console.log(`${w.gray}${`─`.repeat(55)}${w.reset}`)}console.log(`${w.blue}═══════════════════════════════════════════════════════${w.reset}`),console.log(`${w.yellow} No changes were applied (dry-run mode)${w.reset}`),console.log(`${w.blue}═══════════════════════════════════════════════════════${w.reset}`)}const P=new Map,F={},I=new Map;function L(e){if(e.name==null||e.name===``)throw TypeError(`Plugin name is required`);if(!Array.isArray(e.taskTypes)||e.taskTypes.length===0)throw TypeError(`Plugin ${e.name} must define at least one task type`);if(typeof e.execute!=`function`)throw TypeError(`Plugin ${e.name} must provide an execute function`);if(P.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(I.has(t)){let e=I.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}P.set(e.name,e);for(let t of e.taskTypes)I.set(t,e.name);_(`✓ Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`,`info`)}function ie(e){let t=P.get(e);if(t!=null){for(let e of t.taskTypes)I.delete(e);P.delete(e)}}function ae(e){return P.get(e)}function R(e){let t=I.get(e);if(t!=null)return P.get(t)}function z(e){return I.has(e)}function oe(){return Array.from(P.keys())}function se(){P.clear(),I.clear()}function ce(e){e.beforeAll!=null&&(F.beforeAll=e.beforeAll),e.afterAll!=null&&(F.afterAll=e.afterAll),e.beforeTask!=null&&(F.beforeTask=e.beforeTask),e.afterTask!=null&&(F.afterTask=e.afterTask),e.onError!=null&&(F.onError=e.onError)}async function B(e,...t){let n=F[e];if(n!=null)try{e===`beforeAll`||e===`afterAll`?await n(t[0]):(e===`beforeTask`||e===`afterTask`||e===`onError`)&&await n(t[0],t[1])}catch(t){_(`Error in ${e} hook: ${t instanceof Error?t.message:String(t)}`,`error`)}}async function V(e,t,n){let r=R(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}async function le(e,t){let n=R(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function ue(e){let t=R(e.type);return t==null?[`No plugin found for task type: ${e.type}`]:t.validate==null?[]:t.validate(e)}function de(e,t,n,r){return{name:e,...r?.version!=null&&{version:r.version},taskTypes:[t],execute:n,...r?.getDiff!=null&&{getDiff:r.getDiff},...r?.validate!=null&&{validate:r.validate}}}async function H(e,t=new Map,n={}){let r={};if(e.length===0)return r;for(let i of e){let e={...n,...r};if(p(i.enabled,e))try{let e,n=t.get(i.id);switch(i.type){case`input`:{let t={message:i.message};if(n!==void 0&&(t.default=String(n)),i.required!==void 0&&(t.required=i.required),e=await c(t),i.required&&(e==null||typeof e==`string`&&e.trim()===``))throw _(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break}case`password`:if(e=await u({message:i.message,mask:`*`}),i.required&&(e==null||typeof e==`string`&&e.trim()===``))throw _(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break;case`number`:{let t={message:i.message};if(n!==void 0&&(t.default=Number(n)),i.required!==void 0&&(t.required=i.required),i.min!==void 0&&(t.min=i.min),i.max!==void 0&&(t.max=i.max),e=await l(t),i.required&&e==null)throw _(`${i.message} is required`,`error`),Error(`Prompt "${i.id}" is required`);break}case`select`:{let t={message:i.message,choices:i.choices.map(e=>({name:e.name,value:e.value}))};n!==void 0&&(t.default=n),e=await d(t);break}case`confirm`:{let t=n===void 0?!1:!!n;e=await s({message:i.message,default:t});break}default:throw _(`Unknown prompt type: ${i.type}`,`error`),Error(`Unknown prompt type: ${i.type}`)}r[i.id]=e}catch(e){throw e instanceof Error&&_(`Failed to collect prompt "${i.id}": ${e.message}`,`error`),e}}return r}async function U(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`exec`){let e=n.value;if(typeof e!=`string`){_(`Prompt "${t}": exec default value must have a string command`,`error`);return}try{let t=r(e,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:1e4}).trim();if(t.startsWith(`{`)||t.startsWith(`[`))try{return JSON.parse(t)}catch{return t}if(/^-?\d+(?:\.\d+)?$/u.test(t)){let e=Number.parseFloat(t);if(!Number.isNaN(e))return e}return t===`true`||t===`false`?t===`true`:t}catch(e){_(`Prompt "${t}": failed to execute default value command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`static`)return n.value;return e}async function W(e){let t=new Map,n=e.map(async e=>{if(e.default!==void 0){let n=await U(e.default,e.id);n!==void 0&&t.set(e.id,n)}});return await Promise.all(n),t}function G(e){let t=[],n=new Set;for(let r of e){if(n.has(r.id)&&t.push(`Duplicate prompt ID: ${r.id}`),n.add(r.id),/^[\w-]+$/u.test(r.id)||t.push(`Invalid prompt ID "${r.id}": must contain only alphanumeric characters, underscores, and hyphens`),(!r.message||r.message.trim()===``)&&t.push(`Prompt "${r.id}" must have a non-empty message`),r.type===`select`){r.choices.length===0&&t.push(`Select prompt "${r.id}" must have at least one choice`);for(let e of r.choices)(!e.name||e.name.trim()===``)&&t.push(`Select prompt "${r.id}" has a choice with empty name`),e.value===void 0&&t.push(`Select prompt "${r.id}" has a choice with undefined value`)}r.type===`number`&&r.min!==void 0&&r.max!==void 0&&r.min>r.max&&t.push(`Number prompt "${r.id}" has min greater than max`)}return t}const fe=i(t.writeFile);async function pe(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i)){_(`Condition not met, skipping create task`,`info`);return}let a=e.join(n.cwd(),r.file);if(t.existsSync(a)){_(`File already exists, skipping: ${r.file}`,`info`);return}let o=r.template!=null&&r.template!==``,s=r.templateFile!=null&&r.templateFile!==``;if(!o&&!s)throw Error(`Create task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(o&&s)throw Error(`Create task cannot have both "template" and "templateFile" specified. Use one or the other.`);let c;if(s&&r.templateFile.endsWith(`.hbs`))c=x(r.templateFile,i);else if(s){let a=r.templateFile,o=e.isAbsolute(a)?a:e.join(n.cwd(),a);if(!t.existsSync(o))throw Error(`Template file not found: ${a}`);c=v(t.readFileSync(o,`utf-8`),i)}else c=v(r.template,i);let l=e.dirname(a);t.existsSync(l)||t.mkdirSync(l,{recursive:!0}),await fe(a,c),_(`Created file: ${r.file}`,`success`)}const me={name:`create`,version:`1.0.0`,taskTypes:[`create`],execute:async(e,t,n)=>{n.dryRun||await pe(e.config,t)}};async function he(r,i){let{paths:a,condition:o}=r;if(o!=null&&o!==``){if(!i){_(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!b(o,i)){_(`Condition not met, skipping deletion`,`info`);return}}for(let r of a){let i=e.join(n.cwd(),r);t.existsSync(i)&&t.rmSync(i,{recursive:!0,force:!0})}}const ge={name:`delete`,version:`1.0.0`,taskTypes:[`delete`],execute:async(e,t,n)=>{n.dryRun||await he(e.config,t)}};async function _e(t,i){if(t.condition!=null&&t.condition!==``){if(!i){_(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!b(t.condition,i)){_(`Condition not met, skipping exec task`,`info`);return}}let a=t.cwd==null?n.cwd():e.join(n.cwd(),t.cwd);r(t.command,{cwd:a,stdio:`inherit`})}const ve={name:`exec`,version:`1.0.0`,taskTypes:[`exec`],execute:async(e,t,n)=>{n.dryRun||await _e(e.config,t)}};async function ye(i,a){if(i.condition!=null&&i.condition!==``){if(!a){_(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!b(i.condition,a)){_(`Condition not met, skipping git-init task`,`info`);return}}if(i.removeExisting){let r=e.join(n.cwd(),`.git`);t.existsSync(r)&&t.rmSync(r,{recursive:!0,force:!0})}if(r(`git init`,{stdio:`inherit`}),i.initialCommit){let e=i.message??`Initial commit`;r(`git add .`,{stdio:`inherit`}),r(`git commit -m "${e}"`,{stdio:`inherit`})}}const be={name:`git-init`,version:`1.0.0`,taskTypes:[`git-init`],execute:async(e,t,n)=>{n.dryRun||await ye(e.config,t)}},xe=i(t.readFile),Se=i(t.writeFile);async function Ce(t,r){if(t.condition!=null&&t.condition!==``&&!b(t.condition,r)){_(`Condition not met, skipping regex-replace task`,`info`);return}let i=e.join(n.cwd(),t.file),{pattern:a}=t,o=t.flags??``,s=t.replacement||``,c=await xe(i,`utf-8`),l=new RegExp(a,o);c=c.replace(l,v(s,r)),await Se(i,c)}const we={name:`regex-replace`,version:`1.0.0`,taskTypes:[`regex-replace`],execute:async(e,t,n)=>{n.dryRun||await Ce(e.config,t)}},Te=i(t.rename);async function Ee(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i)){_(`Condition not met, skipping rename task`,`info`);return}let a=e.join(n.cwd(),v(r.from,i)),o=e.join(n.cwd(),v(r.to,i));if(!t.existsSync(a)){_(`Source path does not exist: ${a}`,`warn`);return}await Te(a,o)}const De={name:`rename`,version:`1.0.0`,taskTypes:[`rename`],execute:async(e,t,n)=>{n.dryRun||await Ee(e.config,t)}},Oe=i(t.readFile),ke=i(t.writeFile);async function Ae(r,i){if(r.condition!=null&&r.condition!==``&&!b(r.condition,i)){_(`Condition not met, skipping replace-in-file task`,`info`);return}let a=e.join(n.cwd(),r.file),{replacements:o}=r;if(!t.existsSync(a)){_(`File not found: ${a}, skipping`,`warn`);return}let s=await Oe(a,`utf-8`);for(let{find:e,replace:t}of o){let n=v(t,i);s=s.replace(new RegExp(e,`gu`),n)}await ke(a,s)}const je={name:`replace-in-file`,version:`1.0.0`,taskTypes:[`replace-in-file`],execute:async(e,t,n)=>{n.dryRun||await Ae(e.config,t)}},K=i(t.readFile);function q(e){try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}}function J(t,r){if(q(t))return t;if(r==null||r===``)return e.isAbsolute(t)?t:e.resolve(n.cwd(),t);if(q(r))try{let e=new URL(`.`,r);return new URL(t,e).href}catch{throw Error(`Failed to resolve templateFile "${t}" relative to remote template "${r}"`)}let i=e.dirname(r);return e.isAbsolute(t)?t:e.resolve(i,t)}async function Y(e){if(q(e))return X(e);if(!t.existsSync(e))throw Error(`Template file not found: ${e}`);return K(e,`utf-8`)}async function X(e){try{let t=await fetch(e);if(!t.ok)throw Error(`Failed to fetch template from ${e}: ${t.status} ${t.statusText}`);return await t.text()}catch(t){throw t instanceof Error&&t.message.includes(`Failed to fetch`)?t:Error(`Failed to fetch template from ${e}: ${t instanceof Error?t.message:String(t)}`)}}const Z=new Map;async function Me(r,i=new Set){let a=q(r),o;if(o=a||e.isAbsolute(r)?r:e.resolve(n.cwd(),r),Z.has(o))return Z.get(o);if(i.has(o))throw Error(`Circular dependency detected: ${Array.from(i).join(` -> `)} -> ${o}`);i.add(o);let s;if(a)s=await X(o);else{if(!t.existsSync(o))throw Error(`Template file not found: ${o}`);s=await K(o,`utf-8`)}let c;try{c=JSON.parse(s)}catch(e){throw Error(`Failed to parse template file ${o}: ${e instanceof Error?e.message:String(e)}`)}if(c.tasks!==void 0&&!Array.isArray(c.tasks))throw TypeError(`Invalid template file ${o}: 'tasks' must be an array if provided`);c.tasks===void 0&&(c.tasks=[]);for(let e of c.tasks)e.$sourceUrl=o;return Z.set(o,c),c}async function Q(t,r,i=new Set){let a=q(t),o;if(o=a||e.isAbsolute(t)?t:r==null?e.resolve(n.cwd(),t):q(r)?new URL(t,r).href:e.resolve(r,t),i.has(o))throw Error(`Circular dependency detected: ${Array.from(i).join(` -> `)} -> ${o}`);i.add(o);let s=await Me(o);if(s.extends==null||s.extends===``)return s;let c=q(o)?new URL(`.`,o).href:e.dirname(o),l=Array.isArray(s.extends)?s.extends:[s.extends],u=[];for(let e of l){let t=await Q(e,c,i);u.push(t)}return Ne([...u,s])}function Ne(e){if(e.length===0)return{tasks:[]};if(e.length===1)return e[0];let t=new Map,n=new Map,r=new Map;for(let i of e){if(i.prompts!=null)for(let e of i.prompts)r.set(e.id,{...e});if(i.variables!=null)for(let e of i.variables)n.set(e.id,{...e});for(let e of i.tasks??[])if(t.has(e.id)){let n=t.get(e.id);t.set(e.id,Pe(n,e))}else t.set(e.id,{...e})}let i={tasks:Array.from(t.values())};return r.size>0&&(i.prompts=Array.from(r.values())),n.size>0&&(i.variables=Array.from(n.values())),i}function Pe(e,t){let n=typeof e.config==`object`&&e.config!==null&&typeof t.config==`object`&&t.config!==null?{...e.config,...t.config}:t.config,r=e.prompts?[...e.prompts]:void 0;if(t.prompts&&t.prompts.length>0)if(!r)r=[...t.prompts];else{let e=new Map(r.map(e=>[e.id,e]));for(let n of t.prompts)e.set(n.id,n);r=Array.from(e.values())}let i=e.variables?[...e.variables]:void 0;if(t.variables&&t.variables.length>0)if(!i)i=[...t.variables];else{let e=new Map(i.map(e=>[e.id,e]));for(let n of t.variables)e.set(n.id,n);i=Array.from(e.values())}let a=[...e.dependencies??[],...t.dependencies??[]],o=a.length>0?[...new Set(a)]:void 0,s=t.$sourceUrl??e.$sourceUrl;return{...e,...t,config:n,...r!=null&&{prompts:r},...i!=null&&{variables:i},...o!=null&&{dependencies:o},...s!=null&&{$sourceUrl:s}}}function Fe(){Z.clear()}async function Ie(e){_(`Loading tasks from ${e}...`,`info`);let t=await Q(e);_(`Loaded ${t.tasks?.length??0} task(s)`,`info`),t.extends!=null&&t.extends!==``&&_(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.prompts!=null&&t.prompts.length>0&&_(`Found ${t.prompts.length} top-level prompt(s)`,`info`),t.variables!=null&&t.variables.length>0&&_(`Found ${t.variables.length} top-level variable(s)`,`info`);let n={tasks:t.tasks??[]};return t.prompts!=null&&(n.prompts=t.prompts),t.variables!=null&&(n.variables=t.variables),n}const Le=i(t.writeFile);async function Re(t,r,i){if(t.condition!=null&&t.condition!==``&&!b(t.condition,r)){_(`Condition not met, skipping template task`,`info`);return}let a=e.join(n.cwd(),t.file),o=t.template!=null&&t.template!==``,s=t.templateFile!=null&&t.templateFile!==``;if(!o&&!s)throw Error(`Template task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(o&&s)throw Error(`Template task cannot have both "template" and "templateFile" specified. Use one or the other.`);let c;if(s&&t.templateFile.endsWith(`.hbs`)){let e=await Y(J(t.templateFile,i?.$sourceUrl));c=(await import(`handlebars`)).default.compile(e)(r)}else c=v(s?await Y(J(t.templateFile,i?.$sourceUrl)):t.template,r);await Le(a,c)}const ze={name:`template`,version:`1.0.0`,taskTypes:[`template`],execute:async(e,t,n)=>{n.dryRun||await Re(e.config,t,e)}},Be=i(t.readFile),Ve=i(t.writeFile);async function He(t,r){if(t.condition!=null&&t.condition!==``&&!b(t.condition,r)){_(`Condition not met, skipping update-json task`,`info`);return}let i=e.join(n.cwd(),t.file),{updates:a}=t,o=await Be(i,`utf-8`),s=JSON.parse(o);function c(e){if(typeof e==`string`)return v(e,r);if(Array.isArray(e))return e.map(e=>c(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=c(r);return t}return e}for(let[e,t]of Object.entries(a)){let n=c(t);e.includes(`.`)?y(s,e,n):s[e]=n}await Ve(i,`${JSON.stringify(s,null,2)}\n`)}const Ue={name:`update-json`,version:`1.0.0`,taskTypes:[`update-json`],execute:async(e,t,n)=>{n.dryRun||await He(e.config,t)}};let We=!1;function Ge(){We||=(L(Ue),L(ze),L(me),L(we),L(je),L(ge),L(De),L(be),L(ve),!0)}async function Ke(e,t,n=!1){if(Ge(),n){_(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(z(e.type)){await V(e,t,{dryRun:n});return}throw TypeError(`Unknown task type: ${e.type}`)}async function qe(e,t,r,i,a=!1){try{return _(`[${r}/${i}] Running: ${e.name}...`,`info`),await Ke(e,t,a),_(`✓ ${e.name}`,`success`),!0}catch(t){return _(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(_(` Reason: ${t.message}`,`error`),t.stack!=null&&n.env.DEBUG!=null&&console.error(t.stack)),e.required&&_(` This is a required task. Initialization cannot continue.`,`error`),!1}}function Je(e){let t=[],n=new Set,r=new Set,i=new Map(e.map(e=>[e.id,e]));function a(e){if(n.has(e))return;if(r.has(e))throw Error(`Circular dependency detected involving task: ${e}`);r.add(e);let o=i.get(e);if(!o)throw Error(`Task not found: ${e}`);if(o.dependencies)for(let e of o.dependencies)a(e);r.delete(e),n.add(e),t.push(o)}for(let t of e)n.has(t.id)||a(t.id);return t}function $(e,t=new Map){let n={};for(let r of e){let e=t.get(r.id);e!==void 0&&(n[r.id]=e)}return n}async function Ye(e,t){if(e==null)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`exec`){let e=n.value;if(typeof e!=`string`){_(`Variable "${t}": exec value must have a string command`,`error`);return}try{let t=r(e,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:1e4}).trim();if(t.startsWith(`{`)||t.startsWith(`[`))try{return JSON.parse(t)}catch{return t}if(/^-?\d+(?:\.\d+)?$/u.test(t)){let e=Number.parseFloat(t);if(!Number.isNaN(e))return e}return t===`true`||t===`false`?t===`true`:t}catch(e){_(`Variable "${t}": failed to execute command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`static`)return n.value;return e}async function Xe(e){let t=new Map,n=e.map(async e=>{let t=await Ye(e.value,e.id);return{id:e.id,value:t}}),r=await Promise.all(n);for(let e of r)e.value!==void 0&&t.set(e.id,e.value);return t}function Ze(e){let t=[],n=new Set;for(let r of e)if(n.has(r.id)&&t.push(`Duplicate variable ID: "${r.id}"`),n.add(r.id),/^[\w$]+$/u.test(r.id)||t.push(`Variable ID "${r.id}" is invalid. Must contain only letters, numbers, underscore, or dollar sign.`),r.value===void 0||r.value===null)t.push(`Variable "${r.id}" must have a value`);else if(typeof r.value==`object`&&!Array.isArray(r.value)&&r.value!==null){let e=r.value;e.type==null||e.type===``?t.push(`Variable "${r.id}": value object must have a "type" field ("static" or "exec")`):e.type!==`static`&&e.type!==`exec`&&t.push(`Variable "${r.id}": type must be "static" or "exec", got "${e.type}"`),(e.value===void 0||e.value===null)&&t.push(`Variable "${r.id}": value config must have a "value" field`),e.type===`exec`&&typeof e.value!=`string`&&t.push(`Variable "${r.id}": exec type must have a string command as value`)}return t}const Qe=i(t.readFile);async function $e(i,a){let o=i.filter(e=>p(e.enabled,f()));_(`Resolving task dependencies...`,`info`);let s=Je(o);_(`Welcome! Let's execute your tasks.`,`info`),a.dryRun&&_(`🔍 DRY RUN MODE - No changes will be made`,`warn`),_(`This will execute your project tasks based on the defined configuration.`,`info`);let c=f(),l=a.globalVariables??[],u=[],d=[...l];for(let e of s)if(e.variables&&e.variables.length>0)for(let t of e.variables)u.push(t),d.push(t);if(d.length>0){let e=Ze(d);e.length>0&&(_(`❌ Variable validation errors:`,`error`),e.forEach(e=>_(` - ${e}`,`error`)),n.exit(1)),_(`Resolving variable values...`,`info`);let t=$(d,await Xe(d));Object.assign(c,t),Object.keys(t).length>0&&_(`✓ Resolved ${Object.keys(t).length} variable(s)`,`success`)}let m=a.globalPrompts??[],h=[],v=[...m];for(let e of s)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)h.push(t),v.push(t);if(v.length>0){let e=G(v);e.length>0&&(_(`❌ Prompt validation errors:`,`error`),e.forEach(e=>_(` - ${e}`,`error`)),n.exit(1)),_(`Resolving prompt default values...`,`info`);let t=await W(v),r={};if(m.length>0&&(_(`📋 Top-level prompts (available to all tasks):`,`info`),r=await H(m,t,c),Object.assign(c,r)),h.length>0){m.length>0&&_(`📋 Task-specific prompts:`,`info`);let e=await H(h,t,c);Object.assign(c,e)}}let y=s.filter(e=>p(e.enabled,c));if(_(`${y.length} of ${s.length} task(s) enabled for execution`,`info`),a.dryRun){await N(y,c),_(`🔍 Dry run completed - no changes were made`,`info`),_(`Run without --dry-run to apply changes`,`info`);return}_(`Starting task execution...`,`info`),await B(`beforeAll`,c);let b=y.length,x=0,S=0,C=[];for(let e=0;e<y.length;e++){let t=y[e];if(t!=null)if(await B(`beforeTask`,t,c),await qe(t,c,e+1,b,a.dryRun))x++,C.push(t.id),await B(`afterTask`,t,c);else if(t.required){S++,await B(`onError`,Error(`Task ${t.name} failed`),t);break}else _(`⚠️ Non-critical task failed, continuing...`,`warn`),await B(`onError`,Error(`Task ${t.name} failed`),t)}if(S>0&&(_(`❌ Task execution failed with ${S} critical error(s)`,`error`),_(`✓ Completed: ${x}/${b} tasks`,`info`),n.exit(1)),await B(`afterAll`,c),_(`✅ All tasks completed successfully!`,`success`),_(`✓ Completed: ${x}/${b} tasks`,`success`),!a.dryRun){_(`Next steps:`,`info`),_(`1. Review the changes made to your project`,`info`),_(`2. Commit the changes to git`,`info`);let i=e.join(n.cwd(),`package.json`);t.existsSync(i)&&JSON.parse(await Qe(i,`utf-8`)).scripts?.[`turbo:gen:init`]!=null&&(_(`3. Run "pnpm run turbo:gen:init" to create your first package`,`info`),await g(`Would you like to run turbo:gen:init now?`,!0)&&(_(`Running turbo:gen:init...`,`info`),r(`pnpm run turbo:gen:init`,{stdio:`inherit`})))}}const et=n.argv.includes(`--dry-run`),tt=n.argv.includes(`--force`);async function nt(e){try{let t=e||[];t.length===0&&(_(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),_(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),n.exit(1)),await $e(t,{dryRun:et,force:tt,tasksFilePath:void 0})}catch(e){_(`❌ Task execution failed`,`error`),e instanceof Error?(_(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}async function rt(e,t){try{await $e(e,{dryRun:t?.dryRun??et,force:t?.force??tt,tasksFilePath:t?.tasksFilePath??void 0,...t?.globalVariables!=null&&{globalVariables:t.globalVariables},...t?.globalPrompts!=null&&{globalPrompts:t.globalPrompts}})}catch(e){_(`❌ Task execution failed`,`error`),e instanceof Error?(_(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}export{ie as A,O as B,ae as C,oe as D,z as E,te as F,_ as G,b as H,k as I,y as J,h as K,M as L,N as M,j as N,ce as O,ne as P,A as R,V as S,le as T,m as U,D as V,v as W,U as _,Ye as a,se as b,Ke as c,Q as d,Ie as f,W as g,G as h,Xe as i,ue as j,L as k,qe as l,Ne as m,rt as n,$ as o,Me as p,g as q,Ze as r,Je as s,nt as t,Fe as u,H as v,R as w,de as x,B as y,re as z};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pixpilot/scaffoldfy",
3
3
  "type": "module",
4
- "version": "0.8.0",
4
+ "version": "0.10.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/tsconfig": "0.1.0",
51
- "@internal/vitest-config": "0.1.0",
50
+ "@internal/prettier-config": "0.0.1",
52
51
  "@internal/tsdown-config": "0.1.0",
53
- "@internal/prettier-config": "0.0.1"
52
+ "@internal/tsconfig": "0.1.0",
53
+ "@internal/vitest-config": "0.1.0"
54
54
  },
55
55
  "prettier": "@internal/prettier-config",
56
56
  "scripts": {