task-pipeliner 0.3.2 → 0.3.3
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 +5 -4
- package/README.md +3 -2
- package/dist/index.cjs +12 -12
- package/package.json +1 -1
package/README.ko.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 조건 기반 실행과 아름다운 CLI 출력을 제공하는 강력한 워크플로우 오케스트레이션 도구
|
|
4
4
|
|
|
5
|
-
**버전:** 0.3.
|
|
5
|
+
**버전:** 0.3.3
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
|
|
@@ -371,13 +371,14 @@ steps: # 필수: 실행할 단계 배열
|
|
|
371
371
|
- **타입**: `string` (상대 또는 절대 경로)
|
|
372
372
|
- **설명**: 모든 명령 실행을 위한 기본 디렉토리
|
|
373
373
|
- **해석**:
|
|
374
|
-
- **상대 경로** (예: `./`, `../frontend`):
|
|
374
|
+
- **상대 경로** (예: `./`, `../frontend`): 워크플로우 파일의 디렉토리를 기준으로 해석
|
|
375
375
|
- **절대 경로** (예: `/home/user/project`): 그대로 사용
|
|
376
|
-
- **생략 시**:
|
|
376
|
+
- **생략 시**: 워크플로우 파일의 디렉토리 사용 (스케줄 파일과 동일)
|
|
377
377
|
- **예제**:
|
|
378
378
|
```yaml
|
|
379
|
-
baseDir: ./frontend #
|
|
379
|
+
baseDir: ./frontend # 워크플로우 파일 기준 상대 경로
|
|
380
380
|
baseDir: /app/frontend # 절대 경로
|
|
381
|
+
# 생략 시, 명령은 워크플로우 파일의 디렉토리에서 실행됨
|
|
381
382
|
```
|
|
382
383
|
|
|
383
384
|
#### `shell` (선택)
|
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.
|
|
5
|
+
**Version:** 0.3.3
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
|
|
@@ -373,11 +373,12 @@ steps: # Required: Array of steps to execute
|
|
|
373
373
|
- **Resolution**:
|
|
374
374
|
- **Relative path** (e.g., `./`, `../frontend`): Resolved relative to the workflow file's directory
|
|
375
375
|
- **Absolute path** (e.g., `/home/user/project`): Used as-is
|
|
376
|
-
- **If omitted**:
|
|
376
|
+
- **If omitted**: Workflow file's directory is used (same as schedule files)
|
|
377
377
|
- **Example**:
|
|
378
378
|
```yaml
|
|
379
379
|
baseDir: ./frontend # Relative to workflow file
|
|
380
380
|
baseDir: /app/frontend # Absolute path
|
|
381
|
+
# If omitted, commands run in the workflow file's directory
|
|
381
382
|
```
|
|
382
383
|
|
|
383
384
|
#### `shell` (optional)
|
package/dist/index.cjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";var Yt=Object.create;var De=Object.defineProperty;var Ut=Object.getOwnPropertyDescriptor;var Jt=Object.getOwnPropertyNames;var qt=Object.getPrototypeOf,Gt=Object.prototype.hasOwnProperty;var Zt=(o,e)=>()=>(o&&(e=o(o=0)),e);var Xt=(o,e)=>{for(var t in e)De(o,t,{get:e[t],enumerable:!0})},Kt=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Jt(e))!Gt.call(o,n)&&n!==t&&De(o,n,{get:()=>e[n],enumerable:!(r=Ut(e,n))||r.enumerable});return o};var y=(o,e,t)=>(t=o!=null?Yt(qt(o)):{},Kt(e||!o||!o.__esModule?De(t,"default",{value:o,enumerable:!0}):t,o));var Qe={};Xt(Qe,{DAEMON_DIR:()=>q,getDaemonErrorLogPath:()=>Me,getDaemonPid:()=>Te,getDaemonStartTime:()=>Ke,getDaemonStatus:()=>R,isDaemonRunning:()=>A,readDaemonErrorLog:()=>je,removeDaemonPid:()=>se,saveDaemonPid:()=>er,writeDaemonError:()=>Ie});function Qt(o){try{return process.kill(o,0),!0}catch{return!1}}async function Te(){try{if(!(0,
|
|
2
|
+
"use strict";var Yt=Object.create;var De=Object.defineProperty;var Ut=Object.getOwnPropertyDescriptor;var Jt=Object.getOwnPropertyNames;var qt=Object.getPrototypeOf,Gt=Object.prototype.hasOwnProperty;var Zt=(o,e)=>()=>(o&&(e=o(o=0)),e);var Xt=(o,e)=>{for(var t in e)De(o,t,{get:e[t],enumerable:!0})},Kt=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Jt(e))!Gt.call(o,n)&&n!==t&&De(o,n,{get:()=>e[n],enumerable:!(r=Ut(e,n))||r.enumerable});return o};var y=(o,e,t)=>(t=o!=null?Yt(qt(o)):{},Kt(e||!o||!o.__esModule?De(t,"default",{value:o,enumerable:!0}):t,o));var Qe={};Xt(Qe,{DAEMON_DIR:()=>q,getDaemonErrorLogPath:()=>Me,getDaemonPid:()=>Te,getDaemonStartTime:()=>Ke,getDaemonStatus:()=>R,isDaemonRunning:()=>A,readDaemonErrorLog:()=>je,removeDaemonPid:()=>se,saveDaemonPid:()=>er,writeDaemonError:()=>Ie});function Qt(o){try{return process.kill(o,0),!0}catch{return!1}}async function Te(){try{if(!(0,H.existsSync)(N))return null;let o=await(0,x.readFile)(N,"utf-8"),e=parseInt(o.trim(),10);return isNaN(e)?(await(0,x.unlink)(N),null):Qt(e)?e:(await(0,x.unlink)(N),null)}catch(o){if(o instanceof Error&&"code"in o&&o.code==="ENOENT")return null;throw o}}async function A(){return await Te()!==null}async function er(){await(0,x.mkdir)(q,{recursive:!0}),await(0,x.writeFile)(N,process.pid.toString(),"utf-8");let o=new Date().toISOString();await(0,x.writeFile)(oe,o,"utf-8")}async function Ie(o){try{await(0,x.mkdir)(q,{recursive:!0});let e=`${new Date().toISOString()} ${o.message}
|
|
3
3
|
${o.stack??""}
|
|
4
|
-
`;await(0,x.writeFile)(fe,e,"utf-8")}catch{}}async function se(){try{(0,
|
|
5
|
-
`){i.length>0&&(g(),r(i[s]));return}if(d==="\x1B"&&h.length===1){n&&(n="",c(),l());return}if(d==="\x1B[A"){i.length>0&&(s=s>0?s-1:i.length-1,l());return}if(d==="\x1B[B"){i.length>0&&(s=s<i.length-1?s+1:0,l());return}if(d==="\x7F"||d==="\b"){n.length>0&&(n=n.slice(0,-1),c(),l());return}d.length===1&&d>=" "&&d<="~"&&(n+=d,c(),l())},g=()=>{process.stdin.removeListener("data",f),process.stdin.isTTY&&process.stdin.setRawMode(!1),a.close(),process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[?1049l")};l(),process.stdin.on("data",f)})}},me=class{async prompt(e,t){let{value:r}=await Ne.default.prompt([{type:"input",name:"value",message:D.default.cyan(e),default:t}]);return r}};var he=y(require("boxen"),1),G=y(require("chalk"),1);function Ae(o,e,t,r={}){let{borderColor:n="cyan",isNested:s=!1}=r,i;e!==void 0&&(t?i=`line ${e} in ${t}`:i=`line ${e}`);let a=s?`\u2502 ${o}`:`> ${o}`;return(0,he.default)(a,{title:i,borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:n})}function Z(o,e=!1,t){let r=o?"\u2713 Completed":"\u2717 Failed",n=o?G.default.green(r):G.default.red(r);if(t!==void 0){let s=X(t);return`${n} ${G.default.gray(`(${s})`)}`}return n}function ae(o){return(0,he.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 rt(o){return(0,he.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 ot(o){let e=o?"\u2713 All parallel branches completed":"\u2717 Some parallel branches failed";return o?G.default.green(e):G.default.red(e)}function Oe(o,e=!1){return`${e?"| \u2502 ":"\u2502 "}${o}`}function X(o){return`${(o/1e3).toFixed(3)}s`}var nt=require("fs"),st=require("path"),K=class{constructor(e){this.workspace=e}evaluate(e){return"var"in e||"has"in e?this.evaluateVarExists(e):"file"in e?this.evaluateFileExists(e):"choice"in e?this.evaluateChoice(e):"all"in e?this.evaluateAll(e):"any"in e?this.evaluateAny(e):"not"in e?this.evaluateNot(e):!1}evaluateVarExists(e){if(e.has)return this.workspace.hasVariable(e.has)||this.workspace.hasFact(e.has);if(!e.var)return!1;if(typeof e.var=="object"){for(let[r,n]of Object.entries(e.var)){let s=this.workspace.getVariable(r),i=this.workspace.getFact(r),a=s??(i!==void 0?i.toString():void 0);if(a===void 0||a!==n)return!1}return!0}let t=e.var;return this.workspace.hasVariable(t)||this.workspace.hasFact(t)}evaluateFileExists(e){try{let t=e.file.trim(),r=(0,st.resolve)(process.cwd(),t);return(0,nt.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 T=require("fs/promises"),it=require("os"),
|
|
6
|
-
`)),w=
|
|
7
|
-
`)),S=
|
|
4
|
+
`;await(0,x.writeFile)(fe,e,"utf-8")}catch{}}async function se(){try{(0,H.existsSync)(N)&&await(0,x.unlink)(N),(0,H.existsSync)(oe)&&await(0,x.unlink)(oe)}catch{}}async function Ke(){try{if((0,H.existsSync)(oe)){let e=(await(0,x.readFile)(oe,"utf-8")).trim();if(e)return e}if((0,H.existsSync)(N)){let o=await(0,x.stat)(N);return new Date(o.mtime).toISOString()}return null}catch{return null}}function Me(){return fe}async function je(){try{return(0,H.existsSync)(fe)&&(await(0,x.readFile)(fe,"utf-8")).trim()||null}catch{return null}}async function R(){let o=await Te(),e=o?await Ke():null;return{running:o!==null,pid:o,startTime:e}}var H,x,Xe,ne,q,N,oe,fe,ie=Zt(()=>{"use strict";H=require("fs"),x=require("fs/promises"),Xe=require("os"),ne=require("path"),q=(0,ne.join)((0,Xe.homedir)(),".pipeliner","daemon"),N=(0,ne.join)(q,"scheduler.pid"),oe=(0,ne.join)(q,"scheduler.started");fe=(0,ne.join)(q,"error.log")});var Wt=require("child_process"),de=require("fs"),Pe=require("fs/promises"),_t=require("os"),U=require("path"),Vt=require("util"),Ze=y(require("boxen"),1),p=y(require("chalk"),1),Ht=require("commander"),zt=y(require("dayjs"),1);ie();var B=require("path"),lt=y(require("chalk"),1),Se=y(require("log-update"),1);var tt=y(require("readline"),1),D=y(require("chalk"),1),Ne=y(require("inquirer"),1),et=15,L=class{searchable;constructor(e=!1){this.searchable=e}async prompt(e,t){if(this.searchable)return this.promptWithSearch(e,t);let{choice:r}=await Ne.default.prompt([{type:"list",name:"choice",message:D.default.cyan(e),choices:t.map(s=>({name:s.label,value:s.id})),pageSize:et}]),n=t.find(s=>s.id===r);if(!n)throw new Error(`Invalid choice: ${r}`);return n}async promptWithSearch(e,t){return new Promise(r=>{let n="",s=0,i=[...t],a=tt.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(D.default.cyan(`? ${e}`));let h=n?D.default.gray(` Filter: ${n}`)+D.default.gray(` (${i.length}/${t.length})`):D.default.gray(" Type to filter, \u2191\u2193 to navigate, Enter to select");console.log(h),console.log();let d=et,w=0,S=i.length;if(i.length>d){let v=Math.floor(d/2);w=Math.max(0,s-v),S=Math.min(i.length,w+d),S===i.length&&(w=Math.max(0,S-d))}if(i.length===0)console.log(D.default.yellow(" No matches found"));else{w>0&&console.log(D.default.gray(` \u2191 ${w} more above`));for(let v=w;v<S;v++){let $=i[v];console.log(v===s?D.default.cyan(`\u276F ${$.label}`):D.default.white(` ${$.label}`))}S<i.length&&console.log(D.default.gray(` \u2193 ${i.length-S} more below`))}},c=()=>{let h=n.toLowerCase();i=h?t.filter(d=>d.label.toLowerCase().includes(h)):[...t],s>=i.length&&(s=Math.max(0,i.length-1))},f=h=>{let d=h.toString();if(d===""&&(g(),process.exit(0)),d==="\r"||d===`
|
|
5
|
+
`){i.length>0&&(g(),r(i[s]));return}if(d==="\x1B"&&h.length===1){n&&(n="",c(),l());return}if(d==="\x1B[A"){i.length>0&&(s=s>0?s-1:i.length-1,l());return}if(d==="\x1B[B"){i.length>0&&(s=s<i.length-1?s+1:0,l());return}if(d==="\x7F"||d==="\b"){n.length>0&&(n=n.slice(0,-1),c(),l());return}d.length===1&&d>=" "&&d<="~"&&(n+=d,c(),l())},g=()=>{process.stdin.removeListener("data",f),process.stdin.isTTY&&process.stdin.setRawMode(!1),a.close(),process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[?1049l")};l(),process.stdin.on("data",f)})}},me=class{async prompt(e,t){let{value:r}=await Ne.default.prompt([{type:"input",name:"value",message:D.default.cyan(e),default:t}]);return r}};var he=y(require("boxen"),1),G=y(require("chalk"),1);function Ae(o,e,t,r={}){let{borderColor:n="cyan",isNested:s=!1}=r,i;e!==void 0&&(t?i=`line ${e} in ${t}`:i=`line ${e}`);let a=s?`\u2502 ${o}`:`> ${o}`;return(0,he.default)(a,{title:i,borderStyle:"round",padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:0,right:0},borderColor:n})}function Z(o,e=!1,t){let r=o?"\u2713 Completed":"\u2717 Failed",n=o?G.default.green(r):G.default.red(r);if(t!==void 0){let s=X(t);return`${n} ${G.default.gray(`(${s})`)}`}return n}function ae(o){return(0,he.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 rt(o){return(0,he.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 ot(o){let e=o?"\u2713 All parallel branches completed":"\u2717 Some parallel branches failed";return o?G.default.green(e):G.default.red(e)}function Oe(o,e=!1){return`${e?"| \u2502 ":"\u2502 "}${o}`}function X(o){return`${(o/1e3).toFixed(3)}s`}var nt=require("fs"),st=require("path"),K=class{constructor(e){this.workspace=e}evaluate(e){return"var"in e||"has"in e?this.evaluateVarExists(e):"file"in e?this.evaluateFileExists(e):"choice"in e?this.evaluateChoice(e):"all"in e?this.evaluateAll(e):"any"in e?this.evaluateAny(e):"not"in e?this.evaluateNot(e):!1}evaluateVarExists(e){if(e.has)return this.workspace.hasVariable(e.has)||this.workspace.hasFact(e.has);if(!e.var)return!1;if(typeof e.var=="object"){for(let[r,n]of Object.entries(e.var)){let s=this.workspace.getVariable(r),i=this.workspace.getFact(r),a=s??(i!==void 0?i.toString():void 0);if(a===void 0||a!==n)return!1}return!0}let t=e.var;return this.workspace.hasVariable(t)||this.workspace.hasFact(t)}evaluateFileExists(e){try{let t=e.file.trim(),r=(0,st.resolve)(process.cwd(),t);return(0,nt.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 T=require("fs/promises"),it=require("os"),z=require("path"),at=y(require("dayjs"),1),Q=(0,z.join)((0,it.homedir)(),".pipeliner","workflow-history"),ee=class{constructor(){}async saveHistory(e){await(0,T.mkdir)(Q,{recursive:!0});let t=(0,at.default)().format("YYYY-MM-DD_HH-mm-ss"),r=Math.random().toString(36).slice(2,6),n=(0,z.join)(Q,`workflow-${t}-${r}.json`);return await(0,T.writeFile)(n,JSON.stringify(e,null,2),{encoding:"utf8"}),n}async clearAllHistories(){await(0,T.rm)(Q,{recursive:!0,force:!0})}async removeHistory(e){await(0,T.rm)((0,z.join)(Q,e),{force:!0})}async getHistoryNames(){try{let t=(await(0,T.readdir)(Q)).map(r=>(0,z.basename)(r));return t.sort((r,n)=>{let s=l=>{let c=l.match(/workflow-(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-/);return c?c[1]:""},i=s(r),a=s(n);return i===a?n.localeCompare(r):a.localeCompare(i)}),t}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return[];throw e}}async getHistory(e){let t=await(0,T.readFile)((0,z.join)(Q,e),{encoding:"utf8"});return JSON.parse(t)}};var ge=class{records=[];initialTimestamp=Date.now();recordStartTimestamp=Date.now();constructor(){this.records=[]}recordStart(){this.recordStartTimestamp=Date.now()}recordEnd(e,t,r,n){let s=this.getDuration();return this.records.push({step:e,context:t,output:r,duration:s,status:n}),s}reset(){this.records=[],this.initialTimestamp=Date.now()}async save(){let e=new ee,t={initialTimestamp:this.initialTimestamp,records:this.records};return await e.saveHistory(t)}getDuration(){return Date.now()-this.recordStartTimestamp}};var Fe=require("child_process");var we=class{async run(e,t,r,n,s=!1,i=!1,a,l,c,f,g){return s?this.runBuffered(e,c,f,g):this.runRealtime(e,r||e,i,a,l,c,f,g)}async runBuffered(e,t,r,n){return new Promise((s,i)=>{let a=this.spawnWithShell(e,t,n),l=[],c=[],f="",g="",h=null;r&&r>0&&(h=setTimeout(()=>{a.kill("SIGTERM");let d=`Command timed out after ${r} seconds`;c.push(d),s({success:!1,stdout:l,stderr:c})},r*1e3)),a.stdout?.on("data",d=>{let w=d.toString(),{lines:S,remaining:v}=this.processStreamBuffer(w,f);l.push(...S),f=v}),a.stderr?.on("data",d=>{let w=d.toString(),{lines:S,remaining:v}=this.processStreamBuffer(w,g);c.push(...S),g=v}),a.on("close",d=>{h&&clearTimeout(h),f.trim()&&l.push(f),g.trim()&&c.push(g),s({success:d===0,stdout:l,stderr:c})}),a.on("error",d=>{h&&clearTimeout(h);let w=`Error: ${d.message}`;s({success:!1,stdout:l,stderr:[...c,w]})})})}async runRealtime(e,t,r,n,s,i,a,l){let f=Ae(t,n,s,{borderColor:r?"green":"cyan"});console.log(f);let g=Date.now();return new Promise(h=>{let d=this.spawnWithShell(e,i,l),w="",S="",v=null;a&&a>0&&(v=setTimeout(()=>{d.kill("SIGTERM");let $=`Command timed out after ${a} seconds`,C=ae($);console.error(C);let _=Date.now()-g,V=Z(!1,!1,_);console.log(V),h(!1)},a*1e3)),d.stdout?.on("data",$=>{let C=$.toString(),{lines:_,remaining:V}=this.processStreamBuffer(C,w);_.forEach(Ce=>process.stdout.write(`\u2502 ${Ce}
|
|
6
|
+
`)),w=V}),d.stderr?.on("data",$=>{let C=$.toString(),{lines:_,remaining:V}=this.processStreamBuffer(C,S);_.forEach(Ce=>process.stderr.write(`\u2502 ${Ce}
|
|
7
|
+
`)),S=V}),d.on("close",$=>{v&&clearTimeout(v),w.trim()&&process.stdout.write(`\u2502 ${w}
|
|
8
8
|
`),S.trim()&&process.stderr.write(`\u2502 ${S}
|
|
9
|
-
`);let C=$===0,
|
|
9
|
+
`);let C=$===0,_=Date.now()-g,V=Z(C,!1,_);console.log(V),h(C)}),d.on("error",$=>{v&&clearTimeout(v);let C=ae(`Error: ${$.message}`);console.error(C),h(!1)})})}createSpawnOptions(e){let t={stdio:["inherit","pipe","pipe"],shell:!0};return e&&(t.cwd=e),t}spawnWithShell(e,t,r){if(r&&r.length>0){let n=r[0],s=[...r.slice(1),e],i={stdio:["inherit","pipe","pipe"]};return t&&(i.cwd=t),(0,Fe.spawn)(n,s,i)}else{let n=process.env.SHELL||(process.platform==="win32"?"cmd.exe":"/bin/sh"),s=process.platform==="win32"?"/c":"-c",i={stdio:["inherit","pipe","pipe"]};return t&&(i.cwd=t),(0,Fe.spawn)(n,[s,e],i)}}processStreamBuffer(e,t){let r=t+e,n=[],s=r;for(;s.includes(`
|
|
10
10
|
`);){let i=s.indexOf(`
|
|
11
11
|
`),a=s.substring(0,i);s=s.substring(i+1),n.push(a)}return{lines:n,remaining:s}}formatNestedOutput(e,t){t?e.split(`
|
|
12
12
|
`).forEach(r=>{r.trim()&&console.log(`| ${r}`)}):console.log(e)}displayBufferedOutput(e,t,r=!1,n,s){let i=Ae(t,n,s,{borderColor:"cyan",isNested:r});this.formatNestedOutput(i,r),e.stdout.forEach(l=>{let c=Oe(l,r);process.stdout.write(`${c}
|
|
13
13
|
`)}),e.stderr.forEach(l=>{let c=Oe(l,r);process.stderr.write(`${c}
|
|
14
|
-
`)});let a=Z(e.success,r);console.log(a)}};function tr(o,e,t){if(e.hasVariable(o)){let r=e.getVariable(o);return r??t}if(e.hasFact(o)){let r=e.getFact(o);return typeof r=="string"?r:String(r)}if(e.hasChoice(o)){let r=e.getChoice(o);return r??t}return t}function ye(o,e){let t=/\{\{\s*(\w+)\s*\}\}/g;return o.replace(t,(r,n)=>tr(n,e,r))}var be=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 te=class o{static PARALLEL_STEP_INDEX_MULTIPLIER=1e3;workspace;taskRunner;choicePrompt;textPrompt;baseDir;globalShell;constructor(){this.workspace=new be,this.taskRunner=new we,this.choicePrompt=new L,this.textPrompt=new me}resolveBaseDir(e){if(e.baseDir)if((0,
|
|
14
|
+
`)});let a=Z(e.success,r);console.log(a)}};function tr(o,e,t){if(e.hasVariable(o)){let r=e.getVariable(o);return r??t}if(e.hasFact(o)){let r=e.getFact(o);return typeof r=="string"?r:String(r)}if(e.hasChoice(o)){let r=e.getChoice(o);return r??t}return t}function ye(o,e){let t=/\{\{\s*(\w+)\s*\}\}/g;return o.replace(t,(r,n)=>tr(n,e,r))}var be=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 te=class o{static PARALLEL_STEP_INDEX_MULTIPLIER=1e3;workspace;taskRunner;choicePrompt;textPrompt;baseDir;globalShell;constructor(){this.workspace=new be,this.taskRunner=new we,this.choicePrompt=new L,this.textPrompt=new me}resolveBaseDir(e){if(e.baseDir)if((0,B.isAbsolute)(e.baseDir))this.baseDir=e.baseDir;else if(e._filePath){let t=(0,B.dirname)(e._filePath);this.baseDir=(0,B.resolve)(t,e.baseDir)}else this.baseDir=(0,B.resolve)(process.cwd(),e.baseDir);else e._filePath&&(this.baseDir=(0,B.dirname)(e._filePath))}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 K(this.workspace).evaluate(e.when):!0}calculateBaseStepIndex(e){return e.branchIndex===void 0?e.stepIndex:Math.floor(e.stepIndex/o.PARALLEL_STEP_INDEX_MULTIPLIER)}isRunStep(e){return"run"in e}async execute(e,t){if(t?.profileVars&&Object.keys(t.profileVars).length>0)for(let[a,l]of Object.entries(t.profileVars))this.workspace.setVariable(a,l);this.resolveBaseDir(e),this.globalShell=e.shell;let r=new ge,n=Date.now();for(let a=0;a<e.steps.length;a++){let l=e.steps[a],c=this.createStepContext(a,e),f=!!l.when;if(this.evaluateStepCondition(l)){r.recordStart();try{let g=await this.executeStep(l,c,!1,f);this.handleStepResult(l,c,a,g,r)}catch(g){throw this.handleStepError(l,c,a,g,r),g}}}let s=Date.now()-n,i=X(s);console.log(lt.default.cyan(`
|
|
15
15
|
Total execution time: ${i}`)),await r.save(),r.reset()}isStepSuccessful(e,t){return"run"in t?typeof e=="boolean"?e:e&&typeof e=="object"&&"success"in e?e.success:!1:!0}handleStepResult(e,t,r,n,s){let i=this.isRunStep(e)?(()=>{let c=this.workspace.getStepResult(r);return c?c.success:!0})():this.isStepSuccessful(n,e),a=i?"success":"failure",l=s.recordEnd(e,t,n,a);if(!this.isRunStep(e)){let c=Z(i,!1,l);console.log(c)}if(this.isRunStep(e)){if(e.continue===!1){let c=t.lineNumber?` (line ${t.lineNumber})`:"",f=i?`Step ${r}${c} completed, but workflow stopped due to continue: false`:`Step ${r}${c} failed`;throw new Error(f)}if(!i&&e.continue!==!0){let c=t.lineNumber?` (line ${t.lineNumber})`:"";throw new Error(`Step ${r}${c} failed`)}}}handleStepError(e,t,r,n,s){this.workspace.setStepResult(r,!1);let i=n instanceof Error?n.message:String(n),a={success:!1,stdout:[],stderr:[i]};s.recordEnd(e,t,a,"failure")}fixMalformedStep(e){let r=e;return"choose"in e&&r.choose===null&&"message"in e&&"options"in e?{choose:{message:r.message,options:r.options,as:r.as},when:r.when}:"prompt"in e&&r.prompt===null&&"message"in e&&"as"in e?{prompt:{message:r.message,as:r.as,default:r.default},when:r.when}:e}async executeStep(e,t,r=!1,n=!1){if(e=this.fixMalformedStep(e),"run"in e){let s=await this.executeRunStep(e,t,r,n);return r&&typeof s=="object"&&"stdout"in s,s}if("choose"in e){await this.executeChooseStep(e,t);return}if("prompt"in e){await this.executePromptStep(e,t);return}if("parallel"in e){await this.executeParallelStep(e,t);return}if("fail"in e){await this.executeFailStep(e,t);return}}async executeSingleRun(e,t,r=!1,n=!1){let s=this.calculateBaseStepIndex(t),i=ye(e.run,this.workspace),a=e.shell||this.globalShell,l=e.retry??0,c=l==="Infinity"||l===1/0,f=typeof l=="number"?l:0,g=e.timeout,h=!1,d=0;for(;c||d<=f;){let w=await this.taskRunner.run(i,s,i,t.branchIndex,r,n,t.lineNumber,t.fileName,this.baseDir,g,a),S=typeof w=="boolean"?w:w.success;if(h=w,S||!c&&d>=f)break;if(d++,c||d<=f){let v=Math.min(1e3*Math.pow(2,d-1),1e4);await new Promise($=>setTimeout($,v))}}return h}async executeRunStep(e,t,r=!1,n=!1){let s=await this.executeSingleRun({run:e.run,timeout:e.timeout,retry:e.retry,shell:e.shell},t,r,n),i=typeof s=="boolean"?s:s.success;if(this.workspace.setStepResult(t.stepIndex,i),i||!e.onError)return s;let a={run:e.onError.run,timeout:e.onError.timeout,retry:e.onError.retry,onError:e.onError.onError??void 0};return await this.executeRunChain(a,t,r,n)}async executeRunChain(e,t,r,n){let s=await this.executeSingleRun({run:e.run,timeout:e.timeout,retry:e.retry,shell:void 0},t,r,n);return(typeof s=="boolean"?s:s.success)||!e.onError?s:this.executeRunChain(e.onError,t,r,n)}async executeChooseStep(e,t){let r=e.choose.as,n=e.choose.options.map(a=>a.id);if(r&&this.workspace.hasVariable(r)){let a=this.workspace.getVariable(r)??"";if(n.includes(a)){this.workspace.setChoice(a,a),this.workspace.setStepResult(t.stepIndex,!0);return}}let s=await this.choicePrompt.prompt(e.choose.message,e.choose.options);if(!s?.id)throw new Error(`Invalid choice result: ${JSON.stringify(s)}`);let i=r??s.id;this.workspace.setChoice(s.id,s.id),this.workspace.setVariable(i,s.id),this.workspace.setStepResult(t.stepIndex,!0)}async executePromptStep(e,t){let r=e.prompt.as;if(this.workspace.hasVariable(r)){let a=this.workspace.getVariable(r)??"";this.workspace.setFact(r,a),this.workspace.setStepResult(t.stepIndex,!0);return}let n=ye(e.prompt.message,this.workspace),s=e.prompt.default?ye(e.prompt.default,this.workspace):void 0,i=await this.textPrompt.prompt(n,s);this.workspace.setVariable(r,i),this.workspace.setFact(r,i),this.workspace.setStepResult(t.stepIndex,!0)}createParallelContexts(e,t){return e.parallel.map((r,n)=>({workspace:this.workspace.clone(),stepIndex:t.stepIndex*o.PARALLEL_STEP_INDEX_MULTIPLIER+n,branchIndex:n,lineNumber:t.lineNumber,fileName:t.fileName}))}getBranchDisplayName(e,t){return"run"in e?e.run:"choose"in e?`Choose: ${e.choose.message}`:"prompt"in e?`Prompt: ${e.prompt.message}`:"fail"in e?`Fail: ${e.fail.message}`:`Branch ${t+1}`}async executeParallelBranches(e,t){let r=[],n=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],s=0;for(let c=0;c<e.length;c++){let f=e[c],g=t[c];if(f.when&&!new K(g.workspace).evaluate(f.when))continue;let h=this.getBranchDisplayName(f,c);r.push({index:c,name:h,status:"pending"})}let i=setInterval(()=>{s=(s+1)%n.length,this.updateParallelBranchesDisplay(r,n[s])},100),a=r.map(async c=>{let{index:f}=c,g=e[f],h=t[f];c.status="running";try{let d=await this.executeStep(g,h,!0);return c.status="success",this.updateParallelBranchesDisplay(r,n[s]),{index:f,result:d,context:h}}catch(d){h.workspace.setStepResult(h.stepIndex,!1);let w=d instanceof Error?d.message:String(d);return c.status="failed",c.error=w,this.updateParallelBranchesDisplay(r,n[s]),{index:f,error:d,context:h}}}),l=await Promise.all(a);return clearInterval(i),this.updateParallelBranchesDisplay(r,"",!0),Se.default.done(),l}updateParallelBranchesDisplay(e,t,r=!1){let n=e.map(s=>{let i=s.index+1,a="",l="";switch(s.status){case"pending":a="\u25CB",l=`Branch ${i}: ${s.name} - Pending`;break;case"running":a=t,l=`Branch ${i}: ${s.name} - Running...`;break;case"success":a="\u2713",l=`Branch ${i}: ${s.name} - Completed`;break;case"failed":a="\u2717",l=`Branch ${i}: ${s.name} - Failed${s.error?`: ${s.error}`:""}`;break}return`${a} ${l}`});r?(0,Se.default)(n.join(`
|
|
16
16
|
`)):(0,Se.default)(n.join(`
|
|
17
17
|
`))}displayParallelResults(e,t,r){let n=!0,s=!1;console.log("");for(let a of e){if(!a)continue;s=!0;let{index:l,result:c,error:f,context:g}=a;if(f){n=!1;let h=`Branch ${l+1} failed: ${f instanceof Error?f.message:String(f)}`,d=ae(h);console.error(d)}else if(c&&typeof c=="object"&&"stdout"in c){let h=c;if(n=n&&h.success,h.stdout.length>0||h.stderr.length>0||!h.success){let d=t[l],w=this.getBranchDisplayName(d,l);this.taskRunner.displayBufferedOutput(h,w,!1,g.lineNumber,g.fileName)}}}s||console.log("\u26A0\uFE0F All parallel branches were skipped (conditions not met)");let i=ot(n);return console.log(i),n}mergeParallelResults(e){for(let t of e){let r=t.workspace.getAllFacts(),n=t.workspace.getAllVariables();for(let[s,i]of r)this.workspace.setFact(s,i);for(let[s,i]of n)this.workspace.setVariable(s,i)}}countExecutableBranches(e,t){let r=0;for(let n=0;n<e.length;n++){let s=e[n],i=t[n];s.when&&!new K(i.workspace).evaluate(s.when)||r++}return r}async executeParallelStep(e,t){let r=this.createParallelContexts(e,t),n=this.countExecutableBranches(e.parallel,r),s=rt(n);console.log(s);let i=await this.executeParallelBranches(e.parallel,r),a=this.displayParallelResults(i,e.parallel,t);if(this.workspace.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`)}this.mergeParallelResults(r)}async executeFailStep(e,t){let r=new Error(e.fail.message);throw r.stack=void 0,r}};var ft=require("yaml"),_e=require("zod");var u=require("zod"),rr=u.z.object({file:u.z.string()}),or=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()}),nr=u.z.object({status:u.z.object({fact:u.z.string(),is:u.z.enum(["ready","failed","pending"])})}),sr=u.z.object({step:u.z.object({success:u.z.boolean()}).optional(),last_step:u.z.enum(["success","failure"]).optional()}),ir=u.z.object({choice:u.z.string()}),ar=u.z.union([rr,ir,or,nr,sr]),M=u.z.lazy(()=>u.z.union([ar,u.z.object({all:u.z.array(M)}),u.z.object({any:u.z.array(M)}),u.z.object({not:M})])),ct=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:ct.optional()})),ut=u.z.object({run:u.z.string(),when:M.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:ct.optional()}),lr=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:M.optional()}),cr=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:M.optional()});function pt(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=pt(t);if(r.found)return r}return{found:!1}}var dt=u.z.lazy(()=>u.z.union([ut,u.z.object({parallel:u.z.array(u.z.lazy(()=>dt)),when:M.optional()}),u.z.object({fail:u.z.object({message:u.z.string()}),when:M.optional()})]).superRefine((o,e)=>{let t=pt(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)`})})),ur=u.z.lazy(()=>u.z.union([ut,lr,cr,u.z.object({parallel:u.z.array(dt),when:M.optional()}),u.z.object({fail:u.z.object({message:u.z.string()}),when:M.optional()})])),pr=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))}),dr=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(pr).optional(),steps:u.z.array(ur).min(1,"Workflow must have at least one step")});function Le(o){return dr.parse(o)}function mt(o,e){let t=o.path;if(o.code==="custom"){let n=Be(t);return` - ${o.message}${n}`}if(o.message==="Invalid input"){let n=Be(t),s=fr(t,e);return s?` - ${s}${n}`:` - Invalid step type${n}`}let r=Be(t);return` - ${o.message}${r}`}function Be(o){if(o.length===0)return"";let e=[];for(let t=0;t<o.length;t++){let r=o[t],n=o[t+1];r==="steps"&&typeof n=="number"?(e.push(`step ${n+1}`),t++):r==="parallel"&&typeof n=="number"?(e.push(`parallel branch ${n+1}`),t++):typeof r=="string"&&r!=="steps"&&r!=="parallel"&&e.push(r)}return e.length>0?` (${e.join(" \u2192 ")})`:""}function b(o,e,t){let r=t?`
|
|
@@ -37,7 +37,7 @@ ${n}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
|
|
|
37
37
|
`),n=0,s=!1;for(let i=0;i<r.length;i++){let a=r[i].trim();if(a==="steps:"||a.startsWith("steps:")){s=!0;continue}s&&a.startsWith("-")&&t.set(n++,i+1)}return t}},We=class{parse(e){let t;try{t=JSON.parse(e)}catch(r){throw new Error(`Invalid JSON format: ${r instanceof Error?r.message:String(r)}`)}if(t&&typeof t=="object"&&"steps"in t){let r=t;Array.isArray(r.steps)&&(r.steps=r.steps.map(n=>Ve(n)))}gt(t);try{return Le(t)}catch(r){if(r instanceof _e.ZodError){let n=r.issues.map(s=>mt(s,t)).filter(s=>s!==null).join(`
|
|
38
38
|
`);throw new Error(`Invalid workflow structure:
|
|
39
39
|
${n}`)}throw r}}extractStepLineNumbers(e){let t=new Map,r=e.split(`
|
|
40
|
-
`),n=0,s=!1,i=!1;for(let a=0;a<r.length;a++){let c=r[a].trim();if(c.startsWith('"steps"')||c.startsWith("'steps'")){s=!0,c.includes("[")&&(i=!0);continue}if(s&&c==="["){i=!0;continue}if(i&&c==="]"){i=!1,s=!1;continue}i&&c.startsWith("{")&&t.set(n++,a+1)}return t}};function le(o){switch(o.toLowerCase().split(".").pop()){case"yaml":case"yml":return new ve;case"json":return new We;default:return new ve}}var St=require("fs/promises"),vt=require("path"),xe=y(require("boxen"),1),j=y(require("chalk"),1),ze=y(require("node-cron"),1);ie();var re=require("fs/promises"),yt=require("os"),He=require("path"),bt=(0,He.join)((0,yt.homedir)(),".pipeliner","schedules"),wt=(0,He.join)(bt,"schedules.json"),I=class{async loadSchedules(){try{let e=await(0,re.readFile)(wt,"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,re.mkdir)(bt,{recursive:!0}),await(0,re.writeFile)(wt,JSON.stringify({schedules:e},null,2),"utf-8")}async addSchedule(e){let t=await this.loadSchedules(),r=Math.random().toString(36).slice(2,10),n=new Date().toISOString(),s={id:r,createdAt:n,...e};return t.push(s),await this.saveSchedules(t),s}async removeSchedule(e){let t=await this.loadSchedules(),r=t.length,n=t.filter(s=>s.id!==e);return n.length===r?!1:(await this.saveSchedules(n),!0)}async updateLastRun(e){let t=await this.loadSchedules(),r=t.find(n=>n.id===e);r&&(r.lastRun=new Date().toISOString(),await this.saveSchedules(t))}async toggleSchedule(e,t){let r=await this.loadSchedules(),n=r.find(s=>s.id===e);return n?(n.enabled=t,await this.saveSchedules(r),!0):!1}async getSchedule(e){return(await this.loadSchedules()).find(r=>r.id===e)}};var mr=/^([+-])?(\d{1,2})(?::(\d{2}))?$/;function hr(o){let e=o.trim();if(e===""||e==="0"||e==="+0"||e==="-0")return 0;let t=e.match(mr);if(!t)return null;let r=t[1],n=parseInt(t[2],10);if(n>14)return null;let i=r==="-"?-n:n;return i<-12||i>14?null:i}function gr(o){if(o===0)return"UTC";let e=o>0?"-":"+",t=Math.abs(o);return`Etc/GMT${e}${t}`}function ke(o){if(!o?.trim())return;let e=hr(o);if(e!==null)return gr(e)}var
|
|
40
|
+
`),n=0,s=!1,i=!1;for(let a=0;a<r.length;a++){let c=r[a].trim();if(c.startsWith('"steps"')||c.startsWith("'steps'")){s=!0,c.includes("[")&&(i=!0);continue}if(s&&c==="["){i=!0;continue}if(i&&c==="]"){i=!1,s=!1;continue}i&&c.startsWith("{")&&t.set(n++,a+1)}return t}};function le(o){switch(o.toLowerCase().split(".").pop()){case"yaml":case"yml":return new ve;case"json":return new We;default:return new ve}}var St=require("fs/promises"),vt=require("path"),xe=y(require("boxen"),1),j=y(require("chalk"),1),ze=y(require("node-cron"),1);ie();var re=require("fs/promises"),yt=require("os"),He=require("path"),bt=(0,He.join)((0,yt.homedir)(),".pipeliner","schedules"),wt=(0,He.join)(bt,"schedules.json"),I=class{async loadSchedules(){try{let e=await(0,re.readFile)(wt,"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,re.mkdir)(bt,{recursive:!0}),await(0,re.writeFile)(wt,JSON.stringify({schedules:e},null,2),"utf-8")}async addSchedule(e){let t=await this.loadSchedules(),r=Math.random().toString(36).slice(2,10),n=new Date().toISOString(),s={id:r,createdAt:n,...e};return t.push(s),await this.saveSchedules(t),s}async removeSchedule(e){let t=await this.loadSchedules(),r=t.length,n=t.filter(s=>s.id!==e);return n.length===r?!1:(await this.saveSchedules(n),!0)}async updateLastRun(e){let t=await this.loadSchedules(),r=t.find(n=>n.id===e);r&&(r.lastRun=new Date().toISOString(),await this.saveSchedules(t))}async toggleSchedule(e,t){let r=await this.loadSchedules(),n=r.find(s=>s.id===e);return n?(n.enabled=t,await this.saveSchedules(r),!0):!1}async getSchedule(e){return(await this.loadSchedules()).find(r=>r.id===e)}};var mr=/^([+-])?(\d{1,2})(?::(\d{2}))?$/;function hr(o){let e=o.trim();if(e===""||e==="0"||e==="+0"||e==="-0")return 0;let t=e.match(mr);if(!t)return null;let r=t[1],n=parseInt(t[2],10);if(n>14)return null;let i=r==="-"?-n:n;return i<-12||i>14?null:i}function gr(o){if(o===0)return"UTC";let e=o>0?"-":"+",t=Math.abs(o);return`Etc/GMT${e}${t}`}function ke(o){if(!o?.trim())return;let e=hr(o);if(e!==null)return gr(e)}var W=class{scheduleManager;tasks=new Map;startOptions;constructor(){this.scheduleManager=new I}async start(e=!1,t){if(this.startOptions=t,!e&&await A()){let n=await R();throw new Error(`Scheduler daemon is already running (PID: ${n.pid}). Use "tp schedule stop" to stop it first.`)}if(e)console.log("\u{1F680} Starting scheduler daemon in background...");else{let n=j.default.bold("\u{1F680} Starting workflow scheduler...");console.log((0,xe.default)(n,{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 n=[j.default.green("\u2713 Scheduler daemon started"),"",j.default.gray(`PID: ${process.pid}`),j.default.dim(" tp schedule stop stop daemon"),j.default.dim(" tp schedule status check status")].join(`
|
|
41
41
|
`);console.log(`${(0,xe.default)(n,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},borderColor:"green"})}
|
|
42
42
|
`)}}else{let n=[j.default.green("\u2713 Scheduler is running"),j.default.dim(" Press Ctrl+C to stop")].join(`
|
|
43
43
|
`);console.log((0,xe.default)(n,{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(`
|
|
@@ -55,9 +55,9 @@ Found ${r.schedules.length} schedule(s) in file.
|
|
|
55
55
|
`);for(let l of i)console.log(ce(l,{daemonRunning:a.running}));console.log(m.default.dim(' Tip: Run "tp schedule start" to start the scheduler daemon'))}async function kr(){let o=new I,e=await o.loadSchedules();if(e.length===0){console.log("No schedules found");return}let{scheduleId:t}=await Y.default.prompt([{type:"list",name:"scheduleId",message:"Select schedule to remove:",choices:e.map(s=>({name:`${s.name??s.workflowPath} (${s.cron}) ${s.enabled?"\u2713":"\u2717"}`,value:s.id}))}]),{confirm:r}=await Y.default.prompt([{type:"confirm",name:"confirm",message:"Are you sure you want to remove this schedule?",default:!1}]);if(!r){console.log("Cancelled");return}let n=await o.removeSchedule(t);console.log(n?"\u2713 Schedule removed successfully":"\u2717 Schedule not found")}async function Tt(){let e=await new I().loadSchedules();if(e.length===0){let i=[m.default.gray("No schedules registered."),"",m.default.dim(" tp schedule add <schedule.yaml> add from a schedule file")].join(`
|
|
56
56
|
`);console.log(`
|
|
57
57
|
${(0,Re.default)(i,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:0,left:0,right:0},borderColor:"gray"})}
|
|
58
|
-
`);return}let t=await R(),r=t.running?m.default.green("\u25CF running"):m.default.gray("\u25CB stopped"),n=e.filter(i=>i.enabled).length,s=m.default.bold("\u{1F4C5} Workflow Schedules");console.log(s),console.log([m.default.gray(" Daemon: "),r,m.default.gray(` \xB7 Schedules: ${n}/${e.length} enabled`)].join(""));for(let i of e)console.log(ce(i,{daemonRunning:t.running}));console.log(m.default.dim(" Tip: tp schedule start \u2014 run scheduler daemon; tp schedule status \u2014 view live status"))}async function xr(o){if(await A()){let e=await R();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(()=>(ie(),Qe));await e(),await new
|
|
58
|
+
`);return}let t=await R(),r=t.running?m.default.green("\u25CF running"):m.default.gray("\u25CB stopped"),n=e.filter(i=>i.enabled).length,s=m.default.bold("\u{1F4C5} Workflow Schedules");console.log(s),console.log([m.default.gray(" Daemon: "),r,m.default.gray(` \xB7 Schedules: ${n}/${e.length} enabled`)].join(""));for(let i of e)console.log(ce(i,{daemonRunning:t.running}));console.log(m.default.dim(" Tip: tp schedule start \u2014 run scheduler daemon; tp schedule status \u2014 view live status"))}async function xr(o){if(await A()){let e=await R();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(()=>(ie(),Qe));await e(),await new W().start(!0),await new Promise(()=>{})}catch(e){await Ie(e instanceof Error?e:new Error(String(e))),process.exit(1)}else{let e=process.argv.slice(1);(0,Mt.spawn)(process.argv[0],e,{detached:!0,stdio:"ignore",env:{...process.env,TP_DAEMON_MODE:"true"}}).unref();let r=3,n=800,s=!1;for(let i=0;i<r;i++)if(await new Promise(a=>setTimeout(a,n)),await A()){s=!0;break}if(s){let i=await R();console.log(`\u2713 Scheduler daemon started in background (PID: ${i.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 i=await je();i?(console.error(m.default.dim(" Last error from daemon:")),console.error(m.default.red(i.split(`
|
|
59
59
|
`).map(a=>` ${a}`).join(`
|
|
60
|
-
`)))):console.error(m.default.dim(` Check ${Me()} for details`)),process.exit(1)}process.exit(0)}else await new
|
|
60
|
+
`)))):console.error(m.default.dim(` Check ${Me()} for details`)),process.exit(1)}process.exit(0)}else await new W().start(!1,{onScheduleStarted:t=>console.log(ce(t,{daemonRunning:!0}))}),await new Promise(()=>{})}async function $r(){let o=await R();if(!o.running){console.log("Scheduler daemon is not running");return}console.log(`Stopping scheduler daemon (PID: ${o.pid})...`);let t=await new W().stopDaemon();console.log(t?"\u2713 Scheduler daemon stopped":"\u2717 Failed to stop scheduler daemon (process may have already exited)")}function Rr(o){if(!o)return"Unknown";let e=(0,Ee.default)(o),r=(0,Ee.default)().diff(e,"second"),n=Math.floor(r/86400),s=Math.floor(r%86400/3600),i=Math.floor(r%3600/60),a=r%60,l=[];return n>0&&l.push(`${n}d`),s>0&&l.push(`${s}h`),i>0&&l.push(`${i}m`),(a>0||l.length===0)&&l.push(`${a}s`),l.join(" ")}function Er(o,e){return ce(o,{daemonRunning:e})}async function qe(){let o=await R(),t=await new I().loadSchedules(),r=[],n;if(o.running&&o.pid){let i=Rr(o.startTime),a=o.startTime?(0,Ee.default)(o.startTime).format("YYYY-MM-DD HH:mm:ss"):"Unknown";n=[`${m.default.green("\u25CF")} ${m.default.green("active")} ${m.default.gray("(running)")}`,"",`${m.default.gray("Loaded:")} ${m.default.white(a)}`,`${m.default.gray("Active:")} ${m.default.green("active (running)")} since ${m.default.white(a)}`,`${m.default.gray("PID:")} ${m.default.white(o.pid.toString())}`,`${m.default.gray("Uptime:")} ${m.default.white(i)}`].join(`
|
|
61
61
|
`)}else n=[`${m.default.red("\u25CF")} ${m.default.red("inactive")} ${m.default.gray("(dead)")}`,"",`${m.default.gray("Loaded:")} ${m.default.gray("not found")}`,`${m.default.gray("Active:")} ${m.default.red("inactive (dead)")}`].join(`
|
|
62
62
|
`);let s=(0,Re.default)(n,{title:m.default.bold("task-pipeliner-scheduler.service"),titleAlignment:"left",borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:0,left:0,right:0},borderColor:o.running?"green":"red"});if(r.push(s),t.length>0){let i=t.filter(l=>l.enabled).length,a=m.default.bold(`Schedules: ${i}/${t.length} enabled`);r.push(a);for(let l of t)r.push(Er(l,o.running))}else{let i=(0,Re.default)(m.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(i)}return r.join(`
|
|
63
63
|
`)}function It(){process.stdout.write("\x1B[2J\x1B[H")}async function Pr(o){if(o){let e=!0,t=()=>{e=!1,ue.default.done(),process.exit(0)};process.on("SIGINT",t),process.on("SIGTERM",t);let r=setInterval(async()=>{if(!e){clearInterval(r);return}try{let a=await qe(),c=(await R()).running?m.default.gray(`
|
|
@@ -66,7 +66,7 @@ Tip: To start the daemon, run: tp schedule start -d. Press Ctrl+C to exit this v
|
|
|
66
66
|
Press Ctrl+C to exit this view (daemon keeps running in background)`):m.default.gray(`
|
|
67
67
|
Tip: To start the daemon, run: tp schedule start -d. Press Ctrl+C to exit this view.`);(0,ue.default)(`${n}${i}`),await new Promise(()=>{})}else{It();let e=await qe(),r=(await R()).running?"":m.default.gray(`
|
|
68
68
|
Tip: To start the daemon, run: tp schedule start -d`);console.log(`${e}${r}
|
|
69
|
-
`)}}async function Cr(){let o=new I,e=await o.loadSchedules();if(e.length===0){console.log("No schedules found");return}let{scheduleId:t}=await Y.default.prompt([{type:"list",name:"scheduleId",message:"Select schedule to toggle:",choices:e.map(s=>({name:`${s.name??s.workflowPath} (${s.cron}) ${s.enabled?"\u2713":"\u2717"}`,value:s.id}))}]),r=e.find(s=>s.id===t);if(!r){console.log("\u2717 Schedule not found");return}let n=!r.enabled;await o.toggleSchedule(t,n),console.log(`\u2713 Schedule ${n?"enabled":"disabled"}: ${r.name??r.workflowPath}`)}async function Dr(){let o=new I,e=await o.loadSchedules();if(e.length===0){console.log("No schedules found");return}let{confirm:t}=await Y.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 F=require("fs"),E=require("path"),Ge=require("url"),Ot={};function Ft(){console.log=()=>{},console.error=()=>{},console.warn=()=>{},console.info=()=>{},process.stdout.write=()=>!0,process.stderr.write=()=>!0}function Lt(){return"0.3.
|
|
69
|
+
`)}}async function Cr(){let o=new I,e=await o.loadSchedules();if(e.length===0){console.log("No schedules found");return}let{scheduleId:t}=await Y.default.prompt([{type:"list",name:"scheduleId",message:"Select schedule to toggle:",choices:e.map(s=>({name:`${s.name??s.workflowPath} (${s.cron}) ${s.enabled?"\u2713":"\u2717"}`,value:s.id}))}]),r=e.find(s=>s.id===t);if(!r){console.log("\u2717 Schedule not found");return}let n=!r.enabled;await o.toggleSchedule(t,n),console.log(`\u2713 Schedule ${n?"enabled":"disabled"}: ${r.name??r.workflowPath}`)}async function Dr(){let o=new I,e=await o.loadSchedules();if(e.length===0){console.log("No schedules found");return}let{confirm:t}=await Y.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 F=require("fs"),E=require("path"),Ge=require("url"),Ot={};function Ft(){console.log=()=>{},console.error=()=>{},console.warn=()=>{},console.info=()=>{},process.stdout.write=()=>!0,process.stderr.write=()=>!0}function Lt(){return"0.3.3"}function Bt(o){let e=o?(0,E.resolve)(o):process.cwd(),t=50,r=0;for(;r<t;){let n=(0,E.resolve)(e,"tp");try{if((0,F.existsSync)(n)&&(0,F.statSync)(n).isDirectory())return n}catch{}let s=(0,E.dirname)(e);if(s===e)break;e=s,r++}return null}var pe=(0,U.join)((0,_t.homedir)(),".pipeliner"),Tr=(0,Vt.promisify)(Wt.exec),J=new Ht.Command;J.name("task-pipeliner").description(`A powerful task pipeline runner with condition-based workflow execution.
|
|
70
70
|
|
|
71
71
|
Define workflows in YAML or JSON files with conditional execution, parallel tasks,
|
|
72
72
|
interactive prompts, variable substitution, and cron-based scheduling.
|
|
@@ -201,7 +201,7 @@ Please visit manually: ${t}`)),process.exit(1)}});J.addCommand(At());var Ir=J.co
|
|
|
201
201
|
`);console.log((0,Ze.default)(l,{borderStyle:"round",padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1,left:0,right:0},borderColor:o.status==="success"?"green":"red"})),Lr(o.output)&&Br(o.output)}function Or(o){return"run"in o?"Run":"choose"in o?"Choose":"prompt"in o?"Prompt":"parallel"in o?"Parallel":"fail"in o?"Fail":"Unknown"}function Fr(o){return"run"in o?`Command: ${p.default.yellow(o.run)}`:"choose"in o?`Message: ${p.default.yellow(o.choose.message)}`:"prompt"in o?`Message: ${p.default.yellow(o.prompt.message)} | Variable: ${p.default.cyan(o.prompt.as)}`:"parallel"in o?`Parallel execution with ${o.parallel.length} branches`:"fail"in o?`Error: ${p.default.red(o.fail.message)}`:"Unknown step type"}function Lr(o){return typeof o=="object"&&o!==null&&"success"in o&&"stdout"in o&&"stderr"in o}function Br(o){if(o.stdout.length>0){let e=o.stdout.map(t=>p.default.gray(` ${t}`)).join(`
|
|
202
202
|
`);console.log(p.default.green(" Output:")),console.log(e)}if(o.stderr.length>0){let e=o.stderr.map(t=>p.default.gray(` ${t}`)).join(`
|
|
203
203
|
`);console.log(p.default.red(" Errors:")),console.log(e)}}J.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 L().prompt(`This will remove all data in ${p.default.yellow(pe)} (schedules, daemon PID, workflow history). Continue?`,[{id:"yes",label:"Yes, remove all"},{id:"no",label:"No, cancel"}]))?.id!=="yes"){console.log(p.default.yellow(`
|
|
204
|
-
\u2717 Cancelled`));return}try{if(await A()){let t=await R();console.log(p.default.gray(`Stopping scheduler daemon (PID: ${t.pid})...`)),await new
|
|
204
|
+
\u2717 Cancelled`));return}try{if(await A()){let t=await R();console.log(p.default.gray(`Stopping scheduler daemon (PID: ${t.pid})...`)),await new W().stopDaemon(),console.log(p.default.gray(" Daemon stopped"))}(0,de.existsSync)(pe)?(await(0,Pe.rm)(pe,{recursive:!0}),console.log(p.default.green(`
|
|
205
205
|
\u2713 Removed ${pe}`))):console.log(p.default.gray(`
|
|
206
206
|
${pe} does not exist (already clean)`))}catch(t){let r=t instanceof Error?t.message:String(t);console.error(p.default.red(`
|
|
207
207
|
\u2717 Clean failed: ${r}`)),process.exit(1)}});J.parse();
|