@zibby/cli 0.1.75 → 0.1.77

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.
@@ -1,45 +1,46 @@
1
- import e from"chalk";import{readFileSync as v,existsSync as N}from"fs";import{homedir as R}from"os";import{join as C}from"path";var E="https://logs.workflows.zibby.app",_="https://logs-stream.zibby.app/",x=null;async function j(s){return x||(process.env.ZIBBY_SSE_ENDPOINT?(x=process.env.ZIBBY_SSE_ENDPOINT,x):(x=_,x))}function A(s){let n=C(R(),".zibby","config.json");N(n)||(console.log(e.red(`
1
+ import e from"chalk";import{readFileSync as R,existsSync as C}from"fs";import{homedir as _}from"os";import{join as j}from"path";var I="https://logs.workflows.zibby.app",A="https://logs-stream.zibby.app/",S=null;async function O(s){return S||(process.env.ZIBBY_SSE_ENDPOINT?(S=process.env.ZIBBY_SSE_ENDPOINT,S):(S=A,S))}function J(s){let n=j(_(),".zibby","config.json");C(n)||(console.log(e.red(`
2
2
  Not authenticated`)),console.log(e.gray(` Run: zibby login
3
- `)),process.exit(1));let t;try{t=JSON.parse(v(n,"utf-8"))}catch{console.log(e.red(`
3
+ `)),process.exit(1));let t;try{t=JSON.parse(R(n,"utf-8"))}catch{console.log(e.red(`
4
4
  Config file corrupt`)),console.log(e.gray(` Run: zibby login
5
- `)),process.exit(1)}let a=t.sessionToken;a||(console.log(e.red(`
5
+ `)),process.exit(1)}let c=t.sessionToken;c||(console.log(e.red(`
6
6
  Not authenticated`)),console.log(e.gray(` Run: zibby login
7
- `)),process.exit(1));let f=s.project;return{token:a,projectId:f}}function k(s){return new Date(s).toISOString().replace("T"," ").replace("Z","")}async function P(s,n){let t=await fetch(s,{headers:{Authorization:`Bearer ${n}`}});if(!t.ok){let a=await t.text();throw new Error(`API ${t.status}: ${a}`)}return t.json()}async function O(s,n,t,a){return s||(console.log(e.red(`
7
+ `)),process.exit(1));let f=s.project;return{token:c,projectId:f}}function k(s){return new Date(s).toISOString().replace("T"," ").replace("Z","")}async function P(s,n){let t=await fetch(s,{headers:{Authorization:`Bearer ${n}`}});if(!t.ok){let c=await t.text();throw new Error(`API ${t.status}: ${c}`)}return t.json()}async function z(s,n,t,c){return s||(console.log(e.red(`
8
8
  Workflow UUID is required`)),console.log(e.gray(" Usage: zibby logs <workflow-uuid>")),console.log(e.gray(` zibby logs <workflow-uuid> -t
9
- `)),process.exit(1)),s}async function T({token:s,executionId:n,sseEndpoint:t,stopped:a}){let f=null;try{let c=new URL(t);c.searchParams.set("jobId",n),f&&c.searchParams.set("lastEventId",f);let g=await fetch(c.toString(),{headers:{Authorization:`Bearer ${s}`,Accept:"text/event-stream"}});if(!g.ok)throw new Error(`SSE connection failed: ${g.status} ${g.statusText}`);let r=g.body.getReader(),p=new TextDecoder,y="",w=!1;for(;!a.value;){let{done:h,value:$}=await r.read();if(h)break;y+=p.decode($,{stream:!0});let d=y.split(`
10
- `);y=d.pop()||"";for(let o of d)if(o.trim()){if(o.startsWith("id:"))f=o.slice(3).trim();else if(o.startsWith("event:")){let i=o.slice(6).trim();if(i==="log")continue;if(i==="status"){let u=d[d.indexOf(o)+1];if(u&&u.startsWith("data:"))try{let m=JSON.parse(u.slice(5).trim());if(m.status==="new_execution"){let l=m.executionId,b=`${l.slice(0,8)}...${l.slice(-4)}`,S=m.taskId?m.taskId.slice(-8):"pending";console.log(e.cyan(`
11
- \u250C\u2500 Execution: ${b} (task: ${S})`)),console.log(e.cyan(` \u2514\u2500 Streaming logs...
9
+ `)),process.exit(1)),s}async function T({token:s,executionId:n,sseEndpoint:t,stopped:c}){let f=null;try{let a=new URL(t);a.searchParams.set("jobId",n),f&&a.searchParams.set("lastEventId",f);let g=await fetch(a.toString(),{headers:{Authorization:`Bearer ${s}`,Accept:"text/event-stream"}});if(!g.ok)throw new Error(`SSE connection failed: ${g.status} ${g.statusText}`);let r=g.body.getReader(),p=new TextDecoder,y="",w=!1;for(;!c.value;){let{done:$,value:h}=await r.read();if($)break;y+=p.decode(h,{stream:!0});let d=y.split(`
10
+ `);y=d.pop()||"";for(let o of d)if(o.trim()){if(o.startsWith("id:"))f=o.slice(3).trim();else if(o.startsWith("event:")){let l=o.slice(6).trim();if(l==="log")continue;if(l==="status"){let u=d[d.indexOf(o)+1];if(u&&u.startsWith("data:"))try{let m=JSON.parse(u.slice(5).trim());if(m.status==="new_execution"){let i=m.executionId,b=`${i.slice(0,8)}...${i.slice(-4)}`,x=m.taskId?m.taskId.slice(-8):"pending";console.log(e.cyan(`
11
+ \u250C\u2500 Execution: ${b} (task: ${x})`)),console.log(e.cyan(` \u2514\u2500 Streaming logs...
12
12
  `))}else m.status==="waiting"&&console.log(e.gray(`
13
- Waiting for next execution...`))}catch{}continue}if(i==="complete"){console.log(e.green(`
14
- Execution completed.`)),w=!0;continue}if(i==="error"){let u=d[d.indexOf(o)+1];if(u&&u.startsWith("data:"))try{if(JSON.parse(u.slice(5).trim()).error==="No executions found for workflow")return{notFound:!0}}catch{}return{failed:!0}}}else if(o.startsWith("data:")){let i=o.slice(5).trim();if(!i)continue;try{let u=JSON.parse(i);if(u.timestamp&&u.message){let m=e.gray(k(u.timestamp)),l=u.taskId?e.gray(`(${u.taskId.slice(-8)}) `):"";console.log(`${m} ${l}${u.message.replace(/\n$/,"")}`)}}catch{}}}}return{completed:w}}catch(c){if(c.name==="AbortError")return{aborted:!0};throw c}}async function J({token:s,jobId:n,follow:t,projectId:a}){console.log(e.gray(` Streaming logs for workflow ${e.cyan(n)}...`)),console.log(t?e.gray(` Press Ctrl+C to stop.
15
- `):"");let f=await j(s);if(!f)return console.log(e.yellow(` SSE endpoint not configured, using CloudWatch polling...
16
- `)),I({token:s,projectId:null,jobId:n,follow:t,limit:1e5});let c={value:!1},g=()=>{c.value=!0,console.log(e.gray(`
13
+ Waiting for next execution...`))}catch{}continue}if(l==="complete"){w=!0;continue}if(l==="error"){let u=d[d.indexOf(o)+1];if(u&&u.startsWith("data:"))try{if(JSON.parse(u.slice(5).trim()).error==="No executions found for workflow")return{notFound:!0}}catch{}return{failed:!0}}}else if(o.startsWith("data:")){let l=o.slice(5).trim();if(!l)continue;try{let u=JSON.parse(l);if(u.timestamp&&u.message){let m=e.gray(k(u.timestamp)),i=u.taskId?e.gray(`(${u.taskId.slice(-8)}) `):"";console.log(`${m} ${i}${u.message.replace(/\n$/,"")}`)}}catch{}}}}return{completed:w}}catch(a){if(a.name==="AbortError")return{aborted:!0};throw a}}async function E({token:s,jobId:n,follow:t,projectId:c}){console.log(e.gray(` Streaming logs for workflow ${e.cyan(n)}...`)),console.log(t?e.gray(` Press Ctrl+C to stop.
14
+ `):"");let f=await O(s);if(!f)return console.log(e.yellow(` SSE endpoint not configured, using CloudWatch polling...
15
+ `)),v({token:s,projectId:null,jobId:n,follow:t,limit:1e5});let a={value:!1},g=()=>{a.value=!0,console.log(e.gray(`
17
16
  Stopped streaming.
18
- `)),process.exit(0)};process.on("SIGINT",g),process.on("SIGTERM",g);try{let r=await T({token:s,executionId:n,sseEndpoint:f,stopped:c});if(r.aborted||c.value)return;if(r.notFound)if(t)for(console.log(e.yellow(" No executions found yet. Waiting for workflow to be triggered...")),console.log(e.gray(` Press Ctrl+C to stop.
19
- `));!c.value;){if(await new Promise(p=>setTimeout(p,5e3)),c.value)return;try{if(!(await T({token:s,executionId:n,sseEndpoint:f,stopped:c})).notFound)return}catch{}}else console.log(e.yellow(`
17
+ `)),process.exit(0)};process.on("SIGINT",g),process.on("SIGTERM",g);try{let r=await T({token:s,executionId:n,sseEndpoint:f,stopped:a});if(r.aborted||a.value)return;if(r.notFound)if(t)for(console.log(e.yellow(" No executions found yet. Waiting for workflow to be triggered...")),console.log(e.gray(` Press Ctrl+C to stop.
18
+ `));!a.value;){if(await new Promise(p=>setTimeout(p,5e3)),a.value)return;try{if(!(await T({token:s,executionId:n,sseEndpoint:f,stopped:a})).notFound)return}catch{}}else console.log(e.yellow(`
20
19
  No executions found for this workflow. Trigger the workflow first.
21
20
  `)),process.exit(1);if(r.failed){console.log(e.red(`
22
- Execution failed.`)),t||process.exit(1);return}return r.completed&&process.exit(0),console.log(e.yellow(` Connection ended unexpectedly, falling back to polling...
23
- `)),I({token:s,projectId:null,jobId:n,follow:t,limit:1e3})}catch(r){return r.name==="AbortError"||c.value?void 0:(console.error(e.red(` SSE Error: ${r.message}`)),console.log(e.yellow(` Falling back to polling mode...
24
- `)),I({token:s,projectId:null,jobId:n,follow:t,limit:1e3}))}}async function I({token:s,projectId:n,jobId:t,follow:a,limit:f}){let c=n?`${E}/logs/${n}/${t}`:`${E}/job/${t}`,g=null,r=0,p=new Set,y=!1,w=0,h=5,$=()=>{y=!0,console.log(e.gray(`
21
+ Execution failed.`)),t||process.exit(1);return}return r.completed&&process.exit(0),t&&!a.value?(console.log(e.gray(`
22
+ Connection ended, reconnecting...
23
+ `)),E({token:s,jobId:n,follow:t,projectId:null})):void 0}catch(r){if(r.name==="AbortError"||a.value)return;if(console.error(e.red(` SSE Error: ${r.message}`)),t&&!a.value)return console.log(e.gray(`
24
+ Reconnecting...
25
+ `)),E({token:s,jobId:n,follow:t,projectId:null})}}async function v({token:s,projectId:n,jobId:t,follow:c,limit:f}){let a=n?`${I}/logs/${n}/${t}`:`${I}/job/${t}`,g=null,r=0,p=new Set,y=!1,w=0,$=5,h=()=>{y=!0,console.log(e.gray(`
25
26
  Stopped tailing.
26
- `)),process.exit(0)};for(process.on("SIGINT",$),process.on("SIGTERM",$),console.log(e.gray(` Fetching logs for workflow ${e.cyan(t)}...`)),console.log(a?e.gray(` Press Ctrl+C to stop.
27
- `):"");!y;)try{let d=new URLSearchParams({limit:String(f)});g&&d.set("nextToken",g);let o=await P(`${c}?${d}`,s);w=0,o.message&&o.lines?.length===0&&r===0&&console.log(e.gray(` ${o.message}`)),o.status==="starting"&&o.lines?.length===0&&r===0&&console.log(e.gray(" Container starting..."));for(let l of o.lines||[]){let b=`${l.timestamp}:${l.message}`;if(p.has(b))continue;p.add(b);let S=e.gray(k(l.timestamp));console.log(`${S} ${l.message.replace(/\n$/,"")}`)}if(r=o.lines?.length>0?0:r+1,g=o.nextForwardToken||null,o.status==="completed"||o.status==="failed"){let l=o.status==="completed"?e.green:e.red;console.log(l(`
28
- Job ${o.status}.`)),process.exit(o.status==="completed"?0:1)}if(!a){o.status&&console.log(e.gray(`
29
- Status: ${o.status}`));break}let m=o.lines?.length>0?500:r>5?5e3:2e3;await new Promise(l=>setTimeout(l,m))}catch(d){if(d.name==="AbortError")break;d.message.match(/API (400|401|403|404):/)&&(console.error(e.red(`
27
+ `)),process.exit(0)};for(process.on("SIGINT",h),process.on("SIGTERM",h),console.log(e.gray(` Fetching logs for workflow ${e.cyan(t)}...`)),console.log(c?e.gray(` Press Ctrl+C to stop.
28
+ `):"");!y;)try{let d=new URLSearchParams({limit:String(f)});g&&d.set("nextToken",g);let o=await P(`${a}?${d}`,s);w=0,o.message&&o.lines?.length===0&&r===0&&console.log(e.gray(` ${o.message}`)),o.status==="starting"&&o.lines?.length===0&&r===0&&console.log(e.gray(" Container starting..."));for(let i of o.lines||[]){let b=`${i.timestamp}:${i.message}`;if(p.has(b))continue;p.add(b);let x=e.gray(k(i.timestamp)),N=o.taskId?e.gray(`(${o.taskId.slice(-8)}) `):"";console.log(`${x} ${N}${i.message.replace(/\n$/,"")}`)}if(r=o.lines?.length>0?0:r+1,g=o.nextForwardToken||null,o.status==="completed"||o.status==="failed"){let i=o.status==="completed"?e.green:e.red;console.log(i(`
29
+ Job ${o.status}.`)),process.exit(o.status==="completed"?0:1)}if(!c){o.status&&console.log(e.gray(`
30
+ Status: ${o.status}`));break}let m=o.lines?.length>0?500:r>5?5e3:2e3;await new Promise(i=>setTimeout(i,m))}catch(d){if(d.name==="AbortError")break;d.message.match(/API (400|401|403|404):/)&&(console.error(e.red(`
30
31
  ${d.message}
31
- `)),process.exit(1)),w++,console.error(e.red(` Error: ${d.message}`)),w>=h&&(console.error(e.red(`
32
- Too many consecutive errors (${h}). Stopping.
33
- `)),process.exit(1)),a||process.exit(1),await new Promise(i=>setTimeout(i,3e3))}}async function z({token:s,projectId:n,workflow:t,follow:a,limit:f}){let c=`${E}/all/${n}`,g=null,r=0,p=new Set,y=null,w=!1,h=0,$=5,d=()=>{w=!0,console.log(e.gray(`
32
+ `)),process.exit(1)),w++,console.error(e.red(` Error: ${d.message}`)),w>=$&&(console.error(e.red(`
33
+ Too many consecutive errors (${$}). Stopping.
34
+ `)),process.exit(1)),c||process.exit(1),await new Promise(l=>setTimeout(l,3e3))}}async function L({token:s,projectId:n,workflow:t,follow:c,limit:f}){let a=`${I}/all/${n}`,g=null,r=0,p=new Set,y=null,w=!1,$=0,h=5,d=()=>{w=!0,console.log(e.gray(`
34
35
  Stopped tailing.
35
36
  `)),process.exit(0)};for(process.on("SIGINT",d),process.on("SIGTERM",d),console.log(e.gray(`
36
- Tailing all runs for ${e.cyan(t)}...`)),console.log(a?e.gray(` Press Ctrl+C to stop.
37
- `):"");!w;)try{let o=new URLSearchParams({workflow:t,limit:String(f)});g&&o.set("nextToken",g);let i=await P(`${c}?${o}`,s);h=0,i.message&&i.lines?.length===0&&r===0&&console.log(e.gray(` ${i.message}`));for(let l of i.lines||[]){let b=`${l.timestamp}:${l.jobId}:${l.message}`;if(p.has(b))continue;p.add(b),l.jobId!==y&&(y!==null&&console.log(""),console.log(e.dim(` \u2500\u2500 ${l.jobId} \u2500\u2500`)),y=l.jobId);let S=e.gray(k(l.timestamp));console.log(`${S} ${l.message.replace(/\n$/,"")}`)}if(r=i.lines?.length>0?0:r+1,g=i.nextToken||null,!a){g&&console.log(e.gray(`
38
- ... more logs available. Run again or use --follow to stream.`)),i.jobCount&&console.log(e.gray(` ${i.jobCount} job(s) found.`));break}if(!i.hasRunning&&!g&&r>2){console.log(e.gray(`
39
- No running jobs. All caught up.`));break}let m=i.lines?.length>0?500:r>5?5e3:2e3;await new Promise(l=>setTimeout(l,m))}catch(o){if(o.name==="AbortError")break;o.message.match(/API (400|401|403|404):/)&&(console.error(e.red(`
37
+ Tailing all runs for ${e.cyan(t)}...`)),console.log(c?e.gray(` Press Ctrl+C to stop.
38
+ `):"");!w;)try{let o=new URLSearchParams({workflow:t,limit:String(f)});g&&o.set("nextToken",g);let l=await P(`${a}?${o}`,s);$=0,l.message&&l.lines?.length===0&&r===0&&console.log(e.gray(` ${l.message}`));for(let i of l.lines||[]){let b=`${i.timestamp}:${i.jobId}:${i.message}`;if(p.has(b))continue;p.add(b),i.jobId!==y&&(y!==null&&console.log(""),console.log(e.dim(` \u2500\u2500 ${i.jobId} \u2500\u2500`)),y=i.jobId);let x=e.gray(k(i.timestamp));console.log(`${x} ${i.message.replace(/\n$/,"")}`)}if(r=l.lines?.length>0?0:r+1,g=l.nextToken||null,!c){g&&console.log(e.gray(`
39
+ ... more logs available. Run again or use --follow to stream.`)),l.jobCount&&console.log(e.gray(` ${l.jobCount} job(s) found.`));break}if(!l.hasRunning&&!g&&r>2){console.log(e.gray(`
40
+ No running jobs. All caught up.`));break}let m=l.lines?.length>0?500:r>5?5e3:2e3;await new Promise(i=>setTimeout(i,m))}catch(o){if(o.name==="AbortError")break;o.message.match(/API (400|401|403|404):/)&&(console.error(e.red(`
40
41
  ${o.message}
41
- `)),process.exit(1)),h++,console.error(e.red(` Error: ${o.message}`)),h>=$&&(console.error(e.red(`
42
- Too many consecutive errors (${$}). Stopping.
43
- `)),process.exit(1)),a||process.exit(1),await new Promise(u=>setTimeout(u,3e3))}}async function F(s,n){let{token:t,projectId:a}=A(n),f=n.follow===!0,c=n.lines?parseInt(n.lines,10):1e5;if(n.all){let r=n.workflow;return r||(console.log(e.red(`
42
+ `)),process.exit(1)),$++,console.error(e.red(` Error: ${o.message}`)),$>=h&&(console.error(e.red(`
43
+ Too many consecutive errors (${h}). Stopping.
44
+ `)),process.exit(1)),c||process.exit(1),await new Promise(u=>setTimeout(u,3e3))}}async function F(s,n){let{token:t,projectId:c}=J(n),f=n.follow===!0,a=n.lines?parseInt(n.lines,10):1e5;if(n.all){let r=n.workflow;return r||(console.log(e.red(`
44
45
  --workflow is required with --all`)),console.log(e.gray(` Example: zibby logs --workflow ticket-triage --all --project <id>
45
- `)),process.exit(1)),z({token:t,projectId:a,workflow:r,follow:f,limit:c})}let g=await O(s,n,t,a);return f?J({token:t,jobId:g,follow:f,projectId:a}):I({token:t,projectId:a,jobId:g,follow:!1,limit:c})}export{F as logsCommand};
46
+ `)),process.exit(1)),L({token:t,projectId:c,workflow:r,follow:f,limit:a})}let g=await z(s,n,t,c);return f?E({token:t,jobId:g,follow:f,projectId:c}):v({token:t,projectId:c,jobId:g,follow:!1,limit:a})}export{F as logsCommand};
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zibby/cli",
3
- "version": "0.1.75",
3
+ "version": "0.1.77",
4
4
  "description": "Zibby CLI - Test automation generator and runner",
5
5
  "type": "module",
6
6
  "bin": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zibby/cli",
3
- "version": "0.1.75",
3
+ "version": "0.1.77",
4
4
  "description": "Zibby CLI - Test automation generator and runner",
5
5
  "type": "module",
6
6
  "bin": {