@pixpilot/scaffoldfy 0.4.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.
@@ -0,0 +1,468 @@
1
+ //#region src/types.d.ts
2
+ /**
3
+ * Task Types and Interfaces for Template Initialization
4
+ */
5
+ interface InitConfig {
6
+ repoName: string;
7
+ repoOwner: string;
8
+ repoUrl: string;
9
+ author: string;
10
+ baseRepoUrl: string;
11
+ orgName: string;
12
+ [key: string]: unknown;
13
+ }
14
+ /**
15
+ * Prompt type definitions for task-embedded prompts
16
+ */
17
+ type PromptType = 'input' | 'select' | 'confirm' | 'password' | 'number';
18
+ /**
19
+ * Default value types for prompts
20
+ * - 'value': Static value
21
+ * - 'execute': Execute a command to get the value
22
+ */
23
+ type DefaultValueType = 'value' | 'execute';
24
+ /**
25
+ * Default value configuration for prompts
26
+ */
27
+ interface DefaultValueConfig<T = string | number | boolean> {
28
+ type: DefaultValueType;
29
+ value: T | string;
30
+ }
31
+ /**
32
+ * Type for default values that can be either static or executable
33
+ */
34
+ type DefaultValue<T = string | number | boolean> = T | DefaultValueConfig<T>;
35
+ interface BasePrompt {
36
+ id: string;
37
+ type: PromptType;
38
+ message: string;
39
+ required?: boolean;
40
+ global?: boolean;
41
+ }
42
+ interface InputPrompt extends BasePrompt {
43
+ type: 'input' | 'password';
44
+ default?: DefaultValue<string>;
45
+ placeholder?: string;
46
+ }
47
+ interface NumberPrompt extends BasePrompt {
48
+ type: 'number';
49
+ default?: DefaultValue<number>;
50
+ min?: number;
51
+ max?: number;
52
+ }
53
+ interface SelectPrompt extends BasePrompt {
54
+ type: 'select';
55
+ choices: Array<{
56
+ name: string;
57
+ value: string | number | boolean;
58
+ }>;
59
+ default?: DefaultValue<string | number | boolean>;
60
+ }
61
+ interface ConfirmPrompt extends BasePrompt {
62
+ type: 'confirm';
63
+ default?: DefaultValue<boolean>;
64
+ }
65
+ type PromptDefinition = InputPrompt | NumberPrompt | SelectPrompt | ConfirmPrompt;
66
+ type TaskType = 'update-json' | 'template' | 'regex-replace' | 'replace-in-file' | 'delete' | 'rename' | 'git-init' | 'exec';
67
+ interface RollbackConfig {
68
+ type: TaskType;
69
+ config: unknown;
70
+ }
71
+ interface TaskDefinition {
72
+ id: string;
73
+ name: string;
74
+ description: string;
75
+ required: boolean;
76
+ enabled: boolean;
77
+ type: TaskType;
78
+ config: unknown;
79
+ dependencies?: string[];
80
+ rollback?: RollbackConfig;
81
+ prompts?: PromptDefinition[];
82
+ }
83
+ interface UpdateJsonConfig {
84
+ file: string;
85
+ updates: Record<string, unknown>;
86
+ condition?: string;
87
+ }
88
+ interface TemplateConfig {
89
+ file: string;
90
+ template?: string;
91
+ templateFile?: string;
92
+ condition?: string;
93
+ }
94
+ interface RegexReplaceConfig {
95
+ file: string;
96
+ pattern: string;
97
+ flags?: string;
98
+ replacement: string;
99
+ condition?: string;
100
+ }
101
+ interface ReplaceInFileConfig {
102
+ file: string;
103
+ replacements: Array<{
104
+ find: string;
105
+ replace: string;
106
+ }>;
107
+ condition?: string;
108
+ }
109
+ interface DeleteConfig {
110
+ paths: string[];
111
+ condition?: string;
112
+ }
113
+ interface RenameConfig {
114
+ from: string;
115
+ to: string;
116
+ condition?: string;
117
+ }
118
+ interface GitInitConfig {
119
+ removeExisting: boolean;
120
+ initialCommit: boolean;
121
+ message?: string;
122
+ condition?: string;
123
+ }
124
+ interface ExecConfig {
125
+ command: string;
126
+ cwd?: string;
127
+ condition?: string;
128
+ }
129
+ interface InitializationMetadata {
130
+ initializedAt: string;
131
+ config: InitConfig;
132
+ completedTasks: string[];
133
+ version: string;
134
+ }
135
+ /**
136
+ * Configuration file structure for template tasks
137
+ */
138
+ interface TasksConfiguration {
139
+ extends?: string | string[];
140
+ tasks: TaskDefinition[];
141
+ }
142
+ /**
143
+ * Plugin interface for custom task types
144
+ */
145
+ interface TaskPlugin {
146
+ name: string;
147
+ version?: string;
148
+ taskTypes: string[];
149
+ execute: (task: TaskDefinition, config: InitConfig, options: {
150
+ dryRun: boolean;
151
+ }) => Promise<void>;
152
+ getDiff?: (task: TaskDefinition, config: InitConfig) => Promise<string>;
153
+ validate?: (task: TaskDefinition) => string[];
154
+ }
155
+ /**
156
+ * Plugin lifecycle hooks
157
+ */
158
+ interface PluginHooks {
159
+ beforeAll?: (config: InitConfig) => Promise<void>;
160
+ afterAll?: (config: InitConfig) => Promise<void>;
161
+ beforeTask?: (task: TaskDefinition, config: InitConfig) => Promise<void>;
162
+ afterTask?: (task: TaskDefinition, config: InitConfig) => Promise<void>;
163
+ onError?: (error: Error, task?: TaskDefinition) => Promise<void>;
164
+ }
165
+ //#endregion
166
+ //#region src/config.d.ts
167
+ /**
168
+ * Validate the initialization configuration
169
+ */
170
+ declare function validateConfig(config: InitConfig): string[];
171
+ /**
172
+ * Collect configuration from user interactively
173
+ */
174
+ declare function collectConfig(dryRun?: boolean): Promise<InitConfig>;
175
+ //#endregion
176
+ //#region src/dry-run.d.ts
177
+ /**
178
+ * Get diff for update-json task
179
+ */
180
+ declare function getUpdateJsonDiff(config: UpdateJsonConfig, initConfig: InitConfig): Promise<string>;
181
+ /**
182
+ * Get diff for template task
183
+ */
184
+ declare function getTemplateDiff(config: TemplateConfig, initConfig: InitConfig): Promise<string>;
185
+ /**
186
+ * Get diff for regex-replace task
187
+ */
188
+ declare function getRegexReplaceDiff(config: RegexReplaceConfig, initConfig: InitConfig): Promise<string>;
189
+ /**
190
+ * Get diff for replace-in-file task
191
+ */
192
+ declare function getReplaceInFileDiff(config: ReplaceInFileConfig, initConfig: InitConfig): Promise<string>;
193
+ /**
194
+ * Get diff for delete task
195
+ */
196
+ declare function getDeleteDiff(config: DeleteConfig, initConfig: InitConfig): string;
197
+ /**
198
+ * Get diff for rename task
199
+ */
200
+ declare function getRenameDiff(config: RenameConfig, initConfig: InitConfig): string;
201
+ /**
202
+ * Get diff for git-init task
203
+ */
204
+ declare function getGitInitDiff(config: GitInitConfig): string;
205
+ /**
206
+ * Get diff for exec task
207
+ */
208
+ declare function getExecDiff(config: ExecConfig, initConfig: InitConfig): string;
209
+ /**
210
+ * Get diff for any task type
211
+ */
212
+ declare function getTaskDiff(task: TaskDefinition, initConfig: InitConfig): Promise<string>;
213
+ /**
214
+ * Display diffs for all tasks
215
+ */
216
+ declare function displayTasksDiff(tasks: TaskDefinition[], initConfig: InitConfig): Promise<void>;
217
+ //#endregion
218
+ //#region src/plugin.d.ts
219
+ /**
220
+ * Register a plugin
221
+ * @param plugin - The plugin to register
222
+ */
223
+ declare function registerPlugin(plugin: TaskPlugin): void;
224
+ /**
225
+ * Unregister a plugin
226
+ * @param pluginName - Name of the plugin to unregister
227
+ */
228
+ declare function unregisterPlugin(pluginName: string): void;
229
+ /**
230
+ * Get a plugin by name
231
+ * @param pluginName - Name of the plugin
232
+ * @returns The plugin or undefined if not found
233
+ */
234
+ declare function getPlugin(pluginName: string): TaskPlugin | undefined;
235
+ /**
236
+ * Get a plugin for a task type
237
+ * @param taskType - The task type
238
+ * @returns The plugin or undefined if not found
239
+ */
240
+ declare function getPluginForTaskType(taskType: string): TaskPlugin | undefined;
241
+ /**
242
+ * Check if a task type is handled by a plugin
243
+ * @param taskType - The task type to check
244
+ * @returns True if a plugin handles this task type
245
+ */
246
+ declare function isPluginTaskType(taskType: string): boolean;
247
+ /**
248
+ * List all registered plugins
249
+ * @returns Array of plugin names
250
+ */
251
+ declare function listPlugins(): string[];
252
+ /**
253
+ * Clear all registered plugins (useful for testing)
254
+ */
255
+ declare function clearPlugins(): void;
256
+ /**
257
+ * Register global lifecycle hooks
258
+ * @param hooks - Hook functions to register
259
+ */
260
+ declare function registerHooks(hooks: Partial<PluginHooks>): void;
261
+ /**
262
+ * Call a lifecycle hook
263
+ * @param hookName - Name of the hook
264
+ * @param config - Initialization config for beforeAll/afterAll
265
+ */
266
+ declare function callHook(hookName: 'beforeAll' | 'afterAll', config: InitConfig): Promise<void>;
267
+ /**
268
+ * Call a lifecycle hook
269
+ * @param hookName - Name of the hook
270
+ * @param task - Task definition for beforeTask/afterTask
271
+ * @param config - Initialization config
272
+ */
273
+ declare function callHook(hookName: 'beforeTask' | 'afterTask', task: TaskDefinition, config: InitConfig): Promise<void>;
274
+ /**
275
+ * Call a lifecycle hook
276
+ * @param hookName - Name of the hook
277
+ * @param error - Error that occurred
278
+ * @param task - Optional task definition
279
+ */
280
+ declare function callHook(hookName: 'onError', error: Error, task?: TaskDefinition): Promise<void>;
281
+ /**
282
+ * Execute a plugin task
283
+ * @param task - The task to execute
284
+ * @param config - The initialization config
285
+ * @param options - Execution options
286
+ * @param options.dryRun - Whether to run in dry-run mode
287
+ * @returns Promise that resolves when the task is complete
288
+ */
289
+ declare function executePluginTask(task: TaskDefinition, config: InitConfig, options: {
290
+ dryRun: boolean;
291
+ }): Promise<void>;
292
+ /**
293
+ * Get diff for a plugin task
294
+ * @param task - The task to generate diff for
295
+ * @param config - The initialization config
296
+ * @returns Diff string or undefined if not supported
297
+ */
298
+ declare function getPluginTaskDiff(task: TaskDefinition, config: InitConfig): Promise<string | undefined>;
299
+ /**
300
+ * Validate a plugin task
301
+ * @param task - The task to validate
302
+ * @returns Array of validation errors
303
+ */
304
+ declare function validatePluginTask(task: TaskDefinition): string[];
305
+ /**
306
+ * Create a simple plugin
307
+ * @param name - Plugin name
308
+ * @param taskType - Task type this plugin handles
309
+ * @param execute - Execute function
310
+ * @param options - Optional configuration
311
+ * @param options.version - Plugin version
312
+ * @param options.getDiff - Function to generate diff preview
313
+ * @param options.validate - Function to validate task configuration
314
+ * @returns A TaskPlugin object
315
+ */
316
+ declare function createPlugin(name: string, taskType: string, execute: (task: TaskDefinition, config: InitConfig, options: {
317
+ dryRun: boolean;
318
+ }) => Promise<void>, options?: {
319
+ version?: string;
320
+ getDiff?: (task: TaskDefinition, config: InitConfig) => Promise<string>;
321
+ validate?: (task: TaskDefinition) => string[];
322
+ }): TaskPlugin;
323
+ //#endregion
324
+ //#region src/prompts.d.ts
325
+ /**
326
+ * Resolve a default value that may be static or executable
327
+ * @param defaultValue - The default value configuration
328
+ * @param promptId - The prompt ID for error reporting
329
+ * @returns The resolved default value
330
+ */
331
+ declare function resolveDefaultValue<T = string | number | boolean>(defaultValue: DefaultValue<T> | undefined, promptId: string): Promise<T | undefined>;
332
+ /**
333
+ * Pre-resolve all executable default values in parallel
334
+ * @param prompts - Array of prompt definitions
335
+ * @returns Map of prompt IDs to their resolved default values
336
+ */
337
+ declare function resolveAllDefaultValues(prompts: PromptDefinition[]): Promise<Map<string, unknown>>;
338
+ /**
339
+ * Collect prompt answers from task-defined prompts
340
+ * @param prompts - Array of prompt definitions from tasks
341
+ * @param resolvedDefaults - Map of pre-resolved default values
342
+ * @returns Object mapping prompt IDs to their values
343
+ */
344
+ declare function collectPrompts(prompts: PromptDefinition[], resolvedDefaults?: Map<string, unknown>): Promise<Record<string, unknown>>;
345
+ /**
346
+ * Validate prompt definitions
347
+ * @param prompts - Array of prompt definitions to validate
348
+ * @returns Array of validation error messages
349
+ */
350
+ declare function validatePrompts(prompts: PromptDefinition[]): string[];
351
+ //#endregion
352
+ //#region src/state.d.ts
353
+ /**
354
+ * Load initialization state from file
355
+ */
356
+ declare function loadInitializationState(): InitializationMetadata | null;
357
+ /**
358
+ * Save initialization state to file
359
+ */
360
+ declare function saveInitializationState(config: InitConfig, completedTasks: string[], dryRun?: boolean): void;
361
+ //#endregion
362
+ //#region src/task-executors.d.ts
363
+ /**
364
+ * Execute a task based on its type
365
+ */
366
+ declare function executeTask(task: TaskDefinition, config: InitConfig, dryRun?: boolean): Promise<void>;
367
+ /**
368
+ * Run a single task with error handling
369
+ */
370
+ declare function runTask(task: TaskDefinition, config: InitConfig, taskNumber: number, totalTasks: number, dryRun?: boolean): Promise<boolean>;
371
+ //#endregion
372
+ //#region src/task-resolver.d.ts
373
+ /**
374
+ * Sort tasks by dependencies using topological sort
375
+ */
376
+ declare function topologicalSort(tasks: TaskDefinition[]): TaskDefinition[];
377
+ //#endregion
378
+ //#region src/template-inheritance.d.ts
379
+ /**
380
+ * Load a template configuration file
381
+ * @param templatePath - Path to the template file
382
+ * @param visitedPaths - Set of already visited paths to detect circular dependencies
383
+ * @returns The loaded template configuration
384
+ */
385
+ declare function loadTemplate(templatePath: string, visitedPaths?: Set<string>): Promise<TasksConfiguration>;
386
+ /**
387
+ * Recursively load and merge templates
388
+ * @param templatePath - Path to the template file
389
+ * @param baseDir - Base directory for resolving relative paths in extends
390
+ * @param visitedPaths - Set of already visited paths
391
+ * @returns Merged template configuration
392
+ */
393
+ declare function loadAndMergeTemplate(templatePath: string, baseDir?: string, visitedPaths?: Set<string>): Promise<TasksConfiguration>;
394
+ /**
395
+ * Merge multiple template configurations
396
+ * Later templates override earlier ones for conflicting task IDs
397
+ * @param templates - Array of templates to merge (in priority order)
398
+ * @returns Merged template configuration
399
+ */
400
+ declare function mergeTemplates(templates: TasksConfiguration[]): TasksConfiguration;
401
+ /**
402
+ * Clear the template cache (useful for testing)
403
+ */
404
+ declare function clearTemplateCache(): void;
405
+ /**
406
+ * Load tasks from a configuration file with template inheritance support
407
+ * @param tasksFilePath - Path to the tasks configuration file
408
+ * @returns Array of task definitions
409
+ */
410
+ declare function loadTasksWithInheritance(tasksFilePath: string): Promise<TaskDefinition[]>;
411
+ //#endregion
412
+ //#region src/utils.d.ts
413
+ /**
414
+ * Get Git repository information from the current directory
415
+ */
416
+ declare function getGitRepoInfo(): {
417
+ owner: string;
418
+ name: string;
419
+ url: string;
420
+ } | null;
421
+ /**
422
+ * Prompt user for input with optional default value
423
+ */
424
+ declare function prompt(question: string, defaultValue?: string): Promise<string>;
425
+ /**
426
+ * Prompt user for yes/no answer
427
+ */
428
+ declare function promptYesNo(question: string, defaultValue?: boolean): Promise<boolean>;
429
+ /**
430
+ * Log message with colored output
431
+ */
432
+ declare function log(message: string, type?: 'info' | 'success' | 'error' | 'warn'): void;
433
+ /**
434
+ * Interpolate template variables in a string
435
+ */
436
+ declare function interpolateTemplate(template: string, config: InitConfig): string;
437
+ /**
438
+ * Set a nested property in an object using dot notation
439
+ */
440
+ declare function setNestedProperty(obj: Record<string, unknown>, propertyPath: string, value: unknown): void;
441
+ /**
442
+ * Evaluate a condition expression with the given config
443
+ */
444
+ declare function evaluateCondition(condition: string, config: InitConfig): boolean;
445
+ //#endregion
446
+ //#region src/index.d.ts
447
+ /**
448
+ * Main function for running initialization with default/empty tasks
449
+ * For most use cases, you should use runWithTasks() with your custom tasks
450
+ */
451
+ declare function main(customTasks?: TaskDefinition[]): Promise<void>;
452
+ /**
453
+ * Run initialization with custom tasks
454
+ * @param customTasks - Array of task definitions to execute
455
+ * @param options - Optional configuration
456
+ * @param options.dryRun - Preview changes without applying them
457
+ * @param options.force - Force re-initialization even if already initialized
458
+ * @param options.keepTasksFile - Whether to keep the tasks file after initialization
459
+ * @param options.tasksFilePath - Path to the tasks file
460
+ */
461
+ declare function runWithTasks(customTasks: TaskDefinition[], options?: {
462
+ dryRun?: boolean | undefined;
463
+ force?: boolean | undefined;
464
+ keepTasksFile?: boolean | undefined;
465
+ tasksFilePath?: string | undefined;
466
+ }): Promise<void>;
467
+ //#endregion
468
+ export { BasePrompt, 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, collectConfig, 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, validateConfig, validatePluginTask, validatePrompts };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import{A as e,B as t,C as n,D as r,E as i,F as a,G as o,H as s,I as c,J as l,K as u,L as d,M as f,N as p,O as m,P as h,R as g,S as _,T as v,U as y,V as b,W as x,_ as S,a as C,b as w,c as T,d as E,f as D,g as O,h as k,i as A,j,k as M,l as N,m as P,n as F,o as I,p as L,q as R,r as z,s as B,t as V,u as H,v as U,w as W,x as G,y as K,z as q}from"./src-Cn-rEwSc.js";export{S as callHook,U as clearPlugins,z as clearTemplateCache,t as collectConfig,L as collectPrompts,K as createPlugin,e as displayTasksDiff,s as evaluateCondition,w as executePluginTask,N as executeTask,j as getDeleteDiff,f as getExecDiff,p as getGitInitDiff,y as getGitRepoInfo,G as getPlugin,_ as getPluginForTaskType,n as getPluginTaskDiff,h as getRegexReplaceDiff,a as getRenameDiff,c as getReplaceInFileDiff,d as getTaskDiff,g as getTemplateDiff,q as getUpdateJsonDiff,x as interpolateTemplate,W as isPluginTaskType,v as listPlugins,A as loadAndMergeTemplate,E as loadInitializationState,C as loadTasksWithInheritance,I as loadTemplate,o as log,V as main,B as mergeTemplates,u as prompt,R as promptYesNo,i as registerHooks,r as registerPlugin,P as resolveAllDefaultValues,k as resolveDefaultValue,H as runTask,F as runWithTasks,D as saveInitializationState,l as setNestedProperty,T as topologicalSort,m as unregisterPlugin,b as validateConfig,M as validatePluginTask,O as validatePrompts};
@@ -0,0 +1,13 @@
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{confirm as a,input as o,number as s,password as c,select as l}from"@inquirer/prompts";import u from"node:readline";import d from"handlebars";function f(){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 p(e,t){let r=u.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 m(e,t=!1){return p(`${e} (${t?`Y/n`:`y/N`})`,t?`y`:`n`).then(e=>e.toLowerCase()===`y`||e.toLowerCase()===`yes`)}function h(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 g(e,t){return e.replace(/\{\{(?<key>\w+)\}\}/gu,(e,n)=>t[n]?.toString()??``)}function _(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 v(e,t){try{let n={...t};return Function(...Object.keys(n),`'use strict'; return (${e})`)(...Object.values(n))}catch(t){return h(`Failed to evaluate condition: ${e}`,`warn`),t instanceof Error&&h(` Error: ${t.message}`,`warn`),!1}}function y(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 ee(t.readFileSync(a,`utf-8`),i)}catch(e){throw h(`Failed to read template file: ${r}`,`error`),e instanceof Error&&h(` Error: ${e.message}`,`error`),e}}function ee(e,t){try{return d.compile(e)(t)}catch(e){throw h(`Failed to compile Handlebars template`,`error`),e instanceof Error&&h(` Error: ${e.message}`,`error`),e}}function b(e){let t=[];return(!e.repoName||e.repoName.trim()===``)&&t.push(`Repository name is required`),(!e.repoOwner||e.repoOwner.trim()===``)&&t.push(`Repository owner is required`),(!e.repoUrl||e.repoUrl.trim()===``)&&t.push(`Repository URL is required`),(!e.baseRepoUrl||e.baseRepoUrl.trim()===``)&&t.push(`Base repository URL is required`),t}async function x(e=!1){h(`Welcome to the template initialization script!`,`info`),console.log(``),e&&(h(`🔍 DRY RUN MODE - No changes will be made`,`warn`),console.log(``)),h(`This will clean up the template and prepare it for your new project.`,`info`),console.log(``);let t=f(),n=await o({message:`Repository owner/organization`,default:t?.owner??``}),r=await o({message:`Repository name`,default:t?.name??``}),i=await o({message:`Repository URL`,default:t?.url??`https://github.com/${n}/${r}.git`}),a=await o({message:`Author name (for package.json)`,default:``}),s=await o({message:`Organization name for packages (e.g., myorg)`,default:t?.owner!=null&&t.owner!==``&&t.owner.startsWith(`@`)?`${t.owner}`:``}),c=await o({message:`Base repository URL (for package links)`,default:`https://github.com/${n}/${r}`});return console.log(``),{repoName:r,repoOwner:n,repoUrl:i,author:a,baseRepoUrl:c,orgName:s}}const S=i(t.readFile),C={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,cyan:`\x1B[36m`,gray:`\x1B[90m`};function w(e,t){switch(t){case`add`:return`${C.green}+ ${e}${C.reset}`;case`remove`:return`${C.red}- ${e}${C.reset}`;case`context`:return`${C.gray} ${e}${C.reset}`;default:return e}}function T(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(w(t,`context`)):(t!==void 0&&i.push(w(t,`remove`)),a!==void 0&&i.push(w(a,`add`)))}return i}async function E(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i))return`${C.yellow}⊘ Condition not met - task would be skipped${C.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${C.red}✗ File not found: ${r.file}${C.reset}`;try{let e=await S(a,`utf-8`),t=JSON.parse(e),n={...t};function o(e){if(typeof e==`string`)return g(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(`.`)?_(t,e,r):t[e]=r}let s=JSON.stringify(n,null,2),c=JSON.stringify(t,null,2);if(s===c)return`${C.cyan}→ No changes${C.reset}`;let l=T(s,c);return`${C.blue}File: ${r.file}${C.reset}\n${l.join(`
4
+ `)}`}catch(e){return`${C.red}✗ Error: ${e instanceof Error?e.message:String(e)}${C.reset}`}}async function D(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i))return`${C.yellow}⊘ Condition not met - task would be skipped${C.reset}`;if(r.template==null||r.template===``)return`${C.red}✗ No template content provided for file: ${r.file}${C.reset}`;let a=e.join(n.cwd(),r.file),o=g(r.template,i);if(!t.existsSync(a)){let e=o.split(`
5
+ `).slice(0,10).join(`
6
+ `),t=o.split(`
7
+ `).length>10;return`${C.blue}File: ${r.file}${C.reset}\n${C.green}+ New file would be created${C.reset}\n${C.gray}Content preview:${C.reset}\n${e}${t?`
8
+ ...`:``}`}try{let e=await S(a,`utf-8`);if(e===o)return`${C.cyan}→ No changes${C.reset}`;let t=T(e,o);return`${C.blue}File: ${r.file}${C.reset}\n${t.join(`
9
+ `)}`}catch(e){return`${C.red}✗ Error: ${e instanceof Error?e.message:String(e)}${C.reset}`}}async function O(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i))return`${C.yellow}⊘ Condition not met - task would be skipped${C.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${C.red}✗ File not found: ${r.file}${C.reset}`;try{let e=await S(a,`utf-8`),t=new RegExp(r.pattern,r.flags??`g`),n=g(r.replacement,i),o=e.replace(t,n);if(e===o)return`${C.cyan}→ No matches found${C.reset}`;let s=T(e,o);return`${C.blue}File: ${r.file}${C.reset}\n${s.join(`
10
+ `)}`}catch(e){return`${C.red}✗ Error: ${e instanceof Error?e.message:String(e)}${C.reset}`}}async function k(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i))return`${C.yellow}⊘ Condition not met - task would be skipped${C.reset}`;let a=e.join(n.cwd(),r.file);if(!t.existsSync(a))return`${C.red}✗ File not found: ${r.file}${C.reset}`;try{let e=await S(a,`utf-8`),t=e;for(let{find:t,replace:n}of r.replacements){let r=g(t,i),a=g(n,i);e=e.replace(r,a)}if(t===e)return`${C.cyan}→ No changes${C.reset}`;let n=T(t,e);return`${C.blue}File: ${r.file}${C.reset}\n${n.join(`
11
+ `)}`}catch(e){return`${C.red}✗ Error: ${e instanceof Error?e.message:String(e)}${C.reset}`}}function A(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i))return`${C.yellow}⊘ Condition not met - task would be skipped${C.reset}`;let a=r.paths.map(e=>g(e,i)).filter(r=>t.existsSync(e.join(n.cwd(),r)));return a.length===0?`${C.cyan}→ No files/directories to delete${C.reset}`:`${C.red}Would delete:${C.reset}\n${a.map(e=>`${C.red} - ${e}${C.reset}`).join(`
12
+ `)}`}function te(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i))return`${C.yellow}⊘ Condition not met - task would be skipped${C.reset}`;let a=g(r.from,i),o=g(r.to,i),s=e.join(n.cwd(),a),c=e.join(n.cwd(),o);return t.existsSync(s)?t.existsSync(c)?`${C.yellow}⚠ Destination already exists: ${o}${C.reset}\n${C.cyan}Would rename: ${a} → ${o}${C.reset}`:`${C.cyan}Would rename: ${a} → ${o}${C.reset}`:`${C.red}✗ Source not found: ${a}${C.reset}`}function ne(r){if(r.condition!=null&&r.condition!==``)return`${C.yellow}⊘ Condition check skipped in dry-run${C.reset}`;let i=e.join(n.cwd(),`.git`),a=t.existsSync(i),o=[];if(r.removeExisting&&a&&o.push(`${C.red}Would remove existing .git directory${C.reset}`),o.push(`${C.green}Would initialize git repository${C.reset}`),r.initialCommit){let e=r.message??`Initial commit`;o.push(`${C.green}Would create initial commit: "${e}"${C.reset}`)}return o.join(`
13
+ `)}function re(e,t){if(e.condition!=null&&e.condition!==``&&!v(e.condition,t))return`${C.yellow}⊘ Condition not met - task would be skipped${C.reset}`;let r=g(e.command,t),i=e.cwd==null?n.cwd():g(e.cwd,t);return`${C.yellow}Would execute:${C.reset}\n${C.cyan} Command: ${r}${C.reset}\n${C.cyan} Working directory: ${i}${C.reset}`}async function j(e,t){try{switch(e.type){case`update-json`:return await E(e.config,t);case`template`:return await D(e.config,t);case`regex-replace`:return await O(e.config,t);case`replace-in-file`:return await k(e.config,t);case`delete`:return A(e.config,t);case`rename`:return te(e.config,t);case`git-init`:return ne(e.config);case`exec`:return re(e.config,t);default:{let t=e.type;return`${C.yellow}⚠ Diff not available for task type: ${t}${C.reset}`}}}catch(e){return`${C.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${C.reset}`}}async function M(e,t){console.log(``),console.log(`${C.blue}═══════════════════════════════════════════════════════${C.reset}`),console.log(`${C.blue} DRY RUN - Preview of changes${C.reset}`),console.log(`${C.blue}═══════════════════════════════════════════════════════${C.reset}`),console.log(``);for(let n of e){console.log(`${C.cyan}▶ Task: ${n.name}${C.reset}`),console.log(`${C.gray} ${n.description}${C.reset}`),console.log(``);let e=await j(n,t);console.log(e),console.log(``),console.log(`${C.gray}${`─`.repeat(55)}${C.reset}`),console.log(``)}console.log(`${C.blue}═══════════════════════════════════════════════════════${C.reset}`),console.log(`${C.yellow} No changes were applied (dry-run mode)${C.reset}`),console.log(`${C.blue}═══════════════════════════════════════════════════════${C.reset}`),console.log(``)}const N=new Map,P={},F=new Map;function ie(e){if(e.name==null||e.name===``)throw TypeError(`Plugin name is required`);if(!Array.isArray(e.taskTypes)||e.taskTypes.length===0)throw TypeError(`Plugin ${e.name} must define at least one task type`);if(typeof e.execute!=`function`)throw TypeError(`Plugin ${e.name} must provide an execute function`);if(N.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(F.has(t)){let e=F.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}N.set(e.name,e);for(let t of e.taskTypes)F.set(t,e.name);h(`✓ Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`,`info`)}function ae(e){let t=N.get(e);if(t!=null){for(let e of t.taskTypes)F.delete(e);N.delete(e)}}function oe(e){return N.get(e)}function I(e){let t=F.get(e);if(t!=null)return N.get(t)}function L(e){return F.has(e)}function se(){return Array.from(N.keys())}function ce(){N.clear(),F.clear()}function le(e){e.beforeAll!=null&&(P.beforeAll=e.beforeAll),e.afterAll!=null&&(P.afterAll=e.afterAll),e.beforeTask!=null&&(P.beforeTask=e.beforeTask),e.afterTask!=null&&(P.afterTask=e.afterTask),e.onError!=null&&(P.onError=e.onError)}async function R(e,...t){let n=P[e];if(n!=null)try{e===`beforeAll`||e===`afterAll`?await n(t[0]):(e===`beforeTask`||e===`afterTask`||e===`onError`)&&await n(t[0],t[1])}catch(t){h(`Error in ${e} hook: ${t instanceof Error?t.message:String(t)}`,`error`)}}async function z(e,t,n){let r=I(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}async function ue(e,t){let n=I(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function de(e){let t=I(e.type);return t==null?[`No plugin found for task type: ${e.type}`]:t.validate==null?[]:t.validate(e)}function fe(e,t,n,r){return{name:e,...r?.version!=null&&{version:r.version},taskTypes:[t],execute:n,...r?.getDiff!=null&&{getDiff:r.getDiff},...r?.validate!=null&&{validate:r.validate}}}async function B(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`execute`){let e=n.value;if(typeof e!=`string`){h(`Prompt "${t}": execute default value must have a string command`,`error`);return}try{let t=r(e,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:1e4}).trim();if(t.startsWith(`{`)||t.startsWith(`[`))try{return JSON.parse(t)}catch{return t}if(/^-?\d+(?:\.\d+)?$/u.test(t)){let e=Number.parseFloat(t);if(!Number.isNaN(e))return e}return t===`true`||t===`false`?t===`true`:t}catch(e){h(`Prompt "${t}": failed to execute default value command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`value`)return n.value;return e}async function V(e){let t=new Map,n=e.map(async e=>{if(e.default!==void 0){let n=await B(e.default,e.id);n!==void 0&&t.set(e.id,n)}});return await Promise.all(n),t}async function H(e,t=new Map){let n={};if(e.length===0)return n;for(let r of e)try{let e,i=t.get(r.id);switch(r.type){case`input`:{let t={message:r.message};if(i!==void 0&&(t.default=String(i)),r.required!==void 0&&(t.required=r.required),e=await o(t),r.required&&(e==null||typeof e==`string`&&e.trim()===``))throw h(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break}case`password`:if(e=await c({message:r.message,mask:`*`}),r.required&&(e==null||typeof e==`string`&&e.trim()===``))throw h(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break;case`number`:{let t={message:r.message};if(i!==void 0&&(t.default=Number(i)),r.required!==void 0&&(t.required=r.required),r.min!==void 0&&(t.min=r.min),r.max!==void 0&&(t.max=r.max),e=await s(t),r.required&&e==null)throw h(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break}case`select`:{let t={message:r.message,choices:r.choices.map(e=>({name:e.name,value:e.value}))};i!==void 0&&(t.default=i),e=await l(t);break}case`confirm`:{let t=i===void 0?!1:!!i;e=await a({message:r.message,default:t});break}default:throw h(`Unknown prompt type: ${r.type}`,`error`),Error(`Unknown prompt type: ${r.type}`)}n[r.id]=e}catch(e){throw e instanceof Error&&h(`Failed to collect prompt "${r.id}": ${e.message}`,`error`),e}return console.log(``),n}function U(e){let t=[],n=new Set,r=new Set,i=new Set;for(let a of e){if(n.has(a.id)&&t.push(`Duplicate prompt ID: ${a.id}`),n.add(a.id),a.global?r.add(a.id):(r.has(a.id)&&t.push(`Prompt ID "${a.id}" is used as both global and task-specific. Use unique IDs or mark all instances as global.`),i.add(a.id)),a.global&&i.has(a.id)&&t.push(`Prompt ID "${a.id}" is used as both global and task-specific. Use unique IDs or mark all instances as global.`),/^[\w-]+$/u.test(a.id)||t.push(`Invalid prompt ID "${a.id}": must contain only alphanumeric characters, underscores, and hyphens`),(!a.message||a.message.trim()===``)&&t.push(`Prompt "${a.id}" must have a non-empty message`),a.type===`select`){a.choices.length===0&&t.push(`Select prompt "${a.id}" must have at least one choice`);for(let e of a.choices)(!e.name||e.name.trim()===``)&&t.push(`Select prompt "${a.id}" has a choice with empty name`),e.value===void 0&&t.push(`Select prompt "${a.id}" has a choice with undefined value`)}a.type===`number`&&a.min!==void 0&&a.max!==void 0&&a.min>a.max&&t.push(`Number prompt "${a.id}" has min greater than max`)}return t}const W=`.scaffoldfyialized`;function G(){let r=e.join(n.cwd(),W);if(!t.existsSync(r))return null;try{let e=t.readFileSync(r,`utf-8`);return JSON.parse(e)}catch{return null}}function pe(r,i,a=!1){if(a)return;let o=e.join(n.cwd(),`package.json`),s=`0.0.0`;try{s=JSON.parse(t.readFileSync(o,`utf-8`)).version??`0.0.0`}catch{}let c={initializedAt:new Date().toISOString(),config:r,completedTasks:i,version:s},l=e.join(n.cwd(),W);t.writeFileSync(l,JSON.stringify(c,null,2))}const K=i(t.readFile),q=i(t.writeFile),me=i(t.rename);async function he(t,r){if(t.condition!=null&&t.condition!==``&&!v(t.condition,r)){h(`Condition not met, skipping update-json task`,`info`);return}let i=e.join(n.cwd(),t.file),{updates:a}=t,o=await K(i,`utf-8`),s=JSON.parse(o);function c(e){if(typeof e==`string`)return g(e,r);if(Array.isArray(e))return e.map(e=>c(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=c(r);return t}return e}for(let[e,t]of Object.entries(a)){let n=c(t);e.includes(`.`)?_(s,e,n):s[e]=n}await q(i,`${JSON.stringify(s,null,2)}\n`)}async function ge(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i)){h(`Condition not met, skipping template task`,`info`);return}let a=e.join(n.cwd(),r.file),o=r.template!=null&&r.template!==``,s=r.templateFile!=null&&r.templateFile!==``;if(!o&&!s)throw Error(`Template task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(o&&s)throw Error(`Template task cannot have both "template" and "templateFile" specified. Use one or the other.`);let c;if(s&&r.templateFile.endsWith(`.hbs`))c=y(r.templateFile,i);else if(s){let a=r.templateFile,o=e.isAbsolute(a)?a:e.join(n.cwd(),a);if(!t.existsSync(o))throw Error(`Template file not found: ${a}`);c=g(t.readFileSync(o,`utf-8`),i)}else c=g(r.template,i);await q(a,c)}async function _e(t,r){if(t.condition!=null&&t.condition!==``&&!v(t.condition,r)){h(`Condition not met, skipping regex-replace task`,`info`);return}let i=e.join(n.cwd(),t.file),{pattern:a}=t,o=t.flags??``,s=t.replacement||``,c=await K(i,`utf-8`),l=new RegExp(a,o);c=c.replace(l,g(s,r)),await q(i,c)}async function ve(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i)){h(`Condition not met, skipping replace-in-file task`,`info`);return}let a=e.join(n.cwd(),r.file),{replacements:o}=r;if(!t.existsSync(a)){h(`File not found: ${a}, skipping`,`warn`);return}let s=await K(a,`utf-8`);for(let{find:e,replace:t}of o){let n=g(t,i);s=s.replace(new RegExp(e,`gu`),n)}await q(a,s)}async function ye(r,i){let{paths:a,condition:o}=r;if(o!=null&&o!==``){if(!i){h(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!v(o,i)){h(`Condition not met, skipping deletion`,`info`);return}}for(let r of a){let i=e.join(n.cwd(),r);t.existsSync(i)&&t.rmSync(i,{recursive:!0,force:!0})}}async function be(r,i){if(r.condition!=null&&r.condition!==``&&!v(r.condition,i)){h(`Condition not met, skipping rename task`,`info`);return}let a=e.join(n.cwd(),g(r.from,i)),o=e.join(n.cwd(),g(r.to,i));if(!t.existsSync(a)){h(`Source path does not exist: ${a}`,`warn`);return}await me(a,o)}async function xe(i,a){if(i.condition!=null&&i.condition!==``){if(!a){h(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!v(i.condition,a)){h(`Condition not met, skipping git-init task`,`info`);return}}if(i.removeExisting){let r=e.join(n.cwd(),`.git`);t.existsSync(r)&&t.rmSync(r,{recursive:!0,force:!0})}if(r(`git init`,{stdio:`inherit`}),i.initialCommit){let e=i.message??`Initial commit`;r(`git add .`,{stdio:`inherit`}),r(`git commit -m "${e}"`,{stdio:`inherit`})}}async function Se(t,i){if(t.condition!=null&&t.condition!==``){if(!i){h(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!v(t.condition,i)){h(`Condition not met, skipping exec task`,`info`);return}}let a=t.cwd==null?n.cwd():e.join(n.cwd(),t.cwd);r(t.command,{cwd:a,stdio:`inherit`})}async function J(e,t,n=!1){if(n){h(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(L(e.type)){await z(e,t,{dryRun:n});return}switch(e.type){case`update-json`:await he(e.config,t);break;case`template`:await ge(e.config,t);break;case`regex-replace`:await _e(e.config,t);break;case`replace-in-file`:await ve(e.config,t);break;case`delete`:await ye(e.config,t);break;case`rename`:await be(e.config,t);break;case`git-init`:await xe(e.config,t);break;case`exec`:await Se(e.config,t);break;default:{let t=e.type;throw TypeError(`Unknown task type: ${t}`)}}}async function Y(e,t,r,i,a=!1){try{return h(`[${r}/${i}] Running: ${e.name}...`,`info`),await J(e,t,a),h(`✓ ${e.name}`,`success`),!0}catch(t){return h(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(h(` Reason: ${t.message}`,`error`),t.stack!=null&&n.env.DEBUG!=null&&console.error(t.stack)),e.required&&h(` This is a required task. Initialization cannot continue.`,`error`),!1}}function X(e){let t=[],n=new Set,r=new Set,i=new Map(e.map(e=>[e.id,e]));function a(e){if(n.has(e))return;if(r.has(e))throw Error(`Circular dependency detected involving task: ${e}`);r.add(e);let o=i.get(e);if(!o)throw Error(`Task not found: ${e}`);if(o.dependencies)for(let e of o.dependencies)a(e);r.delete(e),n.add(e),t.push(o)}for(let t of e)n.has(t.id)||a(t.id);return t}const Ce=i(t.readFile);async function we(i,a){let o=G();o&&!a.force&&(console.log(``),h(`⚠️ This template has already been initialized!`,`warn`),console.log(``),h(` Initialized at: ${new Date(o.initializedAt).toLocaleString()}`,`info`),h(` Repo: ${o.config.repoName}`,`info`),console.log(``),await m(`Do you want to re-initialize? This may cause issues`,!1)||(h(`Initialization cancelled`,`info`),n.exit(0)),console.log(``),h(`⚠️ Proceeding with re-initialization...`,`warn`),console.log(``));let s=i.filter(e=>e.enabled);h(`Resolving task dependencies...`,`info`);let c=X(s);console.log(``);let l=await x(a.dryRun),u=b(l);u.length>0&&(h(`❌ Configuration errors:`,`error`),u.forEach(e=>h(` - ${e}`,`error`)),console.log(``),n.exit(1));let d=[],f=[],p=[];for(let e of c)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)t.global?d.some(e=>e.id===t.id)||(d.push(t),p.push(t)):(f.push(t),p.push(t));if(p.length>0){let e=U(p);e.length>0&&(h(`❌ Prompt validation errors:`,`error`),e.forEach(e=>h(` - ${e}`,`error`)),console.log(``),n.exit(1)),h(`Resolving prompt default values...`,`info`);let t=await V(p);console.log(``);let r={};if(d.length>0&&(console.log(``),h(`📋 Global prompts (available to all tasks):`,`info`),console.log(``),r=await H(d,t),Object.assign(l,r)),f.length>0){d.length>0&&(h(`📋 Task-specific prompts:`,`info`),console.log(``));let e=await H(f,t);Object.assign(l,e)}}if(a.dryRun){await M(c,l),h(`🔍 Dry run completed - no changes were made`,`info`),h(`Run without --dry-run to apply changes`,`info`);return}console.log(``),h(`Starting initialization tasks...`,`info`),console.log(``),await R(`beforeAll`,l);let g=c.length,_=0,v=0,y=[];for(let e=0;e<c.length;e++){let t=c[e];if(t!=null){if(await R(`beforeTask`,t,l),await Y(t,l,e+1,g,a.dryRun))_++,y.push(t.id),await R(`afterTask`,t,l);else if(t.required){v++,await R(`onError`,Error(`Task ${t.name} failed`),t);break}else h(`⚠️ Non-critical task failed, continuing...`,`warn`),await R(`onError`,Error(`Task ${t.name} failed`),t);console.log(``)}}if(v>0&&(h(`❌ Initialization failed with ${v} critical error(s)`,`error`),h(`✓ Completed: ${_}/${g} tasks`,`info`),n.exit(1)),await R(`afterAll`,l),pe(l,y,a.dryRun),h(`✅ Initialization completed successfully!`,`success`),console.log(``),h(`✓ Completed: ${_}/${g} tasks`,`success`),console.log(``),!a.dryRun&&!a.keepTasksFile&&a.tasksFilePath!=null&&t.existsSync(a.tasksFilePath))try{t.unlinkSync(a.tasksFilePath),h(`🗑️ Removed tasks file: ${e.basename(a.tasksFilePath)}`,`info`),console.log(``)}catch(e){h(`⚠️ Failed to remove tasks file: ${e instanceof Error?e.message:`Unknown error`}`,`warn`)}if(!a.dryRun){h(`Next steps:`,`info`),h(`1. Review the changes made to your project`,`info`),h(`2. Commit the changes to git`,`info`);let i=e.join(n.cwd(),`package.json`);t.existsSync(i)&&JSON.parse(await Ce(i,`utf-8`)).scripts?.[`turbo:gen:init`]!=null&&(h(`3. Run "pnpm run turbo:gen:init" to create your first package`,`info`),console.log(``),await m(`Would you like to run turbo:gen:init now?`,!0)&&(console.log(``),h(`Running turbo:gen:init...`,`info`),r(`pnpm run turbo:gen:init`,{stdio:`inherit`})))}console.log(``)}const Te=i(t.readFile),Z=new Map;async function Ee(r,i=new Set){let a=e.isAbsolute(r)?r:e.resolve(n.cwd(),r);if(Z.has(a))return Z.get(a);if(i.has(a))throw Error(`Circular dependency detected: ${Array.from(i).join(` -> `)} -> ${a}`);if(!t.existsSync(a))throw Error(`Template file not found: ${a}`);i.add(a);let o=await Te(a,`utf-8`),s;try{s=JSON.parse(o)}catch(e){throw Error(`Failed to parse template file ${a}: ${e instanceof Error?e.message:String(e)}`)}if(!Array.isArray(s.tasks))throw TypeError(`Invalid template file ${a}: 'tasks' array is required`);return Z.set(a,s),s}async function Q(t,r,i=new Set){let a=e.isAbsolute(t)?t:e.resolve(r??n.cwd(),t);if(i.has(a))throw Error(`Circular dependency detected: ${Array.from(i).join(` -> `)} -> ${a}`);i.add(a);let o=await Ee(a);if(o.extends==null||o.extends===``)return o;let s=e.dirname(a),c=Array.isArray(o.extends)?o.extends:[o.extends],l=[];for(let e of c){let t=await Q(e,s,i);l.push(t)}return De([...l,o])}function De(e){if(e.length===0)return{tasks:[]};if(e.length===1)return e[0];let t=new Map;for(let n of e)for(let e of n.tasks)if(t.has(e.id)){let n=t.get(e.id);t.set(e.id,Oe(n,e))}else t.set(e.id,{...e});return{tasks:Array.from(t.values())}}function Oe(e,t){let n=typeof e.config==`object`&&e.config!==null&&typeof t.config==`object`&&t.config!==null?{...e.config,...t.config}:t.config,r=e.prompts?[...e.prompts]:void 0;if(t.prompts&&t.prompts.length>0)if(!r)r=[...t.prompts];else{let e=new Map(r.map(e=>[e.id,e]));for(let n of t.prompts)e.set(n.id,n);r=Array.from(e.values())}let i=[...e.dependencies??[],...t.dependencies??[]],a=i.length>0?[...new Set(i)]:void 0;return{...e,...t,config:n,...r!=null&&{prompts:r},...a!=null&&{dependencies:a}}}function ke(){Z.clear()}async function Ae(e){h(`Loading tasks from ${e}...`,`info`);let t=await Q(e);return h(`Loaded ${t.tasks.length} task(s)`,`info`),t.extends!=null&&t.extends!==``&&h(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.tasks}const $=n.argv.includes(`--dry-run`),je=n.argv.includes(`--force`);async function Me(e){try{let t=e||[];t.length===0&&(h(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),console.log(``),h(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),console.log(``),n.exit(1)),await we(t,{dryRun:$,force:je,keepTasksFile:void 0,tasksFilePath:void 0})}catch(e){h(`❌ Initialization failed`,`error`),e instanceof Error?(h(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}async function Ne(e,t){try{await we(e,{dryRun:t?.dryRun??$,force:t?.force??je,keepTasksFile:t?.keepTasksFile??void 0,tasksFilePath:t?.tasksFilePath??void 0})}catch(e){h(`❌ Initialization failed`,`error`),e instanceof Error?(h(`Error: ${e.message}`,`error`),n.env.DEBUG!=null&&console.error(e.stack)):console.error(e),n.exit(1)}}export{M as A,x as B,ue as C,ie as D,le as E,te as F,h as G,v as H,k as I,_ as J,p as K,j as L,re as M,ne as N,ae as O,O as P,D as R,I as S,se as T,f as U,b as V,g as W,R as _,Ae as a,z as b,X as c,G as d,pe as f,U as g,B as h,Q as i,A as j,de as k,J as l,V as m,Ne as n,Ee as o,H as p,m as q,ke as r,De as s,Me as t,Y as u,ce as v,L as w,oe as x,fe as y,E as z};
@@ -0,0 +1,13 @@
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(`@inquirer/prompts`);p=s(p);let m=require(`node:readline`);m=s(m);let h=require(`handlebars`);h=s(h);function g(){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 _(e,t){let n=m.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 v(e,t=!1){return _(`${e} (${t?`Y/n`:`y/N`})`,t?`y`:`n`).then(e=>e.toLowerCase()===`y`||e.toLowerCase()===`yes`)}function y(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 b(e,t){return e.replace(/\{\{(?<key>\w+)\}\}/gu,(e,n)=>t[n]?.toString()??``)}function x(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 S(e,t){try{let n={...t};return Function(...Object.keys(n),`'use strict'; return (${e})`)(...Object.values(n))}catch(t){return y(`Failed to evaluate condition: ${e}`,`warn`),t instanceof Error&&y(` 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 y(`Failed to read template file: ${e}`,`error`),t instanceof Error&&y(` Error: ${t.message}`,`error`),t}}function te(e,t){try{return h.default.compile(e)(t)}catch(e){throw y(`Failed to compile Handlebars template`,`error`),e instanceof Error&&y(` Error: ${e.message}`,`error`),e}}function C(e){let t=[];return(!e.repoName||e.repoName.trim()===``)&&t.push(`Repository name is required`),(!e.repoOwner||e.repoOwner.trim()===``)&&t.push(`Repository owner is required`),(!e.repoUrl||e.repoUrl.trim()===``)&&t.push(`Repository URL is required`),(!e.baseRepoUrl||e.baseRepoUrl.trim()===``)&&t.push(`Base repository URL is required`),t}async function w(e=!1){y(`Welcome to the template initialization script!`,`info`),console.log(``),e&&(y(`🔍 DRY RUN MODE - No changes will be made`,`warn`),console.log(``)),y(`This will clean up the template and prepare it for your new project.`,`info`),console.log(``);let t=g(),n=await(0,p.input)({message:`Repository owner/organization`,default:t?.owner??``}),r=await(0,p.input)({message:`Repository name`,default:t?.name??``}),i=await(0,p.input)({message:`Repository URL`,default:t?.url??`https://github.com/${n}/${r}.git`}),a=await(0,p.input)({message:`Author name (for package.json)`,default:``}),o=await(0,p.input)({message:`Organization name for packages (e.g., myorg)`,default:t?.owner!=null&&t.owner!==``&&t.owner.startsWith(`@`)?`${t.owner}`:``}),s=await(0,p.input)({message:`Base repository URL (for package links)`,default:`https://github.com/${n}/${r}`});return console.log(``),{repoName:r,repoOwner:n,repoUrl:i,author:a,baseRepoUrl:s,orgName:o}}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!==``&&!S(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${E.red}✗ File not found: ${e.file}${E.reset}`;try{let r=await T(n,`utf-8`),i=JSON.parse(r),a={...i};function o(e){if(typeof e==`string`)return b(e,t);if(Array.isArray(e))return e.map(e=>o(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=o(r);return t}return e}for(let[t,n]of Object.entries(e.updates)){let e=o(n);t.includes(`.`)?x(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 A(e,t){if(e.condition!=null&&e.condition!==``&&!S(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=b(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 j(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${E.red}✗ File not found: ${e.file}${E.reset}`;try{let r=await T(n,`utf-8`),i=new RegExp(e.pattern,e.flags??`g`),a=b(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(`
10
+ `)}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function M(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=l.default.join(u.default.cwd(),e.file);if(!c.default.existsSync(n))return`${E.red}✗ File not found: ${e.file}${E.reset}`;try{let r=await T(n,`utf-8`),i=r;for(let{find:n,replace:i}of e.replacements){let e=b(n,t),a=b(i,t);r=r.replace(e,a)}if(i===r)return`${E.cyan}→ No changes${E.reset}`;let a=O(i,r);return`${E.blue}File: ${e.file}${E.reset}\n${a.join(`
11
+ `)}`}catch(e){return`${E.red}✗ Error: ${e instanceof Error?e.message:String(e)}${E.reset}`}}function N(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=e.paths.map(e=>b(e,t)).filter(e=>c.default.existsSync(l.default.join(u.default.cwd(),e)));return n.length===0?`${E.cyan}→ No files/directories to delete${E.reset}`:`${E.red}Would delete:${E.reset}\n${n.map(e=>`${E.red} - ${e}${E.reset}`).join(`
12
+ `)}`}function P(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=b(e.from,t),r=b(e.to,t),i=l.default.join(u.default.cwd(),n),a=l.default.join(u.default.cwd(),r);return c.default.existsSync(i)?c.default.existsSync(a)?`${E.yellow}⚠ Destination already exists: ${r}${E.reset}\n${E.cyan}Would rename: ${n} → ${r}${E.reset}`:`${E.cyan}Would rename: ${n} → ${r}${E.reset}`:`${E.red}✗ Source not found: ${n}${E.reset}`}function ae(e){if(e.condition!=null&&e.condition!==``)return`${E.yellow}⊘ Condition check skipped in dry-run${E.reset}`;let t=l.default.join(u.default.cwd(),`.git`),n=c.default.existsSync(t),r=[];if(e.removeExisting&&n&&r.push(`${E.red}Would remove existing .git directory${E.reset}`),r.push(`${E.green}Would initialize git repository${E.reset}`),e.initialCommit){let t=e.message??`Initial commit`;r.push(`${E.green}Would create initial commit: "${t}"${E.reset}`)}return r.join(`
13
+ `)}function oe(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t))return`${E.yellow}⊘ Condition not met - task would be skipped${E.reset}`;let n=b(e.command,t),r=e.cwd==null?u.default.cwd():b(e.cwd,t);return`${E.yellow}Would execute:${E.reset}\n${E.cyan} Command: ${n}${E.reset}\n${E.cyan} Working directory: ${r}${E.reset}`}async function se(e,t){try{switch(e.type){case`update-json`:return await k(e.config,t);case`template`:return await A(e.config,t);case`regex-replace`:return await j(e.config,t);case`replace-in-file`:return await M(e.config,t);case`delete`:return N(e.config,t);case`rename`:return P(e.config,t);case`git-init`:return ae(e.config);case`exec`:return oe(e.config,t);default:{let t=e.type;return`${E.yellow}⚠ Diff not available for task type: ${t}${E.reset}`}}}catch(e){return`${E.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${E.reset}`}}async function ce(e,t){console.log(``),console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(`${E.blue} DRY RUN - Preview of changes${E.reset}`),console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(``);for(let n of e){console.log(`${E.cyan}▶ Task: ${n.name}${E.reset}`),console.log(`${E.gray} ${n.description}${E.reset}`),console.log(``);let e=await se(n,t);console.log(e),console.log(``),console.log(`${E.gray}${`─`.repeat(55)}${E.reset}`),console.log(``)}console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(`${E.yellow} No changes were applied (dry-run mode)${E.reset}`),console.log(`${E.blue}═══════════════════════════════════════════════════════${E.reset}`),console.log(``)}const F=new Map,I={},L=new Map;function le(e){if(e.name==null||e.name===``)throw TypeError(`Plugin name is required`);if(!Array.isArray(e.taskTypes)||e.taskTypes.length===0)throw TypeError(`Plugin ${e.name} must define at least one task type`);if(typeof e.execute!=`function`)throw TypeError(`Plugin ${e.name} must provide an execute function`);if(F.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(L.has(t)){let e=L.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}F.set(e.name,e);for(let t of e.taskTypes)L.set(t,e.name);y(`✓ Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`,`info`)}function ue(e){let t=F.get(e);if(t!=null){for(let e of t.taskTypes)L.delete(e);F.delete(e)}}function de(e){return F.get(e)}function R(e){let t=L.get(e);if(t!=null)return F.get(t)}function z(e){return L.has(e)}function fe(){return Array.from(F.keys())}function pe(){F.clear(),L.clear()}function me(e){e.beforeAll!=null&&(I.beforeAll=e.beforeAll),e.afterAll!=null&&(I.afterAll=e.afterAll),e.beforeTask!=null&&(I.beforeTask=e.beforeTask),e.afterTask!=null&&(I.afterTask=e.afterTask),e.onError!=null&&(I.onError=e.onError)}async function B(e,...t){let n=I[e];if(n!=null)try{e===`beforeAll`||e===`afterAll`?await n(t[0]):(e===`beforeTask`||e===`afterTask`||e===`onError`)&&await n(t[0],t[1])}catch(t){y(`Error in ${e} hook: ${t instanceof Error?t.message:String(t)}`,`error`)}}async function V(e,t,n){let r=R(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}async function he(e,t){let n=R(e.type);if(!(n==null||n.getDiff==null))return n.getDiff(e,t)}function ge(e){let t=R(e.type);return t==null?[`No plugin found for task type: ${e.type}`]:t.validate==null?[]:t.validate(e)}function _e(e,t,n,r){return{name:e,...r?.version!=null&&{version:r.version},taskTypes:[t],execute:n,...r?.getDiff!=null&&{getDiff:r.getDiff},...r?.validate!=null&&{validate:r.validate}}}async function H(e,t){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return e;let n=e;if(n.type===`execute`){let e=n.value;if(typeof e!=`string`){y(`Prompt "${t}": execute default value must have a string command`,`error`);return}try{let t=(0,d.execSync)(e,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:1e4}).trim();if(t.startsWith(`{`)||t.startsWith(`[`))try{return JSON.parse(t)}catch{return t}if(/^-?\d+(?:\.\d+)?$/u.test(t)){let e=Number.parseFloat(t);if(!Number.isNaN(e))return e}return t===`true`||t===`false`?t===`true`:t}catch(e){y(`Prompt "${t}": failed to execute default value command: ${e instanceof Error?e.message:`Unknown error`}`,`warn`);return}}else if(n.type===`value`)return n.value;return e}async function U(e){let t=new Map,n=e.map(async e=>{if(e.default!==void 0){let n=await H(e.default,e.id);n!==void 0&&t.set(e.id,n)}});return await Promise.all(n),t}async function W(e,t=new Map){let n={};if(e.length===0)return n;for(let r of e)try{let e,i=t.get(r.id);switch(r.type){case`input`:{let t={message:r.message};if(i!==void 0&&(t.default=String(i)),r.required!==void 0&&(t.required=r.required),e=await(0,p.input)(t),r.required&&(e==null||typeof e==`string`&&e.trim()===``))throw y(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break}case`password`:if(e=await(0,p.password)({message:r.message,mask:`*`}),r.required&&(e==null||typeof e==`string`&&e.trim()===``))throw y(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break;case`number`:{let t={message:r.message};if(i!==void 0&&(t.default=Number(i)),r.required!==void 0&&(t.required=r.required),r.min!==void 0&&(t.min=r.min),r.max!==void 0&&(t.max=r.max),e=await(0,p.number)(t),r.required&&e==null)throw y(`${r.message} is required`,`error`),Error(`Prompt "${r.id}" is required`);break}case`select`:{let t={message:r.message,choices:r.choices.map(e=>({name:e.name,value:e.value}))};i!==void 0&&(t.default=i),e=await(0,p.select)(t);break}case`confirm`:{let t=i===void 0?!1:!!i;e=await(0,p.confirm)({message:r.message,default:t});break}default:throw y(`Unknown prompt type: ${r.type}`,`error`),Error(`Unknown prompt type: ${r.type}`)}n[r.id]=e}catch(e){throw e instanceof Error&&y(`Failed to collect prompt "${r.id}": ${e.message}`,`error`),e}return console.log(``),n}function G(e){let t=[],n=new Set,r=new Set,i=new Set;for(let a of e){if(n.has(a.id)&&t.push(`Duplicate prompt ID: ${a.id}`),n.add(a.id),a.global?r.add(a.id):(r.has(a.id)&&t.push(`Prompt ID "${a.id}" is used as both global and task-specific. Use unique IDs or mark all instances as global.`),i.add(a.id)),a.global&&i.has(a.id)&&t.push(`Prompt ID "${a.id}" is used as both global and task-specific. Use unique IDs or mark all instances as global.`),/^[\w-]+$/u.test(a.id)||t.push(`Invalid prompt ID "${a.id}": must contain only alphanumeric characters, underscores, and hyphens`),(!a.message||a.message.trim()===``)&&t.push(`Prompt "${a.id}" must have a non-empty message`),a.type===`select`){a.choices.length===0&&t.push(`Select prompt "${a.id}" must have at least one choice`);for(let e of a.choices)(!e.name||e.name.trim()===``)&&t.push(`Select prompt "${a.id}" has a choice with empty name`),e.value===void 0&&t.push(`Select prompt "${a.id}" has a choice with undefined value`)}a.type===`number`&&a.min!==void 0&&a.max!==void 0&&a.min>a.max&&t.push(`Number prompt "${a.id}" has min greater than max`)}return t}const K=`.scaffoldfyialized`;function q(){let e=l.default.join(u.default.cwd(),K);if(!c.default.existsSync(e))return null;try{let t=c.default.readFileSync(e,`utf-8`);return JSON.parse(t)}catch{return null}}function J(e,t,n=!1){if(n)return;let r=l.default.join(u.default.cwd(),`package.json`),i=`0.0.0`;try{i=JSON.parse(c.default.readFileSync(r,`utf-8`)).version??`0.0.0`}catch{}let a={initializedAt:new Date().toISOString(),config:e,completedTasks:t,version:i},o=l.default.join(u.default.cwd(),K);c.default.writeFileSync(o,JSON.stringify(a,null,2))}const Y=(0,f.promisify)(c.default.readFile),X=(0,f.promisify)(c.default.writeFile),ve=(0,f.promisify)(c.default.rename),ye=2;async function be(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping update-json task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{updates:r}=e,i=await Y(n,`utf-8`),a=JSON.parse(i);function o(e){if(typeof e==`string`)return b(e,t);if(Array.isArray(e))return e.map(e=>o(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=o(r);return t}return e}for(let[e,t]of Object.entries(r)){let n=o(t);e.includes(`.`)?x(a,e,n):a[e]=n}await X(n,`${JSON.stringify(a,null,2)}\n`)}async function xe(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping template task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),r=e.template!=null&&e.template!==``,i=e.templateFile!=null&&e.templateFile!==``;if(!r&&!i)throw Error(`Template task requires either "template" (inline) or "templateFile" (file path) to be specified`);if(r&&i)throw Error(`Template task cannot have both "template" and "templateFile" specified. Use one or the other.`);let a;if(i&&e.templateFile.endsWith(`.hbs`))a=ee(e.templateFile,t);else if(i){let n=e.templateFile,r=l.default.isAbsolute(n)?n:l.default.join(u.default.cwd(),n);if(!c.default.existsSync(r))throw Error(`Template file not found: ${n}`);a=b(c.default.readFileSync(r,`utf-8`),t)}else a=b(e.template,t);await X(n,a)}async function Se(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping regex-replace task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{pattern:r}=e,i=e.flags??``,a=e.replacement||``,o=await Y(n,`utf-8`),s=new RegExp(r,i);o=o.replace(s,b(a,t)),await X(n,o)}async function Ce(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping replace-in-file task`,`info`);return}let n=l.default.join(u.default.cwd(),e.file),{replacements:r}=e;if(!c.default.existsSync(n)){y(`File not found: ${n}, skipping`,`warn`);return}let i=await Y(n,`utf-8`);for(let{find:e,replace:n}of r){let r=b(n,t);i=i.replace(new RegExp(e,`gu`),r)}await X(n,i)}async function we(e,t){let{paths:n,condition:r}=e;if(r!=null&&r!==``){if(!t){y(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!S(r,t)){y(`Condition not met, skipping deletion`,`info`);return}}for(let e of n){let t=l.default.join(u.default.cwd(),e);c.default.existsSync(t)&&c.default.rmSync(t,{recursive:!0,force:!0})}}async function Te(e,t){if(e.condition!=null&&e.condition!==``&&!S(e.condition,t)){y(`Condition not met, skipping rename task`,`info`);return}let n=l.default.join(u.default.cwd(),b(e.from,t)),r=l.default.join(u.default.cwd(),b(e.to,t));if(!c.default.existsSync(n)){y(`Source path does not exist: ${n}`,`warn`);return}await ve(n,r)}async function Ee(e,t){if(e.condition!=null&&e.condition!==``){if(!t){y(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!S(e.condition,t)){y(`Condition not met, skipping git-init task`,`info`);return}}if(e.removeExisting){let e=l.default.join(u.default.cwd(),`.git`);c.default.existsSync(e)&&c.default.rmSync(e,{recursive:!0,force:!0})}if((0,d.execSync)(`git init`,{stdio:`inherit`}),e.initialCommit){let t=e.message??`Initial commit`;(0,d.execSync)(`git add .`,{stdio:`inherit`}),(0,d.execSync)(`git commit -m "${t}"`,{stdio:`inherit`})}}async function De(e,t){if(e.condition!=null&&e.condition!==``){if(!t){y(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!S(e.condition,t)){y(`Condition not met, skipping exec task`,`info`);return}}let n=e.cwd==null?u.default.cwd():l.default.join(u.default.cwd(),e.cwd);(0,d.execSync)(e.command,{cwd:n,stdio:`inherit`})}async function Oe(e,t,n=!1){if(n){y(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(z(e.type)){await V(e,t,{dryRun:n});return}switch(e.type){case`update-json`:await be(e.config,t);break;case`template`:await xe(e.config,t);break;case`regex-replace`:await Se(e.config,t);break;case`replace-in-file`:await Ce(e.config,t);break;case`delete`:await we(e.config,t);break;case`rename`:await Te(e.config,t);break;case`git-init`:await Ee(e.config,t);break;case`exec`:await De(e.config,t);break;default:{let t=e.type;throw TypeError(`Unknown task type: ${t}`)}}}async function ke(e,t,n,r,i=!1){try{return y(`[${n}/${r}] Running: ${e.name}...`,`info`),await Oe(e,t,i),y(`✓ ${e.name}`,`success`),!0}catch(t){return y(`✗ Failed: ${e.name}`,`error`),t instanceof Error&&(y(` Reason: ${t.message}`,`error`),t.stack!=null&&u.default.env.DEBUG!=null&&console.error(t.stack)),e.required&&y(` This is a required task. Initialization cannot continue.`,`error`),!1}}function Ae(e){let t=[],n=new Set,r=new Set,i=new Map(e.map(e=>[e.id,e]));function a(e){if(n.has(e))return;if(r.has(e))throw Error(`Circular dependency detected involving task: ${e}`);r.add(e);let o=i.get(e);if(!o)throw Error(`Task not found: ${e}`);if(o.dependencies)for(let e of o.dependencies)a(e);r.delete(e),n.add(e),t.push(o)}for(let t of e)n.has(t.id)||a(t.id);return t}const je=(0,f.promisify)(c.default.readFile);async function Me(e,t){let n=q();n&&!t.force&&(console.log(``),y(`⚠️ This template has already been initialized!`,`warn`),console.log(``),y(` Initialized at: ${new Date(n.initializedAt).toLocaleString()}`,`info`),y(` Repo: ${n.config.repoName}`,`info`),console.log(``),await v(`Do you want to re-initialize? This may cause issues`,!1)||(y(`Initialization cancelled`,`info`),u.default.exit(0)),console.log(``),y(`⚠️ Proceeding with re-initialization...`,`warn`),console.log(``));let r=e.filter(e=>e.enabled);y(`Resolving task dependencies...`,`info`);let i=Ae(r);console.log(``);let a=await w(t.dryRun),o=C(a);o.length>0&&(y(`❌ Configuration errors:`,`error`),o.forEach(e=>y(` - ${e}`,`error`)),console.log(``),u.default.exit(1));let s=[],f=[],p=[];for(let e of i)if(e.prompts&&e.prompts.length>0)for(let t of e.prompts)t.global?s.some(e=>e.id===t.id)||(s.push(t),p.push(t)):(f.push(t),p.push(t));if(p.length>0){let e=G(p);e.length>0&&(y(`❌ Prompt validation errors:`,`error`),e.forEach(e=>y(` - ${e}`,`error`)),console.log(``),u.default.exit(1)),y(`Resolving prompt default values...`,`info`);let t=await U(p);console.log(``);let n={};if(s.length>0&&(console.log(``),y(`📋 Global prompts (available to all tasks):`,`info`),console.log(``),n=await W(s,t),Object.assign(a,n)),f.length>0){s.length>0&&(y(`📋 Task-specific prompts:`,`info`),console.log(``));let e=await W(f,t);Object.assign(a,e)}}if(t.dryRun){await ce(i,a),y(`🔍 Dry run completed - no changes were made`,`info`),y(`Run without --dry-run to apply changes`,`info`);return}console.log(``),y(`Starting initialization tasks...`,`info`),console.log(``),await B(`beforeAll`,a);let m=i.length,h=0,g=0,_=[];for(let e=0;e<i.length;e++){let n=i[e];if(n!=null){if(await B(`beforeTask`,n,a),await ke(n,a,e+1,m,t.dryRun))h++,_.push(n.id),await B(`afterTask`,n,a);else if(n.required){g++,await B(`onError`,Error(`Task ${n.name} failed`),n);break}else y(`⚠️ Non-critical task failed, continuing...`,`warn`),await B(`onError`,Error(`Task ${n.name} failed`),n);console.log(``)}}if(g>0&&(y(`❌ Initialization failed with ${g} critical error(s)`,`error`),y(`✓ Completed: ${h}/${m} tasks`,`info`),u.default.exit(1)),await B(`afterAll`,a),J(a,_,t.dryRun),y(`✅ Initialization completed successfully!`,`success`),console.log(``),y(`✓ Completed: ${h}/${m} tasks`,`success`),console.log(``),!t.dryRun&&!t.keepTasksFile&&t.tasksFilePath!=null&&c.default.existsSync(t.tasksFilePath))try{c.default.unlinkSync(t.tasksFilePath),y(`🗑️ Removed tasks file: ${l.default.basename(t.tasksFilePath)}`,`info`),console.log(``)}catch(e){y(`⚠️ Failed to remove tasks file: ${e instanceof Error?e.message:`Unknown error`}`,`warn`)}if(!t.dryRun){y(`Next steps:`,`info`),y(`1. Review the changes made to your project`,`info`),y(`2. Commit the changes to git`,`info`);let e=l.default.join(u.default.cwd(),`package.json`);c.default.existsSync(e)&&JSON.parse(await je(e,`utf-8`)).scripts?.[`turbo:gen:init`]!=null&&(y(`3. Run "pnpm run turbo:gen:init" to create your first package`,`info`),console.log(``),await v(`Would you like to run turbo:gen:init now?`,!0)&&(console.log(``),y(`Running turbo:gen:init...`,`info`),(0,d.execSync)(`pnpm run turbo:gen:init`,{stdio:`inherit`})))}console.log(``)}const Ne=(0,f.promisify)(c.default.readFile),Z=new Map;async function Pe(e,t=new Set){let n=l.default.isAbsolute(e)?e:l.default.resolve(u.default.cwd(),e);if(Z.has(n))return Z.get(n);if(t.has(n))throw Error(`Circular dependency detected: ${Array.from(t).join(` -> `)} -> ${n}`);if(!c.default.existsSync(n))throw Error(`Template file not found: ${n}`);t.add(n);let r=await Ne(n,`utf-8`),i;try{i=JSON.parse(r)}catch(e){throw Error(`Failed to parse template file ${n}: ${e instanceof Error?e.message:String(e)}`)}if(!Array.isArray(i.tasks))throw TypeError(`Invalid template file ${n}: 'tasks' array is required`);return Z.set(n,i),i}async function Q(e,t,n=new Set){let r=l.default.isAbsolute(e)?e:l.default.resolve(t??u.default.cwd(),e);if(n.has(r))throw Error(`Circular dependency detected: ${Array.from(n).join(` -> `)} -> ${r}`);n.add(r);let i=await Pe(r);if(i.extends==null||i.extends===``)return i;let a=l.default.dirname(r),o=Array.isArray(i.extends)?i.extends:[i.extends],s=[];for(let e of o){let t=await Q(e,a,n);s.push(t)}return Fe([...s,i])}function Fe(e){if(e.length===0)return{tasks:[]};if(e.length===1)return e[0];let t=new Map;for(let n of e)for(let e of n.tasks)if(t.has(e.id)){let n=t.get(e.id);t.set(e.id,Ie(n,e))}else t.set(e.id,{...e});return{tasks:Array.from(t.values())}}function Ie(e,t){let n=typeof e.config==`object`&&e.config!==null&&typeof t.config==`object`&&t.config!==null?{...e.config,...t.config}:t.config,r=e.prompts?[...e.prompts]:void 0;if(t.prompts&&t.prompts.length>0)if(!r)r=[...t.prompts];else{let e=new Map(r.map(e=>[e.id,e]));for(let n of t.prompts)e.set(n.id,n);r=Array.from(e.values())}let i=[...e.dependencies??[],...t.dependencies??[]],a=i.length>0?[...new Set(i)]:void 0;return{...e,...t,config:n,...r!=null&&{prompts:r},...a!=null&&{dependencies:a}}}function Le(){Z.clear()}async function Re(e){y(`Loading tasks from ${e}...`,`info`);let t=await Q(e);return y(`Loaded ${t.tasks.length} task(s)`,`info`),t.extends!=null&&t.extends!==``&&y(`Extended from: ${(Array.isArray(t.extends)?t.extends:[t.extends]).join(`, `)}`,`info`),t.tasks}const $=u.default.argv.includes(`--dry-run`),ze=u.default.argv.includes(`--force`);async function Be(e){try{let t=e||[];t.length===0&&(y(`⚠️ No tasks defined. Use --tasks-file to specify tasks or call runWithTasks() programmatically.`,`warn`),console.log(``),y(`Example: scaffoldfy --tasks-file ./tasks.json`,`info`),console.log(``),u.default.exit(1)),await Me(t,{dryRun:$,force:ze,keepTasksFile:void 0,tasksFilePath:void 0})}catch(e){y(`❌ Initialization failed`,`error`),e instanceof Error?(y(`Error: ${e.message}`,`error`),u.default.env.DEBUG!=null&&console.error(e.stack)):console.error(e),u.default.exit(1)}}async function Ve(e,t){try{await Me(e,{dryRun:t?.dryRun??$,force:t?.force??ze,keepTasksFile:t?.keepTasksFile??void 0,tasksFilePath:t?.tasksFilePath??void 0})}catch(e){y(`❌ Initialization failed`,`error`),e instanceof Error?(y(`Error: ${e.message}`,`error`),u.default.env.DEBUG!=null&&console.error(e.stack)):console.error(e),u.default.exit(1)}}Object.defineProperty(exports,`A`,{enumerable:!0,get:function(){return ce}}),Object.defineProperty(exports,`B`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`C`,{enumerable:!0,get:function(){return he}}),Object.defineProperty(exports,`D`,{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,`E`,{enumerable:!0,get:function(){return me}}),Object.defineProperty(exports,`F`,{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,`G`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`H`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`I`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`J`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`K`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`L`,{enumerable:!0,get:function(){return se}}),Object.defineProperty(exports,`M`,{enumerable:!0,get:function(){return oe}}),Object.defineProperty(exports,`N`,{enumerable:!0,get:function(){return ae}}),Object.defineProperty(exports,`O`,{enumerable:!0,get:function(){return ue}}),Object.defineProperty(exports,`P`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`R`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`T`,{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,`U`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`V`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`W`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`Y`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return Re}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return Ae}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,`j`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`k`,{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return Oe}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return Ve}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`q`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return Le}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return Fe}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Be}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return ke}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return pe}}),Object.defineProperty(exports,`w`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,`z`,{enumerable:!0,get:function(){return k}});