task-pipeliner 0.2.13 → 0.2.14

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.14
6
6
 
7
7
  ![fox2](https://github.com/user-attachments/assets/fdf8d786-6a91-4d2d-9dc1-72be6f3ccd98)
8
8
 
@@ -609,9 +609,11 @@ steps:
609
609
  ```
610
610
 
611
611
  **속성:**
612
- - `parallel` (필수): `Step` 객체의 `array` - 병렬로 실행할 단계 (`steps`와 동일한 형식, step은 `-`로 시작)
612
+ - `parallel` (필수): 단계들의 `array` - 병렬로 실행할 단계. **`run`, 중첩 `parallel`, `fail` 스텝만 허용됩니다.** `choose`와 `prompt`(사용자 입력 스텝)는 `parallel` **안에서 사용할 수 없습니다**—사용자 입력은 병렬로 실행되지 않습니다.
613
613
  - `when` (선택): `Condition` - 조건이 충족될 때만 병렬 블록 실행
614
614
 
615
+ **제한:** `parallel` 내부의 스텝은 `run`, 중첩 `parallel`, `fail`만 사용할 수 있습니다. `parallel` 안에서 `choose`나 `prompt`를 사용하면 안 되며, 워크플로우 검증 시 에러가 발생합니다 (예: `'choose' step is not allowed inside 'parallel' block`).
616
+
615
617
  **예제:**
616
618
  ```yaml
617
619
  # 기본 병렬 실행
@@ -640,20 +642,12 @@ steps:
640
642
  - run: npm run test
641
643
  - run: npm run lint
642
644
 
643
- # parallel 모든 step 타입을 포함할 있습니다 (run, choose, prompt 등)
645
+ # 중첩 parallel (허용); parallel 내부에는 run / parallel / fail만 사용
644
646
  - parallel:
645
647
  - 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
648
+ - parallel:
649
+ - run: npm run lint
650
+ - run: npm run typecheck
657
651
  ```
658
652
 
659
653
  **동작:**
@@ -661,6 +655,7 @@ steps:
661
655
  - 워크플로우는 모든 병렬 단계가 완료될 때까지 기다립니다
662
656
  - 어떤 단계라도 실패하면 워크플로우가 중지됩니다
663
657
  - 각 병렬 브랜치는 자체 격리된 워크스페이스 상태를 가집니다 (복제됨)
658
+ - **`choose`와 `prompt`는 `parallel` 안에서 사용할 수 없습니다** (사용자 입력은 병렬로 실행되지 않음; `parallel` 블록 앞뒤의 순차 스텝에서만 사용하세요)
664
659
 
665
660
  ---
666
661
 
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.14
6
6
 
7
7
  ![fox2](https://github.com/user-attachments/assets/fdf8d786-6a91-4d2d-9dc1-72be6f3ccd98)
8
8
 
@@ -609,9 +609,11 @@ Execute multiple steps simultaneously. Like `steps`, `parallel` contains an arra
609
609
  ```
610
610
 
611
611
  **Properties:**
612
- - `parallel` (required): `array` of `Step` objects - Steps to execute in parallel (same format as `steps`, each step starts with `-`)
612
+ - `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
613
  - `when` (optional): `Condition` - Execute parallel block only if condition is met
614
614
 
615
+ **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`).
616
+
615
617
  **Examples:**
616
618
  ```yaml
617
619
  # Basic parallel execution
@@ -640,20 +642,12 @@ Execute multiple steps simultaneously. Like `steps`, `parallel` contains an arra
640
642
  - run: npm run test
641
643
  - run: npm run lint
642
644
 
643
- # parallel can contain any step type (run, choose, prompt, etc.)
645
+ # Nested parallel (allowed); only run / parallel / fail inside parallel
644
646
  - parallel:
645
647
  - 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
648
+ - parallel:
649
+ - run: npm run lint
650
+ - run: npm run typecheck
657
651
  ```
658
652
 
659
653
  **Behavior:**
@@ -661,6 +655,7 @@ Execute multiple steps simultaneously. Like `steps`, `parallel` contains an arra
661
655
  - Workflow waits for all parallel steps to complete before continuing
662
656
  - If any step fails, the workflow stops
663
657
  - Each parallel branch has its own isolated workspace state (cloned)
658
+ - **`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
659
 
665
660
  ---
666
661
 
package/dist/index.cjs CHANGED
@@ -1,24 +1,37 @@
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(`
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=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(`
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?`
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:
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:
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:
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:
24
+ - 'steps' is required`);if(!Array.isArray(e.steps))throw new Error(`Invalid workflow structure:
25
+ - 'steps' must be an array`);if(e.steps.length===0)throw new Error(`Invalid workflow structure:
26
+ - 'steps' cannot be empty
27
+ 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(`
16
29
  `);throw new Error(`Invalid workflow structure:
17
- ${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(`
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(`
19
32
  `);throw new Error(`Invalid workflow structure:
20
- ${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.
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.
22
35
 
23
36
  Define workflows in YAML or JSON files with conditional execution, parallel tasks,
24
37
  interactive prompts, and variable substitution.
@@ -56,7 +69,7 @@ Quick Start:
56
69
  tp history remove # Remove a specific history
57
70
  tp history remove-all # Remove all histories
58
71
 
59
- `).version(Re()).addHelpText("after",`
72
+ `).version(Te()).addHelpText("after",`
60
73
  Examples:
61
74
  $ tp run workflow.yaml
62
75
  $ tp run examples/simple-project/workflow.yaml
@@ -94,10 +107,10 @@ Workflow File Structure:
94
107
  \u2022 all/any/not: Combine conditions
95
108
 
96
109
  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(`
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(`
113
+ \u2713 Workflow completed successfully`))}catch(t){let r=t instanceof Error?t.message:String(t);console.error(p.default.red(`
101
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",`
102
115
  Examples:
103
116
  $ tp open generator
@@ -105,29 +118,29 @@ Examples:
105
118
 
106
119
  Targets:
107
120
  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();
121
+ 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
+ \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(`
130
+ \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(`
134
+ \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
+ \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(`
145
+ `);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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-pipeliner",
3
- "version": "0.2.13",
3
+ "version": "0.2.14",
4
4
  "description": "A task pipeline runner with condition-based workflow execution",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",