task-pipeliner 0.1.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.
Files changed (161) hide show
  1. package/LICENSE +21 -0
  2. package/README.ko.md +1034 -0
  3. package/README.md +1031 -0
  4. package/dist/cli/index.d.ts +19 -0
  5. package/dist/cli/index.d.ts.map +1 -0
  6. package/dist/cli/index.js +147 -0
  7. package/dist/cli/index.js.map +1 -0
  8. package/dist/cli/prompts.d.ts +48 -0
  9. package/dist/cli/prompts.d.ts.map +1 -0
  10. package/dist/cli/prompts.js +75 -0
  11. package/dist/cli/prompts.js.map +1 -0
  12. package/dist/cli/ui.d.ts +39 -0
  13. package/dist/cli/ui.d.ts.map +1 -0
  14. package/dist/cli/ui.js +84 -0
  15. package/dist/cli/ui.js.map +1 -0
  16. package/dist/core/__tests__/actual-execution.test.d.ts +2 -0
  17. package/dist/core/__tests__/actual-execution.test.d.ts.map +1 -0
  18. package/dist/core/__tests__/actual-execution.test.js +140 -0
  19. package/dist/core/__tests__/actual-execution.test.js.map +1 -0
  20. package/dist/core/__tests__/base-dir.test.d.ts +2 -0
  21. package/dist/core/__tests__/base-dir.test.d.ts.map +1 -0
  22. package/dist/core/__tests__/base-dir.test.js +146 -0
  23. package/dist/core/__tests__/base-dir.test.js.map +1 -0
  24. package/dist/core/__tests__/built-code-execution.test.d.ts +2 -0
  25. package/dist/core/__tests__/built-code-execution.test.d.ts.map +1 -0
  26. package/dist/core/__tests__/built-code-execution.test.js +48 -0
  27. package/dist/core/__tests__/built-code-execution.test.js.map +1 -0
  28. package/dist/core/__tests__/choose-as-var-condition.test.d.ts +2 -0
  29. package/dist/core/__tests__/choose-as-var-condition.test.d.ts.map +1 -0
  30. package/dist/core/__tests__/choose-as-var-condition.test.js +308 -0
  31. package/dist/core/__tests__/choose-as-var-condition.test.js.map +1 -0
  32. package/dist/core/__tests__/cli-integration.test.d.ts +2 -0
  33. package/dist/core/__tests__/cli-integration.test.d.ts.map +1 -0
  34. package/dist/core/__tests__/cli-integration.test.js +83 -0
  35. package/dist/core/__tests__/cli-integration.test.js.map +1 -0
  36. package/dist/core/__tests__/comprehensive-basic-yaml.test.d.ts +2 -0
  37. package/dist/core/__tests__/comprehensive-basic-yaml.test.d.ts.map +1 -0
  38. package/dist/core/__tests__/comprehensive-basic-yaml.test.js +111 -0
  39. package/dist/core/__tests__/comprehensive-basic-yaml.test.js.map +1 -0
  40. package/dist/core/__tests__/condition-evaluator.test.d.ts +2 -0
  41. package/dist/core/__tests__/condition-evaluator.test.d.ts.map +1 -0
  42. package/dist/core/__tests__/condition-evaluator.test.js +170 -0
  43. package/dist/core/__tests__/condition-evaluator.test.js.map +1 -0
  44. package/dist/core/__tests__/debug-basic-yaml.test.d.ts +2 -0
  45. package/dist/core/__tests__/debug-basic-yaml.test.d.ts.map +1 -0
  46. package/dist/core/__tests__/debug-basic-yaml.test.js +128 -0
  47. package/dist/core/__tests__/debug-basic-yaml.test.js.map +1 -0
  48. package/dist/core/__tests__/example-files.test.d.ts +2 -0
  49. package/dist/core/__tests__/example-files.test.d.ts.map +1 -0
  50. package/dist/core/__tests__/example-files.test.js +200 -0
  51. package/dist/core/__tests__/example-files.test.js.map +1 -0
  52. package/dist/core/__tests__/executor-choice-integration.test.d.ts +2 -0
  53. package/dist/core/__tests__/executor-choice-integration.test.d.ts.map +1 -0
  54. package/dist/core/__tests__/executor-choice-integration.test.js +171 -0
  55. package/dist/core/__tests__/executor-choice-integration.test.js.map +1 -0
  56. package/dist/core/__tests__/executor-choice.test.d.ts +2 -0
  57. package/dist/core/__tests__/executor-choice.test.d.ts.map +1 -0
  58. package/dist/core/__tests__/executor-choice.test.js +174 -0
  59. package/dist/core/__tests__/executor-choice.test.js.map +1 -0
  60. package/dist/core/__tests__/executor-parallel.test.d.ts +2 -0
  61. package/dist/core/__tests__/executor-parallel.test.d.ts.map +1 -0
  62. package/dist/core/__tests__/executor-parallel.test.js +136 -0
  63. package/dist/core/__tests__/executor-parallel.test.js.map +1 -0
  64. package/dist/core/__tests__/executor-prompt.test.d.ts +2 -0
  65. package/dist/core/__tests__/executor-prompt.test.d.ts.map +1 -0
  66. package/dist/core/__tests__/executor-prompt.test.js +149 -0
  67. package/dist/core/__tests__/executor-prompt.test.js.map +1 -0
  68. package/dist/core/__tests__/executor-real-scenario.test.d.ts +2 -0
  69. package/dist/core/__tests__/executor-real-scenario.test.d.ts.map +1 -0
  70. package/dist/core/__tests__/executor-real-scenario.test.js +169 -0
  71. package/dist/core/__tests__/executor-real-scenario.test.js.map +1 -0
  72. package/dist/core/__tests__/file-condition.test.d.ts +2 -0
  73. package/dist/core/__tests__/file-condition.test.d.ts.map +1 -0
  74. package/dist/core/__tests__/file-condition.test.js +182 -0
  75. package/dist/core/__tests__/file-condition.test.js.map +1 -0
  76. package/dist/core/__tests__/final-verification.test.d.ts +2 -0
  77. package/dist/core/__tests__/final-verification.test.d.ts.map +1 -0
  78. package/dist/core/__tests__/final-verification.test.js +59 -0
  79. package/dist/core/__tests__/final-verification.test.js.map +1 -0
  80. package/dist/core/__tests__/parallel-when-condition.test.d.ts +2 -0
  81. package/dist/core/__tests__/parallel-when-condition.test.d.ts.map +1 -0
  82. package/dist/core/__tests__/parallel-when-condition.test.js +155 -0
  83. package/dist/core/__tests__/parallel-when-condition.test.js.map +1 -0
  84. package/dist/core/__tests__/parser.test.d.ts +2 -0
  85. package/dist/core/__tests__/parser.test.d.ts.map +1 -0
  86. package/dist/core/__tests__/parser.test.js +94 -0
  87. package/dist/core/__tests__/parser.test.js.map +1 -0
  88. package/dist/core/__tests__/real-inquirer-test.test.d.ts +2 -0
  89. package/dist/core/__tests__/real-inquirer-test.test.d.ts.map +1 -0
  90. package/dist/core/__tests__/real-inquirer-test.test.js +20 -0
  91. package/dist/core/__tests__/real-inquirer-test.test.js.map +1 -0
  92. package/dist/core/__tests__/reproduce-bug.test.d.ts +2 -0
  93. package/dist/core/__tests__/reproduce-bug.test.d.ts.map +1 -0
  94. package/dist/core/__tests__/reproduce-bug.test.js +84 -0
  95. package/dist/core/__tests__/reproduce-bug.test.js.map +1 -0
  96. package/dist/core/__tests__/timeout-retry.test.d.ts +2 -0
  97. package/dist/core/__tests__/timeout-retry.test.d.ts.map +1 -0
  98. package/dist/core/__tests__/timeout-retry.test.js +184 -0
  99. package/dist/core/__tests__/timeout-retry.test.js.map +1 -0
  100. package/dist/core/__tests__/workflow-validation.test.d.ts +2 -0
  101. package/dist/core/__tests__/workflow-validation.test.d.ts.map +1 -0
  102. package/dist/core/__tests__/workflow-validation.test.js +120 -0
  103. package/dist/core/__tests__/workflow-validation.test.js.map +1 -0
  104. package/dist/core/__tests__/workspace.test.d.ts +2 -0
  105. package/dist/core/__tests__/workspace.test.d.ts.map +1 -0
  106. package/dist/core/__tests__/workspace.test.js +29 -0
  107. package/dist/core/__tests__/workspace.test.js.map +1 -0
  108. package/dist/core/__tests__/yaml-integration.test.d.ts +2 -0
  109. package/dist/core/__tests__/yaml-integration.test.d.ts.map +1 -0
  110. package/dist/core/__tests__/yaml-integration.test.js +114 -0
  111. package/dist/core/__tests__/yaml-integration.test.js.map +1 -0
  112. package/dist/core/__tests__/yaml-scenarios.test.d.ts +2 -0
  113. package/dist/core/__tests__/yaml-scenarios.test.d.ts.map +1 -0
  114. package/dist/core/__tests__/yaml-scenarios.test.js +199 -0
  115. package/dist/core/__tests__/yaml-scenarios.test.js.map +1 -0
  116. package/dist/core/condition-evaluator.d.ts +44 -0
  117. package/dist/core/condition-evaluator.d.ts.map +1 -0
  118. package/dist/core/condition-evaluator.js +121 -0
  119. package/dist/core/condition-evaluator.js.map +1 -0
  120. package/dist/core/executor.d.ts +172 -0
  121. package/dist/core/executor.d.ts.map +1 -0
  122. package/dist/core/executor.js +579 -0
  123. package/dist/core/executor.js.map +1 -0
  124. package/dist/core/parser.d.ts +41 -0
  125. package/dist/core/parser.d.ts.map +1 -0
  126. package/dist/core/parser.js +202 -0
  127. package/dist/core/parser.js.map +1 -0
  128. package/dist/core/rust-task-runner.d.ts +14 -0
  129. package/dist/core/rust-task-runner.d.ts.map +1 -0
  130. package/dist/core/rust-task-runner.js +34 -0
  131. package/dist/core/rust-task-runner.js.map +1 -0
  132. package/dist/core/task-runner.d.ts +63 -0
  133. package/dist/core/task-runner.d.ts.map +1 -0
  134. package/dist/core/task-runner.js +252 -0
  135. package/dist/core/task-runner.js.map +1 -0
  136. package/dist/core/template.d.ts +11 -0
  137. package/dist/core/template.d.ts.map +1 -0
  138. package/dist/core/template.js +36 -0
  139. package/dist/core/template.js.map +1 -0
  140. package/dist/core/workflow-schema.d.ts +31 -0
  141. package/dist/core/workflow-schema.d.ts.map +1 -0
  142. package/dist/core/workflow-schema.js +125 -0
  143. package/dist/core/workflow-schema.js.map +1 -0
  144. package/dist/core/workspace.d.ts +90 -0
  145. package/dist/core/workspace.d.ts.map +1 -0
  146. package/dist/core/workspace.js +143 -0
  147. package/dist/core/workspace.js.map +1 -0
  148. package/dist/index.d.ts +10 -0
  149. package/dist/index.d.ts.map +1 -0
  150. package/dist/index.js +10 -0
  151. package/dist/index.js.map +1 -0
  152. package/dist/task-pipeliner-rs.node +0 -0
  153. package/dist/types/condition.d.ts +62 -0
  154. package/dist/types/condition.d.ts.map +1 -0
  155. package/dist/types/condition.js +6 -0
  156. package/dist/types/condition.js.map +1 -0
  157. package/dist/types/workflow.d.ts +69 -0
  158. package/dist/types/workflow.d.ts.map +1 -0
  159. package/dist/types/workflow.js +2 -0
  160. package/dist/types/workflow.js.map +1 -0
  161. package/package.json +67 -0
package/README.md ADDED
@@ -0,0 +1,1031 @@
1
+ # task-pipeliner
2
+
3
+ > A powerful, condition-based task pipeline runner with beautiful CLI output
4
+
5
+ **Version:** 0.1.0
6
+
7
+ ![task-pipeliner-banner](https://github.com/user-attachments/assets/282f3cfc-cd0d-4767-88dd-f3abb8e71bea)
8
+
9
+ [![npm version](https://img.shields.io/npm/v/task-pipeliner)](https://www.npmjs.com/package/task-pipeliner)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
11
+
12
+ **task-pipeliner** is a modern workflow automation tool that lets you define complex task pipelines using simple YAML or JSON files. With conditional execution, parallel tasks, interactive prompts, and beautiful terminal output, it's perfect for build scripts, deployment workflows, and CI/CD pipelines.
13
+
14
+ ## ✨ Features
15
+
16
+ - 🎯 **Condition-based execution** - Run steps based on file existence, user choices, environment variables, and more
17
+ - ⚡ **Parallel execution** - Run multiple tasks simultaneously
18
+ - 💬 **Interactive prompts** - Ask users for input and choices during execution
19
+ - 🎨 **Beautiful output** - Clean, boxed terminal output with colors and formatting
20
+ - 📝 **YAML & JSON support** - Use YAML for readability or JSON for programmatic generation
21
+ - 🔄 **Variable substitution** - Use `{{variables}}` throughout your workflows
22
+
23
+ ## 🔗 Resources
24
+
25
+ - 📚 **[Documentation](https://task-pipeliner.racgoo.com/)** - Complete DSL reference and guides
26
+ - 🎨 **[Visual Generator](https://task-pipeliner-generator.racgoo.com/)** - Create workflows visually in your browser
27
+ - 💻 **CLI Commands**:
28
+ ```bash
29
+ tp open generator # Open visual generator
30
+ tp open docs # Open documentation
31
+ ```
32
+
33
+ ## 🚀 Quick Start
34
+
35
+ ### Installation
36
+
37
+ #### Global Installation
38
+
39
+ Install globally to use `task-pipeliner` or `tp` commands directly:
40
+
41
+ ```bash
42
+ npm install -g task-pipeliner
43
+ # or
44
+ pnpm add -g task-pipeliner
45
+ ```
46
+
47
+ After global installation, you can run:
48
+ ```bash
49
+ task-pipeliner run workflow.yaml
50
+ # or use the short alias
51
+ tp run workflow.yaml
52
+ ```
53
+
54
+ #### Project Installation (Development)
55
+
56
+ Install as a dev dependency to use with `npx`:
57
+
58
+ ```bash
59
+ npm install -D task-pipeliner
60
+ # or
61
+ pnpm add -D task-pipeliner
62
+ ```
63
+
64
+ After project installation, run with:
65
+ ```bash
66
+ npx task-pipeliner run workflow.yaml
67
+ # or use the short alias
68
+ npx tp run workflow.yaml
69
+ ```
70
+
71
+ ### Basic Usage
72
+
73
+ Create a `workflow.yaml` or `workflow.json` file:
74
+
75
+ **YAML Format (`workflow.yaml`):**
76
+
77
+ ```yaml
78
+ name: My Workflow
79
+
80
+ steps:
81
+ - run: echo "Hello, World!"
82
+
83
+ - choose:
84
+ message: "What would you like to do?"
85
+ options:
86
+ - id: build
87
+ label: "Build project"
88
+ - id: test
89
+ label: "Run tests"
90
+ as: action
91
+
92
+ - when:
93
+ var:
94
+ action: build
95
+ run: npm run build
96
+
97
+ - when:
98
+ var:
99
+ action: test
100
+ run: npm test
101
+ ```
102
+
103
+ **JSON Format (`workflow.json`):**
104
+
105
+ ```json
106
+ {
107
+ "name": "My Workflow",
108
+ "steps": [
109
+ {
110
+ "run": "echo \"Hello, World!\""
111
+ },
112
+ {
113
+ "choose": {
114
+ "message": "What would you like to do?",
115
+ "options": [
116
+ {
117
+ "id": "build",
118
+ "label": "Build project"
119
+ },
120
+ {
121
+ "id": "test",
122
+ "label": "Run tests"
123
+ }
124
+ ],
125
+ "as": "action"
126
+ }
127
+ },
128
+ {
129
+ "when": {
130
+ "var": {
131
+ "action": "build"
132
+ }
133
+ },
134
+ "run": "npm run build"
135
+ },
136
+ {
137
+ "when": {
138
+ "var": {
139
+ "action": "test"
140
+ }
141
+ },
142
+ "run": "npm test"
143
+ }
144
+ ]
145
+ }
146
+ ```
147
+
148
+ Run it:
149
+
150
+ ```bash
151
+ task-pipeliner run workflow.yaml
152
+ # or
153
+ task-pipeliner run workflow.json
154
+ # or use the short alias
155
+ tp run workflow.yaml
156
+ tp run workflow.json
157
+ ```
158
+
159
+ ## 📖 DSL Syntax
160
+
161
+ ### Workflow Structure
162
+
163
+ A workflow file is a YAML or JSON document with the following structure:
164
+
165
+ **YAML Format:**
166
+
167
+ ```yaml
168
+ name: Workflow Name # Optional: Display name for the workflow
169
+ description: | # Optional: Multi-line description
170
+ This workflow does...
171
+ baseDir: ./ # Optional: Base directory for command execution
172
+ # - Relative path: resolved from YAML file location
173
+ # - Absolute path: used as-is
174
+ # - If omitted: uses current working directory
175
+
176
+ steps: # Required: Array of steps to execute
177
+ - some-step-1
178
+ - some-step-2
179
+ # ...
180
+ ```
181
+
182
+ **JSON Format:**
183
+
184
+ ```json
185
+ {
186
+ "name": "Workflow Name", // Optional: Display name for the workflow
187
+ "description": "This workflow does...", // Optional: Description
188
+ "baseDir": "./", // Optional: Base directory for command execution
189
+ // - Relative path: resolved from JSON file location
190
+ // - Absolute path: used as-is
191
+ // - If omitted: uses current working directory
192
+ "steps": [ // Required: Array of steps to execute
193
+ { /* some-step-1 */ },
194
+ { /* some-step-2 */ }
195
+ ]
196
+ }
197
+ ```
198
+
199
+ #### `name` (optional)
200
+ - **Type**: `string`
201
+ - **Description**: Display name for the workflow
202
+ - **Example**: `name: "Build and Deploy"`
203
+
204
+ #### `description` (optional)
205
+ - **Type**: `string` (supports multi-line with `|` in YAML)
206
+ - **Description**: Description of what the workflow does
207
+ - **Example**:
208
+ ```yaml
209
+ description: |
210
+ This workflow builds the project,
211
+ runs tests, and deploys to production.
212
+ ```
213
+
214
+ #### `baseDir` (optional)
215
+ - **Type**: `string` (relative or absolute path)
216
+ - **Description**: Base directory for all command executions
217
+ - **Resolution**:
218
+ - **Relative path** (e.g., `./`, `../frontend`): Resolved relative to the workflow file's directory
219
+ - **Absolute path** (e.g., `/home/user/project`): Used as-is
220
+ - **If omitted**: Uses `process.cwd()` (current working directory)
221
+ - **Example**:
222
+ ```yaml
223
+ baseDir: ./frontend # Relative to workflow file
224
+ baseDir: /app/frontend # Absolute path
225
+ ```
226
+
227
+ #### `steps` (required)
228
+ - **Type**: `array` of `Step` objects
229
+ - **Description**: List of steps to execute sequentially
230
+ - **Execution**: Steps run in order, one after another (unless parallel)
231
+
232
+ ---
233
+
234
+ ### Step Types
235
+
236
+ Each step in the `steps` array can be one of the following types:
237
+
238
+ #### 1. `run` - Execute Command
239
+
240
+ Execute a shell command.
241
+
242
+ **Syntax:**
243
+ ```yaml
244
+ - run: <command>
245
+ when?: <condition> # Optional: Execute only if condition is met
246
+ timeout?: <number> # Optional: Timeout in seconds
247
+ retry?: <number> # Optional: Number of retries on failure (default: 0)
248
+ ```
249
+
250
+ **Properties:**
251
+ - `run` (required): `string` - Shell command to execute
252
+ - `when` (optional): `Condition` - Condition to check before execution
253
+ - `timeout` (optional): `number` - Maximum execution time in seconds. Command will be killed if it exceeds this time.
254
+ - `retry` (optional): `number` - Number of retry attempts if command fails (default: 0, meaning no retry)
255
+
256
+ **Examples:**
257
+ ```yaml
258
+ # Simple command
259
+ steps:
260
+ - run: npm install
261
+
262
+ # Command with condition
263
+ - when:
264
+ file: ./package.json
265
+ run: npm install
266
+
267
+ # Variable input
268
+ - choose:
269
+ message: Select execution mode.
270
+ options:
271
+ - id: 1.1.1
272
+ label: Version 1.1.1 (string displayed in display area)
273
+ - id: 1.1.2
274
+ label: Version 1.1.2 (string displayed in display area)
275
+ - id: 1.1.3
276
+ label: Version 1.1.3 (string displayed in display area)
277
+ as: version
278
+
279
+ # Command with variable substitution
280
+ - run: echo "Building {{version}}"
281
+
282
+ # Command with timeout (30 seconds)
283
+ - run: npm install
284
+ timeout: 30
285
+
286
+ # Command with retry (retry up to 3 times)
287
+ - run: npm install
288
+ retry: 3
289
+
290
+ # Using both timeout and retry
291
+ - run: npm install
292
+ timeout: 60
293
+ retry: 2
294
+ ```
295
+
296
+ **Behavior:**
297
+ - Command runs in the `baseDir` (if specified) or current working directory
298
+ - Workflow stops if command fails (non-zero exit code) after all retries are exhausted
299
+ - Output is displayed in real-time with CLI formatting
300
+ - If `timeout` is specified and command exceeds the time limit, it will be killed and the step will fail
301
+ - If `retry` is specified, the command will be retried up to the retry value until it succeeds
302
+
303
+ ---
304
+
305
+ #### 2. `choose` - User Choice
306
+
307
+ Prompt user to select from a list of options.
308
+
309
+ **Syntax:**
310
+ ```yaml
311
+ steps:
312
+ - choose:
313
+ message: <string> # Required: Question to display
314
+ options: # Required: Array of options
315
+ - id: <string> # Required: Unique identifier (stored as value)
316
+ label: <string> # Required: Display text
317
+ - id: <string>
318
+ label: <string>
319
+ as: <variable-name> # Optional: Variable name to store result
320
+ when: <condition> # Condition for providing choice prompt
321
+ ```
322
+
323
+ **Properties:**
324
+ - `choose.message` (required): `string` - Question text displayed to user
325
+ - `choose.options` (required): `array` of objects with:
326
+ - `id` (required): `string` - Unique identifier (this value is stored)
327
+ - `label` (required): `string` - Display text shown to user
328
+ - `choose.as` (optional): `string` - Variable name to store the selected `id`
329
+ - If omitted: choice is stored by its `id` (for backward compatibility)
330
+ - If provided: selected `id` is stored in this variable name
331
+ - `when` (optional): `Condition` - Show choice prompt only if condition is met
332
+
333
+ **Examples:**
334
+ ```yaml
335
+ # Basic choice
336
+ - choose:
337
+ message: "Select environment:"
338
+ options:
339
+ - id: dev
340
+ label: "Development"
341
+ - id: staging
342
+ label: "Staging"
343
+ - id: prod
344
+ label: "Production"
345
+
346
+ # Choice with variable storage
347
+ - choose:
348
+ message: "Select environment:"
349
+ options:
350
+ - id: dev
351
+ label: "Development"
352
+ - id: prod
353
+ label: "Production"
354
+ as: env # Selected id stored in 'env' variable
355
+
356
+ # Conditional choice
357
+ - when:
358
+ file: ./package.json
359
+ choose:
360
+ message: "Run tests?"
361
+ options:
362
+ - id: yes
363
+ label: "Yes"
364
+ - id: no
365
+ label: "No"
366
+ as: runTests
367
+ ```
368
+
369
+ **Storage:**
370
+ - Selected option's `id` is stored as:
371
+ 1. A choice (accessible via `hasChoice(id)`)
372
+ 2. A variable with the `id` name (for backward compatibility)
373
+ 3. If `as` is provided: also stored as a variable with the `as` name
374
+
375
+ **Usage in conditions:**
376
+ ```yaml
377
+ # After choice with 'as: env'
378
+ - when:
379
+ var: # Definition that uses a variable
380
+ env: prod # Check if 'env' variable equals 'prod'
381
+ run: echo "Deploying to production"
382
+ ```
383
+
384
+ ---
385
+
386
+ #### 3. `prompt` - Text Input
387
+
388
+ Ask user for text input.
389
+
390
+ **Syntax:**
391
+ ```yaml
392
+ - prompt:
393
+ message: <string> # Required: Question to display
394
+ as: <variable-name> # Required: Variable name to store result
395
+ default: <string> # Optional: Default value
396
+ when: <condition> # Optional: Show prompt only if condition is met
397
+ ```
398
+
399
+ **Properties:**
400
+ - `prompt.message` (required): `string` - Question text displayed to user
401
+ - `prompt.as` (required): `string` - Variable name to store the input value
402
+ - `prompt.default` (optional): `string` - Default value if user presses Enter without input
403
+ - `when` (optional): `Condition` - Show prompt only if condition is met
404
+
405
+ **Examples:**
406
+ ```yaml
407
+ # Basic prompt
408
+ - prompt:
409
+ message: "Enter version number:"
410
+ as: version
411
+
412
+ # Prompt with default value
413
+ - prompt:
414
+ message: "Enter version number:"
415
+ as: version
416
+ default: "1.0.0"
417
+
418
+ # Conditional prompt
419
+ - when:
420
+ var:
421
+ env: prod
422
+ prompt:
423
+ message: "Enter production deployment reason:"
424
+ as: deployReason
425
+ ```
426
+
427
+ **Storage:**
428
+ - User input is stored as a variable with the name specified in `as`
429
+ - Can be used in commands with `{{variable}}` syntax
430
+ - Can be checked in conditions with `var` conditions
431
+
432
+ **Usage:**
433
+ ```yaml
434
+ # Use in command
435
+ - run: echo "Building version {{version}}"
436
+
437
+ # Check in condition
438
+ - when:
439
+ var:
440
+ version: "1.0.0"
441
+ run: echo "Deploying stable version"
442
+ ```
443
+
444
+ ---
445
+
446
+ #### 4. `parallel` - Parallel Execution
447
+
448
+ Execute multiple steps simultaneously. Like `steps`, `parallel` contains an array of steps, each starting with `-`. All these steps execute at the same time.
449
+
450
+ **Syntax:**
451
+ ```yaml
452
+ - parallel:
453
+ - <step1> # Each step starts with `-`, same format as `steps`
454
+ - <step2>
455
+ - <step3>
456
+ when?: <condition> # Optional: Execute parallel block only if condition is met
457
+ ```
458
+
459
+ **Properties:**
460
+ - `parallel` (required): `array` of `Step` objects - Steps to execute in parallel (same format as `steps`, each step starts with `-`)
461
+ - `when` (optional): `Condition` - Execute parallel block only if condition is met
462
+
463
+ **Examples:**
464
+ ```yaml
465
+ # Basic parallel execution
466
+ # Each step inside parallel starts with `-`, same format as `steps`
467
+ - parallel:
468
+ - run: npm run test:unit
469
+ - run: npm run test:integration
470
+ - run: npm run lint
471
+
472
+ # Parallel with conditions
473
+ # Each step can have its own `when` condition
474
+ - parallel:
475
+ - when:
476
+ file: ./src
477
+ run: echo "Building frontend..."
478
+ - when:
479
+ file: ./api
480
+ run: echo "Building backend..."
481
+
482
+ # Conditional parallel block
483
+ # The entire parallel block can have a `when` condition
484
+ - when:
485
+ var:
486
+ env: staging
487
+ parallel:
488
+ - run: npm run test
489
+ - run: npm run lint
490
+
491
+ # parallel can contain any step type (run, choose, prompt, etc.)
492
+ - parallel:
493
+ - run: npm run test
494
+ - choose:
495
+ message: "Run lint?"
496
+ options:
497
+ - id: yes
498
+ label: "Yes"
499
+ - id: no
500
+ label: "No"
501
+ as: runLint
502
+ - prompt:
503
+ message: "Enter version:"
504
+ as: version
505
+ ```
506
+
507
+ **Behavior:**
508
+ - All steps in the `parallel` array start executing at the same time
509
+ - Workflow waits for all parallel steps to complete before continuing
510
+ - If any step fails, the workflow stops
511
+ - Each parallel branch has its own isolated workspace state (cloned)
512
+
513
+ ---
514
+
515
+ #### 5. `fail` - Fail Workflow
516
+
517
+ Stop the workflow with an error message.
518
+
519
+ **Syntax:**
520
+ ```yaml
521
+ - fail:
522
+ message: <string>
523
+ when?: <condition> # Optional: Fail only if condition is met
524
+ ```
525
+
526
+ **Properties:**
527
+ - `fail.message` (required): `string` - Error message to display
528
+ - `when` (optional): `Condition` - Fail only if condition is met
529
+
530
+ **Examples:**
531
+ ```yaml
532
+ # Fail if file doesn't exist
533
+ - when:
534
+ not:
535
+ file: ./dist
536
+ fail:
537
+ message: "Build output not found"
538
+
539
+ # Fail based on variable
540
+ - when:
541
+ var:
542
+ env: prod
543
+ fail:
544
+ message: "Cannot deploy to production without approval"
545
+ ```
546
+
547
+ **Behavior:**
548
+ - Immediately stops workflow execution
549
+ - Displays the error message
550
+ - Exits with non-zero status code
551
+
552
+ ---
553
+
554
+ ### Conditions (`when` clause)
555
+
556
+ Conditions control when steps execute. All conditions are evaluated as questions about the workspace state.
557
+
558
+ #### Condition Types
559
+
560
+ ##### 1. File Existence (`file`)
561
+
562
+ Check if a file or directory exists.
563
+
564
+ **Syntax:**
565
+ ```yaml
566
+ when:
567
+ file: <path>
568
+ ```
569
+
570
+ **Properties:**
571
+ - `file`: `string` - File or directory path (relative to current working directory)
572
+
573
+ **Examples:**
574
+ ```yaml
575
+ - when:
576
+ file: ./dist
577
+ run: echo "Build exists"
578
+
579
+ - when:
580
+ file: ./package.json
581
+ run: npm install
582
+
583
+ - when:
584
+ not:
585
+ file: ./node_modules
586
+ run: npm install
587
+ ```
588
+
589
+ **Behavior:**
590
+ - Paths are resolved relative to `process.cwd()` (current working directory)
591
+ - Returns `true` if file or directory exists, `false` otherwise
592
+
593
+ ---
594
+
595
+ ##### 2. Variable Value Comparison (`var` object)
596
+
597
+ Check if a variable equals a specific value.
598
+
599
+ **Syntax:**
600
+ ```yaml
601
+ when:
602
+ var:
603
+ <variable-name>: <expected-value>
604
+ ```
605
+
606
+ **Properties:**
607
+ - `var`: `object` - Object with variable name as key and expected value as value
608
+ - Keys: Variable names (from `prompt.as` or `choose.as`)
609
+ - Values: Expected string values to compare
610
+
611
+ **Examples:**
612
+ ```yaml
613
+ # Check if env variable equals 'prod'
614
+ - when:
615
+ var:
616
+ env: prod
617
+ run: echo "Deploying to production"
618
+
619
+ # Check if version equals specific value
620
+ - when:
621
+ var:
622
+ version: "1.0.0"
623
+ run: echo "Deploying stable version"
624
+
625
+ # Multiple variable checks (all must match)
626
+ - when:
627
+ var:
628
+ env: staging
629
+ version: "2.0.0"
630
+ run: echo "Deploying v2.0.0 to staging"
631
+ ```
632
+
633
+ **Behavior:**
634
+ - Compares variable value (as string) with expected value
635
+ - Returns `true` if values match exactly (case-sensitive)
636
+ - Returns `false` if variable doesn't exist or values don't match
637
+ - All key-value pairs in the object must match (AND logic)
638
+
639
+ ---
640
+
641
+ ##### 3. Variable Existence (`var` string)
642
+
643
+ Check if a variable exists (regardless of value).
644
+
645
+ **Syntax:**
646
+ ```yaml
647
+ when:
648
+ var: <variable-name>
649
+ # or
650
+ when:
651
+ has: <variable-name> # Alias for var
652
+ ```
653
+
654
+ **Properties:**
655
+ - `var` or `has`: `string` - Variable name to check
656
+
657
+ **Examples:**
658
+ ```yaml
659
+ # Check if variable exists
660
+ - when:
661
+ var: version
662
+ run: echo "Version: {{version}}"
663
+
664
+ # Use 'has' alias
665
+ - when:
666
+ has: projectName
667
+ run: echo "Project: {{projectName}}"
668
+ ```
669
+
670
+ **Behavior:**
671
+ - Returns `true` if variable exists (from `prompt.as` or `choose.as`)
672
+ - Returns `false` if variable doesn't exist
673
+ - Only checks existence, not value
674
+
675
+ ---
676
+
677
+ ##### 4. Combined Conditions
678
+
679
+ Combine multiple conditions using `all`, `any`, and `not`.
680
+
681
+ ###### `all` - AND Logic
682
+
683
+ All conditions must be true.
684
+
685
+ **Syntax:**
686
+ ```yaml
687
+ when:
688
+ all:
689
+ - <condition1>
690
+ - <condition2>
691
+ - <condition3>
692
+ ```
693
+
694
+ **Examples:**
695
+ ```yaml
696
+ - when:
697
+ all:
698
+ - file: ./dist
699
+ - var:
700
+ env: production
701
+ run: echo "Production build ready"
702
+
703
+ - when:
704
+ all:
705
+ - var:
706
+ env: staging
707
+ - var:
708
+ version: "2.0.0"
709
+ - file: ./dist
710
+ run: echo "Deploying v2.0.0 to staging"
711
+ ```
712
+
713
+ **Behavior:**
714
+ - Returns `true` only if ALL conditions in the array are `true`
715
+ - Returns `false` if ANY condition is `false`
716
+ - Short-circuit evaluation: stops checking after first `false`
717
+
718
+ ---
719
+
720
+ ###### `any` - OR Logic
721
+
722
+ Any condition can be true.
723
+
724
+ **Syntax:**
725
+ ```yaml
726
+ when:
727
+ any:
728
+ - <condition1>
729
+ - <condition2>
730
+ - <condition3>
731
+ ```
732
+
733
+ **Examples:**
734
+ ```yaml
735
+ - when:
736
+ any:
737
+ - var:
738
+ env: staging
739
+ - var:
740
+ env: production
741
+ run: echo "Deploying to server"
742
+
743
+ - when:
744
+ any:
745
+ - file: ./dist
746
+ - file: ./build
747
+ run: echo "Build output found"
748
+ ```
749
+
750
+ **Behavior:**
751
+ - Returns `true` if ANY condition in the array is `true`
752
+ - Returns `false` only if ALL conditions are `false`
753
+ - Short-circuit evaluation: stops checking after first `true`
754
+
755
+ ---
756
+
757
+ ###### `not` - Negation
758
+
759
+ Negate a condition.
760
+
761
+ **Syntax:**
762
+ ```yaml
763
+ when:
764
+ not:
765
+ <condition>
766
+ ```
767
+
768
+ **Examples:**
769
+ ```yaml
770
+ # Fail if file doesn't exist
771
+ - when:
772
+ not:
773
+ file: ./dist
774
+ fail:
775
+ message: "Build output not found"
776
+
777
+ # Execute if variable doesn't equal value
778
+ - when:
779
+ not:
780
+ var:
781
+ env: prod
782
+ run: echo "Not production environment"
783
+
784
+ # Complex negation
785
+ - when:
786
+ not:
787
+ all:
788
+ - file: ./dist
789
+ - var:
790
+ env: prod
791
+ run: echo "Production not ready"
792
+ ```
793
+
794
+ **Behavior:**
795
+ - Returns `true` if inner condition is `false`
796
+ - Returns `false` if inner condition is `true`
797
+ - Can negate any condition type
798
+
799
+ ---
800
+
801
+ ##### 5. Nested Conditions
802
+
803
+ Nest conditions to create complex logic.
804
+
805
+ **Examples:**
806
+ ```yaml
807
+ # Complex nested condition
808
+ - when:
809
+ all:
810
+ - file: ./dist
811
+ - any:
812
+ - var:
813
+ env: staging
814
+ - var:
815
+ env: production
816
+ - not:
817
+ var:
818
+ version: "0.0.0"
819
+ run: echo "Ready to deploy"
820
+
821
+ # Multiple levels of nesting
822
+ - when:
823
+ any:
824
+ - all:
825
+ - var:
826
+ env: prod
827
+ - file: ./dist
828
+ - all:
829
+ - var:
830
+ env: staging
831
+ - not:
832
+ file: ./test-results
833
+ run: echo "Conditional deployment"
834
+ ```
835
+
836
+ ---
837
+
838
+ ### Variable Substitution
839
+
840
+ Variables can be used in commands using the `{{variable}}` syntax.
841
+
842
+ **Syntax:**
843
+ ```yaml
844
+ run: echo "{{variableName}}"
845
+ ```
846
+
847
+ **Examples:**
848
+ ```yaml
849
+ # Use prompt variable
850
+ - prompt:
851
+ message: "Enter project name:"
852
+ as: projectName
853
+ - run: echo "Building {{projectName}}..."
854
+
855
+ # Use choice variable
856
+ - choose:
857
+ message: "Select environment:"
858
+ options:
859
+ - id: dev
860
+ label: "Development"
861
+ as: env
862
+ - run: echo "Deploying to {{env}}"
863
+
864
+ # Multiple variables
865
+ - run: echo "Building {{projectName}} version {{version}} for {{env}}"
866
+ ```
867
+
868
+ **Behavior:**
869
+ - Variables are replaced with their string values
870
+ - If variable doesn't exist, it's replaced with empty string
871
+ - Variables are resolved at execution time
872
+
873
+ ---
874
+
875
+ ### Complete Example
876
+
877
+ A complete example demonstrating all features:
878
+
879
+ ```yaml
880
+ name: Complete Workflow Example
881
+ description: |
882
+ This workflow demonstrates all DSL features:
883
+ - baseDir configuration
884
+ - User choices and prompts
885
+ - Variable usage
886
+ - Conditional execution
887
+ - Parallel execution
888
+ - File checks
889
+
890
+ baseDir: ./
891
+
892
+ steps:
893
+ # 1. Simple command
894
+ - run: echo "Starting workflow..."
895
+
896
+ # 2. User choice with variable storage
897
+ - choose:
898
+ message: "Select deployment environment:"
899
+ options:
900
+ - id: dev
901
+ label: "Development"
902
+ - id: staging
903
+ label: "Staging"
904
+ - id: prod
905
+ label: "Production"
906
+ as: env
907
+
908
+ # 3. Conditional step based on variable value
909
+ - when:
910
+ var:
911
+ env: prod
912
+ prompt:
913
+ message: "Enter production deployment reason:"
914
+ as: deployReason
915
+
916
+ # 4. Variable value comparison
917
+ - when:
918
+ var:
919
+ env: dev
920
+ run: echo "Deploying to development..."
921
+
922
+ - when:
923
+ var:
924
+ env: staging
925
+ run: echo "Deploying to staging..."
926
+
927
+ # 5. Complex condition (all)
928
+ - when:
929
+ all:
930
+ - var:
931
+ env: prod
932
+ - var: deployReason
933
+ - file: ./dist
934
+ run: echo "Production deployment approved"
935
+
936
+ # 6. Parallel execution
937
+ - parallel:
938
+ - run: npm run test:unit
939
+ - run: npm run test:integration
940
+ - run: npm run lint
941
+
942
+ # 7. File existence check
943
+ - when:
944
+ file: ./test-results
945
+ run: echo "Tests completed"
946
+
947
+ # 8. Combined condition (any)
948
+ - when:
949
+ any:
950
+ - var:
951
+ env: staging
952
+ - var:
953
+ env: prod
954
+ run: echo "Deploying to server..."
955
+
956
+ # 9. Negation
957
+ - when:
958
+ not:
959
+ file: ./dist
960
+ fail:
961
+ message: "Build output not found"
962
+
963
+ # 10. Variable substitution
964
+ - run: echo "Deploying {{projectName}} version {{version}} to {{env}}"
965
+ ```
966
+
967
+ ---
968
+
969
+ ## 📚 Examples
970
+
971
+ ### Project Examples
972
+
973
+ Check out the `examples/` directory for complete project examples:
974
+
975
+ - **`monorepo-example/`** - Monorepo workflow with multiple projects
976
+ - **`simple-project/`** - Simple single-project workflow
977
+ - **`react-app/`** - React application build and deployment
978
+
979
+ ### YAML Examples
980
+
981
+ Check out `examples/yaml-examples/` for YAML workflow examples:
982
+
983
+ - **`basic.yaml`** - Basic workflow with choices and conditions
984
+ - **`simple.yaml`** - Minimal workflow example
985
+ - **`parallel.yaml`** - Parallel execution example
986
+ - **`conditions.yaml`** - Various condition types
987
+ - **`file-checks.yaml`** - File existence checks
988
+ - **`prompt.yaml`** - User input prompts
989
+ - **`variables.yaml`** - Variable substitution examples
990
+
991
+ ### JSON Examples
992
+
993
+ Check out `examples/json-examples/` for JSON workflow examples (equivalent to YAML examples):
994
+
995
+ - **`basic.json`** - Basic workflow with choices and conditions
996
+ - **`simple.json`** - Minimal workflow example
997
+ - **`parallel.json`** - Parallel execution example
998
+ - **`conditions.json`** - Condition evaluation examples
999
+ - **`prompt.json`** - User input prompts
1000
+ - **`variables.json`** - Variable substitution examples
1001
+
1002
+ **Note:** Both YAML and JSON formats are fully supported. Choose the format that fits your preference - YAML for readability, JSON for programmatic generation.
1003
+ - **`variables.yaml`** - Variable usage examples
1004
+ - **`prompt.yaml`** - Text prompt examples
1005
+ - **`var-value-example.yaml`** - Variable value comparison examples
1006
+ - **`choice-as-example.yaml`** - Using `as` keyword in choices
1007
+ - **`base-dir-example.yaml`** - baseDir configuration example
1008
+ - **`timeout-retry-example.yaml`** - Timeout and retry features
1009
+ - **`cicd.yaml`** - CI/CD pipeline example
1010
+ - **`advanced.yaml`** - Advanced workflow patterns
1011
+ - **`multi-choice.yaml`** - Multiple sequential choices
1012
+ - **`react.yaml`** - React-specific workflow
1013
+
1014
+ ## 🏗️ Architecture
1015
+
1016
+ - **CLI**: Node.js + TypeScript with Commander.js
1017
+ - **Task Execution**: Node.js child processes with streaming output
1018
+ - **UI**: Boxen and Chalk for beautiful terminal output
1019
+ - **Prompts**: Inquirer.js for interactive prompts
1020
+
1021
+ ## 🤝 Contributing
1022
+
1023
+ Contributions are welcome! Please leave an ISSUE.
1024
+
1025
+ ## 📄 License
1026
+
1027
+ Copyright (c) 2024 racgoo
1028
+
1029
+ ## 📧 Contact
1030
+
1031
+ For inquiries, please email lhsung98@naver.com!