@zibby/cli 0.1.77 → 0.1.78

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,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
- import{dirname as G,join as L,resolve as J}from"path";import{fileURLToPath as b}from"url";import{readFileSync as j,existsSync as B}from"fs";import{compileGraph as Q,validateGraphConfig as z}from"@zibby/core/framework/graph-compiler.js";import{WorkflowGraph as W}from"@zibby/core/framework/graph.js";import{buildAnalysisGraph as q}from"@zibby/core/templates/code-analysis/graph.js";import{analysisStateSchema as H}from"@zibby/core/templates/code-analysis/state.js";import"@zibby/core/templates/register-nodes.js";async function k(r,t){let a=process.env.CONTEXT_PRESIGNED_URL;if(!a)throw new Error("CONTEXT_PRESIGNED_URL env var is required");console.log("\u{1F4E6} Fetching execution context via pre-signed URL");let e=await fetch(a);if(!e.ok)throw new Error(`Failed to fetch execution context: ${e.status}`);let o=await e.json();return console.log(` \u2705 Got ticketContext (${JSON.stringify(o.ticketContext||{}).length} chars)`),o.nodeConfigs&&Object.keys(o.nodeConfigs).length>0&&console.log(` \u2705 Got nodeConfigs (${Object.keys(o.nodeConfigs).length} nodes configured)`),{ticketContext:o.ticketContext||{},nodeConfigs:o.nodeConfigs||{},graphConfig:o.graphConfig||null,repos:o.repos||[]}}import{SQSClient as M,SendMessageCommand as D}from"@aws-sdk/client-sqs";var I=null;function F(){return I||(I=new M({region:process.env.AWS_REGION||"ap-southeast-2"})),I}async function N(r,t,a,e){let{EXECUTION_ID:o,SQS_AUTH_TOKEN:s,PROGRESS_API_URL:d,PROGRESS_QUEUE_URL:l,PROJECT_API_TOKEN:u}=e;if(!o)return;let f={executionId:o,...s&&{sqsAuthToken:s},step:{name:r,status:t,logs:a,timestamp:new Date().toISOString(),...t==="success"&&{completedAt:new Date().toISOString()}},status:t==="failed"?"failed":"running"};try{d?await v(d,o,f,u):l&&await U(l,o,f)}catch(m){console.error(`\u26A0\uFE0F Failed to send progress: ${m.message}`)}}async function A(r,t,a){let{EXECUTION_ID:e,SQS_AUTH_TOKEN:o,PROGRESS_API_URL:s,PROGRESS_QUEUE_URL:d,PROJECT_API_TOKEN:l}=r;if(!e||!a)return;let u=JSON.stringify(a).length;console.log(`Sending artifact: ${t} (${(u/1024).toFixed(1)}KB)`);let f={executionId:e,...o&&{sqsAuthToken:o},artifacts:{[t]:a},timestamp:new Date().toISOString()},m=s?"HTTP":d?"SQS":"NONE",i=JSON.stringify(f).length;try{if(s)await v(s,e,f,l);else if(d)await U(d,e,f);else{console.warn(`\u26A0\uFE0F No transport configured for artifact ${t} \u2014 neither PROGRESS_API_URL nor PROGRESS_QUEUE_URL set`);return}console.log(`Artifact ${t} sent via ${m} (payload=${(i/1024).toFixed(1)}KB, value=${(u/1024).toFixed(1)}KB)`)}catch(_){console.error(`Failed to send artifact ${t} via ${m}:`),console.error(` Payload size: ${(i/1024).toFixed(1)}KB, Value size: ${(u/1024).toFixed(1)}KB`),console.error(` Error: ${_.message}`),_.name&&console.error(` Error type: ${_.name}`),_.code&&console.error(` Error code: ${_.code}`),i>256*1024&&console.error(" \u26A0\uFE0F Message exceeds SQS 256KB limit! Consider splitting or compressing.")}}async function P(r,{status:t,error:a}){let{EXECUTION_ID:e,SQS_AUTH_TOKEN:o,PROGRESS_API_URL:s,PROGRESS_QUEUE_URL:d,PROJECT_API_TOKEN:l}=r;if(!e)return;let u={executionId:e,...o&&{sqsAuthToken:o},status:t,...a&&{error:a},timestamp:new Date().toISOString()},f=s?"HTTP":d?"SQS":"NONE",m=JSON.stringify(u).length;console.log(`Sending final status: ${t} via ${f} (${(m/1024).toFixed(1)}KB)`);try{if(s)await v(s,e,u,l);else if(d){let i=["completed","failed","insufficient_context","blocked"].includes(t)?"execution_completed":"progress_update";await U(d,e,u,i)}else{console.warn("No transport configured for final status \u2014 neither PROGRESS_API_URL nor PROGRESS_QUEUE_URL set");return}console.log(`Final status ${t} sent via ${f}`)}catch(i){console.error(`Failed to send final status (${t}) via ${f}:`),console.error(` Payload: ${(m/1024).toFixed(1)}KB`),console.error(` Error: ${i.message}`),i.name&&console.error(` Error type: ${i.name}`),i.code&&console.error(` Error code: ${i.code}`)}}async function v(r,t,a,e){let o=`${r}/${t}/progress`,s={"Content-Type":"application/json"};e&&(s.Authorization=`Bearer ${e}`);let d=await fetch(o,{method:"POST",headers:s,body:JSON.stringify(a)});if(!d.ok){let l=await d.text();throw new Error(`HTTP ${d.status}: ${l}`)}}async function U(r,t,a,e="progress_update"){let o=JSON.stringify(a),s=(o.length/1024).toFixed(1);o.length>256*1024&&console.error(`\u274C SQS message too large: ${s}KB (limit 256KB) for ${t} [${e}]`),await F().send(new D({QueueUrl:r,MessageBody:o,MessageGroupId:t,MessageAttributes:{executionId:{DataType:"String",StringValue:t},messageType:{DataType:"String",StringValue:e}}}))}import{writeMcpConfig as X}from"@zibby/core/utils/mcp-config-writer.js";var V=b(import.meta.url),Y=G(V),Z=JSON.parse(j(L(Y,"../../package.json"),"utf-8")),ee={analyze_ticket:r=>({key:"analysis",value:{raw:r.raw,structured:r.output}}),generate_code:r=>({key:"codeImplementation",value:r.output?.codeImplementation}),generate_test_cases:r=>({key:"tests",value:r.output?.tests}),finalize:r=>({key:"report",value:r.output?.report})};function oe(r,t){return async function(e,o,s){let d=Date.now(),l=[],u="",f=console.log,m=process.stdout.write.bind(process.stdout),i=process.stderr.write.bind(process.stderr),_=!1;console.log=(...n)=>{let h=n.map(w=>typeof w=="string"?w:JSON.stringify(w)).join(" ");l.push(h),_=!0,f(...n),_=!1};let S="";process.stdout.write=(n,h,w)=>{if(!_){let g=typeof n=="string"?n:n.toString();S+=g;let $=S.split(`
2
+ import{dirname as G,join as L,resolve as J}from"path";import{fileURLToPath as b}from"url";import{readFileSync as j,existsSync as B}from"fs";import{compileGraph as Q,validateGraphConfig as z,WorkflowGraph as W}from"@zibby/workflow";import{invokeAgent as q}from"@zibby/core";import{buildAnalysisGraph as H}from"@zibby/core/templates/code-analysis/graph.js";import{analysisStateSchema as X}from"@zibby/core/templates/code-analysis/state.js";import"@zibby/core/templates/register-nodes.js";async function k(r,t){let a=process.env.CONTEXT_PRESIGNED_URL;if(!a)throw new Error("CONTEXT_PRESIGNED_URL env var is required");console.log("\u{1F4E6} Fetching execution context via pre-signed URL");let e=await fetch(a);if(!e.ok)throw new Error(`Failed to fetch execution context: ${e.status}`);let o=await e.json();return console.log(` \u2705 Got ticketContext (${JSON.stringify(o.ticketContext||{}).length} chars)`),o.nodeConfigs&&Object.keys(o.nodeConfigs).length>0&&console.log(` \u2705 Got nodeConfigs (${Object.keys(o.nodeConfigs).length} nodes configured)`),{ticketContext:o.ticketContext||{},nodeConfigs:o.nodeConfigs||{},graphConfig:o.graphConfig||null,repos:o.repos||[]}}import{SQSClient as M,SendMessageCommand as D}from"@aws-sdk/client-sqs";var I=null;function F(){return I||(I=new M({region:process.env.AWS_REGION||"ap-southeast-2"})),I}async function A(r,t,a,e){let{EXECUTION_ID:o,SQS_AUTH_TOKEN:s,PROGRESS_API_URL:d,PROGRESS_QUEUE_URL:l,PROJECT_API_TOKEN:u}=e;if(!o)return;let f={executionId:o,...s&&{sqsAuthToken:s},step:{name:r,status:t,logs:a,timestamp:new Date().toISOString(),...t==="success"&&{completedAt:new Date().toISOString()}},status:t==="failed"?"failed":"running"};try{d?await v(d,o,f,u):l&&await U(l,o,f)}catch(m){console.error(`\u26A0\uFE0F Failed to send progress: ${m.message}`)}}async function N(r,t,a){let{EXECUTION_ID:e,SQS_AUTH_TOKEN:o,PROGRESS_API_URL:s,PROGRESS_QUEUE_URL:d,PROJECT_API_TOKEN:l}=r;if(!e||!a)return;let u=JSON.stringify(a).length;console.log(`Sending artifact: ${t} (${(u/1024).toFixed(1)}KB)`);let f={executionId:e,...o&&{sqsAuthToken:o},artifacts:{[t]:a},timestamp:new Date().toISOString()},m=s?"HTTP":d?"SQS":"NONE",i=JSON.stringify(f).length;try{if(s)await v(s,e,f,l);else if(d)await U(d,e,f);else{console.warn(`\u26A0\uFE0F No transport configured for artifact ${t} \u2014 neither PROGRESS_API_URL nor PROGRESS_QUEUE_URL set`);return}console.log(`Artifact ${t} sent via ${m} (payload=${(i/1024).toFixed(1)}KB, value=${(u/1024).toFixed(1)}KB)`)}catch(_){console.error(`Failed to send artifact ${t} via ${m}:`),console.error(` Payload size: ${(i/1024).toFixed(1)}KB, Value size: ${(u/1024).toFixed(1)}KB`),console.error(` Error: ${_.message}`),_.name&&console.error(` Error type: ${_.name}`),_.code&&console.error(` Error code: ${_.code}`),i>256*1024&&console.error(" \u26A0\uFE0F Message exceeds SQS 256KB limit! Consider splitting or compressing.")}}async function P(r,{status:t,error:a}){let{EXECUTION_ID:e,SQS_AUTH_TOKEN:o,PROGRESS_API_URL:s,PROGRESS_QUEUE_URL:d,PROJECT_API_TOKEN:l}=r;if(!e)return;let u={executionId:e,...o&&{sqsAuthToken:o},status:t,...a&&{error:a},timestamp:new Date().toISOString()},f=s?"HTTP":d?"SQS":"NONE",m=JSON.stringify(u).length;console.log(`Sending final status: ${t} via ${f} (${(m/1024).toFixed(1)}KB)`);try{if(s)await v(s,e,u,l);else if(d){let i=["completed","failed","insufficient_context","blocked"].includes(t)?"execution_completed":"progress_update";await U(d,e,u,i)}else{console.warn("No transport configured for final status \u2014 neither PROGRESS_API_URL nor PROGRESS_QUEUE_URL set");return}console.log(`Final status ${t} sent via ${f}`)}catch(i){console.error(`Failed to send final status (${t}) via ${f}:`),console.error(` Payload: ${(m/1024).toFixed(1)}KB`),console.error(` Error: ${i.message}`),i.name&&console.error(` Error type: ${i.name}`),i.code&&console.error(` Error code: ${i.code}`)}}async function v(r,t,a,e){let o=`${r}/${t}/progress`,s={"Content-Type":"application/json"};e&&(s.Authorization=`Bearer ${e}`);let d=await fetch(o,{method:"POST",headers:s,body:JSON.stringify(a)});if(!d.ok){let l=await d.text();throw new Error(`HTTP ${d.status}: ${l}`)}}async function U(r,t,a,e="progress_update"){let o=JSON.stringify(a),s=(o.length/1024).toFixed(1);o.length>256*1024&&console.error(`\u274C SQS message too large: ${s}KB (limit 256KB) for ${t} [${e}]`),await F().send(new D({QueueUrl:r,MessageBody:o,MessageGroupId:t,MessageAttributes:{executionId:{DataType:"String",StringValue:t},messageType:{DataType:"String",StringValue:e}}}))}import{writeMcpConfig as V}from"@zibby/core/utils/mcp-config-writer.js";var Y=b(import.meta.url),Z=G(Y),ee=JSON.parse(j(L(Z,"../../package.json"),"utf-8")),oe={analyze_ticket:r=>({key:"analysis",value:{raw:r.raw,structured:r.output}}),generate_code:r=>({key:"codeImplementation",value:r.output?.codeImplementation}),generate_test_cases:r=>({key:"tests",value:r.output?.tests}),finalize:r=>({key:"report",value:r.output?.report})};function te(r,t){return async function(e,o,s){let d=Date.now(),l=[],u="",f=console.log,m=process.stdout.write.bind(process.stdout),i=process.stderr.write.bind(process.stderr),_=!1;console.log=(...n)=>{let h=n.map(w=>typeof w=="string"?w:JSON.stringify(w)).join(" ");l.push(h),_=!0,f(...n),_=!1};let S="";process.stdout.write=(n,h,w)=>{if(!_){let g=typeof n=="string"?n:n.toString();S+=g;let $=S.split(`
3
3
  `);S=$.pop()||"";for(let y of $){let O=y.trim();O&&l.push(O)}}return m(n,h,w)},f(`[Middleware] Started capturing logs for ${e}`);let R=!1,T=setInterval(()=>{if(R)return;let n=l.join(`
4
4
  `);n!==u&&n.length>0&&(u=n,i(`\u{1F4E1} [Middleware] Sending live update for ${e}: ${n.length} chars, ${l.length} lines
5
5
  `),r(e,"in_progress",n,s).catch(h=>{i(`\u26A0\uFE0F [Middleware] Failed to send live update: ${h.message}
6
6
  `)}))},500);try{await r(e,"in_progress","",s);let n=await o(),h=((Date.now()-d)/1e3).toFixed(1);R=!0,clearInterval(T),await new Promise(g=>setImmediate(g)),console.log=f,process.stdout.write=m,S.trim()&&(l.push(S.trim()),S="");let w=l.join(`
7
7
  `);if(i(`\u{1F4E1} [Middleware] Sending final update for ${e}: ${w.length} chars, ${l.length} total lines captured
8
- `),n.success){await r(e,"success",w||`Completed in ${h}s`,s);let g=ee[e];if(g){let{key:$,value:y}=g(n);y&&await t(s,$,y)}}else await r(e,"failed",`${w}
8
+ `),n.success){await r(e,"success",w||`Completed in ${h}s`,s);let g=oe[e];if(g){let{key:$,value:y}=g(n);y&&await t(s,$,y)}}else await r(e,"failed",`${w}
9
9
 
10
10
  Error: ${n.error}`,s);return n}catch(n){R=!0,clearInterval(T),await new Promise(w=>setImmediate(w)),console.log=f,process.stdout.write=m;let h=`${l.join(`
11
11
  `)}
12
12
 
13
- Error: ${n.message}`;throw await r(e,"failed",h,s),n}}}async function te(r){let{EXECUTION_ID:t,TICKET_KEY:a,PROJECT_ID:e,REPOS:o,PROGRESS_QUEUE_URL:s,PROGRESS_API_URL:d,SQS_AUTH_TOKEN:l,PROJECT_API_TOKEN:u,GITHUB_TOKEN:f,MODEL:m}=process.env;(!t||!a||!e)&&(console.error("\u274C Missing required environment variables"),console.error(" Required: EXECUTION_ID, TICKET_KEY, PROJECT_ID"),process.exit(1));let i=await k(t,e),_=i.ticketContext,S=i.nodeConfigs||{},R=o?JSON.parse(o):i.repos,T=process.env.WORKSPACE||"/workspace",n=b(import.meta.resolve("@zibby/core/package.json")),h=L(G(n),"templates","code-analysis","prompts");console.log(`
14
- \u{1F680} Zibby Analysis (Graph Mode)`),console.log(`@zibby/cli v${Z.version} | Node.js ${process.version}`),console.log("\u2500".repeat(60)),console.log(`Ticket: ${a}`),console.log(`Repositories: ${R.length}`),console.log(`Workspace: ${T}`),console.log(`AI Model: ${m||"auto"}`),console.log("\u2500".repeat(60));let w=oe(N,A),g,$,y=null;if(r?.workflow){let c=J(process.cwd(),r.workflow);if(B(c)||(console.error(`\u274C Workflow file not found: ${c}`),process.exit(1)),c.endsWith(".js")||c.endsWith(".mjs"))try{let{pathToFileURL:p}=await import("url");y=await import(p(c).href),$=`local JS module (${c})`}catch(p){console.error(`\u274C Failed to load workflow JS module: ${p.message}`),process.exit(1)}else{try{let E=JSON.parse(j(c,"utf-8")),{_meta:C,...K}=E;g=K,$=`local file (${c})`}catch(E){console.error(`\u274C Failed to parse workflow file: ${E.message}`),process.exit(1)}let p=z(g);p.valid||(console.error("\u274C Invalid workflow file:"),p.errors.forEach(E=>console.error(` - ${E}`)),process.exit(1))}}else if(i.graphConfig)g=i.graphConfig,$="custom (from project workflow)";else{let c=new W;q(c),g=c.serialize(),$="default"}let O;if(y){let p={...y.nodeConfigs||{},...S};O=y.buildGraph({nodeMiddleware:w}),console.log(`\u{1F4D0} Graph source: ${$}`),console.log(` Nodes: ${O.nodes.size}`),S=p}else{if(S&&Object.keys(S).length>0){let c=g.nodeConfigs||{},p={...c};for(let[E,C]of Object.entries(S))p[E]={...c[E],...C};g.nodeConfigs=p}console.log(`\u{1F4D0} Graph source: ${$}`),console.log(` Nodes: ${g.nodes?.length||0}`),console.log(` Edges: ${g.edges?.length||0}`),O=Q(g,{nodeMiddleware:w,stateSchema:H})}X(S);let x={EXECUTION_ID:t,PROGRESS_QUEUE_URL:s,PROGRESS_API_URL:d,SQS_AUTH_TOKEN:l,PROJECT_API_TOKEN:u,workspace:T,repos:R,ticketContext:_,promptsDir:h,githubToken:f,model:m,nodeConfigs:S};try{let p=(await O.run(null,x)).state,E=p.analyze_ticket_output?.validation||p.analyze_ticket_output?.analysis?.structured?.validation,C="completed";E&&!E.canProceed&&(C=E.status==="insufficient_context"?"insufficient_context":"blocked"),console.log(`
13
+ Error: ${n.message}`;throw await r(e,"failed",h,s),n}}}async function re(r){let{EXECUTION_ID:t,TICKET_KEY:a,PROJECT_ID:e,REPOS:o,PROGRESS_QUEUE_URL:s,PROGRESS_API_URL:d,SQS_AUTH_TOKEN:l,PROJECT_API_TOKEN:u,GITHUB_TOKEN:f,MODEL:m}=process.env;(!t||!a||!e)&&(console.error("\u274C Missing required environment variables"),console.error(" Required: EXECUTION_ID, TICKET_KEY, PROJECT_ID"),process.exit(1));let i=await k(t,e),_=i.ticketContext,S=i.nodeConfigs||{},R=o?JSON.parse(o):i.repos,T=process.env.WORKSPACE||"/workspace",n=b(import.meta.resolve("@zibby/core/package.json")),h=L(G(n),"templates","code-analysis","prompts");console.log(`
14
+ \u{1F680} Zibby Analysis (Graph Mode)`),console.log(`@zibby/cli v${ee.version} | Node.js ${process.version}`),console.log("\u2500".repeat(60)),console.log(`Ticket: ${a}`),console.log(`Repositories: ${R.length}`),console.log(`Workspace: ${T}`),console.log(`AI Model: ${m||"auto"}`),console.log("\u2500".repeat(60));let w=te(A,N),g,$,y=null;if(r?.workflow){let c=J(process.cwd(),r.workflow);if(B(c)||(console.error(`\u274C Workflow file not found: ${c}`),process.exit(1)),c.endsWith(".js")||c.endsWith(".mjs"))try{let{pathToFileURL:p}=await import("url");y=await import(p(c).href),$=`local JS module (${c})`}catch(p){console.error(`\u274C Failed to load workflow JS module: ${p.message}`),process.exit(1)}else{try{let E=JSON.parse(j(c,"utf-8")),{_meta:C,...K}=E;g=K,$=`local file (${c})`}catch(E){console.error(`\u274C Failed to parse workflow file: ${E.message}`),process.exit(1)}let p=z(g);p.valid||(console.error("\u274C Invalid workflow file:"),p.errors.forEach(E=>console.error(` - ${E}`)),process.exit(1))}}else if(i.graphConfig)g=i.graphConfig,$="custom (from project workflow)";else{let c=new W;H(c),g=c.serialize(),$="default"}let O;if(y){let p={...y.nodeConfigs||{},...S};O=y.buildGraph({nodeMiddleware:w}),console.log(`\u{1F4D0} Graph source: ${$}`),console.log(` Nodes: ${O.nodes.size}`),S=p}else{if(S&&Object.keys(S).length>0){let c=g.nodeConfigs||{},p={...c};for(let[E,C]of Object.entries(S))p[E]={...c[E],...C};g.nodeConfigs=p}console.log(`\u{1F4D0} Graph source: ${$}`),console.log(` Nodes: ${g.nodes?.length||0}`),console.log(` Edges: ${g.edges?.length||0}`),O=Q(g,{nodeMiddleware:w,stateSchema:X,invokeAgent:q})}V(S);let x={EXECUTION_ID:t,PROGRESS_QUEUE_URL:s,PROGRESS_API_URL:d,SQS_AUTH_TOKEN:l,PROJECT_API_TOKEN:u,workspace:T,repos:R,ticketContext:_,promptsDir:h,githubToken:f,model:m,nodeConfigs:S};try{let p=(await O.run(null,x)).state,E=p.analyze_ticket_output?.validation||p.analyze_ticket_output?.analysis?.structured?.validation,C="completed";E&&!E.canProceed&&(C=E.status==="insufficient_context"?"insufficient_context":"blocked"),console.log(`
15
15
  \u{1F4CB} Validation: canProceed=${E?.canProceed}, status=${E?.status}, finalStatus=${C}`),console.log(`
16
16
  \u{1F4CA} Sending final status: ${C}`),await P(x,{status:C}),console.log(`
17
17
  \u2705 Analysis completed successfully`),process.exit(0)}catch(c){if(console.error(`
18
- \u274C Analysis failed:`,c.message),t)try{console.log("\u{1F4E1} Reporting failure..."),await P(x,{status:"failed",error:c.message})}catch{console.error("\u26A0\uFE0F Failed to report error")}process.exit(1)}}import.meta.url===`file://${process.argv[1]}`&&te();export{te as analyzeCommand};
18
+ \u274C Analysis failed:`,c.message),t)try{console.log("\u{1F4E1} Reporting failure..."),await P(x,{status:"failed",error:c.message})}catch{console.error("\u26A0\uFE0F Failed to report error")}process.exit(1)}}import.meta.url===`file://${process.argv[1]}`&&re();export{re as analyzeCommand};
@@ -1,4 +1,4 @@
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}from"@zibby/core/framework/graph-compiler.js";import{generateWorkflowCode as S,generateNodeConfigsJson as F}from"@zibby/core/framework/code-generator.js";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 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/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(`
2
2
  ZIBBY_API_KEY not set`)),console.log(o.gray(` Add to .env: ZIBBY_API_KEY=zby_xxx
3
3
  `)),process.exit(1));let l=t.project||process.env.ZIBBY_PROJECT_ID;return l||(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
@@ -8,7 +8,7 @@ import{readFileSync as N,writeFileSync as b,existsSync as B,mkdirSync as D}from"
8
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
9
  `)),process.exit(1)),!U.includes(e)&&!O.test(e)&&(console.log(o.red(`
10
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 no(t){let e=j(),{apiKey:l,projectId:c}=x(t),n=P(t);console.log(o.bold.cyan(`
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(`
12
12
  Zibby Workflow Download
13
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
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(`
@@ -21,7 +21,7 @@ import{readFileSync as N,writeFileSync as b,existsSync as B,mkdirSync as D}from"
21
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
22
  `)),console.log(o.white(" To run locally:")),console.log(o.cyan(` zibby analyze --workflow ${r}
23
23
  `)),console.log(o.white(" To upload changes back:")),console.log(o.cyan(` zibby workflow upload --project ${e.projectId} --type ${t}
24
- `))}async function to(t){let e=j(),{apiKey:l,projectId:c}=await Z(t),n=P(t);console.log(o.bold.cyan(`
24
+ `))}async function no(t){let e=j(),{apiKey:l,projectId:c}=await Z(t),n=P(t);console.log(o.bold.cyan(`
25
25
  Zibby Workflow Upload
26
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
27
  File not found: ${s}`)),console.log(o.gray(` Download a workflow first: zibby workflow download --project <id> --type <type>
@@ -39,9 +39,9 @@ import{readFileSync as N,writeFileSync as b,existsSync as B,mkdirSync as D}from"
39
39
  Workflow "${n}" updated to version ${h.version}`)),console.log(o.gray(` Project: ${c}
40
40
  `))}catch(p){I.fail(" Upload failed"),console.log(o.red(`
41
41
  ${p.message}
42
- `)),process.exit(1)}}var J=["analysis","implementation","run_test"];async function ro(t){let e=j(),{apiKey:l,projectId:c}=x(t);console.log(o.bold.cyan(`
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(`
43
43
  Zibby Workflows
44
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
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
46
  ${i.message}
47
- `)),process.exit(1)}}export{no as workflowDownloadCommand,ro as workflowListCommand,to as workflowUploadCommand};
47
+ `)),process.exit(1)}}export{eo as workflowDownloadCommand,to as workflowListCommand,no as workflowUploadCommand};
@@ -18,9 +18,9 @@ import e from"chalk";import{readFileSync as R,existsSync as C}from"fs";import{ho
18
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(`
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}return r.completed&&process.exit(0),t&&!a.value?(console.log(e.gray(`
21
+ Execution failed.`)),t||process.exit(1);return}if(r.completed&&process.exit(0),t&&!a.value)return console.log(e.gray(`
22
22
  Connection ended, reconnecting...
23
- `)),E({token:s,jobId:n,follow:t,projectId:null})):void 0}catch(r){if(r.name==="AbortError"||a.value)return;if(console.error(e.red(` SSE Error: ${r.message}`)),t&&!a.value)return console.log(e.gray(`
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(`
24
24
  Reconnecting...
25
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(`
26
26
  Stopped tailing.
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zibby/cli",
3
- "version": "0.1.77",
3
+ "version": "0.1.78",
4
4
  "description": "Zibby CLI - Test automation generator and runner",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,6 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@aws-sdk/client-sqs": "^3.1038.0",
36
+ "@zibby/workflow": "^0.1.0",
36
37
  "@zibby/core": "^0.1.30",
37
38
  "@zibby/memory": "^0.1.5",
38
39
  "@zibby/skills": "^0.1.6",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zibby/cli",
3
- "version": "0.1.77",
3
+ "version": "0.1.78",
4
4
  "description": "Zibby CLI - Test automation generator and runner",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,6 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@aws-sdk/client-sqs": "^3.1038.0",
36
+ "@zibby/workflow": "^0.1.0",
36
37
  "@zibby/core": "^0.1.30",
37
38
  "@zibby/memory": "^0.1.5",
38
39
  "@zibby/skills": "^0.1.6",