@zibby/cli 0.1.74 → 0.1.75

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,16 +1,16 @@
1
- import{existsSync as f,readFileSync as T}from"fs";import{join as i}from"path";import l from"chalk";import N from"ora";import H from"dotenv";import{select as O}from"@inquirer/prompts";import{existsSync as J}from"fs";import{join as K}from"path";import{pathToFileURL as M}from"url";async function D(t){let s=K(t,".zibby.config.mjs");if(!J(s))throw new Error(".zibby.config.mjs not found");try{let n=await import(M(s).href);return n.default||n}catch(n){throw new Error(`Failed to load .zibby.config.mjs: ${n.message}`,{cause:n})}}var U={local:{name:"Local Development",apiUrl:"http://localhost:3001",accountApiUrl:"http://localhost:3001",frontendUrl:"http://localhost:3000",description:"Local backend running on port 3001"},prod:{name:"Production",apiUrl:process.env.ZIBBY_PROD_API_URL||"https://api-prod.zibby.app",accountApiUrl:process.env.ZIBBY_PROD_ACCOUNT_API_URL||"https://account-api-prod.zibby.app",frontendUrl:process.env.ZIBBY_PROD_FRONTEND_URL||"https://studio.zibby.app",description:"Production environment"}};function x(){let t;if(process.env.ZIBBY_API_URL)t=process.env.ZIBBY_API_URL;else{let s=process.env.ZIBBY_ENV||"prod";U[s]?t=U[s].apiUrl:t=U.prod.apiUrl}try{let s=new URL(t);return s.protocol!=="http:"&&s.protocol!=="https:"?(console.error(`\u26A0\uFE0F Invalid API URL protocol: ${s.protocol} (only http/https allowed)`),U.prod.apiUrl):t}catch{return console.error(`\u26A0\uFE0F Invalid API URL: ${t}`),U.prod.apiUrl}}H.config();async function q(t){let s=x(),n=N("Fetching projects...").start();try{let d=await fetch(`${s}/projects`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`}});d.ok||(n.fail("Failed to fetch projects"),process.exit(1));let o=await d.json();Array.isArray(o)||(o.projects&&Array.isArray(o.projects)?o=o.projects:o.data&&Array.isArray(o.data)?o=o.data:(n.fail("Unexpected response format"),process.exit(1))),(!o||o.length===0)&&(n.fail("No projects found"),process.exit(1)),n.succeed(`Found ${o.length} project${o.length===1?"":"s"}`),console.log("");let y=o.map(p=>{let k=p.projectId||p.id||p._id||"unknown";return{name:`${p.name||p.projectName||"Unnamed"} (${k})`,value:k}});return await O({message:"Select a project to deploy to:",choices:y})}catch(d){n.fail(`Error: ${d.message}`),process.exit(1)}}async function go(t,s={}){let n=process.cwd(),d=s.apiKey||process.env.ZIBBY_API_KEY;d||(console.log(`
2
- Error: ZIBBY_API_KEY not set`),console.log(` Add to .env or use --api-key flag
3
- `),process.exit(1));let o=".zibby/workflows";try{o=(await D(n))?.paths?.workflows||".zibby/workflows"}catch{}if(!t){let c=i(n,o);f(c)||(console.log(`
4
- Error: No workflows found in ${o}/`),console.log(` Create one with: zibby g workflow <name>
5
- `),process.exit(1));let{readdir:a,stat:w}=await import("fs/promises"),A=await a(c),m=[];for(let b of A){let g=i(c,b);if(!(await w(g)).isDirectory())continue;(f(i(g,"graph.mjs"))||f(i(g,"graph.js")))&&m.push(b)}m.length===0&&(console.log(`
6
- Error: No workflows found in ${o}/`),console.log(` Create one with: zibby g workflow <name>
7
- `),process.exit(1)),console.log(""),t=await O({message:"Select a workflow to deploy:",choices:m.map(b=>({name:b,value:b}))})}let y=s.project||process.env.ZIBBY_PROJECT_ID;y||(console.log(""),y=await q(d));let u=i(n,o,t);f(u)||(console.log(`
8
- Error: Workflow not found: ${o}/${t}`),console.log(` Run: zibby workflow list
9
- `),process.exit(1));let p=i(u,"graph.mjs"),k=i(u,"workflow.json");f(p)||(console.log(`
10
- Error: graph.mjs not found in ${o}/${t}/`),process.exit(1)),console.log(`
1
+ import{existsSync as l,readFileSync as z}from"fs";import{join as c}from"path";import p from"chalk";import S from"ora";import Q from"dotenv";import{select as Y}from"@inquirer/prompts";import{existsSync as M}from"fs";import{join as H}from"path";import{pathToFileURL as q}from"url";async function N(e){let s=H(e,".zibby.config.mjs");if(!M(s))throw new Error(".zibby.config.mjs not found");try{let a=await import(q(s).href);return a.default||a}catch(a){throw new Error(`Failed to load .zibby.config.mjs: ${a.message}`,{cause:a})}}var _={local:{name:"Local Development",apiUrl:"http://localhost:3001",accountApiUrl:"http://localhost:3001",frontendUrl:"http://localhost:3000",description:"Local backend running on port 3001"},prod:{name:"Production",apiUrl:process.env.ZIBBY_PROD_API_URL||"https://api-prod.zibby.app",accountApiUrl:process.env.ZIBBY_PROD_ACCOUNT_API_URL||"https://account-api-prod.zibby.app",frontendUrl:process.env.ZIBBY_PROD_FRONTEND_URL||"https://studio.zibby.app",description:"Production environment"}};function E(){let e;if(process.env.ZIBBY_API_URL)e=process.env.ZIBBY_API_URL;else{let s=process.env.ZIBBY_ENV||"prod";_[s]?e=_[s].apiUrl:e=_.prod.apiUrl}try{let s=new URL(e);return s.protocol!=="http:"&&s.protocol!=="https:"?(console.error(`\u26A0\uFE0F Invalid API URL protocol: ${s.protocol} (only http/https allowed)`),_.prod.apiUrl):e}catch{return console.error(`\u26A0\uFE0F Invalid API URL: ${e}`),_.prod.apiUrl}}Q.config();async function X(e,s){let a=E(),f=S("Fetching projects...").start();try{let w=s||e,d=await fetch(`${a}/projects`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w}`}});d.ok||(f.fail("Failed to fetch projects"),process.exit(1));let t=await d.json();Array.isArray(t)||(t.projects&&Array.isArray(t.projects)?t=t.projects:t.data&&Array.isArray(t.data)?t=t.data:(f.fail("Unexpected response format"),process.exit(1))),(!t||t.length===0)&&(f.fail("No projects found"),process.exit(1)),f.succeed(`Found ${t.length} project${t.length===1?"":"s"}`),console.log("");let I=t.map(g=>{let U=g.projectId||g.id||g._id||"unknown";return{name:`${g.name||g.projectName||"Unnamed"} (${U})`,value:U}});return await Y({message:"Select a project to deploy to:",choices:I})}catch(w){f.fail(`Error: ${w.message}`),process.exit(1)}}async function ho(e,s={}){let a=process.cwd(),f=null,w=s.apiKey||process.env.ZIBBY_API_KEY;try{let n=c(process.env.HOME||process.env.USERPROFILE,".zibby","config.json");l(n)&&(f=JSON.parse(z(n,"utf-8")).sessionToken)}catch{}!f&&!w&&(console.log(`
2
+ Error: Not authenticated`),console.log(" Run: zibby login"),console.log(` Or set ZIBBY_API_KEY
3
+ `),process.exit(1));let d=".zibby/workflows";try{d=(await N(a))?.paths?.workflows||".zibby/workflows"}catch{}if(!e){let n=c(a,d);l(n)||(console.log(`
4
+ Error: No workflows found in ${d}/`),console.log(` Create one with: zibby g workflow <name>
5
+ `),process.exit(1));let{readdir:i,stat:m}=await import("fs/promises"),A=await i(n),b=[];for(let j of A){let u=c(n,j);if(!(await m(u)).isDirectory())continue;(l(c(u,"graph.mjs"))||l(c(u,"graph.js")))&&b.push(j)}b.length===0&&(console.log(`
6
+ Error: No workflows found in ${d}/`),console.log(` Create one with: zibby g workflow <name>
7
+ `),process.exit(1)),console.log(""),e=await Y({message:"Select a workflow to deploy:",choices:b.map(j=>({name:j,value:j}))})}let t=s.project||process.env.ZIBBY_PROJECT_ID;t||(console.log(""),t=await X(w,f));let I=f||w,h=c(a,d,e);l(h)||(console.log(`
8
+ Error: Workflow not found: ${d}/${e}`),console.log(` Run: zibby workflow list
9
+ `),process.exit(1));let g=c(h,"graph.mjs"),U=c(h,"workflow.json");l(g)||(console.log(`
10
+ Error: graph.mjs not found in ${d}/${e}/`),process.exit(1)),console.log(`
11
11
  Deploying Workflow
12
- `),console.log(" ".padEnd(60,"-")),console.log(` Workflow: ${t}`),console.log(` Project: ${y}`),console.log(" ".padEnd(60,"-")),console.log("");let r=N("Validating workflow...").start(),$=T(p,"utf-8");if($.includes("@zibby/core")||$.includes("@zibby/skills")){let c=i(u,"package.json");f(c)||(r.fail("Missing package.json"),console.log(""),console.log(l.red(" \u2717 graph.mjs imports @zibby packages but no package.json found")),console.log(""),console.log(l.yellow(" Create package.json with:")),console.log(""),console.log(l.gray(" {")),console.log(l.gray(' "type": "module",')),console.log(l.gray(' "dependencies": {')),console.log(l.gray(' "@zibby/core": "workspace:*"')),console.log(l.gray(" }")),console.log(l.gray(" }")),console.log(""),process.exit(1));let a=JSON.parse(T(c,"utf-8"));!{...a.dependencies,...a.devDependencies}["@zibby/core"]&&$.includes("@zibby/core")&&(r.fail("Missing @zibby/core dependency"),console.log(""),console.log(l.red(" \u2717 graph.mjs imports @zibby/core but it's not in package.json")),console.log(""),console.log(l.yellow(" Add to package.json dependencies:")),console.log(l.gray(' "@zibby/core": "workspace:*"')),console.log(""),process.exit(1))}r.text="Loading workflow graph...";try{let{pathToFileURL:c}=await import("url"),a=await import(c(p).href),w;if(a.default)if(typeof a.default=="function"){let e=a.default.prototype;e&&e.buildGraph?w=new a.default:w=a.default()}else r.fail("graph.mjs must export a class or factory function"),process.exit(1);else{let e=Object.values(a).find(j=>j.prototype&&j.prototype.buildGraph);e?w=new e:(r.fail("graph.mjs must export a WorkflowAgent class or factory function"),process.exit(1))}let m=w.buildGraph().serialize(),{readdir:b,readFile:g}=await import("fs/promises"),h={};r.text="Packaging workflow sources...";let P=await g(p,"utf-8");if(h["graph.mjs"]=P,f(k)){let e=await g(k,"utf-8");h["workflow.json"]=e}let v=i(u,"nodes");if(f(v)){let e=await b(v);for(let j of e)if(j.endsWith(".mjs")||j.endsWith(".js")){let W=i(v,j),G=await g(W,"utf-8");h[`nodes/${j}`]=G}}let z=i(u,"package.json");if(f(z)){let e=await g(z,"utf-8");h["package.json"]=e,r.text="Including package.json for dependencies..."}let E=i(u,"package-lock.json");if(f(E)){let e=await g(E,"utf-8");h["package-lock.json"]=e}r.text=`Uploading to cloud (${m.nodes.size||Object.keys(m.nodes||{}).length} nodes, ${Object.keys(h).length} files)...`;let R=x(),C=JSON.stringify({format:1,sources:h}),L=Buffer.byteLength(C,"utf8"),_=await fetch(`${R}/projects/${y}/workflows/${t}/sources/presign`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${d}`},body:JSON.stringify({contentLength:L})});if(!_.ok){let e=await _.json().catch(()=>({}));r.fail("Deploy failed (presign)"),console.log(` Error: ${e.error||e.message||_.statusText}
13
- `),process.exit(1)}let Y=await _.json(),{uploadUrl:Z,key:S,headers:F}=Y,B=await fetch(Z,{method:"PUT",headers:{...F||{},"Content-Length":String(L)},body:C});if(!B.ok){let e=await B.text().catch(()=>"");r.fail("Deploy failed (S3 upload)"),console.log(` S3 PUT failed: ${B.status} ${e.slice(0,200)}
14
- `),process.exit(1)}r.text="Saving workflow definition...";let I=await fetch(`${R}/projects/${y}/workflows/${t}`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${d}`},body:JSON.stringify({graph:m,sourcesStagingKey:S,isDefault:!1})});if(!I.ok){let e=await I.json().catch(()=>({}));r.fail("Deploy failed"),console.log(` Error: ${e.message||e.error||I.statusText}
15
- `),process.exit(1)}let V=await I.json();r.succeed(`Deployed successfully (v${V.version||1})`),console.log(""),console.log(" Next steps:"),console.log(` zibby start ${t} Run locally`),console.log(" zibby workflow list View all workflows"),console.log("")}catch(c){r.fail("Deploy failed"),console.log(` Error: ${c.message}
16
- `),process.exit(1)}}export{go as deployWorkflowCommand};
12
+ `),console.log(" ".padEnd(60,"-")),console.log(` Workflow: ${e}`),console.log(` Project: ${t}`),console.log(" ".padEnd(60,"-")),console.log("");let r=S("Validating workflow...").start(),B=z(g,"utf-8");if(B.includes("@zibby/core")||B.includes("@zibby/skills")){let n=c(h,"package.json");l(n)||(r.fail("Missing package.json"),console.log(""),console.log(p.red(" \u2717 graph.mjs imports @zibby packages but no package.json found")),console.log(""),console.log(p.yellow(" Create package.json with:")),console.log(""),console.log(p.gray(" {")),console.log(p.gray(' "type": "module",')),console.log(p.gray(' "dependencies": {')),console.log(p.gray(' "@zibby/core": "workspace:*"')),console.log(p.gray(" }")),console.log(p.gray(" }")),console.log(""),process.exit(1));let i=JSON.parse(z(n,"utf-8"));!{...i.dependencies,...i.devDependencies}["@zibby/core"]&&B.includes("@zibby/core")&&(r.fail("Missing @zibby/core dependency"),console.log(""),console.log(p.red(" \u2717 graph.mjs imports @zibby/core but it's not in package.json")),console.log(""),console.log(p.yellow(" Add to package.json dependencies:")),console.log(p.gray(' "@zibby/core": "workspace:*"')),console.log(""),process.exit(1))}r.text="Loading workflow graph...";try{let{pathToFileURL:n}=await import("url"),i=await import(n(g).href),m;if(i.default)if(typeof i.default=="function"){let o=i.default.prototype;o&&o.buildGraph?m=new i.default:m=i.default()}else r.fail("graph.mjs must export a class or factory function"),process.exit(1);else{let o=Object.values(i).find(k=>k.prototype&&k.prototype.buildGraph);o?m=new o:(r.fail("graph.mjs must export a WorkflowAgent class or factory function"),process.exit(1))}let b=m.buildGraph().serialize(),{readdir:j,readFile:u}=await import("fs/promises"),y={};r.text="Packaging workflow sources...";let R=await u(g,"utf-8");if(y["graph.mjs"]=R,l(U)){let o=await u(U,"utf-8");y["workflow.json"]=o}let P=c(h,"nodes");if(l(P)){let o=await j(P);for(let k of o)if(k.endsWith(".mjs")||k.endsWith(".js")){let G=c(P,k),K=await u(G,"utf-8");y[`nodes/${k}`]=K}}let C=c(h,"package.json");if(l(C)){let o=await u(C,"utf-8");y["package.json"]=o,r.text="Including package.json for dependencies..."}let L=c(h,"package-lock.json");if(l(L)){let o=await u(L,"utf-8");y["package-lock.json"]=o}r.text=`Uploading to cloud (${b.nodes.size||Object.keys(b.nodes||{}).length} nodes, ${Object.keys(y).length} files)...`;let T=E(),O=JSON.stringify({format:1,sources:y}),D=Buffer.byteLength(O,"utf8"),v=await fetch(`${T}/projects/${t}/workflows/${e}/sources/presign`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${I}`},body:JSON.stringify({contentLength:D})});if(!v.ok){let o=await v.json().catch(()=>({}));r.fail("Deploy failed (presign)"),console.log(` Error: ${o.error||o.message||v.statusText}
13
+ `),process.exit(1)}let Z=await v.json(),{uploadUrl:F,key:V,headers:W}=Z,x=await fetch(F,{method:"PUT",headers:{...W||{},"Content-Length":String(D)},body:O});if(!x.ok){let o=await x.text().catch(()=>"");r.fail("Deploy failed (S3 upload)"),console.log(` S3 PUT failed: ${x.status} ${o.slice(0,200)}
14
+ `),process.exit(1)}r.text="Saving workflow definition...";let $=await fetch(`${T}/projects/${t}/workflows/${e}`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${I}`},body:JSON.stringify({graph:b,sourcesStagingKey:V,isDefault:!1})});if(!$.ok){let o=await $.json().catch(()=>({}));r.fail("Deploy failed"),console.log(` Error: ${o.message||o.error||$.statusText}
15
+ `),process.exit(1)}let J=await $.json();r.succeed(`Deployed successfully (v${J.version||1})`),console.log(""),console.log(" Next steps:"),console.log(` zibby start ${e} Run locally`),console.log(" zibby workflow list View all workflows"),console.log("")}catch(n){r.fail("Deploy failed"),console.log(` Error: ${n.message}
16
+ `),process.exit(1)}}export{ho as deployWorkflowCommand};
@@ -1,44 +1,45 @@
1
- import e from"chalk";import{readFileSync as P,existsSync as v}from"fs";import{homedir as N}from"os";import{join as R}from"path";var I="https://logs.workflows.zibby.app",j="https://logs-stream.zibby.app/",$=null;async function C(r){return $||(process.env.ZIBBY_SSE_ENDPOINT?($=process.env.ZIBBY_SSE_ENDPOINT,$):($=j,$))}function _(r){let t=R(N(),".zibby","config.json");v(t)||(console.log(e.red(`
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(`
2
2
  Not authenticated`)),console.log(e.gray(` Run: zibby login
3
- `)),process.exit(1));let n;try{n=JSON.parse(P(t,"utf-8"))}catch{console.log(e.red(`
3
+ `)),process.exit(1));let t;try{t=JSON.parse(v(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 i=n.sessionToken;i||(console.log(e.red(`
5
+ `)),process.exit(1)}let a=t.sessionToken;a||(console.log(e.red(`
6
6
  Not authenticated`)),console.log(e.gray(` Run: zibby login
7
- `)),process.exit(1));let m=r.project;return{token:i,projectId:m}}function k(r){return new Date(r).toISOString().replace("T"," ").replace("Z","")}async function T(r,t){let n=await fetch(r,{headers:{Authorization:`Bearer ${t}`}});if(!n.ok){let i=await n.text();throw new Error(`API ${n.status}: ${i}`)}return n.json()}async function A(r,t,n,i){return r||(console.log(e.red(`
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(`
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)),r}async function O({token:r,executionId:t,sseEndpoint:n,stopped:i}){let m=null;try{let g=new URL(n);g.searchParams.set("jobId",t),m&&g.searchParams.set("lastEventId",m);let a=await fetch(g.toString(),{headers:{Authorization:`Bearer ${r}`,Accept:"text/event-stream"}});if(!a.ok)throw new Error(`SSE connection failed: ${a.status} ${a.statusText}`);let s=a.body.getReader(),h=new TextDecoder,d="",y=!1;for(;!i.value;){let{done:w,value:b}=await s.read();if(w)break;d+=h.decode(b,{stream:!0});let u=d.split(`
10
- `);d=u.pop()||"";for(let o of u)if(o.trim()){if(o.startsWith("id:"))m=o.slice(3).trim();else if(o.startsWith("event:")){let l=o.slice(6).trim();if(l==="log")continue;if(l==="status"){let f=u[u.indexOf(o)+1];if(f&&f.startsWith("data:"))try{let p=JSON.parse(f.slice(5).trim());p.status==="new_execution"?console.log(e.gray(`
11
- New execution detected: ${p.executionId}
12
- `)):p.status==="waiting"&&console.log(e.gray(`
13
- Waiting for next execution...`))}catch{}continue}if(l==="complete"){console.log(e.green(`
14
- Execution completed.`)),y=!0;continue}if(l==="error"){let f=u[u.indexOf(o)+1];if(f&&f.startsWith("data:"))try{if(JSON.parse(f.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 f=JSON.parse(l);if(f.timestamp&&f.message){let p=e.gray(k(f.timestamp));console.log(`${p} ${f.message.replace(/\n$/,"")}`)}}catch{}}}}return{completed:y}}catch(g){if(g.name==="AbortError")return{aborted:!0};throw g}}async function J({token:r,jobId:t,follow:n,projectId:i}){console.log(e.gray(` Streaming logs for workflow ${e.cyan(t)}...`)),console.log(n?e.gray(` Press Ctrl+C to stop.
15
- `):"");let m=await C(r);if(!m)return console.log(e.yellow(` SSE endpoint not configured, using CloudWatch polling...
16
- `)),x({token:r,projectId:null,jobId:t,follow:n,limit:1e5});let g={value:!1},a=()=>{g.value=!0,console.log(e.gray(`
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...
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(`
17
17
  Stopped streaming.
18
- `)),process.exit(0)};process.on("SIGINT",a),process.on("SIGTERM",a);try{let s=await O({token:r,executionId:t,sseEndpoint:m,stopped:g});if(s.aborted||g.value)return;if(s.notFound&&(console.log(e.yellow(`
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(`
19
20
  No executions found for this workflow. Trigger the workflow first.
20
- `)),process.exit(1)),s.failed){console.log(e.red(`
21
- Execution failed.`)),n||process.exit(1);return}return s.completed&&process.exit(0),console.log(e.yellow(` Connection ended unexpectedly, falling back to polling...
22
- `)),x({token:r,projectId:null,jobId:t,follow:n,limit:1e3})}catch(s){return s.name==="AbortError"||g.value?void 0:(console.error(e.red(` SSE Error: ${s.message}`)),console.log(e.yellow(` Falling back to polling mode...
23
- `)),x({token:r,projectId:null,jobId:t,follow:n,limit:1e3}))}}async function x({token:r,projectId:t,jobId:n,follow:i,limit:m}){let g=t?`${I}/logs/${t}/${n}`:`${I}/job/${n}`,a=null,s=0,h=new Set,d=!1,y=0,w=5,b=()=>{d=!0,console.log(e.gray(`
21
+ `)),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(`
24
25
  Stopped tailing.
25
- `)),process.exit(0)};for(process.on("SIGINT",b),process.on("SIGTERM",b),console.log(e.gray(` Fetching logs for workflow ${e.cyan(n)}...`)),console.log(i?e.gray(` Press Ctrl+C to stop.
26
- `):"");!d;)try{let u=new URLSearchParams({limit:String(m)});a&&u.set("nextToken",a);let o=await T(`${g}?${u}`,r);y=0,o.message&&o.lines?.length===0&&s===0&&console.log(e.gray(` ${o.message}`)),o.status==="starting"&&o.lines?.length===0&&s===0&&console.log(e.gray(" Container starting..."));for(let c of o.lines||[]){let S=`${c.timestamp}:${c.message}`;if(h.has(S))continue;h.add(S);let E=e.gray(k(c.timestamp));console.log(`${E} ${c.message.replace(/\n$/,"")}`)}if(s=o.lines?.length>0?0:s+1,a=o.nextForwardToken||null,o.status==="completed"||o.status==="failed"){let c=o.status==="completed"?e.green:e.red;console.log(c(`
27
- Job ${o.status}.`)),process.exit(o.status==="completed"?0:1)}if(!i){o.status&&console.log(e.gray(`
28
- Status: ${o.status}`));break}let p=o.lines?.length>0?500:s>5?5e3:2e3;await new Promise(c=>setTimeout(c,p))}catch(u){if(u.name==="AbortError")break;u.message.match(/API (400|401|403|404):/)&&(console.error(e.red(`
29
- ${u.message}
30
- `)),process.exit(1)),y++,console.error(e.red(` Error: ${u.message}`)),y>=w&&(console.error(e.red(`
31
- Too many consecutive errors (${w}). Stopping.
32
- `)),process.exit(1)),i||process.exit(1),await new Promise(l=>setTimeout(l,3e3))}}async function z({token:r,projectId:t,workflow:n,follow:i,limit:m}){let g=`${I}/all/${t}`,a=null,s=0,h=new Set,d=null,y=!1,w=0,b=5,u=()=>{y=!0,console.log(e.gray(`
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(`
30
+ ${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(`
33
34
  Stopped tailing.
34
- `)),process.exit(0)};for(process.on("SIGINT",u),process.on("SIGTERM",u),console.log(e.gray(`
35
- Tailing all runs for ${e.cyan(n)}...`)),console.log(i?e.gray(` Press Ctrl+C to stop.
36
- `):"");!y;)try{let o=new URLSearchParams({workflow:n,limit:String(m)});a&&o.set("nextToken",a);let l=await T(`${g}?${o}`,r);w=0,l.message&&l.lines?.length===0&&s===0&&console.log(e.gray(` ${l.message}`));for(let c of l.lines||[]){let S=`${c.timestamp}:${c.jobId}:${c.message}`;if(h.has(S))continue;h.add(S),c.jobId!==d&&(d!==null&&console.log(""),console.log(e.dim(` \u2500\u2500 ${c.jobId} \u2500\u2500`)),d=c.jobId);let E=e.gray(k(c.timestamp));console.log(`${E} ${c.message.replace(/\n$/,"")}`)}if(s=l.lines?.length>0?0:s+1,a=l.nextToken||null,!i){a&&console.log(e.gray(`
37
- ... 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&&!a&&s>2){console.log(e.gray(`
38
- No running jobs. All caught up.`));break}let p=l.lines?.length>0?500:s>5?5e3:2e3;await new Promise(c=>setTimeout(c,p))}catch(o){if(o.name==="AbortError")break;o.message.match(/API (400|401|403|404):/)&&(console.error(e.red(`
35
+ `)),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(`
39
40
  ${o.message}
40
- `)),process.exit(1)),w++,console.error(e.red(` Error: ${o.message}`)),w>=b&&(console.error(e.red(`
41
- Too many consecutive errors (${b}). Stopping.
42
- `)),process.exit(1)),i||process.exit(1),await new Promise(f=>setTimeout(f,3e3))}}async function W(r,t){let{token:n,projectId:i}=_(t),m=t.follow===!0,g=t.lines?parseInt(t.lines,10):1e5;if(t.all){let s=t.workflow;return s||(console.log(e.red(`
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(`
43
44
  --workflow is required with --all`)),console.log(e.gray(` Example: zibby logs --workflow ticket-triage --all --project <id>
44
- `)),process.exit(1)),z({token:n,projectId:i,workflow:s,follow:m,limit:g})}let a=await A(r,t,n,i);return m?J({token:n,jobId:a,follow:m,projectId:i}):x({token:n,projectId:i,jobId:a,follow:!1,limit:g})}export{W as logsCommand};
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};
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zibby/cli",
3
- "version": "0.1.74",
3
+ "version": "0.1.75",
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.74",
3
+ "version": "0.1.75",
4
4
  "description": "Zibby CLI - Test automation generator and runner",
5
5
  "type": "module",
6
6
  "bin": {