@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
|
|
2
|
-
Error:
|
|
3
|
-
`),process.exit(1));let
|
|
4
|
-
Error: No workflows found in ${
|
|
5
|
-
`),process.exit(1));let{readdir:
|
|
6
|
-
Error: No workflows found in ${
|
|
7
|
-
`),process.exit(1)),console.log(""),
|
|
8
|
-
Error: Workflow not found: ${
|
|
9
|
-
`),process.exit(1));let
|
|
10
|
-
Error: graph.mjs not found in ${
|
|
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: ${
|
|
13
|
-
`),process.exit(1)}let
|
|
14
|
-
`),process.exit(1)}r.text="Saving workflow definition...";let
|
|
15
|
-
`),process.exit(1)}let
|
|
16
|
-
`),process.exit(1)}}export{
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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)),
|
|
10
|
-
`);d
|
|
11
|
-
|
|
12
|
-
`))
|
|
13
|
-
Waiting for next execution...`))}catch{}continue}if(
|
|
14
|
-
Execution completed.`)),
|
|
15
|
-
`):"");let
|
|
16
|
-
`)),
|
|
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",
|
|
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)
|
|
21
|
-
Execution failed.`)),
|
|
22
|
-
`)),
|
|
23
|
-
`)),
|
|
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"
|
|
26
|
-
`):"");!
|
|
27
|
-
Job ${o.status}.`)),process.exit(o.status==="completed"?0:1)}if(!
|
|
28
|
-
Status: ${o.status}`));break}let
|
|
29
|
-
${
|
|
30
|
-
`)),process.exit(1)),
|
|
31
|
-
Too many consecutive errors (${
|
|
32
|
-
`)),process.exit(1)),
|
|
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",
|
|
35
|
-
Tailing all runs for ${e.cyan(
|
|
36
|
-
`):"");!
|
|
37
|
-
... more logs available. Run again or use --follow to stream.`)),
|
|
38
|
-
No running jobs. All caught up.`));break}let
|
|
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)),
|
|
41
|
-
Too many consecutive errors (${
|
|
42
|
-
`)),process.exit(1)),
|
|
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:
|
|
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