@zibby/cli 0.4.10 → 0.4.11
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.
- package/dist/bin/zibby.js +2 -2
- package/dist/commands/init.js +118 -123
- package/dist/commands/template.js +5 -5
- package/dist/commands/workflow.js +3 -3
- package/dist/commands/workflows/deploy-helpers.js +3 -3
- package/dist/commands/workflows/deploy.js +37 -37
- package/dist/commands/workflows/generate.js +467 -54
- package/dist/commands/workflows/list.js +9 -9
- package/dist/commands/workflows/run-local.js +8 -8
- package/dist/commands/workflows/run.js +1 -1
- package/dist/commands/workflows/start.js +1 -1
- package/dist/package.json +2 -2
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
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
|
|
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.dev",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 E 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 B,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 D(){return A(L(),"config.json")}var so=A(R(),".zibby"),Ao=A(so,"config.json");function io(){let o=L();B(o)||no(o,{recursive:!0})}function b(){try{let o=D();if(B(o)){let e=to(o,"utf-8");return JSON.parse(e)}}catch{}return{}}function U(o){io(),ro(D(),JSON.stringify(o,null,2))}function O(){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 Eo,readFileSync as No,writeFileSync as Co,unlinkSync as Bo}from"fs";import{resolve as Lo}from"path";import{homedir as Oo}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=O(),e=F();return o&&e?{loggedIn:!0,user:e,token:o}:{loggedIn:!1}}async function V(){try{console.log(s.cyan(`
|
|
2
2
|
\u{1F510} Initiating login...
|
|
3
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
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(`
|
|
@@ -7,14 +7,14 @@ import{readdir as wo,stat as ho}from"fs/promises";import{existsSync as P}from"fs
|
|
|
7
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
8
|
`));let m=await W();l(m)}else console.log(s.green(`Using existing session.
|
|
9
9
|
`)),l({success:!0,...o})}catch(m){u(m)}})})}return await W()}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 W(){let o=I(),e=
|
|
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 W(){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 w=await t.json();throw new Error(w.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,h=Math.floor(c/(a||3)),T=0,x=!1,$=()=>{x=!0,f.stop(),console.log(s.yellow(`
|
|
11
11
|
|
|
12
12
|
\u26A0\uFE0F Login cancelled
|
|
13
|
-
`)),process.exit(0)};process.on("SIGINT",$);try{for(;T<h&&!x;){await po(g),T++;let w=await fetch(`${o}/cli/login/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({deviceCode:l})});if(w.status===202)continue;if(!w.ok){f.fail("Authorization failed");let p=await w.json();throw new Error(p.error||"Authorization failed")}let n=await w.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=
|
|
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
|
|
13
|
+
`)),process.exit(0)};process.on("SIGINT",$);try{for(;T<h&&!x;){await po(g),T++;let w=await fetch(`${o}/cli/login/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({deviceCode:l})});if(w.status===202)continue;if(!w.ok){f.fail("Authorization failed");let p=await w.json();throw new Error(p.error||"Authorization failed")}let n=await w.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(),y=await uo(n.token);return p.succeed(`Fetched ${y.length} project${y.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
15
|
Not authenticated.`),console.log(` Run ${E.cyan("zibby login")} or set ${E.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};
|
|
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};
|
|
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(E.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 V(),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="workflows";try{t=(await C(e))?.paths?.workflows||"workflows"}catch{}let l=S(e,t);if(!P(l))return o.quiet?[]:(console.log(r.yellow(`
|
|
18
18
|
No workflows found in ${t}/`)),console.log(r.gray(` Create one with: zibby workflow new <name>
|
|
19
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
20
|
No workflows found in ${t}/`)),console.log(r.gray(` Create one with: zibby workflow new <name>
|
|
@@ -24,12 +24,12 @@ import{readdir as wo,stat as ho}from"fs/promises";import{existsSync as P}from"fs
|
|
|
24
24
|
Total: ${i.length} workflow${i.length===1?"":"s"}
|
|
25
25
|
`)),console.log(r.white(" Commands:")),console.log(r.cyan(" zibby workflow run <name> ")+r.gray("Run 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
26
|
Error reading workflows: ${u.message}
|
|
27
|
-
`)),process.exit(1)}}async function pe(o={}){let e=await
|
|
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 k=(await p.json()).projects||[];for(let v of k){let N=await fetch(`${n}/projects/${v.projectId}/workflows`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`}});if(N.ok){let H=await N.json(),X=["analysis","implementation","run_test"];for(let d of H)X.includes(d.workflowType)||u.push({uuid:d.uuid,name:d.workflowType,projectId:v.projectId,projectName:v.name||v.projectId,version:d.version||0,nodes:d.graphJson?JSON.parse(d.graphJson).nodes?.length:0,updatedAt:d.updatedAt||null,source:"remote",warmEnabled:d.warmEnabled===!0,warmCount:Number(d.warmCount)||0,usesDedicatedEgress:!!d.usesDedicatedEgress})}}}}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,warm:n.warmEnabled?String(n.warmCount||1):"-",egress:n.usesDedicatedEgress?"static":"-"});for(let[n,p]of a.entries())u.some(k=>k.name===n)||c.push({uuid:null,name:p.name,project:"-",version:"-",warm:"-",egress:"-"});if(c.length===0){console.log(`
|
|
28
28
|
No workflows found
|
|
29
29
|
`),console.log(` Create one with: zibby workflow new <name>
|
|
30
30
|
`);return}let m=c.map(n=>({uuid:n.uuid||"-",name:n.name,project:n.project,version:String(n.version),warm:n.warm||"-",egress:n.egress||"-"})),f={uuid:"UUID",name:"Name",project:"Project",version:"Ver",warm:"Warm",egress:"Egress"},g=["uuid","name","project","version","warm","egress"],h=Object.fromEntries(g.map(n=>[n,Math.max(f[n].length,...m.map(p=>String(p[n]).length))])),T=`\u250C${g.map(n=>"\u2500".repeat(h[n]+2)).join("\u252C")}\u2510`,x=`\u251C${g.map(n=>"\u2500".repeat(h[n]+2)).join("\u253C")}\u2524`,$=`\u2514${g.map(n=>"\u2500".repeat(h[n]+2)).join("\u2534")}\u2518`,w=`\u2502${g.map(n=>` ${f[n].padEnd(h[n])} `).join("\u2502")}\u2502`;console.log(`
|
|
31
31
|
Workflows
|
|
32
|
-
`),console.log(` ${T}`),console.log(` ${r.bold(w)}`),console.log(` ${x}`);for(let n of m){let p=g.map(y=>{let
|
|
32
|
+
`),console.log(` ${T}`),console.log(` ${r.bold(w)}`),console.log(` ${x}`);for(let n of m){let p=g.map(y=>{let k=String(n[y]).padEnd(h[y]);return` ${y==="uuid"&&n.uuid!=="-"?r.cyan(k):y==="name"?r.white(k):k} `});console.log(` \u2502${p.join("\u2502")}\u2502`)}console.log(` ${$}`),console.log(`
|
|
33
33
|
Total: ${c.length} workflow${c.length===1?"":"s"}
|
|
34
34
|
`),console.log(" Commands:"),console.log(" zibby workflow new <name> Scaffold a new workflow"),console.log(" zibby workflow run <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,
|
|
35
|
+
Set ZIBBY_API_KEY to see remote workflows`),console.log("")}export{pe as listAllWorkflowsCommand,bo as listLocalWorkflowsCommand};
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
var L=Object.defineProperty;var U=(e,t)=>()=>(e&&(t=e(e=0)),t);var S=(e,t)=>{for(var o in t)L(e,o,{get:t[o],enumerable:!0})};var
|
|
1
|
+
var L=Object.defineProperty;var U=(e,t)=>()=>(e&&(t=e(e=0)),t);var S=(e,t)=>{for(var o in t)L(e,o,{get:t[o],enumerable:!0})};var $={};S($,{_resetLoaderCacheForTests:()=>q,loadCredentialsIntoEnv:()=>V});import v from"node:fs";import z from"node:path";import J from"node:os";async function P(){if(!(process.env.__ZIBBY_CLAUDE_PLAN||process.platform!=="darwin"||!(process.env.CLAUDE_CODE_OAUTH_TOKEN||process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL||process.env.ANTHROPIC_AUTH_TOKEN)))try{let{execSync:t}=await import("node:child_process"),o=t('security find-generic-password -s "Claude Code-credentials" -w',{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim();if(o){let c=JSON.parse(o)?.claudeAiOauth?.subscriptionType;c&&(process.env.__ZIBBY_CLAUDE_PLAN=c)}}catch{}}function Z(e){try{if(!v.existsSync(e))return{};let t=v.readFileSync(e,"utf-8"),o=JSON.parse(t);return o&&o.agentKeys&&typeof o.agentKeys=="object"?o.agentKeys:{}}catch{return{}}}async function V(e={}){let{verbose:t=!1,force:o=!1,configPath:a}=e;if(w&&!o)return g;if(!!(process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL||process.env.ANTHROPIC_API_KEY_POOL||process.env.CLAUDE_CODE_OAUTH_TOKEN||process.env.ANTHROPIC_API_KEY||process.env.ANTHROPIC_AUTH_TOKEN))return await P(),w=!0,g={oauthCount:0,apiCount:0,source:"cloud-env"},t&&console.log("[credentials-loader] env vars already set \u2014 skipping local discovery"),g;let l=a||z.join(J.homedir(),".zibby","config.json"),n=Z(l),r="none",s=0,f=0;for(let i of G)n[i]&&!process.env[i]&&(process.env[i]=String(n[i]).trim(),r="config.json",i.endsWith("_POOL")?s+=String(n[i]).split(",").filter(u=>u.trim()).length:s+=1);for(let i of M)n[i]&&!process.env[i]&&(process.env[i]=String(n[i]).trim(),r="config.json",i.endsWith("_POOL")?f+=String(n[i]).split(",").filter(u=>u.trim()).length:f+=1);return await P(),w=!0,g={oauthCount:s,apiCount:f,source:r},t&&s+f>0&&console.log(`[credentials-loader] loaded ${s} OAuth + ${f} API from ${r} (~/.zibby/config.json)`),g}function q(){w=!1,g=null}var w,g,G,M,b=U(()=>{w=!1,g=null,G=["CLAUDE_CODE_OAUTH_TOKEN","CLAUDE_CODE_OAUTH_TOKEN_POOL","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_AUTH_TOKEN_POOL"],M=["ANTHROPIC_API_KEY","ANTHROPIC_API_KEY_POOL"]});import{existsSync as y}from"fs";import{readFile as Q}from"fs/promises";import{join as _}from"path";import{pathToFileURL as X}from"url";import p from"chalk";import oo from"ora";import{existsSync as j}from"fs";import{join as D}from"path";import{pathToFileURL as K}from"url";async function E(e){let t=D(e,".zibby.config.mjs");if(!j(t))throw new Error(".zibby.config.mjs not found");try{let o=await import(K(t).href);return o.default||o}catch(o){throw new Error(`Failed to load .zibby.config.mjs: ${o.message}`,{cause:o})}}import{existsSync as H,readFileSync as B}from"fs";import{resolve as R}from"path";function F(e){return e==="true"?!0:e==="false"?!1:e==="null"?null:e!==""&&!isNaN(Number(e))?Number(e):e}function W(e){let t={};for(let o of e||[]){let a=o.indexOf("=");if(a===-1){console.warn(` Warning: ignored param "${o}" \u2014 expected key=value format`);continue}let c=o.slice(0,a).trim(),l=F(o.slice(a+1)),n=c.split("."),r=t;for(let s=0;s<n.length-1;s++)(typeof r[n[s]]!="object"||r[n[s]]===null)&&(r[n[s]]={}),r=r[n[s]];r[n[n.length-1]]=l}return t}function Y(e){let t=R(e);H(t)||(console.log(`
|
|
2
2
|
Error: --input-file not found: ${e}
|
|
3
3
|
`),process.exit(1));try{return JSON.parse(B(t,"utf-8"))}catch(o){console.log(`
|
|
4
4
|
Error: --input-file is not valid JSON: ${o.message}
|
|
5
|
-
`),process.exit(1)}}function T(e){let t={};if(e.inputFile&&(t={...
|
|
5
|
+
`),process.exit(1)}}function T(e){let t={};if(e.inputFile&&(t={...Y(e.inputFile)}),e.input)try{t={...t,...JSON.parse(e.input)}}catch(o){console.log(`
|
|
6
6
|
Error: --input is not valid JSON`),console.log(` ${o.message}
|
|
7
|
-
`),process.exit(1)}return e.param?.length&&(t={...t,...W(e.param)}),t}function
|
|
8
|
-
`)}async function eo(e){try{let t=await E(e);return{userConfig:t,workflowsBasePath:t?.paths?.workflows||"
|
|
7
|
+
`),process.exit(1)}return e.param?.length&&(t={...t,...W(e.param)}),t}function N({workflowType:e,jobId:t,projectId:o,agentType:a,model:c,egressIp:l,egressKind:n}){let r="\u2500".repeat(60),s=`${a||"default"} (model: ${c||"auto"})`,f=["",r,` Workflow: ${e}`,` Job: ${t||"local"}`,` Project: ${o||"none"}`,` Agent: ${s}`];if(l||n){let i=l||"unknown",u=n||"static";f.push(` Egress: ${i} (${u})`)}return f.push(r),f.join(`
|
|
8
|
+
`)}async function eo(e){try{let t=await E(e);return{userConfig:t,workflowsBasePath:t?.paths?.workflows||"workflows"}}catch{return{userConfig:null,workflowsBasePath:"workflows"}}}async function to(e,t,o){let a=_(e,"graph.mjs");if(!y(a))throw new Error(`graph.mjs not found in ${o}/${t}/`);let c=await no(e,t),l=await import(X(a).href),n=c.entryClass,r=n&&l[n]||l.default||Object.values(l).find(s=>typeof s=="function"&&s.prototype?.buildGraph);if(!r)throw new Error("No WorkflowAgent class found in graph.mjs. Export a class with buildGraph() method.");return{AgentClass:r,manifest:c}}async function no(e,t){let o=_(e,"workflow.json");if(!y(o))return{name:t,triggers:{api:!0}};let a=await Q(o,"utf-8");return JSON.parse(a)}async function vo(e,t={}){e||(console.log(p.red(`
|
|
9
9
|
Workflow name is required`)),console.log(p.gray(" Usage: zibby workflow run <workflow-name>")),console.log(p.gray(` Example: zibby workflow run my-pipeline -p ticket=BUG-123
|
|
10
|
-
`)),process.exit(1));let o=e.toLowerCase(),a=process.cwd();try{let{loadCredentialsIntoEnv:d}=await Promise.resolve().then(()=>(
|
|
10
|
+
`)),process.exit(1));let o=e.toLowerCase(),a=process.cwd();try{let{loadCredentialsIntoEnv:d}=await Promise.resolve().then(()=>(b(),$));await d({verbose:!!process.env.ZIBBY_DEBUG})}catch{}let{userConfig:c,workflowsBasePath:l}=await eo(a),n=_(a,l,o);y(n)||(console.log(p.red(`
|
|
11
11
|
Workflow not found: ${l}/${o}/`)),console.log(p.gray(" Create one first:")),console.log(p.cyan(` zibby workflow new ${o}
|
|
12
|
-
`)),process.exit(1));let
|
|
12
|
+
`)),process.exit(1));let r=T(t),s=oo(` Loading workflow "${o}"...`).start(),f,i;try{({AgentClass:f,manifest:i}=await to(n,o,l)),s.succeed(` Loaded ${p.bold(i.entryClass||f.name)} (${o})`)}catch(d){s.fail(" Failed to load workflow"),console.log(p.red(`
|
|
13
13
|
${d.message}
|
|
14
|
-
`)),process.exit(1)}let u=`local-${Date.now()}`,k=
|
|
14
|
+
`)),process.exit(1)}let u=`local-${Date.now()}`,k=N({workflowType:o,jobId:u,projectId:c?.projectId,agentType:c?.agent?.provider||process.env.AGENT_TYPE,model:c?.agent?.model||process.env.MODEL});console.log(k);let h=Date.now(),x={...r,cwd:a,runId:u,config:c||{},input:r},m,O;try{O=new f({workflow:o}),m=await O.buildGraph().run(O,x)}catch(d){let I=((Date.now()-h)/1e3).toFixed(1);console.log(p.red(`
|
|
15
15
|
\u2716 ${o} failed after ${I}s`)),console.log(p.red(` ${d.message}
|
|
16
16
|
`)),process.env.ZIBBY_DEBUG&&console.error(d.stack),process.exit(1)}let A=((Date.now()-h)/1e3).toFixed(1),C=m?.success!==!1;C?console.log(p.green(`
|
|
17
17
|
\u2714 ${o} completed in ${A}s`)):(console.log(p.red(`
|
|
18
18
|
\u2716 ${o} failed after ${A}s`)),m?.error&&console.log(p.red(` ${m.error}
|
|
19
|
-
`))),C||process.exit(1)}export{
|
|
19
|
+
`))),C||process.exit(1)}export{vo as runLocalWorkflowCommand};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var se=Object.defineProperty;var re=(o,e)=>()=>(o&&(e=o(o=0)),e);var ie=(o,e)=>{for(var t in e)se(o,t,{get:e[t],enumerable:!0})};var Q={};ie(Q,{uploadSessionArtifacts:()=>_e});import{readdirSync as z,statSync as A,createReadStream as ue,existsSync as fe}from"node:fs";import{join as G,relative as ge,sep as me,extname as ye}from"node:path";function Se(o){let e=ye(o).toLowerCase();return he[e]||"application/octet-stream"}function J(o){let e=[],t;try{t=z(o)}catch{return e}for(let s of t){if(we.has(s)||s.startsWith("."))continue;let r=G(o,s),a;try{a=A(r)}catch{continue}a.isDirectory()?e.push(...J(r)):a.isFile()&&e.push(r)}return e}async function Ee({apiUrl:o,apiKey:e,executionId:t,nodeName:s,filename:r,absolutePath:a,sizeBytes:n,contentType:u}){let p;try{let c=await fetch(`${o}/executions/${t}/artifacts/upload-url`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({nodeName:s,filename:r,contentType:u,sizeBytes:n})});if(!c.ok){let i=await c.text();return console.warn(`[artifacts] upload-url failed for ${s}/${r}: ${c.status} ${i.slice(0,200)}`),null}p=await c.json()}catch(c){return console.warn(`[artifacts] upload-url request errored for ${s}/${r}: ${c.message}`),null}try{let c=ue(a),i=await fetch(p.url,{method:"PUT",headers:{"Content-Type":u,"Content-Length":String(n)},body:c,duplex:"half"});if(!i.ok)return console.warn(`[artifacts] S3 PUT failed for ${s}/${r}: ${i.status}`),null}catch(c){return console.warn(`[artifacts] S3 PUT errored for ${s}/${r}: ${c.message}`),null}return{nodeName:s,filename:r,s3Key:p.s3Key,contentType:u,sizeBytes:n}}async function _e({sessionPath:o,executionId:e,apiUrl:t,apiKey:s}){let r={uploaded:[],skipped:[]};if(!o||!fe(o))return r;if(!t||!s||!e)return console.warn("[artifacts] uploader missing required input \u2014 skipping"),r;let a;try{a=z(o)}catch(i){return console.warn(`[artifacts] could not read session folder ${o}: ${i.message}`),r}let n=[];for(let i of a){let d=G(o,i),g;try{g=A(d)}catch{continue}if(!g.isDirectory()||i.startsWith(".")||i.startsWith("_"))continue;let P=J(d);for(let R of P){let E=ge(d,R).split(me).join("/"),w;try{w=A(R).size}catch{continue}if(w>W){r.skipped.push({nodeName:i,filename:E,reason:`size ${w} > ${W}`});continue}if(w===0){r.skipped.push({nodeName:i,filename:E,reason:"empty"});continue}n.push({apiUrl:t,apiKey:s,executionId:e,nodeName:i,filename:E,absolutePath:R,sizeBytes:w,contentType:Se(E)})}}if(n.length===0)return r;let u=4,p=n.slice(),c=Array.from({length:Math.min(u,p.length)},async()=>{for(;p.length;){let i=p.shift(),d=await Ee(i);d?r.uploaded.push(d):r.skipped.push({nodeName:i.nodeName,filename:i.filename,reason:"upload failed"})}});if(await Promise.all(c),r.uploaded.length>0)try{let i=await fetch(`${t}/executions/${e}/artifacts`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify({files:r.uploaded})});if(!i.ok){let d=await i.text();console.warn(`[artifacts] record failed: ${i.status} ${d.slice(0,200)}`)}}catch(i){console.warn(`[artifacts] record errored: ${i.message}`)}return r}var W,we,he,Y=re(()=>{W=500*1024*1024,we=new Set([".DS_Store","Thumbs.db",".zibby-stop"]),he={".webm":"video/webm",".mp4":"video/mp4",".mov":"video/quicktime",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".txt":"text/plain",".md":"text/markdown",".html":"text/html",".csv":"text/csv",".log":"text/plain",".json":"application/json",".yaml":"application/yaml",".yml":"application/yaml",".pdf":"application/pdf",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip"}});import{mkdirSync as Z,writeFileSync as $e,existsSync as S,readFileSync as M}from"fs";import{join as m,dirname as Oe,resolve as q}from"path";import{pathToFileURL as U}from"url";import{execSync as Re,spawn as H}from"node:child_process";import{SQSClient as ae,SendMessageCommand as ce}from"@aws-sdk/client-sqs";var x=null;function le(){return x||(x=new ae({region:process.env.AWS_REGION||"ap-southeast-2"})),x}async function j(o,{status:e,error:t}){let{EXECUTION_ID:s,SQS_AUTH_TOKEN:r,PROGRESS_API_URL:a,PROGRESS_QUEUE_URL:n,PROJECT_API_TOKEN:u}=o;if(!s)return;let p={executionId:s,...r&&{sqsAuthToken:r},status:e,...t&&{error:t},timestamp:new Date().toISOString()},c=a?"HTTP":n?"SQS":"NONE",i=JSON.stringify(p).length;console.log(`Sending final status: ${e} via ${c} (${(i/1024).toFixed(1)}KB)`);try{if(a)await pe(a,s,p,u);else if(n){let d=["completed","failed","insufficient_context","blocked"].includes(e)?"execution_completed":"progress_update";await de(n,s,p,d)}else{console.warn("No transport configured for final status \u2014 neither PROGRESS_API_URL nor PROGRESS_QUEUE_URL set");return}console.log(`Final status ${e} sent via ${c}`)}catch(d){console.error(`Failed to send final status (${e}) via ${c}:`),console.error(` Payload: ${(i/1024).toFixed(1)}KB`),console.error(` Error: ${d.message}`),d.name&&console.error(` Error type: ${d.name}`),d.code&&console.error(` Error code: ${d.code}`)}}async function pe(o,e,t,s){let r=`${o}/${e}/progress`,a={"Content-Type":"application/json"};s&&(a.Authorization=`Bearer ${s}`);let n=await fetch(r,{method:"POST",headers:a,body:JSON.stringify(t)});if(!n.ok){let u=await n.text();throw new Error(`HTTP ${n.status}: ${u}`)}}async function de(o,e,t,s="progress_update"){let r=JSON.stringify(t),a=(r.length/1024).toFixed(1);r.length>256*1024&&console.error(`\u274C SQS message too large: ${a}KB (limit 256KB) for ${e} [${s}]`),await le().send(new ce({QueueUrl:o,MessageBody:r,MessageGroupId:e,MessageAttributes:{executionId:{DataType:"String",StringValue:e},messageType:{DataType:"String",StringValue:s}}}))}function K({workflowType:o,jobId:e,projectId:t,agentType:s,model:r,egressIp:a,egressKind:n}){let u="\u2500".repeat(60),p=`${s||"default"} (model: ${r||"auto"})`,c=["",u,` Workflow: ${o}`,` Job: ${e||"local"}`,` Project: ${t||"none"}`,` Agent: ${p}`];if(a||n){let i=a||"unknown",d=n||"static";c.push(` Egress: ${i} (${d})`)}return c.push(u),c.join(`
|
|
3
|
-
`)}import"@zibby/core";var I=process.env.WORKSPACE||"/workspace";async function be(o,e){Z(e,{recursive:!0});let t=Date.now();console.log("[setup] Fetching bundle...");let s=setInterval(()=>{let a=((Date.now()-t)/1e3).toFixed(1);console.log(`[setup] still fetching (${a}s elapsed)`)},3e3);try{await new Promise((a,n)=>{let u=H("curl",["-fsSL",o],{stdio:["ignore","pipe","inherit"]}),p=H("tar",["-xzf","-","-C",e],{stdio:["pipe","inherit","inherit"]});u.stdout.pipe(p.stdin);let c,i,d=()=>{if(c!==void 0&&i!==void 0){if(c!==0)return n(new Error(`curl exited ${c}`));if(i!==0)return n(new Error(`tar exited ${i}`));a()}};u.on("close",g=>{c=g,d()}),p.on("close",g=>{i=g,d()}),u.on("error",n),p.on("error",n)})}finally{clearInterval(s)}let r=((Date.now()-t)/1e3).toFixed(1);return console.log(`[setup] Bundle extracted (${r}s)`),e}async function X(){let o=process.env.WORKFLOW_SOURCES_URL;if(!o)throw new Error("WORKFLOW_SOURCES_URL env var is required");let e=await fetch(o);if(!e.ok)throw new Error(`Failed to fetch sources: ${e.status} ${e.statusText}`);let t=await e.json();if(!t.sources||typeof t.sources!="object")throw new Error('Invalid sources payload \u2014 missing "sources" map');return t}function Pe(o){let e=o?.agent;if(!e)return null;if(typeof e=="string")return e;if(typeof e=="object"){if(typeof e.provider=="string")return e.provider;for(let t of["claude","cursor","codex","gemini"])if(e[t])return t}return null}function Te(o,e){let t=q(e),s=0;for(let[r,a]of Object.entries(o)){let n=q(e,r);if(!n.startsWith(`${t}/`)&&n!==t){console.error(` \u26D4 Skipping unsafe path: ${r}`);continue}Z(Oe(n),{recursive:!0}),$e(n,a,"utf-8"),s++}return s}async function ke(){let o=process.env.ZIBBY_EGRESS_PROXY_URL,e=process.env.ZIBBY_EGRESS_TOKEN;if(!(!o||!e))try{let t=await import("undici"),s=new t.ProxyAgent({uri:o,token:`Bearer ${e}`});t.setGlobalDispatcher(s)}catch(t){console.warn(`[setup] Failed to install egress proxy dispatcher: ${t.message}`)}}async function xe(){if(process.env.ZIBBY_EGRESS_IP)return{ip:process.env.ZIBBY_EGRESS_IP,kind:"static"};try{let o=new AbortController,e=setTimeout(()=>o.abort(),1500),t=await fetch("https://api.ipify.org?format=json",{signal:o.signal});return clearTimeout(e),t.ok?{ip:(await t.json())?.ip||null,kind:"dynamic"}:{ip:null,kind:"dynamic"}}catch{return{ip:null,kind:"dynamic"}}}async function Ae(o,e){let t=m(o,"graph.mjs");if(!S(t))throw new Error(`graph.mjs not found at ${t}`);let s=await import(U(t).href),r=e?.entryClass,a=r&&s[r]||s.default||Object.values(s).find(n=>typeof n=="function"&&n.prototype?.buildGraph);if(!a)throw new Error("No WorkflowAgent class found in graph.mjs");return a}async function Je(){if(!process.env.NODE_PATH){process.env.NODE_PATH="/opt/zibby/packages";let l=await import("module");l.default._initPaths&&l.default._initPaths()}await ke();let{WORKFLOW_JOB_ID:o,WORKFLOW_TYPE:e,PROJECT_ID:t,AGENT_TYPE:s,MODEL:r}=process.env;e||(console.error("Missing WORKFLOW_TYPE env var"),process.exit(1));let a=process.env.WORKFLOW_BUNDLE_URL,n,u={},p,c;if(a){p=e,n=m(I,".zibby","workflows",p);try{await be(a,n);try{let l=await X();u=l.input||{},c=l.version}catch{}}catch(l){console.warn(`[setup] Bundle extract failed (${l.message}); falling back to source install`),n=null}}if(!n){let l=await X(),{sources:f,input:h,workflowType:_,version:y}=l;u=h||{},p=_||e,c=y,console.log(`[setup] Workflow v${c||"?"} (${Object.keys(f).length} files)`),n=m(I,".zibby","workflows",p);let b=Te(f,n);console.log(`[setup] Wrote ${b} files`),console.log("[setup] Installing dependencies...");try{Re("npm install --silent --no-audit --no-fund",{cwd:n,stdio:"inherit"}),console.log("[setup] Dependencies installed")}catch($){console.warn(`[setup] npm install failed: ${$.message}`)}}let i={},d=m(n,"workflow.json");S(d)&&(i=JSON.parse(M(d,"utf-8")));let g={},P=m(n,"zibby.config.json");if(S(P))try{g=JSON.parse(M(P,"utf-8")),console.log("[setup] Loaded user config from zibby.config.json")}catch(l){console.warn(`[setup] Failed to parse zibby.config.json: ${l.message} \u2014 falling back to defaults`)}let R=Pe(g)||s,E=await xe();console.log(K({workflowType:e,jobId:o,projectId:t,agentType:R,model:r,egressIp:E.ip,egressKind:E.kind}));let w=await Ae(n,i);console.log(`[setup] Loaded ${w.name}`);let O=[],C=m(n,"node_modules","@zibby","agent-workflow"),N=m(n,"node_modules","@zibby","core","node_modules","@zibby","agent-workflow");S(C)&&O.push({kind:"hoisted",path:C}),S(N)&&O.push({kind:"nested",path:N});let k=process.env.ZIBBY_RUN_DIAG==="1";if(k){let{readdirSync:l}=await import("fs");console.log(` [diag] @zibby/agent-workflow copies in bundle: ${O.length}`);for(let f of O)console.log(` [diag] ${f.kind}: ${f.path}`);try{let f=m(n,"node_modules","@zibby");S(f)&&console.log(` [diag] node_modules/@zibby/ contents: [${l(f).join(", ")}]`)}catch{}}let B=m(n,"node_modules","@zibby","core","dist","index.js");if(S(B)&&O.length>0)try{let l=await import(U(B).href),f=[l.AssistantStrategy,l.CursorAgentStrategy,l.ClaudeAgentStrategy,l.CodexAgentStrategy,l.GeminiAgentStrategy].filter(Boolean);for(let h of O){let _=m(h.path,"dist","index.js");if(!S(_))continue;let y=await import(U(_).href),b=k?y.listStrategies():null;for(let $ of f)try{y.registerStrategy(new $)}catch(ne){console.warn(` register ${$.name} into ${h.kind} failed: ${ne.message}`)}k&&console.log(` [diag] ${h.kind} registry: before=[${b.join(",")||"empty"}] after=[${y.listStrategies().join(",")||"empty"}]`)}console.log("[setup] Registered 5 agent strategies (assistant, cursor, claude, codex, gemini)")}catch(l){console.warn(`[setup] Failed to bridge strategies: ${l.message}`)}else console.warn("[setup] No @zibby/core or @zibby/agent-workflow in bundle \u2014 agent strategies may be unavailable");let V=Date.now(),F=new w({workflow:p||e}),ee=F.buildGraph(),te={
|
|
3
|
+
`)}import"@zibby/core";var I=process.env.WORKSPACE||"/workspace";async function be(o,e){Z(e,{recursive:!0});let t=Date.now();console.log("[setup] Fetching bundle...");let s=setInterval(()=>{let a=((Date.now()-t)/1e3).toFixed(1);console.log(`[setup] still fetching (${a}s elapsed)`)},3e3);try{await new Promise((a,n)=>{let u=H("curl",["-fsSL",o],{stdio:["ignore","pipe","inherit"]}),p=H("tar",["-xzf","-","-C",e],{stdio:["pipe","inherit","inherit"]});u.stdout.pipe(p.stdin);let c,i,d=()=>{if(c!==void 0&&i!==void 0){if(c!==0)return n(new Error(`curl exited ${c}`));if(i!==0)return n(new Error(`tar exited ${i}`));a()}};u.on("close",g=>{c=g,d()}),p.on("close",g=>{i=g,d()}),u.on("error",n),p.on("error",n)})}finally{clearInterval(s)}let r=((Date.now()-t)/1e3).toFixed(1);return console.log(`[setup] Bundle extracted (${r}s)`),e}async function X(){let o=process.env.WORKFLOW_SOURCES_URL;if(!o)throw new Error("WORKFLOW_SOURCES_URL env var is required");let e=await fetch(o);if(!e.ok)throw new Error(`Failed to fetch sources: ${e.status} ${e.statusText}`);let t=await e.json();if(!t.sources||typeof t.sources!="object")throw new Error('Invalid sources payload \u2014 missing "sources" map');return t}function Pe(o){let e=o?.agent;if(!e)return null;if(typeof e=="string")return e;if(typeof e=="object"){if(typeof e.provider=="string")return e.provider;for(let t of["claude","cursor","codex","gemini"])if(e[t])return t}return null}function Te(o,e){let t=q(e),s=0;for(let[r,a]of Object.entries(o)){let n=q(e,r);if(!n.startsWith(`${t}/`)&&n!==t){console.error(` \u26D4 Skipping unsafe path: ${r}`);continue}Z(Oe(n),{recursive:!0}),$e(n,a,"utf-8"),s++}return s}async function ke(){let o=process.env.ZIBBY_EGRESS_PROXY_URL,e=process.env.ZIBBY_EGRESS_TOKEN;if(!(!o||!e))try{let t=await import("undici"),s=new t.ProxyAgent({uri:o,token:`Bearer ${e}`});t.setGlobalDispatcher(s)}catch(t){console.warn(`[setup] Failed to install egress proxy dispatcher: ${t.message}`)}}async function xe(){if(process.env.ZIBBY_EGRESS_IP)return{ip:process.env.ZIBBY_EGRESS_IP,kind:"static"};try{let o=new AbortController,e=setTimeout(()=>o.abort(),1500),t=await fetch("https://api.ipify.org?format=json",{signal:o.signal});return clearTimeout(e),t.ok?{ip:(await t.json())?.ip||null,kind:"dynamic"}:{ip:null,kind:"dynamic"}}catch{return{ip:null,kind:"dynamic"}}}async function Ae(o,e){let t=m(o,"graph.mjs");if(!S(t))throw new Error(`graph.mjs not found at ${t}`);let s=await import(U(t).href),r=e?.entryClass,a=r&&s[r]||s.default||Object.values(s).find(n=>typeof n=="function"&&n.prototype?.buildGraph);if(!a)throw new Error("No WorkflowAgent class found in graph.mjs");return a}async function Je(){if(!process.env.NODE_PATH){process.env.NODE_PATH="/opt/zibby/packages";let l=await import("module");l.default._initPaths&&l.default._initPaths()}await ke();let{WORKFLOW_JOB_ID:o,WORKFLOW_TYPE:e,PROJECT_ID:t,AGENT_TYPE:s,MODEL:r}=process.env;e||(console.error("Missing WORKFLOW_TYPE env var"),process.exit(1));let a=process.env.WORKFLOW_BUNDLE_URL,n,u={},p,c;if(a){p=e,n=m(I,".zibby","workflows",p);try{await be(a,n);try{let l=await X();u=l.input||{},c=l.version}catch{}}catch(l){console.warn(`[setup] Bundle extract failed (${l.message}); falling back to source install`),n=null}}if(!n){let l=await X(),{sources:f,input:h,workflowType:_,version:y}=l;u=h||{},p=_||e,c=y,console.log(`[setup] Workflow v${c||"?"} (${Object.keys(f).length} files)`),n=m(I,".zibby","workflows",p);let b=Te(f,n);console.log(`[setup] Wrote ${b} files`),console.log("[setup] Installing dependencies...");try{Re("npm install --silent --no-audit --no-fund",{cwd:n,stdio:"inherit"}),console.log("[setup] Dependencies installed")}catch($){console.warn(`[setup] npm install failed: ${$.message}`)}}let i={},d=m(n,"workflow.json");S(d)&&(i=JSON.parse(M(d,"utf-8")));let g={},P=m(n,"zibby.config.json");if(S(P))try{g=JSON.parse(M(P,"utf-8")),console.log("[setup] Loaded user config from zibby.config.json")}catch(l){console.warn(`[setup] Failed to parse zibby.config.json: ${l.message} \u2014 falling back to defaults`)}let R=Pe(g)||s,E=await xe();console.log(K({workflowType:e,jobId:o,projectId:t,agentType:R,model:r,egressIp:E.ip,egressKind:E.kind}));let w=await Ae(n,i);console.log(`[setup] Loaded ${w.name}`);let O=[],C=m(n,"node_modules","@zibby","agent-workflow"),N=m(n,"node_modules","@zibby","core","node_modules","@zibby","agent-workflow");S(C)&&O.push({kind:"hoisted",path:C}),S(N)&&O.push({kind:"nested",path:N});let k=process.env.ZIBBY_RUN_DIAG==="1";if(k){let{readdirSync:l}=await import("fs");console.log(` [diag] @zibby/agent-workflow copies in bundle: ${O.length}`);for(let f of O)console.log(` [diag] ${f.kind}: ${f.path}`);try{let f=m(n,"node_modules","@zibby");S(f)&&console.log(` [diag] node_modules/@zibby/ contents: [${l(f).join(", ")}]`)}catch{}}let B=m(n,"node_modules","@zibby","core","dist","index.js");if(S(B)&&O.length>0)try{let l=await import(U(B).href),f=[l.AssistantStrategy,l.CursorAgentStrategy,l.ClaudeAgentStrategy,l.CodexAgentStrategy,l.GeminiAgentStrategy].filter(Boolean);for(let h of O){let _=m(h.path,"dist","index.js");if(!S(_))continue;let y=await import(U(_).href),b=k?y.listStrategies():null;for(let $ of f)try{y.registerStrategy(new $)}catch(ne){console.warn(` register ${$.name} into ${h.kind} failed: ${ne.message}`)}k&&console.log(` [diag] ${h.kind} registry: before=[${b.join(",")||"empty"}] after=[${y.listStrategies().join(",")||"empty"}]`)}console.log("[setup] Registered 5 agent strategies (assistant, cursor, claude, codex, gemini)")}catch(l){console.warn(`[setup] Failed to bridge strategies: ${l.message}`)}else console.warn("[setup] No @zibby/core or @zibby/agent-workflow in bundle \u2014 agent strategies may be unavailable");let V=Date.now(),F=new w({workflow:p||e}),ee=F.buildGraph(),te={...u||{},cwd:I,runId:o||`run-${Date.now()}`,config:g,input:u||{}};console.log("");let T;try{T=await ee.run(F,te)}catch(l){console.error(`
|
|
4
4
|
Workflow execution failed: ${l.message}`),console.error(l.stack),await v("failed",l.message),process.exit(1)}let L=((Date.now()-V)/1e3).toFixed(1),oe=T?.success!==!1,D=p||e;if(process.env.UPLOAD_ARTIFACTS!=="0"){let l=T?.state?.sessionPath,f=process.env.PROGRESS_API_URL||process.env.ZIBBY_API_BASE,h=process.env.PROJECT_API_TOKEN,_=process.env.WORKFLOW_JOB_ID;if(l&&f&&h&&_)try{let{uploadSessionArtifacts:y}=await Promise.resolve().then(()=>(Y(),Q)),{uploaded:b,skipped:$}=await y({sessionPath:l,executionId:_,apiUrl:f,apiKey:h});console.log(`[artifacts] uploaded ${b.length} file(s)${$.length?`, skipped ${$.length}`:""}`)}catch(y){console.warn(`[artifacts] uploader threw: ${y.message}`)}else console.log("[artifacts] skipping upload \u2014 sessionPath/apiUrl/apiKey/executionId missing")}oe?(console.log(`
|
|
5
5
|
[done] ${D} completed in ${L}s`),await v("completed")):(console.error(`
|
|
6
6
|
[done] ${D} failed after ${L}s`),await v("failed",T?.error||"Workflow execution failed"),process.exit(1))}async function v(o,e=null){let t={EXECUTION_ID:process.env.WORKFLOW_JOB_ID,PROGRESS_API_URL:process.env.PROGRESS_API_URL,PROGRESS_QUEUE_URL:process.env.PROGRESS_QUEUE_URL,PROJECT_API_TOKEN:process.env.PROJECT_API_TOKEN,SQS_AUTH_TOKEN:process.env.SQS_AUTH_TOKEN};if(t.EXECUTION_ID)try{await j(t,{status:o,...e&&{error:e}})}catch(s){console.error(`\u26A0\uFE0F Failed to report status: ${s.message}`)}}export{Pe as resolveAgentFromConfig,Je as runWorkflowCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var j=Object.defineProperty;var I=(n,t)=>()=>(n&&(t=n(n=0)),t);var K=(n,t)=>{for(var o in t)j(n,o,{get:t[o],enumerable:!0})};var N={};K(N,{_resetLoaderCacheForTests:()=>G,loadCredentialsIntoEnv:()=>Y});import b from"node:fs";import R from"node:path";import W from"node:os";async function k(){if(!(process.env.__ZIBBY_CLAUDE_PLAN||process.platform!=="darwin"||!(process.env.CLAUDE_CODE_OAUTH_TOKEN||process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL||process.env.ANTHROPIC_AUTH_TOKEN)))try{let{execSync:t}=await import("node:child_process"),o=t('security find-generic-password -s "Claude Code-credentials" -w',{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim();if(o){let f=JSON.parse(o)?.claudeAiOauth?.subscriptionType;f&&(process.env.__ZIBBY_CLAUDE_PLAN=f)}}catch{}}function
|
|
1
|
+
var j=Object.defineProperty;var I=(n,t)=>()=>(n&&(t=n(n=0)),t);var K=(n,t)=>{for(var o in t)j(n,o,{get:t[o],enumerable:!0})};var N={};K(N,{_resetLoaderCacheForTests:()=>G,loadCredentialsIntoEnv:()=>Y});import b from"node:fs";import R from"node:path";import W from"node:os";async function k(){if(!(process.env.__ZIBBY_CLAUDE_PLAN||process.platform!=="darwin"||!(process.env.CLAUDE_CODE_OAUTH_TOKEN||process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL||process.env.ANTHROPIC_AUTH_TOKEN)))try{let{execSync:t}=await import("node:child_process"),o=t('security find-generic-password -s "Claude Code-credentials" -w',{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim();if(o){let f=JSON.parse(o)?.claudeAiOauth?.subscriptionType;f&&(process.env.__ZIBBY_CLAUDE_PLAN=f)}}catch{}}function z(n){try{if(!b.existsSync(n))return{};let t=b.readFileSync(n,"utf-8"),o=JSON.parse(t);return o&&o.agentKeys&&typeof o.agentKeys=="object"?o.agentKeys:{}}catch{return{}}}async function Y(n={}){let{verbose:t=!1,force:o=!1,configPath:c}=n;if(h&&!o)return w;if(!!(process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL||process.env.ANTHROPIC_API_KEY_POOL||process.env.CLAUDE_CODE_OAUTH_TOKEN||process.env.ANTHROPIC_API_KEY||process.env.ANTHROPIC_AUTH_TOKEN))return await k(),h=!0,w={oauthCount:0,apiCount:0,source:"cloud-env"},t&&console.log("[credentials-loader] env vars already set \u2014 skipping local discovery"),w;let l=c||R.join(W.homedir(),".zibby","config.json"),a=z(l),i="none",s=0,g=0;for(let r of B)a[r]&&!process.env[r]&&(process.env[r]=String(a[r]).trim(),i="config.json",r.endsWith("_POOL")?s+=String(a[r]).split(",").filter(p=>p.trim()).length:s+=1);for(let r of F)a[r]&&!process.env[r]&&(process.env[r]=String(a[r]).trim(),i="config.json",r.endsWith("_POOL")?g+=String(a[r]).split(",").filter(p=>p.trim()).length:g+=1);return await k(),h=!0,w={oauthCount:s,apiCount:g,source:i},t&&s+g>0&&console.log(`[credentials-loader] loaded ${s} OAuth + ${g} API from ${i} (~/.zibby/config.json)`),w}function G(){h=!1,w=null}var h,w,B,F,$=I(()=>{h=!1,w=null,B=["CLAUDE_CODE_OAUTH_TOKEN","CLAUDE_CODE_OAUTH_TOKEN_POOL","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_AUTH_TOKEN_POOL"],F=["ANTHROPIC_API_KEY","ANTHROPIC_API_KEY_POOL"]});import{existsSync as _}from"fs";import{readFile as J}from"fs/promises";import{join as C}from"path";import{pathToFileURL as M}from"url";import e from"chalk";import Z from"ora";import{existsSync as H}from"fs";import{join as D}from"path";import{pathToFileURL as x}from"url";async function P(n){let t=D(n,".zibby.config.mjs");if(!H(t))throw new Error(".zibby.config.mjs not found");try{let o=await import(x(t).href);return o.default||o}catch(o){throw new Error(`Failed to load .zibby.config.mjs: ${o.message}`,{cause:o})}}var q=3848;async function V(n){try{let t=await P(n);return{userConfig:t,workflowsBasePath:t?.paths?.workflows||"workflows"}}catch{return{userConfig:null,workflowsBasePath:"workflows"}}}async function X(n,t,o){let c=C(n,"graph.mjs");if(!_(c))throw new Error(`graph.mjs not found in ${o}/${t}/`);let f=await Q(n,t),l=await import(M(c).href),a=f.entryClass,i=a&&l[a]||l.default||Object.values(l).find(s=>typeof s=="function"&&s.prototype?.buildGraph);if(!i)throw new Error("No WorkflowAgent class found in graph.mjs. Export a class with buildGraph() method.");return{AgentClass:i,manifest:f}}async function Q(n,t){let o=C(n,"workflow.json");if(!_(o))return{name:t,triggers:{api:!0}};let c=await J(o,"utf-8");return JSON.parse(c)}async function yo(n,t){n||(console.log(e.red(`
|
|
2
2
|
Workflow name is required`)),console.log(e.gray(" Usage: zibby workflow start <workflow-name>")),console.log(e.gray(` Example: zibby workflow start ticket-triage
|
|
3
3
|
`)),process.exit(1));let o=n.toLowerCase(),c=process.cwd();try{let{loadCredentialsIntoEnv:d}=await Promise.resolve().then(()=>($(),N));await d({verbose:!!process.env.ZIBBY_DEBUG})}catch{}let{userConfig:f,workflowsBasePath:l}=await V(c),a=C(c,l,o);_(a)||(console.log(e.red(`
|
|
4
4
|
Workflow not found: ${l}/${o}/`)),console.log(e.gray(" Create one first:")),console.log(e.cyan(` zibby workflow new ${o}
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zibby/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.11",
|
|
4
4
|
"description": "Zibby CLI - Test automation generator and runner",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "node ../scripts/build.mjs --extra-dirs bin",
|
|
11
|
-
"test": "vitest run test/auth*.test.js test/two-layer-auth.test.js test/trigger-params.test.js test/trigger-helpers.test.js test/deploy-helpers.test.js test/deploy-bundles-user-config.test.js test/deploy-skip-unchanged.test.js test/deploy-warm-flag.test.js test/deploy-402-formatter.test.js test/run-loads-user-config.test.js test/env-helpers.test.js test/env-cli.test.js test/chat-agents.test.js test/chat-agents-api.test.js test/chat-agents-picker.test.js test/chat-sandbox-attach.test.js test/credentials-file.test.js test/credentials-api.test.js test/credentials-loader.test.js test/cli-namespace-consistency.test.js test/cli-workflow-subcommands.test.js test/template-resolver.test.js test/workflow-new-template.test.js test/run-bundle-core-import.test.js test/start-respects-config.test.js test/sse-backoff.test.js test/sse-reconnect-loop.test.js test/run-helpers.test.js test/run-banner.test.js test/run-banner-e2e.test.js test/sse-parser.test.js test/cloud-creds-check.test.js",
|
|
11
|
+
"test": "vitest run test/auth*.test.js test/two-layer-auth.test.js test/trigger-params.test.js test/trigger-helpers.test.js test/deploy-helpers.test.js test/deploy-bundles-user-config.test.js test/deploy-skip-unchanged.test.js test/deploy-warm-flag.test.js test/deploy-402-formatter.test.js test/run-loads-user-config.test.js test/env-helpers.test.js test/env-cli.test.js test/chat-agents.test.js test/chat-agents-api.test.js test/chat-agents-picker.test.js test/chat-sandbox-attach.test.js test/credentials-file.test.js test/credentials-api.test.js test/credentials-loader.test.js test/cli-namespace-consistency.test.js test/cli-workflow-subcommands.test.js test/template-resolver.test.js test/workflow-new-template.test.js test/runner-input-state-shape.test.js test/run-bundle-core-import.test.js test/start-respects-config.test.js test/sse-backoff.test.js test/sse-reconnect-loop.test.js test/run-helpers.test.js test/run-banner.test.js test/run-banner-e2e.test.js test/sse-parser.test.js test/cloud-creds-check.test.js",
|
|
12
12
|
"test:unit": "vitest run src/",
|
|
13
13
|
"test:auth": "vitest run test/auth*.test.js test/two-layer-auth.test.js",
|
|
14
14
|
"lint": "eslint .",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zibby/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.11",
|
|
4
4
|
"description": "Zibby CLI - Test automation generator and runner",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "node ../scripts/build.mjs --extra-dirs bin",
|
|
11
|
-
"test": "vitest run test/auth*.test.js test/two-layer-auth.test.js test/trigger-params.test.js test/trigger-helpers.test.js test/deploy-helpers.test.js test/deploy-bundles-user-config.test.js test/deploy-skip-unchanged.test.js test/deploy-warm-flag.test.js test/deploy-402-formatter.test.js test/run-loads-user-config.test.js test/env-helpers.test.js test/env-cli.test.js test/chat-agents.test.js test/chat-agents-api.test.js test/chat-agents-picker.test.js test/chat-sandbox-attach.test.js test/credentials-file.test.js test/credentials-api.test.js test/credentials-loader.test.js test/cli-namespace-consistency.test.js test/cli-workflow-subcommands.test.js test/template-resolver.test.js test/workflow-new-template.test.js test/run-bundle-core-import.test.js test/start-respects-config.test.js test/sse-backoff.test.js test/sse-reconnect-loop.test.js test/run-helpers.test.js test/run-banner.test.js test/run-banner-e2e.test.js test/sse-parser.test.js test/cloud-creds-check.test.js",
|
|
11
|
+
"test": "vitest run test/auth*.test.js test/two-layer-auth.test.js test/trigger-params.test.js test/trigger-helpers.test.js test/deploy-helpers.test.js test/deploy-bundles-user-config.test.js test/deploy-skip-unchanged.test.js test/deploy-warm-flag.test.js test/deploy-402-formatter.test.js test/run-loads-user-config.test.js test/env-helpers.test.js test/env-cli.test.js test/chat-agents.test.js test/chat-agents-api.test.js test/chat-agents-picker.test.js test/chat-sandbox-attach.test.js test/credentials-file.test.js test/credentials-api.test.js test/credentials-loader.test.js test/cli-namespace-consistency.test.js test/cli-workflow-subcommands.test.js test/template-resolver.test.js test/workflow-new-template.test.js test/runner-input-state-shape.test.js test/run-bundle-core-import.test.js test/start-respects-config.test.js test/sse-backoff.test.js test/sse-reconnect-loop.test.js test/run-helpers.test.js test/run-banner.test.js test/run-banner-e2e.test.js test/sse-parser.test.js test/cloud-creds-check.test.js",
|
|
12
12
|
"test:unit": "vitest run src/",
|
|
13
13
|
"test:auth": "vitest run test/auth*.test.js test/two-layer-auth.test.js",
|
|
14
14
|
"lint": "eslint .",
|