@zibby/cli 0.1.80 → 0.1.81

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,47 +1,48 @@
1
- import{readFileSync as N,writeFileSync as b,existsSync as B,mkdirSync as D}from"fs";import{resolve as T,join as m}from"path";import o from"chalk";import $ from"ora";import Y from"dotenv";import R from"inquirer";var w={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 _(){let t;if(process.env.ZIBBY_API_URL)t=process.env.ZIBBY_API_URL;else{let e=process.env.ZIBBY_ENV||"prod";w[e]?t=w[e].apiUrl:t=w.prod.apiUrl}try{let e=new URL(t);return e.protocol!=="http:"&&e.protocol!=="https:"?(console.error(`\u26A0\uFE0F Invalid API URL protocol: ${e.protocol} (only http/https allowed)`),w.prod.apiUrl):t}catch{return console.error(`\u26A0\uFE0F Invalid API URL: ${t}`),w.prod.apiUrl}}function j(){let t=process.env.ZIBBY_ENV||"prod";return w[t]||w.prod}import{validateGraphConfig as z,generateWorkflowCode as S,generateNodeConfigsJson as F}from"@zibby/agent-workflow";import"@zibby/core/templates/register-nodes.js";Y.config();async function L(t){let e=_(),l=$("Fetching projects...").start();try{let c=await fetch(`${e}/projects`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`}});c.ok||(l.fail("Failed to fetch projects"),process.exit(1));let n=await c.json();Array.isArray(n)||(n.projects&&Array.isArray(n.projects)?n=n.projects:n.data&&Array.isArray(n.data)?n=n.data:(l.fail("Unexpected response format"),process.exit(1))),(!n||n.length===0)&&(l.fail("No projects found"),process.exit(1)),l.stop();let i=n.map(r=>({name:`${r.name||"Unnamed"} (${r.id||"no-id"})`,value:r.id})),{projectId:g}=await R.prompt([{type:"list",name:"projectId",message:"Select a project:",choices:i}]);return g}catch(c){l.fail(`Error: ${c.message}`),process.exit(1)}}function x(t){let e=t.apiKey||process.env.ZIBBY_API_KEY;e||(console.log(o.red(`
1
+ import{readFileSync as C,writeFileSync as U,existsSync as b,mkdirSync as P}from"fs";import{resolve as N,join as w}from"path";import o from"chalk";import v from"ora";import R from"dotenv";import z from"inquirer";var m={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 I(){let n;if(process.env.ZIBBY_API_URL)n=process.env.ZIBBY_API_URL;else{let e=process.env.ZIBBY_ENV||"prod";m[e]?n=m[e].apiUrl:n=m.prod.apiUrl}try{let e=new URL(n);return e.protocol!=="http:"&&e.protocol!=="https:"?(console.error(`\u26A0\uFE0F Invalid API URL protocol: ${e.protocol} (only http/https allowed)`),m.prod.apiUrl):n}catch{return console.error(`\u26A0\uFE0F Invalid API URL: ${n}`),m.prod.apiUrl}}function j(){let n=process.env.ZIBBY_ENV||"prod";return m[n]||m.prod}import{validateGraphConfig as Y,generateWorkflowCode as S,generateNodeConfigsJson as L}from"@zibby/agent-workflow";import"@zibby/core/templates/register-nodes.js";R.config();async function Z(n){let e=I(),i=v("Fetching projects...").start();try{let c=await fetch(`${e}/projects`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`}});c.ok||(i.fail("Failed to fetch projects"),process.exit(1));let t=await c.json();Array.isArray(t)||(t.projects&&Array.isArray(t.projects)?t=t.projects:t.data&&Array.isArray(t.data)?t=t.data:(i.fail("Unexpected response format"),process.exit(1))),(!t||t.length===0)&&(i.fail("No projects found"),process.exit(1)),i.stop();let a=t.map(r=>({name:`${r.name||"Unnamed"} (${r.id||"no-id"})`,value:r.id})),{projectId:d}=await z.prompt([{type:"list",name:"projectId",message:"Select a project:",choices:a}]);return d}catch(c){i.fail(`Error: ${c.message}`),process.exit(1)}}function B(n){let e=n.apiKey||process.env.ZIBBY_API_KEY;e||(console.log(o.red(`
2
2
  ZIBBY_API_KEY not set`)),console.log(o.gray(` Add to .env: ZIBBY_API_KEY=zby_xxx
3
- `)),process.exit(1));let l=t.project||process.env.ZIBBY_PROJECT_ID;return l||(console.log(o.red(`
3
+ `)),process.exit(1));let i=n.project||process.env.ZIBBY_PROJECT_ID;return i||(console.log(o.red(`
4
4
  --project or ZIBBY_PROJECT_ID is required`)),console.log(o.gray(` Example: zibby workflow download --project <id> --type analysis
5
- `)),process.exit(1)),{apiKey:e,projectId:l}}async function Z(t){let e=t.apiKey||process.env.ZIBBY_API_KEY;e||(console.log(o.red(`
5
+ `)),process.exit(1)),{apiKey:e,projectId:i}}async function F(n){let e=n.apiKey||process.env.ZIBBY_API_KEY;e||(console.log(o.red(`
6
6
  ZIBBY_API_KEY not set`)),console.log(o.gray(` Add to .env: ZIBBY_API_KEY=zby_xxx
7
- `)),process.exit(1));let l=t.project||process.env.ZIBBY_PROJECT_ID;return l||(l=await L(e)),{apiKey:e,projectId:l}}var U=["analysis","implementation","run_test"],O=/^[a-z][a-z0-9_-]{0,62}[a-z0-9]$/;function P(t){let e=t.type;return e||(console.log(o.red(`
8
- --type is required`)),console.log(o.gray(` Built-in types: ${U.join(", ")}`)),console.log(o.gray(` Custom workflows: any lowercase slug (e.g., ticket-triage)
9
- `)),process.exit(1)),!U.includes(e)&&!O.test(e)&&(console.log(o.red(`
10
- Invalid workflow type: "${e}"`)),console.log(o.gray(` Built-in: ${U.join(", ")}`)),console.log(o.gray(` Custom: lowercase letters, digits, hyphens (2\u201364 chars)
11
- `)),process.exit(1)),e}async function eo(t){let e=j(),{apiKey:l,projectId:c}=x(t),n=P(t);console.log(o.bold.cyan(`
7
+ `)),process.exit(1));let i=n.project||process.env.ZIBBY_PROJECT_ID;return i||(i=await Z(e)),{apiKey:e,projectId:i}}var _=["analysis","implementation","run_test"],O=/^[a-z][a-z0-9_-]{0,62}[a-z0-9]$/;function x(n){let e=n.type;return e||(console.log(o.red(`
8
+ --type is required`)),console.log(o.gray(` Built-in types: ${_.join(", ")}`)),console.log(o.gray(` Custom workflows: any lowercase slug (e.g., ticket-triage)
9
+ `)),process.exit(1)),!_.includes(e)&&!O.test(e)&&(console.log(o.red(`
10
+ Invalid workflow type: "${e}"`)),console.log(o.gray(` Built-in: ${_.join(", ")}`)),console.log(o.gray(` Custom: lowercase letters, digits, hyphens (2\u201364 chars)
11
+ `)),process.exit(1)),e}var K=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;async function J(n,e){let i=I(),c={"Content-Type":"application/json",Authorization:`Bearer ${e}`},t=await fetch(`${i}/projects`,{method:"GET",headers:c});if(!t.ok)throw new Error(`Failed to list projects: HTTP ${t.status}`);let{projects:a=[]}=await t.json();for(let d of a){let r=await fetch(`${i}/projects/${d.projectId}/workflows`,{method:"GET",headers:c});if(!r.ok)continue;let s=await r.json(),l=(Array.isArray(s)?s:[]).find(p=>p.uuid===n);if(l){let p=l.workflowType||l.name;return{projectId:d.projectId,workflowType:p}}}return null}async function to(n){let e=j(),i,c,t;if(n.uuid){K.test(n.uuid)||(console.log(o.red(`
12
+ '${n.uuid}' is not a UUID.`)),console.log(o.gray(" Cloud workflows are identified by UUID. Run `zibby workflow list` to find yours,")),console.log(o.gray(` or use --type <built-in> for built-in workflow types.
13
+ `)),process.exit(1)),t=n.apiKey||process.env.ZIBBY_API_KEY,t||(t=B({...n,project:"pending"}).apiKey);let d=await J(n.uuid,t);d||(console.log(o.red(`
14
+ Workflow with UUID '${n.uuid}' not found in any of your projects.`)),console.log(o.gray(` Check: zibby workflow list
15
+ `)),process.exit(1)),i=d.projectId,c=d.workflowType}else{let d=B(n);t=d.apiKey,i=d.projectId,c=x(n)}console.log(o.bold.cyan(`
12
16
  Zibby Workflow Download
13
- `)),console.log(o.gray(" ".padEnd(52,"-"))),console.log(o.white(` Environment: ${o.cyan(e.name)}`)),console.log(o.white(` Project: ${o.cyan(c)}`)),console.log(o.white(` Type: ${o.cyan(n)}`)),console.log(o.gray(" ".padEnd(52,"-")));let i=$(" Fetching workflow from cloud...").start();try{let g=_(),r=await fetch(`${g}/projects/${c}/workflows/${n}`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`}});if(!r.ok){let a=await r.text();i.fail(` API error: ${r.status}`),console.log(o.red(` ${a}
14
- `)),process.exit(1)}let s=await r.json();!s.graph&&s.isDefault?i.info(" No custom workflow saved -- downloading default graph"):i.succeed(` Fetched workflow (v${s.version||0})`);let d=s.graph||null;if(!d){console.log(o.yellow(`
17
+ `)),console.log(o.gray(" ".padEnd(52,"-"))),console.log(o.white(` Environment: ${o.cyan(e.name)}`)),console.log(o.white(` Project: ${o.cyan(i)}`)),console.log(o.white(` Type: ${o.cyan(c)}`)),console.log(o.gray(" ".padEnd(52,"-")));let a=v(" Fetching workflow from cloud...").start();try{let d=I(),r=await fetch(`${d}/projects/${i}/workflows/${c}`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`}});if(!r.ok){let p=await r.text();a.fail(` API error: ${r.status}`),console.log(o.red(` ${p}
18
+ `)),process.exit(1)}let s=await r.json();!s.graph&&s.isDefault?a.info(" No custom workflow saved -- downloading default graph"):a.succeed(` Fetched workflow (v${s.version||0})`);let l=s.graph||null;if(!l){console.log(o.yellow(`
15
19
  No graph config available for this workflow.`)),console.log(o.gray(" The project is using the built-in default graph.")),console.log(o.gray(` Edit the graph in the UI first, or use --include-default to download the default.
16
- `)),t.includeDefault||process.exit(0),i.start(" Fetching default graph...");let{getDefaultGraph:a}=await import("@zibby/core/templates/graphs/index.js"),u=a(n);return u||(i.fail(` No default graph found for type "${n}"`),process.exit(1)),k(n,{graph:u,version:0,isDefault:!0,projectId:c,workflowType:n},t)}return k(n,{graph:d,version:s.version||0,isDefault:s.isDefault||!1,projectId:c,workflowType:n},t)}catch(g){i.fail(" Download failed"),console.log(o.red(`
17
- ${g.message}
18
- `)),process.exit(1)}}function k(t,e,l){let c=process.cwd(),n=l.output||m(c,".zibby");B(n)||D(n,{recursive:!0});let i={projectId:e.projectId,workflowType:e.workflowType,version:e.version,isDefault:e.isDefault},g=`workflow-${t}.js`,r=m(n,g),s=S(e.graph,i);b(r,s,"utf-8");let d=e.graph.nodeConfigs||{},a=F(d),u=`workflow-${t}.config.json`,v=m(n,u);b(v,`${JSON.stringify(a,null,2)}
19
- `,"utf-8");let I=`workflow-${t}.json`,p=m(n,I),f={_meta:{...i,downloadedAt:new Date().toISOString()},...e.graph};b(p,`${JSON.stringify(f,null,2)}
20
- `,"utf-8"),console.log(o.green(`
21
- Generated workflow files:`)),console.log(o.white(` ${o.bold(r)}`)),console.log(o.gray(" Executable graph with inline tool bindings")),console.log(o.white(` ${o.bold(v)}`)),console.log(o.gray(" Extra prompt instructions & runtime config")),console.log(o.white(` ${o.bold(p)}`)),console.log(o.gray(" Raw JSON config (for upload back to cloud)")),console.log(""),console.log(o.gray(` Version: ${e.version}`)),console.log(o.gray(` Nodes: ${e.graph.nodes?.length||0}`)),console.log(o.gray(` Edges: ${e.graph.edges?.length||0}
22
- `)),console.log(o.white(" To run locally:")),console.log(o.cyan(` zibby analyze --workflow ${r}
23
- `)),console.log(o.white(" To upload changes back:")),console.log(o.cyan(` zibby workflow upload --project ${e.projectId} --type ${t}
24
- `))}async function no(t){let e=j(),{apiKey:l,projectId:c}=await Z(t),n=P(t);console.log(o.bold.cyan(`
20
+ `)),n.includeDefault||process.exit(0),a.start(" Fetching default graph...");let{getDefaultGraph:p}=await import("@zibby/core/templates/graphs/index.js"),g=p(c);return g||(a.fail(` No default graph found for type "${c}"`),process.exit(1)),D(c,{graph:g,version:0,isDefault:!0,projectId:i,workflowType:c,sources:null,uuid:null},n)}return D(c,{graph:l,version:s.version||0,isDefault:s.isDefault||!1,projectId:i,workflowType:c,sources:s.sources||null,uuid:s.uuid||s.workflowUuid||null},n)}catch(d){a.fail(" Download failed"),console.log(o.red(`
21
+ ${d.message}
22
+ `)),process.exit(1)}}function D(n,e,i){let c=process.cwd(),t=i.output||w(c,".zibby","workflows"),a=w(t,n);b(a)||P(a,{recursive:!0});let d={projectId:e.projectId,workflowType:e.workflowType,version:e.version,isDefault:e.isDefault},r=[];if(e.sources&&typeof e.sources=="object"&&Object.keys(e.sources).length>0)for(let[l,p]of Object.entries(e.sources)){if(l.includes("..")||l.startsWith("/")){console.log(o.yellow(` \u26A0 Skipping unsafe source path: ${l}`));continue}let g=w(a,l),h=w(g,"..");b(h)||P(h,{recursive:!0}),U(g,p,"utf-8"),r.push(l)}else{let l=w(a,"graph.mjs");U(l,S(e.graph,d),"utf-8"),r.push("graph.mjs");let p=e.graph.nodeConfigs||{},g=L(p),h=w(a,"workflow.config.json");U(h,`${JSON.stringify(g,null,2)}
23
+ `,"utf-8"),r.push("workflow.config.json")}if(e.uuid){let l={uuid:e.uuid,name:n,projectId:e.projectId,version:e.version,downloadedAt:new Date().toISOString()};U(w(a,".zibby-deploy.json"),`${JSON.stringify(l,null,2)}
24
+ `,"utf-8"),r.push(".zibby-deploy.json")}let s=`.zibby/workflows/${n}/`;console.log(o.green(`
25
+ Downloaded to ${o.bold(s)}`));for(let l of r)console.log(o.gray(` ${l}`));console.log(""),console.log(o.gray(` Version: ${e.version}`)),console.log(o.gray(` Nodes: ${e.graph.nodes?.length||0}`)),console.log(o.gray(` Edges: ${e.graph.edges?.length||0}`)),e.uuid&&console.log(o.gray(` UUID: ${e.uuid}`)),console.log(""),console.log(o.white(" Next steps:")),console.log(o.cyan(` cd ${s} && npm install `)+o.gray("Install workflow deps")),console.log(o.cyan(` zibby workflow start ${n} `)+o.gray("Run locally")),console.log(o.cyan(` zibby workflow deploy ${n} `)+o.gray("Re-deploy after changes (same UUID)")),console.log("")}async function ro(n){let e=j(),{apiKey:i,projectId:c}=await F(n),t=x(n);console.log(o.bold.cyan(`
25
26
  Zibby Workflow Upload
26
- `)),console.log(o.gray(" ".padEnd(52,"-"))),console.log(o.white(` Environment: ${o.cyan(e.name)}`)),console.log(o.white(` Project: ${o.cyan(c)}`)),console.log(o.white(` Type: ${o.cyan(n)}`)),console.log(o.gray(" ".padEnd(52,"-")));let i=process.cwd(),g=m(i,".zibby",`workflow-${n}.json`),r=m(i,".zibby",`workflow-${n}.js`),s=t.file||(B(r)?r:g);B(s)||(console.log(o.red(`
27
+ `)),console.log(o.gray(" ".padEnd(52,"-"))),console.log(o.white(` Environment: ${o.cyan(e.name)}`)),console.log(o.white(` Project: ${o.cyan(c)}`)),console.log(o.white(` Type: ${o.cyan(t)}`)),console.log(o.gray(" ".padEnd(52,"-")));let a=process.cwd(),d=w(a,".zibby",`workflow-${t}.json`),r=w(a,".zibby",`workflow-${t}.js`),s=n.file||(b(r)?r:d);b(s)||(console.log(o.red(`
27
28
  File not found: ${s}`)),console.log(o.gray(` Download a workflow first: zibby workflow download --project <id> --type <type>
28
- `)),process.exit(1));let d=s.endsWith(".js")||s.endsWith(".mjs"),a;if(d){let p=$(" Loading JS workflow module...").start();try{let{pathToFileURL:f}=await import("url"),h=await import(f(T(s)).href),y=h.buildGraph();a=y.serialize();let E=h.nodeConfigs||{};if(Object.keys(E).length>0)for(let[A,C]of Object.entries(E))a.nodeConfigs[A]={...C,...a.nodeConfigs[A]};p.succeed(` Loaded JS module (${y.nodes.size} nodes)`)}catch(f){p.fail(" Failed to load JS module"),console.log(o.red(`
29
- ${f.message}
30
- `)),process.exit(1)}}else{let p;try{p=JSON.parse(N(s,"utf-8"))}catch(y){console.log(o.red(`
31
- Failed to parse ${s}: ${y.message}
32
- `)),process.exit(1)}let{_meta:f,...h}=p;a=h}(!a.nodes||!a.edges)&&(console.log(o.red(`
29
+ `)),process.exit(1));let l=s.endsWith(".js")||s.endsWith(".mjs"),p;if(l){let f=v(" Loading JS workflow module...").start();try{let{pathToFileURL:u}=await import("url"),y=await import(u(N(s)).href),$=y.buildGraph();p=$.serialize();let E=y.nodeConfigs||{};if(Object.keys(E).length>0)for(let[A,T]of Object.entries(E))p.nodeConfigs[A]={...T,...p.nodeConfigs[A]};f.succeed(` Loaded JS module (${$.nodes.size} nodes)`)}catch(u){f.fail(" Failed to load JS module"),console.log(o.red(`
30
+ ${u.message}
31
+ `)),process.exit(1)}}else{let f;try{f=JSON.parse(C(s,"utf-8"))}catch($){console.log(o.red(`
32
+ Failed to parse ${s}: ${$.message}
33
+ `)),process.exit(1)}let{_meta:u,...y}=f;p=y}(!p.nodes||!p.edges)&&(console.log(o.red(`
33
34
  Invalid workflow file: missing nodes or edges`)),console.log(o.gray(` The file should contain { nodes: [...], edges: [...], nodeConfigs: {...} }
34
35
  `)),process.exit(1)),console.log(o.gray(`
35
- File: ${s}`)),console.log(o.gray(` Format: ${d?"JavaScript (serialized via graph.serialize())":"JSON"}`)),console.log(o.gray(` Nodes: ${a.nodes.length}`)),console.log(o.gray(` Edges: ${a.edges.length}`));let u=$(" Validating graph...").start(),v=z(a);if(!v.valid){u.fail(" Graph validation failed"),console.log("");for(let p of v.errors)console.log(o.red(` ${p}`));console.log(o.gray(`
36
+ File: ${s}`)),console.log(o.gray(` Format: ${l?"JavaScript (serialized via graph.serialize())":"JSON"}`)),console.log(o.gray(` Nodes: ${p.nodes.length}`)),console.log(o.gray(` Edges: ${p.edges.length}`));let g=v(" Validating graph...").start(),h=Y(p);if(!h.valid){g.fail(" Graph validation failed"),console.log("");for(let f of h.errors)console.log(o.red(` ${f}`));console.log(o.gray(`
36
37
  Fix the errors above and try again.
37
- `)),process.exit(1)}u.succeed(" Graph is valid");let I=$(" Uploading to cloud...").start();try{let p=_(),f=await fetch(`${p}/projects/${c}/workflows/${n}`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`},body:JSON.stringify({graph:a})});if(!f.ok){let y=await f.text();I.fail(` API error: ${f.status}`),console.log(o.red(` ${y}
38
- `)),process.exit(1)}let h=await f.json();I.succeed(` Uploaded successfully (v${h.version})`),console.log(o.green(`
39
- Workflow "${n}" updated to version ${h.version}`)),console.log(o.gray(` Project: ${c}
40
- `))}catch(p){I.fail(" Upload failed"),console.log(o.red(`
41
- ${p.message}
42
- `)),process.exit(1)}}var J=["analysis","implementation","run_test"];async function to(t){let e=j(),{apiKey:l,projectId:c}=x(t);console.log(o.bold.cyan(`
38
+ `)),process.exit(1)}g.succeed(" Graph is valid");let k=v(" Uploading to cloud...").start();try{let f=I(),u=await fetch(`${f}/projects/${c}/workflows/${t}`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({graph:p})});if(!u.ok){let $=await u.text();k.fail(` API error: ${u.status}`),console.log(o.red(` ${$}
39
+ `)),process.exit(1)}let y=await u.json();k.succeed(` Uploaded successfully (v${y.version})`),console.log(o.green(`
40
+ Workflow "${t}" updated to version ${y.version}`)),console.log(o.gray(` Project: ${c}
41
+ `))}catch(f){k.fail(" Upload failed"),console.log(o.red(`
42
+ ${f.message}
43
+ `)),process.exit(1)}}var W=["analysis","implementation","run_test"];async function so(n){let e=j(),{apiKey:i,projectId:c}=B(n);console.log(o.bold.cyan(`
43
44
  Zibby Workflows
44
- `));let n=$(" Fetching workflows...").start();try{let i=_(),g=[];for(let r of J){let s=await fetch(`${i}/projects/${c}/workflows/${r}`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`}});if(s.ok){let d=await s.json();g.push({type:r,version:d.version||0,isDefault:d.isDefault!==!1&&!d.graph,nodes:d.graph?.nodes?.length||0,updatedAt:d.updatedAt||null})}}n.succeed(` Fetched workflows
45
- `),console.log(o.gray(" ".padEnd(70,"-"))),console.log(o.white(" Type".padEnd(20))+o.white("Version".padEnd(10))+o.white("Nodes".padEnd(10))+o.white("Status".padEnd(15))+o.white("Updated")),console.log(o.gray(" ".padEnd(70,"-")));for(let r of g){let s=r.isDefault?o.gray("default"):o.green("custom"),d=r.updatedAt?new Date(r.updatedAt).toLocaleDateString():o.gray("-");console.log(` ${o.cyan(r.type.padEnd(18))}${String(r.version).padEnd(10)}${String(r.nodes).padEnd(10)}${s.padEnd(15)}${d}`)}console.log(o.gray(" ".padEnd(70,"-"))),console.log("")}catch(i){n.fail(" Failed to fetch workflows"),console.log(o.red(`
46
- ${i.message}
47
- `)),process.exit(1)}}export{eo as workflowDownloadCommand,to as workflowListCommand,no as workflowUploadCommand};
45
+ `));let t=v(" Fetching workflows...").start();try{let a=I(),d=[];for(let r of W){let s=await fetch(`${a}/projects/${c}/workflows/${r}`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`}});if(s.ok){let l=await s.json();d.push({type:r,version:l.version||0,isDefault:l.isDefault!==!1&&!l.graph,nodes:l.graph?.nodes?.length||0,updatedAt:l.updatedAt||null})}}t.succeed(` Fetched workflows
46
+ `),console.log(o.gray(" ".padEnd(70,"-"))),console.log(o.white(" Type".padEnd(20))+o.white("Version".padEnd(10))+o.white("Nodes".padEnd(10))+o.white("Status".padEnd(15))+o.white("Updated")),console.log(o.gray(" ".padEnd(70,"-")));for(let r of d){let s=r.isDefault?o.gray("default"):o.green("custom"),l=r.updatedAt?new Date(r.updatedAt).toLocaleDateString():o.gray("-");console.log(` ${o.cyan(r.type.padEnd(18))}${String(r.version).padEnd(10)}${String(r.nodes).padEnd(10)}${s.padEnd(15)}${l}`)}console.log(o.gray(" ".padEnd(70,"-"))),console.log("")}catch(a){t.fail(" Failed to fetch workflows"),console.log(o.red(`
47
+ ${a.message}
48
+ `)),process.exit(1)}}export{to as workflowDownloadCommand,so as workflowListCommand,ro as workflowUploadCommand};
@@ -1,17 +1,33 @@
1
- import{existsSync as f,readFileSync as P,writeFileSync as so}from"fs";import{join as i}from"path";import d from"chalk";import V from"ora";import ro from"dotenv";import{select as W}from"@inquirer/prompts";import{existsSync as eo}from"fs";import{join as to}from"path";import{pathToFileURL as no}from"url";async function F(o){let n=to(o,".zibby.config.mjs");if(!eo(n))throw new Error(".zibby.config.mjs not found");try{let c=await import(no(n).href);return c.default||c}catch(c){throw new Error(`Failed to load .zibby.config.mjs: ${c.message}`,{cause:c})}}var v={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 O(){let o;if(process.env.ZIBBY_API_URL)o=process.env.ZIBBY_API_URL;else{let n=process.env.ZIBBY_ENV||"prod";v[n]?o=v[n].apiUrl:o=v.prod.apiUrl}try{let n=new URL(o);return n.protocol!=="http:"&&n.protocol!=="https:"?(console.error(`\u26A0\uFE0F Invalid API URL protocol: ${n.protocol} (only http/https allowed)`),v.prod.apiUrl):o}catch{return console.error(`\u26A0\uFE0F Invalid API URL: ${o}`),v.prod.apiUrl}}function M(o,n){return o?.uuid||o?.workflowUuid||n?.uuid||null}function J({uuid:o,name:n,projectId:c,result:l,existingManifest:u=null,now:a=()=>new Date().toISOString()}){let e=l?.version??(u?.version??0)+1;return{uuid:o,name:n,projectId:c,version:e,deployedAt:a()}}ro.config();async function io(o,n){let c=O(),l=V("Fetching projects...").start();try{let u=n||o,a=await fetch(`${c}/projects`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${u}`}});a.ok||(l.fail("Failed to fetch projects"),process.exit(1));let e=await a.json();Array.isArray(e)||(e.projects&&Array.isArray(e.projects)?e=e.projects:e.data&&Array.isArray(e.data)?e=e.data:(l.fail("Unexpected response format"),process.exit(1))),(!e||e.length===0)&&(l.fail("No projects found"),process.exit(1)),l.succeed(`Found ${e.length} project${e.length===1?"":"s"}`),console.log("");let I=e.map(g=>{let $=g.projectId||g.id||g._id||"unknown";return{name:`${g.name||g.projectName||"Unnamed"} (${$})`,value:$}});return await W({message:"Select a project to deploy to:",choices:I})}catch(u){l.fail(`Error: ${u.message}`),process.exit(1)}}async function vo(o,n={}){let c=process.cwd(),l=null,u=n.apiKey||process.env.ZIBBY_API_KEY;try{let s=i(process.env.HOME||process.env.USERPROFILE,".zibby","config.json");f(s)&&(l=JSON.parse(P(s,"utf-8")).sessionToken)}catch{}!l&&!u&&(console.log(`
2
- Error: Not authenticated`),console.log(" Run: zibby login"),console.log(` Or set ZIBBY_API_KEY
3
- `),process.exit(1));let a=".zibby/workflows";try{a=(await F(c))?.paths?.workflows||".zibby/workflows"}catch{}if(!o){let s=i(c,a);f(s)||(console.log(`
4
- Error: No workflows found in ${a}/`),console.log(` Create one with: zibby g workflow <name>
5
- `),process.exit(1));let{readdir:p,stat:m}=await import("fs/promises"),D=await p(s),j=[];for(let k of D){let y=i(s,k);if(!(await m(y)).isDirectory())continue;(f(i(y,"graph.mjs"))||f(i(y,"graph.js")))&&j.push(k)}j.length===0&&(console.log(`
6
- Error: No workflows found in ${a}/`),console.log(` Create one with: zibby g workflow <name>
7
- `),process.exit(1)),console.log(""),o=await W({message:"Select a workflow to deploy:",choices:j.map(k=>({name:k,value:k}))})}let e=n.project||process.env.ZIBBY_PROJECT_ID;e||(console.log(""),e=await io(u,l));let I=l||u,h=i(c,a,o);f(h)||(console.log(`
8
- Error: Workflow not found: ${a}/${o}`),console.log(` Run: zibby workflow list
9
- `),process.exit(1));let g=i(h,"graph.mjs"),$=i(h,"workflow.json");f(g)||(console.log(`
10
- Error: graph.mjs not found in ${a}/${o}/`),process.exit(1)),console.log(`
1
+ import{existsSync as k,readFileSync as W,writeFileSync as Mo}from"fs";import{join as m}from"path";import j from"chalk";import G from"ora";import Ko from"dotenv";import{select as ko}from"@inquirer/prompts";import{existsSync as To}from"fs";import{join as Po}from"path";import{pathToFileURL as Bo}from"url";async function eo(o){let e=Po(o,".zibby.config.mjs");if(!To(e))throw new Error(".zibby.config.mjs not found");try{let n=await import(Bo(e).href);return n.default||n}catch(n){throw new Error(`Failed to load .zibby.config.mjs: ${n.message}`,{cause:n})}}var A={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 B(){let o;if(process.env.ZIBBY_API_URL)o=process.env.ZIBBY_API_URL;else{let e=process.env.ZIBBY_ENV||"prod";A[e]?o=A[e].apiUrl:o=A.prod.apiUrl}try{let e=new URL(o);return e.protocol!=="http:"&&e.protocol!=="https:"?(console.error(`\u26A0\uFE0F Invalid API URL protocol: ${e.protocol} (only http/https allowed)`),A.prod.apiUrl):o}catch{return console.error(`\u26A0\uFE0F Invalid API URL: ${o}`),A.prod.apiUrl}}function no(o,e){return o?.uuid||o?.workflowUuid||e?.uuid||null}function to({uuid:o,name:e,projectId:n,result:t,existingManifest:h=null,now:a=()=>new Date().toISOString()}){let s=t?.version??(h?.version??0)+1;return{uuid:o,name:e,projectId:n,version:s,deployedAt:a()}}import{existsSync as Fo,readFileSync as Yo}from"fs";import{join as Zo}from"path";import K from"chalk";import{confirm as Jo}from"@inquirer/prompts";import l from"chalk";import J from"ora";import{spawn as Lo}from"child_process";import{existsSync as so,mkdirSync as Ao,readFileSync as Co,writeFileSync as zo}from"fs";import{homedir as ro}from"os";import{join as O}from"path";function io(){return process.env.ZIBBY_CONFIG_DIR||O(ro(),".zibby")}function lo(){return O(io(),"config.json")}var _o=O(ro(),".zibby"),re=O(_o,"config.json");function Eo(){let o=io();so(o)||Ao(o,{recursive:!0})}function S(){try{let o=lo();if(so(o)){let e=Co(o,"utf-8");return JSON.parse(e)}}catch{}return{}}function C(o){Eo(),zo(lo(),JSON.stringify(o,null,2))}function co(){return S().sessionToken||null}function ao(o){let e=S();e.sessionToken=o,C(e)}function po(){return S().user||null}function uo(o){let e=S();e.user=o,C(e)}function fo(o){let e=S();e.proxyUrl=o,C(e)}function go(o){let e=S();e.mem0ProxyUrl=o,C(e)}function yo(o){let e=S();e.projects=o,C(e)}import{existsSync as ce,mkdirSync as ae,readFileSync as pe,writeFileSync as ue,unlinkSync as fe}from"fs";import{resolve as de}from"path";import{homedir as he}from"os";function Oo(o){let e=process.platform;try{let n,t;return e==="darwin"?(n="open",t=[o]):e==="win32"?(n="cmd",t=["/c","start","",o]):(n="xdg-open",t=[o]),Lo(n,t,{detached:!0,stdio:"ignore"}).unref(),!0}catch{return!1}}function Do(){let o=co(),e=po();return o&&e?{loggedIn:!0,user:e,token:o}:{loggedIn:!1}}async function wo(){try{console.log(l.cyan(`
2
+ \u{1F510} Initiating login...
3
+ `));let o=Do();if(o.loggedIn){console.log(l.green("\u2705 Already logged in!")),console.log(l.gray(`User: ${o.user.email}`)),console.log(l.gray(`Name: ${o.user.name}
4
+ `));let{createInterface:e}=await import("readline"),n=e({input:process.stdin,output:process.stdout});return new Promise((t,h)=>{let a=()=>{n.close(),process.stdin.isTTY&&process.stdin.setRawMode(!1)},s=()=>{console.log(l.yellow(`
5
+
6
+ \u26A0\uFE0F Login cancelled
7
+ `)),a(),process.exit(0)};process.on("SIGINT",s),n.question(l.yellow("Continue with this session? (Y/n): "),async d=>{process.removeListener("SIGINT",s),a();try{if(d.toLowerCase()==="n"||d.toLowerCase()==="no"){console.log(l.gray(`Starting new login...
8
+ `));let u=await ho();t(u)}else console.log(l.green(`Using existing session.
9
+ `)),t({success:!0,...o})}catch(u){h(u)}})})}return await ho()}catch(o){return console.error(l.red(`
10
+ \u274C Login failed:`,o.message)),{success:!1,error:o.message}}}async function Ro(o){let e=B();try{let n=await fetch(`${e}/projects`,{headers:{Authorization:`Bearer ${o}`}});if(n.ok){let h=((await n.json()).projects||[]).map(a=>({name:a.name,projectId:a.projectId,apiToken:a.apiToken}));return yo(h),h}}catch(n){console.log(l.gray(`\u26A0\uFE0F Could not fetch projects: ${n.message}`))}return[]}async function ho(){let o=B(),e=J("Requesting login code...").start(),n=await fetch(`${o}/cli/login/initiate`,{method:"POST",headers:{"Content-Type":"application/json"}});if(!n.ok){e.fail("Failed to request login code");let g=await n.json();throw new Error(g.error||"Failed to initiate login")}let{deviceCode:t,userCode:h,verificationUrl:a,expiresIn:s,interval:d}=await n.json();e.succeed("Login code generated"),console.log(""),console.log(l.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")),console.log(l.cyan("\u2551")+l.white.bold(" Complete login in your browser ")+l.cyan("\u2551")),console.log(l.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")),console.log(""),console.log(l.white("Opening browser to login page...")),console.log(l.gray(`Code expires in ${Math.floor(s/60)} minutes`)),console.log(""),await Oo(a)||(console.log(l.yellow("\u26A0\uFE0F Could not open browser automatically.")),console.log(l.white("Please open this URL manually: ")+l.blue(a)),console.log(""));let p=J("Waiting for authorization...").start(),f=(d||3)*1e3,i=Math.floor(s/(d||3)),b=0,D=!1,y=()=>{D=!0,p.stop(),console.log(l.yellow(`
11
+
12
+ \u26A0\uFE0F Login cancelled
13
+ `)),process.exit(0)};process.on("SIGINT",y);try{for(;b<i&&!D;){await No(f),b++;let g=await fetch(`${o}/cli/login/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({deviceCode:t})});if(g.status===202)continue;if(!g.ok){p.fail("Authorization failed");let I=await g.json();throw new Error(I.error||"Authorization failed")}let c=await g.json();if(c.status==="authorized"){p.succeed(l.white("Authorization successful!")),ao(c.token),uo(c.user),c.proxyUrl&&fo(c.proxyUrl),c.mem0ProxyUrl&&go(c.mem0ProxyUrl),console.log(""),console.log(l.gray(`User: ${c.user.email}`));let I=J("Fetching projects...").start(),x=await Ro(c.token);return I.succeed(`Fetched ${x.length} project${x.length!==1?"s":""}`),console.log(l.gray(`Session saved to: ~/.zibby/config.json
14
+ `)),{success:!0,loggedIn:!0,user:c.user,token:c.token}}if(c.status==="denied")throw p.fail("Authorization denied"),new Error("User denied authorization")}throw p.fail("Login timeout"),new Error("Login timed out - please try again")}finally{process.removeListener("SIGINT",y)}}function No(o){return new Promise(e=>setTimeout(e,o))}function mo(){try{let o=process.env.HOME||process.env.USERPROFILE;if(!o)return null;let e=Zo(o,".zibby","config.json");return Fo(e)&&JSON.parse(Yo(e,"utf-8")).sessionToken||null}catch{return null}}function M(){console.log(`
15
+ Not authenticated.`),console.log(` Run ${K.cyan("zibby login")} or set ${K.cyan("ZIBBY_API_KEY")} in your environment.
16
+ `)}async function bo(o={}){let e=o.apiKey||process.env.ZIBBY_API_KEY||null,n=mo();if(n||e)return{sessionToken:n,apiKey:e};if(!process.stdin.isTTY){if(o.optional)return{sessionToken:null,apiKey:null};M(),process.exit(1)}console.log(K.yellow(`
17
+ Not logged in.`));let t;try{t=await Jo({message:"Open browser to log in now?",default:!0})}catch{t=!1}if(!t){if(o.optional)return{sessionToken:null,apiKey:null};M(),process.exit(1)}if(await wo(),n=mo(),!n){if(o.optional)return{sessionToken:null,apiKey:null};M(),process.exit(1)}return{sessionToken:n,apiKey:null}}Ko.config();async function Wo({apiUrl:o,projectId:e,workflowName:n,buildId:t,authToken:h,spinner:a}){let s=Date.now(),d,u;for(;;){let p=new URL(`${o}/projects/${e}/workflows/${n}/build/${t}`);d&&p.searchParams.set("logsToken",d);let f;try{let i=await fetch(p,{headers:{Authorization:`Bearer ${h}`}});if(!i.ok)throw new Error(`HTTP ${i.status}`);f=await i.json()}catch{await new Promise(b=>setTimeout(b,2e3));continue}f.phase&&f.phase!==u&&(u=f.phase,a.text=`Building bundle on Zibby Cloud... (${u.toLowerCase()})`),f.nextLogsToken&&f.nextLogsToken!==d&&(d=f.nextLogsToken);for(let i of f.logEvents||[]){let b=String(i.m||"").trimEnd();b&&process.stdout.write(` ${b}
18
+ `)}if(f.done){let i=(Date.now()-s)/1e3;return{status:f.status,elapsedSec:i,lastPhase:u}}await new Promise(i=>setTimeout(i,2e3))}}async function Go(o,e){let n=B(),t=G("Fetching projects...").start();try{let h=e||o,a=await fetch(`${n}/projects`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${h}`}});a.ok||(t.fail("Failed to fetch projects"),process.exit(1));let s=await a.json();Array.isArray(s)||(s.projects&&Array.isArray(s.projects)?s=s.projects:s.data&&Array.isArray(s.data)?s=s.data:(t.fail("Unexpected response format"),process.exit(1))),(!s||s.length===0)&&(t.fail("No projects found"),process.exit(1)),t.succeed(`Found ${s.length} project${s.length===1?"":"s"}`),console.log("");let d=s.map(p=>{let f=p.projectId||p.id||p._id||"unknown";return{name:`${p.name||p.projectName||"Unnamed"} (${f})`,value:f}});return await ko({message:"Select a project to deploy to:",choices:d})}catch(h){t.fail(`Error: ${h.message}`),process.exit(1)}}async function Ze(o,e={}){let n=process.cwd(),t=".zibby/workflows";try{t=(await eo(n))?.paths?.workflows||".zibby/workflows"}catch{}if(o){let y=m(n,t,o);k(y)||(console.log(`
19
+ Error: Workflow not found: ${t}/${o}/`),console.log(" Run `zibby workflow list` to see local workflows,"),console.log(` or scaffold a new one: zibby workflow new ${o}
20
+ `),process.exit(1))}else{let y=m(n,t);k(y)||(console.log(`
21
+ Error: No workflows found in ${t}/`),console.log(` Create one with: zibby workflow new <name>
22
+ `),process.exit(1));let{readdir:g,stat:c}=await import("fs/promises"),I=await g(y),x=[];for(let $ of I){let v=m(y,$);if(!(await c(v)).isDirectory())continue;(k(m(v,"graph.mjs"))||k(m(v,"graph.js")))&&x.push($)}x.length===0&&(console.log(`
23
+ Error: No workflows found in ${t}/`),console.log(` Create one with: zibby workflow new <name>
24
+ `),process.exit(1)),console.log(""),o=await ko({message:"Select a workflow to deploy:",choices:x.map($=>({name:$,value:$}))})}let{sessionToken:h,apiKey:a}=await bo({apiKey:e.apiKey}),s=e.project||process.env.ZIBBY_PROJECT_ID;s||(console.log(""),s=await Go(a,h));let d=h||a,u=m(n,t,o),p=m(u,"graph.mjs"),f=m(u,"workflow.json");k(p)||(console.log(`
25
+ Error: graph.mjs not found in ${t}/${o}/`),process.exit(1)),console.log(`
11
26
  Deploying Workflow
12
- `),console.log(" ".padEnd(60,"-")),console.log(` Workflow: ${o}`),console.log(` Project: ${e}`),console.log(" ".padEnd(60,"-")),console.log("");let r=V("Validating workflow...").start(),z=P(g,"utf-8");if(z.includes("@zibby/core")||z.includes("@zibby/skills")){let s=i(h,"package.json");f(s)||(r.fail("Missing package.json"),console.log(""),console.log(d.red(" \u2717 graph.mjs imports @zibby packages but no package.json found")),console.log(""),console.log(d.yellow(" Create package.json with:")),console.log(""),console.log(d.gray(" {")),console.log(d.gray(' "type": "module",')),console.log(d.gray(' "dependencies": {')),console.log(d.gray(' "@zibby/core": "workspace:*"')),console.log(d.gray(" }")),console.log(d.gray(" }")),console.log(""),process.exit(1));let p=JSON.parse(P(s,"utf-8"));!{...p.dependencies,...p.devDependencies}["@zibby/core"]&&z.includes("@zibby/core")&&(r.fail("Missing @zibby/core dependency"),console.log(""),console.log(d.red(" \u2717 graph.mjs imports @zibby/core but it's not in package.json")),console.log(""),console.log(d.yellow(" Add to package.json dependencies:")),console.log(d.gray(' "@zibby/core": "workspace:*"')),console.log(""),process.exit(1))}r.text="Loading workflow graph...";try{let{pathToFileURL:s}=await import("url"),p=await import(s(g).href),m;if(p.default)if(typeof p.default=="function"){let t=p.default.prototype;t&&t.buildGraph?m=new p.default:m=p.default()}else r.fail("graph.mjs must export a class or factory function"),process.exit(1);else{let t=Object.values(p).find(w=>w.prototype&&w.prototype.buildGraph);t?m=new t:(r.fail("graph.mjs must export a WorkflowAgent class or factory function"),process.exit(1))}let j=m.buildGraph().serialize(),{readdir:k,readFile:y}=await import("fs/promises"),b={};r.text="Packaging workflow sources...";let L=await y(g,"utf-8");if(b["graph.mjs"]=L,f($)){let t=await y($,"utf-8");b["workflow.json"]=t}let A=i(h,"nodes");if(f(A)){let t=await k(A);for(let w of t)if(w.endsWith(".mjs")||w.endsWith(".js")){let X=i(A,w),oo=await y(X,"utf-8");b[`nodes/${w}`]=oo}}let T=i(h,"package.json");if(f(T)){let t=await y(T,"utf-8");b["package.json"]=t,r.text="Including package.json for dependencies..."}let S=i(h,"package-lock.json");if(f(S)){let t=await y(S,"utf-8");b["package-lock.json"]=t}r.text=`Uploading to cloud (${j.nodes.size||Object.keys(j.nodes||{}).length} nodes, ${Object.keys(b).length} files)...`;let N=O(),Y=JSON.stringify({format:1,sources:b}),Z=Buffer.byteLength(Y,"utf8"),_=await fetch(`${N}/projects/${e}/workflows/${o}/sources/presign`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${I}`},body:JSON.stringify({contentLength:Z})});if(!_.ok){let t=await _.json().catch(()=>({}));r.fail("Deploy failed (presign)"),console.log(` Error: ${t.error||t.message||_.statusText}
13
- `),process.exit(1)}let G=await _.json(),{uploadUrl:K,key:H,headers:q}=G,E=await fetch(K,{method:"PUT",headers:{...q||{},"Content-Length":String(Z)},body:Y});if(!E.ok){let t=await E.text().catch(()=>"");r.fail("Deploy failed (S3 upload)"),console.log(` S3 PUT failed: ${E.status} ${t.slice(0,200)}
14
- `),process.exit(1)}r.text="Saving workflow definition...";let x=await fetch(`${N}/projects/${e}/workflows/${o}`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${I}`},body:JSON.stringify({graph:j,sourcesStagingKey:H,isDefault:!1})});if(!x.ok){let t=await x.json().catch(()=>({}));r.fail("Deploy failed"),console.log(` Error: ${t.message||t.error||x.statusText}
15
- `),process.exit(1)}let R=await x.json(),B=i(h,".zibby-deploy.json"),C=f(B)?(()=>{try{return JSON.parse(P(B,"utf-8"))}catch{return null}})():null,U=M(R,C);if(U){let t=J({uuid:U,name:o,projectId:e,result:R,existingManifest:C});try{so(B,`${JSON.stringify(t,null,2)}
16
- `,"utf-8")}catch(w){console.log(` Warning: failed to write ${B}: ${w.message}`)}}let Q=C?"Updated":"Deployed";r.succeed(`${Q} ${o} (v${R.version||1})`),console.log(""),U&&console.log(` UUID: ${U}`),console.log(""),console.log(" Next steps:"),console.log(` zibby start ${o} Run locally`),U&&console.log(` zibby trigger ${U} Run in cloud`),console.log(" zibby workflow list View all workflows"),console.log("")}catch(s){r.fail("Deploy failed"),console.log(` Error: ${s.message}
17
- `),process.exit(1)}}export{vo as deployWorkflowCommand};
27
+ `),console.log(" ".padEnd(60,"-")),console.log(` Workflow: ${o}`),console.log(` Project: ${s}`),console.log(" ".padEnd(60,"-")),console.log("");let i=G("Validating workflow...").start(),b=W(p,"utf-8");if(b.includes("@zibby/core")||b.includes("@zibby/skills")){let y=m(u,"package.json");k(y)||(i.fail("Missing package.json"),console.log(""),console.log(j.red(" \u2717 graph.mjs imports @zibby packages but no package.json found")),console.log(""),console.log(j.yellow(" Create package.json with:")),console.log(""),console.log(j.gray(" {")),console.log(j.gray(' "type": "module",')),console.log(j.gray(' "dependencies": {')),console.log(j.gray(' "@zibby/core": "workspace:*"')),console.log(j.gray(" }")),console.log(j.gray(" }")),console.log(""),process.exit(1));let g=JSON.parse(W(y,"utf-8"));!{...g.dependencies,...g.devDependencies}["@zibby/core"]&&b.includes("@zibby/core")&&(i.fail("Missing @zibby/core dependency"),console.log(""),console.log(j.red(" \u2717 graph.mjs imports @zibby/core but it's not in package.json")),console.log(""),console.log(j.yellow(" Add to package.json dependencies:")),console.log(j.gray(' "@zibby/core": "workspace:*"')),console.log(""),process.exit(1))}i.text="Loading workflow graph...";try{let{pathToFileURL:y}=await import("url"),g=await import(y(p).href),c;if(g.default)if(typeof g.default=="function"){let r=g.default.prototype;r&&r.buildGraph?c=new g.default:c=g.default()}else i.fail("graph.mjs must export a class or factory function"),process.exit(1);else{let r=Object.values(g).find(w=>w.prototype&&w.prototype.buildGraph);r?c=new r:(i.fail("graph.mjs must export a WorkflowAgent class or factory function"),process.exit(1))}let x=c.buildGraph().serialize(),{readdir:$,readFile:v}=await import("fs/promises"),U={};i.text="Packaging workflow sources...";let V=await v(p,"utf-8");if(U["graph.mjs"]=V,k(f)){let r=await v(f,"utf-8");U["workflow.json"]=r}let R=m(u,"nodes");if(k(R)){let r=await $(R);for(let w of r)if(w.endsWith(".mjs")||w.endsWith(".js")){let P=m(R,w),Z=await v(P,"utf-8");U[`nodes/${w}`]=Z}}let H=m(u,"package.json");if(k(H)){let r=await v(H,"utf-8");U["package.json"]=r,i.text="Including package.json for dependencies..."}let q=m(u,"package-lock.json");if(k(q)){let r=await v(q,"utf-8");U["package-lock.json"]=r}i.text=`Uploading to cloud (${x.nodes.size||Object.keys(x.nodes||{}).length} nodes, ${Object.keys(U).length} files)...`;let z=B(),X=JSON.stringify({format:1,sources:U}),Q=Buffer.byteLength(X,"utf8"),_=await fetch(`${z}/projects/${s}/workflows/${o}/sources/presign`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${d}`},body:JSON.stringify({contentLength:Q})});if(!_.ok){let r=await _.json().catch(()=>({}));i.fail("Deploy failed (presign)"),console.log(` Error: ${r.error||r.message||_.statusText}
28
+ `),process.exit(1)}let jo=await _.json(),{uploadUrl:xo,key:vo,headers:Uo}=jo,N=await fetch(xo,{method:"PUT",headers:{...Uo||{},"Content-Length":String(Q)},body:X});if(!N.ok){let r=await N.text().catch(()=>"");i.fail("Deploy failed (S3 upload)"),console.log(` S3 PUT failed: ${N.status} ${r.slice(0,200)}
29
+ `),process.exit(1)}i.text="Saving workflow definition...";let E=await fetch(`${z}/projects/${s}/workflows/${o}`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${d}`},body:JSON.stringify({graph:x,sourcesStagingKey:vo,isDefault:!1})});if(!E.ok){let r=await E.json().catch(()=>({}));i.fail("Deploy failed"),console.log(` Error: ${r.message||r.error||E.statusText}
30
+ `),process.exit(1)}let F=await E.json(),L=m(u,".zibby-deploy.json"),Y=k(L)?(()=>{try{return JSON.parse(W(L,"utf-8"))}catch{return null}})():null,T=no(F,Y);if(T){let r=to({uuid:T,name:o,projectId:s,result:F,existingManifest:Y});try{Mo(L,`${JSON.stringify(r,null,2)}
31
+ `,"utf-8")}catch(w){console.log(` Warning: failed to write ${L}: ${w.message}`)}}let $o=Y?"Updated":"Deployed";if(i.succeed(`${$o} ${o} (v${F.version||1})`),!(e.noWait===!0||process.env.ZIBBY_DEPLOY_NO_BUNDLE==="1")){console.log("");let r=G("Building bundle on Zibby Cloud...").start();try{let w=await fetch(`${z}/projects/${s}/workflows/${o}/build`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${d}`}});if(w.ok){let P=await w.json(),{buildId:Z}=P,{status:oo,elapsedSec:So,lastPhase:Io}=await Wo({apiUrl:z,projectId:s,workflowName:o,buildId:Z,authToken:d,spinner:r});oo==="SUCCEEDED"?r.succeed(`Bundle ready (${So.toFixed(1)}s) \u2014 runtime npm install eliminated`):r.warn(`Bundle build ${oo} at phase ${Io||"unknown"} \u2014 workflow will fall back to runtime install`)}else{let P=await w.json().catch(()=>({}));r.warn(`Bundle build skipped: ${P.error||P.message||w.statusText}`),console.log(` Workflow will use slower runtime install path until next deploy.
32
+ `)}}catch(w){r.warn(`Bundle build error: ${w.message}`)}}console.log(""),T&&console.log(` UUID: ${T}`),console.log(""),console.log(" Next steps:"),console.log(` zibby workflow start ${o} Run locally`),T&&console.log(` zibby workflow trigger ${T} Run in cloud`),console.log(" zibby workflow list View all workflows"),console.log("")}catch(y){i.fail("Deploy failed"),console.log(` Error: ${y.message}
33
+ `),process.exit(1)}}export{Ze as deployWorkflowCommand};
@@ -1,4 +1,4 @@
1
- import{mkdir as f,writeFile as d}from"fs/promises";import{existsSync as y}from"fs";import{join as a}from"path";import t from"chalk";import E from"ora";import{existsSync as x}from"fs";import{join as v}from"path";import{pathToFileURL as I}from"url";async function g(o){let e=v(o,".zibby.config.mjs");if(!x(e))throw new Error(".zibby.config.mjs not found");try{let s=await import(I(e).href);return s.default||s}catch(s){throw new Error(`Failed to load .zibby.config.mjs: ${s.message}`,{cause:s})}}import{mkdir as ee,writeFile as te,readFile as oe}from"fs/promises";import{existsSync as se,readdirSync as ie}from"fs";import{join as re,resolve as le,dirname as A}from"path";import{homedir as de}from"os";import me from"inquirer";import ue from"chalk";import ye from"ora";import{spawn as be,execSync as we}from"child_process";import{fileURLToPath as C}from"url";import{createRequire as k}from"module";import{existsSync as L,readFileSync as D,writeFileSync as Z,mkdirSync as G}from"fs";import{join as W}from"path";import{homedir as F}from"os";var P=C(import.meta.url),Ae=A(P),Ce=k(import.meta.url);function u(o,e={},s={}){let i=["dolt","mem0"].includes(String(s.memoryBackend||"").toLowerCase())?String(s.memoryBackend).toLowerCase():"dolt",r={claude:`
1
+ import{mkdir as v,writeFile as p}from"fs/promises";import{existsSync as k}from"fs";import{spawn as M}from"child_process";import{join as c}from"path";import t from"chalk";import I from"ora";import{input as j}from"@inquirer/prompts";import{existsSync as P}from"fs";import{join as E}from"path";import{pathToFileURL as $}from"url";async function b(o){let n=E(o,".zibby.config.mjs");if(!P(n))throw new Error(".zibby.config.mjs not found");try{let e=await import($(n).href);return e.default||e}catch(e){throw new Error(`Failed to load .zibby.config.mjs: ${e.message}`,{cause:e})}}import{mkdir as le,writeFile as ce,readFile as de}from"fs/promises";import{existsSync as me,readdirSync as ge}from"fs";import{join as fe,resolve as ye,dirname as _}from"path";import{homedir as we}from"os";import xe from"inquirer";import ke from"chalk";import Ae from"ora";import{spawn as Pe,execSync as Ee}from"child_process";import{fileURLToPath as S}from"url";import{createRequire as z}from"module";import{existsSync as U,readFileSync as q,writeFileSync as J,mkdirSync as X}from"fs";import{join as ee}from"path";import{homedir as oe}from"os";var K=S(import.meta.url),ze=_(K),Ke=z(import.meta.url);function x(o,n={},e={}){let r=["dolt","mem0"].includes(String(e.memoryBackend||"").toLowerCase())?String(e.memoryBackend).toLowerCase():"dolt",l={claude:`
2
2
  claude: {
3
3
  model: 'auto', // Options: 'auto', 'sonnet-4.6', 'opus-4.6', 'sonnet-4.5', 'opus-4.5'
4
4
  maxTokens: 4096,
@@ -11,13 +11,13 @@ import{mkdir as f,writeFile as d}from"fs/promises";import{existsSync as y}from"f
11
11
  },`,gemini:`
12
12
  gemini: {
13
13
  model: 'gemini-2.5-pro', // Options: 'auto', 'gemini-2.5-pro', 'gemini-2.5-flash'
14
- },`},l=o.agent,p=Object.entries(r).filter(([c])=>c!==l).map(([,c])=>c.split(`
15
- `).map(n=>n.trim()?` // ${n.trimStart()}`:n).join(`
14
+ },`},m=o.agent,s=Object.entries(l).filter(([i])=>i!==m).map(([,i])=>i.split(`
15
+ `).map(d=>d.trim()?` // ${d.trimStart()}`:d).join(`
16
16
  `)).join(`
17
17
  `);return`export default {
18
18
  // AI agent settings
19
- agent: {${r[l]}
20
- ${p}
19
+ agent: {${l[m]}
20
+ ${s}
21
21
  strictMode: false,
22
22
  },
23
23
 
@@ -30,7 +30,7 @@ ${p}
30
30
 
31
31
  // Chat memory backend adapter (dolt | mem0)
32
32
  memory: {
33
- backend: '${i}',
33
+ backend: '${r}',
34
34
  },
35
35
 
36
36
  // Advanced: Override models per node (optional)
@@ -44,7 +44,7 @@ ${p}
44
44
  specs: 'test-specs', // Where your .txt test specs are
45
45
  generated: 'tests', // Where generated .spec.js files go
46
46
  output: '.zibby/output', // Where workflow execution results are saved (default: .zibby/output)
47
- workflows: '.zibby/workflows', // Where custom workflows are stored
47
+ workflows: '${o.workflowsPath||".zibby/workflows"}', // Where custom workflows are stored
48
48
  // sessionPrefix: 'run', // Optional: prefix for session folders (e.g., run_1772788458045)
49
49
  },
50
50
 
@@ -81,7 +81,7 @@ ${p}
81
81
  // Cloud sync - auto-upload test results & videos (requires ZIBBY_API_KEY in .env)
82
82
  cloudSync: ${o.cloudSync||!1}
83
83
  };
84
- `}var _=/^[a-z][a-z0-9-]{0,62}[a-z0-9]$/,h=["stellar","quantum","cosmic","nova","nebula","solar","lunar","atomic","plasma","fusion","pulse","flux","spark","blaze","ember","radiant","luminous","electric","magnetic","kinetic","neon","cyber","pixel","matrix","vector","synth","neural","prism","zenith","phoenix","catalyst","nexus","echo","wave","crystal","jade","ruby","emerald","onyx","amber","silver","turbo","lightning","thunder","storm","arcane","mystic","ethereal","celestial","swift","crimson","iron","cobalt"],b=["flow","runner","pipeline","stream","circuit","engine","beacon","forge","relay","shuttle","conduit","gateway","sentinel","scout","pilot","voyager","ranger","dispatch","signal","pulse","agent","daemon","spark","orbit","vector","nexus","matrix","grid","mesh","bridge","link","node","craft","bolt","ray","arc","wave","hook","probe","shard"];function $(){let o=h[Math.floor(Math.random()*h.length)],e=b[Math.floor(Math.random()*b.length)];return`${o}-${e}`}function S(o){return`${o.split("-").map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join("")}Workflow`}function z(o,e){return`/**
84
+ `}function B(o){return new Promise(n=>{let e=M("npm",["install","--no-audit","--no-fund"],{cwd:o,stdio:"pipe",shell:!1}),r="";e.stderr.on("data",l=>{r+=l.toString()}),e.on("error",()=>n({ok:!1,stderr:"npm not found on PATH"})),e.on("close",l=>n({ok:l===0,stderr:r}))})}var T=/^[a-z][a-z0-9-]{0,62}[a-z0-9]$/,A=["stellar","quantum","cosmic","nova","nebula","solar","lunar","atomic","plasma","fusion","pulse","flux","spark","blaze","ember","radiant","luminous","electric","magnetic","kinetic","neon","cyber","pixel","matrix","vector","synth","neural","prism","zenith","phoenix","catalyst","nexus","echo","wave","crystal","jade","ruby","emerald","onyx","amber","silver","turbo","lightning","thunder","storm","arcane","mystic","ethereal","celestial","swift","crimson","iron","cobalt"],C=["flow","runner","pipeline","stream","circuit","engine","beacon","forge","relay","shuttle","conduit","gateway","sentinel","scout","pilot","voyager","ranger","dispatch","signal","pulse","agent","daemon","spark","orbit","vector","nexus","matrix","grid","mesh","bridge","link","node","craft","bolt","ray","arc","wave","hook","probe","shard"];function Y(){let o=A[Math.floor(Math.random()*A.length)],n=C[Math.floor(Math.random()*C.length)];return`${o}-${n}`}function R(o){return`${o.split("-").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join("")}Workflow`}function O(o,n){return`/**
85
85
  * ${o}
86
86
  *
87
87
  * buildGraph() \u2014 define nodes, edges, conditional routing
@@ -104,11 +104,11 @@ export class ${o} extends WorkflowAgent {
104
104
  }
105
105
 
106
106
  async onComplete(result) {
107
- console.log(\`[${e}] workflow complete \u2014 success: \${result.success !== false}\`);
107
+ console.log(\`[${n}] workflow complete \u2014 success: \${result.success !== false}\`);
108
108
  }
109
109
  }
110
- `}function K(){return`export { exampleNode } from './example.mjs';
111
- `}function M(){return`import { z } from '@zibby/core';
110
+ `}function N(){return`export { exampleNode } from './example.mjs';
111
+ `}function L(){return`import { z } from '@zibby/core';
112
112
 
113
113
  const ExampleOutputSchema = z.object({
114
114
  summary: z.string().describe('A short summary of the result'),
@@ -127,16 +127,19 @@ Analyze the input and return a summary with a status.\`,
127
127
 
128
128
  outputSchema: ExampleOutputSchema,
129
129
  };
130
- `}function j(o,e){return`${JSON.stringify({name:o,description:`${e} workflow`,entryClass:e,triggers:{api:!0}},null,2)}
131
- `}function B(){return`${JSON.stringify({type:"module",dependencies:{"@zibby/core":"^0.1.33"}},null,2)}
132
- `}async function Me(o){let e;o?e=o.toLowerCase():(e=$(),console.log(t.gray(`
133
- No name provided \u2014 generated: ${t.white(e)}`))),_.test(e)||(console.log(t.red(`
130
+ `}function D(o,n){return`${JSON.stringify({name:o,description:`${n} workflow`,entryClass:n,triggers:{api:!0}},null,2)}
131
+ `}function Z(){return`${JSON.stringify({type:"module",dependencies:{"@zibby/core":"^0.1.44"}},null,2)}
132
+ `}async function Ze(o,n={}){let e;o?e=o.toLowerCase():(e=Y(),console.log(t.gray(`
133
+ No name provided \u2014 generated: ${t.white(e)}`))),T.test(e)||(console.log(t.red(`
134
134
  Invalid workflow name: "${o}"`)),console.log(t.gray(" Must be lowercase, start with a letter, use only a-z, 0-9, hyphens")),console.log(t.gray(" Length: 2\u201364 characters")),console.log(t.gray(` Example: ticket-triage, pr-review, deploy-checker
135
- `)),process.exit(1));let s=process.cwd(),i=".zibby/workflows";try{let n=await g(s);n?.paths?.workflows&&(i=n.paths.workflows)}catch(n){n?.message?.includes("not found")||(console.log(t.yellow(` \u26A0\uFE0F Could not load .zibby.config.mjs: ${n.message}`)),console.log(t.gray(` Using default path: ${i}`)))}let r=a(s,i,e),l=a(r,"nodes");y(r)&&(console.log(t.red(`
136
- Workflow already exists: ${i}/${e}/`)),console.log(t.gray(` Choose a different name or delete the existing folder.
137
- `)),process.exit(1));let p=S(e),c=E(` Scaffolding workflow "${e}"...`).start();try{await f(a(s,i),{recursive:!0}),await f(l,{recursive:!0}),await Promise.all([d(a(r,"graph.mjs"),z(p,e)),d(a(l,"index.mjs"),K()),d(a(l,"example.mjs"),M()),d(a(r,"workflow.json"),j(e,p)),d(a(r,"package.json"),B())]);let n=a(s,".zibby.config.mjs"),m=!1;if(!y(n)){let w=u({agent:"claude",browserMode:"headless"},{},{memoryBackend:"dolt"});await d(n,w),m=!0}c.succeed(` Scaffolded ${t.bold(e)}`),console.log(t.green(`
138
- Created:`)),console.log(t.white(` ${i}/${e}/`)),console.log(t.gray(` graph.mjs ${p} (entry)`)),console.log(t.gray(" nodes/index.mjs barrel export")),console.log(t.gray(" nodes/example.mjs starter node (prompt + schema)")),console.log(t.gray(" workflow.json manifest")),console.log(t.gray(" package.json dependencies (@zibby/core)")),m&&console.log(t.white(" .zibby.config.mjs project config (agent: claude \u2014 edit to switch)")),console.log(t.white(`
139
- Next steps:`)),console.log(t.cyan(` 1. Edit nodes in ${i}/${e}/nodes/`)),console.log(t.cyan(" 2. Wire them in graph.mjs")),console.log(t.cyan(" 3. Test locally:")),console.log(t.cyan(` zibby start ${e}`)),console.log(t.cyan(" 4. Deploy to cloud:")),console.log(t.cyan(` zibby deploy ${e}
140
- `))}catch(n){c.fail(" Scaffold failed"),console.log(t.red(`
141
- ${n.message}
142
- `)),process.exit(1)}}export{Me as generateWorkflowCommand};
135
+ `)),process.exit(1));let r=process.cwd(),l=c(r,".zibby.config.mjs"),m=k(l),s=".zibby/workflows";if(m)try{let a=await b(r);a?.paths?.workflows&&(s=a.paths.workflows)}catch(a){console.log(t.yellow(` \u26A0\uFE0F Could not load .zibby.config.mjs: ${a.message}`)),console.log(t.gray(` Using default path: ${s}`))}else if(process.stdin.isTTY){console.log(t.gray(`
136
+ Common picks: ${t.white(".zibby/workflows")} (hidden, default) \xB7 ${t.white("workflows")} (visible at project root)
137
+ `));let g=(await j({message:`Where to save workflows? ${t.gray("[Enter for .zibby/workflows]")}`})).trim();s=g===""?".zibby/workflows":g}else console.log(t.gray(` Using default workflows path: ${s} (run interactively to customize)`));let i=c(r,s,e),d=c(i,"nodes");k(i)&&(console.log(t.red(`
138
+ Workflow already exists: ${s}/${e}/`)),console.log(t.gray(` Choose a different name or delete the existing folder.
139
+ `)),process.exit(1));let y=R(e),h=I(` Scaffolding workflow "${e}"...`).start();try{await v(c(r,s),{recursive:!0}),await v(d,{recursive:!0}),await Promise.all([p(c(i,"graph.mjs"),O(y,e)),p(c(d,"index.mjs"),N()),p(c(d,"example.mjs"),L()),p(c(i,"workflow.json"),D(e,y)),p(c(i,"package.json"),Z())]);let a=!1;if(!m){let f=x({agent:"claude",browserMode:"headless",workflowsPath:s},{},{memoryBackend:"dolt"});await p(l,f),a=!0}h.succeed(` Scaffolded ${t.bold(e)}`),console.log(t.green(`
140
+ Created:`)),console.log(t.white(` ${s}/${e}/`)),console.log(t.gray(` graph.mjs ${y} (entry)`)),console.log(t.gray(" nodes/index.mjs barrel export")),console.log(t.gray(" nodes/example.mjs starter node (prompt + schema)")),console.log(t.gray(" workflow.json manifest")),console.log(t.gray(" package.json dependencies (@zibby/core)")),a&&console.log(t.white(" .zibby.config.mjs project config (agent: claude \u2014 edit to switch)"));let g=!1;if(n.skipInstall)console.log(t.gray(` Skipped npm install (--skip-install). Run manually: cd ${s}/${e} && npm install`));else{let f=I({text:` Installing dependencies in ${s}/${e}/...`,prefixText:""}).start(),w=await B(i);w.ok?(f.succeed(` Installed dependencies in ${s}/${e}/`),g=!0):(f.warn(` Could not install dependencies (${w.stderr.trim().split(`
141
+ `)[0]||"unknown error"})`),console.log(t.gray(` Run manually: cd ${s}/${e} && npm install`)))}console.log(t.white(`
142
+ Next steps:`));let u=1;!g&&n.skipInstall!==!0&&console.log(t.cyan(` ${u++}. Install deps: cd ${s}/${e} && npm install`)),console.log(t.cyan(` ${u++}. Edit nodes in ${s}/${e}/nodes/`)),console.log(t.cyan(` ${u++}. Wire them in graph.mjs`)),console.log(t.cyan(` ${u++}. Test locally: zibby workflow start ${e}`)),console.log(t.cyan(` ${u++}. Deploy to cloud: zibby workflow deploy ${e}
143
+ `))}catch(a){h.fail(" Scaffold failed"),console.log(t.red(`
144
+ ${a.message}
145
+ `)),process.exit(1)}}export{Ze as generateWorkflowCommand};
@@ -1,19 +1,35 @@
1
- import{readdir as A,stat as z}from"fs/promises";import{existsSync as w}from"fs";import{join as g}from"path";import n from"chalk";import L from"dotenv";import{existsSync as j}from"fs";import{join as B}from"path";import{pathToFileURL as N}from"url";async function b(e){let r=B(e,".zibby.config.mjs");if(!j(r))throw new Error(".zibby.config.mjs not found");try{let t=await import(N(r).href);return t.default||t}catch(t){throw new Error(`Failed to load .zibby.config.mjs: ${t.message}`,{cause:t})}}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 I(){let e;if(process.env.ZIBBY_API_URL)e=process.env.ZIBBY_API_URL;else{let r=process.env.ZIBBY_ENV||"prod";u[r]?e=u[r].apiUrl:e=u.prod.apiUrl}try{let r=new URL(e);return r.protocol!=="http:"&&r.protocol!=="https:"?(console.error(`\u26A0\uFE0F Invalid API URL protocol: ${r.protocol} (only http/https allowed)`),u.prod.apiUrl):e}catch{return console.error(`\u26A0\uFE0F Invalid API URL: ${e}`),u.prod.apiUrl}}import{existsSync as x,mkdirSync as W,readFileSync as P,writeFileSync as M}from"fs";import{homedir as _}from"os";import{join as y}from"path";function $(){return process.env.ZIBBY_CONFIG_DIR||y(_(),".zibby")}function T(){return y($(),"config.json")}var C=y(_(),".zibby"),q=y(C,"config.json");function R(){try{let e=T();if(x(e)){let r=P(e,"utf-8");return JSON.parse(r)}}catch{}return{}}function k(){return R().sessionToken||null}L.config();async function D(e={}){let r=process.cwd(),t=".zibby/workflows";try{t=(await b(r))?.paths?.workflows||".zibby/workflows"}catch{}let d=g(r,t);if(!w(d))return e.quiet?[]:(console.log(n.yellow(`
2
- No workflows found in ${t}/`)),console.log(n.gray(` Create one with: zibby g workflow <name>
3
- `)),[]);try{let a=await A(d),l=[];for(let s of a){let i=g(d,s);if(!(await z(i)).isDirectory())continue;let c=w(g(i,"graph.mjs"))||w(g(i,"graph.js")),f=w(g(i,"workflow.json"));!c&&!f||l.push({name:s,hasGraph:c,hasManifest:f,path:`${t}/${s}`,source:"local"})}if(e.quiet)return l;if(l.length===0)return console.log(n.yellow(`
4
- No workflows found in ${t}/`)),console.log(n.gray(` Create one with: zibby g workflow <name>
5
- `)),[];console.log(n.bold.cyan(`
1
+ import{readdir as wo,stat as ho}from"fs/promises";import{existsSync as P}from"fs";import{join as S}from"path";import r from"chalk";import ko from"dotenv";import{existsSync as Q}from"fs";import{join as oo}from"path";import{pathToFileURL as eo}from"url";async function C(o){let e=oo(o,".zibby.config.mjs");if(!Q(e))throw new Error(".zibby.config.mjs not found");try{let t=await import(eo(e).href);return t.default||t}catch(t){throw new Error(`Failed to load .zibby.config.mjs: ${t.message}`,{cause:t})}}var j={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 I(){let o;if(process.env.ZIBBY_API_URL)o=process.env.ZIBBY_API_URL;else{let e=process.env.ZIBBY_ENV||"prod";j[e]?o=j[e].apiUrl:o=j.prod.apiUrl}try{let e=new URL(o);return e.protocol!=="http:"&&e.protocol!=="https:"?(console.error(`\u26A0\uFE0F Invalid API URL protocol: ${e.protocol} (only http/https allowed)`),j.prod.apiUrl):o}catch{return console.error(`\u26A0\uFE0F Invalid API URL: ${o}`),j.prod.apiUrl}}import{existsSync as fo,readFileSync as go}from"fs";import{join as yo}from"path";import N from"chalk";import{confirm as mo}from"@inquirer/prompts";import s from"chalk";import _ from"ora";import{spawn as lo}from"child_process";import{existsSync as E,mkdirSync as no,readFileSync as to,writeFileSync as ro}from"fs";import{homedir as R}from"os";import{join as A}from"path";function L(){return process.env.ZIBBY_CONFIG_DIR||A(R(),".zibby")}function O(){return A(L(),"config.json")}var so=A(R(),".zibby"),Ao=A(so,"config.json");function io(){let o=L();E(o)||no(o,{recursive:!0})}function b(){try{let o=O();if(E(o)){let e=to(o,"utf-8");return JSON.parse(e)}}catch{}return{}}function U(o){io(),ro(O(),JSON.stringify(o,null,2))}function D(){return b().sessionToken||null}function Y(o){let e=b();e.sessionToken=o,U(e)}function F(){return b().user||null}function Z(o){let e=b();e.user=o,U(e)}function K(o){let e=b();e.proxyUrl=o,U(e)}function M(o){let e=b();e.mem0ProxyUrl=o,U(e)}function J(o){let e=b();e.projects=o,U(e)}import{existsSync as zo,mkdirSync as No,readFileSync as Bo,writeFileSync as Co,unlinkSync as Eo}from"fs";import{resolve as Lo}from"path";import{homedir as Do}from"os";function co(o){let e=process.platform;try{let t,l;return e==="darwin"?(t="open",l=[o]):e==="win32"?(t="cmd",l=["/c","start","",o]):(t="xdg-open",l=[o]),lo(t,l,{detached:!0,stdio:"ignore"}).unref(),!0}catch{return!1}}function ao(){let o=D(),e=F();return o&&e?{loggedIn:!0,user:e,token:o}:{loggedIn:!1}}async function W(){try{console.log(s.cyan(`
2
+ \u{1F510} Initiating login...
3
+ `));let o=ao();if(o.loggedIn){console.log(s.green("\u2705 Already logged in!")),console.log(s.gray(`User: ${o.user.email}`)),console.log(s.gray(`Name: ${o.user.name}
4
+ `));let{createInterface:e}=await import("readline"),t=e({input:process.stdin,output:process.stdout});return new Promise((l,u)=>{let i=()=>{t.close(),process.stdin.isTTY&&process.stdin.setRawMode(!1)},c=()=>{console.log(s.yellow(`
5
+
6
+ \u26A0\uFE0F Login cancelled
7
+ `)),i(),process.exit(0)};process.on("SIGINT",c),t.question(s.yellow("Continue with this session? (Y/n): "),async a=>{process.removeListener("SIGINT",c),i();try{if(a.toLowerCase()==="n"||a.toLowerCase()==="no"){console.log(s.gray(`Starting new login...
8
+ `));let y=await V();l(y)}else console.log(s.green(`Using existing session.
9
+ `)),l({success:!0,...o})}catch(y){u(y)}})})}return await V()}catch(o){return console.error(s.red(`
10
+ \u274C Login failed:`,o.message)),{success:!1,error:o.message}}}async function uo(o){let e=I();try{let t=await fetch(`${e}/projects`,{headers:{Authorization:`Bearer ${o}`}});if(t.ok){let u=((await t.json()).projects||[]).map(i=>({name:i.name,projectId:i.projectId,apiToken:i.apiToken}));return J(u),u}}catch(t){console.log(s.gray(`\u26A0\uFE0F Could not fetch projects: ${t.message}`))}return[]}async function V(){let o=I(),e=_("Requesting login code...").start(),t=await fetch(`${o}/cli/login/initiate`,{method:"POST",headers:{"Content-Type":"application/json"}});if(!t.ok){e.fail("Failed to request login code");let m=await t.json();throw new Error(m.error||"Failed to initiate login")}let{deviceCode:l,userCode:u,verificationUrl:i,expiresIn:c,interval:a}=await t.json();e.succeed("Login code generated"),console.log(""),console.log(s.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")),console.log(s.cyan("\u2551")+s.white.bold(" Complete login in your browser ")+s.cyan("\u2551")),console.log(s.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")),console.log(""),console.log(s.white("Opening browser to login page...")),console.log(s.gray(`Code expires in ${Math.floor(c/60)} minutes`)),console.log(""),await co(i)||(console.log(s.yellow("\u26A0\uFE0F Could not open browser automatically.")),console.log(s.white("Please open this URL manually: ")+s.blue(i)),console.log(""));let f=_("Waiting for authorization...").start(),g=(a||3)*1e3,w=Math.floor(c/(a||3)),T=0,x=!1,$=()=>{x=!0,f.stop(),console.log(s.yellow(`
11
+
12
+ \u26A0\uFE0F Login cancelled
13
+ `)),process.exit(0)};process.on("SIGINT",$);try{for(;T<w&&!x;){await po(g),T++;let m=await fetch(`${o}/cli/login/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({deviceCode:l})});if(m.status===202)continue;if(!m.ok){f.fail("Authorization failed");let p=await m.json();throw new Error(p.error||"Authorization failed")}let n=await m.json();if(n.status==="authorized"){f.succeed(s.white("Authorization successful!")),Y(n.token),Z(n.user),n.proxyUrl&&K(n.proxyUrl),n.mem0ProxyUrl&&M(n.mem0ProxyUrl),console.log(""),console.log(s.gray(`User: ${n.user.email}`));let p=_("Fetching projects...").start(),d=await uo(n.token);return p.succeed(`Fetched ${d.length} project${d.length!==1?"s":""}`),console.log(s.gray(`Session saved to: ~/.zibby/config.json
14
+ `)),{success:!0,loggedIn:!0,user:n.user,token:n.token}}if(n.status==="denied")throw f.fail("Authorization denied"),new Error("User denied authorization")}throw f.fail("Login timeout"),new Error("Login timed out - please try again")}finally{process.removeListener("SIGINT",$)}}function po(o){return new Promise(e=>setTimeout(e,o))}function G(){try{let o=process.env.HOME||process.env.USERPROFILE;if(!o)return null;let e=yo(o,".zibby","config.json");return fo(e)&&JSON.parse(go(e,"utf-8")).sessionToken||null}catch{return null}}function z(){console.log(`
15
+ Not authenticated.`),console.log(` Run ${N.cyan("zibby login")} or set ${N.cyan("ZIBBY_API_KEY")} in your environment.
16
+ `)}async function q(o={}){let e=o.apiKey||process.env.ZIBBY_API_KEY||null,t=G();if(t||e)return{sessionToken:t,apiKey:e};if(!process.stdin.isTTY){if(o.optional)return{sessionToken:null,apiKey:null};z(),process.exit(1)}console.log(N.yellow(`
17
+ Not logged in.`));let l;try{l=await mo({message:"Open browser to log in now?",default:!0})}catch{l=!1}if(!l){if(o.optional)return{sessionToken:null,apiKey:null};z(),process.exit(1)}if(await W(),t=G(),!t){if(o.optional)return{sessionToken:null,apiKey:null};z(),process.exit(1)}return{sessionToken:t,apiKey:null}}ko.config();async function bo(o={}){let e=process.cwd(),t=".zibby/workflows";try{t=(await C(e))?.paths?.workflows||".zibby/workflows"}catch{}let l=S(e,t);if(!P(l))return o.quiet?[]:(console.log(r.yellow(`
18
+ No workflows found in ${t}/`)),console.log(r.gray(` Create one with: zibby workflow new <name>
19
+ `)),[]);try{let u=await wo(l),i=[];for(let c of u){let a=S(l,c);if(!(await ho(a)).isDirectory())continue;let f=P(S(a,"graph.mjs"))||P(S(a,"graph.js")),g=P(S(a,"workflow.json"));!f&&!g||i.push({name:c,hasGraph:f,hasManifest:g,path:`${t}/${c}`,source:"local"})}if(o.quiet)return i;if(i.length===0)return console.log(r.yellow(`
20
+ No workflows found in ${t}/`)),console.log(r.gray(` Create one with: zibby workflow new <name>
21
+ `)),[];console.log(r.bold.cyan(`
6
22
  Local Workflows (${t})
7
- `)),console.log(n.gray(" ".padEnd(60,"-"))),console.log(n.white(" Name".padEnd(35))+n.white("Files".padEnd(25))),console.log(n.gray(" ".padEnd(60,"-")));for(let s of l){let i=[];s.hasGraph&&i.push("graph"),s.hasManifest&&i.push("manifest"),console.log(` ${n.cyan(s.name.padEnd(33))}${n.gray(i.join(", "))}`)}return console.log(n.gray(" ".padEnd(60,"-"))),console.log(n.gray(`
8
- Total: ${l.length} workflow${l.length===1?"":"s"}
9
- `)),console.log(n.white(" Commands:")),console.log(n.cyan(" zibby start <name> ")+n.gray("Test locally")),console.log(n.cyan(" zibby deploy <name> ")+n.gray("Deploy to cloud")),console.log(n.cyan(" zibby trigger <name> ")+n.gray("Run workflow (returns job ID)")),console.log(n.cyan(" zibby logs <jobId> ")+n.gray("Tail execution logs")),console.log(""),l}catch(a){if(e.quiet)return[];console.log(n.red(`
10
- Error reading workflows: ${a.message}
11
- `)),process.exit(1)}}async function so(e={}){let r=await D({...e,quiet:!0}),t=[],d=k(),a=e.apiKey||process.env.ZIBBY_API_KEY,l=d||a;if(l)try{let o=I(),c=await fetch(`${o}/projects`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`}});if(c.ok){let h=(await c.json()).projects||[];for(let m of h){let U=await fetch(`${o}/projects/${m.projectId}/workflows`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`}});if(U.ok){let v=await U.json(),E=["analysis","implementation","run_test"];for(let p of v)E.includes(p.workflowType)||t.push({uuid:p.uuid,name:p.workflowType,projectId:m.projectId,projectName:m.name||m.projectId,version:p.version||0,nodes:p.graphJson?JSON.parse(p.graphJson).nodes?.length:0,updatedAt:p.updatedAt||null,source:"remote"})}}}}catch{}let s=[],i=new Map(r.map(o=>[o.name,o]));for(let o of t){let c=i.has(o.name);s.push({uuid:o.uuid,name:o.name,project:o.projectName,source:c?"local+remote":"remote",nodes:o.nodes,version:o.version,hasLocal:c})}for(let[o,c]of i.entries())t.some(h=>h.name===o)||s.push({uuid:null,name:c.name,project:"-",source:"local",nodes:"-",version:"-",hasLocal:!0});if(s.length===0){console.log(`
23
+ `)),console.log(r.gray(" ".padEnd(60,"-"))),console.log(r.white(" Name".padEnd(35))+r.white("Files".padEnd(25))),console.log(r.gray(" ".padEnd(60,"-")));for(let c of i){let a=[];c.hasGraph&&a.push("graph"),c.hasManifest&&a.push("manifest"),console.log(` ${r.cyan(c.name.padEnd(33))}${r.gray(a.join(", "))}`)}return console.log(r.gray(" ".padEnd(60,"-"))),console.log(r.gray(`
24
+ Total: ${i.length} workflow${i.length===1?"":"s"}
25
+ `)),console.log(r.white(" Commands:")),console.log(r.cyan(" zibby workflow start <name> ")+r.gray("Test locally")),console.log(r.cyan(" zibby workflow deploy <name> ")+r.gray("Deploy to cloud")),console.log(r.cyan(" zibby workflow trigger <uuid> ")+r.gray("Run workflow (returns job ID)")),console.log(r.cyan(" zibby workflow logs <uuid> ")+r.gray("Tail execution logs")),console.log(""),i}catch(u){if(o.quiet)return[];console.log(r.red(`
26
+ Error reading workflows: ${u.message}
27
+ `)),process.exit(1)}}async function pe(o={}){let e=await bo({...o,quiet:!0}),{sessionToken:t,apiKey:l}=await q({apiKey:o.apiKey,optional:!0}),u=[],i=t||l;if(i)try{let n=I(),p=await fetch(`${n}/projects`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`}});if(p.ok){let h=(await p.json()).projects||[];for(let v of h){let B=await fetch(`${n}/projects/${v.projectId}/workflows`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`}});if(B.ok){let H=await B.json(),X=["analysis","implementation","run_test"];for(let k of H)X.includes(k.workflowType)||u.push({uuid:k.uuid,name:k.workflowType,projectId:v.projectId,projectName:v.name||v.projectId,version:k.version||0,nodes:k.graphJson?JSON.parse(k.graphJson).nodes?.length:0,updatedAt:k.updatedAt||null,source:"remote"})}}}}catch{}let c=[],a=new Map(e.map(n=>[n.name,n]));for(let n of u)c.push({uuid:n.uuid,name:n.name,project:n.projectName,version:n.version});for(let[n,p]of a.entries())u.some(h=>h.name===n)||c.push({uuid:null,name:p.name,project:"-",version:"-"});if(c.length===0){console.log(`
12
28
  No workflows found
13
- `),console.log(` Create one with: zibby g workflow <name>
14
- `);return}console.log(`
29
+ `),console.log(` Create one with: zibby workflow new <name>
30
+ `);return}let y=c.map(n=>({uuid:n.uuid||"-",name:n.name,project:n.project,version:String(n.version)})),f={uuid:"UUID",name:"Name",project:"Project",version:"Ver"},g=["uuid","name","project","version"],w=Object.fromEntries(g.map(n=>[n,Math.max(f[n].length,...y.map(p=>String(p[n]).length))])),T=`\u250C${g.map(n=>"\u2500".repeat(w[n]+2)).join("\u252C")}\u2510`,x=`\u251C${g.map(n=>"\u2500".repeat(w[n]+2)).join("\u253C")}\u2524`,$=`\u2514${g.map(n=>"\u2500".repeat(w[n]+2)).join("\u2534")}\u2518`,m=`\u2502${g.map(n=>` ${f[n].padEnd(w[n])} `).join("\u2502")}\u2502`;console.log(`
15
31
  Workflows
16
- `),console.log(" ".padEnd(115,"-")),console.log(`${" UUID".padEnd(40)+"Name".padEnd(20)+"Project".padEnd(20)+"Source".padEnd(16)+"Nodes".padEnd(8)}Ver`),console.log(" ".padEnd(119,"-"));for(let o of s){let c=o.uuid?n.cyan(o.uuid):n.gray("-"),f=o.uuid?c+" ".repeat(4):c+" ".repeat(39);console.log(` ${f}${o.name.padEnd(20)}${o.project.padEnd(20)}${o.source.padEnd(16)}${String(o.nodes).padEnd(8)}${String(o.version)}`)}console.log(" ".padEnd(119,"-")),console.log(`
17
- Total: ${s.length} workflow${s.length===1?"":"s"}
18
- `),console.log(" Commands:"),console.log(" zibby start <name> Test locally"),console.log(" zibby deploy <name> Deploy to cloud (generates UUID)"),console.log(" zibby logs <uuid> View remote workflow logs"),l||console.log(`
19
- Set ZIBBY_API_KEY to see remote workflows`),console.log("")}export{so as listAllWorkflowsCommand,D as listLocalWorkflowsCommand};
32
+ `),console.log(` ${T}`),console.log(` ${r.bold(m)}`),console.log(` ${x}`);for(let n of y){let p=g.map(d=>{let h=String(n[d]).padEnd(w[d]);return` ${d==="uuid"&&n.uuid!=="-"?r.cyan(h):d==="name"?r.white(h):h} `});console.log(` \u2502${p.join("\u2502")}\u2502`)}console.log(` ${$}`),console.log(`
33
+ Total: ${c.length} workflow${c.length===1?"":"s"}
34
+ `),console.log(" Commands:"),console.log(" zibby workflow new <name> Scaffold a new workflow"),console.log(" zibby workflow start <name> Run locally"),console.log(" zibby workflow deploy <name> Ship to cloud (generates UUID on first deploy)"),console.log(" zibby workflow trigger <uuid> Run a deployed workflow remotely"),console.log(" zibby workflow logs <uuid> Tail logs from a remote run"),console.log(" zibby workflow download <uuid> Pull remote back to local (then edit + redeploy)"),console.log(" zibby workflow delete <uuid> Delete a deployed workflow"),i||console.log(`
35
+ Set ZIBBY_API_KEY to see remote workflows`),console.log("")}export{pe as listAllWorkflowsCommand,bo as listLocalWorkflowsCommand};
@@ -5,42 +5,42 @@ import e from"chalk";import{readFileSync as R,existsSync as C}from"fs";import{ho
5
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
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
- 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: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(`
8
+ Workflow UUID is required`)),console.log(e.gray(" Usage: zibby workflow logs <workflow-uuid>")),console.log(e.gray(` zibby workflow logs <workflow-uuid> -t
9
+ `)),process.exit(1)),s}async function T({token:s,executionId:n,sseEndpoint:t,stopped:c}){let f=null;try{let l=new URL(t);l.searchParams.set("jobId",n),f&&l.searchParams.set("lastEventId",f);let g=await fetch(l.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 a=o.slice(6).trim();if(a==="log")continue;if(a==="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
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(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.
13
+ Waiting for next execution...`))}catch{}continue}if(a==="complete"){w=!0;continue}if(a==="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 a=o.slice(5).trim();if(!a)continue;try{let u=JSON.parse(a);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(l){if(l.name==="AbortError")return{aborted:!0};throw l}}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
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(`
15
+ `)),v({token:s,projectId:null,jobId:n,follow:t,limit:1e5});let l={value:!1},g=()=>{l.value=!0,console.log(e.gray(`
16
16
  Stopped streaming.
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(`
17
+ `)),process.exit(0)};process.on("SIGINT",g),process.on("SIGTERM",g);try{let r=await T({token:s,executionId:n,sseEndpoint:f,stopped:l});if(r.aborted||l.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
+ `));!l.value;){if(await new Promise(p=>setTimeout(p,5e3)),l.value)return;try{if(!(await T({token:s,executionId:n,sseEndpoint:f,stopped:l})).notFound)return}catch{}}else console.log(e.yellow(`
19
19
  No executions found for this workflow. Trigger the workflow first.
20
20
  `)),process.exit(1);if(r.failed){console.log(e.red(`
21
- Execution failed.`)),t||process.exit(1);return}if(r.completed&&process.exit(0),t&&!a.value)return console.log(e.gray(`
21
+ Execution failed.`)),t||process.exit(1);return}if(r.completed&&process.exit(0),t&&!l.value)return console.log(e.gray(`
22
22
  Connection ended, reconnecting...
23
- `)),E({token:s,jobId:n,follow:t,projectId:null})}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(`
23
+ `)),E({token:s,jobId:n,follow:t,projectId:null})}catch(r){if(r.name==="AbortError"||l.value)return;if(console.error(e.red(` SSE Error: ${r.message}`)),t&&!l.value)return console.log(e.gray(`
24
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
+ `)),E({token:s,jobId:n,follow:t,projectId:null})}}async function v({token:s,projectId:n,jobId:t,follow:c,limit:f}){let l=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(`
26
26
  Stopped tailing.
27
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(`
28
+ `):"");!y;)try{let d=new URLSearchParams({limit:String(f)});g&&d.set("nextToken",g);let o=await P(`${l}?${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
29
  Job ${o.status}.`)),process.exit(o.status==="completed"?0:1)}if(!c){o.status&&console.log(e.gray(`
30
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(`
31
31
  ${d.message}
32
32
  `)),process.exit(1)),w++,console.error(e.red(` Error: ${d.message}`)),w>=$&&(console.error(e.red(`
33
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
+ `)),process.exit(1)),c||process.exit(1),await new Promise(a=>setTimeout(a,3e3))}}async function L({token:s,projectId:n,workflow:t,follow:c,limit:f}){let l=`${I}/all/${n}`,g=null,r=0,p=new Set,y=null,w=!1,$=0,h=5,d=()=>{w=!0,console.log(e.gray(`
35
35
  Stopped tailing.
36
36
  `)),process.exit(0)};for(process.on("SIGINT",d),process.on("SIGTERM",d),console.log(e.gray(`
37
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(`
38
+ `):"");!w;)try{let o=new URLSearchParams({workflow:t,limit:String(f)});g&&o.set("nextToken",g);let a=await P(`${l}?${o}`,s);$=0,a.message&&a.lines?.length===0&&r===0&&console.log(e.gray(` ${a.message}`));for(let i of a.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=a.lines?.length>0?0:r+1,g=a.nextToken||null,!c){g&&console.log(e.gray(`
39
+ ... more logs available. Run again or use --follow to stream.`)),a.jobCount&&console.log(e.gray(` ${a.jobCount} job(s) found.`));break}if(!a.hasRunning&&!g&&r>2){console.log(e.gray(`
40
+ No running jobs. All caught up.`));break}let m=a.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(`
41
41
  ${o.message}
42
42
  `)),process.exit(1)),$++,console.error(e.red(` Error: ${o.message}`)),$>=h&&(console.error(e.red(`
43
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(`
45
- --workflow is required with --all`)),console.log(e.gray(` Example: zibby logs --workflow ticket-triage --all --project <id>
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};
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,l=n.lines?parseInt(n.lines,10):1e5;if(n.all){let r=n.workflow;return r||(console.log(e.red(`
45
+ --workflow is required with --all`)),console.log(e.gray(` Example: zibby workflow logs --workflow ticket-triage --all --project <id>
46
+ `)),process.exit(1)),L({token:t,projectId:c,workflow:r,follow:f,limit:l})}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:l})}export{F as logsCommand};