@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.
- package/dist/auth/ensure-auth.js +17 -0
- package/dist/bin/zibby.js +2 -2
- package/dist/commands/chat.js +1 -1
- package/dist/commands/init.js +60 -60
- package/dist/commands/workflow.js +37 -36
- package/dist/commands/workflows/deploy.js +32 -16
- package/dist/commands/workflows/generate.js +26 -23
- package/dist/commands/workflows/list.js +32 -16
- package/dist/commands/workflows/logs.js +18 -18
- package/dist/commands/workflows/run.js +6 -6
- package/dist/commands/workflows/start.js +2 -2
- package/dist/commands/workflows/trigger-helpers.js +1 -1
- package/dist/commands/workflows/trigger.js +8 -8
- package/dist/package.json +2 -2
- package/package.json +2 -2
|
@@ -1,47 +1,48 @@
|
|
|
1
|
-
import{readFileSync as
|
|
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
|
|
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:
|
|
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
|
|
8
|
-
--type is required`)),console.log(o.gray(` Built-in types: ${
|
|
9
|
-
`)),process.exit(1)),!
|
|
10
|
-
Invalid workflow type: "${e}"`)),console.log(o.gray(` Built-in: ${
|
|
11
|
-
`)),process.exit(1)),e}async function
|
|
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(
|
|
14
|
-
`)),process.exit(1)}let s=await r.json();!s.graph&&s.isDefault?
|
|
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
|
-
`)),
|
|
17
|
-
${
|
|
18
|
-
`)),process.exit(1)}}function
|
|
19
|
-
`,"utf-8")
|
|
20
|
-
`,"utf-8"),console.log(o.green(`
|
|
21
|
-
|
|
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(
|
|
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
|
|
29
|
-
${
|
|
30
|
-
`)),process.exit(1)}}else{let
|
|
31
|
-
Failed to parse ${s}: ${
|
|
32
|
-
`)),process.exit(1)}let{_meta:
|
|
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: ${
|
|
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)}
|
|
38
|
-
`)),process.exit(1)}let
|
|
39
|
-
Workflow "${
|
|
40
|
-
`))}catch(
|
|
41
|
-
${
|
|
42
|
-
`)),process.exit(1)}}var
|
|
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
|
|
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
|
|
46
|
-
${
|
|
47
|
-
`)),process.exit(1)}}export{
|
|
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
|
|
2
|
-
|
|
3
|
-
`)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
`),process.exit(
|
|
8
|
-
|
|
9
|
-
`),
|
|
10
|
-
|
|
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: ${
|
|
13
|
-
`),process.exit(1)}let
|
|
14
|
-
`),process.exit(1)}
|
|
15
|
-
`),process.exit(1)}let
|
|
16
|
-
`,"utf-8")}catch(w){console.log(` Warning: failed to write ${
|
|
17
|
-
`),
|
|
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
|
|
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
|
-
},`},
|
|
15
|
-
`).map(
|
|
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: {${
|
|
20
|
-
${
|
|
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: '${
|
|
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
|
|
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(\`[${
|
|
107
|
+
console.log(\`[${n}] workflow complete \u2014 success: \${result.success !== false}\`);
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
-
`}function
|
|
111
|
-
`}function
|
|
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
|
|
131
|
-
`}function
|
|
132
|
-
`}async function
|
|
133
|
-
No name provided \u2014 generated: ${t.white(e)}`))),
|
|
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
|
|
136
|
-
|
|
137
|
-
`))
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
`))}
|
|
141
|
-
|
|
142
|
-
`)),
|
|
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
|
|
2
|
-
|
|
3
|
-
`))
|
|
4
|
-
|
|
5
|
-
|
|
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(
|
|
8
|
-
Total: ${
|
|
9
|
-
`)),console.log(
|
|
10
|
-
Error reading workflows: ${
|
|
11
|
-
`)),process.exit(1)}}async function
|
|
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
|
|
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(
|
|
17
|
-
Total: ${
|
|
18
|
-
`),console.log(" Commands:"),console.log(" zibby start <name>
|
|
19
|
-
Set ZIBBY_API_KEY to see remote workflows`),console.log("")}export{
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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:
|
|
18
|
-
`));!
|
|
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&&!
|
|
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"||
|
|
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
|
|
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(`${
|
|
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(
|
|
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
|
|
39
|
-
... more logs available. Run again or use --follow to stream.`)),
|
|
40
|
-
No running jobs. All caught up.`));break}let m=
|
|
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,
|
|
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:
|
|
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};
|