task-pipeliner 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ko.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > 조건 기반 작업 파이프라인 실행기로 아름다운 CLI 출력을 제공합니다
4
4
 
5
- **버전:** 0.1.7
5
+ **버전:** 0.2.0
6
6
 
7
7
  ![fox2](https://github.com/user-attachments/assets/fdf8d786-6a91-4d2d-9dc1-72be6f3ccd98)
8
8
 
@@ -245,6 +245,12 @@ steps: # 필수: 실행할 단계 배열
245
245
  when?: <condition> # 선택: 조건이 충족될 때만 실행
246
246
  timeout?: <number> # 선택: 타임아웃 (초 단위)
247
247
  retry?: <number> # 선택: 실패 시 재시도 횟수 (기본값: 0)
248
+ onError?: # 선택: 에러 처리 동작
249
+ run: <command> # 체인에서 앞선 명령이 실패했을 때 실행할 대체 명령
250
+ timeout?: <number> # 선택: 이 fallback 명령의 타임아웃
251
+ retry?: <number> # 선택: 이 fallback 명령의 재시도 횟수
252
+ continue?: <bool> # 선택: 체인 전체가 실패해도 워크플로우를 계속 진행할지 여부
253
+ onError?: ... # 선택: 중첩 fallback (재귀 onError 체인)
248
254
  ```
249
255
 
250
256
  **속성:**
@@ -252,6 +258,10 @@ steps: # 필수: 실행할 단계 배열
252
258
  - `when` (선택): `Condition` - 실행 전 확인할 조건
253
259
  - `timeout` (선택): `number` - 최대 실행 시간 (초 단위). 이 시간을 초과하면 명령이 종료됩니다.
254
260
  - `retry` (선택): `number` - 실패 시 재시도 횟수 (기본값: 0, 재시도 없음)
261
+ - `onError.run` (선택): `string` - 이전 체인 명령이 (자신의 재시도 후에도) 실패했을 때 실행할 대체 명령. 체인 안의 어떤 명령이라도 성공하면 이 `run` 단계는 성공으로 간주됩니다.
262
+ - `onError.timeout` (선택): `number` - 이 fallback 명령의 타임아웃.
263
+ - `onError.retry` (선택): `number` - 이 fallback 명령의 재시도 횟수.
264
+ - `onError.continue` (선택): `boolean` - onError 체인 전체가 결국 실패해도, 이 단계를 실패로 기록만 하고 다음 단계로 계속 진행할지 여부.
255
265
 
256
266
  **예제:**
257
267
  ```yaml
@@ -291,11 +301,28 @@ steps:
291
301
  - run: npm install
292
302
  timeout: 60
293
303
  retry: 2
304
+
305
+ # 실패 시 fallback 명령 실행
306
+ - run: pnpm lint
307
+ onError:
308
+ run: pnpm lint:fix
309
+
310
+ # 여러 단계로 이어지는 fallback 체인
311
+ - run: step1
312
+ onError:
313
+ run: step2
314
+ onError:
315
+ run: step3
316
+
317
+ # 실패를 기록만 하고 워크플로우는 계속 진행
318
+ - run: pnpm typecheck
319
+ onError:
320
+ continue: true
294
321
  ```
295
322
 
296
323
  **동작:**
297
324
  - 명령은 `baseDir` (지정된 경우) 또는 현재 작업 디렉토리에서 실행됩니다
298
- - 명령이 실패하면 워크플로우가 중지됩니다 (모든 재시도 후에도 실패한 경우)
325
+ - 명령이 실패하면 onError 체인을 모두 시도한 뒤, 최종적으로 실패인 경우 워크플로우가 중지됩니다 (`onError.continue` `true`인 경우에는 실패로 기록만 하고 계속 진행)
299
326
  - 출력은 CLI 포맷팅과 함께 실시간으로 표시됩니다
300
327
  - `timeout`이 지정되면 명령이 시간 제한을 초과하면 종료되고 단계가 실패합니다
301
328
  - `retry`가 지정되면 성공할때 까지 retry 값 만큼 재시도됩니다
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.1.7
5
+ **Version:** 0.2.0
6
6
 
7
7
  ![fox2](https://github.com/user-attachments/assets/fdf8d786-6a91-4d2d-9dc1-72be6f3ccd98)
8
8
 
@@ -245,6 +245,12 @@ Execute a shell command.
245
245
  when?: <condition> # Optional: Execute only if condition is met
246
246
  timeout?: <number> # Optional: Timeout in seconds
247
247
  retry?: <number> # Optional: Number of retries on failure (default: 0)
248
+ onError?: # Optional: Error handling behavior
249
+ run: <command> # Fallback command when the previous command in the chain fails
250
+ timeout?: <number> # Optional: Timeout for this fallback command
251
+ retry?: <number> # Optional: Retry count for this fallback command
252
+ continue?: <bool> # Optional: Continue workflow even if the whole chain still fails
253
+ onError?: ... # Optional: Nested fallback (recursive onError chain)
248
254
  ```
249
255
 
250
256
  **Properties:**
@@ -252,6 +258,10 @@ Execute a shell command.
252
258
  - `when` (optional): `Condition` - Condition to check before execution
253
259
  - `timeout` (optional): `number` - Maximum execution time in seconds. Command will be killed if it exceeds this time.
254
260
  - `retry` (optional): `number` - Number of retry attempts if command fails (default: 0, meaning no retry)
261
+ - `onError.run` (optional): `string` - Fallback command executed when the previous command in the chain (after its retries) fails. If any command in the chain succeeds, the step is treated as successful.
262
+ - `onError.timeout` (optional): `number` - Timeout for this fallback command.
263
+ - `onError.retry` (optional): `number` - Retry count for this fallback command.
264
+ - `onError.continue` (optional): `boolean` - If `true` and the entire onError chain ultimately fails, record the failure but continue to the next step instead of stopping the workflow.
255
265
 
256
266
  **Examples:**
257
267
  ```yaml
@@ -291,11 +301,28 @@ steps:
291
301
  - run: npm install
292
302
  timeout: 60
293
303
  retry: 2
304
+
305
+ # Command with fallback on error
306
+ - run: pnpm lint
307
+ onError:
308
+ run: pnpm lint:fix
309
+
310
+ # Command with multi-level fallback on error
311
+ - run: step1
312
+ onError:
313
+ run: step2
314
+ onError:
315
+ run: step3
316
+
317
+ # Command that records failure but continues workflow
318
+ - run: pnpm typecheck
319
+ onError:
320
+ continue: true
294
321
  ```
295
322
 
296
323
  **Behavior:**
297
324
  - Command runs in the `baseDir` (if specified) or current working directory
298
- - Workflow stops if command fails (non-zero exit code) after all retries are exhausted
325
+ - Workflow stops if command fails (non-zero exit code) after all retries and onError chain are exhausted, unless `onError.continue` is `true`
299
326
  - Output is displayed in real-time with CLI formatting
300
327
  - If `timeout` is specified and command exceeds the time limit, it will be killed and the step will fail
301
328
  - If `retry` is specified, the command will be retried up to the retry value until it succeeds
package/dist/index.cjs CHANGED
@@ -1,22 +1,22 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var ye=Object.create;var oe=Object.defineProperty;var xe=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var ve=Object.getPrototypeOf,ke=Object.prototype.hasOwnProperty;var Ce=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Se(e))!ke.call(o,s)&&s!==t&&oe(o,s,{get:()=>e[s],enumerable:!(r=xe(e,s))||r.enumerable});return o};var S=(o,e,t)=>(t=o!=null?ye(ve(o)):{},Ce(e||!o||!o.__esModule?oe(t,"default",{value:o,enumerable:!0}):t,o));var de=require("child_process"),fe=require("fs"),he=require("path"),ge=require("util"),re=S(require("boxen"),1),u=S(require("chalk"),1),we=require("commander"),be=S(require("dayjs"),1);var P=require("path"),_=S(require("log-update"),1);var Z=S(require("chalk"),1),G=S(require("inquirer"),1),M=class{async prompt(e,t){let{choice:r}=await G.default.prompt([{type:"list",name:"choice",message:Z.default.cyan(e),choices:t.map(n=>({name:n.label,value:n.id}))}]),s=t.find(n=>n.id===r);if(!s)throw new Error(`Invalid choice: ${r}`);return s}},D=class{async prompt(e,t){let{value:r}=await G.default.prompt([{type:"input",name:"value",message:Z.default.cyan(e),default:t}]);return r}};var L=S(require("boxen"),1),B=S(require("chalk"),1);function X(o,e,t,r={}){let{borderColor:s="cyan",isNested:n=!1}=r,a;e!==void 0&&(t?a=`line ${e} in ${t}`:a=`line ${e}`);let i=n?`\u2502 ${o}`:`> ${o}`;return(0,L.default)(i,{title:a,borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0},borderColor:s})}function F(o,e=!1){let t=o?"\u2713 Completed":"\u2717 Failed";return o?B.default.green(t):B.default.red(t)}function T(o){return(0,L.default)(`\u2717 ${o}`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0},borderColor:"red"})}function se(o){return(0,L.default)(`> Starting parallel execution (${o} branches)`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0},borderColor:"yellow"})}function ne(o){let e=o?"\u2713 All parallel branches completed":"\u2717 Some parallel branches failed";return o?B.default.green(e):B.default.red(e)}function q(o,e=!1){return`${e?"| \u2502 ":"\u2502 "}${o}`}var ae=require("fs"),ie=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,s]of Object.entries(e.var)){let n=this.workspace.getVariable(r),a=this.workspace.getFact(r),i=n??(a!==void 0?a.toString():void 0);if(i===void 0||i!==s)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,ie.resolve)(process.cwd(),t);return(0,ae.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 v=require("fs/promises"),le=require("os"),E=require("path"),ce=S(require("dayjs"),1),N=(0,E.join)((0,le.homedir)(),".pipeliner","workflow-history"),A=class{constructor(){}async saveHistory(e){await(0,v.mkdir)(N,{recursive:!0});let t=(0,ce.default)().format("YYYY-MM-DD_HH-mm-ss"),r=Math.random().toString(36).slice(2,6),s=(0,E.join)(N,`workflow-${t}-${r}.json`);return await(0,v.writeFile)(s,JSON.stringify(e,null,2),{encoding:"utf8"}),s}async clearAllHistories(){await(0,v.rm)(N,{recursive:!0,force:!0})}async removeHistory(e){await(0,v.rm)((0,E.join)(N,e),{force:!0})}async getHistoryNames(){try{let t=(await(0,v.readdir)(N)).map(r=>(0,E.basename)(r));return t.sort((r,s)=>{let n=p=>{let c=p.match(/workflow-(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-/);return c?c[1]:""},a=n(r),i=n(s);return a===i?s.localeCompare(r):i.localeCompare(a)}),t}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return[];throw e}}async getHistory(e){let t=await(0,v.readFile)((0,E.join)(N,e),{encoding:"utf8"});return JSON.parse(t)}};var W=class{records=[];initialTimestamp=Date.now();recordStartTimestamp=Date.now();constructor(){this.records=[]}recordStart(){this.recordStartTimestamp=Date.now()}recordEnd(e,t,r,s){let n=this.getDuration();this.records.push({step:e,context:t,output:r,duration:n,status:s})}reset(){this.records=[],this.initialTimestamp=Date.now()}async save(){let e=new A,t={initialTimestamp:this.initialTimestamp,records:this.records};return await e.saveHistory(t)}getDuration(){return Date.now()-this.recordStartTimestamp}};var H=class{async run(e,t,r,s,n=!1,a=!1,i,p,c,m){return n?this.runBuffered(e,c,m):this.runRealtime(e,r||e,a,i,p,c,m)}async runBuffered(e,t,r){let{spawn:s}=await import("child_process"),[n,...a]=this.parseCommand(e),i=this.createSpawnOptions(t);return new Promise((p,c)=>{let m=s(n,a,i),h=[],d=[],f="",g="",b=null;r&&r>0&&(b=setTimeout(()=>{m.kill("SIGTERM");let w=`Command timed out after ${r} seconds`;d.push(w),p({success:!1,stdout:h,stderr:d})},r*1e3)),m.stdout?.on("data",w=>{let x=w.toString(),{lines:C,remaining:y}=this.processStreamBuffer(x,f);h.push(...C),f=y}),m.stderr?.on("data",w=>{let x=w.toString(),{lines:C,remaining:y}=this.processStreamBuffer(x,g);d.push(...C),g=y}),m.on("close",w=>{b&&clearTimeout(b),f.trim()&&h.push(f),g.trim()&&d.push(g),p({success:w===0,stdout:h,stderr:d})}),m.on("error",w=>{b&&clearTimeout(b);let x=`Error: ${w.message}`;p({success:!1,stdout:h,stderr:[...d,x]})})})}async runRealtime(e,t,r,s,n,a,i){let{spawn:p}=await import("child_process"),[c,...m]=this.parseCommand(e),h=this.createSpawnOptions(a),f=X(t,s,n,{borderColor:r?"green":"cyan"});return console.log(f),new Promise(g=>{let b=p(c,m,h),w="",x="",C=null;i&&i>0&&(C=setTimeout(()=>{b.kill("SIGTERM");let y=`Command timed out after ${i} seconds`,k=T(y);console.error(k);let R=F(!1);console.log(R),g(!1)},i*1e3)),b.stdout?.on("data",y=>{let k=y.toString(),{lines:R,remaining:U}=this.processStreamBuffer(k,w);R.forEach(z=>process.stdout.write(`\u2502 ${z}
3
- `)),w=U}),b.stderr?.on("data",y=>{let k=y.toString(),{lines:R,remaining:U}=this.processStreamBuffer(k,x);R.forEach(z=>process.stderr.write(`\u2502 ${z}
4
- `)),x=U}),b.on("close",y=>{C&&clearTimeout(C),w.trim()&&process.stdout.write(`\u2502 ${w}
2
+ "use strict";var xe=Object.create;var oe=Object.defineProperty;var Se=Object.getOwnPropertyDescriptor;var ve=Object.getOwnPropertyNames;var ke=Object.getPrototypeOf,Re=Object.prototype.hasOwnProperty;var Ce=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of ve(e))!Re.call(s,o)&&o!==t&&oe(s,o,{get:()=>e[o],enumerable:!(r=Se(e,o))||r.enumerable});return s};var S=(s,e,t)=>(t=s!=null?xe(ke(s)):{},Ce(e||!s||!s.__esModule?oe(t,"default",{value:s,enumerable:!0}):t,s));var fe=require("child_process"),he=require("fs"),ge=require("path"),we=require("util"),re=S(require("boxen"),1),u=S(require("chalk"),1),be=require("commander"),ye=S(require("dayjs"),1);var P=require("path"),_=S(require("log-update"),1);var Z=S(require("chalk"),1),G=S(require("inquirer"),1),M=class{async prompt(e,t){let{choice:r}=await G.default.prompt([{type:"list",name:"choice",message:Z.default.cyan(e),choices:t.map(n=>({name:n.label,value:n.id}))}]),o=t.find(n=>n.id===r);if(!o)throw new Error(`Invalid choice: ${r}`);return o}},D=class{async prompt(e,t){let{value:r}=await G.default.prompt([{type:"input",name:"value",message:Z.default.cyan(e),default:t}]);return r}};var L=S(require("boxen"),1),A=S(require("chalk"),1);function X(s,e,t,r={}){let{borderColor:o="cyan",isNested:n=!1}=r,a;e!==void 0&&(t?a=`line ${e} in ${t}`:a=`line ${e}`);let i=n?`\u2502 ${s}`:`> ${s}`;return(0,L.default)(i,{title:a,borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0},borderColor:o})}function F(s,e=!1){let t=s?"\u2713 Completed":"\u2717 Failed";return s?A.default.green(t):A.default.red(t)}function B(s){return(0,L.default)(`\u2717 ${s}`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0},borderColor:"red"})}function ne(s){return(0,L.default)(`> Starting parallel execution (${s} branches)`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0},borderColor:"yellow"})}function se(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 q(s,e=!1){return`${e?"| \u2502 ":"\u2502 "}${s}`}var ae=require("fs"),ie=require("path"),N=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),a=this.workspace.getFact(r),i=n??(a!==void 0?a.toString():void 0);if(i===void 0||i!==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,ie.resolve)(process.cwd(),t);return(0,ae.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 v=require("fs/promises"),le=require("os"),$=require("path"),ce=S(require("dayjs"),1),I=(0,$.join)((0,le.homedir)(),".pipeliner","workflow-history"),T=class{constructor(){}async saveHistory(e){await(0,v.mkdir)(I,{recursive:!0});let t=(0,ce.default)().format("YYYY-MM-DD_HH-mm-ss"),r=Math.random().toString(36).slice(2,6),o=(0,$.join)(I,`workflow-${t}-${r}.json`);return await(0,v.writeFile)(o,JSON.stringify(e,null,2),{encoding:"utf8"}),o}async clearAllHistories(){await(0,v.rm)(I,{recursive:!0,force:!0})}async removeHistory(e){await(0,v.rm)((0,$.join)(I,e),{force:!0})}async getHistoryNames(){try{let t=(await(0,v.readdir)(I)).map(r=>(0,$.basename)(r));return t.sort((r,o)=>{let n=p=>{let c=p.match(/workflow-(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-/);return c?c[1]:""},a=n(r),i=n(o);return a===i?o.localeCompare(r):i.localeCompare(a)}),t}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return[];throw e}}async getHistory(e){let t=await(0,v.readFile)((0,$.join)(I,e),{encoding:"utf8"});return JSON.parse(t)}};var W=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();this.records.push({step:e,context:t,output:r,duration:n,status:o})}reset(){this.records=[],this.initialTimestamp=Date.now()}async save(){let e=new T,t={initialTimestamp:this.initialTimestamp,records:this.records};return await e.saveHistory(t)}getDuration(){return Date.now()-this.recordStartTimestamp}};var H=class{async run(e,t,r,o,n=!1,a=!1,i,p,c,m){return n?this.runBuffered(e,c,m):this.runRealtime(e,r||e,a,i,p,c,m)}async runBuffered(e,t,r){let{spawn:o}=await import("child_process"),[n,...a]=this.parseCommand(e),i=this.createSpawnOptions(t);return new Promise((p,c)=>{let m=o(n,a,i),h=[],d=[],f="",g="",y=null;r&&r>0&&(y=setTimeout(()=>{m.kill("SIGTERM");let w=`Command timed out after ${r} seconds`;d.push(w),p({success:!1,stdout:h,stderr:d})},r*1e3)),m.stdout?.on("data",w=>{let x=w.toString(),{lines:R,remaining:b}=this.processStreamBuffer(x,f);h.push(...R),f=b}),m.stderr?.on("data",w=>{let x=w.toString(),{lines:R,remaining:b}=this.processStreamBuffer(x,g);d.push(...R),g=b}),m.on("close",w=>{y&&clearTimeout(y),f.trim()&&h.push(f),g.trim()&&d.push(g),p({success:w===0,stdout:h,stderr:d})}),m.on("error",w=>{y&&clearTimeout(y);let x=`Error: ${w.message}`;p({success:!1,stdout:h,stderr:[...d,x]})})})}async runRealtime(e,t,r,o,n,a,i){let{spawn:p}=await import("child_process"),[c,...m]=this.parseCommand(e),h=this.createSpawnOptions(a),f=X(t,o,n,{borderColor:r?"green":"cyan"});return console.log(f),new Promise(g=>{let y=p(c,m,h),w="",x="",R=null;i&&i>0&&(R=setTimeout(()=>{y.kill("SIGTERM");let b=`Command timed out after ${i} seconds`,k=B(b);console.error(k);let E=F(!1);console.log(E),g(!1)},i*1e3)),y.stdout?.on("data",b=>{let k=b.toString(),{lines:E,remaining:z}=this.processStreamBuffer(k,w);E.forEach(U=>process.stdout.write(`\u2502 ${U}
3
+ `)),w=z}),y.stderr?.on("data",b=>{let k=b.toString(),{lines:E,remaining:z}=this.processStreamBuffer(k,x);E.forEach(U=>process.stderr.write(`\u2502 ${U}
4
+ `)),x=z}),y.on("close",b=>{R&&clearTimeout(R),w.trim()&&process.stdout.write(`\u2502 ${w}
5
5
  `),x.trim()&&process.stderr.write(`\u2502 ${x}
6
- `);let k=y===0,R=F(k);console.log(R),g(k)}),b.on("error",y=>{C&&clearTimeout(C);let k=T(`Error: ${y.message}`);console.error(k),g(!1)})})}parseCommand(e){let t=e.split(" ");return[t[0],...t.slice(1)]}createSpawnOptions(e){let t={stdio:["inherit","pipe","pipe"],shell:!0};return e&&(t.cwd=e),t}processStreamBuffer(e,t){let r=t+e,s=[],n=r;for(;n.includes(`
6
+ `);let k=b===0,E=F(k);console.log(E),g(k)}),y.on("error",b=>{R&&clearTimeout(R);let k=B(`Error: ${b.message}`);console.error(k),g(!1)})})}parseCommand(e){let t=e.split(" ");return[t[0],...t.slice(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(`
7
7
  `);){let a=n.indexOf(`
8
- `),i=n.substring(0,a);n=n.substring(a+1),s.push(i)}return{lines:s,remaining:n}}formatNestedOutput(e,t){t?e.split(`
9
- `).forEach(r=>{r.trim()&&console.log(`| ${r}`)}):console.log(e)}displayBufferedOutput(e,t,r=!1,s,n){let a=X(t,s,n,{borderColor:"cyan",isNested:r});this.formatNestedOutput(a,r),e.stdout.forEach(p=>{let c=q(p,r);process.stdout.write(`${c}
8
+ `),i=n.substring(0,a);n=n.substring(a+1),o.push(i)}return{lines:o,remaining:n}}formatNestedOutput(e,t){t?e.split(`
9
+ `).forEach(r=>{r.trim()&&console.log(`| ${r}`)}):console.log(e)}displayBufferedOutput(e,t,r=!1,o,n){let a=X(t,o,n,{borderColor:"cyan",isNested:r});this.formatNestedOutput(a,r),e.stdout.forEach(p=>{let c=q(p,r);process.stdout.write(`${c}
10
10
  `)}),e.stderr.forEach(p=>{let c=q(p,r);process.stderr.write(`${c}
11
- `)});let i=F(e.success,r);console.log(i)}};function $e(o,e,t){if(e.hasVariable(o))return e.getVariable(o)||t;if(e.hasFact(o)){let r=e.getFact(o);return typeof r=="string"?r:String(r)}return e.hasChoice(o)&&e.getChoice(o)||t}function O(o,e){let t=/\{\{(\w+)\}\}/g;return o.replace(t,(r,s)=>$e(s,e,r))}var V=class o{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 o;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 Y=class o{static PARALLEL_STEP_INDEX_MULTIPLIER=1e3;workspace;taskRunner;choicePrompt;textPrompt;baseDir;constructor(){this.workspace=new V,this.taskRunner=new H,this.choicePrompt=new M,this.textPrompt=new D}resolveBaseDir(e){if(e.baseDir)if((0,P.isAbsolute)(e.baseDir))this.baseDir=e.baseDir;else if(e._filePath){let t=(0,P.dirname)(e._filePath);this.baseDir=(0,P.resolve)(t,e.baseDir)}else this.baseDir=(0,P.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/o.PARALLEL_STEP_INDEX_MULTIPLIER)}async execute(e){this.resolveBaseDir(e);let t=new W;for(let r=0;r<e.steps.length;r++){let s=e.steps[r],n=this.createStepContext(r,e),a=!!s.when;if(this.evaluateStepCondition(s)){t.recordStart();try{let i=await this.executeStep(s,n,!1,a);if(!this.isStepSuccessful(i,s)){let p=n.lineNumber?` (line ${n.lineNumber})`:"";throw new Error(`Step ${r}${p} failed`)}t.recordEnd(s,n,i,"success")}catch(i){this.workspace.setStepResult(r,!1);let p=i instanceof Error?i.message:String(i),c={success:!1,stdout:[],stderr:[p]};throw t.recordEnd(s,n,c,"failure"),i}}}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}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,s=!1){if(e=this.fixMalformedStep(e),"run"in e){let n=await this.executeRunStep(e,t,r,s);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 executeRunStep(e,t,r=!1,s=!1){let n=this.calculateBaseStepIndex(t),a=O(e.run,this.workspace),i=e.retry??0,p=e.timeout,c=!1,m=0;for(;m<=i;){let d=await this.taskRunner.run(a,n,a,t.branchIndex,r,s,t.lineNumber,t.fileName,this.baseDir,p),f=typeof d=="boolean"?d:d.success;if(c=d,f||m>=i)break;if(m++,m<=i){let g=Math.min(1e3*Math.pow(2,m-1),1e4);await new Promise(b=>setTimeout(b,g))}}let h=typeof c=="boolean"?c:c.success;return this.workspace.setStepResult(t.stepIndex,h),c}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 s=e.choose.as||r.id;this.workspace.setChoice(r.id,r.id),this.workspace.setVariable(s,r.id),this.workspace.setStepResult(t.stepIndex,!0)}async executePromptStep(e,t){let r=O(e.prompt.message,this.workspace),s=e.prompt.default?O(e.prompt.default,this.workspace):void 0,n=await this.textPrompt.prompt(r,s);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,s)=>({workspace:this.workspace.clone(),stepIndex:t.stepIndex*o.PARALLEL_STEP_INDEX_MULTIPLIER+s,branchIndex:s,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=[],s=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],n=0;for(let c=0;c<e.length;c++){let m=e[c],h=t[c];if(m.when&&!new I(h.workspace).evaluate(m.when))continue;let d=this.getBranchDisplayName(m,c);r.push({index:c,name:d,status:"pending"})}let a=setInterval(()=>{n=(n+1)%s.length,this.updateParallelBranchesDisplay(r,s[n])},100),i=r.map(async c=>{let{index:m}=c,h=e[m],d=t[m];c.status="running";try{let f=await this.executeStep(h,d,!0);return c.status="success",this.updateParallelBranchesDisplay(r,s[n]),{index:m,result:f,context:d}}catch(f){d.workspace.setStepResult(d.stepIndex,!1);let g=f instanceof Error?f.message:String(f);return c.status="failed",c.error=g,this.updateParallelBranchesDisplay(r,s[n]),{index:m,error:f,context:d}}}),p=await Promise.all(i);return clearInterval(a),this.updateParallelBranchesDisplay(r,"",!0),_.default.done(),p}updateParallelBranchesDisplay(e,t,r=!1){let s=e.map(n=>{let a=n.index+1,i="",p="";switch(n.status){case"pending":i="\u25CB",p=`Branch ${a}: ${n.name} - Pending`;break;case"running":i=t,p=`Branch ${a}: ${n.name} - Running...`;break;case"success":i="\u2713",p=`Branch ${a}: ${n.name} - Completed`;break;case"failed":i="\u2717",p=`Branch ${a}: ${n.name} - Failed${n.error?`: ${n.error}`:""}`;break}return`${i} ${p}`});r?(0,_.default)(s.join(`
12
- `)):(0,_.default)(s.join(`
13
- `))}displayParallelResults(e,t,r){let s=!0,n=!1;console.log("");for(let i of e){if(!i)continue;n=!0;let{index:p,result:c,error:m,context:h}=i;if(m){s=!1;let d=`Branch ${p+1} failed: ${m instanceof Error?m.message:String(m)}`,f=T(d);console.error(f)}else if(c&&typeof c=="object"&&"stdout"in c){let d=c;if(s=s&&d.success,d.stdout.length>0||d.stderr.length>0||!d.success){let f=t[p],g=this.getBranchDisplayName(f,p);this.taskRunner.displayBufferedOutput(d,g,!1,h.lineNumber,h.fileName)}}}n||console.log("\u26A0\uFE0F All parallel branches were skipped (conditions not met)");let a=ne(s);return console.log(a),s}mergeParallelResults(e){for(let t of e){let r=t.workspace.getAllFacts(),s=t.workspace.getAllVariables();for(let[n,a]of r)this.workspace.setFact(n,a);for(let[n,a]of s)this.workspace.setVariable(n,a)}}countExecutableBranches(e,t){let r=0;for(let s=0;s<e.length;s++){let n=e[s],a=t[s];n.when&&!new I(a.workspace).evaluate(n.when)||r++}return r}async executeParallelStep(e,t){let r=this.createParallelContexts(e,t),s=this.countExecutableBranches(e.parallel,r),n=se(s);console.log(n);let a=await this.executeParallelBranches(e.parallel,r),i=this.displayParallelResults(a,e.parallel,t);if(this.workspace.setStepResult(t.stepIndex,i),!i){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 pe=require("yaml"),ee=require("zod");var l=require("zod"),Re=l.z.object({file:l.z.string()}),Ee=l.z.object({var:l.z.union([l.z.string(),l.z.record(l.z.string(),l.z.string())]).optional(),has:l.z.string().optional()}),Pe=l.z.object({status:l.z.object({fact:l.z.string(),is:l.z.enum(["ready","failed","pending"])})}),Me=l.z.object({step:l.z.object({success:l.z.boolean()}).optional(),last_step:l.z.enum(["success","failure"]).optional()}),Ie=l.z.object({choice:l.z.string()}),Ne=l.z.union([Re,Ie,Ee,Pe,Me]),$=l.z.lazy(()=>l.z.union([Ne,l.z.object({all:l.z.array($)}),l.z.object({any:l.z.array($)}),l.z.object({not:$})])),Ae=l.z.object({run:l.z.string(),when:$.optional(),timeout:l.z.number().optional(),retry:l.z.number().optional()}),Be=l.z.object({choose:l.z.object({message:l.z.string(),options:l.z.array(l.z.object({id:l.z.string(),label:l.z.string()})),as:l.z.string().optional()}),when:$.optional()}),Te=l.z.object({prompt:l.z.object({message:l.z.string(),as:l.z.string(),default:l.z.string().optional(),validate:l.z.string().optional()}),when:$.optional()}),ue=l.z.lazy(()=>l.z.union([Ae,Be,Te,l.z.object({parallel:l.z.array(ue),when:$.optional()}),l.z.object({fail:l.z.object({message:l.z.string()}),when:$.optional()})])),je=l.z.object({name:l.z.string().optional(),baseDir:l.z.string().optional(),steps:l.z.array(ue).min(1,"Workflow must have at least one step")});function K(o){return je.parse(o)}function te(o){let e=o;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=>te(t))}:o}var J=class{parse(e){let t;try{t=(0,pe.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(s=>te(s)))}try{return K(t)}catch(r){if(r instanceof ee.ZodError){let s=r.issues.map(n=>{let a=n.path.length>0?` at ${n.path.join(".")}`:"";return` - ${n.message}${a}`}).join(`
11
+ `)});let i=F(e.success,r);console.log(i)}};function Ee(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 O(s,e){let t=/\{\{(\w+)\}\}/g;return s.replace(t,(r,o)=>Ee(o,e,r))}var V=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 Y=class s{static PARALLEL_STEP_INDEX_MULTIPLIER=1e3;workspace;taskRunner;choicePrompt;textPrompt;baseDir;constructor(){this.workspace=new V,this.taskRunner=new H,this.choicePrompt=new M,this.textPrompt=new D}resolveBaseDir(e){if(e.baseDir)if((0,P.isAbsolute)(e.baseDir))this.baseDir=e.baseDir;else if(e._filePath){let t=(0,P.dirname)(e._filePath);this.baseDir=(0,P.resolve)(t,e.baseDir)}else this.baseDir=(0,P.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 N(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 W;for(let r=0;r<e.steps.length;r++){let o=e.steps[r],n=this.createStepContext(r,e),a=!!o.when;if(this.evaluateStepCondition(o)){t.recordStart();try{let i=await this.executeStep(o,n,!1,a);this.handleStepResult(o,n,r,i,t)}catch(i){throw this.handleStepError(o,n,r,i,t),i}}}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 a=this.isStepSuccessful(o,e);if(this.isRunStep(e)&&!a){if(!(e.onError?.continue===!0)){let c=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Step ${r}${c} failed`)}n.recordEnd(e,t,o,"failure");return}let i=a?"success":"failure";n.recordEnd(e,t,o,i)}handleStepError(e,t,r,o,n){this.workspace.setStepResult(r,!1);let a=o instanceof Error?o.message:String(o),i={success:!1,stdout:[],stderr:[a]};n.recordEnd(e,t,i,"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),a=O(e.run,this.workspace),i=e.retry??0,p=e.timeout,c=!1,m=0;for(;m<=i;){let h=await this.taskRunner.run(a,n,a,t.branchIndex,r,o,t.lineNumber,t.fileName,this.baseDir,p),d=typeof h=="boolean"?h:h.success;if(c=h,d||m>=i)break;if(m++,m<=i){let f=Math.min(1e3*Math.pow(2,m-1),1e4);await new Promise(g=>setTimeout(g,f))}}return c}async executeRunStep(e,t,r=!1,o=!1){let n={run:e.run,timeout:e.timeout,retry:e.retry,onError:e.onError??void 0},a=await this.executeRunChain(n,t,r,o),i=typeof a=="boolean"?a:a.success;return this.workspace.setStepResult(t.stepIndex,i),a}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=O(e.prompt.message,this.workspace),o=e.prompt.default?O(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 c=0;c<e.length;c++){let m=e[c],h=t[c];if(m.when&&!new N(h.workspace).evaluate(m.when))continue;let d=this.getBranchDisplayName(m,c);r.push({index:c,name:d,status:"pending"})}let a=setInterval(()=>{n=(n+1)%o.length,this.updateParallelBranchesDisplay(r,o[n])},100),i=r.map(async c=>{let{index:m}=c,h=e[m],d=t[m];c.status="running";try{let f=await this.executeStep(h,d,!0);return c.status="success",this.updateParallelBranchesDisplay(r,o[n]),{index:m,result:f,context:d}}catch(f){d.workspace.setStepResult(d.stepIndex,!1);let g=f instanceof Error?f.message:String(f);return c.status="failed",c.error=g,this.updateParallelBranchesDisplay(r,o[n]),{index:m,error:f,context:d}}}),p=await Promise.all(i);return clearInterval(a),this.updateParallelBranchesDisplay(r,"",!0),_.default.done(),p}updateParallelBranchesDisplay(e,t,r=!1){let o=e.map(n=>{let a=n.index+1,i="",p="";switch(n.status){case"pending":i="\u25CB",p=`Branch ${a}: ${n.name} - Pending`;break;case"running":i=t,p=`Branch ${a}: ${n.name} - Running...`;break;case"success":i="\u2713",p=`Branch ${a}: ${n.name} - Completed`;break;case"failed":i="\u2717",p=`Branch ${a}: ${n.name} - Failed${n.error?`: ${n.error}`:""}`;break}return`${i} ${p}`});r?(0,_.default)(o.join(`
12
+ `)):(0,_.default)(o.join(`
13
+ `))}displayParallelResults(e,t,r){let o=!0,n=!1;console.log("");for(let i of e){if(!i)continue;n=!0;let{index:p,result:c,error:m,context:h}=i;if(m){o=!1;let d=`Branch ${p+1} failed: ${m instanceof Error?m.message:String(m)}`,f=B(d);console.error(f)}else if(c&&typeof c=="object"&&"stdout"in c){let d=c;if(o=o&&d.success,d.stdout.length>0||d.stderr.length>0||!d.success){let f=t[p],g=this.getBranchDisplayName(f,p);this.taskRunner.displayBufferedOutput(d,g,!1,h.lineNumber,h.fileName)}}}n||console.log("\u26A0\uFE0F All parallel branches were skipped (conditions not met)");let a=se(o);return console.log(a),o}mergeParallelResults(e){for(let t of e){let r=t.workspace.getAllFacts(),o=t.workspace.getAllVariables();for(let[n,a]of r)this.workspace.setFact(n,a);for(let[n,a]of o)this.workspace.setVariable(n,a)}}countExecutableBranches(e,t){let r=0;for(let o=0;o<e.length;o++){let n=e[o],a=t[o];n.when&&!new N(a.workspace).evaluate(n.when)||r++}return r}async executeParallelStep(e,t){let r=this.createParallelContexts(e,t),o=this.countExecutableBranches(e.parallel,r),n=ne(o);console.log(n);let a=await this.executeParallelBranches(e.parallel,r),i=this.displayParallelResults(a,e.parallel,t);if(this.workspace.setStepResult(t.stepIndex,i),!i){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 me=require("yaml"),ee=require("zod");var l=require("zod"),$e=l.z.object({file:l.z.string()}),Pe=l.z.object({var:l.z.union([l.z.string(),l.z.record(l.z.string(),l.z.string())]).optional(),has:l.z.string().optional()}),Me=l.z.object({status:l.z.object({fact:l.z.string(),is:l.z.enum(["ready","failed","pending"])})}),Ne=l.z.object({step:l.z.object({success:l.z.boolean()}).optional(),last_step:l.z.enum(["success","failure"]).optional()}),Ie=l.z.object({choice:l.z.string()}),Te=l.z.union([$e,Ie,Pe,Me,Ne]),C=l.z.lazy(()=>l.z.union([Te,l.z.object({all:l.z.array(C)}),l.z.object({any:l.z.array(C)}),l.z.object({not:C})])),ue=l.z.lazy(()=>l.z.object({run:l.z.string(),timeout:l.z.number().optional(),retry:l.z.number().optional(),continue:l.z.boolean().optional(),onError:ue.optional()})),Ae=l.z.object({run:l.z.string(),when:C.optional(),timeout:l.z.number().optional(),retry:l.z.number().optional(),onError:ue.optional()}),Be=l.z.object({choose:l.z.object({message:l.z.string(),options:l.z.array(l.z.object({id:l.z.string(),label:l.z.string()})),as:l.z.string().optional()}),when:C.optional()}),je=l.z.object({prompt:l.z.object({message:l.z.string(),as:l.z.string(),default:l.z.string().optional(),validate:l.z.string().optional()}),when:C.optional()}),pe=l.z.lazy(()=>l.z.union([Ae,Be,je,l.z.object({parallel:l.z.array(pe),when:C.optional()}),l.z.object({fail:l.z.object({message:l.z.string()}),when:C.optional()})])),De=l.z.object({name:l.z.string().optional(),baseDir:l.z.string().optional(),steps:l.z.array(pe).min(1,"Workflow must have at least one step")});function K(s){return De.parse(s)}function te(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=>te(t))}:s}var J=class{parse(e){let t;try{t=(0,me.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=>te(o)))}try{return K(t)}catch(r){if(r instanceof ee.ZodError){let o=r.issues.map(n=>{let a=n.path.length>0?` at ${n.path.join(".")}`:"";return` - ${n.message}${a}`}).join(`
14
14
  `);throw new Error(`Invalid workflow structure:
15
- ${s}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
16
- `),s=0,n=!1;for(let a=0;a<r.length;a++){let i=r[a].trim();if(i==="steps:"||i.startsWith("steps:")){n=!0;continue}n&&i.startsWith("-")&&t.set(s++,a+1)}return t}},Q=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(s=>te(s)))}try{return K(t)}catch(r){if(r instanceof ee.ZodError){let s=r.issues.map(n=>{let a=n.path.length>0?` at ${n.path.join(".")}`:"";return` - ${n.message}${a}`}).join(`
15
+ ${o}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
16
+ `),o=0,n=!1;for(let a=0;a<r.length;a++){let i=r[a].trim();if(i==="steps:"||i.startsWith("steps:")){n=!0;continue}n&&i.startsWith("-")&&t.set(o++,a+1)}return t}},Q=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=>te(o)))}try{return K(t)}catch(r){if(r instanceof ee.ZodError){let o=r.issues.map(n=>{let a=n.path.length>0?` at ${n.path.join(".")}`:"";return` - ${n.message}${a}`}).join(`
17
17
  `);throw new Error(`Invalid workflow structure:
18
- ${s}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
19
- `),s=0,n=!1,a=!1;for(let i=0;i<r.length;i++){let c=r[i].trim();if(c.startsWith('"steps"')||c.startsWith("'steps'")){n=!0,c.includes("[")&&(a=!0);continue}if(n&&c==="["){a=!0;continue}if(a&&c==="]"){a=!1,n=!1;continue}a&&c.startsWith("{")&&t.set(s++,i+1)}return t}};function me(o){switch(o.toLowerCase().split(".").pop()){case"yaml":case"yml":return new J;case"json":return new Q;default:return new J}}var De=(0,ge.promisify)(de.exec),j=new we.Command;j.name("task-pipeliner").description(`A powerful task pipeline runner with condition-based workflow execution.
18
+ ${o}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
19
+ `),o=0,n=!1,a=!1;for(let i=0;i<r.length;i++){let c=r[i].trim();if(c.startsWith('"steps"')||c.startsWith("'steps'")){n=!0,c.includes("[")&&(a=!0);continue}if(n&&c==="["){a=!0;continue}if(a&&c==="]"){a=!1,n=!1;continue}a&&c.startsWith("{")&&t.set(o++,i+1)}return t}};function de(s){switch(s.toLowerCase().split(".").pop()){case"yaml":case"yml":return new J;case"json":return new Q;default:return new J}}var Le=(0,we.promisify)(fe.exec),j=new be.Command;j.name("task-pipeliner").description(`A powerful task pipeline runner with condition-based workflow execution.
20
20
 
21
21
  Define workflows in YAML or JSON files with conditional execution, parallel tasks,
22
22
  interactive prompts, and variable substitution.
@@ -89,7 +89,7 @@ Workflow File Structure:
89
89
  \u2022 all/any/not: Combine conditions
90
90
 
91
91
  Supported formats: YAML (.yaml, .yml) and JSON (.json)
92
- See README.md for complete DSL documentation.`).action(async o=>{try{let e=me(o);console.log(u.default.blue(`Loading workflow from ${o}...`));let t=(0,fe.readFileSync)(o,"utf-8"),r=e.parse(t);if(!r.steps||!Array.isArray(r.steps))throw new Error("Invalid workflow: steps array is required");r._lineNumbers=e.extractStepLineNumbers(t),r._fileName=Fe(o),r._filePath=(0,he.resolve)(o),console.log(u.default.green(`Starting workflow execution...
92
+ See README.md for complete DSL documentation.`).action(async s=>{try{let e=de(s);console.log(u.default.blue(`Loading workflow from ${s}...`));let t=(0,he.readFileSync)(s,"utf-8"),r=e.parse(t);if(!r.steps||!Array.isArray(r.steps))throw new Error("Invalid workflow: steps array is required");r._lineNumbers=e.extractStepLineNumbers(t),r._fileName=We(s),r._filePath=(0,ge.resolve)(s),console.log(u.default.green(`Starting workflow execution...
93
93
  `)),await new Y().execute(r),console.log(u.default.green(`
94
94
  \u2713 Workflow completed successfully`))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(u.default.red(`
95
95
  \u2717 Workflow failed: ${t}`)),process.exit(1)}});j.command("open").description("Open generator or docs website in browser").argument("<target>",'Target to open: "generator" or "docs"').addHelpText("after",`
@@ -99,26 +99,26 @@ Examples:
99
99
 
100
100
  Targets:
101
101
  generator Open the visual workflow generator (https://task-pipeliner-generator.racgoo.com/)
102
- docs Open the documentation site (https://task-pipeliner.racgoo.com/)`).action(async o=>{let t={generator:"https://task-pipeliner-generator.racgoo.com/",docs:"https://task-pipeliner.racgoo.com/"}[o.toLowerCase()];t||(console.error(u.default.red(`
103
- \u2717 Invalid target: ${o}`)),console.log(u.default.yellow(`
104
- 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,s;r==="darwin"?s=`open "${t}"`:r==="win32"?s=`start "${t}"`:s=`xdg-open "${t}"`,await De(s),console.log(u.default.green(`
105
- \u2713 Opening ${o==="generator"?"generator":"documentation"} in browser...`)),console.log(u.default.blue(` ${t}`))}catch(r){let s=r instanceof Error?r.message:String(r);console.error(u.default.red(`
106
- \u2717 Failed to open browser: ${s}`)),console.log(u.default.yellow(`
107
- Please visit manually: ${t}`)),process.exit(1)}});var Le=j.command("history").description("Manage workflow execution history");Le.action(async()=>{let o=new M,e=await o.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(`
108
- \u2717 Invalid choice`)),process.exit(1));let t=new A;switch(e.id){case"show":{let r=await t.getHistoryNames();if(r.length===0){console.log(u.default.yellow(`
109
- \u26A0 No history found`));return}let s=await o.prompt("Select a history to view",r.map(n=>({id:n,label:n})));s?.id||(console.error(u.default.red(`
110
- \u2717 Invalid choice`)),process.exit(1));try{let n=await t.getHistory(s.id);We(n,s.id)}catch(n){let a=n instanceof Error?n.message:String(n);console.error(u.default.red(`
102
+ 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(`
103
+ \u2717 Invalid target: ${s}`)),console.log(u.default.yellow(`
104
+ 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,o;r==="darwin"?o=`open "${t}"`:r==="win32"?o=`start "${t}"`:o=`xdg-open "${t}"`,await Le(o),console.log(u.default.green(`
105
+ \u2713 Opening ${s==="generator"?"generator":"documentation"} in browser...`)),console.log(u.default.blue(` ${t}`))}catch(r){let o=r instanceof Error?r.message:String(r);console.error(u.default.red(`
106
+ \u2717 Failed to open browser: ${o}`)),console.log(u.default.yellow(`
107
+ Please visit manually: ${t}`)),process.exit(1)}});var Fe=j.command("history").description("Manage workflow execution history");Fe.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(`
108
+ \u2717 Invalid choice`)),process.exit(1));let t=new T;switch(e.id){case"show":{let r=await t.getHistoryNames();if(r.length===0){console.log(u.default.yellow(`
109
+ \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(u.default.red(`
110
+ \u2717 Invalid choice`)),process.exit(1));try{let n=await t.getHistory(o.id);He(n,o.id)}catch(n){let a=n instanceof Error?n.message:String(n);console.error(u.default.red(`
111
111
  \u2717 Failed to load history: ${a}`)),process.exit(1)}break}case"remove":{let r=await t.getHistoryNames();if(r.length===0){console.log(u.default.yellow(`
112
- \u26A0 No history found`));return}let s=await o.prompt("Select a history to remove",r.map(n=>({id:n,label:n})));s?.id||(console.error(u.default.red(`
113
- \u2717 Invalid choice`)),process.exit(1));try{await t.removeHistory(s.id),console.log(u.default.green(`
114
- \u2713 Removed history: ${s.id}`))}catch(n){let a=n instanceof Error?n.message:String(n);console.error(u.default.red(`
115
- \u2717 Failed to remove history: ${a}`)),process.exit(1)}break}case"remove-all":{if((await o.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(`
112
+ \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(u.default.red(`
113
+ \u2717 Invalid choice`)),process.exit(1));try{await t.removeHistory(o.id),console.log(u.default.green(`
114
+ \u2713 Removed history: ${o.id}`))}catch(n){let a=n instanceof Error?n.message:String(n);console.error(u.default.red(`
115
+ \u2717 Failed to remove history: ${a}`)),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(`
116
116
  \u2717 Cancelled`));return}try{await t.clearAllHistories(),console.log(u.default.green(`
117
- \u2713 All histories removed`))}catch(s){let n=s instanceof Error?s.message:String(s);console.error(u.default.red(`
117
+ \u2713 All histories removed`))}catch(o){let n=o instanceof Error?o.message:String(o);console.error(u.default.red(`
118
118
  \u2717 Failed to remove histories: ${n}`)),process.exit(1)}break}default:console.error(u.default.red(`
119
- \u2717 Unknown action: ${e.id}`)),process.exit(1)}});function Fe(o){return o.split("/").pop()??o}function We(o,e){console.log(`
120
- `);let t=o.records.reduce((c,m)=>c+m.duration,0),r=o.records.filter(c=>c.status==="success").length,s=o.records.filter(c=>c.status==="failure").length,n=(0,be.default)(o.initialTimestamp).format("YYYY-MM-DD HH:mm:ss"),i=(t/1e3).toFixed(2),p=[u.default.bold("Workflow Execution History"),"",`${u.default.cyan("File:")} ${e}`,`${u.default.cyan("Started:")} ${n}`,`${u.default.cyan("Total Duration:")} ${i}s`,`${u.default.cyan("Total Steps:")} ${o.records.length}`,`${u.default.green("\u2713 Successful:")} ${r}`,s>0?`${u.default.red("\u2717 Failed:")} ${s}`:""].filter(Boolean).join(`
121
- `);console.log((0,re.default)(p,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderColor:"cyan"})),o.records.forEach((c,m)=>{He(c,m+1,o.records.length)}),console.log("")}function He(o,e,t){let r=Oe(o.step),s=Ve(o.step),n=o.status==="success"?u.default.green("\u2713"):u.default.red("\u2717"),a=o.status==="success"?u.default.green("Success"):u.default.red("Failed"),i=`${(o.duration/1e3).toFixed(2)}s`,p=[`${n} ${u.default.bold(`Step ${e}/${t}`)} - ${u.default.cyan(r)}`,`${u.default.gray("Duration:")} ${i} | ${u.default.gray("Status:")} ${a}`,"",u.default.white(s)].join(`
122
- `);console.log((0,re.default)(p,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderColor:o.status==="success"?"green":"red"})),_e(o.output)&&Ye(o.output)}function Oe(o){return"run"in o?"Run":"choose"in o?"Choose":"prompt"in o?"Prompt":"parallel"in o?"Parallel":"fail"in o?"Fail":"Unknown"}function Ve(o){return"run"in o?`Command: ${u.default.yellow(o.run)}`:"choose"in o?`Message: ${u.default.yellow(o.choose.message)}`:"prompt"in o?`Message: ${u.default.yellow(o.prompt.message)} | Variable: ${u.default.cyan(o.prompt.as)}`:"parallel"in o?`Parallel execution with ${o.parallel.length} branches`:"fail"in o?`Error: ${u.default.red(o.fail.message)}`:"Unknown step type"}function _e(o){return typeof o=="object"&&o!==null&&"success"in o&&"stdout"in o&&"stderr"in o}function Ye(o){if(o.stdout.length>0){let e=o.stdout.map(t=>u.default.gray(` ${t}`)).join(`
123
- `);console.log(u.default.green(" Output:")),console.log(e)}if(o.stderr.length>0){let e=o.stderr.map(t=>u.default.gray(` ${t}`)).join(`
119
+ \u2717 Unknown action: ${e.id}`)),process.exit(1)}});function We(s){return s.split("/").pop()??s}function He(s,e){console.log(`
120
+ `);let t=s.records.reduce((c,m)=>c+m.duration,0),r=s.records.filter(c=>c.status==="success").length,o=s.records.filter(c=>c.status==="failure").length,n=(0,ye.default)(s.initialTimestamp).format("YYYY-MM-DD HH:mm:ss"),i=(t/1e3).toFixed(2),p=[u.default.bold("Workflow Execution History"),"",`${u.default.cyan("File:")} ${e}`,`${u.default.cyan("Started:")} ${n}`,`${u.default.cyan("Total Duration:")} ${i}s`,`${u.default.cyan("Total Steps:")} ${s.records.length}`,`${u.default.green("\u2713 Successful:")} ${r}`,o>0?`${u.default.red("\u2717 Failed:")} ${o}`:""].filter(Boolean).join(`
121
+ `);console.log((0,re.default)(p,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderColor:"cyan"})),s.records.forEach((c,m)=>{Oe(c,m+1,s.records.length)}),console.log("")}function Oe(s,e,t){let r=Ve(s.step),o=_e(s.step),n=s.status==="success"?u.default.green("\u2713"):u.default.red("\u2717"),a=s.status==="success"?u.default.green("Success"):u.default.red("Failed"),i=`${(s.duration/1e3).toFixed(2)}s`,p=[`${n} ${u.default.bold(`Step ${e}/${t}`)} - ${u.default.cyan(r)}`,`${u.default.gray("Duration:")} ${i} | ${u.default.gray("Status:")} ${a}`,"",u.default.white(o)].join(`
122
+ `);console.log((0,re.default)(p,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderColor:s.status==="success"?"green":"red"})),Ye(s.output)&&Je(s.output)}function Ve(s){return"run"in s?"Run":"choose"in s?"Choose":"prompt"in s?"Prompt":"parallel"in s?"Parallel":"fail"in s?"Fail":"Unknown"}function _e(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 Ye(s){return typeof s=="object"&&s!==null&&"success"in s&&"stdout"in s&&"stderr"in s}function Je(s){if(s.stdout.length>0){let e=s.stdout.map(t=>u.default.gray(` ${t}`)).join(`
123
+ `);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(`
124
124
  `);console.log(u.default.red(" Errors:")),console.log(e)}}j.parse();
package/dist/index.js CHANGED
@@ -1,22 +1,22 @@
1
1
  #!/usr/bin/env node
2
- import{exec as Me}from"child_process";import{readFileSync as Ie}from"fs";import{resolve as Ne}from"path";import{promisify as Ae}from"util";import ne from"boxen";import u from"chalk";import{Command as Be}from"commander";import Te from"dayjs";import{resolve as te,isAbsolute as ge,dirname as we}from"path";import U from"log-update";import X from"chalk";import q from"inquirer";var $=class{async prompt(e,t){let{choice:r}=await q.prompt([{type:"list",name:"choice",message:X.cyan(e),choices:t.map(o=>({name:o.label,value:o.id}))}]),n=t.find(o=>o.id===r);if(!n)throw new Error(`Invalid choice: ${r}`);return n}},N=class{async prompt(e,t){let{value:r}=await q.prompt([{type:"input",name:"value",message:X.cyan(e),default:t}]);return r}};import _ from"boxen";import A from"chalk";function Y(s,e,t,r={}){let{borderColor:n="cyan",isNested:o=!1}=r,a;e!==void 0&&(t?a=`line ${e} in ${t}`:a=`line ${e}`);let i=o?`\u2502 ${s}`:`> ${s}`;return _(i,{title:a,borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0},borderColor:n})}function B(s,e=!1){let t=s?"\u2713 Completed":"\u2717 Failed";return s?A.green(t):A.red(t)}function M(s){return _(`\u2717 ${s}`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0},borderColor:"red"})}function K(s){return _(`> Starting parallel execution (${s} branches)`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0},borderColor:"yellow"})}function Q(s){let e=s?"\u2713 All parallel branches completed":"\u2717 Some parallel branches failed";return s?A.green(e):A.red(e)}function J(s,e=!1){return`${e?"| \u2502 ":"\u2502 "}${s}`}import{existsSync as ae}from"fs";import{resolve as ie}from"path";var R=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),a=this.workspace.getFact(r),i=o??(a!==void 0?a.toString():void 0);if(i===void 0||i!==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=ie(process.cwd(),t);return ae(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)}};import{mkdir as le,readdir as ce,readFile as ue,rm as ee,writeFile as pe}from"fs/promises";import{homedir as me}from"os";import{basename as de,join as T}from"path";import fe from"dayjs";var E=T(me(),".pipeliner","workflow-history"),P=class{constructor(){}async saveHistory(e){await le(E,{recursive:!0});let t=fe().format("YYYY-MM-DD_HH-mm-ss"),r=Math.random().toString(36).slice(2,6),n=T(E,`workflow-${t}-${r}.json`);return await pe(n,JSON.stringify(e,null,2),{encoding:"utf8"}),n}async clearAllHistories(){await ee(E,{recursive:!0,force:!0})}async removeHistory(e){await ee(T(E,e),{force:!0})}async getHistoryNames(){try{let t=(await ce(E)).map(r=>de(r));return t.sort((r,n)=>{let o=p=>{let c=p.match(/workflow-(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-/);return c?c[1]:""},a=o(r),i=o(n);return a===i?n.localeCompare(r):i.localeCompare(a)}),t}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return[];throw e}}async getHistory(e){let t=await ue(T(E,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();this.records.push({step:e,context:t,output:r,duration:o,status:n})}reset(){this.records=[],this.initialTimestamp=Date.now()}async save(){let e=new P,t={initialTimestamp:this.initialTimestamp,records:this.records};return await e.saveHistory(t)}getDuration(){return Date.now()-this.recordStartTimestamp}};var D=class{async run(e,t,r,n,o=!1,a=!1,i,p,c,m){return o?this.runBuffered(e,c,m):this.runRealtime(e,r||e,a,i,p,c,m)}async runBuffered(e,t,r){let{spawn:n}=await import("child_process"),[o,...a]=this.parseCommand(e),i=this.createSpawnOptions(t);return new Promise((p,c)=>{let m=n(o,a,i),h=[],d=[],f="",g="",b=null;r&&r>0&&(b=setTimeout(()=>{m.kill("SIGTERM");let w=`Command timed out after ${r} seconds`;d.push(w),p({success:!1,stdout:h,stderr:d})},r*1e3)),m.stdout?.on("data",w=>{let x=w.toString(),{lines:v,remaining:y}=this.processStreamBuffer(x,f);h.push(...v),f=y}),m.stderr?.on("data",w=>{let x=w.toString(),{lines:v,remaining:y}=this.processStreamBuffer(x,g);d.push(...v),g=y}),m.on("close",w=>{b&&clearTimeout(b),f.trim()&&h.push(f),g.trim()&&d.push(g),p({success:w===0,stdout:h,stderr:d})}),m.on("error",w=>{b&&clearTimeout(b);let x=`Error: ${w.message}`;p({success:!1,stdout:h,stderr:[...d,x]})})})}async runRealtime(e,t,r,n,o,a,i){let{spawn:p}=await import("child_process"),[c,...m]=this.parseCommand(e),h=this.createSpawnOptions(a),f=Y(t,n,o,{borderColor:r?"green":"cyan"});return console.log(f),new Promise(g=>{let b=p(c,m,h),w="",x="",v=null;i&&i>0&&(v=setTimeout(()=>{b.kill("SIGTERM");let y=`Command timed out after ${i} seconds`,S=M(y);console.error(S);let C=B(!1);console.log(C),g(!1)},i*1e3)),b.stdout?.on("data",y=>{let S=y.toString(),{lines:C,remaining:O}=this.processStreamBuffer(S,w);C.forEach(V=>process.stdout.write(`\u2502 ${V}
3
- `)),w=O}),b.stderr?.on("data",y=>{let S=y.toString(),{lines:C,remaining:O}=this.processStreamBuffer(S,x);C.forEach(V=>process.stderr.write(`\u2502 ${V}
4
- `)),x=O}),b.on("close",y=>{v&&clearTimeout(v),w.trim()&&process.stdout.write(`\u2502 ${w}
2
+ import{exec as Ne}from"child_process";import{readFileSync as Ie}from"fs";import{resolve as Te}from"path";import{promisify as Ae}from"util";import ae from"boxen";import u from"chalk";import{Command as Be}from"commander";import je from"dayjs";import{resolve as te,isAbsolute as we,dirname as be}from"path";import z from"log-update";import X from"chalk";import q from"inquirer";var C=class{async prompt(e,t){let{choice:r}=await q.prompt([{type:"list",name:"choice",message:X.cyan(e),choices:t.map(o=>({name:o.label,value:o.id}))}]),n=t.find(o=>o.id===r);if(!n)throw new Error(`Invalid choice: ${r}`);return n}},I=class{async prompt(e,t){let{value:r}=await q.prompt([{type:"input",name:"value",message:X.cyan(e),default:t}]);return r}};import _ from"boxen";import T from"chalk";function Y(s,e,t,r={}){let{borderColor:n="cyan",isNested:o=!1}=r,a;e!==void 0&&(t?a=`line ${e} in ${t}`:a=`line ${e}`);let i=o?`\u2502 ${s}`:`> ${s}`;return _(i,{title:a,borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0},borderColor:n})}function A(s,e=!1){let t=s?"\u2713 Completed":"\u2717 Failed";return s?T.green(t):T.red(t)}function M(s){return _(`\u2717 ${s}`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0},borderColor:"red"})}function K(s){return _(`> Starting parallel execution (${s} branches)`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0},borderColor:"yellow"})}function Q(s){let e=s?"\u2713 All parallel branches completed":"\u2717 Some parallel branches failed";return s?T.green(e):T.red(e)}function J(s,e=!1){return`${e?"| \u2502 ":"\u2502 "}${s}`}import{existsSync as ie}from"fs";import{resolve as le}from"path";var E=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),a=this.workspace.getFact(r),i=o??(a!==void 0?a.toString():void 0);if(i===void 0||i!==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=le(process.cwd(),t);return ie(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)}};import{mkdir as ce,readdir as ue,readFile as pe,rm as ee,writeFile as me}from"fs/promises";import{homedir as de}from"os";import{basename as fe,join as B}from"path";import he from"dayjs";var $=B(de(),".pipeliner","workflow-history"),P=class{constructor(){}async saveHistory(e){await ce($,{recursive:!0});let t=he().format("YYYY-MM-DD_HH-mm-ss"),r=Math.random().toString(36).slice(2,6),n=B($,`workflow-${t}-${r}.json`);return await me(n,JSON.stringify(e,null,2),{encoding:"utf8"}),n}async clearAllHistories(){await ee($,{recursive:!0,force:!0})}async removeHistory(e){await ee(B($,e),{force:!0})}async getHistoryNames(){try{let t=(await ue($)).map(r=>fe(r));return t.sort((r,n)=>{let o=p=>{let c=p.match(/workflow-(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-/);return c?c[1]:""},a=o(r),i=o(n);return a===i?n.localeCompare(r):i.localeCompare(a)}),t}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return[];throw e}}async getHistory(e){let t=await pe(B($,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();this.records.push({step:e,context:t,output:r,duration:o,status:n})}reset(){this.records=[],this.initialTimestamp=Date.now()}async save(){let e=new P,t={initialTimestamp:this.initialTimestamp,records:this.records};return await e.saveHistory(t)}getDuration(){return Date.now()-this.recordStartTimestamp}};var D=class{async run(e,t,r,n,o=!1,a=!1,i,p,c,m){return o?this.runBuffered(e,c,m):this.runRealtime(e,r||e,a,i,p,c,m)}async runBuffered(e,t,r){let{spawn:n}=await import("child_process"),[o,...a]=this.parseCommand(e),i=this.createSpawnOptions(t);return new Promise((p,c)=>{let m=n(o,a,i),h=[],d=[],f="",g="",y=null;r&&r>0&&(y=setTimeout(()=>{m.kill("SIGTERM");let w=`Command timed out after ${r} seconds`;d.push(w),p({success:!1,stdout:h,stderr:d})},r*1e3)),m.stdout?.on("data",w=>{let x=w.toString(),{lines:v,remaining:b}=this.processStreamBuffer(x,f);h.push(...v),f=b}),m.stderr?.on("data",w=>{let x=w.toString(),{lines:v,remaining:b}=this.processStreamBuffer(x,g);d.push(...v),g=b}),m.on("close",w=>{y&&clearTimeout(y),f.trim()&&h.push(f),g.trim()&&d.push(g),p({success:w===0,stdout:h,stderr:d})}),m.on("error",w=>{y&&clearTimeout(y);let x=`Error: ${w.message}`;p({success:!1,stdout:h,stderr:[...d,x]})})})}async runRealtime(e,t,r,n,o,a,i){let{spawn:p}=await import("child_process"),[c,...m]=this.parseCommand(e),h=this.createSpawnOptions(a),f=Y(t,n,o,{borderColor:r?"green":"cyan"});return console.log(f),new Promise(g=>{let y=p(c,m,h),w="",x="",v=null;i&&i>0&&(v=setTimeout(()=>{y.kill("SIGTERM");let b=`Command timed out after ${i} seconds`,S=M(b);console.error(S);let R=A(!1);console.log(R),g(!1)},i*1e3)),y.stdout?.on("data",b=>{let S=b.toString(),{lines:R,remaining:O}=this.processStreamBuffer(S,w);R.forEach(V=>process.stdout.write(`\u2502 ${V}
3
+ `)),w=O}),y.stderr?.on("data",b=>{let S=b.toString(),{lines:R,remaining:O}=this.processStreamBuffer(S,x);R.forEach(V=>process.stderr.write(`\u2502 ${V}
4
+ `)),x=O}),y.on("close",b=>{v&&clearTimeout(v),w.trim()&&process.stdout.write(`\u2502 ${w}
5
5
  `),x.trim()&&process.stderr.write(`\u2502 ${x}
6
- `);let S=y===0,C=B(S);console.log(C),g(S)}),b.on("error",y=>{v&&clearTimeout(v);let S=M(`Error: ${y.message}`);console.error(S),g(!1)})})}parseCommand(e){let t=e.split(" ");return[t[0],...t.slice(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(`
6
+ `);let S=b===0,R=A(S);console.log(R),g(S)}),y.on("error",b=>{v&&clearTimeout(v);let S=M(`Error: ${b.message}`);console.error(S),g(!1)})})}parseCommand(e){let t=e.split(" ");return[t[0],...t.slice(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(`
7
7
  `);){let a=o.indexOf(`
8
8
  `),i=o.substring(0,a);o=o.substring(a+1),n.push(i)}return{lines:n,remaining:o}}formatNestedOutput(e,t){t?e.split(`
9
9
  `).forEach(r=>{r.trim()&&console.log(`| ${r}`)}):console.log(e)}displayBufferedOutput(e,t,r=!1,n,o){let a=Y(t,n,o,{borderColor:"cyan",isNested:r});this.formatNestedOutput(a,r),e.stdout.forEach(p=>{let c=J(p,r);process.stdout.write(`${c}
10
10
  `)}),e.stderr.forEach(p=>{let c=J(p,r);process.stderr.write(`${c}
11
- `)});let i=B(e.success,r);console.log(i)}};function he(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 L(s,e){let t=/\{\{(\w+)\}\}/g;return s.replace(t,(r,n)=>he(n,e,r))}var F=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 W=class s{static PARALLEL_STEP_INDEX_MULTIPLIER=1e3;workspace;taskRunner;choicePrompt;textPrompt;baseDir;constructor(){this.workspace=new F,this.taskRunner=new D,this.choicePrompt=new $,this.textPrompt=new N}resolveBaseDir(e){if(e.baseDir)if(ge(e.baseDir))this.baseDir=e.baseDir;else if(e._filePath){let t=we(e._filePath);this.baseDir=te(t,e.baseDir)}else this.baseDir=te(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 R(this.workspace).evaluate(e.when):!0}calculateBaseStepIndex(e){return e.branchIndex===void 0?e.stepIndex:Math.floor(e.stepIndex/s.PARALLEL_STEP_INDEX_MULTIPLIER)}async execute(e){this.resolveBaseDir(e);let t=new j;for(let r=0;r<e.steps.length;r++){let n=e.steps[r],o=this.createStepContext(r,e),a=!!n.when;if(this.evaluateStepCondition(n)){t.recordStart();try{let i=await this.executeStep(n,o,!1,a);if(!this.isStepSuccessful(i,n)){let p=o.lineNumber?` (line ${o.lineNumber})`:"";throw new Error(`Step ${r}${p} failed`)}t.recordEnd(n,o,i,"success")}catch(i){this.workspace.setStepResult(r,!1);let p=i instanceof Error?i.message:String(i),c={success:!1,stdout:[],stderr:[p]};throw t.recordEnd(n,o,c,"failure"),i}}}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}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 executeRunStep(e,t,r=!1,n=!1){let o=this.calculateBaseStepIndex(t),a=L(e.run,this.workspace),i=e.retry??0,p=e.timeout,c=!1,m=0;for(;m<=i;){let d=await this.taskRunner.run(a,o,a,t.branchIndex,r,n,t.lineNumber,t.fileName,this.baseDir,p),f=typeof d=="boolean"?d:d.success;if(c=d,f||m>=i)break;if(m++,m<=i){let g=Math.min(1e3*Math.pow(2,m-1),1e4);await new Promise(b=>setTimeout(b,g))}}let h=typeof c=="boolean"?c:c.success;return this.workspace.setStepResult(t.stepIndex,h),c}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=L(e.prompt.message,this.workspace),n=e.prompt.default?L(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 c=0;c<e.length;c++){let m=e[c],h=t[c];if(m.when&&!new R(h.workspace).evaluate(m.when))continue;let d=this.getBranchDisplayName(m,c);r.push({index:c,name:d,status:"pending"})}let a=setInterval(()=>{o=(o+1)%n.length,this.updateParallelBranchesDisplay(r,n[o])},100),i=r.map(async c=>{let{index:m}=c,h=e[m],d=t[m];c.status="running";try{let f=await this.executeStep(h,d,!0);return c.status="success",this.updateParallelBranchesDisplay(r,n[o]),{index:m,result:f,context:d}}catch(f){d.workspace.setStepResult(d.stepIndex,!1);let g=f instanceof Error?f.message:String(f);return c.status="failed",c.error=g,this.updateParallelBranchesDisplay(r,n[o]),{index:m,error:f,context:d}}}),p=await Promise.all(i);return clearInterval(a),this.updateParallelBranchesDisplay(r,"",!0),U.done(),p}updateParallelBranchesDisplay(e,t,r=!1){let n=e.map(o=>{let a=o.index+1,i="",p="";switch(o.status){case"pending":i="\u25CB",p=`Branch ${a}: ${o.name} - Pending`;break;case"running":i=t,p=`Branch ${a}: ${o.name} - Running...`;break;case"success":i="\u2713",p=`Branch ${a}: ${o.name} - Completed`;break;case"failed":i="\u2717",p=`Branch ${a}: ${o.name} - Failed${o.error?`: ${o.error}`:""}`;break}return`${i} ${p}`});r?U(n.join(`
12
- `)):U(n.join(`
13
- `))}displayParallelResults(e,t,r){let n=!0,o=!1;console.log("");for(let i of e){if(!i)continue;o=!0;let{index:p,result:c,error:m,context:h}=i;if(m){n=!1;let d=`Branch ${p+1} failed: ${m instanceof Error?m.message:String(m)}`,f=M(d);console.error(f)}else if(c&&typeof c=="object"&&"stdout"in c){let d=c;if(n=n&&d.success,d.stdout.length>0||d.stderr.length>0||!d.success){let f=t[p],g=this.getBranchDisplayName(f,p);this.taskRunner.displayBufferedOutput(d,g,!1,h.lineNumber,h.fileName)}}}o||console.log("\u26A0\uFE0F All parallel branches were skipped (conditions not met)");let a=Q(n);return console.log(a),n}mergeParallelResults(e){for(let t of e){let r=t.workspace.getAllFacts(),n=t.workspace.getAllVariables();for(let[o,a]of r)this.workspace.setFact(o,a);for(let[o,a]of n)this.workspace.setVariable(o,a)}}countExecutableBranches(e,t){let r=0;for(let n=0;n<e.length;n++){let o=e[n],a=t[n];o.when&&!new R(a.workspace).evaluate(o.when)||r++}return r}async executeParallelStep(e,t){let r=this.createParallelContexts(e,t),n=this.countExecutableBranches(e.parallel,r),o=K(n);console.log(o);let a=await this.executeParallelBranches(e.parallel,r),i=this.displayParallelResults(a,e.parallel,t);if(this.workspace.setStepResult(t.stepIndex,i),!i){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}};import{parse as Pe}from"yaml";import{ZodError as oe}from"zod";import{z as l}from"zod";var be=l.object({file:l.string()}),ye=l.object({var:l.union([l.string(),l.record(l.string(),l.string())]).optional(),has:l.string().optional()}),xe=l.object({status:l.object({fact:l.string(),is:l.enum(["ready","failed","pending"])})}),Se=l.object({step:l.object({success:l.boolean()}).optional(),last_step:l.enum(["success","failure"]).optional()}),ve=l.object({choice:l.string()}),ke=l.union([be,ve,ye,xe,Se]),k=l.lazy(()=>l.union([ke,l.object({all:l.array(k)}),l.object({any:l.array(k)}),l.object({not:k})])),Ce=l.object({run:l.string(),when:k.optional(),timeout:l.number().optional(),retry:l.number().optional()}),$e=l.object({choose:l.object({message:l.string(),options:l.array(l.object({id:l.string(),label:l.string()})),as:l.string().optional()}),when:k.optional()}),Re=l.object({prompt:l.object({message:l.string(),as:l.string(),default:l.string().optional(),validate:l.string().optional()}),when:k.optional()}),re=l.lazy(()=>l.union([Ce,$e,Re,l.object({parallel:l.array(re),when:k.optional()}),l.object({fail:l.object({message:l.string()}),when:k.optional()})])),Ee=l.object({name:l.string().optional(),baseDir:l.string().optional(),steps:l.array(re).min(1,"Workflow must have at least one step")});function z(s){return Ee.parse(s)}function G(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=>G(t))}:s}var H=class{parse(e){let t;try{t=Pe(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=>G(n)))}try{return z(t)}catch(r){if(r instanceof oe){let n=r.issues.map(o=>{let a=o.path.length>0?` at ${o.path.join(".")}`:"";return` - ${o.message}${a}`}).join(`
11
+ `)});let i=A(e.success,r);console.log(i)}};function ge(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 L(s,e){let t=/\{\{(\w+)\}\}/g;return s.replace(t,(r,n)=>ge(n,e,r))}var F=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 W=class s{static PARALLEL_STEP_INDEX_MULTIPLIER=1e3;workspace;taskRunner;choicePrompt;textPrompt;baseDir;constructor(){this.workspace=new F,this.taskRunner=new D,this.choicePrompt=new C,this.textPrompt=new I}resolveBaseDir(e){if(e.baseDir)if(we(e.baseDir))this.baseDir=e.baseDir;else if(e._filePath){let t=be(e._filePath);this.baseDir=te(t,e.baseDir)}else this.baseDir=te(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 E(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;for(let r=0;r<e.steps.length;r++){let n=e.steps[r],o=this.createStepContext(r,e),a=!!n.when;if(this.evaluateStepCondition(n)){t.recordStart();try{let i=await this.executeStep(n,o,!1,a);this.handleStepResult(n,o,r,i,t)}catch(i){throw this.handleStepError(n,o,r,i,t),i}}}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 a=this.isStepSuccessful(n,e);if(this.isRunStep(e)&&!a){if(!(e.onError?.continue===!0)){let c=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Step ${r}${c} failed`)}o.recordEnd(e,t,n,"failure");return}let i=a?"success":"failure";o.recordEnd(e,t,n,i)}handleStepError(e,t,r,n,o){this.workspace.setStepResult(r,!1);let a=n instanceof Error?n.message:String(n),i={success:!1,stdout:[],stderr:[a]};o.recordEnd(e,t,i,"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),a=L(e.run,this.workspace),i=e.retry??0,p=e.timeout,c=!1,m=0;for(;m<=i;){let h=await this.taskRunner.run(a,o,a,t.branchIndex,r,n,t.lineNumber,t.fileName,this.baseDir,p),d=typeof h=="boolean"?h:h.success;if(c=h,d||m>=i)break;if(m++,m<=i){let f=Math.min(1e3*Math.pow(2,m-1),1e4);await new Promise(g=>setTimeout(g,f))}}return c}async executeRunStep(e,t,r=!1,n=!1){let o={run:e.run,timeout:e.timeout,retry:e.retry,onError:e.onError??void 0},a=await this.executeRunChain(o,t,r,n),i=typeof a=="boolean"?a:a.success;return this.workspace.setStepResult(t.stepIndex,i),a}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=L(e.prompt.message,this.workspace),n=e.prompt.default?L(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 c=0;c<e.length;c++){let m=e[c],h=t[c];if(m.when&&!new E(h.workspace).evaluate(m.when))continue;let d=this.getBranchDisplayName(m,c);r.push({index:c,name:d,status:"pending"})}let a=setInterval(()=>{o=(o+1)%n.length,this.updateParallelBranchesDisplay(r,n[o])},100),i=r.map(async c=>{let{index:m}=c,h=e[m],d=t[m];c.status="running";try{let f=await this.executeStep(h,d,!0);return c.status="success",this.updateParallelBranchesDisplay(r,n[o]),{index:m,result:f,context:d}}catch(f){d.workspace.setStepResult(d.stepIndex,!1);let g=f instanceof Error?f.message:String(f);return c.status="failed",c.error=g,this.updateParallelBranchesDisplay(r,n[o]),{index:m,error:f,context:d}}}),p=await Promise.all(i);return clearInterval(a),this.updateParallelBranchesDisplay(r,"",!0),z.done(),p}updateParallelBranchesDisplay(e,t,r=!1){let n=e.map(o=>{let a=o.index+1,i="",p="";switch(o.status){case"pending":i="\u25CB",p=`Branch ${a}: ${o.name} - Pending`;break;case"running":i=t,p=`Branch ${a}: ${o.name} - Running...`;break;case"success":i="\u2713",p=`Branch ${a}: ${o.name} - Completed`;break;case"failed":i="\u2717",p=`Branch ${a}: ${o.name} - Failed${o.error?`: ${o.error}`:""}`;break}return`${i} ${p}`});r?z(n.join(`
12
+ `)):z(n.join(`
13
+ `))}displayParallelResults(e,t,r){let n=!0,o=!1;console.log("");for(let i of e){if(!i)continue;o=!0;let{index:p,result:c,error:m,context:h}=i;if(m){n=!1;let d=`Branch ${p+1} failed: ${m instanceof Error?m.message:String(m)}`,f=M(d);console.error(f)}else if(c&&typeof c=="object"&&"stdout"in c){let d=c;if(n=n&&d.success,d.stdout.length>0||d.stderr.length>0||!d.success){let f=t[p],g=this.getBranchDisplayName(f,p);this.taskRunner.displayBufferedOutput(d,g,!1,h.lineNumber,h.fileName)}}}o||console.log("\u26A0\uFE0F All parallel branches were skipped (conditions not met)");let a=Q(n);return console.log(a),n}mergeParallelResults(e){for(let t of e){let r=t.workspace.getAllFacts(),n=t.workspace.getAllVariables();for(let[o,a]of r)this.workspace.setFact(o,a);for(let[o,a]of n)this.workspace.setVariable(o,a)}}countExecutableBranches(e,t){let r=0;for(let n=0;n<e.length;n++){let o=e[n],a=t[n];o.when&&!new E(a.workspace).evaluate(o.when)||r++}return r}async executeParallelStep(e,t){let r=this.createParallelContexts(e,t),n=this.countExecutableBranches(e.parallel,r),o=K(n);console.log(o);let a=await this.executeParallelBranches(e.parallel,r),i=this.displayParallelResults(a,e.parallel,t);if(this.workspace.setStepResult(t.stepIndex,i),!i){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}};import{parse as Me}from"yaml";import{ZodError as ne}from"zod";import{z as l}from"zod";var ye=l.object({file:l.string()}),xe=l.object({var:l.union([l.string(),l.record(l.string(),l.string())]).optional(),has:l.string().optional()}),Se=l.object({status:l.object({fact:l.string(),is:l.enum(["ready","failed","pending"])})}),ve=l.object({step:l.object({success:l.boolean()}).optional(),last_step:l.enum(["success","failure"]).optional()}),ke=l.object({choice:l.string()}),Re=l.union([ye,ke,xe,Se,ve]),k=l.lazy(()=>l.union([Re,l.object({all:l.array(k)}),l.object({any:l.array(k)}),l.object({not:k})])),re=l.lazy(()=>l.object({run:l.string(),timeout:l.number().optional(),retry:l.number().optional(),continue:l.boolean().optional(),onError:re.optional()})),Ce=l.object({run:l.string(),when:k.optional(),timeout:l.number().optional(),retry:l.number().optional(),onError:re.optional()}),Ee=l.object({choose:l.object({message:l.string(),options:l.array(l.object({id:l.string(),label:l.string()})),as:l.string().optional()}),when:k.optional()}),$e=l.object({prompt:l.object({message:l.string(),as:l.string(),default:l.string().optional(),validate:l.string().optional()}),when:k.optional()}),oe=l.lazy(()=>l.union([Ce,Ee,$e,l.object({parallel:l.array(oe),when:k.optional()}),l.object({fail:l.object({message:l.string()}),when:k.optional()})])),Pe=l.object({name:l.string().optional(),baseDir:l.string().optional(),steps:l.array(oe).min(1,"Workflow must have at least one step")});function U(s){return Pe.parse(s)}function G(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=>G(t))}:s}var H=class{parse(e){let t;try{t=Me(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=>G(n)))}try{return U(t)}catch(r){if(r instanceof ne){let n=r.issues.map(o=>{let a=o.path.length>0?` at ${o.path.join(".")}`:"";return` - ${o.message}${a}`}).join(`
14
14
  `);throw new Error(`Invalid workflow structure:
15
15
  ${n}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
16
- `),n=0,o=!1;for(let a=0;a<r.length;a++){let i=r[a].trim();if(i==="steps:"||i.startsWith("steps:")){o=!0;continue}o&&i.startsWith("-")&&t.set(n++,a+1)}return t}},Z=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=>G(n)))}try{return z(t)}catch(r){if(r instanceof oe){let n=r.issues.map(o=>{let a=o.path.length>0?` at ${o.path.join(".")}`:"";return` - ${o.message}${a}`}).join(`
16
+ `),n=0,o=!1;for(let a=0;a<r.length;a++){let i=r[a].trim();if(i==="steps:"||i.startsWith("steps:")){o=!0;continue}o&&i.startsWith("-")&&t.set(n++,a+1)}return t}},Z=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=>G(n)))}try{return U(t)}catch(r){if(r instanceof ne){let n=r.issues.map(o=>{let a=o.path.length>0?` at ${o.path.join(".")}`:"";return` - ${o.message}${a}`}).join(`
17
17
  `);throw new Error(`Invalid workflow structure:
18
18
  ${n}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
19
- `),n=0,o=!1,a=!1;for(let i=0;i<r.length;i++){let c=r[i].trim();if(c.startsWith('"steps"')||c.startsWith("'steps'")){o=!0,c.includes("[")&&(a=!0);continue}if(o&&c==="["){a=!0;continue}if(a&&c==="]"){a=!1,o=!1;continue}a&&c.startsWith("{")&&t.set(n++,i+1)}return t}};function se(s){switch(s.toLowerCase().split(".").pop()){case"yaml":case"yml":return new H;case"json":return new Z;default:return new H}}var je=Ae(Me),I=new Be;I.name("task-pipeliner").description(`A powerful task pipeline runner with condition-based workflow execution.
19
+ `),n=0,o=!1,a=!1;for(let i=0;i<r.length;i++){let c=r[i].trim();if(c.startsWith('"steps"')||c.startsWith("'steps'")){o=!0,c.includes("[")&&(a=!0);continue}if(o&&c==="["){a=!0;continue}if(a&&c==="]"){a=!1,o=!1;continue}a&&c.startsWith("{")&&t.set(n++,i+1)}return t}};function se(s){switch(s.toLowerCase().split(".").pop()){case"yaml":case"yml":return new H;case"json":return new Z;default:return new H}}var De=Ae(Ne),N=new Be;N.name("task-pipeliner").description(`A powerful task pipeline runner with condition-based workflow execution.
20
20
 
21
21
  Define workflows in YAML or JSON files with conditional execution, parallel tasks,
22
22
  interactive prompts, and variable substitution.
@@ -67,7 +67,7 @@ Resources:
67
67
  \u{1F4DA} Documentation: https://task-pipeliner.racgoo.com/
68
68
  \u{1F3A8} Visual Generator: https://task-pipeliner-generator.racgoo.com/
69
69
 
70
- See README.md for complete DSL reference.`);I.command("run").description("Run a workflow from a YAML or JSON file").argument("<file>","Path to the workflow file (YAML or JSON, relative or absolute)").addHelpText("after",`
70
+ See README.md for complete DSL reference.`);N.command("run").description("Run a workflow from a YAML or JSON file").argument("<file>","Path to the workflow file (YAML or JSON, relative or absolute)").addHelpText("after",`
71
71
  Examples:
72
72
  $ tp run workflow.yaml
73
73
  $ tp run workflow.json
@@ -89,10 +89,10 @@ Workflow File Structure:
89
89
  \u2022 all/any/not: Combine conditions
90
90
 
91
91
  Supported formats: YAML (.yaml, .yml) and JSON (.json)
92
- See README.md for complete DSL documentation.`).action(async s=>{try{let e=se(s);console.log(u.blue(`Loading workflow from ${s}...`));let t=Ie(s,"utf-8"),r=e.parse(t);if(!r.steps||!Array.isArray(r.steps))throw new Error("Invalid workflow: steps array is required");r._lineNumbers=e.extractStepLineNumbers(t),r._fileName=Le(s),r._filePath=Ne(s),console.log(u.green(`Starting workflow execution...
92
+ See README.md for complete DSL documentation.`).action(async s=>{try{let e=se(s);console.log(u.blue(`Loading workflow from ${s}...`));let t=Ie(s,"utf-8"),r=e.parse(t);if(!r.steps||!Array.isArray(r.steps))throw new Error("Invalid workflow: steps array is required");r._lineNumbers=e.extractStepLineNumbers(t),r._fileName=Fe(s),r._filePath=Te(s),console.log(u.green(`Starting workflow execution...
93
93
  `)),await new W().execute(r),console.log(u.green(`
94
94
  \u2713 Workflow completed successfully`))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(u.red(`
95
- \u2717 Workflow failed: ${t}`)),process.exit(1)}});I.command("open").description("Open generator or docs website in browser").argument("<target>",'Target to open: "generator" or "docs"').addHelpText("after",`
95
+ \u2717 Workflow failed: ${t}`)),process.exit(1)}});N.command("open").description("Open generator or docs website in browser").argument("<target>",'Target to open: "generator" or "docs"').addHelpText("after",`
96
96
  Examples:
97
97
  $ tp open generator
98
98
  $ tp open docs
@@ -101,13 +101,13 @@ Targets:
101
101
  generator Open the visual workflow generator (https://task-pipeliner-generator.racgoo.com/)
102
102
  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.red(`
103
103
  \u2717 Invalid target: ${s}`)),console.log(u.yellow(`
104
- Valid targets:`)),console.log(u.yellow(" \u2022 generator - Open the visual workflow generator")),console.log(u.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 je(n),console.log(u.green(`
104
+ Valid targets:`)),console.log(u.yellow(" \u2022 generator - Open the visual workflow generator")),console.log(u.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 De(n),console.log(u.green(`
105
105
  \u2713 Opening ${s==="generator"?"generator":"documentation"} in browser...`)),console.log(u.blue(` ${t}`))}catch(r){let n=r instanceof Error?r.message:String(r);console.error(u.red(`
106
106
  \u2717 Failed to open browser: ${n}`)),console.log(u.yellow(`
107
- Please visit manually: ${t}`)),process.exit(1)}});var De=I.command("history").description("Manage workflow execution history");De.action(async()=>{let s=new $,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.red(`
107
+ Please visit manually: ${t}`)),process.exit(1)}});var Le=N.command("history").description("Manage workflow execution history");Le.action(async()=>{let s=new C,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.red(`
108
108
  \u2717 Invalid choice`)),process.exit(1));let t=new P;switch(e.id){case"show":{let r=await t.getHistoryNames();if(r.length===0){console.log(u.yellow(`
109
109
  \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.red(`
110
- \u2717 Invalid choice`)),process.exit(1));try{let o=await t.getHistory(n.id);Fe(o,n.id)}catch(o){let a=o instanceof Error?o.message:String(o);console.error(u.red(`
110
+ \u2717 Invalid choice`)),process.exit(1));try{let o=await t.getHistory(n.id);We(o,n.id)}catch(o){let a=o instanceof Error?o.message:String(o);console.error(u.red(`
111
111
  \u2717 Failed to load history: ${a}`)),process.exit(1)}break}case"remove":{let r=await t.getHistoryNames();if(r.length===0){console.log(u.yellow(`
112
112
  \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.red(`
113
113
  \u2717 Invalid choice`)),process.exit(1));try{await t.removeHistory(n.id),console.log(u.green(`
@@ -116,9 +116,9 @@ Please visit manually: ${t}`)),process.exit(1)}});var De=I.command("history").de
116
116
  \u2717 Cancelled`));return}try{await t.clearAllHistories(),console.log(u.green(`
117
117
  \u2713 All histories removed`))}catch(n){let o=n instanceof Error?n.message:String(n);console.error(u.red(`
118
118
  \u2717 Failed to remove histories: ${o}`)),process.exit(1)}break}default:console.error(u.red(`
119
- \u2717 Unknown action: ${e.id}`)),process.exit(1)}});function Le(s){return s.split("/").pop()??s}function Fe(s,e){console.log(`
120
- `);let t=s.records.reduce((c,m)=>c+m.duration,0),r=s.records.filter(c=>c.status==="success").length,n=s.records.filter(c=>c.status==="failure").length,o=Te(s.initialTimestamp).format("YYYY-MM-DD HH:mm:ss"),i=(t/1e3).toFixed(2),p=[u.bold("Workflow Execution History"),"",`${u.cyan("File:")} ${e}`,`${u.cyan("Started:")} ${o}`,`${u.cyan("Total Duration:")} ${i}s`,`${u.cyan("Total Steps:")} ${s.records.length}`,`${u.green("\u2713 Successful:")} ${r}`,n>0?`${u.red("\u2717 Failed:")} ${n}`:""].filter(Boolean).join(`
121
- `);console.log(ne(p,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderColor:"cyan"})),s.records.forEach((c,m)=>{We(c,m+1,s.records.length)}),console.log("")}function We(s,e,t){let r=He(s.step),n=Oe(s.step),o=s.status==="success"?u.green("\u2713"):u.red("\u2717"),a=s.status==="success"?u.green("Success"):u.red("Failed"),i=`${(s.duration/1e3).toFixed(2)}s`,p=[`${o} ${u.bold(`Step ${e}/${t}`)} - ${u.cyan(r)}`,`${u.gray("Duration:")} ${i} | ${u.gray("Status:")} ${a}`,"",u.white(n)].join(`
122
- `);console.log(ne(p,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderColor:s.status==="success"?"green":"red"})),Ve(s.output)&&_e(s.output)}function He(s){return"run"in s?"Run":"choose"in s?"Choose":"prompt"in s?"Prompt":"parallel"in s?"Parallel":"fail"in s?"Fail":"Unknown"}function Oe(s){return"run"in s?`Command: ${u.yellow(s.run)}`:"choose"in s?`Message: ${u.yellow(s.choose.message)}`:"prompt"in s?`Message: ${u.yellow(s.prompt.message)} | Variable: ${u.cyan(s.prompt.as)}`:"parallel"in s?`Parallel execution with ${s.parallel.length} branches`:"fail"in s?`Error: ${u.red(s.fail.message)}`:"Unknown step type"}function Ve(s){return typeof s=="object"&&s!==null&&"success"in s&&"stdout"in s&&"stderr"in s}function _e(s){if(s.stdout.length>0){let e=s.stdout.map(t=>u.gray(` ${t}`)).join(`
119
+ \u2717 Unknown action: ${e.id}`)),process.exit(1)}});function Fe(s){return s.split("/").pop()??s}function We(s,e){console.log(`
120
+ `);let t=s.records.reduce((c,m)=>c+m.duration,0),r=s.records.filter(c=>c.status==="success").length,n=s.records.filter(c=>c.status==="failure").length,o=je(s.initialTimestamp).format("YYYY-MM-DD HH:mm:ss"),i=(t/1e3).toFixed(2),p=[u.bold("Workflow Execution History"),"",`${u.cyan("File:")} ${e}`,`${u.cyan("Started:")} ${o}`,`${u.cyan("Total Duration:")} ${i}s`,`${u.cyan("Total Steps:")} ${s.records.length}`,`${u.green("\u2713 Successful:")} ${r}`,n>0?`${u.red("\u2717 Failed:")} ${n}`:""].filter(Boolean).join(`
121
+ `);console.log(ae(p,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderColor:"cyan"})),s.records.forEach((c,m)=>{He(c,m+1,s.records.length)}),console.log("")}function He(s,e,t){let r=Oe(s.step),n=Ve(s.step),o=s.status==="success"?u.green("\u2713"):u.red("\u2717"),a=s.status==="success"?u.green("Success"):u.red("Failed"),i=`${(s.duration/1e3).toFixed(2)}s`,p=[`${o} ${u.bold(`Step ${e}/${t}`)} - ${u.cyan(r)}`,`${u.gray("Duration:")} ${i} | ${u.gray("Status:")} ${a}`,"",u.white(n)].join(`
122
+ `);console.log(ae(p,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderColor:s.status==="success"?"green":"red"})),_e(s.output)&&Ye(s.output)}function Oe(s){return"run"in s?"Run":"choose"in s?"Choose":"prompt"in s?"Prompt":"parallel"in s?"Parallel":"fail"in s?"Fail":"Unknown"}function Ve(s){return"run"in s?`Command: ${u.yellow(s.run)}`:"choose"in s?`Message: ${u.yellow(s.choose.message)}`:"prompt"in s?`Message: ${u.yellow(s.prompt.message)} | Variable: ${u.cyan(s.prompt.as)}`:"parallel"in s?`Parallel execution with ${s.parallel.length} branches`:"fail"in s?`Error: ${u.red(s.fail.message)}`:"Unknown step type"}function _e(s){return typeof s=="object"&&s!==null&&"success"in s&&"stdout"in s&&"stderr"in s}function Ye(s){if(s.stdout.length>0){let e=s.stdout.map(t=>u.gray(` ${t}`)).join(`
123
123
  `);console.log(u.green(" Output:")),console.log(e)}if(s.stderr.length>0){let e=s.stderr.map(t=>u.gray(` ${t}`)).join(`
124
- `);console.log(u.red(" Errors:")),console.log(e)}}I.parse();
124
+ `);console.log(u.red(" Errors:")),console.log(e)}}N.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-pipeliner",
3
- "version": "0.1.7",
3
+ "version": "0.2.0",
4
4
  "description": "A task pipeline runner with condition-based workflow execution",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",