@zibby/cli 0.1.60 → 0.1.62
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/cli-login.js +12 -12
- package/dist/bin/zibby.js +2 -2
- package/dist/commands/agent-reliability.js +4 -4
- package/dist/commands/analyze-graph.js +14 -14
- package/dist/commands/chat-session-store.js +1 -1
- package/dist/commands/chat.js +71 -62
- package/dist/commands/ci-setup.js +3 -3
- package/dist/commands/generate.js +60 -21
- package/dist/commands/implement.js +15 -15
- package/dist/commands/init.js +88 -67
- package/dist/commands/list-projects.js +9 -9
- package/dist/commands/memory.js +13 -13
- package/dist/commands/project.js +8 -8
- package/dist/commands/run-capacity-queue-cli.js +2 -2
- package/dist/commands/run.js +52 -50
- package/dist/commands/setup-scripts.js +6 -6
- package/dist/commands/studio.js +21 -15
- package/dist/commands/uninstall.js +10 -10
- package/dist/commands/upload.js +15 -15
- package/dist/commands/video.js +1 -1
- package/dist/commands/workflow.js +35 -35
- package/dist/commands/workflows/delete.js +8 -0
- package/dist/commands/workflows/deploy.js +10 -10
- package/dist/commands/workflows/generate.js +17 -17
- package/dist/commands/workflows/list.js +15 -15
- package/dist/commands/workflows/logs.js +13 -13
- package/dist/commands/workflows/run.js +7 -7
- package/dist/commands/workflows/start.js +6 -6
- package/dist/commands/workflows/trigger.js +14 -8
- package/dist/config/config-loader.js +1 -1
- package/dist/config/config.js +1 -1
- package/dist/config/environments.js +1 -1
- package/dist/package.json +2 -2
- package/dist/utils/agent-credentials.js +3 -3
- package/dist/utils/chat-run-lifecycle.js +3 -3
- package/dist/utils/execution-context.js +1 -1
- package/dist/utils/progress-reporter.js +1 -1
- package/dist/utils/studio-cli-log-mirror.js +1 -1
- package/dist/utils/studio-installer.js +5 -5
- package/dist/utils/studio-launcher.js +1 -1
- package/package.json +2 -2
package/dist/auth/cli-login.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import n from"chalk";import I from"ora";import{spawn as q}from"child_process";var y={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 h(){let o;if(process.env.ZIBBY_API_URL)o=process.env.ZIBBY_API_URL;else{let e=process.env.ZIBBY_ENV||"prod";y[e]?o=y[e].apiUrl:o=y.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)`),y.prod.apiUrl):o}catch{return console.error(`\u26A0\uFE0F Invalid API URL: ${o}`),y.prod.apiUrl}}import{existsSync as P,mkdirSync as Z,readFileSync as F,writeFileSync as V}from"fs";import{homedir as T}from"os";import{join as m}from"path";function A(){return process.env.ZIBBY_CONFIG_DIR||m(T(),".zibby")}function _(){return m(A(),"config.json")}var J=m(T(),".zibby"),ro=m(J,"config.json");function M(){let o=A();P(o)||Z(o,{recursive:!0})}function u(){try{let o=_();if(P(o)){let e=F(o,"utf-8");return JSON.parse(e)}}catch{}return{}}function f(o){M(),V(_(),JSON.stringify(o,null,2))}function w(){return u().sessionToken||null}function B(o){let e=u();e.sessionToken=o,f(e)}function N(){return u().user||null}function L(o){let e=u();e.user=o,f(e)}function U(){let o=u();delete o.sessionToken,delete o.user,delete o.mem0ProxyUrl,f(o)}function C(o){let e=u();e.proxyUrl=o,f(e)}function R(o){let e=u();e.mem0ProxyUrl=o,f(e)}function z(o){let e=u();e.projects=o,f(e)}import{existsSync as G,mkdirSync as co,readFileSync as lo,writeFileSync as ao,unlinkSync as H}from"fs";import{resolve as $}from"path";import{homedir as W}from"os";function O(){let o=[$(process.cwd(),".zibby","output","active-skills.json"),$(W(),".zibby","output","active-skills.json")];for(let e of o)try{G(e)&&H(e)}catch{}}function K(o){let e=process.platform;try{let t,s;return e==="darwin"?(t="open",s=[o]):e==="win32"?(t="cmd",s=["/c","start","",o]):(t="xdg-open",s=[o]),q(t,s,{detached:!0,stdio:"ignore"}).unref(),!0}catch{return!1}}function S(){let o=w(),e=N();return o&&e?{loggedIn:!0,user:e,token:o}:{loggedIn:!1}}async function Uo(){try{console.log(n.cyan(`
|
|
2
2
|
\u{1F510} Initiating login...
|
|
3
|
-
`));
|
|
4
|
-
`));
|
|
3
|
+
`));let o=S();if(o.loggedIn){console.log(n.green("\u2705 Already logged in!")),console.log(n.gray(`User: ${o.user.email}`)),console.log(n.gray(`Name: ${o.user.name}
|
|
4
|
+
`));let{createInterface:e}=await import("readline"),t=e({input:process.stdin,output:process.stdout});return new Promise((s,a)=>{let r=()=>{t.close(),process.stdin.isTTY&&process.stdin.setRawMode(!1)},i=()=>{console.log(n.yellow(`
|
|
5
5
|
|
|
6
6
|
\u26A0\uFE0F Login cancelled
|
|
7
|
-
`)),
|
|
8
|
-
`));
|
|
9
|
-
`)),
|
|
10
|
-
\u274C Login failed:`,
|
|
7
|
+
`)),r(),process.exit(0)};process.on("SIGINT",i),t.question(n.yellow("Continue with this session? (Y/n): "),async l=>{process.removeListener("SIGINT",i),r();try{if(l.toLowerCase()==="n"||l.toLowerCase()==="no"){console.log(n.gray(`Starting new login...
|
|
8
|
+
`));let d=await E();s(d)}else console.log(n.green(`Using existing session.
|
|
9
|
+
`)),s({success:!0,...o})}catch(d){a(d)}})})}return await E()}catch(o){return console.error(n.red(`
|
|
10
|
+
\u274C Login failed:`,o.message)),{success:!1,error:o.message}}}async function X(o){let e=h();try{let t=await fetch(`${e}/projects`,{headers:{Authorization:`Bearer ${o}`}});if(t.ok){let a=((await t.json()).projects||[]).map(r=>({name:r.name,projectId:r.projectId,apiToken:r.apiToken}));return z(a),a}}catch(t){console.log(n.gray(`\u26A0\uFE0F Could not fetch projects: ${t.message}`))}return[]}async function E(){let o=h(),e=I("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 g=await t.json();throw new Error(g.error||"Failed to initiate login")}let{deviceCode:s,userCode:a,verificationUrl:r,expiresIn:i,interval:l}=await t.json();e.succeed("Login code generated"),console.log(""),console.log(n.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(n.cyan("\u2551")+n.white.bold(" Complete login in your browser ")+n.cyan("\u2551")),console.log(n.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(n.white("Opening browser to login page...")),console.log(n.gray(`Code expires in ${Math.floor(i/60)} minutes`)),console.log(""),await K(r)||(console.log(n.yellow("\u26A0\uFE0F Could not open browser automatically.")),console.log(n.white("Please open this URL manually: ")+n.blue(r)),console.log(""));let p=I("Waiting for authorization...").start(),D=(l||3)*1e3,Y=Math.floor(i/(l||3)),x=0,b=!1,k=()=>{b=!0,p.stop(),console.log(n.yellow(`
|
|
11
11
|
|
|
12
12
|
\u26A0\uFE0F Login cancelled
|
|
13
|
-
`)),process.exit(0)};process.on("SIGINT",k);try{for(;
|
|
14
|
-
`)),{success:!0,loggedIn:!0,user:
|
|
13
|
+
`)),process.exit(0)};process.on("SIGINT",k);try{for(;x<Y&&!b;){await Q(D),x++;let g=await fetch(`${o}/cli/login/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({deviceCode:s})});if(g.status===202)continue;if(!g.ok){p.fail("Authorization failed");let v=await g.json();throw new Error(v.error||"Authorization failed")}let c=await g.json();if(c.status==="authorized"){p.succeed(n.white("Authorization successful!")),B(c.token),L(c.user),c.proxyUrl&&C(c.proxyUrl),c.mem0ProxyUrl&&R(c.mem0ProxyUrl),console.log(""),console.log(n.gray(`User: ${c.user.email}`));let v=I("Fetching projects...").start(),j=await X(c.token);return v.succeed(`Fetched ${j.length} project${j.length!==1?"s":""}`),console.log(n.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",k)}}function Io(){if(!S().loggedIn){console.log(n.yellow(`
|
|
15
15
|
\u26A0\uFE0F Not logged in.
|
|
16
|
-
`));return}
|
|
17
|
-
`))}async function
|
|
18
|
-
`));return}if(console.log(
|
|
16
|
+
`));return}U(),O(),console.log(n.green("\u2714")+n.white(" Logged out successfully!")),console.log(n.gray(`Session cleared from ~/.zibby/config.json
|
|
17
|
+
`))}async function So(o={}){let e=S(),t=process.env.ZIBBY_USER_TOKEN,s=h(),a=t||e.token;if(o.json){let r={authenticated:!!(e.loggedIn||t),user:e.user||null,tokenSource:t?"environment":e.token?"session":null,tokenType:t?"PAT":e.token?"JWT":null,apiUrl:s,configPath:e.loggedIn?"~/.zibby/config.json":null};if(a)try{let i=await fetch(`${s}/projects`,{headers:{Authorization:`Bearer ${a}`}});if(r.tokenValid=i.ok,i.ok){let l=await i.json();r.projectCount=(l.projects||[]).length}}catch(i){r.tokenValid=!1,r.error=i.message}else r.tokenValid=!1;console.log(JSON.stringify(r,null,2));return}if(console.log(""),!e.loggedIn&&!t){console.log(n.yellow("\u26A0\uFE0F Not authenticated")),console.log(""),console.log(n.white("To authenticate:")),console.log(n.gray(" Local: zibby login")),console.log(n.gray(` CI/CD: Set ZIBBY_USER_TOKEN env variable
|
|
18
|
+
`));return}if(console.log(n.green("\u2705 Authenticated")),console.log(""),console.log(n.bold.white("User Details:")),e.user?(console.log(n.gray(` Email: ${e.user.email}`)),e.user.userId&&console.log(n.gray(` User ID: ${e.user.userId}`)),e.user.name&&console.log(n.gray(` Name: ${e.user.name}`))):t&&console.log(n.gray(" (User details not available with PAT token)")),console.log(""),console.log(n.bold.white("Token Source:")),t?(console.log(n.gray(" Type: Personal Access Token (PAT)")),console.log(n.gray(" Location: ZIBBY_USER_TOKEN environment variable")),console.log(n.gray(` Preview: ${t.substring(0,8)}\u2022\u2022\u2022\u2022`))):(console.log(n.gray(" Type: Session Token (JWT)")),console.log(n.gray(" Location: ~/.zibby/config.json")),e.token&&console.log(n.gray(` Preview: ${e.token.substring(0,8)}\u2022\u2022\u2022\u2022`))),console.log(""),a)try{let r=(await import("ora")).default,i=r("Verifying authentication...").start(),l=await fetch(`${s}/projects`,{headers:{Authorization:`Bearer ${a}`}});if(l.ok){let p=((await l.json()).projects||[]).length;i.succeed(n.white("Token verified")),console.log(n.gray(` Projects: ${p} accessible`))}else i.fail(n.white("Token verification failed")),console.log(n.yellow(` Status: Invalid or expired (HTTP ${l.status})`))}catch(r){console.log(n.yellow(` Status: Could not verify (${r.message})`))}console.log(""),console.log(n.gray("\u{1F4A1} Run 'zibby list' to see your projects")),console.log("")}async function xo(){let o=w();if(!o)return{valid:!1};let e=h();try{return(await fetch(`${e}/projects`,{headers:{Authorization:`Bearer ${o}`}})).ok?{valid:!0}:(U(),{valid:!1})}catch{return{valid:!1}}}function Q(o){return new Promise(e=>setTimeout(e,o))}export{S as checkExistingSession,Uo as loginCli,Io as logoutCli,So as showLoginStatus,xo as validateSession};
|
package/dist/bin/zibby.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
process.stdout.on("error",o=>{o.code}),process.stderr.on("error",o=>{o.code}),process.env.DOTENV_CONFIG_QUIET="true";import"@zibby/skills";import{Command as p}from"commander";import{initCommand as
|
|
3
|
-
`),C(process.cwd());const _=i[0]==="chat",x=["--verbose","--agent","--stream","-s"],A=i.length>0&&i.every(o=>x.includes(o)||i[i.indexOf(o)-1]==="--agent"),B=i.length===0||_||A;if(B&&!j){const o={},t=i.indexOf("--agent");t!==-1&&i[t+1]&&(o.agent=i[t+1]),i.includes("--verbose")&&(o.verbose=!0),(i.includes("--stream")||i.includes("-s"))&&(o.stream=!0);const{chatCommand:n}=await import("../commands/chat.js");await n(o),process.exit(0)}const e=new p;e.name("zibby").description("Zibby Test Automation - AI-powered test generation").version(r.version,"-V, --version"),e.command("init").description("Initialize a new Zibby test project (like rails new)").argument("[project-name]","Project name (optional, uses current directory if not provided)").option("--agent <type>","Agent to use (claude, cursor, codex, gemini)").option("--memory-backend <backend>","Memory backend to configure (dolt, mem0)","dolt").option("--skip-install","Skip npm install").option("--skip-memory","Skip test memory setup during initialization").option("-f, --force","Force reinitialize (overwrite existing config)").option("--headed","Run MCP browser in headed mode (visible browser)").option("--headless","Run MCP browser in headless mode (hidden browser)").option("--api-key <key>","Zibby API key for cloud sync").option("--cloud-sync","Enable cloud sync and install Zibby MCP").action(d),e.command("test").description("Run a test specification").argument("[spec-path]","Path to test spec file or inline test description in quotes").option("--sources <ids>","Comma-separated test case IDs to fetch from cloud").option("--execution <id>","Execution ID containing the test cases (required with --sources)").option("--agent <type>","Agent to use (claude, cursor, codex, gemini) - overrides config").option("--workflow <name>","Workflow to use (e.g., QuickSmokeWorkflow, quick-smoke)").option("--headless","Run browser in headless mode").option("--node <name>","Run only a specific node (e.g., execute_live, generate_script)").option("--session <id>",'Use existing session (e.g., 1768974629717 or "last") - requires --node').option("--session-path <dir>","Use this session folder (absolute or relative to cwd); Studio pins artifacts here").option("--project <id>","Project ID (optional, auto-detected from ZIBBY_API_KEY)").option("--collection <id-or-name>","Collection ID or name (creates new if name doesn't exist)").option("--folder <path>","Folder path within collection (optional, requires --collection)").option("--sync","Force upload to cloud (overrides cloudSync: false)").option("--no-sync","Skip upload to cloud (overrides cloudSync: true)").option("--config <path>","Path to config file",".zibby.config.mjs").option("--auto-approve","Auto-approve MCP tools (for CI/CD)").option("-o, --open","Open test results in browser after completion").option("--verbose","Show info level logs").option("--debug","Show debug level logs (most verbose)").option("-m, --mem","Enable test memory (Dolt-backed knowledge from previous runs)").action((o,t)=>(t.debug?process.env.ZIBBY_DEBUG="true":t.verbose&&(process.env.ZIBBY_VERBOSE="true"),l(o,t))),e.command("implement").description("Implement a Jira ticket using AI agent (runs in ECS container)").action(async(...o)=>{const{implementCommand:t}=await import("../commands/implement.js");return t(...o)}),e.command("analyze").description("Analyze a Jira ticket against the codebase (runs in ECS container)").option("--workflow <path>","Path to a local workflow JSON file (e.g., .zibby/workflow-analysis.json)").action(async(...o)=>{const{analyzeCommand:t}=await import("../commands/analyze-graph.js");return t(...o)}),e.command("video").description("Organize test videos next to test files").action(m),e.command("upload <spec-path>").description("Upload existing test artifacts to Zibby Cloud").option("--project <id>","Project ID (REQUIRED - use flag or ZIBBY_PROJECT_ID env)").option("--collection <id-or-name>","Collection ID or name (creates new if name doesn't exist)").option("--folder <path>","Folder path within collection (optional)").option("--agent <type>","Agent used (for metadata)").action(u),e.command("login").description("Log in to Zibby (opens browser for authentication)").action(async()=>{const{loginCli:o}=await import("../auth/cli-login.js");await o(),process.exit(0)}),e.command("logout").description("Log out from Zibby (clears saved session)").action(async()=>{const{logoutCli:o}=await import("../auth/cli-login.js");o(),process.exit(0)}),e.command("status").description("Show current authentication status and token details").option("--json","Output in JSON format (for scripts)").action(async o=>{const{showLoginStatus:t}=await import("../auth/cli-login.js");await t(o),process.exit(0)}),e.command("list").description("List your projects and API tokens").action(async()=>{const{listProjectsCommand:o}=await import("../commands/list-projects.js");await o()}),e.command("ci-setup").description("Setup Cursor Agent for CI/CD (patch and configure)").option("--get-keys","Get MCP approval keys").option("--save","Save approval keys to project").action(f),e.command("setup-playwright").description("Setup official Playwright MCP (from cursor-agent-package)").option("--headed","Configure MCP in headed mode (visible browser)").option("--viewport-width <width>","Viewport width (default: 1280)","1280").option("--viewport-height <height>","Viewport height (default: 720)","720").action(o=>{const t={width:parseInt(o.viewportWidth,10)||1280,height:parseInt(o.viewportHeight,10)||720};return w({...o,viewport:t})}),e.command("setup-ci-full").description("Complete CI/CD setup from scratch").action(y),e.command("test-video").description("Run Playwright tests with video recording").argument("[test-file]","Test file to run (default: tests/)").option("--headed","Run in headed mode (visible browser)").action(g),e.command("generate").description("Generate test specs from a ticket + codebase (local analysis using real AI agent)").option("-t, --ticket <key>","Jira ticket key (fetches automatically)").option("-i, --input <file>","Input file with ticket description/requirements").option("-d, --description <text>","Inline ticket description").option("--repo <path>","Path to the codebase (default: current directory)").option("--agent <type>","Agent to use (codex, claude, cursor, gemini)").option("--model <model>","Model override").option("-o, --output <dir>","Output directory for spec files (default: test-specs)").action(async o=>{const{generateCommand:t}=await import("../commands/generate.js");return t(o)}),e.command("studio").description("Launch Zibby Studio desktop (installs from CDN if needed). Uses this folder as the Zibby project.").option("-p, --port <port>","Port for the Studio API bridge (default: 3847)").option("--no-open","Start the API only; do not launch desktop app").option("--update","Force re-download of the latest Studio binary").action(async o=>{const{studioCommand:t}=await import("../commands/studio.js");return t(o)});const E=e.command("g").description("Generate scaffolds");E.command("workflow [name]").description("Scaffold a new custom workflow in .zibby/workflows/<name>/ (auto-generates name if omitted)").action(async o=>{const{generateWorkflowCommand:t}=await import("../commands/workflows/generate.js");return t(o)}),e.command("start <workflow-name>").description("Start a local dev server for a custom workflow").option("-p, --port <port>","Port for the workflow server (default: 3848)").action(async(o,t)=>{const{startWorkflowCommand:n}=await import("../commands/workflows/start.js");return n(o,t)}),e.command("deploy [workflow-name]").description("Deploy a custom workflow to Zibby Cloud (interactive selection if workflow-name not provided)").option("--project <id>","Project ID (interactive prompt if not provided, or ZIBBY_PROJECT_ID env)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(o,t)=>{const{deployWorkflowCommand:n}=await import("../commands/workflows/deploy.js");return n(o,t)}),e.command("trigger [workflow-name]").description("Trigger a deployed workflow to run in the cloud (interactive selection if not provided)").option("--project <id>","Project ID (interactive prompt if not provided, or ZIBBY_PROJECT_ID env)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").option("--input <json>",`Input data as JSON string (e.g., '{"key":"value"}')`).option("--idempotency-key <key>","Idempotency key to prevent duplicate executions").action(async(o,t)=>{const{triggerWorkflowCommand:n}=await import("../commands/workflows/trigger.js");return n(o,t)}),e.command("logs [jobId]").description("Tail logs from a workflow job or all executions of a workflow").option("--project <id>","Project ID (or ZIBBY_PROJECT_ID env)").option("--workflow <name>","Workflow name (tails the latest run)").option("--all","Show interleaved logs from all runs (requires --workflow)").option("-t, --tail-latest","Auto-tail newest execution (scrollable history)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").option("--no-follow","Fetch logs once and exit (default: tail)").option("--lines <n>","Max log lines per fetch (default: 500)").action(async(o,t)=>{const{logsCommand:n}=await import("../commands/workflows/logs.js");return n(o,t)}),e.command("run-workflow").description("Run a deployed workflow from S3 sources (used by ECS containers)").action(async()=>{const{runWorkflowCommand:o}=await import("../commands/workflows/run.js");return o()});const a=e.command("memory").description("Test memory database \u2014 version-controlled knowledge from runs");a.command("stats").description("Show memory database statistics").action(async()=>{const{memoryStatsCommand:o}=await import("../commands/memory.js");return o()}),a.command("init").description("Initialize the memory database (Dolt)").action(async()=>{const{memoryInitCommand:o}=await import("../commands/memory.js");return o()}),a.command("compact").description("Prune old data and run Dolt GC to reclaim storage").option("--max-runs <n>","Keep last N runs per spec (default: 50)",parseInt).option("--max-age <days>","Remove data older than N days (default: 90)",parseInt).action(async o=>{const{memoryCompactCommand:t}=await import("../commands/memory.js");return t(o)}),a.command("reset").description("Wipe the memory database").option("-f, --force","Confirm reset").action(async o=>{const{memoryResetCommand:t}=await import("../commands/memory.js");return t(o)});const c=e.command("workflow").description("Manage workflow graphs (download, upload, list)");c.command("download").description("Download a workflow graph from Zibby Cloud to .zibby/").option("--project <id>","Project ID (or ZIBBY_PROJECT_ID env)").option("--type <type>","Workflow type: analysis, implementation, run_test").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").option("--output <dir>","Output directory (default: .zibby/)").option("--include-default","Download the built-in default graph if no custom one exists").action(async o=>{const{workflowDownloadCommand:t}=await import("../commands/workflow.js");return t(o)}),c.command("list").description("List all workflows (local + remote if credentials available)").option("--local-only","Show only local workflows").option("--remote-only","Show only remote workflows (requires --project)").option("--project <id>","Project ID (optional, uses ZIBBY_PROJECT_ID env)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async o=>{if(o.remoteOnly){const{workflowListCommand:n}=await import("../commands/workflow.js");return n(o)}if(o.localOnly){const{listLocalWorkflowsCommand:n}=await import("../commands/workflows/list.js");return n(o)}const{listAllWorkflowsCommand:t}=await import("../commands/workflows/list.js");return t(o)});const D=e.command("project").description("Manage Zibby projects");D.command("list").description("List all projects").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async o=>{const{projectListCommand:t}=await import("../commands/project.js");return t(o)});const Z=e.command("run-queue").description("Parallel capacity \u2014 on-disk wait queue (see parallel.waitWhenAtCapacity in .zibby.config.mjs)");Z.command("list").description("List CLI processes waiting for a run slot").option("--config <path>","Path to config file",".zibby.config.mjs").action(async o=>{const{runCapacityQueueListCommand:t}=await import("../commands/run-capacity-queue-cli.js");await t(o),process.exit(0)}),e.command("uninstall").description("Remove all Zibby data: global CLI, ~/.zibby, Cursor MCP config, Studio, and current project").option("--dry-run","Show what would be deleted without deleting").option("--deep","Also remove npx cache dirs containing zibby").action(async o=>{const{uninstallCommand:t}=await import("../commands/uninstall.js");await t(o),process.exit(0)}),e.parse();
|
|
2
|
+
process.stdout.on("error",o=>{o.code}),process.stderr.on("error",o=>{o.code}),process.env.DOTENV_CONFIG_QUIET="true";import"@zibby/skills";import{Command as p}from"commander";import{initCommand as l}from"../commands/init.js";import{runCommand as m}from"../commands/run.js";import{videoCommand as u}from"../commands/video.js";import{uploadCommand as f}from"../commands/upload.js";import{ciSetupCommand as w}from"../commands/ci-setup.js";import{setupPlaywrightMcpCommand as y,setupCiCommand as g,testWithVideoCommand as h}from"../commands/setup-scripts.js";import{readFileSync as k}from"fs";import{fileURLToPath as b}from"url";import{dirname as v,join as C}from"path";import{bootstrapAgentEnv as I}from"../utils/agent-credentials.js";const P=b(import.meta.url),j=v(P),s=JSON.parse(k(C(j,"../package.json"),"utf-8")),c=`zibby v${s.version}`,i=process.argv.slice(2),S=i.includes("-h")||i.includes("--help"),_=i.includes("-v")||i.includes("-V")||i.includes("--version");_&&(console.log(c),process.exit(0));const d=i[0],x=i[1],A=["logs","uninstall"],D=d==="workflow"&&x==="list";!A.includes(d)&&!D&&console.log(`${c}
|
|
3
|
+
`),I(process.cwd());const B=i[0]==="chat",E=["--verbose","--agent","--stream","-s"],Z=i.length>0&&i.every(o=>E.includes(o)||i[i.indexOf(o)-1]==="--agent"),O=i.length===0||B||Z;if(O&&!S){const o={},t=i.indexOf("--agent");t!==-1&&i[t+1]&&(o.agent=i[t+1]),i.includes("--verbose")&&(o.verbose=!0),(i.includes("--stream")||i.includes("-s"))&&(o.stream=!0);const{chatCommand:n}=await import("../commands/chat.js");await n(o),process.exit(0)}const e=new p;e.name("zibby").description("Zibby Test Automation - AI-powered test generation").version(s.version,"-V, --version"),e.command("init").description("Initialize a new Zibby test project (like rails new)").argument("[project-name]","Project name (optional, uses current directory if not provided)").option("--agent <type>","Agent to use (claude, cursor, codex, gemini)").option("--memory-backend <backend>","Memory backend to configure (dolt, mem0)","dolt").option("--skip-install","Skip npm install").option("--skip-memory","Skip test memory setup during initialization").option("-f, --force","Force reinitialize (overwrite existing config)").option("--headed","Run MCP browser in headed mode (visible browser)").option("--headless","Run MCP browser in headless mode (hidden browser)").option("--api-key <key>","Zibby API key for cloud sync").option("--cloud-sync","Enable cloud sync and install Zibby MCP").action(l),e.command("test").description("Run a test specification").argument("[spec-path]","Path to test spec file or inline test description in quotes").option("--sources <ids>","Comma-separated test case IDs to fetch from cloud").option("--execution <id>","Execution ID containing the test cases (required with --sources)").option("--agent <type>","Agent to use (claude, cursor, codex, gemini) - overrides config").option("--workflow <name>","Workflow to use (e.g., QuickSmokeWorkflow, quick-smoke)").option("--headless","Run browser in headless mode").option("--node <name>","Run only a specific node (e.g., execute_live, generate_script)").option("--session <id>",'Use existing session (e.g., 1768974629717 or "last") - requires --node').option("--session-path <dir>","Use this session folder (absolute or relative to cwd); Studio pins artifacts here").option("--project <id>","Project ID (optional, auto-detected from ZIBBY_API_KEY)").option("--collection <id-or-name>","Collection ID or name (creates new if name doesn't exist)").option("--folder <path>","Folder path within collection (optional, requires --collection)").option("--sync","Force upload to cloud (overrides cloudSync: false)").option("--no-sync","Skip upload to cloud (overrides cloudSync: true)").option("--config <path>","Path to config file",".zibby.config.mjs").option("--auto-approve","Auto-approve MCP tools (for CI/CD)").option("-o, --open","Open test results in browser after completion").option("--verbose","Show info level logs").option("--debug","Show debug level logs (most verbose)").option("-m, --mem","Enable test memory (Dolt-backed knowledge from previous runs)").action((o,t)=>(t.debug?process.env.ZIBBY_DEBUG="true":t.verbose&&(process.env.ZIBBY_VERBOSE="true"),m(o,t))),e.command("implement").description("Implement a Jira ticket using AI agent (runs in ECS container)").action(async(...o)=>{const{implementCommand:t}=await import("../commands/implement.js");return t(...o)}),e.command("analyze").description("Analyze a Jira ticket against the codebase (runs in ECS container)").option("--workflow <path>","Path to a local workflow JSON file (e.g., .zibby/workflow-analysis.json)").action(async(...o)=>{const{analyzeCommand:t}=await import("../commands/analyze-graph.js");return t(...o)}),e.command("video").description("Organize test videos next to test files").action(u),e.command("upload <spec-path>").description("Upload existing test artifacts to Zibby Cloud").option("--project <id>","Project ID (REQUIRED - use flag or ZIBBY_PROJECT_ID env)").option("--collection <id-or-name>","Collection ID or name (creates new if name doesn't exist)").option("--folder <path>","Folder path within collection (optional)").option("--agent <type>","Agent used (for metadata)").action(f),e.command("login").description("Log in to Zibby (opens browser for authentication)").action(async()=>{const{loginCli:o}=await import("../auth/cli-login.js");await o(),process.exit(0)}),e.command("logout").description("Log out from Zibby (clears saved session)").action(async()=>{const{logoutCli:o}=await import("../auth/cli-login.js");o(),process.exit(0)}),e.command("status").description("Show current authentication status and token details").option("--json","Output in JSON format (for scripts)").action(async o=>{const{showLoginStatus:t}=await import("../auth/cli-login.js");await t(o),process.exit(0)}),e.command("list").description("List your projects and API tokens").action(async()=>{const{listProjectsCommand:o}=await import("../commands/list-projects.js");await o()}),e.command("ci-setup").description("Setup Cursor Agent for CI/CD (patch and configure)").option("--get-keys","Get MCP approval keys").option("--save","Save approval keys to project").action(w),e.command("setup-playwright").description("Setup official Playwright MCP (from cursor-agent-package)").option("--headed","Configure MCP in headed mode (visible browser)").option("--viewport-width <width>","Viewport width (default: 1280)","1280").option("--viewport-height <height>","Viewport height (default: 720)","720").action(o=>{const t={width:parseInt(o.viewportWidth,10)||1280,height:parseInt(o.viewportHeight,10)||720};return y({...o,viewport:t})}),e.command("setup-ci-full").description("Complete CI/CD setup from scratch").action(g),e.command("test-video").description("Run Playwright tests with video recording").argument("[test-file]","Test file to run (default: tests/)").option("--headed","Run in headed mode (visible browser)").action(h),e.command("generate").description("Generate test specs from a ticket + codebase (local analysis using real AI agent)").option("-t, --ticket <key>","Jira ticket key (fetches automatically)").option("-i, --input <file>","Input file with ticket description/requirements").option("-d, --description <text>","Inline ticket description").option("--repo <path>","Path to the codebase (default: current directory)").option("--agent <type>","Agent to use (codex, claude, cursor, gemini)").option("--model <model>","Model override").option("-o, --output <dir>","Output directory for spec files (default: test-specs)").action(async o=>{const{generateCommand:t}=await import("../commands/generate.js");return t(o)}),e.command("studio").description("Launch Zibby Studio desktop (installs from CDN if needed). Uses this folder as the Zibby project.").option("-p, --port <port>","Port for the Studio API bridge (default: 3847)").option("--no-open","Start the API only; do not launch desktop app").option("--update","Force re-download of the latest Studio binary").action(async o=>{const{studioCommand:t}=await import("../commands/studio.js");return t(o)});const Y=e.command("g").description("Generate scaffolds");Y.command("workflow [name]").description("Scaffold a new custom workflow in .zibby/workflows/<name>/ (auto-generates name if omitted)").action(async o=>{const{generateWorkflowCommand:t}=await import("../commands/workflows/generate.js");return t(o)}),e.command("start <workflow-name>").description("Start a local dev server for a custom workflow").option("-p, --port <port>","Port for the workflow server (default: 3848)").action(async(o,t)=>{const{startWorkflowCommand:n}=await import("../commands/workflows/start.js");return n(o,t)}),e.command("deploy [workflow-name]").description("Deploy a custom workflow to Zibby Cloud (interactive selection if workflow-name not provided)").option("--project <id>","Project ID (interactive prompt if not provided, or ZIBBY_PROJECT_ID env)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(o,t)=>{const{deployWorkflowCommand:n}=await import("../commands/workflows/deploy.js");return n(o,t)}),e.command("trigger [workflow-name]").description("Trigger a deployed workflow to run in the cloud (interactive selection if not provided)").option("--project <id>","Project ID (interactive prompt if not provided, or ZIBBY_PROJECT_ID env)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").option("--input <json>",`Input data as JSON string (e.g., '{"key":"value"}')`).option("--idempotency-key <key>","Idempotency key to prevent duplicate executions").action(async(o,t)=>{const{triggerWorkflowCommand:n}=await import("../commands/workflows/trigger.js");return n(o,t)}),e.command("logs [jobId]").description("Tail logs from a workflow job or all executions of a workflow").option("--project <id>","Project ID (or ZIBBY_PROJECT_ID env)").option("--workflow <name>","Workflow name (tails the latest run)").option("--all","Show interleaved logs from all runs (requires --workflow)").option("-t, --tail-latest","Auto-tail newest execution (scrollable history)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").option("--no-follow","Fetch logs once and exit (default: tail)").option("--lines <n>","Max log lines per fetch (default: 500)").action(async(o,t)=>{const{logsCommand:n}=await import("../commands/workflows/logs.js");return n(o,t)}),e.command("run-workflow").description("Run a deployed workflow from S3 sources (used by ECS containers)").action(async()=>{const{runWorkflowCommand:o}=await import("../commands/workflows/run.js");return o()});const a=e.command("memory").description("Test memory database \u2014 version-controlled knowledge from runs");a.command("stats").description("Show memory database statistics").action(async()=>{const{memoryStatsCommand:o}=await import("../commands/memory.js");return o()}),a.command("init").description("Initialize the memory database (Dolt)").action(async()=>{const{memoryInitCommand:o}=await import("../commands/memory.js");return o()}),a.command("compact").description("Prune old data and run Dolt GC to reclaim storage").option("--max-runs <n>","Keep last N runs per spec (default: 50)",parseInt).option("--max-age <days>","Remove data older than N days (default: 90)",parseInt).action(async o=>{const{memoryCompactCommand:t}=await import("../commands/memory.js");return t(o)}),a.command("reset").description("Wipe the memory database").option("-f, --force","Confirm reset").action(async o=>{const{memoryResetCommand:t}=await import("../commands/memory.js");return t(o)});const r=e.command("workflow").description("Manage workflow graphs (download, upload, list)");r.command("download").description("Download a workflow graph from Zibby Cloud to .zibby/").option("--project <id>","Project ID (or ZIBBY_PROJECT_ID env)").option("--type <type>","Workflow type: analysis, implementation, run_test").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").option("--output <dir>","Output directory (default: .zibby/)").option("--include-default","Download the built-in default graph if no custom one exists").action(async o=>{const{workflowDownloadCommand:t}=await import("../commands/workflow.js");return t(o)}),r.command("list").description("List all workflows (local + remote if credentials available)").option("--local-only","Show only local workflows").option("--remote-only","Show only remote workflows (requires --project)").option("--project <id>","Project ID (optional, uses ZIBBY_PROJECT_ID env)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async o=>{if(o.remoteOnly){const{workflowListCommand:n}=await import("../commands/workflow.js");return n(o)}if(o.localOnly){const{listLocalWorkflowsCommand:n}=await import("../commands/workflows/list.js");return n(o)}const{listAllWorkflowsCommand:t}=await import("../commands/workflows/list.js");return t(o)}),r.command("delete <uuid>").description("Delete a deployed workflow by UUID").action(async o=>{const{deleteWorkflowCommand:t}=await import("../commands/workflows/delete.js");return t(o,{})});const R=e.command("project").description("Manage Zibby projects");R.command("list").description("List all projects").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async o=>{const{projectListCommand:t}=await import("../commands/project.js");return t(o)});const z=e.command("run-queue").description("Parallel capacity \u2014 on-disk wait queue (see parallel.waitWhenAtCapacity in .zibby.config.mjs)");z.command("list").description("List CLI processes waiting for a run slot").option("--config <path>","Path to config file",".zibby.config.mjs").action(async o=>{const{runCapacityQueueListCommand:t}=await import("../commands/run-capacity-queue-cli.js");await t(o),process.exit(0)}),e.command("uninstall").description("Remove all Zibby data: global CLI, ~/.zibby, Cursor MCP config, Studio, and current project").option("--dry-run","Show what would be deleted without deleting").option("--deep","Also remove npx cache dirs containing zibby").action(async o=>{const{uninstallCommand:t}=await import("../commands/uninstall.js");await t(o),process.exit(0)}),e.parse();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
var f={cli_reliable_v1:{title:"General intelligence reliability contract",operatingRules:["Evidence-first reasoning: ground conclusions in observed outputs or tool evidence, not guesses.","No false completion: never claim success for a state-changing action until verification confirms it.","Execution integrity: do not claim any external action unless the matching tool call actually happened.","Bounded recovery: for transient failures, retry with adjusted parameters up to 2 times, then escalate with blocker + next step.",'Binary-answer discipline: for yes/no questions, verify the exact asked condition before answering; do not answer "yes" from a broader or approximate match.'],executionSafety:["Prefer low-blast-radius, reversible actions first.","Before irreversible or high-impact actions, confirm explicit user intent unless already authorized.","If verification cannot be run, state that limitation explicitly."],investigationLoop:["For unclear failures, follow this loop: detect -> gather evidence -> form hypothesis -> test hypothesis -> conclude.","If evidence is insufficient, explicitly collect more before proposing a root cause.","Prefer smallest validating action first before broad or costly retries."],responseQuality:["State assumptions explicitly when certainty is low.","Differentiate facts, hypotheses, and next actions.","Keep reports concise but decision-useful.","If related-but-not-identical matches exist, report them separately as context, not as the direct yes/no answer."],incidentTemplate:["ONLY when diagnosing failures or errors (never for successful actions), structure your response as: Root cause, Evidence, Attempted fixes, Current status, Next action."],skillRunbooks:{}}},y=2e3,p=12e3;function c(t=[]){if(!Array.isArray(t))return[];let r=new Set,i=[];for(let n of t){let e=String(n||"").replace(/\s+/g," ").trim();e&&(r.has(e)||(r.add(e),i.push(e)))}return i}function m(t,r=y){let i=String(t||"");return i.length<=r?i:`${i.slice(0,Math.max(0,r-14)).trimEnd()}
|
|
2
2
|
|
|
3
|
-
[truncated]`}function s(t,r=[],i=
|
|
4
|
-
`);return m(e,i)}function b(t){return!t||typeof t!="object"||Array.isArray(t)?null:t}function g(t,r){
|
|
3
|
+
[truncated]`}function s(t,r=[],i=y){let n=c(r);if(n.length===0)return"";let e=[`## ${t}`,...n.map(o=>`- ${o}`)].join(`
|
|
4
|
+
`);return m(e,i)}function b(t){return!t||typeof t!="object"||Array.isArray(t)?null:t}function g(t,r){let i={...t,...r},n=["operatingRules","rules","executionSafety","investigationLoop","responseQuality","incidentTemplate"];for(let e of n)Array.isArray(r?.[e])?i[e]=[...c(t?.[e]||[]),...c(r[e])]:Array.isArray(t?.[e])&&(i[e]=[...c(t[e])]);return i.skillRunbooks={...t?.skillRunbooks||{},...r?.skillRunbooks||{}},i}function h(t={},r={}){let i=Array.isArray(t?.reliabilityAppendSections)?t.reliabilityAppendSections:[],n=Array.isArray(r?.reliabilityAppendSections)?r.reliabilityAppendSections:[];return[...i,...n].map(e=>{if(typeof e=="string")return{title:"Additional reliability guidance",lines:[e]};if(!e||typeof e!="object")return null;let o=String(e.title||"Additional reliability guidance").trim(),l=Array.isArray(e.lines)?e.lines:[];return{title:o,lines:l}}).filter(Boolean)}function A(t={},r={}){let i=String(r.reliabilityProfile||process.env.ZIBBY_RELIABILITY_PROFILE||t.reliabilityProfile||"cli_reliable_v1").trim(),n=t?.reliabilityProfiles?.[i];if(typeof n=="string"&&n.trim())return{name:i,text:n.trim()};if(n&&typeof n.instruction=="string"&&n.instruction.trim())return{name:i,text:n.instruction.trim()};let e=f[i]||f.cli_reliable_v1,o=b(n),l=o?g(e,o):e;return{name:i,defaults:l}}function x({activeSkills:t=[],chatConfig:r={},options:i={}}={}){let n=A(r,i);if(n.text)return n.text;let e=n.defaults||f.cli_reliable_v1,o=[s(e.title||"Reliability contract",e.operatingRules||e.rules||[]),s("Execution safety",e.executionSafety||[]),s("Investigation loop",e.investigationLoop||[]),s("Response quality",e.responseQuality||[]),s("Failure reporting format",e.incidentTemplate||[])],l=e.skillRunbooks||{};for(let a of t)l[a]&&o.push(s(`Runbook: ${a}`,l[a]));let d=h(r,i);for(let a of d)o.push(s(a.title,a.lines));let u=o.filter(Boolean).join(`
|
|
5
5
|
|
|
6
|
-
`).trim();return u.length<=
|
|
6
|
+
`).trim();return u.length<=p?u:`${u.slice(0,Math.max(0,p-14)).trimEnd()}
|
|
7
7
|
|
|
8
8
|
[truncated]`}export{x as buildReliabilityInstruction};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{dirname as
|
|
3
|
-
`);
|
|
4
|
-
`);
|
|
5
|
-
`),
|
|
6
|
-
`)}))},500);try{await
|
|
7
|
-
`);if(
|
|
8
|
-
`),
|
|
2
|
+
import{dirname as G,join as L,resolve as J}from"path";import{fileURLToPath as b}from"url";import{readFileSync as j,existsSync as B}from"fs";import{compileGraph as Q,validateGraphConfig as z}from"@zibby/core/framework/graph-compiler.js";import{WorkflowGraph as W}from"@zibby/core/framework/graph.js";import{buildAnalysisGraph as q}from"@zibby/core/templates/code-analysis/graph.js";import{analysisStateSchema as H}from"@zibby/core/templates/code-analysis/state.js";import"@zibby/core/templates/register-nodes.js";async function k(r,t){let a=process.env.CONTEXT_PRESIGNED_URL;if(!a)throw new Error("CONTEXT_PRESIGNED_URL env var is required");console.log("\u{1F4E6} Fetching execution context via pre-signed URL");let e=await fetch(a);if(!e.ok)throw new Error(`Failed to fetch execution context: ${e.status}`);let o=await e.json();return console.log(` \u2705 Got ticketContext (${JSON.stringify(o.ticketContext||{}).length} chars)`),o.nodeConfigs&&Object.keys(o.nodeConfigs).length>0&&console.log(` \u2705 Got nodeConfigs (${Object.keys(o.nodeConfigs).length} nodes configured)`),{ticketContext:o.ticketContext||{},nodeConfigs:o.nodeConfigs||{},graphConfig:o.graphConfig||null,repos:o.repos||[]}}import{SQSClient as M,SendMessageCommand as D}from"@aws-sdk/client-sqs";var I=null;function F(){return I||(I=new M({region:process.env.AWS_REGION||"ap-southeast-2"})),I}async function N(r,t,a,e){let{EXECUTION_ID:o,SQS_AUTH_TOKEN:s,PROGRESS_API_URL:d,PROGRESS_QUEUE_URL:l,PROJECT_API_TOKEN:u}=e;if(!o)return;let f={executionId:o,...s&&{sqsAuthToken:s},step:{name:r,status:t,logs:a,timestamp:new Date().toISOString(),...t==="success"&&{completedAt:new Date().toISOString()}},status:t==="failed"?"failed":"running"};try{d?await v(d,o,f,u):l&&await U(l,o,f)}catch(m){console.error(`\u26A0\uFE0F Failed to send progress: ${m.message}`)}}async function A(r,t,a){let{EXECUTION_ID:e,SQS_AUTH_TOKEN:o,PROGRESS_API_URL:s,PROGRESS_QUEUE_URL:d,PROJECT_API_TOKEN:l}=r;if(!e||!a)return;let u=JSON.stringify(a).length;console.log(`Sending artifact: ${t} (${(u/1024).toFixed(1)}KB)`);let f={executionId:e,...o&&{sqsAuthToken:o},artifacts:{[t]:a},timestamp:new Date().toISOString()},m=s?"HTTP":d?"SQS":"NONE",i=JSON.stringify(f).length;try{if(s)await v(s,e,f,l);else if(d)await U(d,e,f);else{console.warn(`\u26A0\uFE0F No transport configured for artifact ${t} \u2014 neither PROGRESS_API_URL nor PROGRESS_QUEUE_URL set`);return}console.log(`Artifact ${t} sent via ${m} (payload=${(i/1024).toFixed(1)}KB, value=${(u/1024).toFixed(1)}KB)`)}catch(_){console.error(`Failed to send artifact ${t} via ${m}:`),console.error(` Payload size: ${(i/1024).toFixed(1)}KB, Value size: ${(u/1024).toFixed(1)}KB`),console.error(` Error: ${_.message}`),_.name&&console.error(` Error type: ${_.name}`),_.code&&console.error(` Error code: ${_.code}`),i>256*1024&&console.error(" \u26A0\uFE0F Message exceeds SQS 256KB limit! Consider splitting or compressing.")}}async function P(r,{status:t,error:a}){let{EXECUTION_ID:e,SQS_AUTH_TOKEN:o,PROGRESS_API_URL:s,PROGRESS_QUEUE_URL:d,PROJECT_API_TOKEN:l}=r;if(!e)return;let u={executionId:e,...o&&{sqsAuthToken:o},status:t,...a&&{error:a},timestamp:new Date().toISOString()},f=s?"HTTP":d?"SQS":"NONE",m=JSON.stringify(u).length;console.log(`Sending final status: ${t} via ${f} (${(m/1024).toFixed(1)}KB)`);try{if(s)await v(s,e,u,l);else if(d){let i=["completed","failed","insufficient_context","blocked"].includes(t)?"execution_completed":"progress_update";await U(d,e,u,i)}else{console.warn("No transport configured for final status \u2014 neither PROGRESS_API_URL nor PROGRESS_QUEUE_URL set");return}console.log(`Final status ${t} sent via ${f}`)}catch(i){console.error(`Failed to send final status (${t}) via ${f}:`),console.error(` Payload: ${(m/1024).toFixed(1)}KB`),console.error(` Error: ${i.message}`),i.name&&console.error(` Error type: ${i.name}`),i.code&&console.error(` Error code: ${i.code}`)}}async function v(r,t,a,e){let o=`${r}/${t}/progress`,s={"Content-Type":"application/json"};e&&(s.Authorization=`Bearer ${e}`);let d=await fetch(o,{method:"POST",headers:s,body:JSON.stringify(a)});if(!d.ok){let l=await d.text();throw new Error(`HTTP ${d.status}: ${l}`)}}async function U(r,t,a,e="progress_update"){let o=JSON.stringify(a),s=(o.length/1024).toFixed(1);o.length>256*1024&&console.error(`\u274C SQS message too large: ${s}KB (limit 256KB) for ${t} [${e}]`),await F().send(new D({QueueUrl:r,MessageBody:o,MessageGroupId:t,MessageAttributes:{executionId:{DataType:"String",StringValue:t},messageType:{DataType:"String",StringValue:e}}}))}import{writeMcpConfig as X}from"@zibby/core/utils/mcp-config-writer.js";var V=b(import.meta.url),Y=G(V),Z=JSON.parse(j(L(Y,"../../package.json"),"utf-8")),ee={analyze_ticket:r=>({key:"analysis",value:{raw:r.raw,structured:r.output}}),generate_code:r=>({key:"codeImplementation",value:r.output?.codeImplementation}),generate_test_cases:r=>({key:"tests",value:r.output?.tests}),finalize:r=>({key:"report",value:r.output?.report})};function oe(r,t){return async function(e,o,s){let d=Date.now(),l=[],u="",f=console.log,m=process.stdout.write.bind(process.stdout),i=process.stderr.write.bind(process.stderr),_=!1;console.log=(...n)=>{let h=n.map(w=>typeof w=="string"?w:JSON.stringify(w)).join(" ");l.push(h),_=!0,f(...n),_=!1};let S="";process.stdout.write=(n,h,w)=>{if(!_){let g=typeof n=="string"?n:n.toString();S+=g;let $=S.split(`
|
|
3
|
+
`);S=$.pop()||"";for(let y of $){let O=y.trim();O&&l.push(O)}}return m(n,h,w)},f(`[Middleware] Started capturing logs for ${e}`);let R=!1,T=setInterval(()=>{if(R)return;let n=l.join(`
|
|
4
|
+
`);n!==u&&n.length>0&&(u=n,i(`\u{1F4E1} [Middleware] Sending live update for ${e}: ${n.length} chars, ${l.length} lines
|
|
5
|
+
`),r(e,"in_progress",n,s).catch(h=>{i(`\u26A0\uFE0F [Middleware] Failed to send live update: ${h.message}
|
|
6
|
+
`)}))},500);try{await r(e,"in_progress","",s);let n=await o(),h=((Date.now()-d)/1e3).toFixed(1);R=!0,clearInterval(T),await new Promise(g=>setImmediate(g)),console.log=f,process.stdout.write=m,S.trim()&&(l.push(S.trim()),S="");let w=l.join(`
|
|
7
|
+
`);if(i(`\u{1F4E1} [Middleware] Sending final update for ${e}: ${w.length} chars, ${l.length} total lines captured
|
|
8
|
+
`),n.success){await r(e,"success",w||`Completed in ${h}s`,s);let g=ee[e];if(g){let{key:$,value:y}=g(n);y&&await t(s,$,y)}}else await r(e,"failed",`${w}
|
|
9
9
|
|
|
10
|
-
Error: ${
|
|
10
|
+
Error: ${n.error}`,s);return n}catch(n){R=!0,clearInterval(T),await new Promise(w=>setImmediate(w)),console.log=f,process.stdout.write=m;let h=`${l.join(`
|
|
11
11
|
`)}
|
|
12
12
|
|
|
13
|
-
Error: ${
|
|
14
|
-
\u{1F680} Zibby Analysis (Graph Mode)`),console.log(`@zibby/cli v${
|
|
15
|
-
\u{1F4CB} Validation: canProceed=${
|
|
16
|
-
\u{1F4CA} Sending final status: ${
|
|
17
|
-
\u2705 Analysis completed successfully`),process.exit(0)}catch(
|
|
18
|
-
\u274C Analysis failed:`,
|
|
13
|
+
Error: ${n.message}`;throw await r(e,"failed",h,s),n}}}async function te(r){let{EXECUTION_ID:t,TICKET_KEY:a,PROJECT_ID:e,REPOS:o,PROGRESS_QUEUE_URL:s,PROGRESS_API_URL:d,SQS_AUTH_TOKEN:l,PROJECT_API_TOKEN:u,GITHUB_TOKEN:f,MODEL:m}=process.env;(!t||!a||!e)&&(console.error("\u274C Missing required environment variables"),console.error(" Required: EXECUTION_ID, TICKET_KEY, PROJECT_ID"),process.exit(1));let i=await k(t,e),_=i.ticketContext,S=i.nodeConfigs||{},R=o?JSON.parse(o):i.repos,T=process.env.WORKSPACE||"/workspace",n=b(import.meta.resolve("@zibby/core/package.json")),h=L(G(n),"templates","code-analysis","prompts");console.log(`
|
|
14
|
+
\u{1F680} Zibby Analysis (Graph Mode)`),console.log(`@zibby/cli v${Z.version} | Node.js ${process.version}`),console.log("\u2500".repeat(60)),console.log(`Ticket: ${a}`),console.log(`Repositories: ${R.length}`),console.log(`Workspace: ${T}`),console.log(`AI Model: ${m||"auto"}`),console.log("\u2500".repeat(60));let w=oe(N,A),g,$,y=null;if(r?.workflow){let c=J(process.cwd(),r.workflow);if(B(c)||(console.error(`\u274C Workflow file not found: ${c}`),process.exit(1)),c.endsWith(".js")||c.endsWith(".mjs"))try{let{pathToFileURL:p}=await import("url");y=await import(p(c).href),$=`local JS module (${c})`}catch(p){console.error(`\u274C Failed to load workflow JS module: ${p.message}`),process.exit(1)}else{try{let E=JSON.parse(j(c,"utf-8")),{_meta:C,...K}=E;g=K,$=`local file (${c})`}catch(E){console.error(`\u274C Failed to parse workflow file: ${E.message}`),process.exit(1)}let p=z(g);p.valid||(console.error("\u274C Invalid workflow file:"),p.errors.forEach(E=>console.error(` - ${E}`)),process.exit(1))}}else if(i.graphConfig)g=i.graphConfig,$="custom (from project workflow)";else{let c=new W;q(c),g=c.serialize(),$="default"}let O;if(y){let p={...y.nodeConfigs||{},...S};O=y.buildGraph({nodeMiddleware:w}),console.log(`\u{1F4D0} Graph source: ${$}`),console.log(` Nodes: ${O.nodes.size}`),S=p}else{if(S&&Object.keys(S).length>0){let c=g.nodeConfigs||{},p={...c};for(let[E,C]of Object.entries(S))p[E]={...c[E],...C};g.nodeConfigs=p}console.log(`\u{1F4D0} Graph source: ${$}`),console.log(` Nodes: ${g.nodes?.length||0}`),console.log(` Edges: ${g.edges?.length||0}`),O=Q(g,{nodeMiddleware:w,stateSchema:H})}X(S);let x={EXECUTION_ID:t,PROGRESS_QUEUE_URL:s,PROGRESS_API_URL:d,SQS_AUTH_TOKEN:l,PROJECT_API_TOKEN:u,workspace:T,repos:R,ticketContext:_,promptsDir:h,githubToken:f,model:m,nodeConfigs:S};try{let p=(await O.run(null,x)).state,E=p.analyze_ticket_output?.validation||p.analyze_ticket_output?.analysis?.structured?.validation,C="completed";E&&!E.canProceed&&(C=E.status==="insufficient_context"?"insufficient_context":"blocked"),console.log(`
|
|
15
|
+
\u{1F4CB} Validation: canProceed=${E?.canProceed}, status=${E?.status}, finalStatus=${C}`),console.log(`
|
|
16
|
+
\u{1F4CA} Sending final status: ${C}`),await P(x,{status:C}),console.log(`
|
|
17
|
+
\u2705 Analysis completed successfully`),process.exit(0)}catch(c){if(console.error(`
|
|
18
|
+
\u274C Analysis failed:`,c.message),t)try{console.log("\u{1F4E1} Reporting failure..."),await P(x,{status:"failed",error:c.message})}catch{console.error("\u26A0\uFE0F Failed to report error")}process.exit(1)}}import.meta.url===`file://${process.argv[1]}`&&te();export{te as analyzeCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as o,mkdirSync as a,readFileSync as c,writeFileSync as u,unlinkSync as l}from"fs";import{resolve as s}from"path";import{homedir as y}from"os";
|
|
1
|
+
import{existsSync as o,mkdirSync as a,readFileSync as c,writeFileSync as u,unlinkSync as l}from"fs";import{resolve as s}from"path";import{homedir as y}from"os";var p=30;function e(r){let t=s(r,".zibby","output");return o(t)||a(t,{recursive:!0}),t}function v(r){let t=s(r,".zibby","output","chat-history.json");if(!o(t))return[];try{let i=JSON.parse(c(t,"utf-8"));return Array.isArray(i)?i:[]}catch{return[]}}function b(r,t){let i=e(r),n=s(i,"chat-history.json");try{u(n,JSON.stringify((t||[]).slice(-p*2),null,2),"utf-8")}catch{}}function d(r){let t=s(r,".zibby","output","active-skills.json");if(!o(t))return null;try{let i=JSON.parse(c(t,"utf-8"));return Array.isArray(i)?i:null}catch{return null}}function k(r,t){let i=e(r),n=s(i,"active-skills.json");try{u(n,JSON.stringify(Array.isArray(t)?t:[]),"utf-8")}catch{}}function A(){let r=[s(process.cwd(),".zibby","output","active-skills.json"),s(y(),".zibby","output","active-skills.json")];for(let t of r)try{o(t)&&l(t)}catch{}}export{A as clearActiveSkills,d as loadActiveSkills,v as loadChatHistory,k as saveActiveSkills,b as saveChatHistory};
|