task-pipeliner 0.2.13 → 0.2.15

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.13
5
+ **버전:** 0.2.15
6
6
 
7
7
  ![fox2](https://github.com/user-attachments/assets/fdf8d786-6a91-4d2d-9dc1-72be6f3ccd98)
8
8
 
@@ -293,6 +293,10 @@ baseDir: ./ # 선택사항: 명령 실행 기본 디
293
293
  # - 상대 경로: YAML 파일 위치 기준으로 해석
294
294
  # - 절대 경로: 그대로 사용
295
295
  # - 생략 시: 현재 작업 디렉토리 사용
296
+ shell: # 선택사항: 모든 run 명령의 전역 쉘 설정
297
+ - bash # - 첫 번째 요소: 쉘 프로그램 (bash, zsh, sh 등)
298
+ - -lc # - 나머지: 쉘 인자 (-c, -lc 등)
299
+ # - 생략 시: 플랫폼 기본 쉘 사용
296
300
 
297
301
  steps: # 필수: 실행할 단계 배열
298
302
  - some-step-1
@@ -309,6 +313,10 @@ steps: # 필수: 실행할 단계 배열
309
313
  // - 상대 경로: JSON 파일 위치 기준으로 해석
310
314
  // - 절대 경로: 그대로 사용
311
315
  // - 생략 시: 현재 작업 디렉토리 사용
316
+ "shell": ["bash", "-lc"], // 선택사항: 모든 run 명령의 전역 쉘 설정
317
+ // - 첫 번째 요소: 쉘 프로그램
318
+ // - 나머지: 쉘 인자
319
+ // - 생략 시: 플랫폼 기본 쉘 사용
312
320
  "steps": [ // 필수: 실행할 단계 배열
313
321
  { /* some-step-1 */ },
314
322
  { /* some-step-2 */ }
@@ -334,6 +342,33 @@ steps: # 필수: 실행할 단계 배열
334
342
  baseDir: /app/frontend # 절대 경로
335
343
  ```
336
344
 
345
+ #### `shell` (선택)
346
+ - **타입**: `string`의 `array`
347
+ - **설명**: 워크플로우 내 모든 `run` 명령에 대한 전역 쉘 설정
348
+ - **형식**: `[프로그램, ...인자]` - 첫 번째 요소는 쉘 프로그램, 나머지는 인자
349
+ - **우선순위**: 스텝별 `shell` > 워크플로우 `shell` > 사용자의 현재 쉘
350
+ - **사용자의 현재 쉘** (생략 시):
351
+ - **Linux/macOS**: `$SHELL` 환경변수 사용 (예: `/bin/zsh`, `/bin/bash`)
352
+ - **Windows**: `%COMSPEC%` 사용 (일반적으로 `cmd.exe`)
353
+ - **동작**: `tp run`을 실행한 쉘 환경과 동일한 환경에서 명령 실행
354
+ - **예제**:
355
+ ```yaml
356
+ # Unix/Linux/macOS
357
+ shell: [bash, -lc] # bash 로그인 쉘 사용
358
+ shell: [zsh, -c] # zsh 사용
359
+ shell: [sh, -c] # sh 사용 (POSIX)
360
+
361
+ # Windows
362
+ shell: [cmd, /c] # 명령 프롬프트
363
+ shell: [powershell, -Command] # Windows PowerShell
364
+ shell: [pwsh, -Command] # PowerShell Core
365
+ ```
366
+ - **크로스 플랫폼 예시**:
367
+ - **Linux/macOS**: `[bash, -lc]`, `[zsh, -c]`, `[/bin/bash, -c]`
368
+ - **Windows**: `[cmd, /c]`, `[powershell, -Command]`, `[pwsh, -Command]`
369
+ - **Git Bash (Windows)**: `[bash, -c]`
370
+ - **WSL**: `[wsl, bash, -c]` 또는 `wsl` 명령 직접 사용
371
+
337
372
  #### `steps` (필수)
338
373
  - **타입**: `Step` 객체의 `array`
339
374
  - **설명**: 순차적으로 실행할 단계 목록
@@ -355,6 +390,7 @@ steps: # 필수: 실행할 단계 배열
355
390
  when?: <condition> # 선택: 조건이 충족될 때만 실행
356
391
  timeout?: <number> # 선택: 타임아웃 (초 단위)
357
392
  retry?: <number> # 선택: 실패 시 재시도 횟수 (기본값: 0)
393
+ shell?: <array> # 선택: 쉘 설정 (workflow.shell 오버라이드)
358
394
  continue?: <bool> # 선택: 이 스텝 이후 다음 스텝으로 진행할지 여부 (성공/실패 무관)
359
395
  onError?: # 선택: 에러 처리 동작
360
396
  run: <command> # 메인 run 명령이 실패했을 때 실행할 대체 명령 (사이드 이펙트)
@@ -368,6 +404,7 @@ steps: # 필수: 실행할 단계 배열
368
404
  - `when` (선택): `Condition` - 실행 전 확인할 조건
369
405
  - `timeout` (선택): `number` - 최대 실행 시간 (초 단위). 이 시간을 초과하면 명령이 종료됩니다.
370
406
  - `retry` (선택): `number` - 실패 시 재시도 횟수 (기본값: 0, 재시도 없음)
407
+ - `shell` (선택): `string`의 `array` - 이 스텝의 쉘 설정. 워크플로우의 전역 `shell`을 오버라이드합니다. 형식: `[프로그램, ...인자]`. 예: `[bash, -lc]`, `[zsh, -c]`.
371
408
  - `continue` (선택): `boolean` - 이 스텝 완료 후 다음 스텝으로 진행할지 여부를 제어합니다 (성공/실패와 무관).
372
409
  - `continue: true` - 항상 다음 스텝으로 진행 (이 스텝이 실패해도)
373
410
  - `continue: false` - 항상 워크플로우 중단 (이 스텝이 성공해도)
@@ -432,6 +469,18 @@ steps:
432
469
  continue: true
433
470
  onError:
434
471
  run: echo "Type check failed, but continuing..."
472
+
473
+ # 커스텀 쉘 사용 (스텝별)
474
+ - run: echo $SHELL
475
+ shell:
476
+ - zsh
477
+ - -c
478
+
479
+ # bash 로그인 쉘 사용
480
+ - run: source ~/.bashrc && echo "프로필 로드됨"
481
+ shell:
482
+ - bash
483
+ - -lc
435
484
  ```
436
485
 
437
486
  **동작:**
@@ -609,9 +658,11 @@ steps:
609
658
  ```
610
659
 
611
660
  **속성:**
612
- - `parallel` (필수): `Step` 객체의 `array` - 병렬로 실행할 단계 (`steps`와 동일한 형식, step은 `-`로 시작)
661
+ - `parallel` (필수): 단계들의 `array` - 병렬로 실행할 단계. **`run`, 중첩 `parallel`, `fail` 스텝만 허용됩니다.** `choose`와 `prompt`(사용자 입력 스텝)는 `parallel` **안에서 사용할 수 없습니다**—사용자 입력은 병렬로 실행되지 않습니다.
613
662
  - `when` (선택): `Condition` - 조건이 충족될 때만 병렬 블록 실행
614
663
 
664
+ **제한:** `parallel` 내부의 스텝은 `run`, 중첩 `parallel`, `fail`만 사용할 수 있습니다. `parallel` 안에서 `choose`나 `prompt`를 사용하면 안 되며, 워크플로우 검증 시 에러가 발생합니다 (예: `'choose' step is not allowed inside 'parallel' block`).
665
+
615
666
  **예제:**
616
667
  ```yaml
617
668
  # 기본 병렬 실행
@@ -640,20 +691,12 @@ steps:
640
691
  - run: npm run test
641
692
  - run: npm run lint
642
693
 
643
- # parallel 모든 step 타입을 포함할 있습니다 (run, choose, prompt 등)
694
+ # 중첩 parallel (허용); parallel 내부에는 run / parallel / fail만 사용
644
695
  - parallel:
645
696
  - run: npm run test
646
- - choose:
647
- message: "린트를 실행하시겠습니까?"
648
- options:
649
- - id: yes
650
- label: "예"
651
- - id: no
652
- label: "아니오"
653
- as: runLint
654
- - prompt:
655
- message: "버전을 입력하세요:"
656
- as: version
697
+ - parallel:
698
+ - run: npm run lint
699
+ - run: npm run typecheck
657
700
  ```
658
701
 
659
702
  **동작:**
@@ -661,6 +704,7 @@ steps:
661
704
  - 워크플로우는 모든 병렬 단계가 완료될 때까지 기다립니다
662
705
  - 어떤 단계라도 실패하면 워크플로우가 중지됩니다
663
706
  - 각 병렬 브랜치는 자체 격리된 워크스페이스 상태를 가집니다 (복제됨)
707
+ - **`choose`와 `prompt`는 `parallel` 안에서 사용할 수 없습니다** (사용자 입력은 병렬로 실행되지 않음; `parallel` 블록 앞뒤의 순차 스텝에서만 사용하세요)
664
708
 
665
709
  ---
666
710
 
@@ -989,11 +1033,36 @@ when:
989
1033
 
990
1034
  ### 변수 치환
991
1035
 
992
- 변수는 `{{variable}}` 문법을 사용하여 명령에서 사용할 수 있습니다.
1036
+ 변수는 `{{variable}}` 문법을 사용하여 명령에서 사용할 수 있습니다. 선택적으로 공백을 사용할 수 있습니다: `{{var}}`, `{{ var }}`, `{{ var }}` 모두 작동합니다.
993
1037
 
994
1038
  **문법:**
995
1039
  ```yaml
996
1040
  run: echo "{{variableName}}"
1041
+ # 또는 선택적으로 공백 사용
1042
+ run: echo "{{ variableName }}"
1043
+ ```
1044
+
1045
+ **⚠️ 중요: YAML 문법 규칙**
1046
+
1047
+ 명령어에서 `{{variable}}`을 사용할 때, 파싱 오류를 방지하기 위해 다음 규칙을 따르세요:
1048
+
1049
+ ✅ **안전한 패턴:**
1050
+ ```yaml
1051
+ # 단어로 시작 (따옴표 불필요)
1052
+ - run: echo "Building {{version}}..."
1053
+ - run: npm run build --version={{version}}
1054
+
1055
+ # 전체 명령어를 작은따옴표로 감싸기
1056
+ - run: 'echo "Selected: {{mode}}"'
1057
+ ```
1058
+
1059
+ ❌ **문제가 되는 패턴:**
1060
+ ```yaml
1061
+ # 금지: 따옴표 + 변수 앞 콜론
1062
+ - run: echo "mode: {{mode}}" # ❌ YAML 파싱 에러!
1063
+
1064
+ # 해결: 전체 명령어를 작은따옴표로 감싸기
1065
+ - run: 'echo "mode: {{mode}}"' # ✅ 정상 작동
997
1066
  ```
998
1067
 
999
1068
  **예제:**
@@ -1082,6 +1151,10 @@ steps:
1082
1151
  - run: npm run test:integration
1083
1152
  - run: npm run lint
1084
1153
 
1154
+ # 6.5. 스텝별 쉘 오버라이드
1155
+ - run: echo "zsh로 실행"
1156
+ shell: [zsh, -c] # 이 스텝만 워크플로우 쉘 오버라이드
1157
+
1085
1158
  # 7. 파일 존재 확인
1086
1159
  - when:
1087
1160
  file: ./test-results
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.13
5
+ **Version:** 0.2.15
6
6
 
7
7
  ![fox2](https://github.com/user-attachments/assets/fdf8d786-6a91-4d2d-9dc1-72be6f3ccd98)
8
8
 
@@ -293,6 +293,10 @@ baseDir: ./ # Optional: Base directory for command ex
293
293
  # - Relative path: resolved from YAML file location
294
294
  # - Absolute path: used as-is
295
295
  # - If omitted: uses current working directory
296
+ shell: # Optional: Global shell configuration for all run commands
297
+ - bash # - First element: shell program (bash, zsh, sh, etc.)
298
+ - -lc # - Rest: shell arguments (-c, -lc, etc.)
299
+ # - If omitted: uses platform default shell
296
300
 
297
301
  steps: # Required: Array of steps to execute
298
302
  - some-step-1
@@ -309,6 +313,10 @@ steps: # Required: Array of steps to execute
309
313
  // - Relative path: resolved from JSON file location
310
314
  // - Absolute path: used as-is
311
315
  // - If omitted: uses current working directory
316
+ "shell": ["bash", "-lc"], // Optional: Global shell configuration for all run commands
317
+ // - First element: shell program
318
+ // - Rest: shell arguments
319
+ // - If omitted: uses platform default shell
312
320
  "steps": [ // Required: Array of steps to execute
313
321
  { /* some-step-1 */ },
314
322
  { /* some-step-2 */ }
@@ -334,6 +342,33 @@ steps: # Required: Array of steps to execute
334
342
  baseDir: /app/frontend # Absolute path
335
343
  ```
336
344
 
345
+ #### `shell` (optional)
346
+ - **Type**: `array` of `string`
347
+ - **Description**: Global shell configuration for all `run` commands in the workflow
348
+ - **Format**: `[program, ...args]` - First element is the shell program, rest are arguments
349
+ - **Priority**: Step-level `shell` > Workflow-level `shell` > User's current shell
350
+ - **User's current shell** (when omitted):
351
+ - **Linux/macOS**: Uses `$SHELL` environment variable (e.g., `/bin/zsh`, `/bin/bash`)
352
+ - **Windows**: Uses `%COMSPEC%` (typically `cmd.exe`)
353
+ - **Behavior**: Commands run in the same shell environment as where you execute `tp run`
354
+ - **Example**:
355
+ ```yaml
356
+ # Unix/Linux/macOS
357
+ shell: [bash, -lc] # Use bash login shell
358
+ shell: [zsh, -c] # Use zsh
359
+ shell: [sh, -c] # Use sh (POSIX)
360
+
361
+ # Windows
362
+ shell: [cmd, /c] # Command Prompt
363
+ shell: [powershell, -Command] # Windows PowerShell
364
+ shell: [pwsh, -Command] # PowerShell Core
365
+ ```
366
+ - **Cross-platform examples**:
367
+ - **Linux/macOS**: `[bash, -lc]`, `[zsh, -c]`, `[/bin/bash, -c]`
368
+ - **Windows**: `[cmd, /c]`, `[powershell, -Command]`, `[pwsh, -Command]`
369
+ - **Git Bash (Windows)**: `[bash, -c]`
370
+ - **WSL**: `[wsl, bash, -c]` or use `wsl` command directly
371
+
337
372
  #### `steps` (required)
338
373
  - **Type**: `array` of `Step` objects
339
374
  - **Description**: List of steps to execute sequentially
@@ -355,6 +390,7 @@ Execute a shell command.
355
390
  when?: <condition> # Optional: Execute only if condition is met
356
391
  timeout?: <number> # Optional: Timeout in seconds
357
392
  retry?: <number> # Optional: Number of retries on failure (default: 0)
393
+ shell?: <array> # Optional: Shell configuration (overrides workflow.shell)
358
394
  continue?: <bool> # Optional: Continue to next step after this step completes (regardless of success/failure)
359
395
  onError?: # Optional: Error handling behavior
360
396
  run: <command> # Fallback command when main run command fails (side effect)
@@ -368,6 +404,7 @@ Execute a shell command.
368
404
  - `when` (optional): `Condition` - Condition to check before execution
369
405
  - `timeout` (optional): `number` - Maximum execution time in seconds. Command will be killed if it exceeds this time.
370
406
  - `retry` (optional): `number` - Number of retry attempts if command fails (default: 0, meaning no retry)
407
+ - `shell` (optional): `array` of `string` - Shell configuration for this step. Overrides workflow's global `shell`. Format: `[program, ...args]`. Example: `[bash, -lc]`, `[zsh, -c]`.
371
408
  - `continue` (optional): `boolean` - Controls whether to proceed to the next step after this step completes, regardless of success or failure.
372
409
  - `continue: true` - Always proceed to the next step (even if this step fails)
373
410
  - `continue: false` - Always stop the workflow after this step (even if this step succeeds)
@@ -432,6 +469,18 @@ steps:
432
469
  continue: true
433
470
  onError:
434
471
  run: echo "Type check failed, but continuing..."
472
+
473
+ # Command with custom shell (step-level)
474
+ - run: echo $SHELL
475
+ shell:
476
+ - zsh
477
+ - -c
478
+
479
+ # Command with bash login shell
480
+ - run: source ~/.bashrc && echo "Loaded profile"
481
+ shell:
482
+ - bash
483
+ - -lc
435
484
  ```
436
485
 
437
486
  **Behavior:**
@@ -609,9 +658,11 @@ Execute multiple steps simultaneously. Like `steps`, `parallel` contains an arra
609
658
  ```
610
659
 
611
660
  **Properties:**
612
- - `parallel` (required): `array` of `Step` objects - Steps to execute in parallel (same format as `steps`, each step starts with `-`)
661
+ - `parallel` (required): `array` of steps - Steps to execute in parallel. **Only `run`, nested `parallel`, and `fail` steps are allowed.** `choose` and `prompt` (user input steps) are **not allowed** inside `parallel`—user input cannot run in parallel.
613
662
  - `when` (optional): `Condition` - Execute parallel block only if condition is met
614
663
 
664
+ **Restriction:** Steps inside `parallel` may only be `run`, nested `parallel`, or `fail`. Do **not** use `choose` or `prompt` inside `parallel`; the workflow validator will reject it and report an error (e.g. `'choose' step is not allowed inside 'parallel' block`).
665
+
615
666
  **Examples:**
616
667
  ```yaml
617
668
  # Basic parallel execution
@@ -640,20 +691,12 @@ Execute multiple steps simultaneously. Like `steps`, `parallel` contains an arra
640
691
  - run: npm run test
641
692
  - run: npm run lint
642
693
 
643
- # parallel can contain any step type (run, choose, prompt, etc.)
694
+ # Nested parallel (allowed); only run / parallel / fail inside parallel
644
695
  - parallel:
645
696
  - run: npm run test
646
- - choose:
647
- message: "Run lint?"
648
- options:
649
- - id: yes
650
- label: "Yes"
651
- - id: no
652
- label: "No"
653
- as: runLint
654
- - prompt:
655
- message: "Enter version:"
656
- as: version
697
+ - parallel:
698
+ - run: npm run lint
699
+ - run: npm run typecheck
657
700
  ```
658
701
 
659
702
  **Behavior:**
@@ -661,6 +704,7 @@ Execute multiple steps simultaneously. Like `steps`, `parallel` contains an arra
661
704
  - Workflow waits for all parallel steps to complete before continuing
662
705
  - If any step fails, the workflow stops
663
706
  - Each parallel branch has its own isolated workspace state (cloned)
707
+ - **`choose` and `prompt` are not allowed inside `parallel`** (user input cannot run in parallel; use them in sequential steps before or after a `parallel` block)
664
708
 
665
709
  ---
666
710
 
@@ -989,11 +1033,36 @@ Nest conditions to create complex logic.
989
1033
 
990
1034
  ### Variable Substitution
991
1035
 
992
- Variables can be used in commands using the `{{variable}}` syntax.
1036
+ Variables can be used in commands using the `{{variable}}` syntax. Optional whitespace is supported: `{{var}}`, `{{ var }}`, `{{ var }}` all work.
993
1037
 
994
1038
  **Syntax:**
995
1039
  ```yaml
996
1040
  run: echo "{{variableName}}"
1041
+ # or with optional spaces
1042
+ run: echo "{{ variableName }}"
1043
+ ```
1044
+
1045
+ **⚠️ Important YAML Syntax Rules:**
1046
+
1047
+ When using `{{variable}}` in commands, follow these rules to avoid parsing errors:
1048
+
1049
+ ✅ **Safe patterns:**
1050
+ ```yaml
1051
+ # Start with a word (no quotes needed)
1052
+ - run: echo "Building {{version}}..."
1053
+ - run: npm run build --version={{version}}
1054
+
1055
+ # Wrap entire command in single quotes
1056
+ - run: 'echo "Selected: {{mode}}"'
1057
+ ```
1058
+
1059
+ ❌ **Problematic patterns:**
1060
+ ```yaml
1061
+ # DO NOT: quotes + colons before variables
1062
+ - run: echo "mode: {{mode}}" # ❌ YAML parsing error!
1063
+
1064
+ # FIX: Wrap entire command in single quotes
1065
+ - run: 'echo "mode: {{mode}}"' # ✅ Works correctly
997
1066
  ```
998
1067
 
999
1068
  **Examples:**
@@ -1031,6 +1100,7 @@ A complete example demonstrating all features:
1031
1100
  ```yaml
1032
1101
  name: Complete Workflow Example
1033
1102
  baseDir: ./
1103
+ shell: [bash, -c] # Optional: Use bash for all steps (default: user's current shell)
1034
1104
 
1035
1105
  steps:
1036
1106
  # 1. Simple command
@@ -1082,6 +1152,10 @@ steps:
1082
1152
  - run: npm run test:integration
1083
1153
  - run: npm run lint
1084
1154
 
1155
+ # 6.5. Step-level shell override
1156
+ - run: echo "Running with zsh"
1157
+ shell: [zsh, -c] # Override workflow shell for this step only
1158
+
1085
1159
  # 7. File existence check
1086
1160
  - when:
1087
1161
  file: ./test-results
package/dist/index.cjs CHANGED
@@ -1,24 +1,41 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var Te=Object.create;var ce=Object.defineProperty;var Be=Object.getOwnPropertyDescriptor;var Ie=Object.getOwnPropertyNames;var De=Object.getPrototypeOf,Ae=Object.prototype.hasOwnProperty;var je=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Ie(e))!Ae.call(s,n)&&n!==t&&ce(s,n,{get:()=>e[n],enumerable:!(r=Be(e,n))||r.enumerable});return s};var S=(s,e,t)=>(t=s!=null?Te(De(s)):{},je(e||!s||!s.__esModule?ce(t,"default",{value:s,enumerable:!0}):t,s));var Ce=require("child_process"),ae=require("fs"),Ee=require("fs/promises"),L=require("path"),Pe=require("util"),le=S(require("boxen"),1),u=S(require("chalk"),1),Me=require("commander"),Ne=S(require("dayjs"),1);var T=require("path"),be=S(require("chalk"),1),z=S(require("log-update"),1);var pe=S(require("readline"),1),x=S(require("chalk"),1),q=S(require("inquirer"),1),ue=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 q.default.prompt([{type:"list",name:"choice",message:x.default.cyan(e),choices:t.map(o=>({name:o.label,value:o.id})),pageSize:ue}]),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=pe.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 p=()=>{process.stdout.write("\x1B[H\x1B[2J"),console.log(x.default.cyan(`? ${e}`));let h=n?x.default.gray(` Filter: ${n}`)+x.default.gray(` (${i.length}/${t.length})`):x.default.gray(" Type to filter, \u2191\u2193 to navigate, Enter to select");console.log(h),console.log();let m=ue,d=0,g=i.length;if(i.length>m){let w=Math.floor(m/2);d=Math.max(0,o-w),g=Math.min(i.length,d+m),g===i.length&&(d=Math.max(0,g-m))}if(i.length===0)console.log(x.default.yellow(" No matches found"));else{d>0&&console.log(x.default.gray(` \u2191 ${d} more above`));for(let w=d;w<g;w++){let y=i[w];console.log(w===o?x.default.cyan(`\u276F ${y.label}`):x.default.white(` ${y.label}`))}g<i.length&&console.log(x.default.gray(` \u2193 ${i.length-g} more below`))}},l=()=>{let h=n.toLowerCase();i=h?t.filter(m=>m.label.toLowerCase().includes(h)):[...t],o>=i.length&&(o=Math.max(0,i.length-1))},f=()=>{process.stdin.isTTY&&process.stdin.setRawMode(!1),a.close(),process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[?1049l")};p(),process.stdin.on("data",h=>{let m=h.toString();if(m===""&&(f(),process.exit(0)),m==="\r"||m===`
3
- `){i.length>0&&(f(),r(i[o]));return}if(m==="\x1B"&&h.length===1){n&&(n="",l(),p());return}if(m==="\x1B[A"){i.length>0&&(o=o>0?o-1:i.length-1,p());return}if(m==="\x1B[B"){i.length>0&&(o=o<i.length-1?o+1:0,p());return}if(m==="\x7F"||m==="\b"){n.length>0&&(n=n.slice(0,-1),l(),p());return}m.length===1&&m>=" "&&m<="~"&&(n+=m,l(),p())})})}},O=class{async prompt(e,t){let{value:r}=await q.default.prompt([{type:"input",name:"value",message:x.default.cyan(e),default:t}]);return r}};var H=S(require("boxen"),1),B=S(require("chalk"),1);function K(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?B.default.green(r):B.default.red(r);if(t!==void 0){let o=D(t);return`${n} ${B.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 me(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 fe(s){let e=s?"\u2713 All parallel branches completed":"\u2717 Some parallel branches failed";return s?B.default.green(e):B.default.red(e)}function Q(s,e=!1){return`${e?"| \u2502 ":"\u2502 "}${s}`}function D(s){return`${(s/1e3).toFixed(3)}s`}var de=require("fs"),he=require("path"),A=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,he.resolve)(process.cwd(),t);return(0,de.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 k=require("fs/promises"),ge=require("os"),N=require("path"),we=S(require("dayjs"),1),j=(0,N.join)((0,ge.homedir)(),".pipeliner","workflow-history"),F=class{constructor(){}async saveHistory(e){await(0,k.mkdir)(j,{recursive:!0});let t=(0,we.default)().format("YYYY-MM-DD_HH-mm-ss"),r=Math.random().toString(36).slice(2,6),n=(0,N.join)(j,`workflow-${t}-${r}.json`);return await(0,k.writeFile)(n,JSON.stringify(e,null,2),{encoding:"utf8"}),n}async clearAllHistories(){await(0,k.rm)(j,{recursive:!0,force:!0})}async removeHistory(e){await(0,k.rm)((0,N.join)(j,e),{force:!0})}async getHistoryNames(){try{let t=(await(0,k.readdir)(j)).map(r=>(0,N.basename)(r));return t.sort((r,n)=>{let o=p=>{let l=p.match(/workflow-(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-/);return l?l[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,k.readFile)((0,N.join)(j,e),{encoding:"utf8"});return JSON.parse(t)}};var V=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 ee=require("child_process");var J=class{async run(e,t,r,n,o=!1,i=!1,a,p,l,f){return o?this.runBuffered(e,l,f):this.runRealtime(e,r||e,i,a,p,l,f)}async runBuffered(e,t,r){let n=this.createSpawnOptions(t);return new Promise((o,i)=>{let a=(0,ee.spawn)(e,[],n),p=[],l=[],f="",h="",m=null;r&&r>0&&(m=setTimeout(()=>{a.kill("SIGTERM");let d=`Command timed out after ${r} seconds`;l.push(d),o({success:!1,stdout:p,stderr:l})},r*1e3)),a.stdout?.on("data",d=>{let g=d.toString(),{lines:w,remaining:y}=this.processStreamBuffer(g,f);p.push(...w),f=y}),a.stderr?.on("data",d=>{let g=d.toString(),{lines:w,remaining:y}=this.processStreamBuffer(g,h);l.push(...w),h=y}),a.on("close",d=>{m&&clearTimeout(m),f.trim()&&p.push(f),h.trim()&&l.push(h),o({success:d===0,stdout:p,stderr:l})}),a.on("error",d=>{m&&clearTimeout(m);let g=`Error: ${d.message}`;o({success:!1,stdout:p,stderr:[...l,g]})})})}async runRealtime(e,t,r,n,o,i,a){let p=this.createSpawnOptions(i),f=K(t,n,o,{borderColor:r?"green":"cyan"});console.log(f);let h=Date.now();return new Promise(m=>{let d=(0,ee.spawn)(e,[],p),g="",w="",y=null;a&&a>0&&(y=setTimeout(()=>{d.kill("SIGTERM");let R=`Command timed out after ${a} seconds`,v=W(R);console.error(v);let E=Date.now()-h,P=I(!1,!1,E);console.log(P),m(!1)},a*1e3)),d.stdout?.on("data",R=>{let v=R.toString(),{lines:E,remaining:P}=this.processStreamBuffer(v,g);E.forEach(X=>process.stdout.write(`\u2502 ${X}
4
- `)),g=P}),d.stderr?.on("data",R=>{let v=R.toString(),{lines:E,remaining:P}=this.processStreamBuffer(v,w);E.forEach(X=>process.stderr.write(`\u2502 ${X}
5
- `)),w=P}),d.on("close",R=>{y&&clearTimeout(y),g.trim()&&process.stdout.write(`\u2502 ${g}
6
- `),w.trim()&&process.stderr.write(`\u2502 ${w}
7
- `);let v=R===0,E=Date.now()-h,P=I(v,!1,E);console.log(P),m(v)}),d.on("error",R=>{y&&clearTimeout(y);let v=W(`Error: ${R.message}`);console.error(v),m(!1)})})}createSpawnOptions(e){let t={stdio:["inherit","pipe","pipe"],shell:!0};return e&&(t.cwd=e),t}processStreamBuffer(e,t){let r=t+e,n=[],o=r;for(;o.includes(`
2
+ "use strict";var Fe=Object.create;var pe=Object.defineProperty;var We=Object.getOwnPropertyDescriptor;var Oe=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 n of Oe(e))!Ve.call(s,n)&&n!==t&&pe(s,n,{get:()=>e[n],enumerable:!(r=We(e,n))||r.enumerable});return s};var x=(s,e,t)=>(t=s!=null?Fe(_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"),W=require("path"),Ie=require("util"),ue=x(require("boxen"),1),p=x(require("chalk"),1),De=require("commander"),Le=x(require("dayjs"),1);var N=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`))}},l=()=>{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="",l(),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),l(),u());return}f.length===1&&f>=" "&&f<="~"&&(n+=f,l(),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)})}},V=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 B(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=I(t);return`${n} ${A.default.gray(`(${o})`)}`}return n}function O(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 I(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"),T=require("path"),ye=x(require("dayjs"),1),L=(0,T.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,T.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,T.join)(L,e),{force:!0})}async getHistoryNames(){try{let t=(await(0,R.readdir)(L)).map(r=>(0,T.basename)(r));return t.sort((r,n)=>{let o=u=>{let l=u.match(/workflow-(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-/);return l?l[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,T.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,l,m,h){return o?this.runBuffered(e,l,m,h):this.runRealtime(e,r||e,i,a,u,l,m,h)}async runBuffered(e,t,r,n){return new Promise((o,i)=>{let a=this.spawnWithShell(e,t,n),u=[],l=[],m="",h="",d=null;r&&r>0&&(d=setTimeout(()=>{a.kill("SIGTERM");let f=`Command timed out after ${r} seconds`;l.push(f),o({success:!1,stdout:u,stderr:l})},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);l.push(...b),h=y}),a.on("close",f=>{d&&clearTimeout(d),m.trim()&&u.push(m),h.trim()&&l.push(h),o({success:f===0,stdout:u,stderr:l})}),a.on("error",f=>{d&&clearTimeout(d);let g=`Error: ${f.message}`;o({success:!1,stdout:u,stderr:[...l,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`,$=O(k);console.error($);let P=Date.now()-h,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($,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=B($,!1,P);console.log(j),d($)}),f.on("error",k=>{y&&clearTimeout(y);let $=O(`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
8
  `);){let i=o.indexOf(`
9
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=K(t,n,o,{borderColor:"cyan",isNested:r});this.formatNestedOutput(i,r),e.stdout.forEach(p=>{let l=Q(p,r);process.stdout.write(`${l}
11
- `)}),e.stderr.forEach(p=>{let l=Q(p,r);process.stderr.write(`${l}
12
- `)});let a=I(e.success,r);console.log(a)}};function Fe(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,n)=>Fe(n,e,r))}var U=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 U,this.taskRunner=new J,this.choicePrompt=new M,this.textPrompt=new O}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 A(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 V,r=Date.now();for(let i=0;i<e.steps.length;i++){let a=e.steps[i],p=this.createStepContext(i,e),l=!!a.when;if(this.evaluateStepCondition(a)){t.recordStart();try{let f=await this.executeStep(a,p,!1,l);this.handleStepResult(a,p,i,f,t)}catch(f){throw this.handleStepError(a,p,i,f,t),f}}}let n=Date.now()-r,o=D(n);console.log(be.default.cyan(`
13
- Total execution time: ${o}`)),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,n,o){let i=this.isRunStep(e)?(()=>{let l=this.workspace.getStepResult(r);return l?l.success:!0})():this.isStepSuccessful(n,e),a=i?"success":"failure",p=o.recordEnd(e,t,n,a);if(!this.isRunStep(e)){let l=I(i,!1,p);console.log(l)}if(this.isRunStep(e)){if(e.continue===!1){let l=t.lineNumber?` (line ${t.lineNumber})`:"",f=i?`Step ${r}${l} completed, but workflow stopped due to continue: false`:`Step ${r}${l} failed`;throw new Error(f)}if(!i&&e.continue!==!0){let l=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Step ${r}${l} 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.retry??0,p=e.timeout,l=!1,f=0;for(;f<=a;){let h=await this.taskRunner.run(i,o,i,t.branchIndex,r,n,t.lineNumber,t.fileName,this.baseDir,p),m=typeof h=="boolean"?h:h.success;if(l=h,m||f>=a)break;if(f++,f<=a){let d=Math.min(1e3*Math.pow(2,f-1),1e4);await new Promise(g=>setTimeout(g,d))}}return l}async executeRunStep(e,t,r=!1,n=!1){let o=await this.executeSingleRun({run:e.run,timeout:e.timeout,retry:e.retry},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},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=await this.choicePrompt.prompt(e.choose.message,e.choose.options);if(!r?.id)throw new Error(`Invalid choice result: ${JSON.stringify(r)}`);let n=e.choose.as??r.id;this.workspace.setChoice(r.id,r.id),this.workspace.setVariable(n,r.id),this.workspace.setStepResult(t.stepIndex,!0)}async executePromptStep(e,t){let r=Y(e.prompt.message,this.workspace),n=e.prompt.default?Y(e.prompt.default,this.workspace):void 0,o=await this.textPrompt.prompt(r,n);this.workspace.setVariable(e.prompt.as,o),this.workspace.setFact(e.prompt.as,o),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 l=0;l<e.length;l++){let f=e[l],h=t[l];if(f.when&&!new A(h.workspace).evaluate(f.when))continue;let m=this.getBranchDisplayName(f,l);r.push({index:l,name:m,status:"pending"})}let i=setInterval(()=>{o=(o+1)%n.length,this.updateParallelBranchesDisplay(r,n[o])},100),a=r.map(async l=>{let{index:f}=l,h=e[f],m=t[f];l.status="running";try{let d=await this.executeStep(h,m,!0);return l.status="success",this.updateParallelBranchesDisplay(r,n[o]),{index:f,result:d,context:m}}catch(d){m.workspace.setStepResult(m.stepIndex,!1);let g=d instanceof Error?d.message:String(d);return l.status="failed",l.error=g,this.updateParallelBranchesDisplay(r,n[o]),{index:f,error:d,context:m}}}),p=await Promise.all(a);return clearInterval(i),this.updateParallelBranchesDisplay(r,"",!0),z.default.done(),p}updateParallelBranchesDisplay(e,t,r=!1){let n=e.map(o=>{let i=o.index+1,a="",p="";switch(o.status){case"pending":a="\u25CB",p=`Branch ${i}: ${o.name} - Pending`;break;case"running":a=t,p=`Branch ${i}: ${o.name} - Running...`;break;case"success":a="\u2713",p=`Branch ${i}: ${o.name} - Completed`;break;case"failed":a="\u2717",p=`Branch ${i}: ${o.name} - Failed${o.error?`: ${o.error}`:""}`;break}return`${a} ${p}`});r?(0,z.default)(n.join(`
14
- `)):(0,z.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:p,result:l,error:f,context:h}=a;if(f){n=!1;let m=`Branch ${p+1} failed: ${f instanceof Error?f.message:String(f)}`,d=W(m);console.error(d)}else if(l&&typeof l=="object"&&"stdout"in l){let m=l;if(n=n&&m.success,m.stdout.length>0||m.stderr.length>0||!m.success){let d=t[p],g=this.getBranchDisplayName(d,p);this.taskRunner.displayBufferedOutput(m,g,!1,h.lineNumber,h.fileName)}}}o||console.log("\u26A0\uFE0F All parallel branches were skipped (conditions not met)");let i=fe(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 A(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=me(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 p=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Parallel step ${t.stepIndex}${p} 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 Se=require("yaml"),oe=require("zod");var c=require("zod"),Le=c.z.object({file:c.z.string()}),We=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()}),_e=c.z.object({status:c.z.object({fact:c.z.string(),is:c.z.enum(["ready","failed","pending"])})}),Oe=c.z.object({step:c.z.object({success:c.z.boolean()}).optional(),last_step:c.z.enum(["success","failure"]).optional()}),He=c.z.object({choice:c.z.string()}),Ve=c.z.union([Le,He,We,_e,Oe]),C=c.z.lazy(()=>c.z.union([Ve,c.z.object({all:c.z.array(C)}),c.z.object({any:c.z.array(C)}),c.z.object({not:C})])),ye=c.z.lazy(()=>c.z.object({run:c.z.string(),timeout:c.z.number().optional(),retry:c.z.number().optional(),onError:ye.optional()})),Je=c.z.object({run:c.z.string(),when:C.optional(),timeout:c.z.number().optional(),retry:c.z.number().optional(),continue:c.z.boolean().optional(),onError:ye.optional()}),Ye=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:C.optional()}),Ue=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:C.optional()}),xe=c.z.lazy(()=>c.z.union([Je,Ye,Ue,c.z.object({parallel:c.z.array(xe),when:C.optional()}),c.z.object({fail:c.z.object({message:c.z.string()}),when:C.optional()})])),ze=c.z.object({name:c.z.string().optional(),baseDir:c.z.string().optional(),steps:c.z.array(xe).min(1,"Workflow must have at least one step")});function te(s){return ze.parse(s)}function ne(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=>ne(t))}:s}var G=class{parse(e){let t;try{t=(0,Se.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=>ne(n)))}try{return te(t)}catch(r){if(r instanceof oe.ZodError){let n=r.issues.map(o=>{let i=o.path.length>0?` at ${o.path.join(".")}`:"";return` - ${o.message}${i}`}).join(`
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 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)){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 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 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){this.resolveBaseDir(e),this.globalShell=e.shell;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 n=Date.now()-r,o=I(n);console.log(Se.default.cyan(`
13
+ Total execution time: ${o}`)),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,n,o){let i=this.isRunStep(e)?(()=>{let l=this.workspace.getStepResult(r);return l?l.success:!0})():this.isStepSuccessful(n,e),a=i?"success":"failure",u=o.recordEnd(e,t,n,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,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,l=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,l,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=await this.choicePrompt.prompt(e.choose.message,e.choose.options);if(!r?.id)throw new Error(`Invalid choice result: ${JSON.stringify(r)}`);let n=e.choose.as??r.id;this.workspace.setChoice(r.id,r.id),this.workspace.setVariable(n,r.id),this.workspace.setStepResult(t.stepIndex,!0)}async executePromptStep(e,t){let r=Y(e.prompt.message,this.workspace),n=e.prompt.default?Y(e.prompt.default,this.workspace):void 0,o=await this.textPrompt.prompt(r,n);this.workspace.setVariable(e.prompt.as,o),this.workspace.setFact(e.prompt.as,o),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 l=0;l<e.length;l++){let m=e[l],h=t[l];if(m.when&&!new D(h.workspace).evaluate(m.when))continue;let d=this.getBranchDisplayName(m,l);r.push({index:l,name:d,status:"pending"})}let i=setInterval(()=>{o=(o+1)%n.length,this.updateParallelBranchesDisplay(r,n[o])},100),a=r.map(async l=>{let{index:m}=l,h=e[m],d=t[m];l.status="running";try{let f=await this.executeStep(h,d,!0);return l.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 l.status="failed",l.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:l,error:m,context:h}=a;if(m){n=!1;let d=`Branch ${u+1} failed: ${m instanceof Error?m.message:String(m)}`,f=O(d);console.error(f)}else if(l&&typeof l=="object"&&"stdout"in l){let d=l;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 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()})),ve=c.z.object({run:c.z.string(),when:E.optional(),timeout:c.z.number().optional(),retry:c.z.number().optional(),shell:c.z.array(c.z.string()).min(1,"shell must have at least one element").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 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=c.z.lazy(()=>c.z.union([ve,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=xe(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([ve,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(),shell:c.z.array(c.z.string()).min(1,"shell must have at least one element").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 n=ne(t);return` - ${s.message}${n}`}if(s.message==="Invalid input"){let n=ne(t),o=tt(t,e);return o?` - ${o}${n}`:` - Invalid step type${n}`}let r=ne(t);return` - ${s.message}${r}`}function ne(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
+ Reason: ${t}`:"";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
+ - '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(o==="prompt"){if(t){let u=r.join(" \u2192 ");throw new Error(`Invalid workflow structure:
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(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 l=[...r,`branch ${a+1}`];Ce(u,e,!0,l)}}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
+ - 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("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:
28
+ - 'steps' is required`);if(!Array.isArray(e.steps))throw new Error(`Invalid workflow structure:
29
+ - 'steps' must be an array`);if(e.steps.length===0)throw new Error(`Invalid workflow structure:
30
+ - 'steps' cannot be empty
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:
32
+ - Step ${t+1} must be an object`);Ce(r,t)}}function tt(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(`
16
33
  `);throw new Error(`Invalid workflow structure:
17
34
  ${n}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
18
- `),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}},re=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=>ne(n)))}try{return te(t)}catch(r){if(r instanceof oe.ZodError){let n=r.issues.map(o=>{let i=o.path.length>0?` at ${o.path.join(".")}`:"";return` - ${o.message}${i}`}).join(`
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}},oe=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(`
19
36
  `);throw new Error(`Invalid workflow structure:
20
37
  ${n}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
21
- `),n=0,o=!1,i=!1;for(let a=0;a<r.length;a++){let l=r[a].trim();if(l.startsWith('"steps"')||l.startsWith("'steps'")){o=!0,l.includes("[")&&(i=!0);continue}if(o&&l==="["){i=!0;continue}if(i&&l==="]"){i=!1,o=!1;continue}i&&l.startsWith("{")&&t.set(n++,a+1)}return t}};function se(s){switch(s.toLowerCase().split(".").pop()){case"yaml":case"yml":return new G;case"json":return new re;default:return new G}}var $=require("fs"),b=require("path"),ie=require("url"),ke={};function ve(){console.log=()=>{},console.error=()=>{},console.warn=()=>{},console.info=()=>{},process.stdout.write=()=>!0,process.stderr.write=()=>!0}function Re(){return"0.2.13"}function $e(s){let e=s?(0,b.resolve)(s):process.cwd(),t=50,r=0;for(;r<t;){let n=(0,b.resolve)(e,"tp");try{if((0,$.existsSync)(n)&&(0,$.statSync)(n).isDirectory())return n}catch{}let o=(0,b.dirname)(e);if(o===e)break;e=o,r++}return null}var Ze=(0,Pe.promisify)(Ce.exec),_=new Me.Command;_.name("task-pipeliner").description(`A powerful task pipeline runner with condition-based workflow execution.
38
+ `),n=0,o=!1,i=!1;for(let a=0;a<r.length;a++){let l=r[a].trim();if(l.startsWith('"steps"')||l.startsWith("'steps'")){o=!0,l.includes("[")&&(i=!0);continue}if(o&&l==="["){i=!0;continue}if(i&&l==="]"){i=!1,o=!1;continue}i&&l.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 oe;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.15"}function Ne(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 rt=(0,Ie.promisify)(Ae.exec),_=new De.Command;_.name("task-pipeliner").description(`A powerful task pipeline runner with condition-based workflow execution.
22
39
 
23
40
  Define workflows in YAML or JSON files with conditional execution, parallel tasks,
24
41
  interactive prompts, and variable substitution.
@@ -56,7 +73,7 @@ Quick Start:
56
73
  tp history remove # Remove a specific history
57
74
  tp history remove-all # Remove all histories
58
75
 
59
- `).version(Re()).addHelpText("after",`
76
+ `).version(Te()).addHelpText("after",`
60
77
  Examples:
61
78
  $ tp run workflow.yaml
62
79
  $ tp run examples/simple-project/workflow.yaml
@@ -94,10 +111,10 @@ Workflow File Structure:
94
111
  \u2022 all/any/not: Combine conditions
95
112
 
96
113
  Supported formats: YAML (.yaml, .yml) and JSON (.json)
97
- See README.md for complete DSL documentation.`).action(async(s,e)=>{try{let t=s??await Xe()??null;t||(console.error(u.default.red(`
98
- \u2717 No workflow file found`)),process.exit(1)),e.silent&&ve();let r=se(t);console.log(u.default.blue(`Loading workflow from ${t}...`));let n=(0,ae.readFileSync)(t,"utf-8"),o=r.parse(n);if(!o.steps||!Array.isArray(o.steps))throw new Error("Invalid workflow: steps array is required");o._lineNumbers=r.extractStepLineNumbers(n),o._fileName=qe(t),o._filePath=(0,L.resolve)(t),console.log(u.default.green(`Starting workflow execution...
99
- `)),await new Z().execute(o),console.log(u.default.green(`
100
- \u2713 Workflow completed successfully`))}catch(t){let r=t instanceof Error?t.message:String(t);console.error(u.default.red(`
114
+ See README.md for complete DSL documentation.`).action(async(s,e)=>{try{let t=s??await ot()??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");o._lineNumbers=r.extractStepLineNumbers(n),o._fileName=st(t),o._filePath=(0,W.resolve)(t),console.log(p.default.green(`Starting workflow execution...
116
+ `)),await new Z().execute(o),console.log(p.default.green(`
117
+ \u2713 Workflow completed successfully`))}catch(t){let r=t instanceof Error?t.message:String(t);console.error(p.default.red(`
101
118
  \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",`
102
119
  Examples:
103
120
  $ tp open generator
@@ -105,29 +122,29 @@ Examples:
105
122
 
106
123
  Targets:
107
124
  generator Open the visual workflow generator (https://task-pipeliner-generator.racgoo.com/)
108
- 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(u.default.red(`
109
- \u2717 Invalid target: ${s}`)),console.log(u.default.yellow(`
110
- Valid targets:`)),console.log(u.default.yellow(" \u2022 generator - Open the visual workflow generator")),console.log(u.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 Ze(n),console.log(u.default.green(`
111
- \u2713 Opening ${s==="generator"?"generator":"documentation"} in browser...`)),console.log(u.default.blue(` ${t}`))}catch(r){let n=r instanceof Error?r.message:String(r);console.error(u.default.red(`
112
- \u2717 Failed to open browser: ${n}`)),console.log(u.default.yellow(`
113
- Please visit manually: ${t}`)),process.exit(1)}});var Ge=_.command("history").description("Manage workflow execution history");Ge.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(u.default.red(`
114
- \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(u.default.yellow(`
115
- \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(u.default.red(`
116
- \u2717 Invalid choice`)),process.exit(1));try{let o=await t.getHistory(n.id);Ke(o,n.id)}catch(o){let i=o instanceof Error?o.message:String(o);console.error(u.default.red(`
117
- \u2717 Failed to load history: ${i}`)),process.exit(1)}break}case"remove":{let r=await t.getHistoryNames();if(r.length===0){console.log(u.default.yellow(`
118
- \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(u.default.red(`
119
- \u2717 Invalid choice`)),process.exit(1));try{await t.removeHistory(n.id),console.log(u.default.green(`
120
- \u2713 Removed history: ${n.id}`))}catch(o){let i=o instanceof Error?o.message:String(o);console.error(u.default.red(`
121
- \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(u.default.yellow(`
122
- \u2717 Cancelled`));return}try{await t.clearAllHistories(),console.log(u.default.green(`
123
- \u2713 All histories removed`))}catch(n){let o=n instanceof Error?n.message:String(n);console.error(u.default.red(`
124
- \u2717 Failed to remove histories: ${o}`)),process.exit(1)}break}default:console.error(u.default.red(`
125
- \u2717 Unknown action: ${e.id}`)),process.exit(1)}});async function Xe(){let s=$e();if(!s)return console.error(u.default.red(`
126
- \u2717 No tp directory found`)),null;try{let t=(await(0,Ee.readdir)(s)).filter(i=>{let a=(0,L.extname)(i).toLowerCase();return[".yaml",".yml",".json"].includes(a)});if(t.length===0)return console.error(u.default.red(`
127
- \u2717 No workflow files found in ${s}`)),null;let r=await Promise.all(t.map(async i=>{let a=(0,L.join)(s,i);try{let p=se(a),l=(0,ae.readFileSync)(a,"utf-8"),h=p.parse(l).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(u.default.red(`
128
- \u2717 Failed to read tp directory: ${t}`)),null}}function qe(s){return s.split("/").pop()??s}function Ke(s,e){console.log(`
129
- `);let t=s.records.reduce((l,f)=>l+f.duration,0),r=s.records.filter(l=>l.status==="success").length,n=s.records.filter(l=>l.status==="failure").length,o=(0,Ne.default)(s.initialTimestamp).format("YYYY-MM-DD HH:mm:ss"),a=D(t),p=[u.default.bold("Workflow Execution History"),"",`${u.default.cyan("File:")} ${e}`,`${u.default.cyan("Started:")} ${o}`,`${u.default.cyan("Total Duration:")} ${a}`,`${u.default.cyan("Total Steps:")} ${s.records.length}`,`${u.default.green("\u2713 Successful:")} ${r}`,n>0?`${u.default.red("\u2717 Failed:")} ${n}`:""].filter(Boolean).join(`
130
- `);console.log((0,le.default)(p,{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,f)=>{Qe(l,f+1,s.records.length)}),console.log("")}function Qe(s,e,t){let r=et(s.step),n=tt(s.step),o=s.status==="success"?u.default.green("\u2713"):u.default.red("\u2717"),i=s.status==="success"?u.default.green("Success"):u.default.red("Failed"),a=D(s.duration),p=[`${o} ${u.default.bold(`Step ${e}/${t}`)} - ${u.default.cyan(r)}`,`${u.default.gray("Duration:")} ${a} | ${u.default.gray("Status:")} ${i}`,"",u.default.white(n)].join(`
131
- `);console.log((0,le.default)(p,{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"})),rt(s.output)&&ot(s.output)}function et(s){return"run"in s?"Run":"choose"in s?"Choose":"prompt"in s?"Prompt":"parallel"in s?"Parallel":"fail"in s?"Fail":"Unknown"}function tt(s){return"run"in s?`Command: ${u.default.yellow(s.run)}`:"choose"in s?`Message: ${u.default.yellow(s.choose.message)}`:"prompt"in s?`Message: ${u.default.yellow(s.prompt.message)} | Variable: ${u.default.cyan(s.prompt.as)}`:"parallel"in s?`Parallel execution with ${s.parallel.length} branches`:"fail"in s?`Error: ${u.default.red(s.fail.message)}`:"Unknown step type"}function rt(s){return typeof s=="object"&&s!==null&&"success"in s&&"stdout"in s&&"stderr"in s}function ot(s){if(s.stdout.length>0){let e=s.stdout.map(t=>u.default.gray(` ${t}`)).join(`
132
- `);console.log(u.default.green(" Output:")),console.log(e)}if(s.stderr.length>0){let e=s.stderr.map(t=>u.default.gray(` ${t}`)).join(`
133
- `);console.log(u.default.red(" Errors:")),console.log(e)}}_.parse();
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(`
126
+ \u2717 Invalid target: ${s}`)),console.log(p.default.yellow(`
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 rt(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=_.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);it(o,n.id)}catch(o){let i=o instanceof Error?o.message:String(o);console.error(p.default.red(`
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(`
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(`
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(`
139
+ \u2717 Cancelled`));return}try{await t.clearAllHistories(),console.log(p.default.green(`
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 ot(){let s=Ne();if(!s)return console.error(p.default.red(`
143
+ \u2717 No tp directory found`)),null;try{let t=(await(0,Be.readdir)(s)).filter(i=>{let a=(0,W.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,W.join)(s,i);try{let u=ae(a),l=(0,ce.readFileSync)(a,"utf-8"),h=u.parse(l).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 st(s){return s.split("/").pop()??s}function it(s,e){console.log(`
146
+ `);let t=s.records.reduce((l,m)=>l+m.duration,0),r=s.records.filter(l=>l.status==="success").length,n=s.records.filter(l=>l.status==="failure").length,o=(0,Le.default)(s.initialTimestamp).format("YYYY-MM-DD HH:mm:ss"),a=I(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((l,m)=>{at(l,m+1,s.records.length)}),console.log("")}function at(s,e,t){let r=lt(s.step),n=ct(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=I(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"})),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(`
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(`
150
+ `);console.log(p.default.red(" Errors:")),console.log(e)}}_.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.13",
3
+ "version": "0.2.15",
4
4
  "description": "A task pipeline runner with condition-based workflow execution",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",