task-pipeliner 0.3.7 → 0.3.8

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.3.7
5
+ **버전:** 0.3.8
6
6
 
7
7
  ![fox2](https://github.com/user-attachments/assets/fdf8d786-6a91-4d2d-9dc1-72be6f3ccd98)
8
8
 
@@ -44,6 +44,8 @@
44
44
 
45
45
  - **변수 치환** - 워크플로우 전반에서 `{{variables}}` 사용
46
46
 
47
+ - **Stdout 캡쳐** - 다양한 캡쳐 전략(정규식, JSON/YAML, 키-값 등)을 사용하여 명령 출력에서 값을 추출하여 변수로 저장
48
+
47
49
  - **프로필** - 미리 정의한 변수로 비대화형 실행 (`tp run --profile <name>`); 프로필에 설정된 변수에 대해서는 choose/prompt 단계 생략
48
50
 
49
51
  - **실행 히스토리** - 상세한 단계별 기록으로 과거 워크플로우 실행 추적 및 검토
@@ -257,6 +259,13 @@ steps:
257
259
  var:
258
260
  action: test
259
261
  run: 'npm test'
262
+
263
+ # 명령 출력에서 값 추출
264
+ - run: 'cat package.json'
265
+ captures:
266
+ - json: "$.version"
267
+ as: version
268
+ - run: 'echo "Version: {{version}}"'
260
269
  ```
261
270
 
262
271
  **JSON 형식 (`workflow.json`):**
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > A powerful workflow orchestration tool with condition-based execution and beautiful CLI output
4
4
 
5
- **Version:** 0.3.7
5
+ **Version:** 0.3.8
6
6
 
7
7
  ![fox2](https://github.com/user-attachments/assets/fdf8d786-6a91-4d2d-9dc1-72be6f3ccd98)
8
8
 
@@ -105,6 +105,8 @@ After upgrading to a new version, if you see compatibility issues (e.g. schedule
105
105
 
106
106
  - **Variable substitution** - Use `{{variables}}` throughout your workflows
107
107
 
108
+ - **Stdout capture** - Extract values from command output into variables using various capture strategies (regex, JSON/YAML, key-value, etc.)
109
+
108
110
  - **Profiles** - Run workflows non-interactively with pre-set variables (`tp run --profile <name>`); choose/prompt steps are skipped when the variable is set in the profile
109
111
 
110
112
  - **Execution history** - Track and review past workflow executions with detailed step-by-step records
@@ -258,6 +260,13 @@ steps:
258
260
  var:
259
261
  action: test
260
262
  run: 'npm test'
263
+
264
+ # Extract values from command output
265
+ - run: 'cat package.json'
266
+ captures:
267
+ - json: "$.version"
268
+ as: version
269
+ - run: 'echo "Version: {{version}}"'
261
270
  ```
262
271
 
263
272
  **JSON Format (`workflow.json`):**
package/dist/index.cjs CHANGED
@@ -1,33 +1,36 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var xr=Object.create;var ct=Object.defineProperty;var kr=Object.getOwnPropertyDescriptor;var vr=Object.getOwnPropertyNames;var $r=Object.getPrototypeOf,Rr=Object.prototype.hasOwnProperty;var Er=(r,e)=>()=>(r&&(e=r(r=0)),e);var Pr=(r,e)=>{for(var t in e)ct(r,t,{get:e[t],enumerable:!0})},Cr=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of vr(e))!Rr.call(r,s)&&s!==t&&ct(r,s,{get:()=>e[s],enumerable:!(o=kr(e,s))||o.enumerable});return r};var S=(r,e,t)=>(t=r!=null?xr($r(r)):{},Cr(e||!r||!r.__esModule?ct(t,"default",{value:r,enumerable:!0}):t,r));var Vt={};Pr(Vt,{DAEMON_DIR:()=>fe,getDaemonErrorLogPath:()=>dt,getDaemonPid:()=>ut,getDaemonStartTime:()=>Ht,getDaemonStatus:()=>N,isDaemonRunning:()=>Y,readDaemonErrorLog:()=>mt,removeDaemonPid:()=>Ce,saveDaemonPid:()=>Tr,writeDaemonError:()=>pt});function Dr(r){try{return process.kill(r,0),!0}catch{return!1}}async function ut(){try{if(!(0,le.existsSync)(z))return null;let r=await(0,M.readFile)(z,"utf-8"),e=parseInt(r.trim(),10);return isNaN(e)?(await(0,M.unlink)(z),null):Dr(e)?e:(await(0,M.unlink)(z),null)}catch(r){if(r instanceof Error&&"code"in r&&r.code==="ENOENT")return null;throw r}}async function Y(){return await ut()!==null}async function Tr(){await(0,M.mkdir)(fe,{recursive:!0}),await(0,M.writeFile)(z,process.pid.toString(),"utf-8");let r=new Date().toISOString();await(0,M.writeFile)(Ee,r,"utf-8")}async function pt(r){try{await(0,M.mkdir)(fe,{recursive:!0});let e=`${new Date().toISOString()} ${r.message}
3
- ${r.stack??""}
4
- `;await(0,M.writeFile)(We,e,"utf-8")}catch{}}async function Ce(){try{(0,le.existsSync)(z)&&await(0,M.unlink)(z),(0,le.existsSync)(Ee)&&await(0,M.unlink)(Ee)}catch{}}async function Ht(){try{if((0,le.existsSync)(Ee)){let e=(await(0,M.readFile)(Ee,"utf-8")).trim();if(e)return e}if((0,le.existsSync)(z)){let r=await(0,M.stat)(z);return new Date(r.mtime).toISOString()}return null}catch{return null}}function dt(){return We}async function mt(){try{return(0,le.existsSync)(We)&&(await(0,M.readFile)(We,"utf-8")).trim()||null}catch{return null}}async function N(){let r=await ut(),e=r?await Ht():null;return{running:r!==null,pid:r,startTime:e}}var le,M,Wt,Pe,fe,z,Ee,We,he=Er(()=>{"use strict";le=require("fs"),M=require("fs/promises"),Wt=require("os"),Pe=require("path"),fe=(0,Pe.join)((0,Wt.homedir)(),".pipeliner","daemon"),z=(0,Pe.join)(fe,"scheduler.pid"),Ee=(0,Pe.join)(fe,"scheduler.started");We=(0,Pe.join)(fe,"error.log")});var or=require("child_process"),ee=require("fs"),te=require("fs/promises"),rr=require("os"),G=require("path"),nr=require("util"),b=S(require("chalk"),1),sr=require("commander");he();var de=require("path"),ao=S(require("chalk"),1);var Ut=S(require("readline"),1),F=S(require("chalk"),1),ft=S(require("inquirer"),1),_t=15,B=class{searchable;constructor(e=!1){this.searchable=e}async prompt(e,t){if(this.searchable)return this.promptWithSearch(e,t);let{choice:o}=await ft.default.prompt([{type:"list",name:"choice",message:F.default.cyan(e),choices:t.map(i=>({name:i.label,value:i.id})),pageSize:_t}]),s=t.find(i=>i.id===o);if(!s)throw new Error(`Invalid choice: ${o}`);return s}async promptWithSearch(e,t){return new Promise(o=>{let s="",i=0,n=[...t],a=Ut.createInterface({input:process.stdin,output:process.stdout,terminal:!1});process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdout.write("\x1B[?1049h"),process.stdout.write("\x1B[?25l");let l=()=>{process.stdout.write("\x1B[H\x1B[2J"),console.log(F.default.cyan(`? ${e}`));let m=s?F.default.gray(` Filter: ${s}`)+F.default.gray(` (${n.length}/${t.length})`):F.default.gray(" Type to filter, \u2191\u2193 to navigate, Enter to select");console.log(m),console.log();let u=_t,h=0,g=n.length;if(n.length>u){let w=Math.floor(u/2);h=Math.max(0,i-w),g=Math.min(n.length,h+u),g===n.length&&(h=Math.max(0,g-u))}if(n.length===0)console.log(F.default.yellow(" No matches found"));else{h>0&&console.log(F.default.gray(` \u2191 ${h} more above`));for(let w=h;w<g;w++){let y=n[w];console.log(w===i?F.default.cyan(`\u276F ${y.label}`):F.default.white(` ${y.label}`))}g<n.length&&console.log(F.default.gray(` \u2193 ${n.length-g} more below`))}},c=()=>{let m=s.toLowerCase();n=m?t.filter(u=>u.label.toLowerCase().includes(m)):[...t],i>=n.length&&(i=Math.max(0,n.length-1))},p=m=>{let u=m.toString();if(u===""&&(f(),process.exit(0)),u==="\r"||u===`
5
- `){n.length>0&&(f(),o(n[i]));return}if(u==="\x1B"&&m.length===1){s&&(s="",c(),l());return}if(u==="\x1B[A"){n.length>0&&(i=i>0?i-1:n.length-1,l());return}if(u==="\x1B[B"){n.length>0&&(i=i<n.length-1?i+1:0,l());return}if(u==="\x7F"||u==="\b"){s.length>0&&(s=s.slice(0,-1),c(),l());return}u.length===1&&u>=" "&&u<="~"&&(s+=u,c(),l())},f=()=>{process.stdin.removeListener("data",p),process.stdin.isTTY&&process.stdin.setRawMode(!1),a.close(),process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[?1049l")};l(),process.stdin.on("data",p)})}},He=class{async prompt(e,t){let{value:o}=await ft.default.prompt([{type:"input",name:"value",message:F.default.cyan(e),default:t}]);return o}};var Gt=S(require("boxen"),1),C=S(require("chalk"),1),ht=S(require("string-width"),1);function Ve(r){if(r.records.length===0)return"";let e=Ir(r.records),t=0;for(let m of e)m.length>1?t+=Math.max(...m.map(u=>u.duration)):t+=m[0].duration;let o=(t/1e3).toFixed(1),s=r.records.reduce((m,u)=>u.duration>m.duration?u:m),i=r.records.indexOf(s)+1,n=(s.duration/1e3).toFixed(1),a=[],l=0;for(let m=0;m<e.length;m++){let u=e[m];if(u.some(w=>w.context.branchIndex!==void 0&&w.context.stepIndex>=1e3)&&u.length>=1&&u.length>0){let w=u,y=w.map($=>({name:zt($),startTime:l,duration:$.duration})),k=Math.max(...w.map($=>$.duration));a.push({stepNumber:m+1,name:"Parallel",startTime:l,duration:k,isParallel:!0,parallelBranches:y}),l+=k}else{let w=u[0],k=zt(w)||"Unknown";a.push({stepNumber:m+1,name:k,startTime:l,duration:w.duration,isParallel:!1}),l+=w.duration}}let c=Mr(a,t,s.duration),f=`${`${C.default.bold("Workflow Summary")}
6
- ${C.default.cyan(`Workflow finished in ${o}s`)}
2
+ "use strict";var $r=Object.create;var ct=Object.defineProperty;var Rr=Object.getOwnPropertyDescriptor;var Er=Object.getOwnPropertyNames;var Pr=Object.getPrototypeOf,Cr=Object.prototype.hasOwnProperty;var Dr=(o,e)=>()=>(o&&(e=o(o=0)),e);var Tr=(o,e)=>{for(var t in e)ct(o,t,{get:e[t],enumerable:!0})},Ir=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Er(e))!Cr.call(o,s)&&s!==t&&ct(o,s,{get:()=>e[s],enumerable:!(r=Rr(e,s))||r.enumerable});return o};var S=(o,e,t)=>(t=o!=null?$r(Pr(o)):{},Ir(e||!o||!o.__esModule?ct(t,"default",{value:o,enumerable:!0}):t,o));var _t={};Tr(_t,{DAEMON_DIR:()=>he,getDaemonErrorLogPath:()=>dt,getDaemonPid:()=>ut,getDaemonStartTime:()=>Vt,getDaemonStatus:()=>N,isDaemonRunning:()=>Y,readDaemonErrorLog:()=>mt,removeDaemonPid:()=>Ce,saveDaemonPid:()=>Nr,writeDaemonError:()=>pt});function Mr(o){try{return process.kill(o,0),!0}catch{return!1}}async function ut(){try{if(!(0,ce.existsSync)(z))return null;let o=await(0,M.readFile)(z,"utf-8"),e=parseInt(o.trim(),10);return isNaN(e)?(await(0,M.unlink)(z),null):Mr(e)?e:(await(0,M.unlink)(z),null)}catch(o){if(o instanceof Error&&"code"in o&&o.code==="ENOENT")return null;throw o}}async function Y(){return await ut()!==null}async function Nr(){await(0,M.mkdir)(he,{recursive:!0}),await(0,M.writeFile)(z,process.pid.toString(),"utf-8");let o=new Date().toISOString();await(0,M.writeFile)(Ee,o,"utf-8")}async function pt(o){try{await(0,M.mkdir)(he,{recursive:!0});let e=`${new Date().toISOString()} ${o.message}
3
+ ${o.stack??""}
4
+ `;await(0,M.writeFile)(We,e,"utf-8")}catch{}}async function Ce(){try{(0,ce.existsSync)(z)&&await(0,M.unlink)(z),(0,ce.existsSync)(Ee)&&await(0,M.unlink)(Ee)}catch{}}async function Vt(){try{if((0,ce.existsSync)(Ee)){let e=(await(0,M.readFile)(Ee,"utf-8")).trim();if(e)return e}if((0,ce.existsSync)(z)){let o=await(0,M.stat)(z);return new Date(o.mtime).toISOString()}return null}catch{return null}}function dt(){return We}async function mt(){try{return(0,ce.existsSync)(We)&&(await(0,M.readFile)(We,"utf-8")).trim()||null}catch{return null}}async function N(){let o=await ut(),e=o?await Vt():null;return{running:o!==null,pid:o,startTime:e}}var ce,M,Ht,Pe,he,z,Ee,We,ge=Dr(()=>{"use strict";ce=require("fs"),M=require("fs/promises"),Ht=require("os"),Pe=require("path"),he=(0,Pe.join)((0,Ht.homedir)(),".pipeliner","daemon"),z=(0,Pe.join)(he,"scheduler.pid"),Ee=(0,Pe.join)(he,"scheduler.started");We=(0,Pe.join)(he,"error.log")});var sr=require("child_process"),te=require("fs"),oe=require("fs/promises"),ir=require("os"),G=require("path"),ar=require("util"),b=S(require("chalk"),1),lr=require("commander");ge();var K=require("path"),uo=S(require("chalk"),1);var zt=S(require("readline"),1),F=S(require("chalk"),1),ft=S(require("inquirer"),1),Ut=15,B=class{searchable;constructor(e=!1){this.searchable=e}async prompt(e,t){if(this.searchable)return this.promptWithSearch(e,t);let{choice:r}=await ft.default.prompt([{type:"list",name:"choice",message:F.default.cyan(e),choices:t.map(i=>({name:i.label,value:i.id})),pageSize:Ut}]),s=t.find(i=>i.id===r);if(!s)throw new Error(`Invalid choice: ${r}`);return s}async promptWithSearch(e,t){return new Promise(r=>{let s="",i=0,n=[...t],a=zt.createInterface({input:process.stdin,output:process.stdout,terminal:!1});process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdout.write("\x1B[?1049h"),process.stdout.write("\x1B[?25l");let l=()=>{process.stdout.write("\x1B[H\x1B[2J"),console.log(F.default.cyan(`? ${e}`));let m=s?F.default.gray(` Filter: ${s}`)+F.default.gray(` (${n.length}/${t.length})`):F.default.gray(" Type to filter, \u2191\u2193 to navigate, Enter to select");console.log(m),console.log();let p=Ut,h=0,g=n.length;if(n.length>p){let w=Math.floor(p/2);h=Math.max(0,i-w),g=Math.min(n.length,h+p),g===n.length&&(h=Math.max(0,g-p))}if(n.length===0)console.log(F.default.yellow(" No matches found"));else{h>0&&console.log(F.default.gray(` \u2191 ${h} more above`));for(let w=h;w<g;w++){let y=n[w];console.log(w===i?F.default.cyan(`\u276F ${y.label}`):F.default.white(` ${y.label}`))}g<n.length&&console.log(F.default.gray(` \u2193 ${n.length-g} more below`))}},c=()=>{let m=s.toLowerCase();n=m?t.filter(p=>p.label.toLowerCase().includes(m)):[...t],i>=n.length&&(i=Math.max(0,n.length-1))},d=m=>{let p=m.toString();if(p===""&&(f(),process.exit(0)),p==="\r"||p===`
5
+ `){n.length>0&&(f(),r(n[i]));return}if(p==="\x1B"&&m.length===1){s&&(s="",c(),l());return}if(p==="\x1B[A"){n.length>0&&(i=i>0?i-1:n.length-1,l());return}if(p==="\x1B[B"){n.length>0&&(i=i<n.length-1?i+1:0,l());return}if(p==="\x7F"||p==="\b"){s.length>0&&(s=s.slice(0,-1),c(),l());return}p.length===1&&p>=" "&&p<="~"&&(s+=p,c(),l())},f=()=>{process.stdin.removeListener("data",d),process.stdin.isTTY&&process.stdin.setRawMode(!1),a.close(),process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[?1049l")};l(),process.stdin.on("data",d)})}},He=class{async prompt(e,t){let{value:r}=await ft.default.prompt([{type:"input",name:"value",message:F.default.cyan(e),default:t}]);return r}};var Zt=S(require("boxen"),1),C=S(require("chalk"),1),ht=S(require("string-width"),1);function Ve(o){if(o.records.length===0)return"";let e=jr(o.records),t=0;for(let m of e)m.length>1?t+=Math.max(...m.map(p=>p.duration)):t+=m[0].duration;let r=(t/1e3).toFixed(1),s=o.records.reduce((m,p)=>p.duration>m.duration?p:m),i=o.records.indexOf(s)+1,n=(s.duration/1e3).toFixed(1),a=[],l=0;for(let m=0;m<e.length;m++){let p=e[m];if(p.some(w=>w.context.branchIndex!==void 0&&w.context.stepIndex>=1e3)&&p.length>=1&&p.length>0){let w=p,y=w.map($=>({name:Yt($),startTime:l,duration:$.duration})),k=Math.max(...w.map($=>$.duration));a.push({stepNumber:m+1,name:"Parallel",startTime:l,duration:k,isParallel:!0,parallelBranches:y}),l+=k}else{let w=p[0],k=Yt(w)||"Unknown";a.push({stepNumber:m+1,name:k,startTime:l,duration:w.duration,isParallel:!1}),l+=w.duration}}let c=Ar(a,t,s.duration),f=`${`${C.default.bold("Workflow Summary")}
6
+ ${C.default.cyan(`Workflow finished in ${r}s`)}
7
7
  ${C.default.yellow(`Slowest step: Step ${i} (${n}s)`)}`}
8
8
 
9
9
  ${c}`;return`
10
- ${(0,Gt.default)(f,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"cyan"})}`}function Ir(r){let e=[],t=new Map,o=1e3;for(let i of r){let n;i.context.branchIndex!==void 0&&i.context.stepIndex>=o?n=Math.floor(i.context.stepIndex/o):n=i.context.stepIndex,t.has(n)||t.set(n,[]);let a=t.get(n);a&&a.push(i)}let s=Array.from(t.keys()).sort((i,n)=>i-n);for(let i of s){let n=t.get(i);if(n){let a=n.filter(l=>l.context.branchIndex!==void 0&&l.context.stepIndex>=o);if(a.length>0){a.sort((c,p)=>{let f=c.context.branchIndex??-1,m=p.context.branchIndex??-1;return f-m}),e.push(a);let l=n.filter(c=>(c.context.branchIndex===void 0||c.context.stepIndex<o)&&!("parallel"in c.step));l.length>0&&(l.sort((c,p)=>c.context.stepIndex-p.context.stepIndex),e.push(l))}else n.sort((l,c)=>l.context.stepIndex-c.context.stepIndex),e.push(n)}}return e}function zt(r){let e=r.step,t=28;if("run"in e){let o=r.resolvedCommand??e.run;return o.length>t?`${o.substring(0,t-2)}..`:o}else if("choose"in e){let o=e.choose.message;return o.length>t?`${o.substring(0,t-2)}..`:o}else if("prompt"in e){let o=e.prompt.message;return o.length>t?`${o.substring(0,t-2)}..`:o}else{if("parallel"in e)return"Parallel";if("fail"in e){let o=e.fail.message;return o.length>t?`${o.substring(0,t-2)}..`:o}}return"Unknown"}function Yt(r,e){return Te(r)<=e}function Mr(r,e,t){let o=process.stdout.columns||80,s=36,i=4,n=36,a=8,l=8,p=n+a+l+9,m=o-s-i-p,g=Math.max(40,Math.max(0,m-5)),w=[],y=2+n+3+a+3+l+3+g+2,k=o-s-8,$=(R,P,Z=!1)=>{let Re=Te(R);if(Re===P)return R;if(Re>P)return De(R,P);let re=P-Re;if(Z){let ne=R.lastIndexOf("\u2524"),me=R.lastIndexOf("\u253C",ne-1);if(me>0&&ne>me){let Oe=R.slice(0,me+1),at=R.slice(me+1,ne),Fe=R.slice(ne);return Oe+at+"\u2500".repeat(re)+Fe}return R.slice(0,-1)+"\u2500".repeat(re)+R.slice(-1)}let Le=R.lastIndexOf("\u2502");return Le>0?R.slice(0,Le)+" ".repeat(re)+R.slice(Le):R+" ".repeat(re)},I="\u2500".repeat(n),H="\u2500".repeat(a),j="\u2500".repeat(l),ot="\u2500".repeat(g),rt=`\u250C\u2500${I}\u2500\u252C\u2500${H}\u2500\u252C\u2500${j}\u2500\u252C\u2500${ot}\u2500\u2510`;rt=$(rt,y,!0),w.push(rt);let ir=ce("Step / Task",n),ar=J("Start",a),lr=ce("Duration",l),cr=ce("Timeline",g),nt=`\u2502 ${C.default.bold(ir)} \u2502 ${C.default.bold(ar)} \u2502 ${C.default.bold(lr)} \u2502 ${C.default.bold(cr)} \u2502`;nt=$(nt,y),w.push(nt);let ur="\u2500".repeat(n),pr="\u2500".repeat(a),dr="\u2500".repeat(l),mr="\u2500".repeat(g),st=`\u251C\u2500${ur}\u2500\u253C\u2500${pr}\u2500\u253C\u2500${dr}\u2500\u253C\u2500${mr}\u2500\u2524`;st=$(st,y,!0),w.push(st);let Be=new Map;for(let R=0;R<r.length;R++){let P=r[R],Z=Math.round(P.startTime);Be.has(Z)||Be.set(Z,[]),Be.get(Z)?.push(R)}for(let R=0;R<r.length;R++){let P=r[R],Z=(P.startTime/1e3).toFixed(1),Re=(P.duration/1e3).toFixed(1),re=`${C.default.cyan(`Step ${P.stepNumber}`)}: ${P.name}`,ne=Jt(P.duration,t)(`${Re}s`),me=Math.round(P.startTime),Oe=Be.get(me)??[],at=Oe.indexOf(R),Fe=qt(P.startTime,P.duration,e,g,P.duration,t,!1,at,Oe.length,P.isParallel),se=`\u2502 ${ce(re,n)} \u2502 ${J(`${Z}s`,a)} \u2502 ${J(ne,l)} \u2502 ${Fe} \u2502`;if(se=$(se,y),!Yt(se,k)){let ie=De(re,n);se=`\u2502 ${ce(ie,n)} \u2502 ${J(`${Z}s`,a)} \u2502 ${J(ne,l)} \u2502 ${Fe} \u2502`,se=$(se,y)}if(w.push(se),P.isParallel&&P.parallelBranches&&P.parallelBranches.length>0)for(let ie=0;ie<P.parallelBranches.length;ie++){let X=P.parallelBranches[ie],Bt=(X.startTime/1e3).toFixed(1),br=(X.duration/1e3).toFixed(1),Lt=qt(X.startTime,X.duration,e,g,X.duration,t,!0,0,1,!1),Ot=ie===0?"\u2502 \u23A7 ":ie===P.parallelBranches.length-1?"\u2502 \u23A9 ":"\u2502 \u251C ",lt=n-3,yr=ce(C.default.blue(X.name),lt),Ft=Jt(X.duration,t)(`${br}s`),ae=`${Ot}${yr} \u2502 ${J(`${Bt}s`,a)} \u2502 ${J(Ft,l)} \u2502 ${Lt} \u2502`;if(ae=$(ae,y),!Yt(ae,k)){let Sr=De(C.default.blue(X.name),lt-3);ae=`${Ot}${ce(Sr,lt)} \u2502 ${J(`${Bt}s`,a)} \u2502 ${J(Ft,l)} \u2502 ${Lt} \u2502`,ae=$(ae,y)}w.push(ae)}}let fr="\u2500".repeat(n),hr="\u2500".repeat(a),gr="\u2500".repeat(l),wr="\u2500".repeat(g),it=`\u2514\u2500${fr}\u2500\u2534\u2500${hr}\u2500\u2534\u2500${gr}\u2500\u2534\u2500${wr}\u2500\u2518`;return it=$(it,y,!0),w.push(it),w.join(`
11
- `)}function Jt(r,e){if(r===0)return C.default.gray;let t=r/e;return t>=.8?C.default.red:t>=.5?C.default.yellow:C.default.green}function qt(r,e,t,o,s,i,n=!1,a=0,l=1,c=!1){let p=r/t,m=(r+e)/t,u=Math.round(p*o),h=Math.round(m*o);if(l>1&&e===0){let j=a*1e-4;u=Math.round((p+j)*o),h=u+1}else h<=u&&(h=u+1);u=Math.max(0,Math.min(u,o-1)),h=Math.max(u+1,Math.min(h,o));let g;if(n)g=C.default.cyan;else if(c)g=C.default.blue;else if(s===0)g=C.default.gray;else{let j=s/i;j>=.8?g=C.default.red:j>=.5?g=C.default.yellow:g=C.default.green}let y=m>=.99||h>=o?o:h,k="";for(let j=0;j<u;j++)k+=C.default.gray("\u2591");let $=y-u,I="\u2588".repeat($);k+=g(I);let H=o-y;for(let j=0;j<H;j++)k+=C.default.gray("\u2591");return k}function Te(r){return(0,ht.default)(r)}function De(r,e){if(Te(r)<=e)return r;let s=e-2;if(s<1)return"..";let i=/\u001b\[[0-9;]*m/g,n=[],a;for(;(a=i.exec(r))!==null;)n.push(a[0]);let l=r.replace(i,""),c="",p=0;for(let f=0;f<l.length;f++){let m=l[f],u=(0,ht.default)(m);if(p+u>s)break;c+=m,p+=u}return c+="..",n.length>0&&c.length>0?n[0]+c+(n[n.length-1]??""):c}function ce(r,e){let t=Te(r);return t>=e?De(r,e):r+" ".repeat(e-t)}function J(r,e){let t=Te(r);return t>=e?De(r,e):" ".repeat(e-t)+r}var _e=S(require("boxen"),1),ge=S(require("chalk"),1);function gt(r,e,t,o={}){let{borderColor:s="cyan",isNested:i=!1}=o,n;e!==void 0&&(t?n=`line ${e} in ${t}`:n=`line ${e}`);let a=i?`\u2502 ${r}`:`> ${r}`;return(0,_e.default)(a,{title:n,borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:s})}function we(r,e=!1,t){let o=r?"\u2713 Completed":"\u2717 Failed",s=r?ge.default.green(o):ge.default.red(o);if(t!==void 0){let i=be(t);return`${s} ${ge.default.gray(`(${i})`)}`}return s}function Ie(r){return(0,_e.default)(`\u2717 ${r}`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"red"})}function Zt(r){return(0,_e.default)(`> Starting parallel execution (${r} branches)`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"yellow"})}function Xt(r){let e=r?"\u2713 All parallel branches completed":"\u2717 Some parallel branches failed";return r?ge.default.green(e):ge.default.red(e)}function wt(r,e=!1){return`${e?"| \u2502 ":"\u2502 "}${r}`}function be(r){return`${(r/1e3).toFixed(3)}s`}var Kt=require("fs"),Qt=require("path"),ue=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[o,s]of Object.entries(e.var)){let i=this.workspace.getVariable(o),n=this.workspace.getFact(o),a=i??(n!==void 0?n.toString():void 0);if(a===void 0||a!==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(),o=(0,Qt.resolve)(process.cwd(),t);return(0,Kt.existsSync)(o)}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 bt=S(require("log-update"),1);var yt=1e3;function Nr(r,e,t){return e.parallel.map((o,s)=>({workspace:r.workspace.clone(),stepIndex:t.stepIndex*yt+s,branchIndex:s,lineNumber:t.lineNumber,fileName:t.fileName}))}function eo(r,e){return"run"in r?r.run:"choose"in r?`Choose: ${r.choose.message}`:"prompt"in r?`Prompt: ${r.prompt.message}`:"fail"in r?`Fail: ${r.fail.message}`:`Branch ${e+1}`}function Ar(r,e){let t=0;for(let o=0;o<r.length;o++){let s=r[o],i=e[o];s.when&&!new ue(i.workspace).evaluate(s.when)||t++}return t}function Ue(r,e,t=!1){let o=r.map(s=>{let i=s.index+1,n="",a="";switch(s.status){case"pending":n="\u25CB",a=`Branch ${i}: ${s.name} - Pending`;break;case"running":n=e,a=`Branch ${i}: ${s.name} - Running...`;break;case"success":n="\u2713",a=`Branch ${i}: ${s.name} - Completed`;break;case"failed":n="\u2717",a=`Branch ${i}: ${s.name} - Failed${s.error?`: ${s.error}`:""}`;break}return`${n} ${a}`});(0,bt.default)(o.join(`
12
- `))}async function jr(r,e,t,o){let s=[],i=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],n=0;for(let p=0;p<t.length;p++){let f=t[p],m=o[p];if(f.when&&!new ue(m.workspace).evaluate(f.when))continue;let u=e(f,p);s.push({index:p,name:u,status:"pending"})}let a=setInterval(()=>{n=(n+1)%i.length,Ue(s,i[n])},100),l=s.map(async p=>{let{index:f}=p,m=t[f],u=o[f];p.status="running";try{let h=await r.executeStep(m,u,!0);if(p.status="success",Ue(s,i[n]),r.recordBranch){let g="run"in m?{resolvedCommand:m.run}:void 0;r.recordBranch(m,u,h,"success",g)}return{index:f,result:h,context:u}}catch(h){u.workspace.setStepResult(u.stepIndex,!1);let g=h instanceof Error?h.message:String(h);if(p.status="failed",p.error=g,Ue(s,i[n]),r.recordBranch){let w="run"in m?{resolvedCommand:m.run}:void 0;r.recordBranch(m,u,void 0,"failure",w)}return{index:f,error:h,context:u}}}),c=await Promise.all(l);return clearInterval(a),Ue(s,"",!0),bt.default.done(),c}function Br(r,e,t,o,s){let i=!0,n=!1;console.log("");for(let l of t){if(!l)continue;n=!0;let{index:c,result:p,error:f,context:m}=l;if(f){i=!1;let u=`Branch ${c+1} failed: ${f instanceof Error?f.message:String(f)}`,h=Ie(u);console.error(h)}else if(p&&typeof p=="object"&&"stdout"in p){let u=p;if(i=i&&u.success,u.stdout.length>0||u.stderr.length>0||!u.success){let h=o[c],g=e(h,c);r.taskRunner.displayBufferedOutput(u,g,!1,m.lineNumber,m.fileName)}}}n||console.log("\u26A0\uFE0F All parallel branches were skipped (conditions not met)");let a=Xt(i);return console.log(a),i}function Lr(r,e){for(let t of e){let o=t.workspace.getAllFacts(),s=t.workspace.getAllVariables();for(let[i,n]of o)r.workspace.setFact(i,n);for(let[i,n]of s)r.workspace.setVariable(i,n)}}async function to(r,e,t){let o=Nr(r,e,t),s=Ar(e.parallel,o),i=Zt(s);console.log(i);let n=await jr(r,eo,e.parallel,o),a=Br(r,eo,n,e.parallel,t);if(r.setStepResult(t.stepIndex,a),!a){let l=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Parallel step ${t.stepIndex}${l} failed: one or more branches failed`)}Lr(r,o)}function Or(r,e,t){if(e.hasVariable(r))return e.getVariable(r)??t;if(e.hasFact(r)){let o=e.getFact(r);return typeof o=="string"?o:String(o)}return e.hasChoice(r)?e.getChoice(r)??t:t}function ye(r,e){let t=/\{\{\s*(\w+)\s*\}\}/g;return r.replace(t,(o,s)=>Or(s,e,o))}async function oo(r,e,t,o,s){let{workspace:i,taskRunner:n,baseDir:a,globalShell:l,calculateBaseStepIndex:c}=r,p=c(t),f=ye(e.run.trim(),i),m=e.shell??l,u=e.retry??0,h=u==="Infinity"||u===1/0,g=typeof u=="number"?u:0,w=e.timeout,y=!1,k=0,$=e.run.trim()!==f?`${f}
13
- (template: ${e.run})`:f;for(;h||k<=g;){let I=await n.run(f,p,$,t.branchIndex,o,s,t.lineNumber,t.fileName,a,w,m),H=typeof I=="boolean"?I:I.success;if(y=I,H||!h&&k>=g)break;if(k++,h||k<=g){let j=Math.min(1e3*Math.pow(2,k-1),1e4);await new Promise(ot=>setTimeout(ot,j))}}return y}async function ro(r,e,t,o,s){let i=await oo(r,{run:e.run,timeout:e.timeout,retry:e.retry,shell:void 0},t,o,s);return(typeof i=="boolean"?i:i.success)||!e.onError?i:ro(r,e.onError,t,o,s)}async function no(r,e,t,o=!1,s=!1){let{workspace:i}=r,n=await oo(r,{run:e.run,timeout:e.timeout,retry:e.retry,shell:e.shell},t,o,s),a=typeof n=="boolean"?n:n.success;if(i.setStepResult(t.stepIndex,a),a||!e.onError)return n;let l={run:e.onError.run,timeout:e.onError.timeout,retry:e.onError.retry,onError:e.onError.onError??void 0};return await ro(r,l,t,o,s)}var V=require("fs/promises"),so=require("os"),pe=require("path"),io=S(require("dayjs"),1),Se=(0,pe.join)((0,so.homedir)(),".pipeliner","workflow-history"),xe=class{constructor(){}async saveHistory(e){await(0,V.mkdir)(Se,{recursive:!0});let t=(0,io.default)().format("YYYY-MM-DD_HH-mm-ss"),o=Math.random().toString(36).slice(2,6),s=(0,pe.join)(Se,`workflow-${t}-${o}.json`);return await(0,V.writeFile)(s,JSON.stringify(e,null,2),{encoding:"utf8"}),s}async clearAllHistories(){await(0,V.rm)(Se,{recursive:!0,force:!0})}async removeHistory(e){await(0,V.rm)((0,pe.join)(Se,e),{force:!0})}async getHistoryNames(){try{let t=(await(0,V.readdir)(Se)).map(o=>(0,pe.basename)(o));return t.sort((o,s)=>{let i=l=>{let c=l.match(/workflow-(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-/);return c?c[1]:""},n=i(o),a=i(s);return n===a?s.localeCompare(o):a.localeCompare(n)}),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,pe.join)(Se,e),{encoding:"utf8"});return JSON.parse(t)}};var ze=class{records=[];initialTimestamp=Date.now();recordStartTimestamp=Date.now();constructor(){this.records=[]}recordStart(){this.recordStartTimestamp=Date.now()}recordEnd(e,t,o,s,i){let n=this.getDuration();return this.records.push({step:e,context:t,output:o,duration:n,status:s,...i}),n}reset(){this.records=[],this.initialTimestamp=Date.now()}async save(){let e=new xe,t={initialTimestamp:this.initialTimestamp,records:this.records};return await e.saveHistory(t)}getDuration(){return Date.now()-this.recordStartTimestamp}getHistory(){return{initialTimestamp:this.initialTimestamp,records:this.records}}};var St=require("child_process");var Ye=class{async run(e,t,o,s,i=!1,n=!1,a,l,c,p,f){return i?this.runBuffered(e,c,p,f):this.runRealtime(e,o??e,n,a,l,c,p,f)}async runBuffered(e,t,o,s){return new Promise((i,n)=>{let a=this.spawnWithShell(e,t,s),l=[],c=[],p="",f="",m=null;o&&o>0&&(m=setTimeout(()=>{a.kill("SIGTERM");let u=`Command timed out after ${o} seconds`;c.push(u),i({success:!1,stdout:l,stderr:c})},o*1e3)),a.stdout?.on("data",u=>{let h=u.toString(),{lines:g,remaining:w}=this.processStreamBuffer(h,p);l.push(...g),p=w}),a.stderr?.on("data",u=>{let h=u.toString(),{lines:g,remaining:w}=this.processStreamBuffer(h,f);c.push(...g),f=w}),a.on("close",u=>{m&&clearTimeout(m),p.trim()&&l.push(p),f.trim()&&c.push(f),i({success:u===0,stdout:l,stderr:c})}),a.on("error",u=>{m&&clearTimeout(m);let h=`Error: ${u.message}`;i({success:!1,stdout:l,stderr:[...c,h]})})})}async runRealtime(e,t,o,s,i,n,a,l){let p=gt(t,s,i,{borderColor:o?"green":"cyan"});console.log(p);let f=Date.now();return new Promise(m=>{let u=this.spawnWithShell(e,n,l),h="",g="",w=null;a&&a>0&&(w=setTimeout(()=>{u.kill("SIGTERM");let y=`Command timed out after ${a} seconds`,k=Ie(y);console.error(k);let $=Date.now()-f,I=we(!1,!1,$);console.log(I),m(!1)},a*1e3)),u.stdout?.on("data",y=>{let k=y.toString(),{lines:$,remaining:I}=this.processStreamBuffer(k,h);$.forEach(H=>process.stdout.write(`\u2502 ${H}
14
- `)),h=I}),u.stderr?.on("data",y=>{let k=y.toString(),{lines:$,remaining:I}=this.processStreamBuffer(k,g);$.forEach(H=>process.stderr.write(`\u2502 ${H}
15
- `)),g=I}),u.on("close",y=>{w&&clearTimeout(w),h.trim()&&process.stdout.write(`\u2502 ${h}
10
+ ${(0,Zt.default)(f,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"cyan"})}`}function jr(o){let e=[],t=new Map,r=1e3;for(let i of o){let n;i.context.branchIndex!==void 0&&i.context.stepIndex>=r?n=Math.floor(i.context.stepIndex/r):n=i.context.stepIndex,t.has(n)||t.set(n,[]);let a=t.get(n);a&&a.push(i)}let s=Array.from(t.keys()).sort((i,n)=>i-n);for(let i of s){let n=t.get(i);if(n){let a=n.filter(l=>l.context.branchIndex!==void 0&&l.context.stepIndex>=r);if(a.length>0){a.sort((c,d)=>{let f=c.context.branchIndex??-1,m=d.context.branchIndex??-1;return f-m}),e.push(a);let l=n.filter(c=>(c.context.branchIndex===void 0||c.context.stepIndex<r)&&!("parallel"in c.step));l.length>0&&(l.sort((c,d)=>c.context.stepIndex-d.context.stepIndex),e.push(l))}else n.sort((l,c)=>l.context.stepIndex-c.context.stepIndex),e.push(n)}}return e}function Yt(o){let e=o.step,t=28;if("run"in e){let r=o.resolvedCommand??e.run;return r.length>t?`${r.substring(0,t-2)}..`:r}else if("choose"in e){let r=e.choose.message;return r.length>t?`${r.substring(0,t-2)}..`:r}else if("prompt"in e){let r=e.prompt.message;return r.length>t?`${r.substring(0,t-2)}..`:r}else{if("parallel"in e)return"Parallel";if("fail"in e){let r=e.fail.message;return r.length>t?`${r.substring(0,t-2)}..`:r}}return"Unknown"}function Jt(o,e){return Te(o)<=e}function Ar(o,e,t){let r=process.stdout.columns||80,s=36,i=4,n=36,a=8,l=8,d=n+a+l+9,m=r-s-i-d,g=Math.max(40,Math.max(0,m-5)),w=[],y=2+n+3+a+3+l+3+g+2,k=r-s-8,$=(R,P,Z=!1)=>{let Re=Te(R);if(Re===P)return R;if(Re>P)return De(R,P);let ne=P-Re;if(Z){let se=R.lastIndexOf("\u2524"),fe=R.lastIndexOf("\u253C",se-1);if(fe>0&&se>fe){let Le=R.slice(0,fe+1),at=R.slice(fe+1,se),Fe=R.slice(se);return Le+at+"\u2500".repeat(ne)+Fe}return R.slice(0,-1)+"\u2500".repeat(ne)+R.slice(-1)}let Oe=R.lastIndexOf("\u2502");return Oe>0?R.slice(0,Oe)+" ".repeat(ne)+R.slice(Oe):R+" ".repeat(ne)},I="\u2500".repeat(n),H="\u2500".repeat(a),A="\u2500".repeat(l),ot="\u2500".repeat(g),rt=`\u250C\u2500${I}\u2500\u252C\u2500${H}\u2500\u252C\u2500${A}\u2500\u252C\u2500${ot}\u2500\u2510`;rt=$(rt,y,!0),w.push(rt);let cr=ue("Step / Task",n),ur=J("Start",a),pr=ue("Duration",l),dr=ue("Timeline",g),nt=`\u2502 ${C.default.bold(cr)} \u2502 ${C.default.bold(ur)} \u2502 ${C.default.bold(pr)} \u2502 ${C.default.bold(dr)} \u2502`;nt=$(nt,y),w.push(nt);let mr="\u2500".repeat(n),fr="\u2500".repeat(a),hr="\u2500".repeat(l),gr="\u2500".repeat(g),st=`\u251C\u2500${mr}\u2500\u253C\u2500${fr}\u2500\u253C\u2500${hr}\u2500\u253C\u2500${gr}\u2500\u2524`;st=$(st,y,!0),w.push(st);let Be=new Map;for(let R=0;R<o.length;R++){let P=o[R],Z=Math.round(P.startTime);Be.has(Z)||Be.set(Z,[]),Be.get(Z)?.push(R)}for(let R=0;R<o.length;R++){let P=o[R],Z=(P.startTime/1e3).toFixed(1),Re=(P.duration/1e3).toFixed(1),ne=`${C.default.cyan(`Step ${P.stepNumber}`)}: ${P.name}`,se=qt(P.duration,t)(`${Re}s`),fe=Math.round(P.startTime),Le=Be.get(fe)??[],at=Le.indexOf(R),Fe=Gt(P.startTime,P.duration,e,g,P.duration,t,!1,at,Le.length,P.isParallel),ie=`\u2502 ${ue(ne,n)} \u2502 ${J(`${Z}s`,a)} \u2502 ${J(se,l)} \u2502 ${Fe} \u2502`;if(ie=$(ie,y),!Jt(ie,k)){let ae=De(ne,n);ie=`\u2502 ${ue(ae,n)} \u2502 ${J(`${Z}s`,a)} \u2502 ${J(se,l)} \u2502 ${Fe} \u2502`,ie=$(ie,y)}if(w.push(ie),P.isParallel&&P.parallelBranches&&P.parallelBranches.length>0)for(let ae=0;ae<P.parallelBranches.length;ae++){let X=P.parallelBranches[ae],Ot=(X.startTime/1e3).toFixed(1),xr=(X.duration/1e3).toFixed(1),Lt=Gt(X.startTime,X.duration,e,g,X.duration,t,!0,0,1,!1),Ft=ae===0?"\u2502 \u23A7 ":ae===P.parallelBranches.length-1?"\u2502 \u23A9 ":"\u2502 \u251C ",lt=n-3,kr=ue(C.default.blue(X.name),lt),Wt=qt(X.duration,t)(`${xr}s`),le=`${Ft}${kr} \u2502 ${J(`${Ot}s`,a)} \u2502 ${J(Wt,l)} \u2502 ${Lt} \u2502`;if(le=$(le,y),!Jt(le,k)){let vr=De(C.default.blue(X.name),lt-3);le=`${Ft}${ue(vr,lt)} \u2502 ${J(`${Ot}s`,a)} \u2502 ${J(Wt,l)} \u2502 ${Lt} \u2502`,le=$(le,y)}w.push(le)}}let wr="\u2500".repeat(n),br="\u2500".repeat(a),yr="\u2500".repeat(l),Sr="\u2500".repeat(g),it=`\u2514\u2500${wr}\u2500\u2534\u2500${br}\u2500\u2534\u2500${yr}\u2500\u2534\u2500${Sr}\u2500\u2518`;return it=$(it,y,!0),w.push(it),w.join(`
11
+ `)}function qt(o,e){if(o===0)return C.default.gray;let t=o/e;return t>=.8?C.default.red:t>=.5?C.default.yellow:C.default.green}function Gt(o,e,t,r,s,i,n=!1,a=0,l=1,c=!1){let d=o/t,m=(o+e)/t,p=Math.round(d*r),h=Math.round(m*r);if(l>1&&e===0){let A=a*1e-4;p=Math.round((d+A)*r),h=p+1}else h<=p&&(h=p+1);p=Math.max(0,Math.min(p,r-1)),h=Math.max(p+1,Math.min(h,r));let g;if(n)g=C.default.cyan;else if(c)g=C.default.blue;else if(s===0)g=C.default.gray;else{let A=s/i;A>=.8?g=C.default.red:A>=.5?g=C.default.yellow:g=C.default.green}let y=m>=.99||h>=r?r:h,k="";for(let A=0;A<p;A++)k+=C.default.gray("\u2591");let $=y-p,I="\u2588".repeat($);k+=g(I);let H=r-y;for(let A=0;A<H;A++)k+=C.default.gray("\u2591");return k}function Te(o){return(0,ht.default)(o)}function De(o,e){if(Te(o)<=e)return o;let s=e-2;if(s<1)return"..";let i=/\u001b\[[0-9;]*m/g,n=[],a;for(;(a=i.exec(o))!==null;)n.push(a[0]);let l=o.replace(i,""),c="",d=0;for(let f=0;f<l.length;f++){let m=l[f],p=(0,ht.default)(m);if(d+p>s)break;c+=m,d+=p}return c+="..",n.length>0&&c.length>0?n[0]+c+(n[n.length-1]??""):c}function ue(o,e){let t=Te(o);return t>=e?De(o,e):o+" ".repeat(e-t)}function J(o,e){let t=Te(o);return t>=e?De(o,e):" ".repeat(e-t)+o}var _e=S(require("boxen"),1),we=S(require("chalk"),1);function gt(o,e,t,r={}){let{borderColor:s="cyan",isNested:i=!1}=r,n;e!==void 0&&(t?n=`line ${e} in ${t}`:n=`line ${e}`);let a=i?`\u2502 ${o}`:`> ${o}`;return(0,_e.default)(a,{title:n,borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:s})}function be(o,e=!1,t){let r=o?"\u2713 Completed":"\u2717 Failed",s=o?we.default.green(r):we.default.red(r);if(t!==void 0){let i=ye(t);return`${s} ${we.default.gray(`(${i})`)}`}return s}function Ie(o){return(0,_e.default)(`\u2717 ${o}`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"red"})}function Xt(o){return(0,_e.default)(`> Starting parallel execution (${o} branches)`,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"yellow"})}function Kt(o){let e=o?"\u2713 All parallel branches completed":"\u2717 Some parallel branches failed";return o?we.default.green(e):we.default.red(e)}function wt(o,e=!1){return`${e?"| \u2502 ":"\u2502 "}${o}`}function ye(o){return`${(o/1e3).toFixed(3)}s`}var Qt=require("fs"),eo=require("path"),pe=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 i=this.workspace.getVariable(r),n=this.workspace.getFact(r),a=i??(n!==void 0?n.toString():void 0);if(a===void 0||a!==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,eo.resolve)(process.cwd(),t);return(0,Qt.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 bt=S(require("log-update"),1);var yt=1e3;function Br(o,e,t){return e.parallel.map((r,s)=>({workspace:o.workspace.clone(),stepIndex:t.stepIndex*yt+s,branchIndex:s,lineNumber:t.lineNumber,fileName:t.fileName}))}function to(o,e){return"run"in o?o.run:"choose"in o?`Choose: ${o.choose.message}`:"prompt"in o?`Prompt: ${o.prompt.message}`:"fail"in o?`Fail: ${o.fail.message}`:`Branch ${e+1}`}function Or(o,e){let t=0;for(let r=0;r<o.length;r++){let s=o[r],i=e[r];s.when&&!new pe(i.workspace).evaluate(s.when)||t++}return t}function Ue(o,e,t=!1){let r=o.map(s=>{let i=s.index+1,n="",a="";switch(s.status){case"pending":n="\u25CB",a=`Branch ${i}: ${s.name} - Pending`;break;case"running":n=e,a=`Branch ${i}: ${s.name} - Running...`;break;case"success":n="\u2713",a=`Branch ${i}: ${s.name} - Completed`;break;case"failed":n="\u2717",a=`Branch ${i}: ${s.name} - Failed${s.error?`: ${s.error}`:""}`;break}return`${n} ${a}`});(0,bt.default)(r.join(`
12
+ `))}async function Lr(o,e,t,r){let s=[],i=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],n=0;for(let d=0;d<t.length;d++){let f=t[d],m=r[d];if(f.when&&!new pe(m.workspace).evaluate(f.when))continue;let p=e(f,d);s.push({index:d,name:p,status:"pending"})}let a=setInterval(()=>{n=(n+1)%i.length,Ue(s,i[n])},100),l=s.map(async d=>{let{index:f}=d,m=t[f],p=r[f];d.status="running";try{let h=await o.executeStep(m,p,!0);if(d.status="success",Ue(s,i[n]),o.recordBranch){let g="run"in m?{resolvedCommand:m.run}:void 0;o.recordBranch(m,p,h,"success",g)}return{index:f,result:h,context:p}}catch(h){p.workspace.setStepResult(p.stepIndex,!1);let g=h instanceof Error?h.message:String(h);if(d.status="failed",d.error=g,Ue(s,i[n]),o.recordBranch){let w="run"in m?{resolvedCommand:m.run}:void 0;o.recordBranch(m,p,void 0,"failure",w)}return{index:f,error:h,context:p}}}),c=await Promise.all(l);return clearInterval(a),Ue(s,"",!0),bt.default.done(),c}function Fr(o,e,t,r,s){let i=!0,n=!1;console.log("");for(let l of t){if(!l)continue;n=!0;let{index:c,result:d,error:f,context:m}=l;if(f){i=!1;let p=`Branch ${c+1} failed: ${f instanceof Error?f.message:String(f)}`,h=Ie(p);console.error(h)}else if(d&&typeof d=="object"&&"stdout"in d){let p=d;if(i=i&&p.success,p.stdout.length>0||p.stderr.length>0||!p.success){let h=r[c],g=e(h,c);o.taskRunner.displayBufferedOutput(p,g,!1,m.lineNumber,m.fileName)}}}n||console.log("\u26A0\uFE0F All parallel branches were skipped (conditions not met)");let a=Kt(i);return console.log(a),i}function Wr(o,e){for(let t of e){let r=t.workspace.getAllFacts(),s=t.workspace.getAllVariables();for(let[i,n]of r)o.workspace.setFact(i,n);for(let[i,n]of s)o.workspace.setVariable(i,n)}}async function oo(o,e,t){let r=Br(o,e,t),s=Or(e.parallel,r),i=Xt(s);console.log(i);let n=await Lr(o,to,e.parallel,r),a=Fr(o,to,n,e.parallel,t);if(o.setStepResult(t.stepIndex,a),!a){let l=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Parallel step ${t.stepIndex}${l} failed: one or more branches failed`)}Wr(o,r)}var St=require("jsonpath-plus"),ro=require("yaml");function no(o,e){try{let t=e.join(`
13
+ `);if(!("regex"in o)&&!("json"in o)&&!("yaml"in o)&&!("yml"in o)&&!("kv"in o)&&!("after"in o)&&!("before"in o)&&!("line"in o))return t;if("regex"in o){let r=new RegExp(o.regex),s=t.match(r);return s&&s[1]?s[1]:null}if("json"in o)try{let r=JSON.parse(t),s=(0,St.JSONPath)({path:o.json,json:r});if(s&&s.length>0){let i=s[0];return typeof i=="string"?i:JSON.stringify(i)}return null}catch{return null}if("yaml"in o||"yml"in o)try{let r=(0,ro.parse)(t),s="yaml"in o?o.yaml:o.yml,i=(0,St.JSONPath)({path:s,json:r});if(i&&i.length>0){let n=i[0];return typeof n=="string"?n:JSON.stringify(n)}return null}catch{return null}if("kv"in o){let r=o.kv;for(let s of e){let i=s.trim();if(!i||i.startsWith("#"))continue;let n=`^${r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\s*=\\s*(.+)$`,a=i.match(new RegExp(n));if(a&&a[1])return a[1].trim().replace(/^["']|["']$/g,"")}return null}if("after"in o||"before"in o){let r="after"in o?o.after:"",s="before"in o?o.before:void 0;if(r){let i=t.indexOf(r);if(i===-1)return null;let n=i+r.length,a=t.length;if(s){let l=t.indexOf(s,n);if(l===-1)return null;a=l}return t.substring(n,a).trim()}if(s){let i=t.indexOf(s);return i===-1?null:t.substring(0,i).trim()}}if("line"in o){let{from:r,to:s}=o.line,i=Math.max(0,r-1),n=Math.min(e.length,s);return i>=e.length||n<=i||i<0||s<r?null:e.slice(i,n).join(`
14
+ `)}return null}catch{return null}}function Hr(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:t}function de(o,e){let t=/\{\{\s*(\w+)\s*\}\}/g;return o.replace(t,(r,s)=>Hr(s,e,r))}async function so(o,e,t,r,s){let{workspace:i,taskRunner:n,baseDir:a,globalShell:l,calculateBaseStepIndex:c}=o,d=c(t),f=de(e.run.trim(),i),m=e.shell??l,p=e.retry??0,h=p==="Infinity"||p===1/0,g=typeof p=="number"?p:0,w=e.timeout,y=!1,k=0,$=e.run.trim()!==f?`${f}
15
+ (template: ${e.run})`:f;for(;h||k<=g;){let I=await n.run(f,d,$,t.branchIndex,r,s,t.lineNumber,t.fileName,a,w,m),H=typeof I=="boolean"?I:I.success;if(y=I,H||!h&&k>=g)break;if(k++,h||k<=g){let A=Math.min(1e3*Math.pow(2,k-1),1e4);await new Promise(ot=>setTimeout(ot,A))}}return y}async function io(o,e,t,r,s){let i=await so(o,{run:e.run,timeout:e.timeout,retry:e.retry,shell:void 0},t,r,s);return(typeof i=="boolean"?i:i.success)||!e.onError?i:io(o,e.onError,t,r,s)}async function ao(o,e,t,r=!1,s=!1){let{workspace:i}=o,n=!!(r===!0||e.captures&&e.captures.length>0),a=await so(o,{run:e.run,timeout:e.timeout,retry:e.retry,shell:e.shell},t,n,s),l=typeof a=="boolean"?a:a.success;if(i.setStepResult(t.stepIndex,l),n&&typeof a=="object"&&"stdout"in a){let f=de(e.run.trim(),i),m=e.run.trim()!==f?`${f}
16
+ (template: ${e.run})`:f;o.taskRunner.displayBufferedOutput(a,m,!1,t.lineNumber,t.fileName)}if(e.captures&&typeof a=="object"&&"stdout"in a){let f=a.stdout||[];for(let m of e.captures){let p=no(m,f);p!==null&&m.as&&i.setVariable(m.as,p)}}if(l||!e.onError)return a;let c={run:e.onError.run,timeout:e.onError.timeout,retry:e.onError.retry,onError:e.onError.onError??void 0};return await io(o,c,t,r,s)}var V=require("fs/promises"),lo=require("os"),me=require("path"),co=S(require("dayjs"),1),Se=(0,me.join)((0,lo.homedir)(),".pipeliner","workflow-history"),xe=class{constructor(){}async saveHistory(e){await(0,V.mkdir)(Se,{recursive:!0});let t=(0,co.default)().format("YYYY-MM-DD_HH-mm-ss"),r=Math.random().toString(36).slice(2,6),s=(0,me.join)(Se,`workflow-${t}-${r}.json`);return await(0,V.writeFile)(s,JSON.stringify(e,null,2),{encoding:"utf8"}),s}async clearAllHistories(){await(0,V.rm)(Se,{recursive:!0,force:!0})}async removeHistory(e){await(0,V.rm)((0,me.join)(Se,e),{force:!0})}async getHistoryNames(){try{let t=(await(0,V.readdir)(Se)).map(r=>(0,me.basename)(r));return t.sort((r,s)=>{let i=l=>{let c=l.match(/workflow-(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-/);return c?c[1]:""},n=i(r),a=i(s);return n===a?s.localeCompare(r):a.localeCompare(n)}),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,me.join)(Se,e),{encoding:"utf8"});return JSON.parse(t)}};var ze=class{records=[];initialTimestamp=Date.now();recordStartTimestamp=Date.now();constructor(){this.records=[]}recordStart(){this.recordStartTimestamp=Date.now()}recordEnd(e,t,r,s,i){let n=this.getDuration();return this.records.push({step:e,context:t,output:r,duration:n,status:s,...i}),n}reset(){this.records=[],this.initialTimestamp=Date.now()}async save(){let e=new xe,t={initialTimestamp:this.initialTimestamp,records:this.records};return await e.saveHistory(t)}getDuration(){return Date.now()-this.recordStartTimestamp}getHistory(){return{initialTimestamp:this.initialTimestamp,records:this.records}}};var xt=require("child_process");var Ye=class{async run(e,t,r,s,i=!1,n=!1,a,l,c,d,f){return i?this.runBuffered(e,c,d,f):this.runRealtime(e,r??e,n,a,l,c,d,f)}async runBuffered(e,t,r,s){return new Promise((i,n)=>{let a=this.spawnWithShell(e,t,s),l=[],c=[],d="",f="",m=null;r&&r>0&&(m=setTimeout(()=>{a.kill("SIGTERM");let p=`Command timed out after ${r} seconds`;c.push(p),i({success:!1,stdout:l,stderr:c})},r*1e3)),a.stdout?.on("data",p=>{let h=p.toString(),{lines:g,remaining:w}=this.processStreamBuffer(h,d);l.push(...g),d=w}),a.stderr?.on("data",p=>{let h=p.toString(),{lines:g,remaining:w}=this.processStreamBuffer(h,f);c.push(...g),f=w}),a.on("close",p=>{m&&clearTimeout(m),d.trim()&&l.push(d),f.trim()&&c.push(f),i({success:p===0,stdout:l,stderr:c})}),a.on("error",p=>{m&&clearTimeout(m);let h=`Error: ${p.message}`;i({success:!1,stdout:l,stderr:[...c,h]})})})}async runRealtime(e,t,r,s,i,n,a,l){let d=gt(t,s,i,{borderColor:r?"green":"cyan"});console.log(d);let f=Date.now();return new Promise(m=>{let p=this.spawnWithShell(e,n,l),h="",g="",w=null;a&&a>0&&(w=setTimeout(()=>{p.kill("SIGTERM");let y=`Command timed out after ${a} seconds`,k=Ie(y);console.error(k);let $=Date.now()-f,I=be(!1,!1,$);console.log(I),m(!1)},a*1e3)),p.stdout?.on("data",y=>{let k=y.toString(),{lines:$,remaining:I}=this.processStreamBuffer(k,h);$.forEach(H=>process.stdout.write(`\u2502 ${H}
17
+ `)),h=I}),p.stderr?.on("data",y=>{let k=y.toString(),{lines:$,remaining:I}=this.processStreamBuffer(k,g);$.forEach(H=>process.stderr.write(`\u2502 ${H}
18
+ `)),g=I}),p.on("close",y=>{w&&clearTimeout(w),h.trim()&&process.stdout.write(`\u2502 ${h}
16
19
  `),g.trim()&&process.stderr.write(`\u2502 ${g}
17
- `);let k=y===0,$=Date.now()-f,I=we(k,!1,$);console.log(I),m(k)}),u.on("error",y=>{w&&clearTimeout(w);let k=Ie(`Error: ${y.message}`);console.error(k),m(!1)})})}createSpawnOptions(e){let t={stdio:["inherit","pipe","pipe"],shell:!0};return e&&(t.cwd=e),t}spawnWithShell(e,t,o){if(o&&o.length>0){let s=o[0],i=[...o.slice(1),e],n={stdio:["inherit","pipe","pipe"]};return t&&(n.cwd=t),(0,St.spawn)(s,i,n)}else{let s=process.env.SHELL??(process.platform==="win32"?"cmd.exe":"/bin/sh"),i=process.platform==="win32"?"/c":"-c",n={stdio:["inherit","pipe","pipe"]};return t&&(n.cwd=t),(0,St.spawn)(s,[i,e],n)}}processStreamBuffer(e,t){let o=t+e,s=[],i=o;for(;i.includes(`
20
+ `);let k=y===0,$=Date.now()-f,I=be(k,!1,$);console.log(I),m(k)}),p.on("error",y=>{w&&clearTimeout(w);let k=Ie(`Error: ${y.message}`);console.error(k),m(!1)})})}createSpawnOptions(e){let t={stdio:["inherit","pipe","pipe"],shell:!0};return e&&(t.cwd=e),t}spawnWithShell(e,t,r){if(r&&r.length>0){let s=r[0],i=[...r.slice(1),e],n={stdio:["inherit","pipe","pipe"]};return t&&(n.cwd=t),(0,xt.spawn)(s,i,n)}else{let s=process.env.SHELL??(process.platform==="win32"?"cmd.exe":"/bin/sh"),i=process.platform==="win32"?"/c":"-c",n={stdio:["inherit","pipe","pipe"]};return t&&(n.cwd=t),(0,xt.spawn)(s,[i,e],n)}}processStreamBuffer(e,t){let r=t+e,s=[],i=r;for(;i.includes(`
18
21
  `);){let n=i.indexOf(`
19
22
  `),a=i.substring(0,n);i=i.substring(n+1),s.push(a)}return{lines:s,remaining:i}}formatNestedOutput(e,t){t?e.split(`
20
- `).forEach(o=>{o.trim()&&console.log(`| ${o}`)}):console.log(e)}displayBufferedOutput(e,t,o=!1,s,i){let n=gt(t,s,i,{borderColor:"cyan",isNested:o});this.formatNestedOutput(n,o),e.stdout.forEach(l=>{let c=wt(l,o);process.stdout.write(`${c}
21
- `)}),e.stderr.forEach(l=>{let c=wt(l,o);process.stderr.write(`${c}
22
- `)});let a=we(e.success,o);console.log(a)}};var Je=class r{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,o){this.state.stepResults.set(e,{success:t,exitCode:o}),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 r;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 ke=class{workspace;taskRunner;choicePrompt;textPrompt;baseDir;globalShell;constructor(){this.workspace=new Je,this.taskRunner=new Ye,this.choicePrompt=new B,this.textPrompt=new He}resolveBaseDir(e){if(e.baseDir)if((0,de.isAbsolute)(e.baseDir))this.baseDir=e.baseDir;else if(e._filePath){let t=(0,de.dirname)(e._filePath);this.baseDir=(0,de.resolve)(t,e.baseDir)}else this.baseDir=(0,de.resolve)(process.cwd(),e.baseDir)}createStepContext(e,t){let o={workspace:this.workspace,stepIndex:e};return t._lineNumbers&&(o.lineNumber=t._lineNumbers.get(e)),t._fileName&&(o.fileName=t._fileName),o}evaluateStepCondition(e){return e.when?new ue(this.workspace).evaluate(e.when):!0}calculateBaseStepIndex(e){return e.branchIndex===void 0?e.stepIndex:Math.floor(e.stepIndex/yt)}isRunStep(e){return"run"in e}getRecordResolved(e){if("run"in e)return{resolvedCommand:ye(e.run.trim(),this.workspace)};if("choose"in e){let t=e.choose.as&&this.workspace.hasVariable(e.choose.as)?this.workspace.getVariable(e.choose.as):e.choose.options.find(o=>this.workspace.getChoice(o.id))?.id;return t!==void 0?{choiceValue:t}:void 0}if("prompt"in e){let t=this.workspace.getFact(e.prompt.as);return t!==void 0?{promptValue:t}:void 0}}async execute(e,t){if(t?.profileVars&&Object.keys(t.profileVars).length>0)for(let[c,p]of Object.entries(t.profileVars))this.workspace.setVariable(c,p);this.resolveBaseDir(e),this.globalShell=e.shell;let o=new ze,s=Date.now();for(let c=0;c<e.steps.length;c++){let p=e.steps[c],f=this.createStepContext(c,e),m=!!p.when;if(this.evaluateStepCondition(p)){o.recordStart();try{let u=await this.executeStep(p,f,!1,m,o);"parallel"in p||this.handleStepResult(p,f,c,u,o)}catch(u){throw"parallel"in p||this.handleStepError(p,f,c,u,o),u}}}let i=Date.now()-s,n=be(i);console.log(ao.default.cyan(`
23
- Total execution time: ${n}`));let a=o.getHistory(),l=Ve(a);l&&console.log(l),await o.save(),o.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,o,s,i){let n=this.isRunStep(e)?(()=>{let p=this.workspace.getStepResult(o);return p?p.success:!0})():this.isStepSuccessful(s,e),a=n?"success":"failure",l=this.getRecordResolved(e),c=i.recordEnd(e,t,s,a,l);if(!this.isRunStep(e)){let p=we(n,!1,c);console.log(p)}if(this.isRunStep(e)){if(e.continue===!1){let p=t.lineNumber?` (line ${t.lineNumber})`:"",f=n?`Step ${o}${p} completed, but workflow stopped due to continue: false`:`Step ${o}${p} failed`;throw new Error(f)}if(!n&&e.continue!==!0){let p=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Step ${o}${p} failed`)}}}handleStepError(e,t,o,s,i){this.workspace.setStepResult(o,!1);let n=s instanceof Error?s.message:String(s),a={success:!1,stdout:[],stderr:[n]},l=this.getRecordResolved(e);i.recordEnd(e,t,a,"failure",l)}fixMalformedStep(e){let o=e;return"choose"in e&&o.choose===null&&"message"in e&&"options"in e?{choose:{message:o.message,options:o.options,as:o.as},when:o.when}:"prompt"in e&&o.prompt===null&&"message"in e&&"as"in e?{prompt:{message:o.message,as:o.as,default:o.default},when:o.when}:e}async executeStep(e,t,o=!1,s=!1,i){if(e=this.fixMalformedStep(e),"run"in e){let n=await no({workspace:this.workspace,taskRunner:this.taskRunner,baseDir:this.baseDir,globalShell:this.globalShell,calculateBaseStepIndex:a=>this.calculateBaseStepIndex(a)},e,t,o,s);return o&&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 to({workspace:this.workspace,taskRunner:this.taskRunner,executeStep:(n,a,l)=>this.executeStep(n,a,l,!!n.when,i),setStepResult:(n,a)=>this.workspace.setStepResult(n,a),recordBranch:i?(n,a,l,c,p)=>{i.recordStart();let f=p||this.getRecordResolved(n);i.recordEnd(n,a,l,c,f)}:void 0},e,t);return}if("fail"in e){await this.executeFailStep(e,t);return}}async executeChooseStep(e,t){let o=e.choose.as,s=e.choose.options.map(a=>a.id);if(o&&this.workspace.hasVariable(o)){let a=this.workspace.getVariable(o)??"";if(s.includes(a)){this.workspace.setChoice(a,a),this.workspace.setStepResult(t.stepIndex,!0);return}}let i=await this.choicePrompt.prompt(e.choose.message,e.choose.options);if(!i?.id)throw new Error(`Invalid choice result: ${JSON.stringify(i)}`);let n=o??i.id;this.workspace.setChoice(i.id,i.id),this.workspace.setVariable(n,i.id),this.workspace.setStepResult(t.stepIndex,!0)}async executePromptStep(e,t){let o=e.prompt.as;if(this.workspace.hasVariable(o)){let a=this.workspace.getVariable(o)??"";this.workspace.setFact(o,a),this.workspace.setStepResult(t.stepIndex,!0);return}let s=ye(e.prompt.message,this.workspace),i=e.prompt.default?ye(e.prompt.default,this.workspace):void 0,n=await this.textPrompt.prompt(s,i);this.workspace.setVariable(o,n),this.workspace.setFact(o,n),this.workspace.setStepResult(t.stepIndex,!0)}async executeFailStep(e,t){let o=new Error(e.fail.message);throw o.stack=void 0,o}};var mo=require("yaml"),$t=require("zod");var d=require("zod"),Fr=d.z.object({file:d.z.string()}),Wr=d.z.object({var:d.z.union([d.z.string(),d.z.record(d.z.string(),d.z.string())]).optional(),has:d.z.string().optional()}),Hr=d.z.object({status:d.z.object({fact:d.z.string(),is:d.z.enum(["ready","failed","pending"])})}),Vr=d.z.object({step:d.z.object({success:d.z.boolean()}).optional(),last_step:d.z.enum(["success","failure"]).optional()}),_r=d.z.object({choice:d.z.string()}),Ur=d.z.union([Fr,_r,Wr,Hr,Vr]),_=d.z.lazy(()=>d.z.union([Ur,d.z.object({all:d.z.array(_)}),d.z.object({any:d.z.array(_)}),d.z.object({not:_})])),lo=d.z.lazy(()=>d.z.object({run:d.z.string(),timeout:d.z.number().optional(),retry:d.z.union([d.z.number(),d.z.literal("Infinity")]).optional(),onError:lo.optional()})),co=d.z.object({run:d.z.string(),when:_.optional(),timeout:d.z.number().optional(),retry:d.z.union([d.z.number(),d.z.literal("Infinity")]).optional(),shell:d.z.array(d.z.string()).min(1,"shell must have at least one element").optional(),continue:d.z.boolean().optional(),onError:lo.optional()}),zr=d.z.object({choose:d.z.object({message:d.z.string(),options:d.z.array(d.z.object({id:d.z.string(),label:d.z.string()})),as:d.z.string().optional()}),when:_.optional()}),Yr=d.z.object({prompt:d.z.object({message:d.z.string(),as:d.z.string(),default:d.z.string().optional(),validate:d.z.string().optional()}),when:_.optional()});function uo(r){if(!r||typeof r!="object")return{found:!1};let e=r;if("choose"in e)return{found:!0,type:"choose"};if("prompt"in e)return{found:!0,type:"prompt"};if("parallel"in e&&Array.isArray(e.parallel))for(let t of e.parallel){let o=uo(t);if(o.found)return o}return{found:!1}}var po=d.z.lazy(()=>d.z.union([co,d.z.object({parallel:d.z.array(d.z.lazy(()=>po)),when:_.optional()}),d.z.object({fail:d.z.object({message:d.z.string()}),when:_.optional()})]).superRefine((r,e)=>{let t=uo(r);t.found&&e.addIssue({code:d.z.ZodIssueCode.custom,message:`'${t.type}' step is not allowed inside 'parallel' block (user input cannot run in parallel)`})})),Jr=d.z.lazy(()=>d.z.union([co,zr,Yr,d.z.object({parallel:d.z.array(po),when:_.optional()}),d.z.object({fail:d.z.object({message:d.z.string()}),when:_.optional()})])),qr=d.z.object({name:d.z.string().min(1,"Profile name must be non-empty"),var:d.z.record(d.z.string(),d.z.union([d.z.string(),d.z.number(),d.z.boolean()]).transform(String))}),Gr=d.z.object({name:d.z.string().optional(),baseDir:d.z.string().optional(),shell:d.z.array(d.z.string()).min(1,"shell must have at least one element").optional(),profiles:d.z.array(qr).optional(),steps:d.z.array(Jr).min(1,"Workflow must have at least one step")});function xt(r){return Gr.parse(r)}function fo(r,e){let t=r.path;if(r.code==="custom"){let s=kt(t);return` - ${r.message}${s}`}if(r.message==="Invalid input"){let s=kt(t),i=Zr(t,e);return i?` - ${i}${s}`:` - Invalid step type${s}`}let o=kt(t);return` - ${r.message}${o}`}function kt(r){if(r.length===0)return"";let e=[];for(let t=0;t<r.length;t++){let o=r[t],s=r[t+1];o==="steps"&&typeof s=="number"?(e.push(`step ${s+1}`),t++):o==="parallel"&&typeof s=="number"?(e.push(`parallel branch ${s+1}`),t++):typeof o=="string"&&o!=="steps"&&o!=="parallel"&&e.push(o)}return e.length>0?` (${e.join(" \u2192 ")})`:""}function T(r,e,t){let o=t?`
23
+ `).forEach(r=>{r.trim()&&console.log(`| ${r}`)}):console.log(e)}displayBufferedOutput(e,t,r=!1,s,i){let n=gt(t,s,i,{borderColor:"cyan",isNested:r});this.formatNestedOutput(n,r),e.stdout.forEach(l=>{let c=wt(l,r);process.stdout.write(`${c}
24
+ `)}),e.stderr.forEach(l=>{let c=wt(l,r);process.stderr.write(`${c}
25
+ `)});let a=be(e.success,r);console.log(a)}};var Je=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 ke=class{workspace;taskRunner;choicePrompt;textPrompt;baseDir;globalShell;constructor(){this.workspace=new Je,this.taskRunner=new Ye,this.choicePrompt=new B,this.textPrompt=new He}resolveBaseDir(e){if(!e.baseDir){e._filePath&&(this.baseDir=(0,K.dirname)(e._filePath));return}if((0,K.isAbsolute)(e.baseDir))this.baseDir=e.baseDir;else if(e._filePath){let t=(0,K.dirname)(e._filePath);this.baseDir=(0,K.resolve)(t,e.baseDir)}else this.baseDir=(0,K.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 pe(this.workspace).evaluate(e.when):!0}calculateBaseStepIndex(e){return e.branchIndex===void 0?e.stepIndex:Math.floor(e.stepIndex/yt)}isRunStep(e){return"run"in e}getRecordResolved(e){if("run"in e)return{resolvedCommand:de(e.run.trim(),this.workspace)};if("choose"in e){let t=e.choose.as&&this.workspace.hasVariable(e.choose.as)?this.workspace.getVariable(e.choose.as):e.choose.options.find(r=>this.workspace.getChoice(r.id))?.id;return t!==void 0?{choiceValue:t}:void 0}if("prompt"in e){let t=this.workspace.getFact(e.prompt.as);return t!==void 0?{promptValue:t}:void 0}}async execute(e,t){if(t?.profileVars&&Object.keys(t.profileVars).length>0)for(let[c,d]of Object.entries(t.profileVars))this.workspace.setVariable(c,d);this.resolveBaseDir(e),this.globalShell=e.shell;let r=new ze,s=Date.now();for(let c=0;c<e.steps.length;c++){let d=e.steps[c],f=this.createStepContext(c,e),m=!!d.when;if(this.evaluateStepCondition(d)){r.recordStart();try{let p=await this.executeStep(d,f,!1,m,r);"parallel"in d||this.handleStepResult(d,f,c,p,r)}catch(p){throw"parallel"in d||this.handleStepError(d,f,c,p,r),p}}}let i=Date.now()-s,n=ye(i);console.log(uo.default.cyan(`
26
+ Total execution time: ${n}`));let a=r.getHistory(),l=Ve(a);l&&console.log(l),await r.save(),r.reset()}isStepSuccessful(e,t){return"run"in t?typeof e=="boolean"?e:e&&typeof e=="object"&&"success"in e?e.success:!1:!0}handleStepResult(e,t,r,s,i){let n=this.isRunStep(e)?(()=>{let d=this.workspace.getStepResult(r);return d?d.success:!0})():this.isStepSuccessful(s,e),a=n?"success":"failure",l=this.getRecordResolved(e),c=i.recordEnd(e,t,s,a,l);if(!this.isRunStep(e)){let d=be(n,!1,c);console.log(d)}if(this.isRunStep(e)){if(e.continue===!1){let d=t.lineNumber?` (line ${t.lineNumber})`:"",f=n?`Step ${r}${d} completed, but workflow stopped due to continue: false`:`Step ${r}${d} failed`;throw new Error(f)}if(!n&&e.continue!==!0){let d=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Step ${r}${d} failed`)}}}handleStepError(e,t,r,s,i){this.workspace.setStepResult(r,!1);let n=s instanceof Error?s.message:String(s),a={success:!1,stdout:[],stderr:[n]},l=this.getRecordResolved(e);i.recordEnd(e,t,a,"failure",l)}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,i){if(e=this.fixMalformedStep(e),"run"in e){let n=await ao({workspace:this.workspace,taskRunner:this.taskRunner,baseDir:this.baseDir,globalShell:this.globalShell,calculateBaseStepIndex:a=>this.calculateBaseStepIndex(a)},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 oo({workspace:this.workspace,taskRunner:this.taskRunner,executeStep:(n,a,l)=>this.executeStep(n,a,l,!!n.when,i),setStepResult:(n,a)=>this.workspace.setStepResult(n,a),recordBranch:i?(n,a,l,c,d)=>{i.recordStart();let f=d||this.getRecordResolved(n);i.recordEnd(n,a,l,c,f)}:void 0},e,t);return}if("fail"in e){await this.executeFailStep(e,t);return}}async executeChooseStep(e,t){let r=e.choose.as,s=e.choose.options.map(a=>a.id);if(r&&this.workspace.hasVariable(r)){let a=this.workspace.getVariable(r)??"";if(s.includes(a)){this.workspace.setChoice(a,a),this.workspace.setStepResult(t.stepIndex,!0);return}}let i=await this.choicePrompt.prompt(e.choose.message,e.choose.options);if(!i?.id)throw new Error(`Invalid choice result: ${JSON.stringify(i)}`);let n=r??i.id;this.workspace.setChoice(i.id,i.id),this.workspace.setVariable(n,i.id),this.workspace.setStepResult(t.stepIndex,!0)}async executePromptStep(e,t){let r=e.prompt.as;if(this.workspace.hasVariable(r)){let a=this.workspace.getVariable(r)??"";this.workspace.setFact(r,a),this.workspace.setStepResult(t.stepIndex,!0);return}let s=de(e.prompt.message,this.workspace),i=e.prompt.default?de(e.prompt.default,this.workspace):void 0,n=await this.textPrompt.prompt(s,i);this.workspace.setVariable(r,n),this.workspace.setFact(r,n),this.workspace.setStepResult(t.stepIndex,!0)}async executeFailStep(e,t){let r=new Error(e.fail.message);throw r.stack=void 0,r}};var go=require("yaml"),Rt=require("zod");var u=require("zod"),Vr=u.z.object({file:u.z.string()}),_r=u.z.object({var:u.z.union([u.z.string(),u.z.record(u.z.string(),u.z.string())]).optional(),has:u.z.string().optional()}),Ur=u.z.object({status:u.z.object({fact:u.z.string(),is:u.z.enum(["ready","failed","pending"])})}),zr=u.z.object({step:u.z.object({success:u.z.boolean()}).optional(),last_step:u.z.enum(["success","failure"]).optional()}),Yr=u.z.object({choice:u.z.string()}),Jr=u.z.union([Vr,Yr,_r,Ur,zr]),_=u.z.lazy(()=>u.z.union([Jr,u.z.object({all:u.z.array(_)}),u.z.object({any:u.z.array(_)}),u.z.object({not:_})])),po=u.z.lazy(()=>u.z.object({run:u.z.string(),timeout:u.z.number().optional(),retry:u.z.union([u.z.number(),u.z.literal("Infinity")]).optional(),onError:po.optional()})),qr=u.z.object({as:u.z.string()}),Gr=u.z.object({regex:u.z.string(),as:u.z.string()}),Zr=u.z.object({json:u.z.string(),as:u.z.string()}),Xr=u.z.object({yaml:u.z.string(),as:u.z.string()}),Kr=u.z.object({yml:u.z.string(),as:u.z.string()}),Qr=u.z.object({kv:u.z.string(),as:u.z.string()}),en=u.z.object({after:u.z.string(),as:u.z.string()}),tn=u.z.object({before:u.z.string(),as:u.z.string()}),on=u.z.object({after:u.z.string(),before:u.z.string(),as:u.z.string()}),rn=u.z.object({line:u.z.object({from:u.z.number(),to:u.z.number()}),as:u.z.string()}),nn=u.z.union([Gr,Zr,Xr,Kr,Qr,on,en,tn,rn,qr]),mo=u.z.object({run:u.z.string(),when:_.optional(),timeout:u.z.number().optional(),retry:u.z.union([u.z.number(),u.z.literal("Infinity")]).optional(),shell:u.z.array(u.z.string()).min(1,"shell must have at least one element").optional(),continue:u.z.boolean().optional(),onError:po.optional(),captures:u.z.array(nn).optional()}),sn=u.z.object({choose:u.z.object({message:u.z.string(),options:u.z.array(u.z.object({id:u.z.string(),label:u.z.string()})),as:u.z.string().optional()}),when:_.optional()}),an=u.z.object({prompt:u.z.object({message:u.z.string(),as:u.z.string(),default:u.z.string().optional(),validate:u.z.string().optional()}),when:_.optional()});function fo(o){if(!o||typeof o!="object")return{found:!1};let e=o;if("choose"in e)return{found:!0,type:"choose"};if("prompt"in e)return{found:!0,type:"prompt"};if("parallel"in e&&Array.isArray(e.parallel))for(let t of e.parallel){let r=fo(t);if(r.found)return r}return{found:!1}}var ho=u.z.lazy(()=>u.z.union([mo,u.z.object({parallel:u.z.array(u.z.lazy(()=>ho)),when:_.optional()}),u.z.object({fail:u.z.object({message:u.z.string()}),when:_.optional()})]).superRefine((o,e)=>{let t=fo(o);t.found&&e.addIssue({code:u.z.ZodIssueCode.custom,message:`'${t.type}' step is not allowed inside 'parallel' block (user input cannot run in parallel)`})})),ln=u.z.lazy(()=>u.z.union([mo,sn,an,u.z.object({parallel:u.z.array(ho),when:_.optional()}),u.z.object({fail:u.z.object({message:u.z.string()}),when:_.optional()})])),cn=u.z.object({name:u.z.string().min(1,"Profile name must be non-empty"),var:u.z.record(u.z.string(),u.z.union([u.z.string(),u.z.number(),u.z.boolean()]).transform(String))}),un=u.z.object({name:u.z.string().optional(),baseDir:u.z.string().optional(),shell:u.z.array(u.z.string()).min(1,"shell must have at least one element").optional(),profiles:u.z.array(cn).optional(),steps:u.z.array(ln).min(1,"Workflow must have at least one step")});function kt(o){return un.parse(o)}function wo(o,e){let t=o.path;if(o.code==="custom"){let s=vt(t);return` - ${o.message}${s}`}if(o.message==="Invalid input"){let s=vt(t),i=pn(t,e);return i?` - ${i}${s}`:` - Invalid step type${s}`}let r=vt(t);return` - ${o.message}${r}`}function vt(o){if(o.length===0)return"";let e=[];for(let t=0;t<o.length;t++){let r=o[t],s=o[t+1];r==="steps"&&typeof s=="number"?(e.push(`step ${s+1}`),t++):r==="parallel"&&typeof s=="number"?(e.push(`parallel branch ${s+1}`),t++):typeof r=="string"&&r!=="steps"&&r!=="parallel"&&e.push(r)}return e.length>0?` (${e.join(" \u2192 ")})`:""}function T(o,e,t){let r=t?`
24
27
  Reason: ${t}`:"";throw new Error(`Invalid workflow structure:
25
- - ${e} (step ${r+1})${o}`)}function ho(r,e,t=!1,o=[]){let s=["run","choose","prompt","parallel","fail"],i=s.find(n=>n in r);if(!i){let n=Object.keys(r).filter(a=>a!=="when");T(e,`Unknown step type. Found keys: [${n.join(", ")}]. Valid types: ${s.join(", ")}`)}if(i==="run"){let n=r.run;if(typeof n!="string"&&T(e,"'run' must be a string command"),n===""&&T(e,"'run' command cannot be empty"),"shell"in r&&r.shell!==void 0){Array.isArray(r.shell)||T(e,"'shell' must be an array");let a=r.shell;a.length===0&&T(e,"'shell' cannot be empty","Shell configuration must have at least one element (program name)");for(let l=0;l<a.length;l++)typeof a[l]!="string"&&T(e,`'shell[${l}]' must be a string`)}}if(i==="choose"){if(t){let l=o.join(" \u2192 ");throw new Error(`Invalid workflow structure:
28
+ - ${e} (step ${o+1})${r}`)}function bo(o,e,t=!1,r=[]){let s=["run","choose","prompt","parallel","fail"],i=s.find(n=>n in o);if(!i){let n=Object.keys(o).filter(a=>a!=="when");T(e,`Unknown step type. Found keys: [${n.join(", ")}]. Valid types: ${s.join(", ")}`)}if(i==="run"){let n=o.run;if(typeof n!="string"&&T(e,"'run' must be a string command"),n===""&&T(e,"'run' command cannot be empty"),"shell"in o&&o.shell!==void 0){Array.isArray(o.shell)||T(e,"'shell' must be an array");let a=o.shell;a.length===0&&T(e,"'shell' cannot be empty","Shell configuration must have at least one element (program name)");for(let l=0;l<a.length;l++)typeof a[l]!="string"&&T(e,`'shell[${l}]' must be a string`)}}if(i==="choose"){if(t){let l=r.join(" \u2192 ");throw new Error(`Invalid workflow structure:
26
29
  - 'choose' step is not allowed inside 'parallel' block (step ${e+1}, ${l})
27
- Reason: User input prompts cannot run in parallel`)}let n=r.choose;(!n||typeof n!="object")&&T(e,"'choose' must be an object with 'message' and 'options'");let a=n;(!a.message||typeof a.message!="string")&&T(e,"'choose.message' is required and must be a string"),Array.isArray(a.options)||T(e,"'choose.options' is required and must be an array"),a.options.length===0&&T(e,"'choose.options' cannot be empty","At least one option is required");for(let l=0;l<a.options.length;l++){let c=a.options[l];(!c||typeof c!="object")&&T(e,`'choose.options[${l}]' must be an object with 'id' and 'label'`),(!c.id||typeof c.id!="string")&&T(e,`'choose.options[${l}].id' is required and must be a string`),(!c.label||typeof c.label!="string")&&T(e,`'choose.options[${l}].label' is required and must be a string`)}}if(i==="prompt"){if(t){let l=o.join(" \u2192 ");throw new Error(`Invalid workflow structure:
30
+ Reason: User input prompts cannot run in parallel`)}let n=o.choose;(!n||typeof n!="object")&&T(e,"'choose' must be an object with 'message' and 'options'");let a=n;(!a.message||typeof a.message!="string")&&T(e,"'choose.message' is required and must be a string"),Array.isArray(a.options)||T(e,"'choose.options' is required and must be an array"),a.options.length===0&&T(e,"'choose.options' cannot be empty","At least one option is required");for(let l=0;l<a.options.length;l++){let c=a.options[l];(!c||typeof c!="object")&&T(e,`'choose.options[${l}]' must be an object with 'id' and 'label'`),(!c.id||typeof c.id!="string")&&T(e,`'choose.options[${l}].id' is required and must be a string`),(!c.label||typeof c.label!="string")&&T(e,`'choose.options[${l}].label' is required and must be a string`)}}if(i==="prompt"){if(t){let l=r.join(" \u2192 ");throw new Error(`Invalid workflow structure:
28
31
  - 'prompt' step is not allowed inside 'parallel' block (step ${e+1}, ${l})
29
- Reason: User input prompts cannot run in parallel`)}let n=r.prompt;(!n||typeof n!="object")&&T(e,"'prompt' must be an object with 'message' and 'as'");let a=n;(!a.message||typeof a.message!="string")&&T(e,"'prompt.message' is required and must be a string"),(!a.as||typeof a.as!="string")&&T(e,"'prompt.as' is required and must be a string","The 'as' field specifies the variable name to store the user's input")}if(i==="parallel"){let n=r.parallel;Array.isArray(n)||T(e,"'parallel' must be an array of steps"),n.length===0&&T(e,"'parallel' cannot be empty","At least one step is required");for(let a=0;a<n.length;a++){let l=n[a];(!l||typeof l!="object")&&T(e,`'parallel[${a}]' must be a valid step object`);let c=[...o,`branch ${a+1}`];ho(l,e,!0,c)}}if(i==="fail"){let n=r.fail;(!n||typeof n!="object")&&T(e,"'fail' must be an object with 'message'");let a=n;(!a.message||typeof a.message!="string")&&T(e,"'fail.message' is required and must be a string")}}function go(r){if(!r||typeof r!="object")throw new Error(`Invalid workflow structure:
30
- - Workflow must be an object`);let e=r;if("name"in e&&e.name!==void 0&&typeof e.name!="string")throw new Error(`Invalid workflow structure:
32
+ Reason: User input prompts cannot run in parallel`)}let n=o.prompt;(!n||typeof n!="object")&&T(e,"'prompt' must be an object with 'message' and 'as'");let a=n;(!a.message||typeof a.message!="string")&&T(e,"'prompt.message' is required and must be a string"),(!a.as||typeof a.as!="string")&&T(e,"'prompt.as' is required and must be a string","The 'as' field specifies the variable name to store the user's input")}if(i==="parallel"){let n=o.parallel;Array.isArray(n)||T(e,"'parallel' must be an array of steps"),n.length===0&&T(e,"'parallel' cannot be empty","At least one step is required");for(let a=0;a<n.length;a++){let l=n[a];(!l||typeof l!="object")&&T(e,`'parallel[${a}]' must be a valid step object`);let c=[...r,`branch ${a+1}`];bo(l,e,!0,c)}}if(i==="fail"){let n=o.fail;(!n||typeof n!="object")&&T(e,"'fail' must be an object with 'message'");let a=n;(!a.message||typeof a.message!="string")&&T(e,"'fail.message' is required and must be a string")}}function yo(o){if(!o||typeof o!="object")throw new Error(`Invalid workflow structure:
33
+ - Workflow must be an object`);let e=o;if("name"in e&&e.name!==void 0&&typeof e.name!="string")throw new Error(`Invalid workflow structure:
31
34
  - 'name' must be a string`);if("shell"in e&&e.shell!==void 0){if(!Array.isArray(e.shell))throw new Error(`Invalid workflow structure:
32
35
  - 'shell' must be an array`);if(e.shell.length===0)throw new Error(`Invalid workflow structure:
33
36
  - 'shell' cannot be empty
@@ -36,60 +39,60 @@ Total execution time: ${n}`));let a=o.getHistory(),l=Ve(a);l&&console.log(l),awa
36
39
  - 'steps' is required`);if(!Array.isArray(e.steps))throw new Error(`Invalid workflow structure:
37
40
  - 'steps' must be an array`);if(e.steps.length===0)throw new Error(`Invalid workflow structure:
38
41
  - 'steps' cannot be empty
39
- Reason: Workflow must have at least one step`);for(let t=0;t<e.steps.length;t++){let o=e.steps[t];if(!o||typeof o!="object")throw new Error(`Invalid workflow structure:
40
- - Step ${t+1} must be an object`);ho(o,t)}}function Zr(r,e){try{let t=e;for(let i of r)if(typeof i!="symbol")if(t&&typeof t=="object")t=t[i];else return null;if(!t||typeof t!="object")return null;let s=Object.keys(t);if(s.length>0){let i=["run","choose","prompt","parallel","fail"];if(!s.some(a=>i.includes(a)))return`Unknown step type. Found keys: [${s.join(", ")}]. Valid types: run, choose, prompt, parallel, fail`}return null}catch{return null}}function Rt(r){let e=r;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=>Rt(t))}:r}var qe=class{parse(e){let t;try{t=(0,mo.parse)(e)}catch(o){throw new Error(`Invalid YAML format: ${o instanceof Error?o.message:String(o)}`)}if(t&&typeof t=="object"&&"steps"in t){let o=t;Array.isArray(o.steps)&&(o.steps=o.steps.map(s=>Rt(s)))}go(t);try{return xt(t)}catch(o){if(o instanceof $t.ZodError){let s=o.issues.map(i=>fo(i,t)).filter(i=>i!==null).join(`
42
+ Reason: Workflow must have at least one step`);for(let t=0;t<e.steps.length;t++){let r=e.steps[t];if(!r||typeof r!="object")throw new Error(`Invalid workflow structure:
43
+ - Step ${t+1} must be an object`);bo(r,t)}}function pn(o,e){try{let t=e;for(let i of o)if(typeof i!="symbol")if(t&&typeof t=="object")t=t[i];else return null;if(!t||typeof t!="object")return null;let s=Object.keys(t);if(s.length>0){let i=["run","choose","prompt","parallel","fail"];if(!s.some(a=>i.includes(a)))return`Unknown step type. Found keys: [${s.join(", ")}]. Valid types: run, choose, prompt, parallel, fail`}return null}catch{return null}}function Et(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=>Et(t))}:o}var qe=class{parse(e){let t;try{t=(0,go.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=>Et(s)))}yo(t);try{return kt(t)}catch(r){if(r instanceof Rt.ZodError){let s=r.issues.map(i=>wo(i,t)).filter(i=>i!==null).join(`
41
44
  `);throw new Error(`Invalid workflow structure:
42
- ${s}`)}throw o}}extractStepLineNumbers(e){let t=new Map,o=e.split(`
43
- `),s=0,i=!1;for(let n=0;n<o.length;n++){let a=o[n].trim();if(a==="steps:"||a.startsWith("steps:")){i=!0;continue}i&&a.startsWith("-")&&t.set(s++,n+1)}return t}},vt=class{parse(e){let t;try{t=JSON.parse(e)}catch(o){throw new Error(`Invalid JSON format: ${o instanceof Error?o.message:String(o)}`)}if(t&&typeof t=="object"&&"steps"in t){let o=t;Array.isArray(o.steps)&&(o.steps=o.steps.map(s=>Rt(s)))}go(t);try{return xt(t)}catch(o){if(o instanceof $t.ZodError){let s=o.issues.map(i=>fo(i,t)).filter(i=>i!==null).join(`
45
+ ${s}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
46
+ `),s=0,i=!1;for(let n=0;n<r.length;n++){let a=r[n].trim();if(a==="steps:"||a.startsWith("steps:")){i=!0;continue}i&&a.startsWith("-")&&t.set(s++,n+1)}return t}},$t=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=>Et(s)))}yo(t);try{return kt(t)}catch(r){if(r instanceof Rt.ZodError){let s=r.issues.map(i=>wo(i,t)).filter(i=>i!==null).join(`
44
47
  `);throw new Error(`Invalid workflow structure:
45
- ${s}`)}throw o}}extractStepLineNumbers(e){let t=new Map,o=e.split(`
46
- `),s=0,i=!1,n=!1;for(let a=0;a<o.length;a++){let c=o[a].trim();if(c.startsWith('"steps"')||c.startsWith("'steps'")){i=!0,c.includes("[")&&(n=!0);continue}if(i&&c==="["){n=!0;continue}if(n&&c==="]"){n=!1,i=!1;continue}n&&c.startsWith("{")&&t.set(s++,a+1)}return t}};function ve(r){switch(r.toLowerCase().split(".").pop()){case"yaml":case"yml":return new qe;case"json":return new vt;default:return new qe}}var So=require("fs/promises"),xo=require("path"),Ze=S(require("boxen"),1),U=S(require("chalk"),1),Pt=S(require("node-cron"),1);he();var $e=require("fs/promises"),bo=require("os"),Et=require("path"),yo=(0,Et.join)((0,bo.homedir)(),".pipeliner","schedules"),wo=(0,Et.join)(yo,"schedules.json"),W=class{async loadSchedules(){try{let e=await(0,$e.readFile)(wo,"utf-8");return JSON.parse(e).schedules||[]}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return[];throw e}}async saveSchedules(e){await(0,$e.mkdir)(yo,{recursive:!0}),await(0,$e.writeFile)(wo,JSON.stringify({schedules:e},null,2),"utf-8")}async addSchedule(e){let t=await this.loadSchedules(),o=Math.random().toString(36).slice(2,10),s=new Date().toISOString(),i={id:o,createdAt:s,...e};return t.push(i),await this.saveSchedules(t),i}async removeSchedule(e){let t=await this.loadSchedules(),o=t.length,s=t.filter(i=>i.id!==e);return s.length===o?!1:(await this.saveSchedules(s),!0)}async updateLastRun(e){let t=await this.loadSchedules(),o=t.find(s=>s.id===e);o&&(o.lastRun=new Date().toISOString(),await this.saveSchedules(t))}async toggleSchedule(e,t){let o=await this.loadSchedules(),s=o.find(i=>i.id===e);return s?(s.enabled=t,await this.saveSchedules(o),!0):!1}async getSchedule(e){return(await this.loadSchedules()).find(o=>o.id===e)}};var Xr=/^([+-])?(\d{1,2})(?::(\d{2}))?$/;function Kr(r){let e=r.trim();if(e===""||e==="0"||e==="+0"||e==="-0")return 0;let t=e.match(Xr);if(!t)return null;let o=t[1],s=parseInt(t[2],10);if(s>14)return null;let n=o==="-"?-s:s;return n<-12||n>14?null:n}function Qr(r){if(r===0)return"UTC";let e=r>0?"-":"+",t=Math.abs(r);return`Etc/GMT${e}${t}`}function Ge(r){if(!r?.trim())return;let e=Kr(r);if(e!==null)return Qr(e)}var K=class{scheduleManager;tasks=new Map;startOptions;constructor(){this.scheduleManager=new W}async start(e=!1,t){if(this.startOptions=t,!e&&await Y()){let s=await N();throw new Error(`Scheduler daemon is already running (PID: ${s.pid}). Use "tp schedule stop" to stop it first.`)}if(e)console.log("\u{1F680} Starting scheduler daemon in background...");else{let s=U.default.bold("\u{1F680} Starting workflow scheduler...");console.log((0,Ze.default)(s,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"cyan"}))}if(await this.reload(),e){if(!process.env.TP_DAEMON_MODE){let s=[U.default.green("\u2713 Scheduler daemon started"),"",U.default.gray(`PID: ${process.pid}`),U.default.dim(" tp schedule stop stop daemon"),U.default.dim(" tp schedule status check status")].join(`
48
+ ${s}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
49
+ `),s=0,i=!1,n=!1;for(let a=0;a<r.length;a++){let c=r[a].trim();if(c.startsWith('"steps"')||c.startsWith("'steps'")){i=!0,c.includes("[")&&(n=!0);continue}if(i&&c==="["){n=!0;continue}if(n&&c==="]"){n=!1,i=!1;continue}n&&c.startsWith("{")&&t.set(s++,a+1)}return t}};function ve(o){switch(o.toLowerCase().split(".").pop()){case"yaml":case"yml":return new qe;case"json":return new $t;default:return new qe}}var vo=require("fs/promises"),$o=require("path"),Ze=S(require("boxen"),1),U=S(require("chalk"),1),Ct=S(require("node-cron"),1);ge();var $e=require("fs/promises"),xo=require("os"),Pt=require("path"),ko=(0,Pt.join)((0,xo.homedir)(),".pipeliner","schedules"),So=(0,Pt.join)(ko,"schedules.json"),W=class{async loadSchedules(){try{let e=await(0,$e.readFile)(So,"utf-8");return JSON.parse(e).schedules||[]}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return[];throw e}}async saveSchedules(e){await(0,$e.mkdir)(ko,{recursive:!0}),await(0,$e.writeFile)(So,JSON.stringify({schedules:e},null,2),"utf-8")}async addSchedule(e){let t=await this.loadSchedules(),r=Math.random().toString(36).slice(2,10),s=new Date().toISOString(),i={id:r,createdAt:s,...e};return t.push(i),await this.saveSchedules(t),i}async removeSchedule(e){let t=await this.loadSchedules(),r=t.length,s=t.filter(i=>i.id!==e);return s.length===r?!1:(await this.saveSchedules(s),!0)}async updateLastRun(e){let t=await this.loadSchedules(),r=t.find(s=>s.id===e);r&&(r.lastRun=new Date().toISOString(),await this.saveSchedules(t))}async toggleSchedule(e,t){let r=await this.loadSchedules(),s=r.find(i=>i.id===e);return s?(s.enabled=t,await this.saveSchedules(r),!0):!1}async getSchedule(e){return(await this.loadSchedules()).find(r=>r.id===e)}};var dn=/^([+-])?(\d{1,2})(?::(\d{2}))?$/;function mn(o){let e=o.trim();if(e===""||e==="0"||e==="+0"||e==="-0")return 0;let t=e.match(dn);if(!t)return null;let r=t[1],s=parseInt(t[2],10);if(s>14)return null;let n=r==="-"?-s:s;return n<-12||n>14?null:n}function fn(o){if(o===0)return"UTC";let e=o>0?"-":"+",t=Math.abs(o);return`Etc/GMT${e}${t}`}function Ge(o){if(!o?.trim())return;let e=mn(o);if(e!==null)return fn(e)}var Q=class{scheduleManager;tasks=new Map;startOptions;constructor(){this.scheduleManager=new W}async start(e=!1,t){if(this.startOptions=t,!e&&await Y()){let s=await N();throw new Error(`Scheduler daemon is already running (PID: ${s.pid}). Use "tp schedule stop" to stop it first.`)}if(e)console.log("\u{1F680} Starting scheduler daemon in background...");else{let s=U.default.bold("\u{1F680} Starting workflow scheduler...");console.log((0,Ze.default)(s,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"cyan"}))}if(await this.reload(),e){if(!process.env.TP_DAEMON_MODE){let s=[U.default.green("\u2713 Scheduler daemon started"),"",U.default.gray(`PID: ${process.pid}`),U.default.dim(" tp schedule stop stop daemon"),U.default.dim(" tp schedule status check status")].join(`
47
50
  `);console.log(`${(0,Ze.default)(s,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},borderColor:"green"})}
48
51
  `)}}else{let s=[U.default.green("\u2713 Scheduler is running"),U.default.dim(" Press Ctrl+C to stop")].join(`
49
- `);console.log((0,Ze.default)(s,{borderStyle:"round",padding:{top:0,bottom:0,left:2,right:2},margin:{top:0,bottom:0,left:0,right:0},borderColor:"green"}))}let o=async()=>{e||console.log(`
50
- \u23F9 Stopping scheduler...`),this.stop(),await Ce(),e||process.exit(0)};process.on("SIGINT",o),process.on("SIGTERM",o),e&&process.stdin.destroy()}async reload(){this.stop();let t=(await this.scheduleManager.loadSchedules()).filter(o=>o.enabled);if(t.length===0){console.log(U.default.gray(` No enabled schedules to load.
51
- `));return}for(let o of t)try{this.startSchedule(o)}catch(s){console.error(U.default.red(` \u2717 Failed to start schedule ${o.id}:`),s)}}startSchedule(e){if(!Pt.default.validate(e.cron)){console.error(` \u2717 Invalid cron expression for schedule ${e.id}: ${e.cron}`);return}let t={},o=Ge(e.timezone);o&&(t.timezone=o);let s;try{s=Pt.default.schedule(e.cron,async()=>{await this.executeSchedule(e)},t)}catch(i){throw console.error(` \u2717 Cron schedule failed for ${e.id} (timezone: ${o??"local"}).`,i instanceof Error?i.message:i),i}this.tasks.set(e.id,s),this.startOptions?.onScheduleStarted?.(e)}async executeSchedule(e){let t=e.name??e.workflowPath;e.silent||(console.log(`
52
- \u23F0 Running scheduled workflow: ${t}`),console.log(` Time: ${new Date().toISOString()}`),e.profile&&console.log(` Profile: ${e.profile}`));try{let o=(0,xo.resolve)(e.workflowPath),s=ve(o),i=await(0,So.readFile)(o,"utf-8"),n=s.parse(i),a=new ke,l={};if(e.profile){if(!n.profiles)throw new Error(`Profile "${e.profile}" not found: no profiles defined in workflow`);let c=n.profiles.find(p=>p.name===e.profile);if(!c)throw new Error(`Profile "${e.profile}" not found. Available profiles: ${n.profiles.map(p=>p.name).join(", ")}`);l.profileVars=c.var}await a.execute(n,l),await this.scheduleManager.updateLastRun(e.id),e.silent||console.log(`\u2713 Scheduled workflow completed: ${t}
53
- `)}catch(o){e.silent||(console.error(`\u2717 Scheduled workflow failed: ${t}`),console.error(` Error: ${o instanceof Error?o.message:String(o)}
54
- `))}}stop(){for(let e of this.tasks.values())e.stop();this.tasks.clear()}async stopDaemon(){let e=await N();if(!e.running||!e.pid)return!1;let t=e.pid;try{if(process.kill(t,"SIGTERM"),await new Promise(o=>setTimeout(o,1e3)),await Y()){try{process.kill(t,"SIGKILL")}catch{}await new Promise(o=>setTimeout(o,500))}return await Ce(),!0}catch{return await Ce(),!1}}};var Ct=S(require("boxen"),1),x=S(require("chalk"),1),ko=S(require("dayjs"),1);function vo(r,e){console.log();let t=r.records.reduce((c,p)=>c+p.duration,0),o=r.records.filter(c=>c.status==="success").length,s=r.records.filter(c=>c.status==="failure").length,i=(0,ko.default)(r.initialTimestamp).format("YYYY-MM-DD HH:mm:ss"),n=be(t),a=[x.default.bold("Workflow Execution History"),"",`${x.default.cyan("File:")} ${e}`,`${x.default.cyan("Started:")} ${i}`,`${x.default.cyan("Total Duration:")} ${n}`,`${x.default.cyan("Total Steps:")} ${r.records.length}`,`${x.default.green("\u2713 Successful:")} ${o}`,s>0?`${x.default.red("\u2717 Failed:")} ${s}`:""].filter(Boolean).join(`
55
- `);console.log((0,Ct.default)(a,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"cyan"})),r.records.forEach((c,p)=>{en(c,p+1,r.records.length)});let l=Ve(r);l&&console.log(l),console.log()}function en(r,e,t){let o=tn(r.step),s=on(r),i=r.status==="success"?x.default.green("\u2713"):x.default.red("\u2717"),n=r.status==="success"?x.default.green("Success"):x.default.red("Failed"),a=be(r.duration),l=[`${i} ${x.default.bold(`Step ${e}/${t}`)} - ${x.default.cyan(o)}`,`${x.default.gray("Duration:")} ${a} | ${x.default.gray("Status:")} ${n}`,"",x.default.white(s)].join(`
56
- `);console.log((0,Ct.default)(l,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:r.status==="success"?"green":"red"})),rn(r.output)&&nn(r.output)}function tn(r){return"run"in r?"Run":"choose"in r?"Choose":"prompt"in r?"Prompt":"parallel"in r?"Parallel":"fail"in r?"Fail":"Unknown"}function on(r){let e=r.step,t=[];if("run"in e){let o=r.resolvedCommand,s=o??e.run;t.push(`Command: ${x.default.yellow(s)}`),o&&o!==e.run&&t.push(`${x.default.gray("Template:")} ${x.default.gray(e.run)}`)}else if("choose"in e){if(t.push(`Message: ${x.default.yellow(e.choose.message)}`),r.choiceValue!==void 0){let o=e.choose.options.find(s=>s.id===r.choiceValue)?.label??r.choiceValue;t.push(`${x.default.gray("Selected:")} ${x.default.cyan(r.choiceValue)}${o!==r.choiceValue?` (${o})`:""}`)}}else"prompt"in e?(t.push(`Message: ${x.default.yellow(e.prompt.message)} | Variable: ${x.default.cyan(e.prompt.as)}`),r.promptValue!==void 0&&t.push(`${x.default.gray("Entered:")} ${x.default.cyan(String(r.promptValue))}`)):"parallel"in e?t.push(`Parallel execution with ${e.parallel.length} branches`):"fail"in e?t.push(`Error: ${x.default.red(e.fail.message)}`):t.push("Unknown step type");return t.join(`
57
- `)}function rn(r){return typeof r=="object"&&r!==null&&"success"in r&&"stdout"in r&&"stderr"in r}function nn(r){if(r.stdout.length>0){let e=r.stdout.map(t=>x.default.gray(` ${t}`)).join(`
58
- `);console.log(x.default.green(" Output:")),console.log(e)}if(r.stderr.length>0){let e=r.stderr.map(t=>x.default.gray(` ${t}`)).join(`
59
- `);console.log(x.default.red(" Errors:")),console.log(e)}}var Go=require("commander");var jo=require("child_process"),Ke=require("fs"),Bo=require("fs/promises"),A=require("path"),Lo=S(require("boxen"),1),D=S(require("chalk"),1),Qe=S(require("inquirer"),1),Oo=S(require("node-cron"),1);he();var Ro=require("fs/promises"),Eo=require("path"),Po=require("yaml"),Co=require("zod");var O=require("zod"),sn=O.z.object({name:O.z.string().min(1,"Schedule name must be non-empty"),cron:O.z.string().min(1,"Cron expression is required"),workflow:O.z.string().min(1,"Workflow path is required"),baseDir:O.z.string().optional(),timezone:O.z.union([O.z.string(),O.z.number()]).transform(String).optional(),silent:O.z.boolean().optional(),profile:O.z.string().optional()}),an=O.z.object({schedules:O.z.array(sn).min(1,"Schedule file must have at least one schedule")});function $o(r){return an.parse(r)}async function Do(r){let e=await(0,Ro.readFile)(r,"utf-8"),t=(0,Eo.extname)(r).toLowerCase(),o;try{if(t===".yaml"||t===".yml")o=(0,Po.parse)(e);else if(t===".json")o=JSON.parse(e);else throw new Error(`Unsupported file format: ${t}. Use .yaml, .yml, or .json`)}catch(s){if(s instanceof Error&&s.message.startsWith("Unsupported"))throw s;let i=t===".json"?"JSON":"YAML";throw new Error(`Invalid ${i} format: ${s instanceof Error?s.message:String(s)}`)}try{return $o(o)}catch(s){if(s instanceof Co.ZodError){let i=s.issues.map(n=>` - ${n.message} (${n.path.join(".")})`).join(`
52
+ `);console.log((0,Ze.default)(s,{borderStyle:"round",padding:{top:0,bottom:0,left:2,right:2},margin:{top:0,bottom:0,left:0,right:0},borderColor:"green"}))}let r=async()=>{e||console.log(`
53
+ \u23F9 Stopping scheduler...`),this.stop(),await Ce(),e||process.exit(0)};process.on("SIGINT",r),process.on("SIGTERM",r),e&&process.stdin.destroy()}async reload(){this.stop();let t=(await this.scheduleManager.loadSchedules()).filter(r=>r.enabled);if(t.length===0){console.log(U.default.gray(` No enabled schedules to load.
54
+ `));return}for(let r of t)try{this.startSchedule(r)}catch(s){console.error(U.default.red(` \u2717 Failed to start schedule ${r.id}:`),s)}}startSchedule(e){if(!Ct.default.validate(e.cron)){console.error(` \u2717 Invalid cron expression for schedule ${e.id}: ${e.cron}`);return}let t={},r=Ge(e.timezone);r&&(t.timezone=r);let s;try{s=Ct.default.schedule(e.cron,async()=>{await this.executeSchedule(e)},t)}catch(i){throw console.error(` \u2717 Cron schedule failed for ${e.id} (timezone: ${r??"local"}).`,i instanceof Error?i.message:i),i}this.tasks.set(e.id,s),this.startOptions?.onScheduleStarted?.(e)}async executeSchedule(e){let t=e.name??e.workflowPath;e.silent||(console.log(`
55
+ \u23F0 Running scheduled workflow: ${t}`),console.log(` Time: ${new Date().toISOString()}`),e.profile&&console.log(` Profile: ${e.profile}`));try{let r=(0,$o.resolve)(e.workflowPath),s=ve(r),i=await(0,vo.readFile)(r,"utf-8"),n=s.parse(i);n._filePath=r,n._fileName=r.split(/[/\\]/).pop()||"workflow";let a=new ke,l={};if(e.profile){if(!n.profiles)throw new Error(`Profile "${e.profile}" not found: no profiles defined in workflow`);let c=n.profiles.find(d=>d.name===e.profile);if(!c)throw new Error(`Profile "${e.profile}" not found. Available profiles: ${n.profiles.map(d=>d.name).join(", ")}`);l.profileVars=c.var}await a.execute(n,l),await this.scheduleManager.updateLastRun(e.id),e.silent||console.log(`\u2713 Scheduled workflow completed: ${t}
56
+ `)}catch(r){e.silent||(console.error(`\u2717 Scheduled workflow failed: ${t}`),console.error(` Error: ${r instanceof Error?r.message:String(r)}
57
+ `))}}stop(){for(let e of this.tasks.values())e.stop();this.tasks.clear()}async stopDaemon(){let e=await N();if(!e.running||!e.pid)return!1;let t=e.pid;try{if(process.kill(t,"SIGTERM"),await new Promise(r=>setTimeout(r,1e3)),await Y()){try{process.kill(t,"SIGKILL")}catch{}await new Promise(r=>setTimeout(r,500))}return await Ce(),!0}catch{return await Ce(),!1}}};var Dt=S(require("boxen"),1),x=S(require("chalk"),1),Ro=S(require("dayjs"),1);function Eo(o,e){console.log();let t=o.records.reduce((c,d)=>c+d.duration,0),r=o.records.filter(c=>c.status==="success").length,s=o.records.filter(c=>c.status==="failure").length,i=(0,Ro.default)(o.initialTimestamp).format("YYYY-MM-DD HH:mm:ss"),n=ye(t),a=[x.default.bold("Workflow Execution History"),"",`${x.default.cyan("File:")} ${e}`,`${x.default.cyan("Started:")} ${i}`,`${x.default.cyan("Total Duration:")} ${n}`,`${x.default.cyan("Total Steps:")} ${o.records.length}`,`${x.default.green("\u2713 Successful:")} ${r}`,s>0?`${x.default.red("\u2717 Failed:")} ${s}`:""].filter(Boolean).join(`
58
+ `);console.log((0,Dt.default)(a,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"cyan"})),o.records.forEach((c,d)=>{hn(c,d+1,o.records.length)});let l=Ve(o);l&&console.log(l),console.log()}function hn(o,e,t){let r=gn(o.step),s=wn(o),i=o.status==="success"?x.default.green("\u2713"):x.default.red("\u2717"),n=o.status==="success"?x.default.green("Success"):x.default.red("Failed"),a=ye(o.duration),l=[`${i} ${x.default.bold(`Step ${e}/${t}`)} - ${x.default.cyan(r)}`,`${x.default.gray("Duration:")} ${a} | ${x.default.gray("Status:")} ${n}`,"",x.default.white(s)].join(`
59
+ `);console.log((0,Dt.default)(l,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:o.status==="success"?"green":"red"})),bn(o.output)&&yn(o.output)}function gn(o){return"run"in o?"Run":"choose"in o?"Choose":"prompt"in o?"Prompt":"parallel"in o?"Parallel":"fail"in o?"Fail":"Unknown"}function wn(o){let e=o.step,t=[];if("run"in e){let r=o.resolvedCommand,s=r??e.run;t.push(`Command: ${x.default.yellow(s)}`),r&&r!==e.run&&t.push(`${x.default.gray("Template:")} ${x.default.gray(e.run)}`)}else if("choose"in e){if(t.push(`Message: ${x.default.yellow(e.choose.message)}`),o.choiceValue!==void 0){let r=e.choose.options.find(s=>s.id===o.choiceValue)?.label??o.choiceValue;t.push(`${x.default.gray("Selected:")} ${x.default.cyan(o.choiceValue)}${r!==o.choiceValue?` (${r})`:""}`)}}else"prompt"in e?(t.push(`Message: ${x.default.yellow(e.prompt.message)} | Variable: ${x.default.cyan(e.prompt.as)}`),o.promptValue!==void 0&&t.push(`${x.default.gray("Entered:")} ${x.default.cyan(String(o.promptValue))}`)):"parallel"in e?t.push(`Parallel execution with ${e.parallel.length} branches`):"fail"in e?t.push(`Error: ${x.default.red(e.fail.message)}`):t.push("Unknown step type");return t.join(`
60
+ `)}function bn(o){return typeof o=="object"&&o!==null&&"success"in o&&"stdout"in o&&"stderr"in o}function yn(o){if(o.stdout.length>0){let e=o.stdout.map(t=>x.default.gray(` ${t}`)).join(`
61
+ `);console.log(x.default.green(" Output:")),console.log(e)}if(o.stderr.length>0){let e=o.stderr.map(t=>x.default.gray(` ${t}`)).join(`
62
+ `);console.log(x.default.red(" Errors:")),console.log(e)}}var Ko=require("commander");var Lo=require("child_process"),Ke=require("fs"),Fo=require("fs/promises"),j=require("path"),Wo=S(require("boxen"),1),D=S(require("chalk"),1),Qe=S(require("inquirer"),1),Ho=S(require("node-cron"),1);ge();var Co=require("fs/promises"),Do=require("path"),To=require("yaml"),Io=require("zod");var L=require("zod"),Sn=L.z.object({name:L.z.string().min(1,"Schedule name must be non-empty"),cron:L.z.string().min(1,"Cron expression is required"),workflow:L.z.string().min(1,"Workflow path is required"),baseDir:L.z.string().optional(),timezone:L.z.union([L.z.string(),L.z.number()]).transform(String).optional(),silent:L.z.boolean().optional(),profile:L.z.string().optional()}),xn=L.z.object({schedules:L.z.array(Sn).min(1,"Schedule file must have at least one schedule")});function Po(o){return xn.parse(o)}async function Mo(o){let e=await(0,Co.readFile)(o,"utf-8"),t=(0,Do.extname)(o).toLowerCase(),r;try{if(t===".yaml"||t===".yml")r=(0,To.parse)(e);else if(t===".json")r=JSON.parse(e);else throw new Error(`Unsupported file format: ${t}. Use .yaml, .yml, or .json`)}catch(s){if(s instanceof Error&&s.message.startsWith("Unsupported"))throw s;let i=t===".json"?"JSON":"YAML";throw new Error(`Invalid ${i} format: ${s instanceof Error?s.message:String(s)}`)}try{return Po(r)}catch(s){if(s instanceof Io.ZodError){let i=s.issues.map(n=>` - ${n.message} (${n.path.join(".")})`).join(`
60
63
  `);throw new Error(`Invalid schedule file structure:
61
- ${i}`)}throw s}}var To=S(require("boxen"),1),E=S(require("chalk"),1),Io=S(require("cronstrue"),1),Dt=S(require("dayjs"),1),Tt=S(require("node-cron"),1);function It(r){try{return Io.default.toString(r)}catch{return null}}function ln(r){if(!Tt.default.validate(r.cron))return null;try{let e={},t=Ge(r.timezone);t&&(e.timezone=t);let o=Tt.default.createTask(r.cron,()=>{},e),s=o.getNextRun();return o.destroy(),s}catch{return null}}function Q(r,e){let t=r,{daemonRunning:o,emphasizeState:s}=e,i=t.enabled?s?E.default.bold.green("ENABLED"):E.default.green("enabled"):s?E.default.bold.gray("DISABLED"):E.default.gray("disabled"),n=o&&t.enabled,a=n?E.default.green("\u25CF active"):E.default.gray("\u25CB inactive"),l=s?t.enabled?E.default.bold.green(" [ENABLED]"):E.default.bold.gray(" [DISABLED]"):"",c=E.default.bold(t.name??t.workflowPath),p=ln(t),f=p?(0,Dt.default)(p).format("YYYY-MM-DD HH:mm:ss"):E.default.dim("\u2014"),m=t.lastRun?(0,Dt.default)(t.lastRun).format("YYYY-MM-DD HH:mm:ss"):E.default.dim("never"),u=It(t.cron),h=t.timezone?t.timezone.startsWith("+")||t.timezone.startsWith("-")?`UTC${t.timezone}`:`UTC+${t.timezone}`:null,g=h??"local",w=u?`${t.cron} ${E.default.dim(`\u2192 ${u} (${g})`)}`:t.cron,y=[[E.default.gray("Enabled"),i],[E.default.gray("Cron"),w],[E.default.gray("Timezone"),h??E.default.dim("local")],[E.default.gray("Workflow"),t.workflowPath],...t.profile?[[E.default.gray("Profile"),E.default.cyan(t.profile)]]:[],...t.silent?[[E.default.gray("Silent"),E.default.yellow("yes")]]:[],[E.default.gray("Last run"),m],[E.default.gray("Next run"),f]],k=[`${c} ${a}${l}`,...y.map(([I,H])=>` ${I.padEnd(10)} ${H}`)].join(`
62
- `);return(0,To.default)(k,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:n?"green":"gray"})}var q=require("fs"),L=require("path"),Mt=require("url"),Mo={};function No(){console.log=()=>{},console.error=()=>{},console.warn=()=>{},console.info=()=>{},process.stdout.write=()=>!0,process.stderr.write=()=>!0}function Ao(){return"0.3.7"}function Xe(r){let e=r?(0,L.resolve)(r):process.cwd(),t=50,o=0;for(;o<t;){let s=(0,L.resolve)(e,"tp");try{if((0,q.existsSync)(s)&&(0,q.statSync)(s).isDirectory())return s}catch{}let i=(0,L.dirname)(e);if(i===e)break;e=i,o++}return null}function Nt(r,e){let t=e.workflow;if((0,A.isAbsolute)(t))return t;let o=e.baseDir?(0,A.resolve)(e.baseDir):(0,A.dirname)(r);return(0,A.resolve)(o,t)}function Fo(r,e="plain"){let t=r.name??"(no alias)",o=(0,A.basename)(r.workflowPath),s=It(r.cron)??r.cron,i=e==="color"?r.enabled?D.default.green("Enabled"):D.default.dim("Disabled"):r.enabled?"\u2713":"\u2717";return`${t} \xB7 ${o} \xB7 ${r.cron} \xB7 ${s} \xB7 ${i}`}async function Wo(r){let e=new W;if(!r){let l=Xe();l||(console.error(D.default.red(`
63
- \u2717 No tp directory found`)),process.exit(1));let c=(0,A.join)(l,"schedules");(0,Ke.existsSync)(c)||(console.error(D.default.red(`
64
- \u2717 No schedules directory found at ${c}`)),process.exit(1));let f=(await(0,Bo.readdir)(c)).filter(g=>{let w=(0,A.extname)(g).toLowerCase();return[".yaml",".yml",".json"].includes(w)});f.length===0&&(console.error(D.default.red(`
65
- \u2717 No schedule files found in ${c}`)),process.exit(1));let m=f.map(g=>({id:(0,A.join)(c,g),label:g}));r=(await new B(!0).prompt("Select a schedule file to add",m)).id}let t=(0,A.resolve)(r);(0,Ke.existsSync)(t)||(console.error(`\u2717 File not found: ${t}`),process.exit(1));let o;try{o=await Do(t)}catch(l){console.error(`\u2717 Failed to parse schedule file: ${l instanceof Error?l.message:String(l)}`),process.exit(1)}let s=o.schedules.filter(l=>!Oo.default.validate(l.cron));if(s.length>0){console.error("\u2717 Invalid cron expression(s):");for(let l of s)console.error(` - ${l.name}: "${l.cron}"`);process.exit(1)}let i=o.schedules.filter(l=>{let c=Nt(t,l);return!(0,Ke.existsSync)(c)});if(i.length>0){console.error("\u2717 Workflow file(s) not found:");for(let l of i){let c=Nt(t,l);console.error(` - ${l.name}: ${l.workflow} (resolved: ${c})`)}process.exit(1)}console.log(`
66
- Found ${o.schedules.length} schedule(s) in file.
67
- `);let n=[];for(let l of o.schedules){let{alias:c}=await Qe.default.prompt([{type:"input",name:"alias",message:`Alias for "${l.name}" (press Enter to use as-is):`,default:l.name}]),p=await e.addSchedule({name:c,workflowPath:Nt(t,l),cron:l.cron,enabled:!0,timezone:l.timezone,silent:l.silent,profile:l.profile});n.push(p)}let a=await N();console.log(`
64
+ ${i}`)}throw s}}var No=S(require("boxen"),1),E=S(require("chalk"),1),jo=S(require("cronstrue"),1),Tt=S(require("dayjs"),1),It=S(require("node-cron"),1);function Mt(o){try{return jo.default.toString(o)}catch{return null}}function kn(o){if(!It.default.validate(o.cron))return null;try{let e={},t=Ge(o.timezone);t&&(e.timezone=t);let r=It.default.createTask(o.cron,()=>{},e),s=r.getNextRun();return r.destroy(),s}catch{return null}}function ee(o,e){let t=o,{daemonRunning:r,emphasizeState:s}=e,i=t.enabled?s?E.default.bold.green("ENABLED"):E.default.green("enabled"):s?E.default.bold.gray("DISABLED"):E.default.gray("disabled"),n=r&&t.enabled,a=n?E.default.green("\u25CF active"):E.default.gray("\u25CB inactive"),l=s?t.enabled?E.default.bold.green(" [ENABLED]"):E.default.bold.gray(" [DISABLED]"):"",c=E.default.bold(t.name??t.workflowPath),d=kn(t),f=d?(0,Tt.default)(d).format("YYYY-MM-DD HH:mm:ss"):E.default.dim("\u2014"),m=t.lastRun?(0,Tt.default)(t.lastRun).format("YYYY-MM-DD HH:mm:ss"):E.default.dim("never"),p=Mt(t.cron),h=t.timezone?t.timezone.startsWith("+")||t.timezone.startsWith("-")?`UTC${t.timezone}`:`UTC+${t.timezone}`:null,g=h??"local",w=p?`${t.cron} ${E.default.dim(`\u2192 ${p} (${g})`)}`:t.cron,y=[[E.default.gray("Enabled"),i],[E.default.gray("Cron"),w],[E.default.gray("Timezone"),h??E.default.dim("local")],[E.default.gray("Workflow"),t.workflowPath],...t.profile?[[E.default.gray("Profile"),E.default.cyan(t.profile)]]:[],...t.silent?[[E.default.gray("Silent"),E.default.yellow("yes")]]:[],[E.default.gray("Last run"),m],[E.default.gray("Next run"),f]],k=[`${c} ${a}${l}`,...y.map(([I,H])=>` ${I.padEnd(10)} ${H}`)].join(`
65
+ `);return(0,No.default)(k,{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:n?"green":"gray"})}var q=require("fs"),O=require("path"),Nt=require("url"),Ao={};function Bo(){console.log=()=>{},console.error=()=>{},console.warn=()=>{},console.info=()=>{},process.stdout.write=()=>!0,process.stderr.write=()=>!0}function Oo(){return"0.3.8"}function Xe(o){let e=o?(0,O.resolve)(o):process.cwd(),t=50,r=0;for(;r<t;){let s=(0,O.resolve)(e,"tp");try{if((0,q.existsSync)(s)&&(0,q.statSync)(s).isDirectory())return s}catch{}let i=(0,O.dirname)(e);if(i===e)break;e=i,r++}return null}function jt(o,e){let t=e.workflow;if((0,j.isAbsolute)(t))return t;let r=e.baseDir?(0,j.resolve)(e.baseDir):(0,j.dirname)(o);return(0,j.resolve)(r,t)}function Vo(o,e="plain"){let t=o.name??"(no alias)",r=(0,j.basename)(o.workflowPath),s=Mt(o.cron)??o.cron,i=e==="color"?o.enabled?D.default.green("Enabled"):D.default.dim("Disabled"):o.enabled?"\u2713":"\u2717";return`${t} \xB7 ${r} \xB7 ${o.cron} \xB7 ${s} \xB7 ${i}`}async function _o(o){let e=new W;if(!o){let l=Xe();l||(console.error(D.default.red(`
66
+ \u2717 No tp directory found`)),process.exit(1));let c=(0,j.join)(l,"schedules");(0,Ke.existsSync)(c)||(console.error(D.default.red(`
67
+ \u2717 No schedules directory found at ${c}`)),process.exit(1));let f=(await(0,Fo.readdir)(c)).filter(g=>{let w=(0,j.extname)(g).toLowerCase();return[".yaml",".yml",".json"].includes(w)});f.length===0&&(console.error(D.default.red(`
68
+ \u2717 No schedule files found in ${c}`)),process.exit(1));let m=f.map(g=>({id:(0,j.join)(c,g),label:g}));o=(await new B(!0).prompt("Select a schedule file to add",m)).id}let t=(0,j.resolve)(o);(0,Ke.existsSync)(t)||(console.error(`\u2717 File not found: ${t}`),process.exit(1));let r;try{r=await Mo(t)}catch(l){console.error(`\u2717 Failed to parse schedule file: ${l instanceof Error?l.message:String(l)}`),process.exit(1)}let s=r.schedules.filter(l=>!Ho.default.validate(l.cron));if(s.length>0){console.error("\u2717 Invalid cron expression(s):");for(let l of s)console.error(` - ${l.name}: "${l.cron}"`);process.exit(1)}let i=r.schedules.filter(l=>{let c=jt(t,l);return!(0,Ke.existsSync)(c)});if(i.length>0){console.error("\u2717 Workflow file(s) not found:");for(let l of i){let c=jt(t,l);console.error(` - ${l.name}: ${l.workflow} (resolved: ${c})`)}process.exit(1)}console.log(`
69
+ Found ${r.schedules.length} schedule(s) in file.
70
+ `);let n=[];for(let l of r.schedules){let{alias:c}=await Qe.default.prompt([{type:"input",name:"alias",message:`Alias for "${l.name}" (press Enter to use as-is):`,default:l.name}]),d=await e.addSchedule({name:c,workflowPath:jt(t,l),cron:l.cron,enabled:!0,timezone:l.timezone,silent:l.silent,profile:l.profile});n.push(d)}let a=await N();console.log(`
68
71
  \u2713 Added ${n.length} schedule(s) successfully
69
- `);for(let l of n)console.log(Q(l,{daemonRunning:a.running}));console.log(D.default.dim(' Tip: Run "tp schedule start" to start the scheduler daemon'))}async function Ho(){let r=new W,e=await r.loadSchedules();if(e.length===0){console.log("No schedules found");return}let t=e.map(c=>({id:c.id,label:Fo(c)})),i=(await new B(!0).prompt("Select schedule to remove:",t)).id,n=e.find(c=>c.id===i),{confirm:a}=await Qe.default.prompt([{type:"confirm",name:"confirm",message:"Are you sure you want to remove this schedule?",default:!1}]);if(!a){console.log("Cancelled");return}let l=await r.removeSchedule(i);if(l&&n){let c=await N();console.log(`
72
+ `);for(let l of n)console.log(ee(l,{daemonRunning:a.running}));console.log(D.default.dim(' Tip: Run "tp schedule start" to start the scheduler daemon'))}async function Uo(){let o=new W,e=await o.loadSchedules();if(e.length===0){console.log("No schedules found");return}let t=e.map(c=>({id:c.id,label:Vo(c)})),i=(await new B(!0).prompt("Select schedule to remove:",t)).id,n=e.find(c=>c.id===i),{confirm:a}=await Qe.default.prompt([{type:"confirm",name:"confirm",message:"Are you sure you want to remove this schedule?",default:!1}]);if(!a){console.log("Cancelled");return}let l=await o.removeSchedule(i);if(l&&n){let c=await N();console.log(`
70
73
  \u2713 Schedule removed
71
- `),console.log(Q(n,{daemonRunning:c.running}))}else console.log(l?"\u2713 Schedule removed successfully":"\u2717 Schedule not found")}async function At(){let e=await new W().loadSchedules();if(e.length===0){let n=[D.default.gray("No schedules registered."),"",D.default.dim(" tp schedule add <schedule.yaml> add from a schedule file")].join(`
74
+ `),console.log(ee(n,{daemonRunning:c.running}))}else console.log(l?"\u2713 Schedule removed successfully":"\u2717 Schedule not found")}async function At(){let e=await new W().loadSchedules();if(e.length===0){let n=[D.default.gray("No schedules registered."),"",D.default.dim(" tp schedule add <schedule.yaml> add from a schedule file")].join(`
72
75
  `);console.log(`
73
- ${(0,Lo.default)(n,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:0,left:0,right:0},borderColor:"gray"})}
74
- `);return}let t=await N(),o=t.running?D.default.green("\u25CF running"):D.default.gray("\u25CB stopped"),s=e.filter(n=>n.enabled).length,i=D.default.bold("\u{1F4C5} Workflow Schedules");console.log(i),console.log([D.default.gray(" Daemon: "),o,D.default.gray(` \xB7 Schedules: ${s}/${e.length} enabled`)].join(""));for(let n of e)console.log(Q(n,{daemonRunning:t.running}));console.log(D.default.dim(" Tip: tp schedule start \u2014 run scheduler daemon; tp schedule status \u2014 view live status"))}async function Vo(r){if(await Y()){let e=await N();console.error(`\u2717 Scheduler daemon is already running (PID: ${e.pid})`),console.error(' Run "tp schedule stop" to stop it first'),process.exit(1)}if(r)if(process.env.TP_DAEMON_MODE==="true")try{let{saveDaemonPid:e}=await Promise.resolve().then(()=>(he(),Vt));await e(),await new K().start(!0),await new Promise(()=>{})}catch(e){await pt(e instanceof Error?e:new Error(String(e))),process.exit(1)}else{let e=process.argv.slice(1);(0,jo.spawn)(process.argv[0],e,{detached:!0,stdio:"ignore",env:{...process.env,TP_DAEMON_MODE:"true"}}).unref();let o=3,s=800,i=!1;for(let n=0;n<o;n++)if(await new Promise(a=>setTimeout(a,s)),await Y()){i=!0;break}if(i){let n=await N();console.log(`\u2713 Scheduler daemon started in background (PID: ${n.pid})`),console.log(' Run "tp schedule stop" to stop the daemon'),console.log(' Run "tp schedule status" to check daemon status')}else{console.error("\u2717 Failed to start scheduler daemon");let n=await mt();n?(console.error(D.default.dim(" Last error from daemon:")),console.error(D.default.red(n.split(`
76
+ ${(0,Wo.default)(n,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:0,left:0,right:0},borderColor:"gray"})}
77
+ `);return}let t=await N(),r=t.running?D.default.green("\u25CF running"):D.default.gray("\u25CB stopped"),s=e.filter(n=>n.enabled).length,i=D.default.bold("\u{1F4C5} Workflow Schedules");console.log(i),console.log([D.default.gray(" Daemon: "),r,D.default.gray(` \xB7 Schedules: ${s}/${e.length} enabled`)].join(""));for(let n of e)console.log(ee(n,{daemonRunning:t.running}));console.log(D.default.dim(" Tip: tp schedule start \u2014 run scheduler daemon; tp schedule status \u2014 view live status"))}async function zo(o){if(await Y()){let e=await N();console.error(`\u2717 Scheduler daemon is already running (PID: ${e.pid})`),console.error(' Run "tp schedule stop" to stop it first'),process.exit(1)}if(o)if(process.env.TP_DAEMON_MODE==="true")try{let{saveDaemonPid:e}=await Promise.resolve().then(()=>(ge(),_t));await e(),await new Q().start(!0),await new Promise(()=>{})}catch(e){await pt(e instanceof Error?e:new Error(String(e))),process.exit(1)}else{let e=process.argv.slice(1);(0,Lo.spawn)(process.argv[0],e,{detached:!0,stdio:"ignore",env:{...process.env,TP_DAEMON_MODE:"true"}}).unref();let r=3,s=800,i=!1;for(let n=0;n<r;n++)if(await new Promise(a=>setTimeout(a,s)),await Y()){i=!0;break}if(i){let n=await N();console.log(`\u2713 Scheduler daemon started in background (PID: ${n.pid})`),console.log(' Run "tp schedule stop" to stop the daemon'),console.log(' Run "tp schedule status" to check daemon status')}else{console.error("\u2717 Failed to start scheduler daemon");let n=await mt();n?(console.error(D.default.dim(" Last error from daemon:")),console.error(D.default.red(n.split(`
75
78
  `).map(a=>` ${a}`).join(`
76
- `)))):console.error(D.default.dim(` Check ${dt()} for details`)),process.exit(1)}process.exit(0)}else await new K().start(!1,{onScheduleStarted:t=>console.log(Q(t,{daemonRunning:!0}))}),await new Promise(()=>{})}async function _o(){let r=await N();if(!r.running){console.log("Scheduler daemon is not running");return}console.log(`Stopping scheduler daemon (PID: ${r.pid})...`);let t=await new K().stopDaemon();console.log(t?"\u2713 Scheduler daemon stopped":"\u2717 Failed to stop scheduler daemon (process may have already exited)")}async function Uo(){let r=new W,e=await r.loadSchedules();if(e.length===0){console.log("No schedules found");return}let t=e.map(m=>({id:m.id,label:Fo(m,"color")})),i=(await new B(!0).prompt("Select schedule to toggle:",t)).id,n=e.find(m=>m.id===i);if(!n){console.log("\u2717 Schedule not found");return}let a=!n.enabled;await r.toggleSchedule(i,a);let l=await N(),c={...n,enabled:a},p=a?D.default.bold.green("ENABLED"):D.default.bold.gray("DISABLED"),f=a?D.default.dim(" (will run at the times shown below)"):D.default.dim(" (will not run until you enable it again)");console.log(`
77
- \u2713 Schedule is now ${p}${f}
78
- `),console.log(Q(c,{daemonRunning:l.running,emphasizeState:!0}))}async function zo(){let r=new W,e=await r.loadSchedules();if(e.length===0){console.log("No schedules found");return}let{confirm:t}=await Qe.default.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to remove all ${e.length} schedule(s)?`,default:!1}]);if(!t){console.log("Cancelled");return}await r.saveSchedules([]),console.log(`\u2713 Removed all ${e.length} schedule(s)`)}var jt=S(require("boxen"),1),v=S(require("chalk"),1),et=S(require("dayjs"),1),Me=S(require("log-update"),1);he();function cn(r){if(!r)return"Unknown";let e=(0,et.default)(r),o=(0,et.default)().diff(e,"second"),s=Math.floor(o/86400),i=Math.floor(o%86400/3600),n=Math.floor(o%3600/60),a=o%60,l=[];return s>0&&l.push(`${s}d`),i>0&&l.push(`${i}h`),n>0&&l.push(`${n}m`),(a>0||l.length===0)&&l.push(`${a}s`),l.join(" ")}function un(r,e){return Q(r,{daemonRunning:e})}async function Yo(){let r=await N(),t=await new W().loadSchedules(),o=[],s;if(r.running&&r.pid){let n=cn(r.startTime),a=r.startTime?(0,et.default)(r.startTime).format("YYYY-MM-DD HH:mm:ss"):"Unknown";s=[`${v.default.green("\u25CF")} ${v.default.green("active")} ${v.default.gray("(running)")}`,"",`${v.default.gray("Loaded:")} ${v.default.white(a)}`,`${v.default.gray("Active:")} ${v.default.green("active (running)")} since ${v.default.white(a)}`,`${v.default.gray("PID:")} ${v.default.white(r.pid.toString())}`,`${v.default.gray("Uptime:")} ${v.default.white(n)}`].join(`
79
+ `)))):console.error(D.default.dim(` Check ${dt()} for details`)),process.exit(1)}process.exit(0)}else await new Q().start(!1,{onScheduleStarted:t=>console.log(ee(t,{daemonRunning:!0}))}),await new Promise(()=>{})}async function Yo(){let o=await N();if(!o.running){console.log("Scheduler daemon is not running");return}console.log(`Stopping scheduler daemon (PID: ${o.pid})...`);let t=await new Q().stopDaemon();console.log(t?"\u2713 Scheduler daemon stopped":"\u2717 Failed to stop scheduler daemon (process may have already exited)")}async function Jo(){let o=new W,e=await o.loadSchedules();if(e.length===0){console.log("No schedules found");return}let t=e.map(m=>({id:m.id,label:Vo(m,"color")})),i=(await new B(!0).prompt("Select schedule to toggle:",t)).id,n=e.find(m=>m.id===i);if(!n){console.log("\u2717 Schedule not found");return}let a=!n.enabled;await o.toggleSchedule(i,a);let l=await N(),c={...n,enabled:a},d=a?D.default.bold.green("ENABLED"):D.default.bold.gray("DISABLED"),f=a?D.default.dim(" (will run at the times shown below)"):D.default.dim(" (will not run until you enable it again)");console.log(`
80
+ \u2713 Schedule is now ${d}${f}
81
+ `),console.log(ee(c,{daemonRunning:l.running,emphasizeState:!0}))}async function qo(){let o=new W,e=await o.loadSchedules();if(e.length===0){console.log("No schedules found");return}let{confirm:t}=await Qe.default.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to remove all ${e.length} schedule(s)?`,default:!1}]);if(!t){console.log("Cancelled");return}await o.saveSchedules([]),console.log(`\u2713 Removed all ${e.length} schedule(s)`)}var Bt=S(require("boxen"),1),v=S(require("chalk"),1),et=S(require("dayjs"),1),Me=S(require("log-update"),1);ge();function vn(o){if(!o)return"Unknown";let e=(0,et.default)(o),r=(0,et.default)().diff(e,"second"),s=Math.floor(r/86400),i=Math.floor(r%86400/3600),n=Math.floor(r%3600/60),a=r%60,l=[];return s>0&&l.push(`${s}d`),i>0&&l.push(`${i}h`),n>0&&l.push(`${n}m`),(a>0||l.length===0)&&l.push(`${a}s`),l.join(" ")}function $n(o,e){return ee(o,{daemonRunning:e})}async function Go(){let o=await N(),t=await new W().loadSchedules(),r=[],s;if(o.running&&o.pid){let n=vn(o.startTime),a=o.startTime?(0,et.default)(o.startTime).format("YYYY-MM-DD HH:mm:ss"):"Unknown";s=[`${v.default.green("\u25CF")} ${v.default.green("active")} ${v.default.gray("(running)")}`,"",`${v.default.gray("Loaded:")} ${v.default.white(a)}`,`${v.default.gray("Active:")} ${v.default.green("active (running)")} since ${v.default.white(a)}`,`${v.default.gray("PID:")} ${v.default.white(o.pid.toString())}`,`${v.default.gray("Uptime:")} ${v.default.white(n)}`].join(`
79
82
  `)}else s=[`${v.default.red("\u25CF")} ${v.default.red("inactive")} ${v.default.gray("(dead)")}`,"",`${v.default.gray("Loaded:")} ${v.default.gray("not found")}`,`${v.default.gray("Active:")} ${v.default.red("inactive (dead)")}`].join(`
80
- `);let i=(0,jt.default)(s,{title:v.default.bold("task-pipeliner-scheduler.service"),titleAlignment:"left",borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:1,bottom:0,left:0,right:0},borderColor:r.running?"green":"red"});if(o.push(i),t.length>0){let n=t.filter(l=>l.enabled).length,a=v.default.bold(`Schedules: ${n}/${t.length} enabled`);o.push(a);for(let l of t)o.push(un(l,r.running))}else{let n=(0,jt.default)(v.default.gray("No schedules configured"),{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"gray"});o.push(n)}return`
83
+ `);let i=(0,Bt.default)(s,{title:v.default.bold("task-pipeliner-scheduler.service"),titleAlignment:"left",borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:1,bottom:0,left:0,right:0},borderColor:o.running?"green":"red"});if(r.push(i),t.length>0){let n=t.filter(l=>l.enabled).length,a=v.default.bold(`Schedules: ${n}/${t.length} enabled`);r.push(a);for(let l of t)r.push($n(l,o.running))}else{let n=(0,Bt.default)(v.default.gray("No schedules configured"),{borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:"gray"});r.push(n)}return`
81
84
 
82
- ${o.join(`
83
- `)}`}function Jo(){process.stdout.write("\x1B[2J\x1B[H")}var pn=2,dn=24;function mn(){let r=typeof process.stdout.rows=="number"?process.stdout.rows:dn;return Math.max(5,r-pn)}function fn(r){let e=r.toString("utf8");return e==="\x1B[A"?"up":e==="\x1B[B"?"down":e==="\x1B[5~"?"pageup":e==="\x1B[6~"?"pagedown":e==="\x1B[H"||e==="\x1B[1~"?"home":e==="\x1B[4~"||e==="\x1B[F"?"end":null}async function qo(r){if(r){let e=process.stdin.isTTY&&process.stdout.isTTY,t=mn(),o=!0,s=[],i="",n=0,a=()=>{let f=s.length,m=Math.max(0,f-t);n=Math.min(n,m);let h=s.slice(n,n+t).join(`
85
+ ${r.join(`
86
+ `)}`}function Zo(){process.stdout.write("\x1B[2J\x1B[H")}var Rn=2,En=24;function Pn(){let o=typeof process.stdout.rows=="number"?process.stdout.rows:En;return Math.max(5,o-Rn)}function Cn(o){let e=o.toString("utf8");return e==="\x1B[A"?"up":e==="\x1B[B"?"down":e==="\x1B[5~"?"pageup":e==="\x1B[6~"?"pagedown":e==="\x1B[H"||e==="\x1B[1~"?"home":e==="\x1B[4~"||e==="\x1B[F"?"end":null}async function Xo(o){if(o){let e=process.stdin.isTTY&&process.stdout.isTTY,t=Pn(),r=!0,s=[],i="",n=0,a=()=>{let f=s.length,m=Math.max(0,f-t);n=Math.min(n,m);let h=s.slice(n,n+t).join(`
84
87
  `),g=f>t?v.default.dim(` [${n+1}-${Math.min(n+t,f)}/${f}] \u2191/\u2193 PgUp/PgDn: scroll`):"";(0,Me.default)(`${h}
85
- ${i}${g}`)},l=()=>{o=!1,e&&process.stdin.isTTY&&(process.stdin.setRawMode(!1),process.stdin.pause()),Me.default.done(),process.exit(0)};process.on("SIGINT",l),process.on("SIGTERM",l),e&&process.stdin.isTTY&&(process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding("utf8"),process.stdin.on("data",f=>{let m=typeof f=="string"?Buffer.from(f,"utf8"):f;if(m.length===1&&m[0]===3){l();return}let u=fn(m);if(!u||s.length<=t){u&&a();return}let h=Math.max(0,s.length-t);switch(u){case"up":n=Math.max(0,n-1);break;case"down":n=Math.min(h,n+1);break;case"pageup":n=Math.max(0,n-t);break;case"pagedown":n=Math.min(h,n+t);break;case"home":n=0;break;case"end":n=h;break}a()}));let c=async()=>{try{let f=await Yo(),m=await N();if(i=m.running?v.default.gray(`
88
+ ${i}${g}`)},l=()=>{r=!1,e&&process.stdin.isTTY&&(process.stdin.setRawMode(!1),process.stdin.pause()),Me.default.done(),process.exit(0)};process.on("SIGINT",l),process.on("SIGTERM",l),e&&process.stdin.isTTY&&(process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding("utf8"),process.stdin.on("data",f=>{let m=typeof f=="string"?Buffer.from(f,"utf8"):f;if(m.length===1&&m[0]===3){l();return}let p=Cn(m);if(!p||s.length<=t){p&&a();return}let h=Math.max(0,s.length-t);switch(p){case"up":n=Math.max(0,n-1);break;case"down":n=Math.min(h,n+1);break;case"pageup":n=Math.max(0,n-t);break;case"pagedown":n=Math.min(h,n+t);break;case"home":n=0;break;case"end":n=h;break}a()}));let c=async()=>{try{let f=await Go(),m=await N();if(i=m.running?v.default.gray(`
86
89
  Ctrl+C: exit (daemon keeps running)`):v.default.gray(`
87
90
  Tip: tp schedule start -d to start daemon. Ctrl+C: exit.`),s=f.split(`
88
- `),e)a();else{let u=m.running?v.default.gray(`
91
+ `),e)a();else{let p=m.running?v.default.gray(`
89
92
  Press Ctrl+C to exit (daemon keeps running in background)`):v.default.gray(`
90
- Tip: To start the daemon, run: tp schedule start -d. Press Ctrl+C to exit.`);(0,Me.default)(`${f}${u}`)}}catch(f){Me.default.done(),console.error("Error updating status:",f),process.exit(1)}},p=setInterval(async()=>{if(!o){clearInterval(p);return}await c()},1e3);Jo(),await c(),await new Promise(()=>{})}else{Jo();let e=await Yo(),o=(await N()).running?"":v.default.gray(`
91
- Tip: To start the daemon, run: tp schedule start -d`);console.log(`${e}${o}
92
- `)}}function Zo(){let r=new Go.Command("schedule").description("Manage workflow schedules").action(async()=>{await At()});return r.command("add [scheduleFile]").description("Add schedules from a schedule file (YAML or JSON). If no file given, select from nearest tp/schedules directory.").action(async e=>{await Wo(e)}),r.command("remove").alias("rm").description("Remove a workflow schedule").action(async()=>{await Ho()}),r.command("remove-all").description("Remove all workflow schedules").action(async()=>{await zo()}),r.command("list").alias("ls").description("List all workflow schedules").action(async()=>{await At()}),r.command("start").description("Start the scheduler daemon").option("-d, --daemon","Run in background daemon mode").action(async e=>{await Vo(e.daemon??!1)}),r.command("stop").description("Stop the scheduler daemon").action(async()=>{await _o()}),r.command("status").description('View daemon and schedule status (does not start the daemon). In live mode, Ctrl+C only exits the status view; the daemon keeps running if it was started with "tp schedule start -d".').option("-n, --no-follow","Show status once and exit (no live refresh)").action(async e=>{let t=e.follow!==!1;await qo(t)}),r.command("toggle").description("Enable or disable a schedule").action(async()=>{await Uo()}),r}var Xo=[{filename:"example-hello.yaml",content:`name: Hello World (with choose)
93
+ Tip: To start the daemon, run: tp schedule start -d. Press Ctrl+C to exit.`);(0,Me.default)(`${f}${p}`)}}catch(f){Me.default.done(),console.error("Error updating status:",f),process.exit(1)}},d=setInterval(async()=>{if(!r){clearInterval(d);return}await c()},1e3);Zo(),await c(),await new Promise(()=>{})}else{Zo();let e=await Go(),r=(await N()).running?"":v.default.gray(`
94
+ Tip: To start the daemon, run: tp schedule start -d`);console.log(`${e}${r}
95
+ `)}}function Qo(){let o=new Ko.Command("schedule").description("Manage workflow schedules").action(async()=>{await At()});return o.command("add [scheduleFile]").description("Add schedules from a schedule file (YAML or JSON). If no file given, select from nearest tp/schedules directory.").action(async e=>{await _o(e)}),o.command("remove").alias("rm").description("Remove a workflow schedule").action(async()=>{await Uo()}),o.command("remove-all").description("Remove all workflow schedules").action(async()=>{await qo()}),o.command("list").alias("ls").description("List all workflow schedules").action(async()=>{await At()}),o.command("start").description("Start the scheduler daemon").option("-d, --daemon","Run in background daemon mode").action(async e=>{await zo(e.daemon??!1)}),o.command("stop").description("Stop the scheduler daemon").action(async()=>{await Yo()}),o.command("status").description('View daemon and schedule status (does not start the daemon). In live mode, Ctrl+C only exits the status view; the daemon keeps running if it was started with "tp schedule start -d".').option("-n, --no-follow","Show status once and exit (no live refresh)").action(async e=>{let t=e.follow!==!1;await Xo(t)}),o.command("toggle").description("Enable or disable a schedule").action(async()=>{await Jo()}),o}var er=[{filename:"example-hello.yaml",content:`name: Hello World (with choose)
93
96
 
94
97
  # Interactive choice: stored as variable and used in later steps
95
98
  steps:
@@ -150,7 +153,7 @@ steps:
150
153
  mode: prod
151
154
  run: 'echo "Prod-only step (e.g. npm run build)"'
152
155
  - run: 'echo "Done. Replace run steps with real commands."'
153
- `}],Ko=[{filename:"example-daily.yaml",content:`schedules:
156
+ `}],tr=[{filename:"example-daily.yaml",content:`schedules:
154
157
  # Runs at 09:00 daily; interactive choose is skipped in scheduled runs (no TTY)
155
158
  - name: Daily Hello
156
159
  cron: "0 9 * * *"
@@ -165,11 +168,11 @@ steps:
165
168
  cron: "0 2 * * *"
166
169
  workflow: ../workflows/example-build.yaml
167
170
  profile: Prod
168
- `}];var tt=require("fs"),Qo=require("fs/promises"),Ae=require("path"),Ne=S(require("chalk"),1);async function er(){let r=Xe();if(!r)return console.error(Ne.default.red(`
169
- \u2717 No tp directory found`)),null;let e=(0,Ae.join)(r,"workflows");if(!(0,tt.existsSync)(e))return console.error(Ne.default.red(`
170
- \u2717 No workflows directory found at ${e}`)),null;try{let o=(await(0,Qo.readdir)(e)).filter(a=>{let l=(0,Ae.extname)(a).toLowerCase();return[".yaml",".yml",".json"].includes(l)});if(o.length===0)return console.error(Ne.default.red(`
171
- \u2717 No workflow files found in tp/workflows`)),null;let s=await Promise.all(o.map(async a=>{let l=(0,Ae.join)(e,a);try{let c=ve(l),p=(0,tt.readFileSync)(l,"utf-8"),m=c.parse(p).name??"Untitled";return{id:l,label:`${a} - ${m}`}}catch{return{id:l,label:a}}}));return(await new B(!0).prompt("Select a workflow to run",s))?.id??null}catch(t){let o=t instanceof Error?t.message:String(t);return console.error(Ne.default.red(`
172
- \u2717 Failed to read tp directory: ${o}`)),null}}function tr(r){return r.split("/").pop()??r}var je=(0,G.join)((0,rr.homedir)(),".pipeliner"),hn=(0,nr.promisify)(or.exec),oe=new sr.Command;oe.name("task-pipeliner").description(`A powerful task pipeline runner with condition-based workflow execution.
171
+ `}];var tt=require("fs"),or=require("fs/promises"),je=require("path"),Ne=S(require("chalk"),1);async function rr(){let o=Xe();if(!o)return console.error(Ne.default.red(`
172
+ \u2717 No tp directory found`)),null;let e=(0,je.join)(o,"workflows");if(!(0,tt.existsSync)(e))return console.error(Ne.default.red(`
173
+ \u2717 No workflows directory found at ${e}`)),null;try{let r=(await(0,or.readdir)(e)).filter(a=>{let l=(0,je.extname)(a).toLowerCase();return[".yaml",".yml",".json"].includes(l)});if(r.length===0)return console.error(Ne.default.red(`
174
+ \u2717 No workflow files found in tp/workflows`)),null;let s=await Promise.all(r.map(async a=>{let l=(0,je.join)(e,a);try{let c=ve(l),d=(0,tt.readFileSync)(l,"utf-8"),m=c.parse(d).name??"Untitled";return{id:l,label:`${a} - ${m}`}}catch{return{id:l,label:a}}}));return(await new B(!0).prompt("Select a workflow to run",s))?.id??null}catch(t){let r=t instanceof Error?t.message:String(t);return console.error(Ne.default.red(`
175
+ \u2717 Failed to read tp directory: ${r}`)),null}}function nr(o){return o.split("/").pop()??o}var Ae=(0,G.join)((0,ir.homedir)(),".pipeliner"),Dn=(0,ar.promisify)(sr.exec),re=new lr.Command;re.name("task-pipeliner").description(`A powerful task pipeline runner with condition-based workflow execution.
173
176
 
174
177
  Define workflows in YAML or JSON files with conditional execution, parallel tasks,
175
178
  interactive prompts, variable substitution, and cron-based scheduling.
@@ -225,7 +228,7 @@ Quick Start:
225
228
 
226
229
  Note: After upgrading to a new version, if you see compatibility issues (e.g. schedules or daemon), run "tp clean" to reset ~/.pipeliner data.
227
230
 
228
- `).version(Ao()).addHelpText("after",`
231
+ `).version(Oo()).addHelpText("after",`
229
232
  Examples:
230
233
  $ tp setup
231
234
  $ tp run workflow.yaml
@@ -246,7 +249,7 @@ Resources:
246
249
  \u{1F4DA} Documentation: https://task-pipeliner.racgoo.com/
247
250
  \u{1F3A8} Visual Generator: https://task-pipeliner-generator.racgoo.com/
248
251
 
249
- See README.md for complete DSL reference.`);oe.command("run").description("Run a workflow from a YAML or JSON file").argument("[file]","Path to the workflow file (YAML or JSON, relative or absolute). If omitted, will select from workflows in the nearest tp/workflows directory.").option("-s, --silent","Run in silent mode (suppress console output)").option("-p, --profile <name>","Run in profile mode (use profile name)").addHelpText("after",`
252
+ See README.md for complete DSL reference.`);re.command("run").description("Run a workflow from a YAML or JSON file").argument("[file]","Path to the workflow file (YAML or JSON, relative or absolute). If omitted, will select from workflows in the nearest tp/workflows directory.").option("-s, --silent","Run in silent mode (suppress console output)").option("-p, --profile <name>","Run in profile mode (use profile name)").addHelpText("after",`
250
253
  Examples:
251
254
  $ tp run workflow.yaml
252
255
  $ tp run workflow.json
@@ -271,40 +274,40 @@ Workflow File Structure:
271
274
  \u2022 all/any/not: Combine conditions
272
275
 
273
276
  Supported formats: YAML (.yaml, .yml) and JSON (.json)
274
- See README.md for complete DSL documentation.`).action(async(r,e)=>{try{let t=r??await er()??null;t||(console.error(b.default.red(`
275
- \u2717 No workflow file found`)),process.exit(1)),e.silent&&No();let o=ve(t);console.log(b.default.blue(`Loading workflow from ${t}...`));let s=(0,ee.readFileSync)(t,"utf-8"),i=o.parse(s);if(!i.steps||!Array.isArray(i.steps))throw new Error("Invalid workflow: steps array is required");let n;if(e.profile){let l=e.profile.trim();if(!i.profiles?.length)throw new Error(`Profile "${l}" requested but workflow has no "profiles" defined. Add a "profiles" section to your workflow file.`);let c=i.profiles.find(p=>p.name===l);if(!c){let p=i.profiles.map(f=>f.name).join(", ");throw new Error(`Profile "${l}" not found. Available profile(s): ${p}`)}n=c.var}i._lineNumbers=o.extractStepLineNumbers(s),i._fileName=tr(t),i._filePath=(0,G.resolve)(t),console.log(b.default.green(`Starting workflow execution...
277
+ See README.md for complete DSL documentation.`).action(async(o,e)=>{try{let t=o??await rr()??null;t||(console.error(b.default.red(`
278
+ \u2717 No workflow file found`)),process.exit(1)),e.silent&&Bo();let r=ve(t);console.log(b.default.blue(`Loading workflow from ${t}...`));let s=(0,te.readFileSync)(t,"utf-8"),i=r.parse(s);if(!i.steps||!Array.isArray(i.steps))throw new Error("Invalid workflow: steps array is required");let n;if(e.profile){let l=e.profile.trim();if(!i.profiles?.length)throw new Error(`Profile "${l}" requested but workflow has no "profiles" defined. Add a "profiles" section to your workflow file.`);let c=i.profiles.find(d=>d.name===l);if(!c){let d=i.profiles.map(f=>f.name).join(", ");throw new Error(`Profile "${l}" not found. Available profile(s): ${d}`)}n=c.var}i._lineNumbers=r.extractStepLineNumbers(s),i._fileName=nr(t),i._filePath=(0,G.resolve)(t),console.log(b.default.green(`Starting workflow execution...
276
279
  `)),await new ke().execute(i,n?{profileVars:n}:void 0),console.log(b.default.green(`
277
- \u2713 Workflow completed successfully`))}catch(t){let o=t instanceof Error?t.message:String(t);console.error(b.default.red(`
278
- \u2717 Workflow failed: ${o}`)),process.exit(1)}});oe.command("open").description("Open generator or docs website in browser").argument("<target>",'Target to open: "generator" or "docs"').addHelpText("after",`
280
+ \u2713 Workflow completed successfully`))}catch(t){let r=t instanceof Error?t.message:String(t);console.error(b.default.red(`
281
+ \u2717 Workflow failed: ${r}`)),process.exit(1)}});re.command("open").description("Open generator or docs website in browser").argument("<target>",'Target to open: "generator" or "docs"').addHelpText("after",`
279
282
  Examples:
280
283
  $ tp open generator
281
284
  $ tp open docs
282
285
 
283
286
  Targets:
284
287
  generator Open the visual workflow generator (https://task-pipeliner-generator.racgoo.com/)
285
- docs Open the documentation site (https://task-pipeliner.racgoo.com/)`).action(async r=>{let t={generator:"https://task-pipeliner-generator.racgoo.com/",docs:"https://task-pipeliner.racgoo.com/"}[r.toLowerCase()];t||(console.error(b.default.red(`
286
- \u2717 Invalid target: ${r}`)),console.log(b.default.yellow(`
287
- Valid targets:`)),console.log(b.default.yellow(" \u2022 generator - Open the visual workflow generator")),console.log(b.default.yellow(" \u2022 docs - Open the documentation site")),process.exit(1));try{let o=process.platform,s;o==="darwin"?s=`open "${t}"`:o==="win32"?s=`start "${t}"`:s=`xdg-open "${t}"`,await hn(s),console.log(b.default.green(`
288
- \u2713 Opening ${r==="generator"?"generator":"documentation"} in browser...`)),console.log(b.default.blue(` ${t}`))}catch(o){let s=o instanceof Error?o.message:String(o);console.error(b.default.red(`
288
+ 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(b.default.red(`
289
+ \u2717 Invalid target: ${o}`)),console.log(b.default.yellow(`
290
+ Valid targets:`)),console.log(b.default.yellow(" \u2022 generator - Open the visual workflow generator")),console.log(b.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 Dn(s),console.log(b.default.green(`
291
+ \u2713 Opening ${o==="generator"?"generator":"documentation"} in browser...`)),console.log(b.default.blue(` ${t}`))}catch(r){let s=r instanceof Error?r.message:String(r);console.error(b.default.red(`
289
292
  \u2717 Failed to open browser: ${s}`)),console.log(b.default.yellow(`
290
- Please visit manually: ${t}`)),process.exit(1)}});oe.addCommand(Zo());oe.command("setup").description("Create tp directory with workflows and schedules folders and add 2 example files in each (echo-based dummies). Run from project root for easy initial setup.").action(async()=>{let r=process.cwd(),e=(0,G.join)(r,"tp"),t=(0,G.join)(e,"workflows"),o=(0,G.join)(e,"schedules");(0,ee.existsSync)(e)?console.log(b.default.gray(`
291
- tp directory already exists at ${e}`)):(await(0,te.mkdir)(e,{recursive:!0}),console.log(b.default.green(`
292
- \u2713 Created ${e}`)));let s=async(n,a)=>{(0,ee.existsSync)(n)?console.log(b.default.gray(` ${a} already exists`)):(await(0,te.mkdir)(n,{recursive:!0}),console.log(b.default.green(`\u2713 Created ${a}`)))};await s(t,"tp/workflows"),await s(o,"tp/schedules");let i=[];for(let{filename:n,content:a}of Xo){let l=(0,G.join)(t,n);(0,ee.existsSync)(l)?console.log(b.default.gray(` Skipped (exists): tp/workflows/${n}`)):(await(0,te.writeFile)(l,a,"utf-8"),i.push(`tp/workflows/${n}`))}for(let{filename:n,content:a}of Ko){let l=(0,G.join)(o,n);(0,ee.existsSync)(l)?console.log(b.default.gray(` Skipped (exists): tp/schedules/${n}`)):(await(0,te.writeFile)(l,a,"utf-8"),i.push(`tp/schedules/${n}`))}i.length>0&&(console.log(b.default.green(`
293
+ Please visit manually: ${t}`)),process.exit(1)}});re.addCommand(Qo());re.command("setup").description("Create tp directory with workflows and schedules folders and add 2 example files in each (echo-based dummies). Run from project root for easy initial setup.").action(async()=>{let o=process.cwd(),e=(0,G.join)(o,"tp"),t=(0,G.join)(e,"workflows"),r=(0,G.join)(e,"schedules");(0,te.existsSync)(e)?console.log(b.default.gray(`
294
+ tp directory already exists at ${e}`)):(await(0,oe.mkdir)(e,{recursive:!0}),console.log(b.default.green(`
295
+ \u2713 Created ${e}`)));let s=async(n,a)=>{(0,te.existsSync)(n)?console.log(b.default.gray(` ${a} already exists`)):(await(0,oe.mkdir)(n,{recursive:!0}),console.log(b.default.green(`\u2713 Created ${a}`)))};await s(t,"tp/workflows"),await s(r,"tp/schedules");let i=[];for(let{filename:n,content:a}of er){let l=(0,G.join)(t,n);(0,te.existsSync)(l)?console.log(b.default.gray(` Skipped (exists): tp/workflows/${n}`)):(await(0,oe.writeFile)(l,a,"utf-8"),i.push(`tp/workflows/${n}`))}for(let{filename:n,content:a}of tr){let l=(0,G.join)(r,n);(0,te.existsSync)(l)?console.log(b.default.gray(` Skipped (exists): tp/schedules/${n}`)):(await(0,oe.writeFile)(l,a,"utf-8"),i.push(`tp/schedules/${n}`))}i.length>0&&(console.log(b.default.green(`
293
296
  \u2713 Added ${i.length} example file(s):`)),i.forEach(n=>console.log(b.default.dim(` ${n}`)))),console.log(b.default.dim(`
294
- Next: tp run tp/workflows/example-hello.yaml | tp schedule add tp/schedules/example-daily.yaml | tp schedule list`)),console.log()});var gn=oe.command("history").description("Manage workflow execution history");gn.action(async()=>{let r=new B,e=new B(!0),t=await r.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"}]);t?.id||(console.error(b.default.red(`
295
- \u2717 Invalid choice`)),process.exit(1));let o=new xe;switch(t.id){case"show":{let s=await o.getHistoryNames();if(s.length===0){console.log(b.default.yellow(`
297
+ Next: tp run tp/workflows/example-hello.yaml | tp schedule add tp/schedules/example-daily.yaml | tp schedule list`)),console.log()});var Tn=re.command("history").description("Manage workflow execution history");Tn.action(async()=>{let o=new B,e=new B(!0),t=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"}]);t?.id||(console.error(b.default.red(`
298
+ \u2717 Invalid choice`)),process.exit(1));let r=new xe;switch(t.id){case"show":{let s=await r.getHistoryNames();if(s.length===0){console.log(b.default.yellow(`
296
299
  \u26A0 No history found`));return}let i=await e.prompt("Select a history to view",s.map(n=>({id:n,label:n})));i?.id||(console.error(b.default.red(`
297
- \u2717 Invalid choice`)),process.exit(1));try{let n=await o.getHistory(i.id);vo(n,i.id)}catch(n){let a=n instanceof Error?n.message:String(n);console.error(b.default.red(`
298
- \u2717 Failed to load history: ${a}`)),process.exit(1)}break}case"remove":{let s=await o.getHistoryNames();if(s.length===0){console.log(b.default.yellow(`
300
+ \u2717 Invalid choice`)),process.exit(1));try{let n=await r.getHistory(i.id);Eo(n,i.id)}catch(n){let a=n instanceof Error?n.message:String(n);console.error(b.default.red(`
301
+ \u2717 Failed to load history: ${a}`)),process.exit(1)}break}case"remove":{let s=await r.getHistoryNames();if(s.length===0){console.log(b.default.yellow(`
299
302
  \u26A0 No history found`));return}let i=await e.prompt("Select a history to remove",s.map(n=>({id:n,label:n})));i?.id||(console.error(b.default.red(`
300
- \u2717 Invalid choice`)),process.exit(1));try{await o.removeHistory(i.id),console.log(b.default.green(`
303
+ \u2717 Invalid choice`)),process.exit(1));try{await r.removeHistory(i.id),console.log(b.default.green(`
301
304
  \u2713 Removed history: ${i.id}`))}catch(n){let a=n instanceof Error?n.message:String(n);console.error(b.default.red(`
302
- \u2717 Failed to remove history: ${a}`)),process.exit(1)}break}case"remove-all":{if((await r.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(b.default.yellow(`
303
- \u2717 Cancelled`));return}try{await o.clearAllHistories(),console.log(b.default.green(`
305
+ \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(b.default.yellow(`
306
+ \u2717 Cancelled`));return}try{await r.clearAllHistories(),console.log(b.default.green(`
304
307
  \u2713 All histories removed`))}catch(i){let n=i instanceof Error?i.message:String(i);console.error(b.default.red(`
305
308
  \u2717 Failed to remove histories: ${n}`)),process.exit(1)}break}default:console.error(b.default.red(`
306
- \u2717 Unknown action: ${t.id}`)),process.exit(1)}});oe.command("clean").description("Remove all data in ~/.pipeliner (schedules, daemon state, workflow history). Use after upgrades if data is incompatible.").action(async()=>{if((await new B().prompt(`This will remove all data in ${b.default.yellow(je)} (schedules, daemon PID, workflow history). Continue?`,[{id:"yes",label:"Yes, remove all"},{id:"no",label:"No, cancel"}]))?.id!=="yes"){console.log(b.default.yellow(`
307
- \u2717 Cancelled`));return}try{if(await Y()){let t=await N();console.log(b.default.gray(`Stopping scheduler daemon (PID: ${t.pid})...`)),await new K().stopDaemon(),console.log(b.default.gray(" Daemon stopped"))}(0,ee.existsSync)(je)?(await(0,te.rm)(je,{recursive:!0}),console.log(b.default.green(`
308
- \u2713 Removed ${je}`))):console.log(b.default.gray(`
309
- ${je} does not exist (already clean)`))}catch(t){let o=t instanceof Error?t.message:String(t);console.error(b.default.red(`
310
- \u2717 Clean failed: ${o}`)),process.exit(1)}});oe.parse();
309
+ \u2717 Unknown action: ${t.id}`)),process.exit(1)}});re.command("clean").description("Remove all data in ~/.pipeliner (schedules, daemon state, workflow history). Use after upgrades if data is incompatible.").action(async()=>{if((await new B().prompt(`This will remove all data in ${b.default.yellow(Ae)} (schedules, daemon PID, workflow history). Continue?`,[{id:"yes",label:"Yes, remove all"},{id:"no",label:"No, cancel"}]))?.id!=="yes"){console.log(b.default.yellow(`
310
+ \u2717 Cancelled`));return}try{if(await Y()){let t=await N();console.log(b.default.gray(`Stopping scheduler daemon (PID: ${t.pid})...`)),await new Q().stopDaemon(),console.log(b.default.gray(" Daemon stopped"))}(0,te.existsSync)(Ae)?(await(0,oe.rm)(Ae,{recursive:!0}),console.log(b.default.green(`
311
+ \u2713 Removed ${Ae}`))):console.log(b.default.gray(`
312
+ ${Ae} does not exist (already clean)`))}catch(t){let r=t instanceof Error?t.message:String(t);console.error(b.default.red(`
313
+ \u2717 Clean failed: ${r}`)),process.exit(1)}});re.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-pipeliner",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "A task pipeline runner with condition-based workflow execution",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -51,6 +51,7 @@
51
51
  "cronstrue": "^3.11.0",
52
52
  "dayjs": "^1.11.19",
53
53
  "inquirer": "^8.2.6",
54
+ "jsonpath-plus": "^8.0.0",
54
55
  "log-update": "^4.0.0",
55
56
  "node-cron": "^4.2.1",
56
57
  "ora": "^5.4.1",