task-pipeliner 0.2.14 → 0.2.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ko.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > 조건 기반 작업 파이프라인 실행기로 아름다운 CLI 출력을 제공합니다
4
4
 
5
- **버전:** 0.2.14
5
+ **버전:** 0.2.16
6
6
 
7
7
  ![fox2](https://github.com/user-attachments/assets/fdf8d786-6a91-4d2d-9dc1-72be6f3ccd98)
8
8
 
@@ -25,6 +25,8 @@
25
25
 
26
26
  - **변수 치환** - 워크플로우 전반에서 `{{variables}}` 사용
27
27
 
28
+ - **프로필** - 미리 정의한 변수로 비대화형 실행 (`tp run --profile <name>`); 프로필에 설정된 변수에 대해서는 choose/prompt 단계 생략
29
+
28
30
  - **실행 히스토리** - 상세한 단계별 기록으로 과거 워크플로우 실행 추적 및 검토
29
31
 
30
32
  ## 리소스
@@ -47,6 +49,8 @@
47
49
  ```bash
48
50
  tp run workflow.yaml # 워크플로우 실행
49
51
  tp run # 가장 가까운 tp 디렉토리에서 워크플로우 선택하여 실행
52
+ tp run workflow.yaml --profile Test # 프로필로 실행 (프로필에 설정된 변수는 choose/prompt 생략)
53
+ tp run workflow.yaml -p Test # 프로필 짧은 형식
50
54
  tp run workflow.yaml --silent # 사일런트 모드로 실행 (모든 콘솔 출력 억제)
51
55
  tp run workflow.yaml -s # 사일런트 모드 짧은 형식
52
56
  ```
@@ -293,6 +297,15 @@ baseDir: ./ # 선택사항: 명령 실행 기본 디
293
297
  # - 상대 경로: YAML 파일 위치 기준으로 해석
294
298
  # - 절대 경로: 그대로 사용
295
299
  # - 생략 시: 현재 작업 디렉토리 사용
300
+ shell: # 선택사항: 모든 run 명령의 전역 쉘 설정
301
+ - bash # - 첫 번째 요소: 쉘 프로그램 (bash, zsh, sh 등)
302
+ - -lc # - 나머지: 쉘 인자 (-c, -lc 등)
303
+ # - 생략 시: 플랫폼 기본 쉘 사용
304
+ profiles: # 선택사항: tp run --profile <name>용 미리 설정된 변수
305
+ - name: Test # - name: 프로필 이름
306
+ var: # - var: 키-값 맵 ({{variable}} 치환 및 choose/prompt 생략에 사용)
307
+ mode: "dev"
308
+ label: "test-label"
296
309
 
297
310
  steps: # 필수: 실행할 단계 배열
298
311
  - some-step-1
@@ -309,6 +322,13 @@ steps: # 필수: 실행할 단계 배열
309
322
  // - 상대 경로: JSON 파일 위치 기준으로 해석
310
323
  // - 절대 경로: 그대로 사용
311
324
  // - 생략 시: 현재 작업 디렉토리 사용
325
+ "shell": ["bash", "-lc"], // 선택사항: 모든 run 명령의 전역 쉘 설정
326
+ // - 첫 번째 요소: 쉘 프로그램
327
+ // - 나머지: 쉘 인자
328
+ // - 생략 시: 플랫폼 기본 쉘 사용
329
+ "profiles": [ // 선택사항: tp run --profile <name>용 미리 설정된 변수
330
+ { "name": "Test", "var": { "mode": "dev", "label": "test-label" } }
331
+ ],
312
332
  "steps": [ // 필수: 실행할 단계 배열
313
333
  { /* some-step-1 */ },
314
334
  { /* some-step-2 */ }
@@ -334,6 +354,53 @@ steps: # 필수: 실행할 단계 배열
334
354
  baseDir: /app/frontend # 절대 경로
335
355
  ```
336
356
 
357
+ #### `shell` (선택)
358
+ - **타입**: `string`의 `array`
359
+ - **설명**: 워크플로우 내 모든 `run` 명령에 대한 전역 쉘 설정
360
+ - **형식**: `[프로그램, ...인자]` - 첫 번째 요소는 쉘 프로그램, 나머지는 인자
361
+ - **우선순위**: 스텝별 `shell` > 워크플로우 `shell` > 사용자의 현재 쉘
362
+ - **사용자의 현재 쉘** (생략 시):
363
+ - **Linux/macOS**: `$SHELL` 환경변수 사용 (예: `/bin/zsh`, `/bin/bash`)
364
+ - **Windows**: `%COMSPEC%` 사용 (일반적으로 `cmd.exe`)
365
+ - **동작**: `tp run`을 실행한 쉘 환경과 동일한 환경에서 명령 실행
366
+ - **예제**:
367
+ ```yaml
368
+ # Unix/Linux/macOS
369
+ shell: [bash, -lc] # bash 로그인 쉘 사용
370
+ shell: [zsh, -c] # zsh 사용
371
+ shell: [sh, -c] # sh 사용 (POSIX)
372
+
373
+ # Windows
374
+ shell: [cmd, /c] # 명령 프롬프트
375
+ shell: [powershell, -Command] # Windows PowerShell
376
+ shell: [pwsh, -Command] # PowerShell Core
377
+ ```
378
+ - **크로스 플랫폼 예시**:
379
+ - **Linux/macOS**: `[bash, -lc]`, `[zsh, -c]`, `[/bin/bash, -c]`
380
+ - **Windows**: `[cmd, /c]`, `[powershell, -Command]`, `[pwsh, -Command]`
381
+ - **Git Bash (Windows)**: `[bash, -c]`
382
+ - **WSL**: `[wsl, bash, -c]` 또는 `wsl` 명령 직접 사용
383
+
384
+ #### `profiles` (선택)
385
+ - **타입**: `{ name: string, var: Record<string, string> }` 의 `array`
386
+ - **설명**: 비대화형 실행을 위한 이름 붙은 변수 세트. `tp run --profile <name>` 과 함께 사용.
387
+ - **동작**: 프로필을 사용하면, 프로필에 이미 설정된 변수에 값을 저장하는 **choose** 또는 **prompt** 단계는 생략되고, 프로필 값이 `{{variable}}` 치환 및 조건에 사용됩니다.
388
+ - **예제**:
389
+ ```yaml
390
+ profiles:
391
+ - name: Test
392
+ var:
393
+ mode: "dev"
394
+ label: "test-label"
395
+ - name: Prod
396
+ var:
397
+ mode: "prod"
398
+ label: "prod-label"
399
+ ```
400
+ ```bash
401
+ tp run workflow.yaml --profile Test # Test 프로필 변수 사용; mode, label에 대한 choose/prompt 생략
402
+ ```
403
+
337
404
  #### `steps` (필수)
338
405
  - **타입**: `Step` 객체의 `array`
339
406
  - **설명**: 순차적으로 실행할 단계 목록
@@ -355,6 +422,7 @@ steps: # 필수: 실행할 단계 배열
355
422
  when?: <condition> # 선택: 조건이 충족될 때만 실행
356
423
  timeout?: <number> # 선택: 타임아웃 (초 단위)
357
424
  retry?: <number> # 선택: 실패 시 재시도 횟수 (기본값: 0)
425
+ shell?: <array> # 선택: 쉘 설정 (workflow.shell 오버라이드)
358
426
  continue?: <bool> # 선택: 이 스텝 이후 다음 스텝으로 진행할지 여부 (성공/실패 무관)
359
427
  onError?: # 선택: 에러 처리 동작
360
428
  run: <command> # 메인 run 명령이 실패했을 때 실행할 대체 명령 (사이드 이펙트)
@@ -368,6 +436,7 @@ steps: # 필수: 실행할 단계 배열
368
436
  - `when` (선택): `Condition` - 실행 전 확인할 조건
369
437
  - `timeout` (선택): `number` - 최대 실행 시간 (초 단위). 이 시간을 초과하면 명령이 종료됩니다.
370
438
  - `retry` (선택): `number` - 실패 시 재시도 횟수 (기본값: 0, 재시도 없음)
439
+ - `shell` (선택): `string`의 `array` - 이 스텝의 쉘 설정. 워크플로우의 전역 `shell`을 오버라이드합니다. 형식: `[프로그램, ...인자]`. 예: `[bash, -lc]`, `[zsh, -c]`.
371
440
  - `continue` (선택): `boolean` - 이 스텝 완료 후 다음 스텝으로 진행할지 여부를 제어합니다 (성공/실패와 무관).
372
441
  - `continue: true` - 항상 다음 스텝으로 진행 (이 스텝이 실패해도)
373
442
  - `continue: false` - 항상 워크플로우 중단 (이 스텝이 성공해도)
@@ -432,6 +501,18 @@ steps:
432
501
  continue: true
433
502
  onError:
434
503
  run: echo "Type check failed, but continuing..."
504
+
505
+ # 커스텀 쉘 사용 (스텝별)
506
+ - run: echo $SHELL
507
+ shell:
508
+ - zsh
509
+ - -c
510
+
511
+ # bash 로그인 쉘 사용
512
+ - run: source ~/.bashrc && echo "프로필 로드됨"
513
+ shell:
514
+ - bash
515
+ - -lc
435
516
  ```
436
517
 
437
518
  **동작:**
@@ -984,11 +1065,36 @@ when:
984
1065
 
985
1066
  ### 변수 치환
986
1067
 
987
- 변수는 `{{variable}}` 문법을 사용하여 명령에서 사용할 수 있습니다.
1068
+ 변수는 `{{variable}}` 문법을 사용하여 명령에서 사용할 수 있습니다. 선택적으로 공백을 사용할 수 있습니다: `{{var}}`, `{{ var }}`, `{{ var }}` 모두 작동합니다.
988
1069
 
989
1070
  **문법:**
990
1071
  ```yaml
991
1072
  run: echo "{{variableName}}"
1073
+ # 또는 선택적으로 공백 사용
1074
+ run: echo "{{ variableName }}"
1075
+ ```
1076
+
1077
+ **⚠️ 중요: YAML 문법 규칙**
1078
+
1079
+ 명령어에서 `{{variable}}`을 사용할 때, 파싱 오류를 방지하기 위해 다음 규칙을 따르세요:
1080
+
1081
+ ✅ **안전한 패턴:**
1082
+ ```yaml
1083
+ # 단어로 시작 (따옴표 불필요)
1084
+ - run: echo "Building {{version}}..."
1085
+ - run: npm run build --version={{version}}
1086
+
1087
+ # 전체 명령어를 작은따옴표로 감싸기
1088
+ - run: 'echo "Selected: {{mode}}"'
1089
+ ```
1090
+
1091
+ ❌ **문제가 되는 패턴:**
1092
+ ```yaml
1093
+ # 금지: 따옴표 + 변수 앞 콜론
1094
+ - run: echo "mode: {{mode}}" # ❌ YAML 파싱 에러!
1095
+
1096
+ # 해결: 전체 명령어를 작은따옴표로 감싸기
1097
+ - run: 'echo "mode: {{mode}}"' # ✅ 정상 작동
992
1098
  ```
993
1099
 
994
1100
  **예제:**
@@ -1077,6 +1183,10 @@ steps:
1077
1183
  - run: npm run test:integration
1078
1184
  - run: npm run lint
1079
1185
 
1186
+ # 6.5. 스텝별 쉘 오버라이드
1187
+ - run: echo "zsh로 실행"
1188
+ shell: [zsh, -c] # 이 스텝만 워크플로우 쉘 오버라이드
1189
+
1080
1190
  # 7. 파일 존재 확인
1081
1191
  - when:
1082
1192
  file: ./test-results
@@ -1229,6 +1339,7 @@ tp history remove-all -y # 확인 건너뛰기
1229
1339
  - **`file-checks.yaml`** - 파일 존재 확인
1230
1340
  - **`prompt.yaml`** - 사용자 입력 프롬프트
1231
1341
  - **`variables.yaml`** - 변수 치환 예제
1342
+ - **`profiles-example.yaml`** - 비대화형 실행용 프로필 (`tp run --profile <name>`)
1232
1343
 
1233
1344
  ### JSON 예제
1234
1345
 
@@ -1240,6 +1351,7 @@ tp history remove-all -y # 확인 건너뛰기
1240
1351
  - **`conditions.json`** - 조건 평가 예제
1241
1352
  - **`prompt.json`** - 사용자 입력 프롬프트
1242
1353
  - **`variables.json`** - 변수 치환 예제
1354
+ - **`profiles-example.json`** - 비대화형 실행용 프로필 (`tp run --profile <name>`)
1243
1355
 
1244
1356
  **참고:** YAML과 JSON 형식 모두 완전히 지원됩니다. 선호하는 형식을 선택하세요 - 가독성을 위해 YAML, 프로그래밍 방식 생성을 위해 JSON.
1245
1357
  - **`variables.yaml`** - 변수 사용 예제
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > A powerful, condition-based task pipeline runner with beautiful CLI output
4
4
 
5
- **Version:** 0.2.14
5
+ **Version:** 0.2.16
6
6
 
7
7
  ![fox2](https://github.com/user-attachments/assets/fdf8d786-6a91-4d2d-9dc1-72be6f3ccd98)
8
8
 
@@ -25,6 +25,8 @@
25
25
 
26
26
  - **Variable substitution** - Use `{{variables}}` throughout your workflows
27
27
 
28
+ - **Profiles** - Run workflows non-interactively with pre-set variables (`tp run --profile <name>`); choose/prompt steps are skipped when the variable is set in the profile
29
+
28
30
  - **Execution history** - Track and review past workflow executions with detailed step-by-step records
29
31
 
30
32
  ## 🔗 Resources
@@ -47,6 +49,8 @@
47
49
  ```bash
48
50
  tp run workflow.yaml # Run a workflow
49
51
  tp run # Select and run a workflow from nearest tp directory
52
+ tp run workflow.yaml --profile Test # Run with profile (skip choose/prompt for variables set in profile)
53
+ tp run workflow.yaml -p Test # Short form for profile
50
54
  tp run workflow.yaml --silent # Run in silent mode (suppress all console output)
51
55
  tp run workflow.yaml -s # Short form for silent mode
52
56
  ```
@@ -293,6 +297,15 @@ baseDir: ./ # Optional: Base directory for command ex
293
297
  # - Relative path: resolved from YAML file location
294
298
  # - Absolute path: used as-is
295
299
  # - If omitted: uses current working directory
300
+ shell: # Optional: Global shell configuration for all run commands
301
+ - bash # - First element: shell program (bash, zsh, sh, etc.)
302
+ - -lc # - Rest: shell arguments (-c, -lc, etc.)
303
+ # - If omitted: uses platform default shell
304
+ profiles: # Optional: Pre-set variables for tp run --profile <name>
305
+ - name: Test # - name: profile name
306
+ var: # - var: key-value map (used for {{variable}} and to skip choose/prompt)
307
+ mode: "dev"
308
+ label: "test-label"
296
309
 
297
310
  steps: # Required: Array of steps to execute
298
311
  - some-step-1
@@ -309,6 +322,13 @@ steps: # Required: Array of steps to execute
309
322
  // - Relative path: resolved from JSON file location
310
323
  // - Absolute path: used as-is
311
324
  // - If omitted: uses current working directory
325
+ "shell": ["bash", "-lc"], // Optional: Global shell configuration for all run commands
326
+ // - First element: shell program
327
+ // - Rest: shell arguments
328
+ // - If omitted: uses platform default shell
329
+ "profiles": [ // Optional: Pre-set variables for tp run --profile <name>
330
+ { "name": "Test", "var": { "mode": "dev", "label": "test-label" } }
331
+ ],
312
332
  "steps": [ // Required: Array of steps to execute
313
333
  { /* some-step-1 */ },
314
334
  { /* some-step-2 */ }
@@ -334,6 +354,53 @@ steps: # Required: Array of steps to execute
334
354
  baseDir: /app/frontend # Absolute path
335
355
  ```
336
356
 
357
+ #### `shell` (optional)
358
+ - **Type**: `array` of `string`
359
+ - **Description**: Global shell configuration for all `run` commands in the workflow
360
+ - **Format**: `[program, ...args]` - First element is the shell program, rest are arguments
361
+ - **Priority**: Step-level `shell` > Workflow-level `shell` > User's current shell
362
+ - **User's current shell** (when omitted):
363
+ - **Linux/macOS**: Uses `$SHELL` environment variable (e.g., `/bin/zsh`, `/bin/bash`)
364
+ - **Windows**: Uses `%COMSPEC%` (typically `cmd.exe`)
365
+ - **Behavior**: Commands run in the same shell environment as where you execute `tp run`
366
+ - **Example**:
367
+ ```yaml
368
+ # Unix/Linux/macOS
369
+ shell: [bash, -lc] # Use bash login shell
370
+ shell: [zsh, -c] # Use zsh
371
+ shell: [sh, -c] # Use sh (POSIX)
372
+
373
+ # Windows
374
+ shell: [cmd, /c] # Command Prompt
375
+ shell: [powershell, -Command] # Windows PowerShell
376
+ shell: [pwsh, -Command] # PowerShell Core
377
+ ```
378
+ - **Cross-platform examples**:
379
+ - **Linux/macOS**: `[bash, -lc]`, `[zsh, -c]`, `[/bin/bash, -c]`
380
+ - **Windows**: `[cmd, /c]`, `[powershell, -Command]`, `[pwsh, -Command]`
381
+ - **Git Bash (Windows)**: `[bash, -c]`
382
+ - **WSL**: `[wsl, bash, -c]` or use `wsl` command directly
383
+
384
+ #### `profiles` (optional)
385
+ - **Type**: `array` of `{ name: string, var: Record<string, string> }`
386
+ - **Description**: Named sets of variables for non-interactive runs. Use with `tp run --profile <name>`.
387
+ - **Behavior**: When a profile is used, any **choose** or **prompt** step that stores into a variable already set in the profile is skipped; the profile value is used for `{{variable}}` substitution and conditions.
388
+ - **Example**:
389
+ ```yaml
390
+ profiles:
391
+ - name: Test
392
+ var:
393
+ mode: "dev"
394
+ label: "test-label"
395
+ - name: Prod
396
+ var:
397
+ mode: "prod"
398
+ label: "prod-label"
399
+ ```
400
+ ```bash
401
+ tp run workflow.yaml --profile Test # Uses Test profile variables; choose/prompt for mode, label are skipped
402
+ ```
403
+
337
404
  #### `steps` (required)
338
405
  - **Type**: `array` of `Step` objects
339
406
  - **Description**: List of steps to execute sequentially
@@ -355,6 +422,7 @@ Execute a shell command.
355
422
  when?: <condition> # Optional: Execute only if condition is met
356
423
  timeout?: <number> # Optional: Timeout in seconds
357
424
  retry?: <number> # Optional: Number of retries on failure (default: 0)
425
+ shell?: <array> # Optional: Shell configuration (overrides workflow.shell)
358
426
  continue?: <bool> # Optional: Continue to next step after this step completes (regardless of success/failure)
359
427
  onError?: # Optional: Error handling behavior
360
428
  run: <command> # Fallback command when main run command fails (side effect)
@@ -368,6 +436,7 @@ Execute a shell command.
368
436
  - `when` (optional): `Condition` - Condition to check before execution
369
437
  - `timeout` (optional): `number` - Maximum execution time in seconds. Command will be killed if it exceeds this time.
370
438
  - `retry` (optional): `number` - Number of retry attempts if command fails (default: 0, meaning no retry)
439
+ - `shell` (optional): `array` of `string` - Shell configuration for this step. Overrides workflow's global `shell`. Format: `[program, ...args]`. Example: `[bash, -lc]`, `[zsh, -c]`.
371
440
  - `continue` (optional): `boolean` - Controls whether to proceed to the next step after this step completes, regardless of success or failure.
372
441
  - `continue: true` - Always proceed to the next step (even if this step fails)
373
442
  - `continue: false` - Always stop the workflow after this step (even if this step succeeds)
@@ -432,6 +501,18 @@ steps:
432
501
  continue: true
433
502
  onError:
434
503
  run: echo "Type check failed, but continuing..."
504
+
505
+ # Command with custom shell (step-level)
506
+ - run: echo $SHELL
507
+ shell:
508
+ - zsh
509
+ - -c
510
+
511
+ # Command with bash login shell
512
+ - run: source ~/.bashrc && echo "Loaded profile"
513
+ shell:
514
+ - bash
515
+ - -lc
435
516
  ```
436
517
 
437
518
  **Behavior:**
@@ -984,11 +1065,36 @@ Nest conditions to create complex logic.
984
1065
 
985
1066
  ### Variable Substitution
986
1067
 
987
- Variables can be used in commands using the `{{variable}}` syntax.
1068
+ Variables can be used in commands using the `{{variable}}` syntax. Optional whitespace is supported: `{{var}}`, `{{ var }}`, `{{ var }}` all work.
988
1069
 
989
1070
  **Syntax:**
990
1071
  ```yaml
991
1072
  run: echo "{{variableName}}"
1073
+ # or with optional spaces
1074
+ run: echo "{{ variableName }}"
1075
+ ```
1076
+
1077
+ **⚠️ Important YAML Syntax Rules:**
1078
+
1079
+ When using `{{variable}}` in commands, follow these rules to avoid parsing errors:
1080
+
1081
+ ✅ **Safe patterns:**
1082
+ ```yaml
1083
+ # Start with a word (no quotes needed)
1084
+ - run: echo "Building {{version}}..."
1085
+ - run: npm run build --version={{version}}
1086
+
1087
+ # Wrap entire command in single quotes
1088
+ - run: 'echo "Selected: {{mode}}"'
1089
+ ```
1090
+
1091
+ ❌ **Problematic patterns:**
1092
+ ```yaml
1093
+ # DO NOT: quotes + colons before variables
1094
+ - run: echo "mode: {{mode}}" # ❌ YAML parsing error!
1095
+
1096
+ # FIX: Wrap entire command in single quotes
1097
+ - run: 'echo "mode: {{mode}}"' # ✅ Works correctly
992
1098
  ```
993
1099
 
994
1100
  **Examples:**
@@ -1026,6 +1132,7 @@ A complete example demonstrating all features:
1026
1132
  ```yaml
1027
1133
  name: Complete Workflow Example
1028
1134
  baseDir: ./
1135
+ shell: [bash, -c] # Optional: Use bash for all steps (default: user's current shell)
1029
1136
 
1030
1137
  steps:
1031
1138
  # 1. Simple command
@@ -1077,6 +1184,10 @@ steps:
1077
1184
  - run: npm run test:integration
1078
1185
  - run: npm run lint
1079
1186
 
1187
+ # 6.5. Step-level shell override
1188
+ - run: echo "Running with zsh"
1189
+ shell: [zsh, -c] # Override workflow shell for this step only
1190
+
1080
1191
  # 7. File existence check
1081
1192
  - when:
1082
1193
  file: ./test-results
@@ -1229,6 +1340,7 @@ Check out `examples/yaml-examples/` for YAML workflow examples:
1229
1340
  - **`file-checks.yaml`** - File existence checks
1230
1341
  - **`prompt.yaml`** - User input prompts
1231
1342
  - **`variables.yaml`** - Variable substitution examples
1343
+ - **`profiles-example.yaml`** - Profiles for non-interactive runs (`tp run --profile <name>`)
1232
1344
 
1233
1345
  ### JSON Examples
1234
1346
 
@@ -1240,6 +1352,7 @@ Check out `examples/json-examples/` for JSON workflow examples (equivalent to YA
1240
1352
  - **`conditions.json`** - Condition evaluation examples
1241
1353
  - **`prompt.json`** - User input prompts
1242
1354
  - **`variables.json`** - Variable substitution examples
1355
+ - **`profiles-example.json`** - Profiles for non-interactive runs (`tp run --profile <name>`)
1243
1356
 
1244
1357
  **Note:** Both YAML and JSON formats are fully supported. Choose the format that fits your preference - YAML for readability, JSON for programmatic generation.
1245
1358
  - **`variables.yaml`** - Variable usage examples
package/dist/index.cjs CHANGED
@@ -1,37 +1,41 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var Le=Object.create;var pe=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var We=Object.getOwnPropertyNames;var _e=Object.getPrototypeOf,Ve=Object.prototype.hasOwnProperty;var He=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of We(e))!Ve.call(s,o)&&o!==t&&pe(s,o,{get:()=>e[o],enumerable:!(r=Oe(e,o))||r.enumerable});return s};var v=(s,e,t)=>(t=s!=null?Le(_e(s)):{},He(e||!s||!s.__esModule?pe(t,"default",{value:s,enumerable:!0}):t,s));var Ae=require("child_process"),ce=require("fs"),Be=require("fs/promises"),O=require("path"),De=require("util"),ue=v(require("boxen"),1),p=v(require("chalk"),1),Ie=require("commander"),Fe=v(require("dayjs"),1);var N=require("path"),Se=v(require("chalk"),1),q=v(require("log-update"),1);var me=v(require("readline"),1),x=v(require("chalk"),1),K=v(require("inquirer"),1),fe=15,M=class{searchable;constructor(e=!1){this.searchable=e}async prompt(e,t){if(this.searchable)return this.promptWithSearch(e,t);let{choice:r}=await K.default.prompt([{type:"list",name:"choice",message:x.default.cyan(e),choices:t.map(n=>({name:n.label,value:n.id})),pageSize:fe}]),o=t.find(n=>n.id===r);if(!o)throw new Error(`Invalid choice: ${r}`);return o}async promptWithSearch(e,t){return new Promise(r=>{let o="",n=0,i=[...t],a=me.createInterface({input:process.stdin,output:process.stdout,terminal:!1});process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdout.write("\x1B[?1049h"),process.stdout.write("\x1B[?25l");let u=()=>{process.stdout.write("\x1B[H\x1B[2J"),console.log(x.default.cyan(`? ${e}`));let d=o?x.default.gray(` Filter: ${o}`)+x.default.gray(` (${i.length}/${t.length})`):x.default.gray(" Type to filter, \u2191\u2193 to navigate, Enter to select");console.log(d),console.log();let f=fe,h=0,y=i.length;if(i.length>f){let b=Math.floor(f/2);h=Math.max(0,n-b),y=Math.min(i.length,h+f),y===i.length&&(h=Math.max(0,y-f))}if(i.length===0)console.log(x.default.yellow(" No matches found"));else{h>0&&console.log(x.default.gray(` \u2191 ${h} more above`));for(let b=h;b<y;b++){let k=i[b];console.log(b===n?x.default.cyan(`\u276F ${k.label}`):x.default.white(` ${k.label}`))}y<i.length&&console.log(x.default.gray(` \u2193 ${i.length-y} more below`))}},l=()=>{let d=o.toLowerCase();i=d?t.filter(f=>f.label.toLowerCase().includes(d)):[...t],n>=i.length&&(n=Math.max(0,i.length-1))},m=d=>{let f=d.toString();if(f===""&&(g(),process.exit(0)),f==="\r"||f===`
3
- `){i.length>0&&(g(),r(i[n]));return}if(f==="\x1B"&&d.length===1){o&&(o="",l(),u());return}if(f==="\x1B[A"){i.length>0&&(n=n>0?n-1:i.length-1,u());return}if(f==="\x1B[B"){i.length>0&&(n=n<i.length-1?n+1:0,u());return}if(f==="\x7F"||f==="\b"){o.length>0&&(o=o.slice(0,-1),l(),u());return}f.length===1&&f>=" "&&f<="~"&&(o+=f,l(),u())},g=()=>{process.stdin.removeListener("data",m),process.stdin.isTTY&&process.stdin.setRawMode(!1),a.close(),process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[?1049l")};u(),process.stdin.on("data",m)})}},V=class{async prompt(e,t){let{value:r}=await K.default.prompt([{type:"input",name:"value",message:x.default.cyan(e),default:t}]);return r}};var H=v(require("boxen"),1),A=v(require("chalk"),1);function Q(s,e,t,r={}){let{borderColor:o="cyan",isNested:n=!1}=r,i;e!==void 0&&(t?i=`line ${e} in ${t}`:i=`line ${e}`);let a=n?`\u2502 ${s}`:`> ${s}`;return(0,H.default)(a,{title:i,borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:o})}function B(s,e=!1,t){let r=s?"\u2713 Completed":"\u2717 Failed",o=s?A.default.green(r):A.default.red(r);if(t!==void 0){let n=D(t);return`${o} ${A.default.gray(`(${n})`)}`}return o}function W(s){return(0,H.default)(`\u2717 ${s}`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"red"})}function de(s){return(0,H.default)(`> Starting parallel execution (${s} branches)`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"yellow"})}function he(s){let e=s?"\u2713 All parallel branches completed":"\u2717 Some parallel branches failed";return s?A.default.green(e):A.default.red(e)}function ee(s,e=!1){return`${e?"| \u2502 ":"\u2502 "}${s}`}function D(s){return`${(s/1e3).toFixed(3)}s`}var ge=require("fs"),we=require("path"),I=class{constructor(e){this.workspace=e}evaluate(e){return"var"in e||"has"in e?this.evaluateVarExists(e):"file"in e?this.evaluateFileExists(e):"choice"in e?this.evaluateChoice(e):"all"in e?this.evaluateAll(e):"any"in e?this.evaluateAny(e):"not"in e?this.evaluateNot(e):!1}evaluateVarExists(e){if(e.has)return this.workspace.hasVariable(e.has)||this.workspace.hasFact(e.has);if(!e.var)return!1;if(typeof e.var=="object"){for(let[r,o]of Object.entries(e.var)){let n=this.workspace.getVariable(r),i=this.workspace.getFact(r),a=n??(i!==void 0?i.toString():void 0);if(a===void 0||a!==o)return!1}return!0}let t=e.var;return this.workspace.hasVariable(t)||this.workspace.hasFact(t)}evaluateFileExists(e){try{let t=e.file.trim(),r=(0,we.resolve)(process.cwd(),t);return(0,ge.existsSync)(r)}catch{return!1}}evaluateChoice(e){return this.workspace.hasChoice(e.choice)}evaluateAll(e){return e.all.every(t=>this.evaluate(t))}evaluateAny(e){return e.any.some(t=>this.evaluate(t))}evaluateNot(e){return!this.evaluate(e.not)}};var R=require("fs/promises"),be=require("os"),T=require("path"),ye=v(require("dayjs"),1),F=(0,T.join)((0,be.homedir)(),".pipeliner","workflow-history"),L=class{constructor(){}async saveHistory(e){await(0,R.mkdir)(F,{recursive:!0});let t=(0,ye.default)().format("YYYY-MM-DD_HH-mm-ss"),r=Math.random().toString(36).slice(2,6),o=(0,T.join)(F,`workflow-${t}-${r}.json`);return await(0,R.writeFile)(o,JSON.stringify(e,null,2),{encoding:"utf8"}),o}async clearAllHistories(){await(0,R.rm)(F,{recursive:!0,force:!0})}async removeHistory(e){await(0,R.rm)((0,T.join)(F,e),{force:!0})}async getHistoryNames(){try{let t=(await(0,R.readdir)(F)).map(r=>(0,T.basename)(r));return t.sort((r,o)=>{let n=u=>{let l=u.match(/workflow-(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-/);return l?l[1]:""},i=n(r),a=n(o);return i===a?o.localeCompare(r):a.localeCompare(i)}),t}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return[];throw e}}async getHistory(e){let t=await(0,R.readFile)((0,T.join)(F,e),{encoding:"utf8"});return JSON.parse(t)}};var J=class{records=[];initialTimestamp=Date.now();recordStartTimestamp=Date.now();constructor(){this.records=[]}recordStart(){this.recordStartTimestamp=Date.now()}recordEnd(e,t,r,o){let n=this.getDuration();return this.records.push({step:e,context:t,output:r,duration:n,status:o}),n}reset(){this.records=[],this.initialTimestamp=Date.now()}async save(){let e=new L,t={initialTimestamp:this.initialTimestamp,records:this.records};return await e.saveHistory(t)}getDuration(){return Date.now()-this.recordStartTimestamp}};var te=require("child_process");var U=class{async run(e,t,r,o,n=!1,i=!1,a,u,l,m){return n?this.runBuffered(e,l,m):this.runRealtime(e,r||e,i,a,u,l,m)}async runBuffered(e,t,r){let o=this.createSpawnOptions(t);return new Promise((n,i)=>{let a=(0,te.spawn)(e,[],o),u=[],l=[],m="",g="",d=null;r&&r>0&&(d=setTimeout(()=>{a.kill("SIGTERM");let f=`Command timed out after ${r} seconds`;l.push(f),n({success:!1,stdout:u,stderr:l})},r*1e3)),a.stdout?.on("data",f=>{let h=f.toString(),{lines:y,remaining:b}=this.processStreamBuffer(h,m);u.push(...y),m=b}),a.stderr?.on("data",f=>{let h=f.toString(),{lines:y,remaining:b}=this.processStreamBuffer(h,g);l.push(...y),g=b}),a.on("close",f=>{d&&clearTimeout(d),m.trim()&&u.push(m),g.trim()&&l.push(g),n({success:f===0,stdout:u,stderr:l})}),a.on("error",f=>{d&&clearTimeout(d);let h=`Error: ${f.message}`;n({success:!1,stdout:u,stderr:[...l,h]})})})}async runRealtime(e,t,r,o,n,i,a){let u=this.createSpawnOptions(i),m=Q(t,o,n,{borderColor:r?"green":"cyan"});console.log(m);let g=Date.now();return new Promise(d=>{let f=(0,te.spawn)(e,[],u),h="",y="",b=null;a&&a>0&&(b=setTimeout(()=>{f.kill("SIGTERM");let k=`Command timed out after ${a} seconds`,$=W(k);console.error($);let P=Date.now()-g,j=B(!1,!1,P);console.log(j),d(!1)},a*1e3)),f.stdout?.on("data",k=>{let $=k.toString(),{lines:P,remaining:j}=this.processStreamBuffer($,h);P.forEach(X=>process.stdout.write(`\u2502 ${X}
4
- `)),h=j}),f.stderr?.on("data",k=>{let $=k.toString(),{lines:P,remaining:j}=this.processStreamBuffer($,y);P.forEach(X=>process.stderr.write(`\u2502 ${X}
5
- `)),y=j}),f.on("close",k=>{b&&clearTimeout(b),h.trim()&&process.stdout.write(`\u2502 ${h}
6
- `),y.trim()&&process.stderr.write(`\u2502 ${y}
7
- `);let $=k===0,P=Date.now()-g,j=B($,!1,P);console.log(j),d($)}),f.on("error",k=>{b&&clearTimeout(b);let $=W(`Error: ${k.message}`);console.error($),d(!1)})})}createSpawnOptions(e){let t={stdio:["inherit","pipe","pipe"],shell:!0};return e&&(t.cwd=e),t}processStreamBuffer(e,t){let r=t+e,o=[],n=r;for(;n.includes(`
8
- `);){let i=n.indexOf(`
9
- `),a=n.substring(0,i);n=n.substring(i+1),o.push(a)}return{lines:o,remaining:n}}formatNestedOutput(e,t){t?e.split(`
10
- `).forEach(r=>{r.trim()&&console.log(`| ${r}`)}):console.log(e)}displayBufferedOutput(e,t,r=!1,o,n){let i=Q(t,o,n,{borderColor:"cyan",isNested:r});this.formatNestedOutput(i,r),e.stdout.forEach(u=>{let l=ee(u,r);process.stdout.write(`${l}
11
- `)}),e.stderr.forEach(u=>{let l=ee(u,r);process.stderr.write(`${l}
12
- `)});let a=B(e.success,r);console.log(a)}};function Je(s,e,t){if(e.hasVariable(s))return e.getVariable(s)||t;if(e.hasFact(s)){let r=e.getFact(s);return typeof r=="string"?r:String(r)}return e.hasChoice(s)&&e.getChoice(s)||t}function Y(s,e){let t=/\{\{(\w+)\}\}/g;return s.replace(t,(r,o)=>Je(o,e,r))}var z=class s{state;constructor(){this.state={facts:new Map,choices:new Map,variables:new Map,stepResults:new Map,lastStepIndex:-1}}hasFact(e){return this.state.facts.has(e)}getFact(e){return this.state.facts.get(e)}setFact(e,t){this.state.facts.set(e,t)}getFactStatus(e){if(!this.hasFact(e))return"pending";let t=this.getFact(e);return t===!1||t==="failed"?"failed":"ready"}getAllFacts(){return new Map(this.state.facts)}hasChoice(e){return this.state.choices.has(e)}getChoice(e){return this.state.choices.get(e)}setChoice(e,t){this.state.choices.set(e,t)}hasVariable(e){return this.state.variables.has(e)}getVariable(e){return this.state.variables.get(e)}setVariable(e,t){this.state.variables.set(e,t)}getAllVariables(){return new Map(this.state.variables)}setStepResult(e,t,r){this.state.stepResults.set(e,{success:t,exitCode:r}),this.state.lastStepIndex=e}getStepResult(e){return this.state.stepResults.get(e)}getLastStepResult(){if(this.state.lastStepIndex!==-1)return this.state.stepResults.get(this.state.lastStepIndex)}clone(){let e=new s;return e.state.facts=new Map(this.state.facts),e.state.choices=new Map(this.state.choices),e.state.variables=new Map(this.state.variables),e.state.stepResults=new Map(this.state.stepResults),e.state.lastStepIndex=this.state.lastStepIndex,e}};var Z=class s{static PARALLEL_STEP_INDEX_MULTIPLIER=1e3;workspace;taskRunner;choicePrompt;textPrompt;baseDir;constructor(){this.workspace=new z,this.taskRunner=new U,this.choicePrompt=new M,this.textPrompt=new V}resolveBaseDir(e){if(e.baseDir)if((0,N.isAbsolute)(e.baseDir))this.baseDir=e.baseDir;else if(e._filePath){let t=(0,N.dirname)(e._filePath);this.baseDir=(0,N.resolve)(t,e.baseDir)}else this.baseDir=(0,N.resolve)(process.cwd(),e.baseDir)}createStepContext(e,t){let r={workspace:this.workspace,stepIndex:e};return t._lineNumbers&&(r.lineNumber=t._lineNumbers.get(e)),t._fileName&&(r.fileName=t._fileName),r}evaluateStepCondition(e){return e.when?new I(this.workspace).evaluate(e.when):!0}calculateBaseStepIndex(e){return e.branchIndex===void 0?e.stepIndex:Math.floor(e.stepIndex/s.PARALLEL_STEP_INDEX_MULTIPLIER)}isRunStep(e){return"run"in e}async execute(e){this.resolveBaseDir(e);let t=new J,r=Date.now();for(let i=0;i<e.steps.length;i++){let a=e.steps[i],u=this.createStepContext(i,e),l=!!a.when;if(this.evaluateStepCondition(a)){t.recordStart();try{let m=await this.executeStep(a,u,!1,l);this.handleStepResult(a,u,i,m,t)}catch(m){throw this.handleStepError(a,u,i,m,t),m}}}let o=Date.now()-r,n=D(o);console.log(Se.default.cyan(`
13
- Total execution time: ${n}`)),await t.save(),t.reset()}isStepSuccessful(e,t){return"run"in t?typeof e=="boolean"?e:e&&typeof e=="object"&&"success"in e?e.success:!1:!0}handleStepResult(e,t,r,o,n){let i=this.isRunStep(e)?(()=>{let l=this.workspace.getStepResult(r);return l?l.success:!0})():this.isStepSuccessful(o,e),a=i?"success":"failure",u=n.recordEnd(e,t,o,a);if(!this.isRunStep(e)){let l=B(i,!1,u);console.log(l)}if(this.isRunStep(e)){if(e.continue===!1){let l=t.lineNumber?` (line ${t.lineNumber})`:"",m=i?`Step ${r}${l} completed, but workflow stopped due to continue: false`:`Step ${r}${l} failed`;throw new Error(m)}if(!i&&e.continue!==!0){let l=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Step ${r}${l} failed`)}}}handleStepError(e,t,r,o,n){this.workspace.setStepResult(r,!1);let i=o instanceof Error?o.message:String(o),a={success:!1,stdout:[],stderr:[i]};n.recordEnd(e,t,a,"failure")}fixMalformedStep(e){let r=e;return"choose"in e&&r.choose===null&&"message"in e&&"options"in e?{choose:{message:r.message,options:r.options,as:r.as},when:r.when}:"prompt"in e&&r.prompt===null&&"message"in e&&"as"in e?{prompt:{message:r.message,as:r.as,default:r.default},when:r.when}:e}async executeStep(e,t,r=!1,o=!1){if(e=this.fixMalformedStep(e),"run"in e){let n=await this.executeRunStep(e,t,r,o);return r&&typeof n=="object"&&"stdout"in n,n}if("choose"in e){await this.executeChooseStep(e,t);return}if("prompt"in e){await this.executePromptStep(e,t);return}if("parallel"in e){await this.executeParallelStep(e,t);return}if("fail"in e){await this.executeFailStep(e,t);return}}async executeSingleRun(e,t,r=!1,o=!1){let n=this.calculateBaseStepIndex(t),i=Y(e.run,this.workspace),a=e.retry??0,u=e.timeout,l=!1,m=0;for(;m<=a;){let g=await this.taskRunner.run(i,n,i,t.branchIndex,r,o,t.lineNumber,t.fileName,this.baseDir,u),d=typeof g=="boolean"?g:g.success;if(l=g,d||m>=a)break;if(m++,m<=a){let f=Math.min(1e3*Math.pow(2,m-1),1e4);await new Promise(h=>setTimeout(h,f))}}return l}async executeRunStep(e,t,r=!1,o=!1){let n=await this.executeSingleRun({run:e.run,timeout:e.timeout,retry:e.retry},t,r,o),i=typeof n=="boolean"?n:n.success;if(this.workspace.setStepResult(t.stepIndex,i),i||!e.onError)return n;let a={run:e.onError.run,timeout:e.onError.timeout,retry:e.onError.retry,onError:e.onError.onError??void 0};return await this.executeRunChain(a,t,r,o)}async executeRunChain(e,t,r,o){let n=await this.executeSingleRun({run:e.run,timeout:e.timeout,retry:e.retry},t,r,o);return(typeof n=="boolean"?n:n.success)||!e.onError?n:this.executeRunChain(e.onError,t,r,o)}async executeChooseStep(e,t){let r=await this.choicePrompt.prompt(e.choose.message,e.choose.options);if(!r?.id)throw new Error(`Invalid choice result: ${JSON.stringify(r)}`);let o=e.choose.as??r.id;this.workspace.setChoice(r.id,r.id),this.workspace.setVariable(o,r.id),this.workspace.setStepResult(t.stepIndex,!0)}async executePromptStep(e,t){let r=Y(e.prompt.message,this.workspace),o=e.prompt.default?Y(e.prompt.default,this.workspace):void 0,n=await this.textPrompt.prompt(r,o);this.workspace.setVariable(e.prompt.as,n),this.workspace.setFact(e.prompt.as,n),this.workspace.setStepResult(t.stepIndex,!0)}createParallelContexts(e,t){return e.parallel.map((r,o)=>({workspace:this.workspace.clone(),stepIndex:t.stepIndex*s.PARALLEL_STEP_INDEX_MULTIPLIER+o,branchIndex:o,lineNumber:t.lineNumber,fileName:t.fileName}))}getBranchDisplayName(e,t){return"run"in e?e.run:"choose"in e?`Choose: ${e.choose.message}`:"prompt"in e?`Prompt: ${e.prompt.message}`:"fail"in e?`Fail: ${e.fail.message}`:`Branch ${t+1}`}async executeParallelBranches(e,t){let r=[],o=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],n=0;for(let l=0;l<e.length;l++){let m=e[l],g=t[l];if(m.when&&!new I(g.workspace).evaluate(m.when))continue;let d=this.getBranchDisplayName(m,l);r.push({index:l,name:d,status:"pending"})}let i=setInterval(()=>{n=(n+1)%o.length,this.updateParallelBranchesDisplay(r,o[n])},100),a=r.map(async l=>{let{index:m}=l,g=e[m],d=t[m];l.status="running";try{let f=await this.executeStep(g,d,!0);return l.status="success",this.updateParallelBranchesDisplay(r,o[n]),{index:m,result:f,context:d}}catch(f){d.workspace.setStepResult(d.stepIndex,!1);let h=f instanceof Error?f.message:String(f);return l.status="failed",l.error=h,this.updateParallelBranchesDisplay(r,o[n]),{index:m,error:f,context:d}}}),u=await Promise.all(a);return clearInterval(i),this.updateParallelBranchesDisplay(r,"",!0),q.default.done(),u}updateParallelBranchesDisplay(e,t,r=!1){let o=e.map(n=>{let i=n.index+1,a="",u="";switch(n.status){case"pending":a="\u25CB",u=`Branch ${i}: ${n.name} - Pending`;break;case"running":a=t,u=`Branch ${i}: ${n.name} - Running...`;break;case"success":a="\u2713",u=`Branch ${i}: ${n.name} - Completed`;break;case"failed":a="\u2717",u=`Branch ${i}: ${n.name} - Failed${n.error?`: ${n.error}`:""}`;break}return`${a} ${u}`});r?(0,q.default)(o.join(`
14
- `)):(0,q.default)(o.join(`
15
- `))}displayParallelResults(e,t,r){let o=!0,n=!1;console.log("");for(let a of e){if(!a)continue;n=!0;let{index:u,result:l,error:m,context:g}=a;if(m){o=!1;let d=`Branch ${u+1} failed: ${m instanceof Error?m.message:String(m)}`,f=W(d);console.error(f)}else if(l&&typeof l=="object"&&"stdout"in l){let d=l;if(o=o&&d.success,d.stdout.length>0||d.stderr.length>0||!d.success){let f=t[u],h=this.getBranchDisplayName(f,u);this.taskRunner.displayBufferedOutput(d,h,!1,g.lineNumber,g.fileName)}}}n||console.log("\u26A0\uFE0F All parallel branches were skipped (conditions not met)");let i=he(o);return console.log(i),o}mergeParallelResults(e){for(let t of e){let r=t.workspace.getAllFacts(),o=t.workspace.getAllVariables();for(let[n,i]of r)this.workspace.setFact(n,i);for(let[n,i]of o)this.workspace.setVariable(n,i)}}countExecutableBranches(e,t){let r=0;for(let o=0;o<e.length;o++){let n=e[o],i=t[o];n.when&&!new I(i.workspace).evaluate(n.when)||r++}return r}async executeParallelStep(e,t){let r=this.createParallelContexts(e,t),o=this.countExecutableBranches(e.parallel,r),n=de(o);console.log(n);let i=await this.executeParallelBranches(e.parallel,r),a=this.displayParallelResults(i,e.parallel,t);if(this.workspace.setStepResult(t.stepIndex,a),!a){let u=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Parallel step ${t.stepIndex}${u} failed: one or more branches failed`)}this.mergeParallelResults(r)}async executeFailStep(e,t){let r=new Error(e.fail.message);throw r.stack=void 0,r}};var $e=require("yaml"),se=require("zod");var c=require("zod"),Ue=c.z.object({file:c.z.string()}),Ye=c.z.object({var:c.z.union([c.z.string(),c.z.record(c.z.string(),c.z.string())]).optional(),has:c.z.string().optional()}),ze=c.z.object({status:c.z.object({fact:c.z.string(),is:c.z.enum(["ready","failed","pending"])})}),qe=c.z.object({step:c.z.object({success:c.z.boolean()}).optional(),last_step:c.z.enum(["success","failure"]).optional()}),Ze=c.z.object({choice:c.z.string()}),Ge=c.z.union([Ue,Ze,Ye,ze,qe]),E=c.z.lazy(()=>c.z.union([Ge,c.z.object({all:c.z.array(E)}),c.z.object({any:c.z.array(E)}),c.z.object({not:E})])),ke=c.z.lazy(()=>c.z.object({run:c.z.string(),timeout:c.z.number().optional(),retry:c.z.number().optional(),onError:ke.optional()})),xe=c.z.object({run:c.z.string(),when:E.optional(),timeout:c.z.number().optional(),retry:c.z.number().optional(),continue:c.z.boolean().optional(),onError:ke.optional()}),Xe=c.z.object({choose:c.z.object({message:c.z.string(),options:c.z.array(c.z.object({id:c.z.string(),label:c.z.string()})),as:c.z.string().optional()}),when:E.optional()}),Ke=c.z.object({prompt:c.z.object({message:c.z.string(),as:c.z.string(),default:c.z.string().optional(),validate:c.z.string().optional()}),when:E.optional()});function ve(s){if(!s||typeof s!="object")return{found:!1};let e=s;if("choose"in e)return{found:!0,type:"choose"};if("prompt"in e)return{found:!0,type:"prompt"};if("parallel"in e&&Array.isArray(e.parallel))for(let t of e.parallel){let r=ve(t);if(r.found)return r}return{found:!1}}var Re=c.z.lazy(()=>c.z.union([xe,c.z.object({parallel:c.z.array(c.z.lazy(()=>Re)),when:E.optional()}),c.z.object({fail:c.z.object({message:c.z.string()}),when:E.optional()})]).superRefine((s,e)=>{let t=ve(s);t.found&&e.addIssue({code:c.z.ZodIssueCode.custom,message:`'${t.type}' step is not allowed inside 'parallel' block (user input cannot run in parallel)`})})),Qe=c.z.lazy(()=>c.z.union([xe,Xe,Ke,c.z.object({parallel:c.z.array(Re),when:E.optional()}),c.z.object({fail:c.z.object({message:c.z.string()}),when:E.optional()})])),et=c.z.object({name:c.z.string().optional(),baseDir:c.z.string().optional(),steps:c.z.array(Qe).min(1,"Workflow must have at least one step")});function re(s){return et.parse(s)}function Ee(s,e){let t=s.path;if(s.code==="custom"){let o=oe(t);return` - ${s.message}${o}`}if(s.message==="Invalid input"){let o=oe(t),n=tt(t,e);return n?` - ${n}${o}`:` - Invalid step type${o}`}let r=oe(t);return` - ${s.message}${r}`}function oe(s){if(s.length===0)return"";let e=[];for(let t=0;t<s.length;t++){let r=s[t],o=s[t+1];r==="steps"&&typeof o=="number"?(e.push(`step ${o+1}`),t++):r==="parallel"&&typeof o=="number"?(e.push(`parallel branch ${o+1}`),t++):typeof r=="string"&&r!=="steps"&&r!=="parallel"&&e.push(r)}return e.length>0?` (${e.join(" \u2192 ")})`:""}function w(s,e,t){let r=t?`
2
+ "use strict";var Fe=Object.create;var pe=Object.defineProperty;var Ve=Object.getOwnPropertyDescriptor;var We=Object.getOwnPropertyNames;var Oe=Object.getPrototypeOf,_e=Object.prototype.hasOwnProperty;var He=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of We(e))!_e.call(s,n)&&n!==t&&pe(s,n,{get:()=>e[n],enumerable:!(r=Ve(e,n))||r.enumerable});return s};var x=(s,e,t)=>(t=s!=null?Fe(Oe(s)):{},He(e||!s||!s.__esModule?pe(t,"default",{value:s,enumerable:!0}):t,s));var Ae=require("child_process"),ce=require("fs"),Ie=require("fs/promises"),V=require("path"),Be=require("util"),ue=x(require("boxen"),1),p=x(require("chalk"),1),De=require("commander"),Le=x(require("dayjs"),1);var T=require("path"),Se=x(require("chalk"),1),q=x(require("log-update"),1);var me=x(require("readline"),1),v=x(require("chalk"),1),K=x(require("inquirer"),1),fe=15,M=class{searchable;constructor(e=!1){this.searchable=e}async prompt(e,t){if(this.searchable)return this.promptWithSearch(e,t);let{choice:r}=await K.default.prompt([{type:"list",name:"choice",message:v.default.cyan(e),choices:t.map(o=>({name:o.label,value:o.id})),pageSize:fe}]),n=t.find(o=>o.id===r);if(!n)throw new Error(`Invalid choice: ${r}`);return n}async promptWithSearch(e,t){return new Promise(r=>{let n="",o=0,i=[...t],a=me.createInterface({input:process.stdin,output:process.stdout,terminal:!1});process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdout.write("\x1B[?1049h"),process.stdout.write("\x1B[?25l");let u=()=>{process.stdout.write("\x1B[H\x1B[2J"),console.log(v.default.cyan(`? ${e}`));let d=n?v.default.gray(` Filter: ${n}`)+v.default.gray(` (${i.length}/${t.length})`):v.default.gray(" Type to filter, \u2191\u2193 to navigate, Enter to select");console.log(d),console.log();let f=fe,g=0,b=i.length;if(i.length>f){let y=Math.floor(f/2);g=Math.max(0,o-y),b=Math.min(i.length,g+f),b===i.length&&(g=Math.max(0,b-f))}if(i.length===0)console.log(v.default.yellow(" No matches found"));else{g>0&&console.log(v.default.gray(` \u2191 ${g} more above`));for(let y=g;y<b;y++){let k=i[y];console.log(y===o?v.default.cyan(`\u276F ${k.label}`):v.default.white(` ${k.label}`))}b<i.length&&console.log(v.default.gray(` \u2193 ${i.length-b} more below`))}},c=()=>{let d=n.toLowerCase();i=d?t.filter(f=>f.label.toLowerCase().includes(d)):[...t],o>=i.length&&(o=Math.max(0,i.length-1))},m=d=>{let f=d.toString();if(f===""&&(h(),process.exit(0)),f==="\r"||f===`
3
+ `){i.length>0&&(h(),r(i[o]));return}if(f==="\x1B"&&d.length===1){n&&(n="",c(),u());return}if(f==="\x1B[A"){i.length>0&&(o=o>0?o-1:i.length-1,u());return}if(f==="\x1B[B"){i.length>0&&(o=o<i.length-1?o+1:0,u());return}if(f==="\x7F"||f==="\b"){n.length>0&&(n=n.slice(0,-1),c(),u());return}f.length===1&&f>=" "&&f<="~"&&(n+=f,c(),u())},h=()=>{process.stdin.removeListener("data",m),process.stdin.isTTY&&process.stdin.setRawMode(!1),a.close(),process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[?1049l")};u(),process.stdin.on("data",m)})}},_=class{async prompt(e,t){let{value:r}=await K.default.prompt([{type:"input",name:"value",message:v.default.cyan(e),default:t}]);return r}};var H=x(require("boxen"),1),A=x(require("chalk"),1);function Q(s,e,t,r={}){let{borderColor:n="cyan",isNested:o=!1}=r,i;e!==void 0&&(t?i=`line ${e} in ${t}`:i=`line ${e}`);let a=o?`\u2502 ${s}`:`> ${s}`;return(0,H.default)(a,{title:i,borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:n})}function I(s,e=!1,t){let r=s?"\u2713 Completed":"\u2717 Failed",n=s?A.default.green(r):A.default.red(r);if(t!==void 0){let o=B(t);return`${n} ${A.default.gray(`(${o})`)}`}return n}function W(s){return(0,H.default)(`\u2717 ${s}`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"red"})}function de(s){return(0,H.default)(`> Starting parallel execution (${s} branches)`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"yellow"})}function he(s){let e=s?"\u2713 All parallel branches completed":"\u2717 Some parallel branches failed";return s?A.default.green(e):A.default.red(e)}function ee(s,e=!1){return`${e?"| \u2502 ":"\u2502 "}${s}`}function B(s){return`${(s/1e3).toFixed(3)}s`}var ge=require("fs"),we=require("path"),D=class{constructor(e){this.workspace=e}evaluate(e){return"var"in e||"has"in e?this.evaluateVarExists(e):"file"in e?this.evaluateFileExists(e):"choice"in e?this.evaluateChoice(e):"all"in e?this.evaluateAll(e):"any"in e?this.evaluateAny(e):"not"in e?this.evaluateNot(e):!1}evaluateVarExists(e){if(e.has)return this.workspace.hasVariable(e.has)||this.workspace.hasFact(e.has);if(!e.var)return!1;if(typeof e.var=="object"){for(let[r,n]of Object.entries(e.var)){let o=this.workspace.getVariable(r),i=this.workspace.getFact(r),a=o??(i!==void 0?i.toString():void 0);if(a===void 0||a!==n)return!1}return!0}let t=e.var;return this.workspace.hasVariable(t)||this.workspace.hasFact(t)}evaluateFileExists(e){try{let t=e.file.trim(),r=(0,we.resolve)(process.cwd(),t);return(0,ge.existsSync)(r)}catch{return!1}}evaluateChoice(e){return this.workspace.hasChoice(e.choice)}evaluateAll(e){return e.all.every(t=>this.evaluate(t))}evaluateAny(e){return e.any.some(t=>this.evaluate(t))}evaluateNot(e){return!this.evaluate(e.not)}};var R=require("fs/promises"),be=require("os"),N=require("path"),ye=x(require("dayjs"),1),L=(0,N.join)((0,be.homedir)(),".pipeliner","workflow-history"),F=class{constructor(){}async saveHistory(e){await(0,R.mkdir)(L,{recursive:!0});let t=(0,ye.default)().format("YYYY-MM-DD_HH-mm-ss"),r=Math.random().toString(36).slice(2,6),n=(0,N.join)(L,`workflow-${t}-${r}.json`);return await(0,R.writeFile)(n,JSON.stringify(e,null,2),{encoding:"utf8"}),n}async clearAllHistories(){await(0,R.rm)(L,{recursive:!0,force:!0})}async removeHistory(e){await(0,R.rm)((0,N.join)(L,e),{force:!0})}async getHistoryNames(){try{let t=(await(0,R.readdir)(L)).map(r=>(0,N.basename)(r));return t.sort((r,n)=>{let o=u=>{let c=u.match(/workflow-(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-/);return c?c[1]:""},i=o(r),a=o(n);return i===a?n.localeCompare(r):a.localeCompare(i)}),t}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return[];throw e}}async getHistory(e){let t=await(0,R.readFile)((0,N.join)(L,e),{encoding:"utf8"});return JSON.parse(t)}};var J=class{records=[];initialTimestamp=Date.now();recordStartTimestamp=Date.now();constructor(){this.records=[]}recordStart(){this.recordStartTimestamp=Date.now()}recordEnd(e,t,r,n){let o=this.getDuration();return this.records.push({step:e,context:t,output:r,duration:o,status:n}),o}reset(){this.records=[],this.initialTimestamp=Date.now()}async save(){let e=new F,t={initialTimestamp:this.initialTimestamp,records:this.records};return await e.saveHistory(t)}getDuration(){return Date.now()-this.recordStartTimestamp}};var te=require("child_process");var U=class{async run(e,t,r,n,o=!1,i=!1,a,u,c,m,h){return o?this.runBuffered(e,c,m,h):this.runRealtime(e,r||e,i,a,u,c,m,h)}async runBuffered(e,t,r,n){return new Promise((o,i)=>{let a=this.spawnWithShell(e,t,n),u=[],c=[],m="",h="",d=null;r&&r>0&&(d=setTimeout(()=>{a.kill("SIGTERM");let f=`Command timed out after ${r} seconds`;c.push(f),o({success:!1,stdout:u,stderr:c})},r*1e3)),a.stdout?.on("data",f=>{let g=f.toString(),{lines:b,remaining:y}=this.processStreamBuffer(g,m);u.push(...b),m=y}),a.stderr?.on("data",f=>{let g=f.toString(),{lines:b,remaining:y}=this.processStreamBuffer(g,h);c.push(...b),h=y}),a.on("close",f=>{d&&clearTimeout(d),m.trim()&&u.push(m),h.trim()&&c.push(h),o({success:f===0,stdout:u,stderr:c})}),a.on("error",f=>{d&&clearTimeout(d);let g=`Error: ${f.message}`;o({success:!1,stdout:u,stderr:[...c,g]})})})}async runRealtime(e,t,r,n,o,i,a,u){let m=Q(t,n,o,{borderColor:r?"green":"cyan"});console.log(m);let h=Date.now();return new Promise(d=>{let f=this.spawnWithShell(e,i,u),g="",b="",y=null;a&&a>0&&(y=setTimeout(()=>{f.kill("SIGTERM");let k=`Command timed out after ${a} seconds`,$=W(k);console.error($);let P=Date.now()-h,j=I(!1,!1,P);console.log(j),d(!1)},a*1e3)),f.stdout?.on("data",k=>{let $=k.toString(),{lines:P,remaining:j}=this.processStreamBuffer($,g);P.forEach(X=>process.stdout.write(`\u2502 ${X}
4
+ `)),g=j}),f.stderr?.on("data",k=>{let $=k.toString(),{lines:P,remaining:j}=this.processStreamBuffer($,b);P.forEach(X=>process.stderr.write(`\u2502 ${X}
5
+ `)),b=j}),f.on("close",k=>{y&&clearTimeout(y),g.trim()&&process.stdout.write(`\u2502 ${g}
6
+ `),b.trim()&&process.stderr.write(`\u2502 ${b}
7
+ `);let $=k===0,P=Date.now()-h,j=I($,!1,P);console.log(j),d($)}),f.on("error",k=>{y&&clearTimeout(y);let $=W(`Error: ${k.message}`);console.error($),d(!1)})})}createSpawnOptions(e){let t={stdio:["inherit","pipe","pipe"],shell:!0};return e&&(t.cwd=e),t}spawnWithShell(e,t,r){if(r&&r.length>0){let n=r[0],o=[...r.slice(1),e],i={stdio:["inherit","pipe","pipe"]};return t&&(i.cwd=t),(0,te.spawn)(n,o,i)}else{let n=process.env.SHELL||(process.platform==="win32"?"cmd.exe":"/bin/sh"),o=process.platform==="win32"?"/c":"-c",i={stdio:["inherit","pipe","pipe"]};return t&&(i.cwd=t),(0,te.spawn)(n,[o,e],i)}}processStreamBuffer(e,t){let r=t+e,n=[],o=r;for(;o.includes(`
8
+ `);){let i=o.indexOf(`
9
+ `),a=o.substring(0,i);o=o.substring(i+1),n.push(a)}return{lines:n,remaining:o}}formatNestedOutput(e,t){t?e.split(`
10
+ `).forEach(r=>{r.trim()&&console.log(`| ${r}`)}):console.log(e)}displayBufferedOutput(e,t,r=!1,n,o){let i=Q(t,n,o,{borderColor:"cyan",isNested:r});this.formatNestedOutput(i,r),e.stdout.forEach(u=>{let c=ee(u,r);process.stdout.write(`${c}
11
+ `)}),e.stderr.forEach(u=>{let c=ee(u,r);process.stderr.write(`${c}
12
+ `)});let a=I(e.success,r);console.log(a)}};function Je(s,e,t){if(e.hasVariable(s)){let r=e.getVariable(s);return r??t}if(e.hasFact(s)){let r=e.getFact(s);return typeof r=="string"?r:String(r)}if(e.hasChoice(s)){let r=e.getChoice(s);return r??t}return t}function Y(s,e){let t=/\{\{\s*(\w+)\s*\}\}/g;return s.replace(t,(r,n)=>Je(n,e,r))}var z=class s{state;constructor(){this.state={facts:new Map,choices:new Map,variables:new Map,stepResults:new Map,lastStepIndex:-1}}hasFact(e){return this.state.facts.has(e)}getFact(e){return this.state.facts.get(e)}setFact(e,t){this.state.facts.set(e,t)}getFactStatus(e){if(!this.hasFact(e))return"pending";let t=this.getFact(e);return t===!1||t==="failed"?"failed":"ready"}getAllFacts(){return new Map(this.state.facts)}hasChoice(e){return this.state.choices.has(e)}getChoice(e){return this.state.choices.get(e)}setChoice(e,t){this.state.choices.set(e,t)}hasVariable(e){return this.state.variables.has(e)}getVariable(e){return this.state.variables.get(e)}setVariable(e,t){this.state.variables.set(e,t)}getAllVariables(){return new Map(this.state.variables)}setStepResult(e,t,r){this.state.stepResults.set(e,{success:t,exitCode:r}),this.state.lastStepIndex=e}getStepResult(e){return this.state.stepResults.get(e)}getLastStepResult(){if(this.state.lastStepIndex!==-1)return this.state.stepResults.get(this.state.lastStepIndex)}clone(){let e=new s;return e.state.facts=new Map(this.state.facts),e.state.choices=new Map(this.state.choices),e.state.variables=new Map(this.state.variables),e.state.stepResults=new Map(this.state.stepResults),e.state.lastStepIndex=this.state.lastStepIndex,e}};var Z=class s{static PARALLEL_STEP_INDEX_MULTIPLIER=1e3;workspace;taskRunner;choicePrompt;textPrompt;baseDir;globalShell;constructor(){this.workspace=new z,this.taskRunner=new U,this.choicePrompt=new M,this.textPrompt=new _}resolveBaseDir(e){if(e.baseDir)if((0,T.isAbsolute)(e.baseDir))this.baseDir=e.baseDir;else if(e._filePath){let t=(0,T.dirname)(e._filePath);this.baseDir=(0,T.resolve)(t,e.baseDir)}else this.baseDir=(0,T.resolve)(process.cwd(),e.baseDir)}createStepContext(e,t){let r={workspace:this.workspace,stepIndex:e};return t._lineNumbers&&(r.lineNumber=t._lineNumbers.get(e)),t._fileName&&(r.fileName=t._fileName),r}evaluateStepCondition(e){return e.when?new D(this.workspace).evaluate(e.when):!0}calculateBaseStepIndex(e){return e.branchIndex===void 0?e.stepIndex:Math.floor(e.stepIndex/s.PARALLEL_STEP_INDEX_MULTIPLIER)}isRunStep(e){return"run"in e}async execute(e,t){if(t?.profileVars&&Object.keys(t.profileVars).length>0)for(let[a,u]of Object.entries(t.profileVars))this.workspace.setVariable(a,u);this.resolveBaseDir(e),this.globalShell=e.shell;let r=new J,n=Date.now();for(let a=0;a<e.steps.length;a++){let u=e.steps[a],c=this.createStepContext(a,e),m=!!u.when;if(this.evaluateStepCondition(u)){r.recordStart();try{let h=await this.executeStep(u,c,!1,m);this.handleStepResult(u,c,a,h,r)}catch(h){throw this.handleStepError(u,c,a,h,r),h}}}let o=Date.now()-n,i=B(o);console.log(Se.default.cyan(`
13
+ Total execution time: ${i}`)),await r.save(),r.reset()}isStepSuccessful(e,t){return"run"in t?typeof e=="boolean"?e:e&&typeof e=="object"&&"success"in e?e.success:!1:!0}handleStepResult(e,t,r,n,o){let i=this.isRunStep(e)?(()=>{let c=this.workspace.getStepResult(r);return c?c.success:!0})():this.isStepSuccessful(n,e),a=i?"success":"failure",u=o.recordEnd(e,t,n,a);if(!this.isRunStep(e)){let c=I(i,!1,u);console.log(c)}if(this.isRunStep(e)){if(e.continue===!1){let c=t.lineNumber?` (line ${t.lineNumber})`:"",m=i?`Step ${r}${c} completed, but workflow stopped due to continue: false`:`Step ${r}${c} failed`;throw new Error(m)}if(!i&&e.continue!==!0){let c=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Step ${r}${c} failed`)}}}handleStepError(e,t,r,n,o){this.workspace.setStepResult(r,!1);let i=n instanceof Error?n.message:String(n),a={success:!1,stdout:[],stderr:[i]};o.recordEnd(e,t,a,"failure")}fixMalformedStep(e){let r=e;return"choose"in e&&r.choose===null&&"message"in e&&"options"in e?{choose:{message:r.message,options:r.options,as:r.as},when:r.when}:"prompt"in e&&r.prompt===null&&"message"in e&&"as"in e?{prompt:{message:r.message,as:r.as,default:r.default},when:r.when}:e}async executeStep(e,t,r=!1,n=!1){if(e=this.fixMalformedStep(e),"run"in e){let o=await this.executeRunStep(e,t,r,n);return r&&typeof o=="object"&&"stdout"in o,o}if("choose"in e){await this.executeChooseStep(e,t);return}if("prompt"in e){await this.executePromptStep(e,t);return}if("parallel"in e){await this.executeParallelStep(e,t);return}if("fail"in e){await this.executeFailStep(e,t);return}}async executeSingleRun(e,t,r=!1,n=!1){let o=this.calculateBaseStepIndex(t),i=Y(e.run,this.workspace),a=e.shell||this.globalShell,u=e.retry??0,c=e.timeout,m=!1,h=0;for(;h<=u;){let d=await this.taskRunner.run(i,o,i,t.branchIndex,r,n,t.lineNumber,t.fileName,this.baseDir,c,a),f=typeof d=="boolean"?d:d.success;if(m=d,f||h>=u)break;if(h++,h<=u){let g=Math.min(1e3*Math.pow(2,h-1),1e4);await new Promise(b=>setTimeout(b,g))}}return m}async executeRunStep(e,t,r=!1,n=!1){let o=await this.executeSingleRun({run:e.run,timeout:e.timeout,retry:e.retry,shell:e.shell},t,r,n),i=typeof o=="boolean"?o:o.success;if(this.workspace.setStepResult(t.stepIndex,i),i||!e.onError)return o;let a={run:e.onError.run,timeout:e.onError.timeout,retry:e.onError.retry,onError:e.onError.onError??void 0};return await this.executeRunChain(a,t,r,n)}async executeRunChain(e,t,r,n){let o=await this.executeSingleRun({run:e.run,timeout:e.timeout,retry:e.retry,shell:void 0},t,r,n);return(typeof o=="boolean"?o:o.success)||!e.onError?o:this.executeRunChain(e.onError,t,r,n)}async executeChooseStep(e,t){let r=e.choose.as,n=e.choose.options.map(a=>a.id);if(r&&this.workspace.hasVariable(r)){let a=this.workspace.getVariable(r)??"";if(n.includes(a)){this.workspace.setChoice(a,a),this.workspace.setStepResult(t.stepIndex,!0);return}}let o=await this.choicePrompt.prompt(e.choose.message,e.choose.options);if(!o?.id)throw new Error(`Invalid choice result: ${JSON.stringify(o)}`);let i=r??o.id;this.workspace.setChoice(o.id,o.id),this.workspace.setVariable(i,o.id),this.workspace.setStepResult(t.stepIndex,!0)}async executePromptStep(e,t){let r=e.prompt.as;if(this.workspace.hasVariable(r)){let a=this.workspace.getVariable(r)??"";this.workspace.setFact(r,a),this.workspace.setStepResult(t.stepIndex,!0);return}let n=Y(e.prompt.message,this.workspace),o=e.prompt.default?Y(e.prompt.default,this.workspace):void 0,i=await this.textPrompt.prompt(n,o);this.workspace.setVariable(r,i),this.workspace.setFact(r,i),this.workspace.setStepResult(t.stepIndex,!0)}createParallelContexts(e,t){return e.parallel.map((r,n)=>({workspace:this.workspace.clone(),stepIndex:t.stepIndex*s.PARALLEL_STEP_INDEX_MULTIPLIER+n,branchIndex:n,lineNumber:t.lineNumber,fileName:t.fileName}))}getBranchDisplayName(e,t){return"run"in e?e.run:"choose"in e?`Choose: ${e.choose.message}`:"prompt"in e?`Prompt: ${e.prompt.message}`:"fail"in e?`Fail: ${e.fail.message}`:`Branch ${t+1}`}async executeParallelBranches(e,t){let r=[],n=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],o=0;for(let c=0;c<e.length;c++){let m=e[c],h=t[c];if(m.when&&!new D(h.workspace).evaluate(m.when))continue;let d=this.getBranchDisplayName(m,c);r.push({index:c,name:d,status:"pending"})}let i=setInterval(()=>{o=(o+1)%n.length,this.updateParallelBranchesDisplay(r,n[o])},100),a=r.map(async c=>{let{index:m}=c,h=e[m],d=t[m];c.status="running";try{let f=await this.executeStep(h,d,!0);return c.status="success",this.updateParallelBranchesDisplay(r,n[o]),{index:m,result:f,context:d}}catch(f){d.workspace.setStepResult(d.stepIndex,!1);let g=f instanceof Error?f.message:String(f);return c.status="failed",c.error=g,this.updateParallelBranchesDisplay(r,n[o]),{index:m,error:f,context:d}}}),u=await Promise.all(a);return clearInterval(i),this.updateParallelBranchesDisplay(r,"",!0),q.default.done(),u}updateParallelBranchesDisplay(e,t,r=!1){let n=e.map(o=>{let i=o.index+1,a="",u="";switch(o.status){case"pending":a="\u25CB",u=`Branch ${i}: ${o.name} - Pending`;break;case"running":a=t,u=`Branch ${i}: ${o.name} - Running...`;break;case"success":a="\u2713",u=`Branch ${i}: ${o.name} - Completed`;break;case"failed":a="\u2717",u=`Branch ${i}: ${o.name} - Failed${o.error?`: ${o.error}`:""}`;break}return`${a} ${u}`});r?(0,q.default)(n.join(`
14
+ `)):(0,q.default)(n.join(`
15
+ `))}displayParallelResults(e,t,r){let n=!0,o=!1;console.log("");for(let a of e){if(!a)continue;o=!0;let{index:u,result:c,error:m,context:h}=a;if(m){n=!1;let d=`Branch ${u+1} failed: ${m instanceof Error?m.message:String(m)}`,f=W(d);console.error(f)}else if(c&&typeof c=="object"&&"stdout"in c){let d=c;if(n=n&&d.success,d.stdout.length>0||d.stderr.length>0||!d.success){let f=t[u],g=this.getBranchDisplayName(f,u);this.taskRunner.displayBufferedOutput(d,g,!1,h.lineNumber,h.fileName)}}}o||console.log("\u26A0\uFE0F All parallel branches were skipped (conditions not met)");let i=he(n);return console.log(i),n}mergeParallelResults(e){for(let t of e){let r=t.workspace.getAllFacts(),n=t.workspace.getAllVariables();for(let[o,i]of r)this.workspace.setFact(o,i);for(let[o,i]of n)this.workspace.setVariable(o,i)}}countExecutableBranches(e,t){let r=0;for(let n=0;n<e.length;n++){let o=e[n],i=t[n];o.when&&!new D(i.workspace).evaluate(o.when)||r++}return r}async executeParallelStep(e,t){let r=this.createParallelContexts(e,t),n=this.countExecutableBranches(e.parallel,r),o=de(n);console.log(o);let i=await this.executeParallelBranches(e.parallel,r),a=this.displayParallelResults(i,e.parallel,t);if(this.workspace.setStepResult(t.stepIndex,a),!a){let u=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Parallel step ${t.stepIndex}${u} failed: one or more branches failed`)}this.mergeParallelResults(r)}async executeFailStep(e,t){let r=new Error(e.fail.message);throw r.stack=void 0,r}};var $e=require("yaml"),se=require("zod");var l=require("zod"),Ue=l.z.object({file:l.z.string()}),Ye=l.z.object({var:l.z.union([l.z.string(),l.z.record(l.z.string(),l.z.string())]).optional(),has:l.z.string().optional()}),ze=l.z.object({status:l.z.object({fact:l.z.string(),is:l.z.enum(["ready","failed","pending"])})}),qe=l.z.object({step:l.z.object({success:l.z.boolean()}).optional(),last_step:l.z.enum(["success","failure"]).optional()}),Ze=l.z.object({choice:l.z.string()}),Ge=l.z.union([Ue,Ze,Ye,ze,qe]),E=l.z.lazy(()=>l.z.union([Ge,l.z.object({all:l.z.array(E)}),l.z.object({any:l.z.array(E)}),l.z.object({not:E})])),ke=l.z.lazy(()=>l.z.object({run:l.z.string(),timeout:l.z.number().optional(),retry:l.z.number().optional(),onError:ke.optional()})),ve=l.z.object({run:l.z.string(),when:E.optional(),timeout:l.z.number().optional(),retry:l.z.number().optional(),shell:l.z.array(l.z.string()).min(1,"shell must have at least one element").optional(),continue:l.z.boolean().optional(),onError:ke.optional()}),Xe=l.z.object({choose:l.z.object({message:l.z.string(),options:l.z.array(l.z.object({id:l.z.string(),label:l.z.string()})),as:l.z.string().optional()}),when:E.optional()}),Ke=l.z.object({prompt:l.z.object({message:l.z.string(),as:l.z.string(),default:l.z.string().optional(),validate:l.z.string().optional()}),when:E.optional()});function xe(s){if(!s||typeof s!="object")return{found:!1};let e=s;if("choose"in e)return{found:!0,type:"choose"};if("prompt"in e)return{found:!0,type:"prompt"};if("parallel"in e&&Array.isArray(e.parallel))for(let t of e.parallel){let r=xe(t);if(r.found)return r}return{found:!1}}var Re=l.z.lazy(()=>l.z.union([ve,l.z.object({parallel:l.z.array(l.z.lazy(()=>Re)),when:E.optional()}),l.z.object({fail:l.z.object({message:l.z.string()}),when:E.optional()})]).superRefine((s,e)=>{let t=xe(s);t.found&&e.addIssue({code:l.z.ZodIssueCode.custom,message:`'${t.type}' step is not allowed inside 'parallel' block (user input cannot run in parallel)`})})),Qe=l.z.lazy(()=>l.z.union([ve,Xe,Ke,l.z.object({parallel:l.z.array(Re),when:E.optional()}),l.z.object({fail:l.z.object({message:l.z.string()}),when:E.optional()})])),et=l.z.object({name:l.z.string().min(1,"Profile name must be non-empty"),var:l.z.record(l.z.string(),l.z.union([l.z.string(),l.z.number(),l.z.boolean()]).transform(String))}),tt=l.z.object({name:l.z.string().optional(),baseDir:l.z.string().optional(),shell:l.z.array(l.z.string()).min(1,"shell must have at least one element").optional(),profiles:l.z.array(et).optional(),steps:l.z.array(Qe).min(1,"Workflow must have at least one step")});function re(s){return tt.parse(s)}function Ee(s,e){let t=s.path;if(s.code==="custom"){let n=oe(t);return` - ${s.message}${n}`}if(s.message==="Invalid input"){let n=oe(t),o=rt(t,e);return o?` - ${o}${n}`:` - Invalid step type${n}`}let r=oe(t);return` - ${s.message}${r}`}function oe(s){if(s.length===0)return"";let e=[];for(let t=0;t<s.length;t++){let r=s[t],n=s[t+1];r==="steps"&&typeof n=="number"?(e.push(`step ${n+1}`),t++):r==="parallel"&&typeof n=="number"?(e.push(`parallel branch ${n+1}`),t++):typeof r=="string"&&r!=="steps"&&r!=="parallel"&&e.push(r)}return e.length>0?` (${e.join(" \u2192 ")})`:""}function w(s,e,t){let r=t?`
16
16
  Reason: ${t}`:"";throw new Error(`Invalid workflow structure:
17
- - ${e} (step ${s+1})${r}`)}function Ce(s,e,t=!1,r=[]){let o=["run","choose","prompt","parallel","fail"],n=o.find(i=>i in s);if(!n){let i=Object.keys(s).filter(a=>a!=="when");w(e,`Unknown step type. Found keys: [${i.join(", ")}]. Valid types: ${o.join(", ")}`)}if(n==="run"){let i=s.run;typeof i!="string"&&w(e,"'run' must be a string command"),i===""&&w(e,"'run' command cannot be empty")}if(n==="choose"){if(t){let u=r.join(" \u2192 ");throw new Error(`Invalid workflow structure:
17
+ - ${e} (step ${s+1})${r}`)}function Ce(s,e,t=!1,r=[]){let n=["run","choose","prompt","parallel","fail"],o=n.find(i=>i in s);if(!o){let i=Object.keys(s).filter(a=>a!=="when");w(e,`Unknown step type. Found keys: [${i.join(", ")}]. Valid types: ${n.join(", ")}`)}if(o==="run"){let i=s.run;if(typeof i!="string"&&w(e,"'run' must be a string command"),i===""&&w(e,"'run' command cannot be empty"),"shell"in s&&s.shell!==void 0){Array.isArray(s.shell)||w(e,"'shell' must be an array");let a=s.shell;a.length===0&&w(e,"'shell' cannot be empty","Shell configuration must have at least one element (program name)");for(let u=0;u<a.length;u++)typeof a[u]!="string"&&w(e,`'shell[${u}]' must be a string`)}}if(o==="choose"){if(t){let u=r.join(" \u2192 ");throw new Error(`Invalid workflow structure:
18
18
  - 'choose' step is not allowed inside 'parallel' block (step ${e+1}, ${u})
19
- Reason: User input prompts cannot run in parallel`)}let i=s.choose;(!i||typeof i!="object")&&w(e,"'choose' must be an object with 'message' and 'options'");let a=i;(!a.message||typeof a.message!="string")&&w(e,"'choose.message' is required and must be a string"),Array.isArray(a.options)||w(e,"'choose.options' is required and must be an array"),a.options.length===0&&w(e,"'choose.options' cannot be empty","At least one option is required");for(let u=0;u<a.options.length;u++){let l=a.options[u];(!l||typeof l!="object")&&w(e,`'choose.options[${u}]' must be an object with 'id' and 'label'`),(!l.id||typeof l.id!="string")&&w(e,`'choose.options[${u}].id' is required and must be a string`),(!l.label||typeof l.label!="string")&&w(e,`'choose.options[${u}].label' is required and must be a string`)}}if(n==="prompt"){if(t){let u=r.join(" \u2192 ");throw new Error(`Invalid workflow structure:
19
+ Reason: User input prompts cannot run in parallel`)}let i=s.choose;(!i||typeof i!="object")&&w(e,"'choose' must be an object with 'message' and 'options'");let a=i;(!a.message||typeof a.message!="string")&&w(e,"'choose.message' is required and must be a string"),Array.isArray(a.options)||w(e,"'choose.options' is required and must be an array"),a.options.length===0&&w(e,"'choose.options' cannot be empty","At least one option is required");for(let u=0;u<a.options.length;u++){let c=a.options[u];(!c||typeof c!="object")&&w(e,`'choose.options[${u}]' must be an object with 'id' and 'label'`),(!c.id||typeof c.id!="string")&&w(e,`'choose.options[${u}].id' is required and must be a string`),(!c.label||typeof c.label!="string")&&w(e,`'choose.options[${u}].label' is required and must be a string`)}}if(o==="prompt"){if(t){let u=r.join(" \u2192 ");throw new Error(`Invalid workflow structure:
20
20
  - 'prompt' step is not allowed inside 'parallel' block (step ${e+1}, ${u})
21
- Reason: User input prompts cannot run in parallel`)}let i=s.prompt;(!i||typeof i!="object")&&w(e,"'prompt' must be an object with 'message' and 'as'");let a=i;(!a.message||typeof a.message!="string")&&w(e,"'prompt.message' is required and must be a string"),(!a.as||typeof a.as!="string")&&w(e,"'prompt.as' is required and must be a string","The 'as' field specifies the variable name to store the user's input")}if(n==="parallel"){let i=s.parallel;Array.isArray(i)||w(e,"'parallel' must be an array of steps"),i.length===0&&w(e,"'parallel' cannot be empty","At least one step is required");for(let a=0;a<i.length;a++){let u=i[a];(!u||typeof u!="object")&&w(e,`'parallel[${a}]' must be a valid step object`);let l=[...r,`branch ${a+1}`];Ce(u,e,!0,l)}}if(n==="fail"){let i=s.fail;(!i||typeof i!="object")&&w(e,"'fail' must be an object with 'message'");let a=i;(!a.message||typeof a.message!="string")&&w(e,"'fail.message' is required and must be a string")}}function Pe(s){if(!s||typeof s!="object")throw new Error(`Invalid workflow structure:
21
+ Reason: User input prompts cannot run in parallel`)}let i=s.prompt;(!i||typeof i!="object")&&w(e,"'prompt' must be an object with 'message' and 'as'");let a=i;(!a.message||typeof a.message!="string")&&w(e,"'prompt.message' is required and must be a string"),(!a.as||typeof a.as!="string")&&w(e,"'prompt.as' is required and must be a string","The 'as' field specifies the variable name to store the user's input")}if(o==="parallel"){let i=s.parallel;Array.isArray(i)||w(e,"'parallel' must be an array of steps"),i.length===0&&w(e,"'parallel' cannot be empty","At least one step is required");for(let a=0;a<i.length;a++){let u=i[a];(!u||typeof u!="object")&&w(e,`'parallel[${a}]' must be a valid step object`);let c=[...r,`branch ${a+1}`];Ce(u,e,!0,c)}}if(o==="fail"){let i=s.fail;(!i||typeof i!="object")&&w(e,"'fail' must be an object with 'message'");let a=i;(!a.message||typeof a.message!="string")&&w(e,"'fail.message' is required and must be a string")}}function Pe(s){if(!s||typeof s!="object")throw new Error(`Invalid workflow structure:
22
22
  - Workflow must be an object`);let e=s;if("name"in e&&e.name!==void 0&&typeof e.name!="string")throw new Error(`Invalid workflow structure:
23
- - 'name' must be a string`);if(!("steps"in e))throw new Error(`Invalid workflow structure:
23
+ - 'name' must be a string`);if("shell"in e&&e.shell!==void 0){if(!Array.isArray(e.shell))throw new Error(`Invalid workflow structure:
24
+ - 'shell' must be an array`);if(e.shell.length===0)throw new Error(`Invalid workflow structure:
25
+ - 'shell' cannot be empty
26
+ Reason: Shell configuration must have at least one element (program name)`);for(let t=0;t<e.shell.length;t++)if(typeof e.shell[t]!="string")throw new Error(`Invalid workflow structure:
27
+ - 'shell[${t}]' must be a string`)}if(!("steps"in e))throw new Error(`Invalid workflow structure:
24
28
  - 'steps' is required`);if(!Array.isArray(e.steps))throw new Error(`Invalid workflow structure:
25
29
  - 'steps' must be an array`);if(e.steps.length===0)throw new Error(`Invalid workflow structure:
26
30
  - 'steps' cannot be empty
27
31
  Reason: Workflow must have at least one step`);for(let t=0;t<e.steps.length;t++){let r=e.steps[t];if(!r||typeof r!="object")throw new Error(`Invalid workflow structure:
28
- - Step ${t+1} must be an object`);Ce(r,t)}}function tt(s,e){try{let t=e;for(let n of s)if(typeof n!="symbol")if(t&&typeof t=="object")t=t[n];else return null;if(!t||typeof t!="object")return null;let o=Object.keys(t);if(o.length>0){let n=["run","choose","prompt","parallel","fail"];if(!o.some(a=>n.includes(a)))return`Unknown step type. Found keys: [${o.join(", ")}]. Valid types: run, choose, prompt, parallel, fail`}return null}catch{return null}}function ie(s){let e=s;return"choose"in e&&(e.choose===null||e.choose===void 0)&&"message"in e&&"options"in e?{choose:{message:e.message,options:e.options,as:e.as},when:e.when}:"prompt"in e&&(e.prompt===null||e.prompt===void 0)&&"message"in e&&"as"in e?{prompt:{message:e.message,as:e.as,default:e.default,validate:e.validate},when:e.when}:"parallel"in e&&Array.isArray(e.parallel)?{...e,parallel:e.parallel.map(t=>ie(t))}:s}var G=class{parse(e){let t;try{t=(0,$e.parse)(e)}catch(r){throw new Error(`Invalid YAML format: ${r instanceof Error?r.message:String(r)}`)}if(t&&typeof t=="object"&&"steps"in t){let r=t;Array.isArray(r.steps)&&(r.steps=r.steps.map(o=>ie(o)))}Pe(t);try{return re(t)}catch(r){if(r instanceof se.ZodError){let o=r.issues.map(n=>Ee(n,t)).filter(n=>n!==null).join(`
32
+ - Step ${t+1} must be an object`);Ce(r,t)}}function rt(s,e){try{let t=e;for(let o of s)if(typeof o!="symbol")if(t&&typeof t=="object")t=t[o];else return null;if(!t||typeof t!="object")return null;let n=Object.keys(t);if(n.length>0){let o=["run","choose","prompt","parallel","fail"];if(!n.some(a=>o.includes(a)))return`Unknown step type. Found keys: [${n.join(", ")}]. Valid types: run, choose, prompt, parallel, fail`}return null}catch{return null}}function ie(s){let e=s;return"choose"in e&&(e.choose===null||e.choose===void 0)&&"message"in e&&"options"in e?{choose:{message:e.message,options:e.options,as:e.as},when:e.when}:"prompt"in e&&(e.prompt===null||e.prompt===void 0)&&"message"in e&&"as"in e?{prompt:{message:e.message,as:e.as,default:e.default,validate:e.validate},when:e.when}:"parallel"in e&&Array.isArray(e.parallel)?{...e,parallel:e.parallel.map(t=>ie(t))}:s}var G=class{parse(e){let t;try{t=(0,$e.parse)(e)}catch(r){throw new Error(`Invalid YAML format: ${r instanceof Error?r.message:String(r)}`)}if(t&&typeof t=="object"&&"steps"in t){let r=t;Array.isArray(r.steps)&&(r.steps=r.steps.map(n=>ie(n)))}Pe(t);try{return re(t)}catch(r){if(r instanceof se.ZodError){let n=r.issues.map(o=>Ee(o,t)).filter(o=>o!==null).join(`
29
33
  `);throw new Error(`Invalid workflow structure:
30
- ${o}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
31
- `),o=0,n=!1;for(let i=0;i<r.length;i++){let a=r[i].trim();if(a==="steps:"||a.startsWith("steps:")){n=!0;continue}n&&a.startsWith("-")&&t.set(o++,i+1)}return t}},ne=class{parse(e){let t;try{t=JSON.parse(e)}catch(r){throw new Error(`Invalid JSON format: ${r instanceof Error?r.message:String(r)}`)}if(t&&typeof t=="object"&&"steps"in t){let r=t;Array.isArray(r.steps)&&(r.steps=r.steps.map(o=>ie(o)))}Pe(t);try{return re(t)}catch(r){if(r instanceof se.ZodError){let o=r.issues.map(n=>Ee(n,t)).filter(n=>n!==null).join(`
34
+ ${n}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
35
+ `),n=0,o=!1;for(let i=0;i<r.length;i++){let a=r[i].trim();if(a==="steps:"||a.startsWith("steps:")){o=!0;continue}o&&a.startsWith("-")&&t.set(n++,i+1)}return t}},ne=class{parse(e){let t;try{t=JSON.parse(e)}catch(r){throw new Error(`Invalid JSON format: ${r instanceof Error?r.message:String(r)}`)}if(t&&typeof t=="object"&&"steps"in t){let r=t;Array.isArray(r.steps)&&(r.steps=r.steps.map(n=>ie(n)))}Pe(t);try{return re(t)}catch(r){if(r instanceof se.ZodError){let n=r.issues.map(o=>Ee(o,t)).filter(o=>o!==null).join(`
32
36
  `);throw new Error(`Invalid workflow structure:
33
- ${o}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
34
- `),o=0,n=!1,i=!1;for(let a=0;a<r.length;a++){let l=r[a].trim();if(l.startsWith('"steps"')||l.startsWith("'steps'")){n=!0,l.includes("[")&&(i=!0);continue}if(n&&l==="["){i=!0;continue}if(i&&l==="]"){i=!1,n=!1;continue}i&&l.startsWith("{")&&t.set(o++,a+1)}return t}};function ae(s){switch(s.toLowerCase().split(".").pop()){case"yaml":case"yml":return new G;case"json":return new ne;default:return new G}}var C=require("fs"),S=require("path"),le=require("url"),je={};function Me(){console.log=()=>{},console.error=()=>{},console.warn=()=>{},console.info=()=>{},process.stdout.write=()=>!0,process.stderr.write=()=>!0}function Te(){return"0.2.14"}function Ne(s){let e=s?(0,S.resolve)(s):process.cwd(),t=50,r=0;for(;r<t;){let o=(0,S.resolve)(e,"tp");try{if((0,C.existsSync)(o)&&(0,C.statSync)(o).isDirectory())return o}catch{}let n=(0,S.dirname)(e);if(n===e)break;e=n,r++}return null}var rt=(0,De.promisify)(Ae.exec),_=new Ie.Command;_.name("task-pipeliner").description(`A powerful task pipeline runner with condition-based workflow execution.
37
+ ${n}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
38
+ `),n=0,o=!1,i=!1;for(let a=0;a<r.length;a++){let c=r[a].trim();if(c.startsWith('"steps"')||c.startsWith("'steps'")){o=!0,c.includes("[")&&(i=!0);continue}if(o&&c==="["){i=!0;continue}if(i&&c==="]"){i=!1,o=!1;continue}i&&c.startsWith("{")&&t.set(n++,a+1)}return t}};function ae(s){switch(s.toLowerCase().split(".").pop()){case"yaml":case"yml":return new G;case"json":return new ne;default:return new G}}var C=require("fs"),S=require("path"),le=require("url"),je={};function Me(){console.log=()=>{},console.error=()=>{},console.warn=()=>{},console.info=()=>{},process.stdout.write=()=>!0,process.stderr.write=()=>!0}function Ne(){return"0.2.16"}function Te(s){let e=s?(0,S.resolve)(s):process.cwd(),t=50,r=0;for(;r<t;){let n=(0,S.resolve)(e,"tp");try{if((0,C.existsSync)(n)&&(0,C.statSync)(n).isDirectory())return n}catch{}let o=(0,S.dirname)(e);if(o===e)break;e=o,r++}return null}var ot=(0,Be.promisify)(Ae.exec),O=new De.Command;O.name("task-pipeliner").description(`A powerful task pipeline runner with condition-based workflow execution.
35
39
 
36
40
  Define workflows in YAML or JSON files with conditional execution, parallel tasks,
37
41
  interactive prompts, and variable substitution.
@@ -69,7 +73,7 @@ Quick Start:
69
73
  tp history remove # Remove a specific history
70
74
  tp history remove-all # Remove all histories
71
75
 
72
- `).version(Te()).addHelpText("after",`
76
+ `).version(Ne()).addHelpText("after",`
73
77
  Examples:
74
78
  $ tp run workflow.yaml
75
79
  $ tp run examples/simple-project/workflow.yaml
@@ -82,7 +86,7 @@ Resources:
82
86
  \u{1F4DA} Documentation: https://task-pipeliner.racgoo.com/
83
87
  \u{1F3A8} Visual Generator: https://task-pipeliner-generator.racgoo.com/
84
88
 
85
- See README.md for complete DSL reference.`);_.command("run").description("Run a workflow from a YAML or JSON file").argument("[file]","Path to the workflow file (YAML or JSON, relative or absolute). If omitted, will search for workflows in the nearest tp directory.").option("-s, --silent","Run in silent mode (suppress console output)").addHelpText("after",`
89
+ See README.md for complete DSL reference.`);O.command("run").description("Run a workflow from a YAML or JSON file").argument("[file]","Path to the workflow file (YAML or JSON, relative or absolute). If omitted, will search for workflows in the nearest tp directory.").option("-s, --silent","Run in silent mode (suppress console output)").option("-p, --profile <name>","Run in profile mode (use profile name)").addHelpText("after",`
86
90
  Examples:
87
91
  $ tp run workflow.yaml
88
92
  $ tp run workflow.json
@@ -107,11 +111,11 @@ Workflow File Structure:
107
111
  \u2022 all/any/not: Combine conditions
108
112
 
109
113
  Supported formats: YAML (.yaml, .yml) and JSON (.json)
110
- See README.md for complete DSL documentation.`).action(async(s,e)=>{try{let t=s??await nt()??null;t||(console.error(p.default.red(`
111
- \u2717 No workflow file found`)),process.exit(1)),e.silent&&Me();let r=ae(t);console.log(p.default.blue(`Loading workflow from ${t}...`));let o=(0,ce.readFileSync)(t,"utf-8"),n=r.parse(o);if(!n.steps||!Array.isArray(n.steps))throw new Error("Invalid workflow: steps array is required");n._lineNumbers=r.extractStepLineNumbers(o),n._fileName=st(t),n._filePath=(0,O.resolve)(t),console.log(p.default.green(`Starting workflow execution...
112
- `)),await new Z().execute(n),console.log(p.default.green(`
114
+ See README.md for complete DSL documentation.`).action(async(s,e)=>{try{let t=s??await st()??null;t||(console.error(p.default.red(`
115
+ \u2717 No workflow file found`)),process.exit(1)),e.silent&&Me();let r=ae(t);console.log(p.default.blue(`Loading workflow from ${t}...`));let n=(0,ce.readFileSync)(t,"utf-8"),o=r.parse(n);if(!o.steps||!Array.isArray(o.steps))throw new Error("Invalid workflow: steps array is required");let i;if(e.profile){let u=e.profile.trim();if(!o.profiles?.length)throw new Error(`Profile "${u}" requested but workflow has no "profiles" defined. Add a "profiles" section to your workflow file.`);let c=o.profiles.find(m=>m.name===u);if(!c){let m=o.profiles.map(h=>h.name).join(", ");throw new Error(`Profile "${u}" not found. Available profile(s): ${m}`)}i=c.var}o._lineNumbers=r.extractStepLineNumbers(n),o._fileName=it(t),o._filePath=(0,V.resolve)(t),console.log(p.default.green(`Starting workflow execution...
116
+ `)),await new Z().execute(o,i?{profileVars:i}:void 0),console.log(p.default.green(`
113
117
  \u2713 Workflow completed successfully`))}catch(t){let r=t instanceof Error?t.message:String(t);console.error(p.default.red(`
114
- \u2717 Workflow failed: ${r}`)),process.exit(1)}});_.command("open").description("Open generator or docs website in browser").argument("<target>",'Target to open: "generator" or "docs"').addHelpText("after",`
118
+ \u2717 Workflow failed: ${r}`)),process.exit(1)}});O.command("open").description("Open generator or docs website in browser").argument("<target>",'Target to open: "generator" or "docs"').addHelpText("after",`
115
119
  Examples:
116
120
  $ tp open generator
117
121
  $ tp open docs
@@ -120,27 +124,27 @@ Targets:
120
124
  generator Open the visual workflow generator (https://task-pipeliner-generator.racgoo.com/)
121
125
  docs Open the documentation site (https://task-pipeliner.racgoo.com/)`).action(async s=>{let t={generator:"https://task-pipeliner-generator.racgoo.com/",docs:"https://task-pipeliner.racgoo.com/"}[s.toLowerCase()];t||(console.error(p.default.red(`
122
126
  \u2717 Invalid target: ${s}`)),console.log(p.default.yellow(`
123
- Valid targets:`)),console.log(p.default.yellow(" \u2022 generator - Open the visual workflow generator")),console.log(p.default.yellow(" \u2022 docs - Open the documentation site")),process.exit(1));try{let r=process.platform,o;r==="darwin"?o=`open "${t}"`:r==="win32"?o=`start "${t}"`:o=`xdg-open "${t}"`,await rt(o),console.log(p.default.green(`
124
- \u2713 Opening ${s==="generator"?"generator":"documentation"} in browser...`)),console.log(p.default.blue(` ${t}`))}catch(r){let o=r instanceof Error?r.message:String(r);console.error(p.default.red(`
125
- \u2717 Failed to open browser: ${o}`)),console.log(p.default.yellow(`
126
- Please visit manually: ${t}`)),process.exit(1)}});var ot=_.command("history").description("Manage workflow execution history");ot.action(async()=>{let s=new M,e=await s.prompt("Select an action",[{id:"show",label:"Show - View and select a history to view"},{id:"remove",label:"Remove - Delete a specific history file"},{id:"remove-all",label:"Remove All - Delete all history files"}]);e?.id||(console.error(p.default.red(`
127
- \u2717 Invalid choice`)),process.exit(1));let t=new L;switch(e.id){case"show":{let r=await t.getHistoryNames();if(r.length===0){console.log(p.default.yellow(`
128
- \u26A0 No history found`));return}let o=await s.prompt("Select a history to view",r.map(n=>({id:n,label:n})));o?.id||(console.error(p.default.red(`
129
- \u2717 Invalid choice`)),process.exit(1));try{let n=await t.getHistory(o.id);it(n,o.id)}catch(n){let i=n instanceof Error?n.message:String(n);console.error(p.default.red(`
127
+ Valid targets:`)),console.log(p.default.yellow(" \u2022 generator - Open the visual workflow generator")),console.log(p.default.yellow(" \u2022 docs - Open the documentation site")),process.exit(1));try{let r=process.platform,n;r==="darwin"?n=`open "${t}"`:r==="win32"?n=`start "${t}"`:n=`xdg-open "${t}"`,await ot(n),console.log(p.default.green(`
128
+ \u2713 Opening ${s==="generator"?"generator":"documentation"} in browser...`)),console.log(p.default.blue(` ${t}`))}catch(r){let n=r instanceof Error?r.message:String(r);console.error(p.default.red(`
129
+ \u2717 Failed to open browser: ${n}`)),console.log(p.default.yellow(`
130
+ Please visit manually: ${t}`)),process.exit(1)}});var nt=O.command("history").description("Manage workflow execution history");nt.action(async()=>{let s=new M,e=await s.prompt("Select an action",[{id:"show",label:"Show - View and select a history to view"},{id:"remove",label:"Remove - Delete a specific history file"},{id:"remove-all",label:"Remove All - Delete all history files"}]);e?.id||(console.error(p.default.red(`
131
+ \u2717 Invalid choice`)),process.exit(1));let t=new F;switch(e.id){case"show":{let r=await t.getHistoryNames();if(r.length===0){console.log(p.default.yellow(`
132
+ \u26A0 No history found`));return}let n=await s.prompt("Select a history to view",r.map(o=>({id:o,label:o})));n?.id||(console.error(p.default.red(`
133
+ \u2717 Invalid choice`)),process.exit(1));try{let o=await t.getHistory(n.id);at(o,n.id)}catch(o){let i=o instanceof Error?o.message:String(o);console.error(p.default.red(`
130
134
  \u2717 Failed to load history: ${i}`)),process.exit(1)}break}case"remove":{let r=await t.getHistoryNames();if(r.length===0){console.log(p.default.yellow(`
131
- \u26A0 No history found`));return}let o=await s.prompt("Select a history to remove",r.map(n=>({id:n,label:n})));o?.id||(console.error(p.default.red(`
132
- \u2717 Invalid choice`)),process.exit(1));try{await t.removeHistory(o.id),console.log(p.default.green(`
133
- \u2713 Removed history: ${o.id}`))}catch(n){let i=n instanceof Error?n.message:String(n);console.error(p.default.red(`
135
+ \u26A0 No history found`));return}let n=await s.prompt("Select a history to remove",r.map(o=>({id:o,label:o})));n?.id||(console.error(p.default.red(`
136
+ \u2717 Invalid choice`)),process.exit(1));try{await t.removeHistory(n.id),console.log(p.default.green(`
137
+ \u2713 Removed history: ${n.id}`))}catch(o){let i=o instanceof Error?o.message:String(o);console.error(p.default.red(`
134
138
  \u2717 Failed to remove history: ${i}`)),process.exit(1)}break}case"remove-all":{if((await s.prompt("Are you sure you want to remove all histories?",[{id:"yes",label:"Yes, remove all"},{id:"no",label:"No, cancel"}]))?.id!=="yes"){console.log(p.default.yellow(`
135
139
  \u2717 Cancelled`));return}try{await t.clearAllHistories(),console.log(p.default.green(`
136
- \u2713 All histories removed`))}catch(o){let n=o instanceof Error?o.message:String(o);console.error(p.default.red(`
137
- \u2717 Failed to remove histories: ${n}`)),process.exit(1)}break}default:console.error(p.default.red(`
138
- \u2717 Unknown action: ${e.id}`)),process.exit(1)}});async function nt(){let s=Ne();if(!s)return console.error(p.default.red(`
139
- \u2717 No tp directory found`)),null;try{let t=(await(0,Be.readdir)(s)).filter(i=>{let a=(0,O.extname)(i).toLowerCase();return[".yaml",".yml",".json"].includes(a)});if(t.length===0)return console.error(p.default.red(`
140
- \u2717 No workflow files found in ${s}`)),null;let r=await Promise.all(t.map(async i=>{let a=(0,O.join)(s,i);try{let u=ae(a),l=(0,ce.readFileSync)(a,"utf-8"),g=u.parse(l).name??"Untitled";return{id:a,label:`${i} - ${g}`}}catch{return{id:a,label:i}}}));return(await new M(!0).prompt("Select a workflow to run",r)).id}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(p.default.red(`
141
- \u2717 Failed to read tp directory: ${t}`)),null}}function st(s){return s.split("/").pop()??s}function it(s,e){console.log(`
142
- `);let t=s.records.reduce((l,m)=>l+m.duration,0),r=s.records.filter(l=>l.status==="success").length,o=s.records.filter(l=>l.status==="failure").length,n=(0,Fe.default)(s.initialTimestamp).format("YYYY-MM-DD HH:mm:ss"),a=D(t),u=[p.default.bold("Workflow Execution History"),"",`${p.default.cyan("File:")} ${e}`,`${p.default.cyan("Started:")} ${n}`,`${p.default.cyan("Total Duration:")} ${a}`,`${p.default.cyan("Total Steps:")} ${s.records.length}`,`${p.default.green("\u2713 Successful:")} ${r}`,o>0?`${p.default.red("\u2717 Failed:")} ${o}`:""].filter(Boolean).join(`
143
- `);console.log((0,ue.default)(u,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1,left:0,right:0},borderColor:"cyan"})),s.records.forEach((l,m)=>{at(l,m+1,s.records.length)}),console.log("")}function at(s,e,t){let r=lt(s.step),o=ct(s.step),n=s.status==="success"?p.default.green("\u2713"):p.default.red("\u2717"),i=s.status==="success"?p.default.green("Success"):p.default.red("Failed"),a=D(s.duration),u=[`${n} ${p.default.bold(`Step ${e}/${t}`)} - ${p.default.cyan(r)}`,`${p.default.gray("Duration:")} ${a} | ${p.default.gray("Status:")} ${i}`,"",p.default.white(o)].join(`
144
- `);console.log((0,ue.default)(u,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1,left:0,right:0},borderColor:s.status==="success"?"green":"red"})),ut(s.output)&&pt(s.output)}function lt(s){return"run"in s?"Run":"choose"in s?"Choose":"prompt"in s?"Prompt":"parallel"in s?"Parallel":"fail"in s?"Fail":"Unknown"}function ct(s){return"run"in s?`Command: ${p.default.yellow(s.run)}`:"choose"in s?`Message: ${p.default.yellow(s.choose.message)}`:"prompt"in s?`Message: ${p.default.yellow(s.prompt.message)} | Variable: ${p.default.cyan(s.prompt.as)}`:"parallel"in s?`Parallel execution with ${s.parallel.length} branches`:"fail"in s?`Error: ${p.default.red(s.fail.message)}`:"Unknown step type"}function ut(s){return typeof s=="object"&&s!==null&&"success"in s&&"stdout"in s&&"stderr"in s}function pt(s){if(s.stdout.length>0){let e=s.stdout.map(t=>p.default.gray(` ${t}`)).join(`
140
+ \u2713 All histories removed`))}catch(n){let o=n instanceof Error?n.message:String(n);console.error(p.default.red(`
141
+ \u2717 Failed to remove histories: ${o}`)),process.exit(1)}break}default:console.error(p.default.red(`
142
+ \u2717 Unknown action: ${e.id}`)),process.exit(1)}});async function st(){let s=Te();if(!s)return console.error(p.default.red(`
143
+ \u2717 No tp directory found`)),null;try{let t=(await(0,Ie.readdir)(s)).filter(i=>{let a=(0,V.extname)(i).toLowerCase();return[".yaml",".yml",".json"].includes(a)});if(t.length===0)return console.error(p.default.red(`
144
+ \u2717 No workflow files found in ${s}`)),null;let r=await Promise.all(t.map(async i=>{let a=(0,V.join)(s,i);try{let u=ae(a),c=(0,ce.readFileSync)(a,"utf-8"),h=u.parse(c).name??"Untitled";return{id:a,label:`${i} - ${h}`}}catch{return{id:a,label:i}}}));return(await new M(!0).prompt("Select a workflow to run",r)).id}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(p.default.red(`
145
+ \u2717 Failed to read tp directory: ${t}`)),null}}function it(s){return s.split("/").pop()??s}function at(s,e){console.log(`
146
+ `);let t=s.records.reduce((c,m)=>c+m.duration,0),r=s.records.filter(c=>c.status==="success").length,n=s.records.filter(c=>c.status==="failure").length,o=(0,Le.default)(s.initialTimestamp).format("YYYY-MM-DD HH:mm:ss"),a=B(t),u=[p.default.bold("Workflow Execution History"),"",`${p.default.cyan("File:")} ${e}`,`${p.default.cyan("Started:")} ${o}`,`${p.default.cyan("Total Duration:")} ${a}`,`${p.default.cyan("Total Steps:")} ${s.records.length}`,`${p.default.green("\u2713 Successful:")} ${r}`,n>0?`${p.default.red("\u2717 Failed:")} ${n}`:""].filter(Boolean).join(`
147
+ `);console.log((0,ue.default)(u,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1,left:0,right:0},borderColor:"cyan"})),s.records.forEach((c,m)=>{lt(c,m+1,s.records.length)}),console.log("")}function lt(s,e,t){let r=ct(s.step),n=ut(s.step),o=s.status==="success"?p.default.green("\u2713"):p.default.red("\u2717"),i=s.status==="success"?p.default.green("Success"):p.default.red("Failed"),a=B(s.duration),u=[`${o} ${p.default.bold(`Step ${e}/${t}`)} - ${p.default.cyan(r)}`,`${p.default.gray("Duration:")} ${a} | ${p.default.gray("Status:")} ${i}`,"",p.default.white(n)].join(`
148
+ `);console.log((0,ue.default)(u,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1,left:0,right:0},borderColor:s.status==="success"?"green":"red"})),pt(s.output)&&ft(s.output)}function ct(s){return"run"in s?"Run":"choose"in s?"Choose":"prompt"in s?"Prompt":"parallel"in s?"Parallel":"fail"in s?"Fail":"Unknown"}function ut(s){return"run"in s?`Command: ${p.default.yellow(s.run)}`:"choose"in s?`Message: ${p.default.yellow(s.choose.message)}`:"prompt"in s?`Message: ${p.default.yellow(s.prompt.message)} | Variable: ${p.default.cyan(s.prompt.as)}`:"parallel"in s?`Parallel execution with ${s.parallel.length} branches`:"fail"in s?`Error: ${p.default.red(s.fail.message)}`:"Unknown step type"}function pt(s){return typeof s=="object"&&s!==null&&"success"in s&&"stdout"in s&&"stderr"in s}function ft(s){if(s.stdout.length>0){let e=s.stdout.map(t=>p.default.gray(` ${t}`)).join(`
145
149
  `);console.log(p.default.green(" Output:")),console.log(e)}if(s.stderr.length>0){let e=s.stderr.map(t=>p.default.gray(` ${t}`)).join(`
146
- `);console.log(p.default.red(" Errors:")),console.log(e)}}_.parse();
150
+ `);console.log(p.default.red(" Errors:")),console.log(e)}}O.parse();
package/dist/index.d.ts CHANGED
@@ -3,5 +3,5 @@
3
3
 
4
4
  /* auto-generated by NAPI-RS */
5
5
 
6
- export declare function runTask(command: string): Promise<boolean>
7
- export declare function runTaskSync(command: string): boolean
6
+ export declare function runTask(command: string, shell?: Array<string> | undefined | null): Promise<boolean>
7
+ export declare function runTaskSync(command: string, shell?: Array<string> | undefined | null): boolean
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-pipeliner",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "description": "A task pipeline runner with condition-based workflow execution",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",