@zibby/cli 0.7.1 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/zibby.js +3 -3
- package/dist/commands/workflows/logs.js +37 -37
- package/dist/commands/workflows/run.js +26 -26
- package/dist/commands/workflows/trigger.js +37 -37
- package/dist/package.json +3 -3
- package/dist/templates/.claude/commands/zibby-app-upgrade.md +1 -1
- package/package.json +3 -3
- package/templates/.claude/commands/zibby-app-upgrade.md +1 -1
package/dist/bin/zibby.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
process.stdout.on("error",e=>{e.code}),process.stderr.on("error",e=>{e.code}),process.env.DOTENV_CONFIG_QUIET="true";import"@zibby/skills";import{Command as P}from"commander";import{initCommand as A}from"../commands/init.js";import{runCommand as _}from"../commands/run.js";import{videoCommand as S}from"../commands/video.js";import{uploadCommand as B}from"../commands/upload.js";import{ciSetupCommand as E}from"../commands/ci-setup.js";import{setupPlaywrightMcpCommand as Y,setupCiCommand as x,testWithVideoCommand as O}from"../commands/setup-scripts.js";import{readFileSync as R}from"fs";import{fileURLToPath as j}from"url";import{dirname as Z,join as T}from"path";import{bootstrapAgentEnv as
|
|
3
|
-
`),
|
|
2
|
+
process.stdout.on("error",e=>{e.code}),process.stderr.on("error",e=>{e.code}),process.env.DOTENV_CONFIG_QUIET="true";import"@zibby/skills";import{Command as P}from"commander";import{initCommand as A}from"../commands/init.js";import{runCommand as _}from"../commands/run.js";import{videoCommand as S}from"../commands/video.js";import{uploadCommand as B}from"../commands/upload.js";import{ciSetupCommand as E}from"../commands/ci-setup.js";import{setupPlaywrightMcpCommand as Y,setupCiCommand as x,testWithVideoCommand as O}from"../commands/setup-scripts.js";import{readFileSync as R}from"fs";import{fileURLToPath as j}from"url";import{dirname as Z,join as T}from"path";import{bootstrapAgentEnv as D}from"../utils/agent-credentials.js";import{WARM_POOL_QUANTITY_OPTIONS as g,WARM_POOL_MAX_QUANTITY as k}from"../config/warmPool.js";const z=j(import.meta.url),U=Z(z),b=JSON.parse(R(T(U,"../package.json"),"utf-8"));function p(e,o){return o.push(e),o}function v(e){if(e===void 0||e===!0||e==="")return 1;const o=parseInt(e,10);if(!Number.isFinite(o)||!g.includes(o))throw new Error(`--warm must be one of [${g.join(", ")}] (got "${e}"). Omit the flag to disable warm pool.`);return o}const I=`zibby v${b.version}`,a=process.argv.slice(2),L=a.includes("-h")||a.includes("--help"),M=a.includes("-v")||a.includes("-V")||a.includes("--version");M&&(console.log(I),process.exit(0));const h=a[0],K=a[1],N=["logs","uninstall"],F=(h==="workflow"||h==="agent")&&K==="list";!N.includes(h)&&!F&&console.log(`${I}
|
|
3
|
+
`),D(process.cwd());const W=a[0]==="chat",H=["--verbose","--agent","--stream","-s"],J=a.length>0&&a.every(e=>H.includes(e)||a[a.indexOf(e)-1]==="--agent"),q=a.length===0||W||J;if(q&&!L){const e={},o=a.indexOf("--agent");o!==-1&&a[o+1]&&(e.agent=a[o+1]),a.includes("--verbose")&&(e.verbose=!0),(a.includes("--stream")||a.includes("-s"))&&(e.stream=!0);const{chatCommand:t}=await import("../commands/chat.js");await t(e),process.exit(0)}const n=new P;n.name("zibby").description("Zibby \u2014 the cloud pipeline for Claude Code, Cursor, Codex, and Gemini. Compose them into structured workflows with schema-enforced handoff.").version(b.version,"-V, --version"),n.configureHelp({visibleCommands:()=>[]}),n.addHelpText("after",`
|
|
4
4
|
Agent (the platform) (alias: workflow):
|
|
5
5
|
agent new <name> Scaffold a new agent at .zibby/workflows/<name>/
|
|
6
6
|
agent run <name> Run an agent locally (one-shot, mirrors trigger flags)
|
|
@@ -45,5 +45,5 @@ Examples:
|
|
|
45
45
|
# run the built-in browser-test recipe
|
|
46
46
|
|
|
47
47
|
Docs: https://docs.zibby.app
|
|
48
|
-
GitHub: https://github.com/
|
|
48
|
+
GitHub: https://github.com/ZibbyDev/zibby-agent
|
|
49
49
|
`),n.command("init").description("Initialize a Zibby project (config + credentials only \u2014 pass -t <name> to also scaffold a workflow template)").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 (mem0, dolt). Default: mem0 (semantic vector memory; falls back to dolt if the embedding proxy is unavailable). Use dolt for self-contained structured memory.","mem0").option("--infer","Smart memory: let the LLM distill/dedupe facts on store (mem0 only; costs tokens). Default off = embed-only, free.").option("-t, --template <name>","Workflow template to scaffold into .zibby/ (see `zibby template list`). Default: none \u2014 init only sets up config and credentials.").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").option("--agent-key <key>","Agent API key (non-interactive). For Claude this is the per-token API key").option("--agent-oauth-token <token>","Claude OAuth subscription token (non-interactive). Saves to ~/.zibby/config.json").action(A),n.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((e,o)=>(o.debug?process.env.ZIBBY_DEBUG="true":o.verbose&&(process.env.ZIBBY_VERBOSE="true"),_(e,o))),n.command("implement").description("Implement a Jira ticket using AI agent (runs in ECS container)").action(async(...e)=>{const{implementCommand:o}=await import("../commands/implement.js");return o(...e)}),n.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(...e)=>{const{analyzeCommand:o}=await import("../commands/analyze-graph.js");return o(...e)}),n.command("video").description("Organize test videos next to test files").action(S),n.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(B),n.command("login").description("Log in to Zibby (opens browser for authentication)").action(async()=>{const{loginCli:e}=await import("../auth/cli-login.js");await e(),process.exit(0)}),n.command("logout").description("Log out from Zibby (clears saved session)").action(async()=>{const{logoutCli:e}=await import("../auth/cli-login.js");e(),process.exit(0)}),n.command("status").description("Show current authentication status and token details").option("--json","Output in JSON format (for scripts)").action(async e=>{const{showLoginStatus:o}=await import("../auth/cli-login.js");await o(e),process.exit(0)}),n.command("list").description("List your projects and API tokens").action(async()=>{const{listProjectsCommand:e}=await import("../commands/list-projects.js");await e()}),n.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(E),n.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(e=>{const o={width:parseInt(e.viewportWidth,10)||1280,height:parseInt(e.viewportHeight,10)||720};return Y({...e,viewport:o})}),n.command("setup-ci-full").description("Complete CI/CD setup from scratch").action(x),n.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(O),n.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 e=>{const{generateCommand:o}=await import("../commands/generate.js");return o(e)}),n.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 e=>{const{studioCommand:o}=await import("../commands/studio.js");return o(e)});const m=n.command("creds").description("Manage credentials Zibby has stored for your workspace (KMS-encrypted)");m.command("list").description("List credentials stored for your workspace (masked)").action(async()=>{const{listCmd:e}=await import("../commands/creds.js");await e(),process.exit(0)}),m.command("sync").description("Re-read ~/.zibby/credentials.env and upload any new tokens").action(async()=>{const{syncCmd:e}=await import("../commands/creds.js");await e(),process.exit(0)}),m.command("set <provider> <token>").description("Paste-token shortcut. e.g. zibby creds set claude sk-ant-oat01-... (auto-detects oauth vs api)").option("--type <kind>","Force credential kind: oauth | api (skips auto-detect)").action(async(e,o,t)=>{const{setCmd:s}=await import("../commands/creds.js");await s(e,o,t),process.exit(0)}),m.command("remove <type> <index>").description("Remove a stored credential. e.g. zibby creds remove oauth 0").action(async(e,o)=>{const{removeCmd:t}=await import("../commands/creds.js");await t(e,o),process.exit(0)});const G=n.command("g").description("Generate scaffolds");G.command("workflow [name]").description("Scaffold a new custom workflow in .zibby/workflows/<name>/ (auto-generates name if omitted)").option("-t, --template <name>","Scaffold from a template (see `zibby template list`). Future: also accepts npm package / git URL identifiers.").option("--skip-install","Skip running `npm install` in the new workflow folder").option("--skip-init-check","Skip the first-run init prompt that fires when ~/.zibby/config.json is missing (CI/scripted setups)").option("--agent-helpers [list]",'Install agent helpers (Claude Code / Cursor slash commands). List = comma-separated, e.g. "claude" or "claude,cursor". Bare flag defaults to claude.').option("--no-agent-helpers","Skip agent helpers even if .zibby.config.mjs says install").option("--agent <agent>","(legacy) Set up agent helpers: claude | cursor | codex | all | none. Prefer --agent-helpers.").option("--force-agents","Overwrite user-edited agent helper files (use with --agent-helpers)").action(async(e,o)=>{const{generateWorkflowCommand:t}=await import("../commands/workflows/generate.js");return t(e,o)}),n.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(e,o)=>{const{startWorkflowCommand:t}=await import("../commands/workflows/start.js");return t(e,o)}),n.command("run <workflow-name>").description("Run a workflow locally \u2014 one-shot (alias of `zibby workflow run`)").option("-p, --param <key=value>","Input param (repeatable)",p,[]).option("--input <json>","Input as JSON string").option("--input-file <path>","Input as JSON file").action(async(e,o)=>{const{runLocalWorkflowCommand:t}=await import("../commands/workflows/run-local.js");return t(e,o)}),n.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)").option("--dedicated-ip <action>","Manage dedicated egress IP addon: enable | status | disable | use | unuse").option("--env <path>","Path to a .env file to sync into per-workflow env vars after deploy (repeatable)",p,[]).option("--verbose","Show raw CodeBuild logs during the bundle build").option("--no-creds-check","Skip the project secrets sanity check (CI/CD when the secret is provisioned out-of-band)").option("--force","Deploy even if the source checksum matches the last deployed version (bypasses the unchanged check)").option("--warm [count]",`Enable warm-pool execution for this workflow (default 1, max ${k}). Skips ~60s Fargate cold-start by routing triggers to a per-account pool of always-on tasks. Pricing applies (paid feature).`,v).option("--ai-agent <agent>","Per-workflow AI agent override (claude | cursor | codex | gemini). Falls back to the project default when omitted.").action(async(e,o)=>{if(o.dedicatedIp){const{dedicatedEgressCommand:s}=await import("../commands/workflows/dedicated-egress.js");return s(o.dedicatedIp,o.project)}o.aiAgent&&!["claude","cursor","codex","gemini"].includes(o.aiAgent)&&(console.error(chalk.red(`Invalid --ai-agent: ${o.aiAgent}. Must be one of: claude, cursor, codex, gemini.`)),process.exit(1));const{deployWorkflowCommand:t}=await import("../commands/workflows/deploy.js");return t(e,o)}),n.command("trigger [uuid]").description("Trigger a deployed workflow by UUID (interactive selection if not provided). Get UUIDs from `zibby workflow list`.").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("-p, --param <key=value>","Input param (repeatable, e.g. -p url=https://x.com -p count=5)",p,[]).option("--input <json>",`Input as JSON string \u2014 overridden by --param (e.g. '{"key":"value"}')`).option("--input-file <path>","Input as JSON/YAML file \u2014 lowest precedence").option("--idempotency-key <key>","Idempotency key to prevent duplicate executions").option("-t, --follow","Stream logs in real-time after triggering (no need to run `logs -t` separately)").action(async(e,o)=>{const{triggerWorkflowCommand:t}=await import("../commands/workflows/trigger.js");return t(e,o)}),n.command("run-workflow").description("Run a deployed workflow from S3 sources (used by ECS containers)").action(async()=>{const{runWorkflowCommand:e}=await import("../commands/workflows/run.js");return e()});const C=n.command("template").description("Manage workflow templates in this project");C.command("list").description("List available workflow templates").action(async()=>{const{templateListCommand:e}=await import("../commands/template.js");return e()}),C.command("add",{hidden:!0}).argument("<name>","Template name (see `zibby template list`)").description("(deprecated \u2014 `zibby test` auto-installs the template) Copy a template into .zibby/, overwriting existing files").option("--skip-memory","Strip SKILLS.MEMORY from copied execute-live.mjs (browser-test only)").action(async(e,o)=>{const{templateAddCommand:t}=await import("../commands/template.js");return t(e,{enableMemory:!o.skipMemory})});const c=n.command("memory").description("Test memory database \u2014 version-controlled knowledge from runs");c.command("stats").description("Show memory database statistics").action(async()=>{const{memoryStatsCommand:e}=await import("../commands/memory.js");return e()}),c.command("init").description("Initialize the memory database (Dolt)").action(async()=>{const{memoryInitCommand:e}=await import("../commands/memory.js");return e()}),c.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 e=>{const{memoryCompactCommand:o}=await import("../commands/memory.js");return o(e)}),c.command("reset").description("Wipe the memory database").option("-f, --force","Confirm reset").action(async e=>{const{memoryResetCommand:o}=await import("../commands/memory.js");return o(e)}),c.command("cost").description("Show real LLM token usage from past runs (input/output/cache)").action(async()=>{const{memoryCostCommand:e}=await import("../commands/memory.js");return e()});const u=c.command("remote").description("Configure a remote so the team shares cross-spec memory");u.command("add").argument("<url>","Remote URL: aws://, gs://, https://, file:///").option("--name <name>","Remote name (default: origin)","origin").description("Point the local memory DB at a shared remote (S3/GCS/DoltHub/filesystem)").action(async(e,o)=>{const{memoryRemoteAddCommand:t}=await import("../commands/memory.js");return t(e,o)}),u.command("use").description("Switch to a managed remote backend. Currently: --hosted (Zibby-managed S3, signed-in users only).").option("--hosted","Use Zibby-managed S3 (allocates a tenant-scoped prefix per-project)").option("--project-id <id>","Override the projectId from .zibby.config.mjs").action(async e=>{e.hosted||(console.log("Pass --hosted. (Other backends will be added later.)"),process.exit(1));const{memoryRemoteUseHostedCommand:o}=await import("../commands/memory.js");return o(e)}),u.command("info").description("Show the configured memory remote (if any)").action(async()=>{const{memoryRemoteInfoCommand:e}=await import("../commands/memory.js");return e()}),u.command("remove").argument("[name]","Remote name (default: origin)").description("Remove a configured memory remote (memory becomes local-only)").action(async e=>{const{memoryRemoteRemoveCommand:o}=await import("../commands/memory.js");return o(e)}),c.command("pull").description("Pull latest team memory from the configured remote").action(async()=>{const{memoryPullCommand:e}=await import("../commands/memory.js");return e()}),c.command("push").description("Push local memory to the configured remote (auto-runs after passing tests)").action(async()=>{const{memoryPushCommand:e}=await import("../commands/memory.js");return e()});const V=n.command("agents").description("Manage Claude/Cursor/Codex helper files for working with Zibby workflows");V.command("add [agent]").description("Add agent helpers (claude | cursor | codex | all). Prompts if no agent given.").option("--force","Overwrite user-edited helper files").action(async(e,o)=>{const{runAgentHelpers:t,addAgent:s}=await import("../commands/workflows/agent-helpers.js");if(e){const d=["claude","cursor","codex","all","none"];d.includes(e)||(console.error(`Unknown agent "${e}". Valid: ${d.join(", ")}`),process.exit(1)),e==="none"?await t({forcedAgents:["none"],force:o.force===!0}):e==="all"?await t({forcedAgents:["claude","cursor","codex"],force:o.force===!0}):await s(e,{force:o.force===!0})}else await t({forcedAgents:void 0,force:o.force===!0,forcePrompt:!0})});const r=n.command("workflow").alias("agent").description("Manage agents \u2014 new, start, deploy, trigger, logs, list, download, delete (alias: workflow)");r.command("new [name]").description("Scaffold a new custom workflow (alias of `zibby g workflow`)").option("-t, --template <name>","Scaffold from a template (see `zibby template list`). Future: also accepts npm package / git URL identifiers.").option("--skip-install","Skip running `npm install` in the new workflow folder").option("--skip-init-check","Skip the first-run init prompt that fires when ~/.zibby/config.json is missing (CI/scripted setups)").option("--agent-helpers [list]",'Install agent helpers (Claude Code / Cursor slash commands). List = comma-separated, e.g. "claude" or "claude,cursor". Bare flag defaults to claude.').option("--no-agent-helpers","Skip agent helpers even if .zibby.config.mjs says install").option("--agent <agent>","(legacy) Set up agent helpers: claude | cursor | codex | all | none. Prefer --agent-helpers.").option("--force-agents","Overwrite user-edited agent helper files (use with --agent-helpers)").action(async(e,o)=>{const{generateWorkflowCommand:t}=await import("../commands/workflows/generate.js");return t(e,o)}),r.command("run <workflow-name>").description("Run a workflow locally \u2014 one-shot, same input flags as `workflow trigger`").option("-p, --param <key=value>","Input param (repeatable, e.g. -p url=https://x.com -p count=5)",p,[]).option("--input <json>",`Input as JSON string \u2014 overridden by --param (e.g. '{"key":"value"}')`).option("--input-file <path>","Input as JSON file \u2014 lowest precedence").action(async(e,o)=>{const{runLocalWorkflowCommand:t}=await import("../commands/workflows/run-local.js");return t(e,o)}),r.command("start <workflow-name>").description("Start a long-lived local dev server (Studio integration). Prefer `workflow run` for one-shots.").option("-p, --port <port>","Port for the workflow server (default: 3848)").action(async(e,o)=>{const{startWorkflowCommand:t}=await import("../commands/workflows/start.js");return t(e,o)}),r.command("deploy [workflow-name]").description("Deploy a workflow to Zibby Cloud (alias of `zibby deploy`)").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("--env <path>","Path to a .env file to sync into per-workflow env vars after deploy (repeatable)",p,[]).option("--verbose","Show raw CodeBuild logs during the bundle build").option("--no-creds-check","Skip the project secrets sanity check (CI/CD when the secret is provisioned out-of-band)").option("--force","Deploy even if the source checksum matches the last deployed version (bypasses the unchanged check)").option("--warm [count]",`Enable warm-pool execution for this workflow (default 1, max ${k}). Skips ~60s Fargate cold-start by routing triggers to a per-account pool of always-on tasks. Pricing applies (paid feature).`,v).action(async(e,o)=>{const{deployWorkflowCommand:t}=await import("../commands/workflows/deploy.js");return t(e,o)}),r.command("trigger [uuid]").description("Trigger a deployed workflow by UUID (alias of `zibby trigger`)").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("-p, --param <key=value>","Input param (repeatable, e.g. -p url=https://x.com -p count=5)",p,[]).option("--input <json>",`Input as JSON string \u2014 overridden by --param (e.g. '{"key":"value"}')`).option("--input-file <path>","Input as JSON/YAML file \u2014 lowest precedence").option("--idempotency-key <key>","Idempotency key to prevent duplicate executions").option("-t, --follow","Stream logs in real-time after triggering (no need to run `logs -t` separately)").action(async(e,o)=>{const{triggerWorkflowCommand:t}=await import("../commands/workflows/trigger.js");return t(e,o)}),r.command("logs [jobId]").description("Tail logs from a workflow execution (alias of `zibby logs`)").option("--project <id>","Project ID (or ZIBBY_PROJECT_ID env)").option("--workflow <name>","Workflow name (fetches the latest run)").option("--all","Show interleaved logs from all runs (requires --workflow)").option("-t, --follow","Stream logs in real-time (like Heroku logs -t)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").option("--lines <n>","Max log lines per fetch (default: 500)").action(async(e,o)=>{const{logsCommand:t}=await import("../commands/workflows/logs.js");return t(e,o)}),r.command("download <uuid>").description("Download a deployed workflow back to local (edit it, then re-deploy with `zibby workflow deploy`)").option("--dest <path>","Destination directory (default: ./workflows/<name> when run inside a .zibby project)").option("--force","Overwrite without prompting; bypass uuid-mismatch guard").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{downloadWorkflowCommand:t}=await import("../commands/workflows/download.js");return t(e,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 e=>{if(e.remoteOnly){const{workflowListCommand:t}=await import("../commands/workflow.js");return t(e)}if(e.localOnly){const{listLocalWorkflowsCommand:t}=await import("../commands/workflows/list.js");return t(e)}const{listAllWorkflowsCommand:o}=await import("../commands/workflows/list.js");return o(e)}),r.command("validate <name>").description("Static-check a local workflow (.zibby/workflows/<name>/). Catches schema/topology/skill errors in ~30ms before you run anything.").option("--verbose","Print stack traces on graph.mjs import errors").action(async(e,o)=>{const{validateCommand:t}=await import("../commands/workflows/validate.js");return t(e,o)}),r.command("schedule <uuid> [action] [cron]").description(`Manage a workflow's cron schedule. Actions: get (default) | set <cron> | clear. Cron is Unix 5-field, e.g. "0 9 * * 1-5".`).option("--tz <iana>","IANA timezone for the schedule (default: UTC)").option("-p, --param <key=value>","Fixed input param for every scheduled run (repeatable)",p,[]).option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o,t,s)=>{const{scheduleCommand:d}=await import("../commands/workflows/schedule.js");return d(e,o,t,s)});const y=r.command("webhook").description("Configure a workflow's inbound webhook + auth (enable/disable, basic/ip/token, show)");y.command("enable <uuid>").description("Enable the workflow's inbound webhook (HTTP trigger)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{webhookCommand:t}=await import("../commands/workflows/webhook.js");return t("enable",e,void 0,o)}),y.command("disable <uuid>").description("Disable the workflow's inbound webhook (HTTP trigger)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{webhookCommand:t}=await import("../commands/workflows/webhook.js");return t("disable",e,void 0,o)}),y.command("show <uuid>").description("Show current webhook config (which auth methods are on, masked token, IP list, URL)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{webhookCommand:t}=await import("../commands/workflows/webhook.js");return t("show",e,void 0,o)});const w=y.command("auth").description("Configure webhook auth methods: basic | ip | token");w.command("basic <uuid>").description("Enable HTTP Basic auth (or --disable to turn it off). Password optional on update.").option("--username <u>","Basic auth username").option("--password <p>","Basic auth password (plaintext; backend hashes it; omit to keep existing)").option("--disable","Turn Basic auth off").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{webhookCommand:t}=await import("../commands/workflows/webhook.js");return t("auth","basic",e,o)}),w.command("ip <uuid>").description("Set the IP allowlist (or --disable to turn it off)").option("--allow <cidr,...>","Comma-separated IPs/CIDRs, e.g. 1.2.3.4,10.0.0.0/8").option("--disable","Turn the IP allowlist off").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{webhookCommand:t}=await import("../commands/workflows/webhook.js");return t("auth","ip",e,o)}),w.command("token <uuid>").description("Generate a bearer token (--generate) \u2014 printed ONCE \u2014 or --disable to turn it off").option("--generate","Mint a new token; printed once in plaintext").option("--disable","Turn token auth off").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{webhookCommand:t}=await import("../commands/workflows/webhook.js");return t("auth","token",e,o)}),r.command("delete <uuid>").description("Delete a deployed workflow by UUID").action(async e=>{const{deleteWorkflowCommand:o}=await import("../commands/workflows/delete.js");return o(e,{})});const f=r.command("env").description("Manage per-workflow encrypted env vars (set ANTHROPIC_API_KEY, DATABASE_URL, etc. per workflow)");f.command("list <uuid>").description("List env var key names for a workflow (values never returned)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{listEnvCommand:t}=await import("../commands/workflows/env.js");return t(e,o)}),f.command("set <uuid> <kv>").description("Set or update one env var: zibby workflow env set <uuid> KEY=value").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o,t)=>{const{setEnvCommand:s}=await import("../commands/workflows/env.js");return s(e,o,t)}),f.command("unset <uuid> <key>").description("Remove one env var from a workflow").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o,t)=>{const{unsetEnvCommand:s}=await import("../commands/workflows/env.js");return s(e,o,t)}),f.command("push <uuid>").description("Bulk-replace env from one or more .env files (later files override). Removes any keys not in the new map.").option("--file <path>","Path to a .env file (repeatable, e.g. --file .env --file .env.prod)",p,[]).option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{pushEnvCommand:t}=await import("../commands/workflows/env.js");return t(e,o)});const $=n.command("project").description("Manage Zibby projects");$.command("list").description("List all projects").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async e=>{const{projectListCommand:o}=await import("../commands/project.js");return o(e)});const Q=n.command("run-queue").description("Parallel capacity \u2014 on-disk wait queue (see parallel.waitWhenAtCapacity in .zibby.config.mjs)");Q.command("list").description("List CLI processes waiting for a run slot").option("--config <path>","Path to config file",".zibby.config.mjs").action(async e=>{const{runCapacityQueueListCommand:o}=await import("../commands/run-capacity-queue-cli.js");await o(e),process.exit(0)});const X=n.command("mcp").description("Manage the Zibby Remote MCP integration in your AI agent");X.command("install").description("Auto-configure Zibby MCP into your AI agent (Claude Code/Desktop, Cursor, Codex, Gemini)").option("--agent <name>","claude-code | claude-desktop | cursor | codex | gemini").option("--all","Install for every supported agent on this machine").option("--token <pat>","Use this PAT (zby_pat_\u2026) instead of minting one via session. Also reads ZIBBY_PAT env var.").option("--force","Overwrite the existing zibby block even if unchanged").action(async e=>{const{mcpInstallCommand:o}=await import("../commands/mcp.js");await o(e),process.exit(0)});const i=n.command("app").description("Manage Zibby Managed Apps \u2014 templates, deploy, list, status, destroy");i.command("templates").description("List the app catalog (n8n, grafana, gas-town, \u2026)").action(async e=>{const{appTemplatesCommand:o}=await import("../commands/app.js");return o(e)}),i.command("list").description("List deployed app instances (use --project to scope to one project)").option("--project <id>","Project ID \u2014 defaults to all instances under your account").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async e=>{const{appListCommand:o}=await import("../commands/app.js");return o(e)}),i.command("deploy [appType]").description('Deploy an app \u2014 either from the catalog (e.g. `zibby app deploy grafana --project <id>`) or a free-form install described by --goal (e.g. `zibby app deploy --goal "Install n8n at /n8n on port 5678, persist data in /data" --project <id>`). Pass exactly one of <appType> OR --goal. Catalog deploys are curated by Zibby; goal-based deploys are user-directed installs where you (not Zibby) choose what gets installed and accept the license terms of whatever you install.').option("--mode <name>",'Deploy mode \u2014 "cloud" (default, shared Fargate) or "solo" (dedicated t4g.* EC2 per app, cheaper + isolated). Solo deploys take --repo / --tier / --secret instead of <appType>; see `zibby app deploy --mode solo --help` for the solo flags.').option("--slug <name>","[solo] App slug \u2014 used to form the public hostname <slug>.solo.zibby.app. lowercase [a-z0-9-], 1-40 chars.").option("--repo <ownerRepo>",'[solo] GitHub source repo in "owner/name" form. Mutually exclusive with --tarball.').option("--ref <ref>","[solo] Git ref (branch, tag, sha) to clone. Defaults to the repo's default branch.").option("--tarball <s3Url>","[solo] s3:// URL of a tarball source. Mutually exclusive with --repo.").option("--framework <name>",'[solo] Framework hint \u2014 auto (default), rails, node, python, static, other. "auto" lets agent-ops detect from the source tree.').option("--tier <id>","[solo] Instance tier id: micro | small | medium | large. Run `zibby app deploy --mode solo` without --tier to see the live pricing table.").option("--region <id>","[solo] AWS region for the VM: ap-southeast-2 (Sydney, default) | us-east-1 | us-west-2 | eu-west-1 | ap-northeast-1 | auto (latency-probe + pick nearest). The Zibby control plane stays in Sydney; only your app's EC2 + storage move. Pricing is the same in every region. Omit the flag in interactive mode to pick from a list sorted by measured latency.").option("--secret <kv...>","[solo] Repeatable. Each is KEY=VALUEREF where VALUEREF points at your workspace-credentials (uploaded via `zibby creds set`). Plaintext is NOT accepted here. Example: --secret STRIPE_KEY=workspace:stripe-prod.").option("--db-persistence <kind>","[solo] Database persistence: sqlite-litestream | postgres-walg | none (default).").option("--files-persistence <kind>","[solo] Files persistence: activestorage-s3 | rclone-bisync | none (default).").option("--no-tail","[solo] Skip the post-fire status tail. Default tails until phase=running/failed (max 15 min). --yes implies --no-tail.").option("-y, --yes","Non-interactive mode \u2014 exit 1 on any missing inputs instead of prompting. Implies --no-tail.").option("--project <id>","Project ID (interactive prompt if not provided)").option("--goal <text>",'Free-form natural-language description of what to install (mutually exclusive with <appType>). The agent-ops bootstrap follows the description \u2014 e.g. "install n8n on port 5678 with sqlite persistence". You are responsible for the license terms of any software you install via this path.').option("--name <name>","Instance display name (defaults to appType, or first line of --goal)").option("--provider <name>",'Agent provider \u2014 "claude" (default) or "codex"').option("--arch <name>",`CPU architecture \u2014 "x86_64" or "arm64" (default = catalog's first listed arch; arm64 is ~20% greener at the same price)`).option("--model <name>","Claude model identifier to use for the agent-ops bootstrap (e.g. claude-sonnet-4-6, claude-opus-4-5, claude-haiku-4-5-20251001). Overrides the daemon's baked default. Use a stronger model (Opus) for complex installs; a cheaper one (Haiku) for trivial ones.").option("--anthropic-token <token>","SENSITIVE: Per-deploy Claude credential override. Replaces the workspace-stored token for THIS deploy only \u2014 never persisted. Must start with sk-ant-oat01- (OAuth subscription) or sk-ant-api03- (Anthropic API key). Env equivalent: ZIBBY_ANTHROPIC_TOKEN.").option("--max-turns <n>","Cap on Claude subprocess --max-turns (cfg.Agent.MaxToolCallsPerTask). Default 25; bump for heavy goal-mode installs (n8n, OpenHands) that exhaust the default before finishing. Range 1..200. Example: --max-turns 60.").option("--timeout-min <n>","Bootstrap-task wall-clock cap in minutes. Default 30; bump when npm install / docker pull / native compile dominates wall time (n8n ~500MB install often takes 25-40min). Range 1..120. Example: --timeout-min 45.").option("--auth-type <kind>",'Optional auth sidecar \u2014 "basic" (username + password), "token" (bearer header), or "none" (default, no auth). Adds a tiny Caddy container in front of the public URL that gates requests. Use this on apps with weak / no built-in auth (Grafana ships admin/admin; n8n ships with nothing).').option("--auth-user <name>","Username for --auth-type basic. Required for basic auth. Printable ASCII, no spaces (1-64 chars).").option("--auth-password <pass>","SENSITIVE: Password for --auth-type basic. 8-256 chars; bcrypt-hashed server-side, plaintext never persisted. Env equivalent: ZIBBY_APP_AUTH_PASSWORD.").option("--auth-token <tok>","Optional explicit bearer token for --auth-type token. 16-128 chars, base64url alphabet only ([A-Za-z0-9_-]). Omit to let the backend auto-generate a 32-byte token (returned ONCE in the deploy response \u2014 save it). Env equivalent: ZIBBY_APP_AUTH_TOKEN.").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appDeployCommand:t}=await import("../commands/app.js");return t(e,o)}),i.command("status <instanceId>").description("Show one instance: status, resources, public URL").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appStatusCommand:t}=await import("../commands/app.js");return t(e,o)}),i.command("destroy <instanceId>").description("Stop + remove an app instance (interactive confirm unless --yes)").option("-y, --yes","Skip the confirmation prompt").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appDestroyCommand:t}=await import("../commands/app.js");return t(e,o)}),i.command("upgrade <instanceId>").description("Roll the agent-ops container image without destroying the instance (EFS data preserved)").option("--version <tag>","Pin to a specific agent-ops version (e.g. 0.1.16). Defaults to whatever AppsFleet base task def says.").option("-y, --yes","Skip the confirmation prompt").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appUpgradeCommand:t}=await import("../commands/app.js");return t(e,o)}),i.command("update-credential <instanceId>").description("Rotate the per-instance Claude credential to whatever's currently in your workspace-credentials. EFS preserved; task restarts ~30s.").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appUpdateCredentialCommand:t}=await import("../commands/app.js");return t(e,o)}),i.command("set-auth <instanceId>").description("Enable, rotate, or disable the optional Caddy auth sidecar on a running instance. Use --auth-type basic / token / none, or --off to disable. PATCH semantics: omitted flags preserve current state, so e.g. `zibby app set-auth <id> --auth-password new` rotates JUST the password on a basic-auth instance.").option("--auth-type <kind>",'"basic" | "token" | "none". Omit to keep current type (e.g. just rotate the password).').option("--auth-user <name>","Username for basic auth. Required when switching TO basic; preserved on subsequent rotations.").option("--auth-password <pass>","SENSITIVE: Password for basic auth. 8-256 chars; bcrypt-hashed server-side. Env equivalent: ZIBBY_APP_AUTH_PASSWORD.").option("--auth-token <tok>","Optional bearer token for token auth. Omit to let the backend regenerate a fresh 32-byte token (returned ONCE \u2014 save it). Env equivalent: ZIBBY_APP_AUTH_TOKEN.").option("--off","Disable the auth sidecar entirely (alias for --auth-type none). Caddy container removed; public URL exposes the app port directly again.").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appSetAuthCommand:t}=await import("../commands/app.js");return t(e,o)});const l=i.command("auth").description("Manage access control on a running app instance: credential auth (basic / token / none) and/or an IP allowlist. `auth show|basic|token|clear|ip <instanceId>`.");l.command("show <instanceId>").description("Show the current access-control gate (credential auth type + IP allowlist).").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appAuthShowCommand:t}=await import("../commands/app-auth.js");return t(e,o)}),l.command("basic <instanceId>").description("Enable / rotate HTTP basic auth (username + password). Adds a Caddy sidecar that gates the public URL. Task restarts ~1 min.").requiredOption("--user <name>","Username (1-64 printable ASCII, no spaces)").option("--password <pass>","SENSITIVE: password (8-256 chars). Env equivalent: ZIBBY_APP_AUTH_PASSWORD.").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appAuthBasicCommand:t}=await import("../commands/app-auth.js");return t(e,o)}),l.command("token <instanceId>").description("Enable / rotate bearer-token auth. Omit --token to let the backend auto-generate one (printed ONCE \u2014 save it). Task restarts ~1 min.").option("--token <tok>","Optional explicit token (16-128 chars, base64url [A-Za-z0-9_-]). Omit to auto-generate. Env equivalent: ZIBBY_APP_AUTH_TOKEN.").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appAuthTokenCommand:t}=await import("../commands/app-auth.js");return t(e,o)}),l.command("clear <instanceId>").description("Disable credential auth (authType none). The Caddy credential check is removed; any IP allowlist is left intact (clear it with `auth ip --clear-ip`).").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appAuthClearCommand:t}=await import("../commands/app-auth.js");return t(e,o)}),l.command("ip <instanceId>").description("Manage the IP allowlist (independent of credential auth). Only the listed source IPs/CIDRs may reach the app; all others get 403. SECURITY: enforced behind the ALB via X-Forwarded-For \u2014 verify it works on your instance before relying on it.").option("--allow <cidr...>","One or more IPs/CIDRs to allow (e.g. --allow 203.0.113.5/32 198.51.100.0/24). Replaces the current allowlist.").option("--clear-ip","Remove the IP allowlist entirely (all source IPs allowed again). Credential auth is left untouched.").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appAuthIpCommand:t}=await import("../commands/app-auth.js");return t(e,o)}),i.command("logs <instanceId>").description("Show recent logs from an app instance (use -t to tail; polls every 3s)").option("-t, --follow","Tail mode \u2014 poll every 3s and print new lines as they arrive (Ctrl+C to stop)").option("--lines <n>","Max lines per fetch (default 200, max 5000)").option("--service <name>","For multi-container apps: limit logs to one service (e.g. `db`, `web`, `agent-ops`). Defaults to interleaved across all containers.").option("--json","Print raw JSON lines (one per line) instead of parsed summary").option("--verbose","Print the full line including JSON body (default: parsed `<time> <msg>` summary)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appLogsCommand:t}=await import("../commands/app.js");return t(e,o)}),i.command("run [cmd...]").description("Run a one-off command on a linked solo app (e.g. `zibby app run rails db:migrate`). Attaches your TTY via SSM \u2014 no AWS creds needed.").option("--app <slug>","App slug (defaults to the nearest .zibby/app.json)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appRunCommand:t}=await import("../commands/app-run.js");return t(e,o)}),i.command("console").description("Open the framework REPL on a linked solo app (rails console, python manage.py shell, node, iex -S mix)").option("--app <slug>","App slug (defaults to the nearest .zibby/app.json)").option("--framework <name>","Override the framework from the link file (rails | django | python | node | elixir)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async e=>{const{appConsoleCommand:o}=await import("../commands/app-run.js");return o(e)}),i.command("migrate").description("Run database migrations on a linked solo app (rails db:migrate / python manage.py migrate)").option("--app <slug>","App slug (defaults to the nearest .zibby/app.json)").option("--framework <name>","Override the framework from the link file").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async e=>{const{appMigrateCommand:o}=await import("../commands/app-run.js");return o(e)}),i.command("rollback [steps]").description("Roll back the last database migration(s) on a linked solo app (rails db:rollback STEP=<n>, default 1)").option("--app <slug>","App slug (defaults to the nearest .zibby/app.json)").option("--framework <name>","Override the framework from the link file").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appRollbackCommand:t}=await import("../commands/app-run.js");return t(e,o)}),i.command("link <slug>").description("Link the current directory to a solo app \u2014 writes .zibby/app.json (commit it so your team can `zibby app run` without --app)").option("--api-key <key>","API key (or ZIBBY_API_KEY env)").action(async(e,o)=>{const{appLinkCommand:t}=await import("../commands/app-run.js");return t(e,o)}),n.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 e=>{const{uninstallCommand:o}=await import("../commands/uninstall.js");await o(e),process.exit(0)}),n.parse();
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import
|
|
2
|
-
Not authenticated`)),console.log(
|
|
3
|
-
`)),process.exit(1));let o;try{o=JSON.parse(
|
|
4
|
-
Config file corrupt`)),console.log(
|
|
5
|
-
`)),process.exit(1)}let n=o.sessionToken;n||(console.log(
|
|
6
|
-
Not authenticated`)),console.log(
|
|
7
|
-
`)),process.exit(1));let
|
|
8
|
-
Workflow UUID is required`)),console.log(
|
|
9
|
-
`)),process.exit(1)),
|
|
10
|
-
`),
|
|
11
|
-
\u250C\u2500 Execution: ${b.shortId} (task: ${b.taskSuffix})`)),console.log(
|
|
12
|
-
`)),b.headerPrinted=!0)},
|
|
13
|
-
Waiting for next execution...`));break;case"complete":
|
|
1
|
+
import t from"chalk";import{readFileSync as z,existsSync as D,writeSync as A}from"fs";import{homedir as F}from"os";import{join as Z}from"path";var R={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://api-prod.zibby.app",frontendUrl:process.env.ZIBBY_PROD_FRONTEND_URL||"https://studio.zibby.dev",description:"Production environment"}};function O(){let r;if(process.env.ZIBBY_API_URL)r=process.env.ZIBBY_API_URL;else{let e=process.env.ZIBBY_ENV||"prod";R[e]?r=R[e].apiUrl:r=R.prod.apiUrl}try{let e=new URL(r);return e.protocol!=="http:"&&e.protocol!=="https:"?(console.error(`\u26A0\uFE0F Invalid API URL protocol: ${e.protocol} (only http/https allowed)`),R.prod.apiUrl):r}catch{return console.error(`\u26A0\uFE0F Invalid API URL: ${r}`),R.prod.apiUrl}}var B="https://logs.workflows.zibby.app",W="https://logs-stream.zibby.app/",v=null;async function J(r){return v||(process.env.ZIBBY_SSE_ENDPOINT?(v=process.env.ZIBBY_SSE_ENDPOINT,v):(v=W,v))}function G(r){let e=Z(F(),".zibby","config.json");D(e)||(console.log(t.red(`
|
|
2
|
+
Not authenticated`)),console.log(t.gray(` Run: zibby login
|
|
3
|
+
`)),process.exit(1));let o;try{o=JSON.parse(z(e,"utf-8"))}catch{console.log(t.red(`
|
|
4
|
+
Config file corrupt`)),console.log(t.gray(` Run: zibby login
|
|
5
|
+
`)),process.exit(1)}let n=o.sessionToken;n||(console.log(t.red(`
|
|
6
|
+
Not authenticated`)),console.log(t.gray(` Run: zibby login
|
|
7
|
+
`)),process.exit(1));let p=r.project;return{token:n,projectId:p}}function L(r){let e=new Date(r);if(process.env.ZIBBY_LOGS_UTC==="1")return e.toISOString().replace("T"," ").replace("Z","");let o=(n,p=2)=>String(n).padStart(p,"0");return`${e.getFullYear()}-${o(e.getMonth()+1)}-${o(e.getDate())} ${o(e.getHours())}:${o(e.getMinutes())}:${o(e.getSeconds())}.${o(e.getMilliseconds(),3)}`}async function M(r,e){let o=await fetch(r,{headers:{Authorization:`Bearer ${e}`}});if(!o.ok){let n=await o.text();throw new Error(`API ${o.status}: ${n}`)}return o.json()}async function V(r,e,o,n){return r||(console.log(t.red(`
|
|
8
|
+
Workflow UUID is required`)),console.log(t.gray(" Usage: zibby workflow logs <workflow-uuid>")),console.log(t.gray(` zibby workflow logs <workflow-uuid> -t
|
|
9
|
+
`)),process.exit(1)),r}function H(r,e){let n=((r||"")+e).split(`
|
|
10
|
+
`),p=n.pop()||"",a=[],l=null,u=null;for(let s=0;s<n.length;s++){let i=n[s];if(i.trim()){if(i.startsWith("id:")){l=i.slice(3).trim();continue}if(i.startsWith("event:")){let f=i.slice(6).trim();if(f==="log")continue;if(f==="status"){let d=n[s+1];if(d&&d.startsWith("data:"))try{let w=JSON.parse(d.slice(5).trim());w.status==="new_execution"?a.push({type:"newExecution",executionId:w.executionId,taskId:w.taskId}):w.status==="waiting"&&a.push({type:"waiting"})}catch{}continue}if(f==="complete"){a.push({type:"complete"});continue}if(f==="error"){let d=n[s+1];if(d&&d.startsWith("data:"))try{if(JSON.parse(d.slice(5).trim()).error==="No executions found for workflow"){u={type:"notFound"};break}}catch{}u={type:"failed"};break}continue}if(i.startsWith("data:")){let f=i.slice(5).trim();if(!f)continue;try{let d=JSON.parse(f);d.timestamp&&d.message&&a.push({type:"log",timestamp:d.timestamp,message:d.message,taskId:d.taskId})}catch{}}}}return{actions:a,remainder:p,lastEventId:l,returnSignal:u}}async function X({token:r,executionId:e,sseEndpoint:o,stopped:n}){let p=null;try{let y=function(){let b=Array.from(I.entries()).slice(0,d);I.clear();for(let[h,m]of b)I.set(h,m);c=new Set(Array.from(I.values()).map(h=>h.taskId).filter(Boolean));for(let h of[...g.keys()])I.has(h)||g.delete(h)},E=function($){for(let[b,h]of I)if(h.taskId===$)return b;return null},_=function($){let b=I.get($);!b||b.headerPrinted||(console.log(t.cyan(`
|
|
11
|
+
\u250C\u2500 Execution: ${b.shortId} (task: ${b.taskSuffix})`)),console.log(t.cyan(` \u2514\u2500 Streaming logs...
|
|
12
|
+
`)),b.headerPrinted=!0)},T=function($){let b=t.gray(L($.timestamp)),h=$.taskId?t.gray(`(${$.taskId.slice(-8)}) `):"";console.log(`${b} ${h}${$.message.replace(/\n$/,"")}`)},P=function(){if(!k)return;k=!1,S&&(clearTimeout(S),S=null);let $=Array.from(I.entries()).reverse();for(let[b]of $){let h=g.get(b);if(!(!h||h.length===0)){_(b);for(let m of h)T(m)}}g.clear()},U=function(){k&&(S&&clearTimeout(S),S=setTimeout(P,w))},a=new URL(o);a.searchParams.set("jobId",e),p&&a.searchParams.set("lastEventId",p);let l=await fetch(a.toString(),{headers:{Authorization:`Bearer ${r}`,Accept:"text/event-stream"}});if(!l.ok)throw new Error(`SSE connection failed: ${l.status} ${l.statusText}`);let u=l.body.getReader(),s=new TextDecoder,i="",f=!1,d=Number(process.env.ZIBBY_LOGS_HISTORY_LIMIT)||10,w=Number(process.env.ZIBBY_LOGS_REPLAY_TIMEOUT_MS)||3e3,I=new Map,c=new Set,g=new Map,k=!0,S=null;for(U();!n.value;){let{done:$,value:b}=await u.read();if($)break;let h=H(i,s.decode(b,{stream:!0}));i=h.remainder,h.lastEventId&&(p=h.lastEventId);for(let m of h.actions)switch(m.type){case"newExecution":{let x=`${m.executionId.slice(0,8)}...${m.executionId.slice(-4)}`,N=m.taskId?m.taskId.slice(-8):"pending";I.set(m.executionId,{shortId:x,taskSuffix:N,taskId:m.taskId||null,headerPrinted:!1}),g.has(m.executionId)||g.set(m.executionId,[]),y(),U();break}case"waiting":P(),console.log(t.gray(`
|
|
13
|
+
Waiting for next execution...`));break;case"complete":P(),f=!0;break;case"log":{if(m.taskId&&c.size>0&&!c.has(m.taskId))break;if(k){let x=m.taskId?E(m.taskId):null;if(x){let N=g.get(x)||[];N.push(m),g.set(x,N),U()}else T(m)}else{if(m.taskId){let x=E(m.taskId);x&&_(x)}T(m)}break}}if(h.returnSignal)return h.returnSignal.type==="notFound"?{notFound:!0}:{failed:!0}}return P(),{completed:f}}catch(a){if(a.name==="AbortError")return{aborted:!0};throw a}}function q(r,{baseMs:e=500,capMs:o=3e4,rand:n=Math.random}={}){let p=Math.min(o,e*Math.pow(2,Math.max(0,r)));return Math.floor(n()*p)}async function K({attemptStream:r,stopped:e,follow:o,logger:n,sleep:p=s=>new Promise(i=>setTimeout(i,s)),exit:a=s=>{throw new Error(`exit:${s}`)},backoff:l=q,notFoundPollMs:u=5e3}){let s=0,i=!1;for(;!e.value;){let f;try{f=await r(),s=0}catch(d){if(d.name==="AbortError"||e.value)return{reason:"aborted"};if(i||(n.error(` SSE Error: ${d.message}`),o&&n.gray(" Reconnecting..."),i=!0),!o)return a("error")??{reason:"error"};let w=l(s);s++,await p(w);continue}if(f.aborted||e.value)return{reason:"aborted"};if(f.notFound){if(o){i||(n.yellow(" No executions found yet. Waiting for workflow to be triggered..."),n.gray(" Press Ctrl+C to stop."),i=!0),await p(u);continue}return n.yellow(`
|
|
14
14
|
No executions found for this workflow. Trigger the workflow first.
|
|
15
|
-
`),a("notFound")??{reason:"notFound"}}if(
|
|
16
|
-
`),
|
|
17
|
-
Execution failed.`),o?{reason:"failed"}:a("failed")??{reason:"failed"};if(
|
|
18
|
-
`):"");let
|
|
19
|
-
`)),
|
|
15
|
+
`),a("notFound")??{reason:"notFound"}}if(i&&(n.gray(` Reconnected.
|
|
16
|
+
`),i=!1),f.failed)return n.red(`
|
|
17
|
+
Execution failed.`),o?{reason:"failed"}:a("failed")??{reason:"failed"};if(f.completed)return a("completed")??{reason:"completed"};if(!o)return{reason:"disconnected"}}return{reason:"stopped"}}async function Y(r){if(process.env.ZIBBY_SSE_NO_WAKE==="1")return{state:"unknown"};try{let e=O().replace(/\/$/,""),o=await fetch(`${e}/logs/wake`,{method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"}});if(!o.ok)return{state:"unknown"};let n=await o.json().catch(()=>({}));return n&&(n.state==="ready"||n.state==="warming")?{state:n.state}:{state:"unknown"}}catch{return{state:"unknown"}}}var C=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];async function Q(r,{timeoutMs:e=9e4,pollMs:o=3e3}={}){let n=Date.now(),p=0,a=process.stderr.isTTY,l=()=>{if(!a)return;let i=Math.round((Date.now()-n)/1e3),f=C[p++%C.length];try{A(2,`\r ${t.cyan(f)} Starting log stream\u2026 (~60s on first connect) ${t.gray(`${i}s`)} `)}catch{}},u=()=>{if(a)try{A(2,`\r${" ".repeat(64)}\r`)}catch{}};a||console.log(t.gray(" Starting log stream\u2026 (~60s on first connect)"));let s=a?setInterval(l,120):null;try{for(;Date.now()-n<e;){let{state:i}=await Y(r);if(i==="ready")break;await new Promise(f=>setTimeout(f,o))}}finally{s&&clearInterval(s),u()}}async function ee({token:r,jobId:e,follow:o,projectId:n}){(await Y(r)).state==="warming"&&await Q(r),console.log(t.gray(` Streaming logs for workflow ${t.cyan(e)}...`)),console.log(o?t.gray(` Press Ctrl+C to stop.
|
|
18
|
+
`):"");let a=await J(r);if(!a)return console.log(t.yellow(` SSE endpoint not configured, using CloudWatch polling...
|
|
19
|
+
`)),j({token:r,projectId:null,jobId:e,follow:o,limit:1e5});let l={value:!1},u=()=>{l.value=!0;try{A(2,`
|
|
20
20
|
Stopped streaming.
|
|
21
|
-
`)}catch{}process.exit(0)};process.prependListener("SIGINT",
|
|
21
|
+
`)}catch{}process.exit(0)};process.prependListener("SIGINT",u),process.prependListener("SIGTERM",u),await K({attemptStream:()=>X({token:r,executionId:e,sseEndpoint:a,stopped:l}),stopped:l,follow:o,logger:{gray:s=>console.log(t.gray(s)),red:s=>console.log(t.red(s)),yellow:s=>console.log(t.yellow(s)),error:s=>console.error(t.red(s))},exit:s=>{s==="completed"&&process.exit(0),(s==="error"||s==="notFound"||s==="failed")&&process.exit(1)}})}async function j({token:r,projectId:e,jobId:o,follow:n,limit:p}){let a=e?`${B}/logs/${e}/${o}`:`${B}/job/${o}`,l=null,u=0,s=new Set,i=!1,f=0,d=5,w=()=>{i=!0,console.log(t.gray(`
|
|
22
22
|
Stopped tailing.
|
|
23
|
-
`)),process.exit(0)};for(process.on("SIGINT",
|
|
24
|
-
`):"");!
|
|
25
|
-
Job ${
|
|
26
|
-
Status: ${
|
|
23
|
+
`)),process.exit(0)};for(process.on("SIGINT",w),process.on("SIGTERM",w),console.log(t.gray(` Fetching logs for workflow ${t.cyan(o)}...`)),console.log(n?t.gray(` Press Ctrl+C to stop.
|
|
24
|
+
`):"");!i;)try{let I=new URLSearchParams({limit:String(p)});l&&I.set("nextToken",l);let c=await M(`${a}?${I}`,r);f=0,c.message&&c.lines?.length===0&&u===0&&console.log(t.gray(` ${c.message}`)),c.status==="starting"&&c.lines?.length===0&&u===0&&console.log(t.gray(" Container starting..."));for(let y of c.lines||[]){let E=`${y.timestamp}:${y.message}`;if(s.has(E))continue;s.add(E);let _=t.gray(L(y.timestamp)),T=c.taskId?t.gray(`(${c.taskId.slice(-8)}) `):"";console.log(`${_} ${T}${y.message.replace(/\n$/,"")}`)}if(u=c.lines?.length>0?0:u+1,l=c.nextForwardToken||null,c.status==="completed"||c.status==="failed"){let y=c.status==="completed"?t.green:t.red;console.log(y(`
|
|
25
|
+
Job ${c.status}.`)),process.exit(c.status==="completed"?0:1)}if(!n){c.status&&console.log(t.gray(`
|
|
26
|
+
Status: ${c.status}`));break}let S=c.lines?.length>0?500:u>5?5e3:2e3;await new Promise(y=>setTimeout(y,S))}catch(I){if(I.name==="AbortError")break;I.message.match(/API (400|401|403|404):/)&&(console.error(t.red(`
|
|
27
27
|
${I.message}
|
|
28
|
-
`)),process.exit(1)),
|
|
29
|
-
Too many consecutive errors (${
|
|
30
|
-
`)),process.exit(1)),n||process.exit(1),await new Promise(
|
|
28
|
+
`)),process.exit(1)),f++,console.error(t.red(` Error: ${I.message}`)),f>=d&&(console.error(t.red(`
|
|
29
|
+
Too many consecutive errors (${d}). Stopping.
|
|
30
|
+
`)),process.exit(1)),n||process.exit(1),await new Promise(g=>setTimeout(g,3e3))}}async function te({token:r,projectId:e,workflow:o,follow:n,limit:p}){let a=`${B}/all/${e}`,l=null,u=0,s=new Set,i=null,f=!1,d=0,w=5,I=()=>{f=!0,console.log(t.gray(`
|
|
31
31
|
Stopped tailing.
|
|
32
|
-
`)),process.exit(0)};for(process.on("SIGINT",I),process.on("SIGTERM",I),console.log(
|
|
33
|
-
Tailing all runs for ${
|
|
34
|
-
`):"");!
|
|
35
|
-
... more logs available. Run again or use --follow to stream.`)),
|
|
36
|
-
No running jobs. All caught up.`));break}let
|
|
37
|
-
${
|
|
38
|
-
`)),process.exit(1)),
|
|
39
|
-
Too many consecutive errors (${
|
|
40
|
-
`)),process.exit(1)),n||process.exit(1),await new Promise(k=>setTimeout(k,3e3))}}async function
|
|
41
|
-
--workflow is required with --all`)),console.log(
|
|
42
|
-
`)),process.exit(1)),
|
|
32
|
+
`)),process.exit(0)};for(process.on("SIGINT",I),process.on("SIGTERM",I),console.log(t.gray(`
|
|
33
|
+
Tailing all runs for ${t.cyan(o)}...`)),console.log(n?t.gray(` Press Ctrl+C to stop.
|
|
34
|
+
`):"");!f;)try{let c=new URLSearchParams({workflow:o,limit:String(p)});l&&c.set("nextToken",l);let g=await M(`${a}?${c}`,r);d=0,g.message&&g.lines?.length===0&&u===0&&console.log(t.gray(` ${g.message}`));for(let y of g.lines||[]){let E=`${y.timestamp}:${y.jobId}:${y.message}`;if(s.has(E))continue;s.add(E),y.jobId!==i&&(i!==null&&console.log(""),console.log(t.dim(` \u2500\u2500 ${y.jobId} \u2500\u2500`)),i=y.jobId);let _=t.gray(L(y.timestamp));console.log(`${_} ${y.message.replace(/\n$/,"")}`)}if(u=g.lines?.length>0?0:u+1,l=g.nextToken||null,!n){l&&console.log(t.gray(`
|
|
35
|
+
... more logs available. Run again or use --follow to stream.`)),g.jobCount&&console.log(t.gray(` ${g.jobCount} job(s) found.`));break}if(!g.hasRunning&&!l&&u>2){console.log(t.gray(`
|
|
36
|
+
No running jobs. All caught up.`));break}let S=g.lines?.length>0?500:u>5?5e3:2e3;await new Promise(y=>setTimeout(y,S))}catch(c){if(c.name==="AbortError")break;c.message.match(/API (400|401|403|404):/)&&(console.error(t.red(`
|
|
37
|
+
${c.message}
|
|
38
|
+
`)),process.exit(1)),d++,console.error(t.red(` Error: ${c.message}`)),d>=w&&(console.error(t.red(`
|
|
39
|
+
Too many consecutive errors (${w}). Stopping.
|
|
40
|
+
`)),process.exit(1)),n||process.exit(1),await new Promise(k=>setTimeout(k,3e3))}}async function ce(r,e){let{token:o,projectId:n}=G(e),p=e.follow===!0,a=e.lines?parseInt(e.lines,10):1e5;if(e.all){let u=e.workflow;return u||(console.log(t.red(`
|
|
41
|
+
--workflow is required with --all`)),console.log(t.gray(` Example: zibby workflow logs --workflow ticket-triage --all --project <id>
|
|
42
|
+
`)),process.exit(1)),te({token:o,projectId:n,workflow:u,follow:p,limit:a})}let l=await V(r,e,o,n);return p?ee({token:o,jobId:l,follow:p,projectId:n}):j({token:o,projectId:n,jobId:l,follow:!1,limit:a})}export{ce as logsCommand,H as parseSseChunk,K as runReconnectLoop,q as sseBackoffMs};
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var Ct=Object.defineProperty;var Ce=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var y=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ne=(e,t)=>{for(var r in t)Ct(e,r,{get:t[r],enumerable:!0})};var He,Je=y(()=>{He="ffffffff-ffff-ffff-ffff-ffffffffffff"});var Me,Qe=y(()=>{Me="00000000-0000-0000-0000-000000000000"});var Ye,qe=y(()=>{Ye=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i});function Vt(e){return typeof e=="string"&&Ye.test(e)}var F,J=y(()=>{qe();F=Vt});function Xt(e){if(!F(e))throw TypeError("Invalid UUID");let t;return Uint8Array.of((t=parseInt(e.slice(0,8),16))>>>24,t>>>16&255,t>>>8&255,t&255,(t=parseInt(e.slice(9,13),16))>>>8,t&255,(t=parseInt(e.slice(14,18),16))>>>8,t&255,(t=parseInt(e.slice(19,23),16))>>>8,t&255,(t=parseInt(e.slice(24,36),16))/1099511627776&255,t/4294967296&255,t>>>24&255,t>>>16&255,t>>>8&255,t&255)}var C,M=y(()=>{J();C=Xt});function U(e,t=0){return($[e[t+0]]+$[e[t+1]]+$[e[t+2]]+$[e[t+3]]+"-"+$[e[t+4]]+$[e[t+5]]+"-"+$[e[t+6]]+$[e[t+7]]+"-"+$[e[t+8]]+$[e[t+9]]+"-"+$[e[t+10]]+$[e[t+11]]+$[e[t+12]]+$[e[t+13]]+$[e[t+14]]+$[e[t+15]]).toLowerCase()}function Zt(e,t=0){let r=U(e,t);if(!F(r))throw TypeError("Stringified UUID is invalid");return r}var $,Ve,N=y(()=>{J();$=[];for(let e=0;e<256;++e)$.push((e+256).toString(16).slice(1));Ve=Zt});import{randomFillSync as er}from"crypto";function j(){return re>oe.length-16&&(er(oe),re=0),oe.slice(re,re+=16)}var oe,re,ne=y(()=>{oe=new Uint8Array(256),re=oe.length});function tr(e,t,r){let o,n=e?._v6??!1;if(e){let s=Object.keys(e);s.length===1&&s[0]==="_v6"&&(e=void 0)}if(e)o=Xe(e.random??e.rng?.()??j(),e.msecs,e.nsecs,e.clockseq,e.node,t,r);else{let s=Date.now(),i=j();rr(Q,s,i),o=Xe(i,Q.msecs,Q.nsecs,n?void 0:Q.clockseq,n?void 0:Q.node,t,r)}return t??U(o)}function rr(e,t,r){return e.msecs??=-1/0,e.nsecs??=0,t===e.msecs?(e.nsecs++,e.nsecs>=1e4&&(e.node=void 0,e.nsecs=0)):t>e.msecs?e.nsecs=0:t<e.msecs&&(e.node=void 0),e.node||(e.node=r.slice(10,16),e.node[0]|=1,e.clockseq=(r[8]<<8|r[9])&16383),e.msecs=t,e}function Xe(e,t,r,o,n,s,i=0){if(e.length<16)throw new Error("Random bytes length must be >= 16");if(!s)s=new Uint8Array(16),i=0;else if(i<0||i+16>s.length)throw new RangeError(`UUID byte range ${i}:${i+15} is out of buffer bounds`);t??=Date.now(),r??=0,o??=(e[8]<<8|e[9])&16383,n??=e.slice(10,16),t+=122192928e5;let f=((t&268435455)*1e4+r)%4294967296;s[i++]=f>>>24&255,s[i++]=f>>>16&255,s[i++]=f>>>8&255,s[i++]=f&255;let a=t/4294967296*1e4&268435455;s[i++]=a>>>8&255,s[i++]=a&255,s[i++]=a>>>24&15|16,s[i++]=a>>>16&255,s[i++]=o>>>8|128,s[i++]=o&255;for(let l=0;l<6;++l)s[i++]=n[l];return s}var Q,se,he=y(()=>{ne();N();Q={};se=tr});function Y(e){let t=typeof e=="string"?C(e):e,r=or(t);return typeof e=="string"?U(r):r}function or(e){return Uint8Array.of((e[6]&15)<<4|e[7]>>4&15,(e[7]&15)<<4|(e[4]&240)>>4,(e[4]&15)<<4|(e[5]&240)>>4,(e[5]&15)<<4|(e[0]&240)>>4,(e[0]&15)<<4|(e[1]&240)>>4,(e[1]&15)<<4|(e[2]&240)>>4,96|e[2]&15,e[3],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}var we=y(()=>{M();N()});import{createHash as nr}from"crypto";function sr(e){return Array.isArray(e)?e=Buffer.from(e):typeof e=="string"&&(e=Buffer.from(e,"utf8")),nr("md5").update(e).digest()}var Ze,et=y(()=>{Ze=sr});function ir(e){e=unescape(encodeURIComponent(e));let t=new Uint8Array(e.length);for(let r=0;r<e.length;++r)t[r]=e.charCodeAt(r);return t}function q(e,t,r,o,n,s){let i=typeof r=="string"?ir(r):r,f=typeof o=="string"?C(o):o;if(typeof o=="string"&&(o=C(o)),o?.length!==16)throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)");let a=new Uint8Array(16+i.length);if(a.set(f),a.set(i,f.length),a=t(a),a[6]=a[6]&15|e,a[8]=a[8]&63|128,n){if(s=s||0,s<0||s+16>n.length)throw new RangeError(`UUID byte range ${s}:${s+15} is out of buffer bounds`);for(let l=0;l<16;++l)n[s+l]=a[l];return n}return U(a)}var ie,ae,Se=y(()=>{M();N();ie="6ba7b810-9dad-11d1-80b4-00c04fd430c8",ae="6ba7b811-9dad-11d1-80b4-00c04fd430c8"});function ye(e,t,r,o){return q(48,Ze,e,t,r,o)}var tt,rt=y(()=>{et();Se();ye.DNS=ie;ye.URL=ae;tt=ye});import{randomUUID as ar}from"crypto";var xe,ot=y(()=>{xe={randomUUID:ar}});function cr(e,t,r){if(xe.randomUUID&&!t&&!e)return xe.randomUUID();e=e||{};let o=e.random??e.rng?.()??j();if(o.length<16)throw new Error("Random bytes length must be >= 16");if(o[6]=o[6]&15|64,o[8]=o[8]&63|128,t){if(r=r||0,r<0||r+16>t.length)throw new RangeError(`UUID byte range ${r}:${r+15} is out of buffer bounds`);for(let n=0;n<16;++n)t[r+n]=o[n];return t}return U(o)}var nt,st=y(()=>{ot();ne();N();nt=cr});import{createHash as lr}from"crypto";function fr(e){return Array.isArray(e)?e=Buffer.from(e):typeof e=="string"&&(e=Buffer.from(e,"utf8")),lr("sha1").update(e).digest()}var it,at=y(()=>{it=fr});function _e(e,t,r,o){return q(80,it,e,t,r,o)}var ct,lt=y(()=>{at();Se();_e.DNS=ie;_e.URL=ae;ct=_e});function pr(e,t,r){e??={},r??=0;let o=se({...e,_v6:!0},new Uint8Array(16));if(o=Y(o),t){if(r<0||r+16>t.length)throw new RangeError(`UUID byte range ${r}:${r+15} is out of buffer bounds`);for(let n=0;n<16;n++)t[r+n]=o[n];return t}return U(o)}var ft,pt=y(()=>{N();he();we();ft=pr});function Ee(e){let t=typeof e=="string"?C(e):e,r=dr(t);return typeof e=="string"?U(r):r}function dr(e){return Uint8Array.of((e[3]&15)<<4|e[4]>>4&15,(e[4]&15)<<4|(e[5]&240)>>4,(e[5]&15)<<4|e[6]&15,e[7],(e[1]&15)<<4|(e[2]&240)>>4,(e[2]&15)<<4|(e[3]&240)>>4,16|(e[0]&240)>>4,(e[0]&15)<<4|(e[1]&240)>>4,e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}var dt=y(()=>{M();N()});function ur(e,t,r){let o;if(e)o=ut(e.random??e.rng?.()??j(),e.msecs,e.seq,t,r);else{let n=Date.now(),s=j();gr($e,n,s),o=ut(s,$e.msecs,$e.seq,t,r)}return t??U(o)}function gr(e,t,r){return e.msecs??=-1/0,e.seq??=0,t>e.msecs?(e.seq=r[6]<<23|r[7]<<16|r[8]<<8|r[9],e.msecs=t):(e.seq=e.seq+1|0,e.seq===0&&e.msecs++),e}function ut(e,t,r,o,n=0){if(e.length<16)throw new Error("Random bytes length must be >= 16");if(!o)o=new Uint8Array(16),n=0;else if(n<0||n+16>o.length)throw new RangeError(`UUID byte range ${n}:${n+15} is out of buffer bounds`);return t??=Date.now(),r??=e[6]*127<<24|e[7]<<16|e[8]<<8|e[9],o[n++]=t/1099511627776&255,o[n++]=t/4294967296&255,o[n++]=t/16777216&255,o[n++]=t/65536&255,o[n++]=t/256&255,o[n++]=t&255,o[n++]=112|r>>>28&15,o[n++]=r>>>20&255,o[n++]=128|r>>>14&63,o[n++]=r>>>6&255,o[n++]=r<<2&255|e[10]&3,o[n++]=e[11],o[n++]=e[12],o[n++]=e[13],o[n++]=e[14],o[n++]=e[15],o}var $e,gt,mt=y(()=>{ne();N();$e={};gt=ur});function mr(e){if(!F(e))throw TypeError("Invalid UUID");return parseInt(e.slice(14,15),16)}var ht,wt=y(()=>{J();ht=mr});var St={};Ne(St,{MAX:()=>He,NIL:()=>Me,parse:()=>C,stringify:()=>Ve,v1:()=>se,v1ToV6:()=>Y,v3:()=>tt,v4:()=>nt,v5:()=>ct,v6:()=>ft,v6ToV1:()=>Ee,v7:()=>gt,validate:()=>F,version:()=>ht});var yt=y(()=>{Je();Qe();M();N();he();we();rt();st();lt();pt();dt();mt();J();wt()});var Rt={};Ne(Rt,{uploadSessionArtifacts:()=>Or});import{readdirSync as _t,statSync as Re,createReadStream as hr,existsSync as wr}from"node:fs";import{join as Et,relative as Sr,sep as yr,extname as xr}from"node:path";function Rr(e){let t=xr(e).toLowerCase();return $r[t]||"application/octet-stream"}function $t(e){let t=[],r;try{r=_t(e)}catch{return t}for(let o of r){if(_r.has(o)||o.startsWith(".")||Er.has(o))continue;let n=Et(e,o),s;try{s=Re(n)}catch{continue}s.isDirectory()?t.push(...$t(n)):s.isFile()&&t.push(n)}return t}async function Ur({apiUrl:e,apiKey:t,executionId:r,nodeName:o,filename:n,absolutePath:s,sizeBytes:i,contentType:f}){let a;try{let l=await fetch(`${e}/${r}/artifacts/upload-url`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({nodeName:o,filename:n,contentType:f,sizeBytes:i})});if(!l.ok){let c=await l.text();return console.warn(`[artifacts] upload-url failed for ${o}/${n}: ${l.status} ${c.slice(0,200)}`),null}a=await l.json()}catch(l){return console.warn(`[artifacts] upload-url request errored for ${o}/${n}: ${l.message}`),null}try{let l=hr(s),c=a.requiredHeaders?{...a.requiredHeaders,"Content-Length":String(i)}:{"Content-Type":f,"Content-Length":String(i)},p=await fetch(a.url,{method:"PUT",headers:c,body:l,duplex:"half"});if(!p.ok)return console.warn(`[artifacts] S3 PUT failed for ${o}/${n}: ${p.status}`),null}catch(l){return console.warn(`[artifacts] S3 PUT errored for ${o}/${n}: ${l.message}`),null}return{nodeName:o,filename:n,s3Key:a.s3Key,contentType:f,sizeBytes:i}}async function Or({sessionPath:e,executionId:t,apiUrl:r,apiKey:o}){let n={uploaded:[],skipped:[]};if(!e||!wr(e))return n;if(!r||!o||!t)return console.warn("[artifacts] uploader missing required input \u2014 skipping"),n;let s;try{s=_t(e)}catch(c){return console.warn(`[artifacts] could not read session folder ${e}: ${c.message}`),n}let i=[];for(let c of s){let p=Et(e,c),d;try{d=Re(p)}catch{continue}if(!d.isDirectory()||c.startsWith(".")||c.startsWith("_"))continue;let R=$t(p);for(let S of R){let I=Sr(p,S).split(yr).join("/"),_;try{_=Re(S).size}catch{continue}if(_>xt){n.skipped.push({nodeName:c,filename:I,reason:`size ${_} > ${xt}`});continue}if(_===0){n.skipped.push({nodeName:c,filename:I,reason:"empty"});continue}i.push({apiUrl:r,apiKey:o,executionId:t,nodeName:c,filename:I,absolutePath:S,sizeBytes:_,contentType:Rr(I)})}}if(i.length===0)return n;let f=4,a=i.slice(),l=Array.from({length:Math.min(f,a.length)},async()=>{for(;a.length;){let c=a.shift(),p=await Ur(c);p?n.uploaded.push(p):n.skipped.push({nodeName:c.nodeName,filename:c.filename,reason:"upload failed"})}});if(await Promise.all(l),n.uploaded.length>0)try{let c=await fetch(`${r}/${t}/artifacts`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify({files:n.uploaded})});if(!c.ok){let p=await c.text();console.warn(`[artifacts] record failed: ${c.status} ${p.slice(0,200)}`)}}catch(c){console.warn(`[artifacts] record errored: ${c.message}`)}return n}var xt,_r,Er,$r,Ut=y(()=>{xt=500*1024*1024,_r=new Set([".DS_Store","Thumbs.db",".zibby-stop"]),Er=new Set(["node_modules",".git","dist",".zibby","__tests__","__mocks__",".cache",".next",".turbo"]),$r={".webm":"video/webm",".mp4":"video/mp4",".mov":"video/quicktime",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".txt":"text/plain",".md":"text/markdown",".csv":"text/csv",".log":"text/plain",".json":"application/json",".yaml":"application/yaml",".yml":"application/yaml",".pdf":"application/pdf",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip"}});import{mkdirSync as Pt,writeFileSync as Ir,existsSync as G,readFileSync as Ot}from"fs";import{join as D,dirname as Tr,resolve as It}from"path";import{pathToFileURL as Oe}from"url";import{spawn as Ie}from"node:child_process";import{SQSClient as Nt,SendMessageCommand as jt}from"@aws-sdk/client-sqs";var pe=null;function Kt(){return pe||(pe=new Nt({region:process.env.AWS_REGION||"ap-southeast-2"})),pe}async function de(e,t,r,o){let{EXECUTION_ID:n,SQS_AUTH_TOKEN:s,PROGRESS_API_URL:i,PROGRESS_QUEUE_URL:f,PROJECT_API_TOKEN:a}=o;if(!n)return;let l={executionId:n,...s&&{sqsAuthToken:s},step:{name:e,status:t,logs:r,timestamp:new Date().toISOString(),...t==="success"&&{completedAt:new Date().toISOString()}},status:t==="failed"?"failed":"running"};try{i?await ue(i,n,l,a):f&&await ge(f,n,l)}catch(c){console.error(`\u26A0\uFE0F Failed to send progress: ${c.message}`)}}async function je(e,t,r){let{EXECUTION_ID:o,SQS_AUTH_TOKEN:n,PROGRESS_API_URL:s,PROGRESS_QUEUE_URL:i,PROJECT_API_TOKEN:f}=e;if(!o||!r)return;let a=JSON.stringify(r).length;console.log(`Sending artifact: ${t} (${(a/1024).toFixed(1)}KB)`);let l={executionId:o,...n&&{sqsAuthToken:n},artifacts:{[t]:r},timestamp:new Date().toISOString()},c=s?"HTTP":i?"SQS":"NONE",p=JSON.stringify(l).length;try{if(s)await ue(s,o,l,f);else if(i)await ge(i,o,l);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 ${c} (payload=${(p/1024).toFixed(1)}KB, value=${(a/1024).toFixed(1)}KB)`)}catch(d){console.error(`Failed to send artifact ${t} via ${c}:`),console.error(` Payload size: ${(p/1024).toFixed(1)}KB, Value size: ${(a/1024).toFixed(1)}KB`),console.error(` Error: ${d.message}`),d.name&&console.error(` Error type: ${d.name}`),d.code&&console.error(` Error code: ${d.code}`),p>256*1024&&console.error(" \u26A0\uFE0F Message exceeds SQS 256KB limit! Consider splitting or compressing.")}}async function Ke(e,{status:t,error:r,finalState:o}){let{EXECUTION_ID:n,SQS_AUTH_TOKEN:s,PROGRESS_API_URL:i,PROGRESS_QUEUE_URL:f,PROJECT_API_TOKEN:a}=e;if(!n)return;let l={executionId:n,...s&&{sqsAuthToken:s},status:t,...r&&{error:r},...o&&typeof o=="object"&&Object.keys(o).length>0?{finalState:o}:{},timestamp:new Date().toISOString()},c=i?"HTTP":f?"SQS":"NONE",p=JSON.stringify(l).length;console.log(`Sending final status: ${t} via ${c} (${(p/1024).toFixed(1)}KB)`);try{if(i)await ue(i,n,l,a);else if(f){let d=["completed","failed","insufficient_context","blocked"].includes(t)?"execution_completed":"progress_update";await ge(f,n,l,d)}else{console.warn("No transport configured for final status \u2014 neither PROGRESS_API_URL nor PROGRESS_QUEUE_URL set");return}console.log(`Final status ${t} sent via ${c}`)}catch(d){console.error(`Failed to send final status (${t}) via ${c}:`),console.error(` Payload: ${(p/1024).toFixed(1)}KB`),console.error(` Error: ${d.message}`),d.name&&console.error(` Error type: ${d.name}`),d.code&&console.error(` Error code: ${d.code}`)}}async function ue(e,t,r,o){let n=`${e}/${t}/progress`,s={"Content-Type":"application/json"};o&&(s.Authorization=`Bearer ${o}`);let i=await fetch(n,{method:"POST",headers:s,body:JSON.stringify(r)});if(!i.ok){let f=await i.text();throw new Error(`HTTP ${i.status}: ${f}`)}}async function ge(e,t,r,o="progress_update"){let n=JSON.stringify(r),s=(n.length/1024).toFixed(1);n.length>256*1024&&console.error(`\u274C SQS message too large: ${s}KB (limit 256KB) for ${t} [${o}]`),await Kt().send(new jt({QueueUrl:e,MessageBody:n,MessageGroupId:t,MessageAttributes:{executionId:{DataType:"String",StringValue:t},messageType:{DataType:"String",StringValue:o}}}))}function Ft(e,t){try{let r=e?.sessionPath||e?.SESSION_PATH||process.env.ZIBBY_SESSION_PATH;if(!r||!t)return null;let o=Ce("fs"),s=Ce("path").join(r,t,"usage.json");if(!o.existsSync(s))return null;let i=o.readFileSync(s,"utf-8"),f=JSON.parse(i);return!f.input_tokens&&!f.output_tokens&&!f.inputTokens&&!f.outputTokens?null:f}catch{return null}}function Fe(e,t,r=null){return async function(n,s,i){let f=Date.now(),a=[],l="",c=console.log,p=process.stdout.write.bind(process.stdout),d=process.stderr.write.bind(process.stderr),R=!1;console.log=(...w)=>{let u=w.map(h=>typeof h=="string"?h:JSON.stringify(h)).join(" ");a.push(u),R=!0,c(...w),R=!1};let S="";process.stdout.write=(w,u,h)=>{if(!R){let x=typeof w=="string"?w:w.toString();S+=x;let m=S.split(`
|
|
3
|
-
`);
|
|
4
|
-
`);
|
|
5
|
-
`),e(n,"in_progress",
|
|
6
|
-
`)}))},500);try{await e(n,"in_progress","",i);let
|
|
7
|
-
`);
|
|
8
|
-
`);let
|
|
9
|
-
`)}if(
|
|
10
|
-
`)}}else await e(n,"failed",`${
|
|
2
|
+
var Nt=Object.defineProperty;var Ne=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var S=(e,t)=>()=>(e&&(t=e(e=0)),t);var je=(e,t)=>{for(var r in t)Nt(e,r,{get:t[r],enumerable:!0})};var Je,Me=S(()=>{Je="ffffffff-ffff-ffff-ffff-ffffffffffff"});var Qe,Ye=S(()=>{Qe="00000000-0000-0000-0000-000000000000"});var qe,Ve=S(()=>{qe=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i});function Xt(e){return typeof e=="string"&&qe.test(e)}var F,J=S(()=>{Ve();F=Xt});function Zt(e){if(!F(e))throw TypeError("Invalid UUID");let t;return Uint8Array.of((t=parseInt(e.slice(0,8),16))>>>24,t>>>16&255,t>>>8&255,t&255,(t=parseInt(e.slice(9,13),16))>>>8,t&255,(t=parseInt(e.slice(14,18),16))>>>8,t&255,(t=parseInt(e.slice(19,23),16))>>>8,t&255,(t=parseInt(e.slice(24,36),16))/1099511627776&255,t/4294967296&255,t>>>24&255,t>>>16&255,t>>>8&255,t&255)}var N,M=S(()=>{J();N=Zt});function O(e,t=0){return(_[e[t+0]]+_[e[t+1]]+_[e[t+2]]+_[e[t+3]]+"-"+_[e[t+4]]+_[e[t+5]]+"-"+_[e[t+6]]+_[e[t+7]]+"-"+_[e[t+8]]+_[e[t+9]]+"-"+_[e[t+10]]+_[e[t+11]]+_[e[t+12]]+_[e[t+13]]+_[e[t+14]]+_[e[t+15]]).toLowerCase()}function er(e,t=0){let r=O(e,t);if(!F(r))throw TypeError("Stringified UUID is invalid");return r}var _,Xe,j=S(()=>{J();_=[];for(let e=0;e<256;++e)_.push((e+256).toString(16).slice(1));Xe=er});import{randomFillSync as tr}from"crypto";function K(){return re>oe.length-16&&(tr(oe),re=0),oe.slice(re,re+=16)}var oe,re,ne=S(()=>{oe=new Uint8Array(256),re=oe.length});function rr(e,t,r){let o,n=e?._v6??!1;if(e){let s=Object.keys(e);s.length===1&&s[0]==="_v6"&&(e=void 0)}if(e)o=Ze(e.random??e.rng?.()??K(),e.msecs,e.nsecs,e.clockseq,e.node,t,r);else{let s=Date.now(),i=K();or(Q,s,i),o=Ze(i,Q.msecs,Q.nsecs,n?void 0:Q.clockseq,n?void 0:Q.node,t,r)}return t??O(o)}function or(e,t,r){return e.msecs??=-1/0,e.nsecs??=0,t===e.msecs?(e.nsecs++,e.nsecs>=1e4&&(e.node=void 0,e.nsecs=0)):t>e.msecs?e.nsecs=0:t<e.msecs&&(e.node=void 0),e.node||(e.node=r.slice(10,16),e.node[0]|=1,e.clockseq=(r[8]<<8|r[9])&16383),e.msecs=t,e}function Ze(e,t,r,o,n,s,i=0){if(e.length<16)throw new Error("Random bytes length must be >= 16");if(!s)s=new Uint8Array(16),i=0;else if(i<0||i+16>s.length)throw new RangeError(`UUID byte range ${i}:${i+15} is out of buffer bounds`);t??=Date.now(),r??=0,o??=(e[8]<<8|e[9])&16383,n??=e.slice(10,16),t+=122192928e5;let f=((t&268435455)*1e4+r)%4294967296;s[i++]=f>>>24&255,s[i++]=f>>>16&255,s[i++]=f>>>8&255,s[i++]=f&255;let a=t/4294967296*1e4&268435455;s[i++]=a>>>8&255,s[i++]=a&255,s[i++]=a>>>24&15|16,s[i++]=a>>>16&255,s[i++]=o>>>8|128,s[i++]=o&255;for(let l=0;l<6;++l)s[i++]=n[l];return s}var Q,se,he=S(()=>{ne();j();Q={};se=rr});function Y(e){let t=typeof e=="string"?N(e):e,r=nr(t);return typeof e=="string"?O(r):r}function nr(e){return Uint8Array.of((e[6]&15)<<4|e[7]>>4&15,(e[7]&15)<<4|(e[4]&240)>>4,(e[4]&15)<<4|(e[5]&240)>>4,(e[5]&15)<<4|(e[0]&240)>>4,(e[0]&15)<<4|(e[1]&240)>>4,(e[1]&15)<<4|(e[2]&240)>>4,96|e[2]&15,e[3],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}var we=S(()=>{M();j()});import{createHash as sr}from"crypto";function ir(e){return Array.isArray(e)?e=Buffer.from(e):typeof e=="string"&&(e=Buffer.from(e,"utf8")),sr("md5").update(e).digest()}var et,tt=S(()=>{et=ir});function ar(e){e=unescape(encodeURIComponent(e));let t=new Uint8Array(e.length);for(let r=0;r<e.length;++r)t[r]=e.charCodeAt(r);return t}function q(e,t,r,o,n,s){let i=typeof r=="string"?ar(r):r,f=typeof o=="string"?N(o):o;if(typeof o=="string"&&(o=N(o)),o?.length!==16)throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)");let a=new Uint8Array(16+i.length);if(a.set(f),a.set(i,f.length),a=t(a),a[6]=a[6]&15|e,a[8]=a[8]&63|128,n){if(s=s||0,s<0||s+16>n.length)throw new RangeError(`UUID byte range ${s}:${s+15} is out of buffer bounds`);for(let l=0;l<16;++l)n[s+l]=a[l];return n}return O(a)}var ie,ae,Se=S(()=>{M();j();ie="6ba7b810-9dad-11d1-80b4-00c04fd430c8",ae="6ba7b811-9dad-11d1-80b4-00c04fd430c8"});function ye(e,t,r,o){return q(48,et,e,t,r,o)}var rt,ot=S(()=>{tt();Se();ye.DNS=ie;ye.URL=ae;rt=ye});import{randomUUID as cr}from"crypto";var xe,nt=S(()=>{xe={randomUUID:cr}});function lr(e,t,r){if(xe.randomUUID&&!t&&!e)return xe.randomUUID();e=e||{};let o=e.random??e.rng?.()??K();if(o.length<16)throw new Error("Random bytes length must be >= 16");if(o[6]=o[6]&15|64,o[8]=o[8]&63|128,t){if(r=r||0,r<0||r+16>t.length)throw new RangeError(`UUID byte range ${r}:${r+15} is out of buffer bounds`);for(let n=0;n<16;++n)t[r+n]=o[n];return t}return O(o)}var st,it=S(()=>{nt();ne();j();st=lr});import{createHash as fr}from"crypto";function pr(e){return Array.isArray(e)?e=Buffer.from(e):typeof e=="string"&&(e=Buffer.from(e,"utf8")),fr("sha1").update(e).digest()}var at,ct=S(()=>{at=pr});function _e(e,t,r,o){return q(80,at,e,t,r,o)}var lt,ft=S(()=>{ct();Se();_e.DNS=ie;_e.URL=ae;lt=_e});function dr(e,t,r){e??={},r??=0;let o=se({...e,_v6:!0},new Uint8Array(16));if(o=Y(o),t){if(r<0||r+16>t.length)throw new RangeError(`UUID byte range ${r}:${r+15} is out of buffer bounds`);for(let n=0;n<16;n++)t[r+n]=o[n];return t}return O(o)}var pt,dt=S(()=>{j();he();we();pt=dr});function Ee(e){let t=typeof e=="string"?N(e):e,r=ur(t);return typeof e=="string"?O(r):r}function ur(e){return Uint8Array.of((e[3]&15)<<4|e[4]>>4&15,(e[4]&15)<<4|(e[5]&240)>>4,(e[5]&15)<<4|e[6]&15,e[7],(e[1]&15)<<4|(e[2]&240)>>4,(e[2]&15)<<4|(e[3]&240)>>4,16|(e[0]&240)>>4,(e[0]&15)<<4|(e[1]&240)>>4,e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}var ut=S(()=>{M();j()});function gr(e,t,r){let o;if(e)o=gt(e.random??e.rng?.()??K(),e.msecs,e.seq,t,r);else{let n=Date.now(),s=K();mr($e,n,s),o=gt(s,$e.msecs,$e.seq,t,r)}return t??O(o)}function mr(e,t,r){return e.msecs??=-1/0,e.seq??=0,t>e.msecs?(e.seq=r[6]<<23|r[7]<<16|r[8]<<8|r[9],e.msecs=t):(e.seq=e.seq+1|0,e.seq===0&&e.msecs++),e}function gt(e,t,r,o,n=0){if(e.length<16)throw new Error("Random bytes length must be >= 16");if(!o)o=new Uint8Array(16),n=0;else if(n<0||n+16>o.length)throw new RangeError(`UUID byte range ${n}:${n+15} is out of buffer bounds`);return t??=Date.now(),r??=e[6]*127<<24|e[7]<<16|e[8]<<8|e[9],o[n++]=t/1099511627776&255,o[n++]=t/4294967296&255,o[n++]=t/16777216&255,o[n++]=t/65536&255,o[n++]=t/256&255,o[n++]=t&255,o[n++]=112|r>>>28&15,o[n++]=r>>>20&255,o[n++]=128|r>>>14&63,o[n++]=r>>>6&255,o[n++]=r<<2&255|e[10]&3,o[n++]=e[11],o[n++]=e[12],o[n++]=e[13],o[n++]=e[14],o[n++]=e[15],o}var $e,mt,ht=S(()=>{ne();j();$e={};mt=gr});function hr(e){if(!F(e))throw TypeError("Invalid UUID");return parseInt(e.slice(14,15),16)}var wt,St=S(()=>{J();wt=hr});var yt={};je(yt,{MAX:()=>Je,NIL:()=>Qe,parse:()=>N,stringify:()=>Xe,v1:()=>se,v1ToV6:()=>Y,v3:()=>rt,v4:()=>st,v5:()=>lt,v6:()=>pt,v6ToV1:()=>Ee,v7:()=>mt,validate:()=>F,version:()=>wt});var xt=S(()=>{Me();Ye();M();j();he();we();ot();it();ft();dt();ut();ht();J();St()});var Ot={};je(Ot,{uploadSessionArtifacts:()=>Ir});import{readdirSync as Et,statSync as Re,createReadStream as wr,existsSync as Sr}from"node:fs";import{join as $t,relative as yr,sep as xr,extname as _r}from"node:path";function Or(e){let t=_r(e).toLowerCase();return Rr[t]||"application/octet-stream"}function Rt(e){let t=[],r;try{r=Et(e)}catch{return t}for(let o of r){if(Er.has(o)||o.startsWith(".")||$r.has(o))continue;let n=$t(e,o),s;try{s=Re(n)}catch{continue}s.isDirectory()?t.push(...Rt(n)):s.isFile()&&t.push(n)}return t}async function Ur({apiUrl:e,apiKey:t,executionId:r,nodeName:o,filename:n,absolutePath:s,sizeBytes:i,contentType:f}){let a;try{let l=await fetch(`${e}/${r}/artifacts/upload-url`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({nodeName:o,filename:n,contentType:f,sizeBytes:i})});if(!l.ok){let c=await l.text();return console.warn(`[artifacts] upload-url failed for ${o}/${n}: ${l.status} ${c.slice(0,200)}`),null}a=await l.json()}catch(l){return console.warn(`[artifacts] upload-url request errored for ${o}/${n}: ${l.message}`),null}try{let l=wr(s),c=a.requiredHeaders?{...a.requiredHeaders,"Content-Length":String(i)}:{"Content-Type":f,"Content-Length":String(i)},d=await fetch(a.url,{method:"PUT",headers:c,body:l,duplex:"half"});if(!d.ok)return console.warn(`[artifacts] S3 PUT failed for ${o}/${n}: ${d.status}`),null}catch(l){return console.warn(`[artifacts] S3 PUT errored for ${o}/${n}: ${l.message}`),null}return{nodeName:o,filename:n,s3Key:a.s3Key,contentType:f,sizeBytes:i}}async function Ir({sessionPath:e,executionId:t,apiUrl:r,apiKey:o}){let n={uploaded:[],skipped:[]};if(!e||!Sr(e))return n;if(!r||!o||!t)return console.warn("[artifacts] uploader missing required input \u2014 skipping"),n;let s;try{s=Et(e)}catch(c){return console.warn(`[artifacts] could not read session folder ${e}: ${c.message}`),n}let i=[];for(let c of s){let d=$t(e,c),u;try{u=Re(d)}catch{continue}if(!u.isDirectory()||c.startsWith(".")||c.startsWith("_"))continue;let $=Rt(d);for(let y of $){let U=yr(d,y).split(xr).join("/"),R;try{R=Re(y).size}catch{continue}if(R>_t){n.skipped.push({nodeName:c,filename:U,reason:`size ${R} > ${_t}`});continue}if(R===0){n.skipped.push({nodeName:c,filename:U,reason:"empty"});continue}i.push({apiUrl:r,apiKey:o,executionId:t,nodeName:c,filename:U,absolutePath:y,sizeBytes:R,contentType:Or(U)})}}if(i.length===0)return n;let f=4,a=i.slice(),l=Array.from({length:Math.min(f,a.length)},async()=>{for(;a.length;){let c=a.shift(),d=await Ur(c);d?n.uploaded.push(d):n.skipped.push({nodeName:c.nodeName,filename:c.filename,reason:"upload failed"})}});if(await Promise.all(l),n.uploaded.length>0)try{let c=await fetch(`${r}/${t}/artifacts`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify({files:n.uploaded})});if(!c.ok){let d=await c.text();console.warn(`[artifacts] record failed: ${c.status} ${d.slice(0,200)}`)}}catch(c){console.warn(`[artifacts] record errored: ${c.message}`)}return n}var _t,Er,$r,Rr,Ut=S(()=>{_t=500*1024*1024,Er=new Set([".DS_Store","Thumbs.db",".zibby-stop"]),$r=new Set(["node_modules",".git","dist",".zibby","__tests__","__mocks__",".cache",".next",".turbo"]),Rr={".webm":"video/webm",".mp4":"video/mp4",".mov":"video/quicktime",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".txt":"text/plain",".md":"text/markdown",".csv":"text/csv",".log":"text/plain",".json":"application/json",".yaml":"application/yaml",".yml":"application/yaml",".pdf":"application/pdf",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip"}});import{mkdirSync as At,writeFileSync as Tr,existsSync as G,readFileSync as It}from"fs";import{join as b,dirname as Pr,resolve as Tt}from"path";import{pathToFileURL as Ue}from"url";import{spawn as Ie}from"node:child_process";import{SQSClient as jt,SendMessageCommand as Kt}from"@aws-sdk/client-sqs";var pe=null;function Ft(){return pe||(pe=new jt({region:process.env.AWS_REGION||"ap-southeast-2"})),pe}async function de(e,t,r,o){let{EXECUTION_ID:n,SQS_AUTH_TOKEN:s,PROGRESS_API_URL:i,PROGRESS_QUEUE_URL:f,PROJECT_API_TOKEN:a}=o;if(!n)return;let l={executionId:n,...s&&{sqsAuthToken:s},step:{name:e,status:t,logs:r,timestamp:new Date().toISOString(),...t==="success"&&{completedAt:new Date().toISOString()}},status:t==="failed"?"failed":"running"};try{i?await ue(i,n,l,a):f&&await ge(f,n,l)}catch(c){console.error(`\u26A0\uFE0F Failed to send progress: ${c.message}`)}}async function Ke(e,t,r){let{EXECUTION_ID:o,SQS_AUTH_TOKEN:n,PROGRESS_API_URL:s,PROGRESS_QUEUE_URL:i,PROJECT_API_TOKEN:f}=e;if(!o||!r)return;let a=JSON.stringify(r).length;console.log(`Sending artifact: ${t} (${(a/1024).toFixed(1)}KB)`);let l={executionId:o,...n&&{sqsAuthToken:n},artifacts:{[t]:r},timestamp:new Date().toISOString()},c=s?"HTTP":i?"SQS":"NONE",d=JSON.stringify(l).length;try{if(s)await ue(s,o,l,f);else if(i)await ge(i,o,l);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 ${c} (payload=${(d/1024).toFixed(1)}KB, value=${(a/1024).toFixed(1)}KB)`)}catch(u){console.error(`Failed to send artifact ${t} via ${c}:`),console.error(` Payload size: ${(d/1024).toFixed(1)}KB, Value size: ${(a/1024).toFixed(1)}KB`),console.error(` Error: ${u.message}`),u.name&&console.error(` Error type: ${u.name}`),u.code&&console.error(` Error code: ${u.code}`),d>256*1024&&console.error(" \u26A0\uFE0F Message exceeds SQS 256KB limit! Consider splitting or compressing.")}}async function Fe(e,{status:t,error:r,finalState:o}){let{EXECUTION_ID:n,SQS_AUTH_TOKEN:s,PROGRESS_API_URL:i,PROGRESS_QUEUE_URL:f,PROJECT_API_TOKEN:a}=e;if(!n)return;let l={executionId:n,...s&&{sqsAuthToken:s},status:t,...r&&{error:r},...o&&typeof o=="object"&&Object.keys(o).length>0?{finalState:o}:{},timestamp:new Date().toISOString()},c=i?"HTTP":f?"SQS":"NONE",d=JSON.stringify(l).length;console.log(`Sending final status: ${t} via ${c} (${(d/1024).toFixed(1)}KB)`);try{if(i)await ue(i,n,l,a);else if(f){let u=["completed","failed","insufficient_context","blocked"].includes(t)?"execution_completed":"progress_update";await ge(f,n,l,u)}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 ${c}`)}catch(u){console.error(`Failed to send final status (${t}) via ${c}:`),console.error(` Payload: ${(d/1024).toFixed(1)}KB`),console.error(` Error: ${u.message}`),u.name&&console.error(` Error type: ${u.name}`),u.code&&console.error(` Error code: ${u.code}`)}}async function ue(e,t,r,o){let n=`${e}/${t}/progress`,s={"Content-Type":"application/json"};o&&(s.Authorization=`Bearer ${o}`);let i=await fetch(n,{method:"POST",headers:s,body:JSON.stringify(r)});if(!i.ok){let f=await i.text();throw new Error(`HTTP ${i.status}: ${f}`)}}async function ge(e,t,r,o="progress_update"){let n=JSON.stringify(r),s=(n.length/1024).toFixed(1);n.length>256*1024&&console.error(`\u274C SQS message too large: ${s}KB (limit 256KB) for ${t} [${o}]`),await Ft().send(new Kt({QueueUrl:e,MessageBody:n,MessageGroupId:t,MessageAttributes:{executionId:{DataType:"String",StringValue:t},messageType:{DataType:"String",StringValue:o}}}))}function Gt(e,t){try{let r=e?.sessionPath||e?.SESSION_PATH||process.env.ZIBBY_SESSION_PATH;if(!r||!t)return null;let o=Ne("fs"),s=Ne("path").join(r,t,"usage.json");if(!o.existsSync(s))return null;let i=o.readFileSync(s,"utf-8"),f=JSON.parse(i);return!f.input_tokens&&!f.output_tokens&&!f.inputTokens&&!f.outputTokens?null:f}catch{return null}}function Ge(e,t,r=null){return async function(n,s,i){let f=Date.now(),a=[],l="",c=console.log,d=process.stdout.write.bind(process.stdout),u=process.stderr.write.bind(process.stderr),$=!1;console.log=(...h)=>{let g=h.map(w=>typeof w=="string"?w:JSON.stringify(w)).join(" ");a.push(g),$=!0,c(...h),$=!1};let y="";process.stdout.write=(h,g,w)=>{if(!$){let E=typeof h=="string"?h:h.toString();y+=E;let m=y.split(`
|
|
3
|
+
`);y=m.pop()||"";for(let I of m){let D=I.trim();D&&a.push(D)}}return d(h,g,w)},c(`[Middleware] Started capturing logs for ${n}`);let U=!1,R=setInterval(()=>{if(U)return;let h=a.join(`
|
|
4
|
+
`);h!==l&&h.length>0&&(l=h,u(`\u{1F4E1} [Middleware] Sending live update for ${n}: ${h.length} chars, ${a.length} lines
|
|
5
|
+
`),e(n,"in_progress",h,i).catch(g=>{u(`\u26A0\uFE0F [Middleware] Failed to send live update: ${g.message}
|
|
6
|
+
`)}))},500);try{await e(n,"in_progress","",i);let h=await s(),g=((Date.now()-f)/1e3).toFixed(1);U=!0,clearInterval(R),await new Promise(m=>setImmediate(m)),console.log=c,process.stdout.write=d,y.trim()&&(a.push(y.trim()),y="");let w=a.join(`
|
|
7
|
+
`);u(`\u{1F4E1} [Middleware] Sending final update for ${n}: ${w.length} chars, ${a.length} total lines captured
|
|
8
|
+
`);let E=Gt(i,n);if(E)try{await t(i,`usage_${n}`,E)}catch(m){u(`\u26A0\uFE0F [Middleware] usage ship failed for ${n}: ${m.message}
|
|
9
|
+
`)}if(h.success){if(await e(n,"success",w||`Completed in ${g}s`,i),r)try{let m=r(n,h);m&&m.key&&m.value&&await t(i,m.key,m.value)}catch(m){u(`\u26A0\uFE0F [Middleware] artifactExtractor for ${n} threw: ${m.message}
|
|
10
|
+
`)}}else await e(n,"failed",`${w}
|
|
11
11
|
|
|
12
|
-
Error: ${
|
|
12
|
+
Error: ${h.error}`,i);return h}catch(h){U=!0,clearInterval(R),await new Promise(w=>setImmediate(w)),console.log=c,process.stdout.write=d;let g=`${a.join(`
|
|
13
13
|
`)}
|
|
14
14
|
|
|
15
|
-
Error: ${
|
|
16
|
-
`)){let
|
|
17
|
-
`)){let
|
|
18
|
-
`)
|
|
19
|
-
`);
|
|
20
|
-
`);
|
|
21
|
-
`)}))},
|
|
22
|
-
`);if(
|
|
15
|
+
Error: ${h.message}`;throw await e(n,"failed",g,i),h}}}import{existsSync as zt,readFileSync as Bt}from"fs";var Wt="/tmp/zibby-entrypoint-setup.log",Ht=500;function B(e){return e.replace(/\r/g,"").trimEnd()}function ze({reportProgressFn:e,state:t,entrypointLogPath:r=Wt}={}){if(!t||!t.EXECUTION_ID)return{finalize:async()=>{},getBuffer:()=>""};let o=[],n=0,s=!1;try{if(zt(r)){let g=Bt(r,"utf-8");for(let w of g.split(`
|
|
16
|
+
`)){let E=B(w);E&&o.push(E)}}}catch{}let i=console.log,f=console.warn,a=console.error,l=process.stdout.write.bind(process.stdout),c=process.stderr.write.bind(process.stderr),d=!1,u=g=>(...w)=>{let E=w.map(m=>typeof m=="string"?m:(()=>{try{return JSON.stringify(m)}catch{return String(m)}})()).join(" ");for(let m of E.split(`
|
|
17
|
+
`)){let I=B(m);I&&o.push(I)}d=!0;try{g(...w)}finally{d=!1}};console.log=u(i),console.warn=u(f),console.error=u(a);let $="",y="";process.stdout.write=(g,w,E)=>{if(!d){let m=typeof g=="string"?g:g.toString();$+=m;let I=$.split(`
|
|
18
|
+
`);$=I.pop()||"";for(let D of I){let L=B(D);L&&o.push(L)}}return l(g,w,E)},process.stderr.write=(g,w,E)=>{if(!d){let m=typeof g=="string"?g:g.toString();y+=m;let I=y.split(`
|
|
19
|
+
`);y=I.pop()||"";for(let D of I){let L=B(D);L&&o.push(L)}}return c(g,w,E)};let R=setInterval(()=>{if(s)return;let g=o.join(`
|
|
20
|
+
`);g.length!==n&&(n=g.length,e("setup","in_progress",g,t).catch(w=>{c(`[setup-progress] flush failed: ${w.message}
|
|
21
|
+
`)}))},Ht);return R.unref&&R.unref(),{finalize:async()=>{if(s)return;s=!0,clearInterval(R),console.log=i,console.warn=f,console.error=a,process.stdout.write=l,process.stderr.write=c,$.trim()&&(o.push(B($)),$=""),y.trim()&&(o.push(B(y)),y="");let g=o.join(`
|
|
22
|
+
`);if(g.length>0)try{await e("setup","in_progress",g,t)}catch(w){c(`[setup-progress] final flush failed: ${w.message}
|
|
23
23
|
`)}},getBuffer:()=>o.join(`
|
|
24
|
-
`)}}function
|
|
25
|
-
`)}import{existsSync as
|
|
24
|
+
`)}}function Be({workflowType:e,jobId:t,projectId:r,agentType:o,model:n,egressIp:s,egressKind:i}){let f="\u2500".repeat(60),a=`${o||"default"} (model: ${n||"auto"})`,l=["",f,` Workflow: ${e}`,` Job: ${t||"local"}`,` Project: ${r||"none"}`,` Agent: ${a}`];if(s||i){let c=s||"unknown",d=i||"static";l.push(` Egress: ${c} (${d})`)}return l.push(f),l.join(`
|
|
25
|
+
`)}import{existsSync as Jt,writeFileSync as Mt}from"fs";import{join as We}from"path";var me={width:1280,height:720},Qt="on",Yt="tests",qt="test-results/playwright";function Vt(e={}){let t=e.viewport&&typeof e.viewport=="object"?{width:Number(e.viewport.width)||me.width,height:Number(e.viewport.height)||me.height}:me,r=typeof e.video=="string"?e.video:Qt,o=e.paths?.generated||Yt,n=e.playwrightArtifacts!==!1,s=n?"on":"off",i=n?"only-on-failure":"off";return`// AUTO-GENERATED at workflow run start by @zibby/cli's
|
|
26
26
|
// playwright-config-materialize.js. Derived from the bundled
|
|
27
27
|
// zibby.config.json (which @zibby/workflow-deploy serialized from your
|
|
28
28
|
// project's .zibby.config.mjs). Do NOT edit by hand \u2014 re-run a workflow
|
|
@@ -33,7 +33,7 @@ import { defineConfig } from '@playwright/test';
|
|
|
33
33
|
|
|
34
34
|
export default defineConfig({
|
|
35
35
|
testDir: '${o.replace(/'/g,"\\'")}',
|
|
36
|
-
outputDir: '${
|
|
36
|
+
outputDir: '${qt}',
|
|
37
37
|
timeout: 60000,
|
|
38
38
|
retries: 0,
|
|
39
39
|
workers: 1,
|
|
@@ -48,8 +48,8 @@ export default defineConfig({
|
|
|
48
48
|
|
|
49
49
|
reporter: [['list']],
|
|
50
50
|
});
|
|
51
|
-
`}function
|
|
52
|
-
`);ee=
|
|
53
|
-
Workflow execution failed: ${
|
|
54
|
-
[done] ${
|
|
55
|
-
[done] ${
|
|
51
|
+
`}function He(e,t){if(!e)return{written:!1,path:null,reason:"no workspaceDir"};for(let n of["js","mjs","ts"]){let s=We(e,`playwright.config.${n}`);if(Jt(s))return{written:!1,path:s,reason:`existing playwright.config.${n} in workspace`}}let r=We(e,"playwright.config.js"),o=Vt(t||{});try{return Mt(r,o,"utf-8"),{written:!0,path:r,reason:"derived from zibby.config"}}catch(n){return{written:!1,path:null,reason:`write failed: ${n.message}`}}}import"@zibby/core";var V=process.env.WORKSPACE||"/workspace";async function Ar(e,t){At(t,{recursive:!0});let r=Date.now();console.log("[setup] Fetching bundle...");let o=setInterval(()=>{let s=((Date.now()-r)/1e3).toFixed(1);console.log(`[setup] still fetching (${s}s elapsed)`)},3e3);try{await new Promise((s,i)=>{let f=Ie("curl",["-fsSL",e],{stdio:["ignore","pipe","inherit"]}),a=Ie("tar",["-xzf","-","-C",t],{stdio:["pipe","inherit","inherit"]});f.stdout.pipe(a.stdin);let l,c,d=()=>{if(l!==void 0&&c!==void 0){if(l!==0)return i(new Error(`curl exited ${l}`));if(c!==0)return i(new Error(`tar exited ${c}`));s()}};f.on("close",u=>{l=u,d()}),a.on("close",u=>{c=u,d()}),f.on("error",i),a.on("error",i)})}finally{clearInterval(o)}let n=((Date.now()-r)/1e3).toFixed(1);return console.log(`[setup] Bundle extracted (${n}s)`),t}async function Pt(){let e=process.env.WORKFLOW_SOURCES_URL;if(!e)throw new Error("WORKFLOW_SOURCES_URL env var is required");let t=await fetch(e);if(!t.ok)throw new Error(`Failed to fetch sources: ${t.status} ${t.statusText}`);let r=await t.json();if(!r.sources||typeof r.sources!="object")throw new Error('Invalid sources payload \u2014 missing "sources" map');return r}function vr(e){let t=e?.agent;if(!t)return null;if(typeof t=="string")return t;if(typeof t=="object"){if(typeof t.provider=="string")return t.provider;for(let r of["claude","cursor","codex","gemini"])if(t[r])return r}return null}function br(e,t){let r=Tt(t),o=0;for(let[n,s]of Object.entries(e)){let i=Tt(t,n);if(!i.startsWith(`${r}/`)&&i!==r){console.error(` \u26D4 Skipping unsafe path: ${n}`);continue}At(Pr(i),{recursive:!0}),Tr(i,s,"utf-8"),o++}return o}async function Dr(){let e=process.env.ZIBBY_EGRESS_PROXY_URL,t=process.env.ZIBBY_EGRESS_TOKEN;if(!(!e||!t))try{let r=await import("undici"),o=new r.ProxyAgent({uri:e,token:`Bearer ${t}`});r.setGlobalDispatcher(o)}catch(r){console.warn(`[setup] Failed to install egress proxy dispatcher: ${r.message}`)}}async function Lr(){if(process.env.ZIBBY_EGRESS_IP)return{ip:process.env.ZIBBY_EGRESS_IP,kind:"static"};try{let e=new AbortController,t=setTimeout(()=>e.abort(),1500),r=await fetch("https://api.ipify.org?format=json",{signal:e.signal});return clearTimeout(t),r.ok?{ip:(await r.json())?.ip||null,kind:"dynamic"}:{ip:null,kind:"dynamic"}}catch{return{ip:null,kind:"dynamic"}}}async function Cr(e,t){let r=b(e,"graph.mjs");if(!G(r))throw new Error(`graph.mjs not found at ${r}`);let o=await import(Ue(r).href),n=t?.entryClass,s=n&&o[n]||o.default||Object.values(o).find(i=>typeof i=="function"&&i.prototype?.buildGraph);if(!s)throw new Error("No WorkflowAgent class found in graph.mjs");return s}async function mn(){if(!process.env.NODE_PATH){process.env.NODE_PATH="/opt/zibby/packages";let p=await import("module");p.default._initPaths&&p.default._initPaths()}let e={EXECUTION_ID:process.env.EXECUTION_ID||process.env.WORKFLOW_JOB_ID||"",PROGRESS_API_URL:process.env.PROGRESS_API_URL||"",PROGRESS_QUEUE_URL:process.env.PROGRESS_QUEUE_URL||"",SQS_AUTH_TOKEN:process.env.SQS_AUTH_TOKEN||"",PROJECT_API_TOKEN:process.env.PROJECT_API_TOKEN||""},t=ze({reportProgressFn:de,state:e});await Dr();let{WORKFLOW_JOB_ID:r,WORKFLOW_TYPE:o,PROJECT_ID:n,AGENT_TYPE:s,MODEL:i}=process.env;o||(console.error("Missing WORKFLOW_TYPE env var"),process.exit(1));let f=process.env.WORKFLOW_BUNDLE_URL,a,l={},c,d,u={};if(f){c=o,a=b(V,".zibby","workflows",c);try{await Ar(f,a);try{let p=await Pt();l=p.input||{},d=p.version,p.nodeConfigs&&typeof p.nodeConfigs=="object"&&(u=p.nodeConfigs)}catch{}}catch(p){console.warn(`[setup] Bundle extract failed (${p.message}); falling back to source install`),a=null}}if(!a){let p=await Pt(),{sources:x,input:T,workflowType:A,version:P}=p;l=T||{},c=A||o,d=P,p.nodeConfigs&&typeof p.nodeConfigs=="object"&&(u=p.nodeConfigs),console.log(`[setup] Workflow v${d||"?"} (${Object.keys(x).length} files)`),a=b(V,".zibby","workflows",c);let C=br(x,a);console.log(`[setup] Wrote ${C} files`),console.log("[setup] Installing dependencies...");let v=Date.now();try{await new Promise((Ct,be)=>{let Z=Ie("npm",["install","--silent","--no-audit","--no-fund"],{cwd:a,stdio:["ignore","pipe","pipe"]}),De=(k,Le)=>{let ee="";k.on("data",te=>{ee+=te.toString();let Ce=ee.split(`
|
|
52
|
+
`);ee=Ce.pop()||"";for(let kt of Ce){let ke=kt.replace(/\r/g,"").trimEnd();ke&&Le(ke)}}),k.on("end",()=>{let te=ee.replace(/\r/g,"").trimEnd();te&&Le(te)})};De(Z.stdout,k=>console.log(`[npm] ${k}`)),De(Z.stderr,k=>console.warn(`[npm] ${k}`)),Z.on("error",be),Z.on("close",k=>{k===0?Ct():be(new Error(`npm install exited with code ${k}`))})});let H=((Date.now()-v)/1e3).toFixed(1);console.log(`[setup] Dependencies installed (${H}s)`)}catch(H){console.warn(`[setup] npm install failed: ${H.message}`)}}let $={},y=b(a,"workflow.json");G(y)&&($=JSON.parse(It(y,"utf-8")));let U={},R=b(a,"zibby.config.json");if(G(R))try{U=JSON.parse(It(R,"utf-8")),console.log("[setup] Loaded user config from zibby.config.json")}catch(p){console.warn(`[setup] Failed to parse zibby.config.json: ${p.message} \u2014 falling back to defaults`)}let h=He(V,U);h.written?console.log(`[setup] Materialized playwright.config.js \u2192 ${h.path} (${h.reason})`):h.path&&console.log(`[setup] Using existing playwright config: ${h.path}`);let g=vr(U)||s,w=await Lr();console.log(Be({workflowType:o,jobId:r,projectId:n,agentType:g,model:i,egressIp:w.ip,egressKind:w.kind}));let E=await Cr(a,$);console.log(`[setup] Loaded ${E.name}`);let m=[],I=b(a,"node_modules","@zibby","agent-workflow"),D=b(a,"node_modules","@zibby","core","node_modules","@zibby","agent-workflow");G(I)&&m.push({kind:"hoisted",path:I}),G(D)&&m.push({kind:"nested",path:D});let L=process.env.ZIBBY_RUN_DIAG==="1";if(L){let{readdirSync:p}=await import("fs");console.log(` [diag] @zibby/agent-workflow copies in bundle: ${m.length}`);for(let x of m)console.log(` [diag] ${x.kind}: ${x.path}`);try{let x=b(a,"node_modules","@zibby");G(x)&&console.log(` [diag] node_modules/@zibby/ contents: [${p(x).join(", ")}]`)}catch{}}let Te=b(a,"node_modules","@zibby","core","dist","index.js");if(G(Te)&&m.length>0)try{let p=await import(Ue(Te).href),x=[p.AssistantStrategy,p.CursorAgentStrategy,p.ClaudeAgentStrategy,p.CodexAgentStrategy,p.GeminiAgentStrategy].filter(Boolean);for(let T of m){let A=b(T.path,"dist","index.js");if(!G(A))continue;let P=await import(Ue(A).href),C=L?P.listStrategies():null;for(let v of x)try{P.registerStrategy(new v)}catch(H){console.warn(` register ${v.name} into ${T.kind} failed: ${H.message}`)}L&&console.log(` [diag] ${T.kind} registry: before=[${C.join(",")||"empty"}] after=[${P.listStrategies().join(",")||"empty"}]`)}console.log("[setup] Registered 5 agent strategies (assistant, cursor, claude, codex, gemini)")}catch(p){console.warn(`[setup] Failed to bridge strategies: ${p.message}`)}else console.warn("[setup] No @zibby/core or @zibby/agent-workflow in bundle \u2014 agent strategies may be unavailable");let vt=Date.now(),Pe=new E({workflow:c||o}),ce=Pe.buildGraph(),bt=Ge(de,Ke);Array.isArray(ce.middleware)?ce.middleware.push(bt):console.warn("[run] graph.middleware not an array \u2014 per-node progress reporting disabled for this run");let W=process.env.WORKFLOW_UUID||null,X=process.env.ZIBBY_CONVERSATION_ID||null,le=!1;if(W&&X)try{let{v5:p}=await Promise.resolve().then(()=>(xt(),yt)),x=p(`${W}:${X}`,"6ba7b810-9dad-11d1-80b4-00c04fd430c8"),T=(process.env.PROGRESS_API_URL||process.env.ZIBBY_API_BASE||"").replace(/\/executions\/?$/,"").replace(/\/+$/,""),A=process.env.PROJECT_API_TOKEN;if(process.env.ZIBBY_SDK_DEBUG==="1"&&console.log(`[session-preflight] sessionId=${x} apiUrl=${T?"set":"unset"} apiKey=${A?"set":"unset"}`),T&&A){let P=`${T}/workflows/${encodeURIComponent(W)}/sessions/${encodeURIComponent(x)}`,C=await fetch(P,{method:"GET",headers:{Authorization:`Bearer ${A}`}});if(process.env.ZIBBY_SDK_DEBUG==="1"&&console.log(`[session-preflight] GET ${P} \u2192 HTTP ${C.status}`),C.ok){let v=await C.json().catch(()=>({}));le=Array.isArray(v?.entries)&&v.entries.length>0,process.env.ZIBBY_SDK_DEBUG==="1"&&console.log(`[session-preflight] hasPriorSession=${le} entries=${v?.entries?.length??"n/a"}`)}}}catch(p){process.env.ZIBBY_SDK_DEBUG==="1"&&console.log(`[session-preflight] threw: ${p.message}`)}let fe=null;try{process.env.REPOS&&(fe=JSON.parse(process.env.REPOS))}catch{}let Dt={...l||{},cwd:V,runId:r||`run-${Date.now()}`,config:U,input:l||{},...u&&Object.keys(u).length>0?{nodeConfigs:u}:{},...W?{workflowUuid:W}:{},...X?{conversationId:X}:{},...le?{hasPriorSession:!0}:{},workspace:V,...fe?{repos:fe}:{},...process.env.GITHUB_TOKEN?{githubToken:process.env.GITHUB_TOKEN}:{},EXECUTION_ID:process.env.EXECUTION_ID||r||"",PROGRESS_API_URL:process.env.PROGRESS_API_URL||"",PROGRESS_QUEUE_URL:process.env.PROGRESS_QUEUE_URL||"",SQS_AUTH_TOKEN:process.env.SQS_AUTH_TOKEN||"",PROJECT_API_TOKEN:process.env.PROJECT_API_TOKEN||""};await t.finalize(),console.log("");let z;try{z=await ce.run(Pe,Dt)}catch(p){console.error(`
|
|
53
|
+
Workflow execution failed: ${p.message}`),console.error(p.stack),await Oe("failed",p.message),process.exit(1)}let Ae=((Date.now()-vt)/1e3).toFixed(1),Lt=z?.success!==!1,ve=c||o;if(process.env.UPLOAD_ARTIFACTS!=="0"){let p=z?.state?.sessionPath,x=process.env.PROGRESS_API_URL||process.env.ZIBBY_API_BASE,T=process.env.PROJECT_API_TOKEN,A=process.env.WORKFLOW_JOB_ID;if(p&&x&&T&&A)try{let{uploadSessionArtifacts:P}=await Promise.resolve().then(()=>(Ut(),Ot)),{uploaded:C,skipped:v}=await P({sessionPath:p,executionId:A,apiUrl:x,apiKey:T});console.log(`[artifacts] uploaded ${C.length} file(s)${v.length?`, skipped ${v.length}`:""}`)}catch(P){console.warn(`[artifacts] uploader threw: ${P.message}`)}else console.log("[artifacts] skipping upload \u2014 sessionPath/apiUrl/apiKey/executionId missing")}Lt?(console.log(`
|
|
54
|
+
[done] ${ve} completed in ${Ae}s`),await Oe("completed",null,z?.state)):(console.error(`
|
|
55
|
+
[done] ${ve} failed after ${Ae}s`),await Oe("failed",z?.error||"Workflow execution failed",z?.state),process.exit(1))}async function Oe(e,t=null,r=void 0){let o={EXECUTION_ID:process.env.WORKFLOW_JOB_ID,PROGRESS_API_URL:process.env.PROGRESS_API_URL,PROGRESS_QUEUE_URL:process.env.PROGRESS_QUEUE_URL,PROJECT_API_TOKEN:process.env.PROJECT_API_TOKEN,SQS_AUTH_TOKEN:process.env.SQS_AUTH_TOKEN};if(o.EXECUTION_ID)try{await Fe(o,{status:e,...t&&{error:t},...r?{finalState:r}:{}})}catch(n){console.error(`\u26A0\uFE0F Failed to report status: ${n.message}`)}}export{vr as resolveAgentFromConfig,mn as runWorkflowCommand};
|
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
var
|
|
1
|
+
var ee=Object.defineProperty;var z=(o,e)=>()=>(o&&(e=o(o=0)),e);var oe=(o,e)=>{for(var t in e)ee(o,t,{get:e[t],enumerable:!0})};function v(){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}}var j,A=z(()=>{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://api-prod.zibby.app",frontendUrl:process.env.ZIBBY_PROD_FRONTEND_URL||"https://studio.zibby.dev",description:"Production environment"}}});var H={};oe(H,{logsCommand:()=>Ie,parseSseChunk:()=>W,runReconnectLoop:()=>V,sseBackoffMs:()=>G});import i from"chalk";import{readFileSync as ae,existsSync as ce,writeSync as B}from"fs";import{homedir as le}from"os";import{join as fe}from"path";async function ue(o){return _||(process.env.ZIBBY_SSE_ENDPOINT?(_=process.env.ZIBBY_SSE_ENDPOINT,_):(_=pe,_))}function de(o){let e=fe(le(),".zibby","config.json");ce(e)||(console.log(i.red(`
|
|
2
2
|
Not authenticated`)),console.log(i.gray(` Run: zibby login
|
|
3
|
-
`)),process.exit(1));let t;try{t=JSON.parse(
|
|
3
|
+
`)),process.exit(1));let t;try{t=JSON.parse(ae(e,"utf-8"))}catch{console.log(i.red(`
|
|
4
4
|
Config file corrupt`)),console.log(i.gray(` Run: zibby login
|
|
5
5
|
`)),process.exit(1)}let n=t.sessionToken;n||(console.log(i.red(`
|
|
6
6
|
Not authenticated`)),console.log(i.gray(` Run: zibby login
|
|
7
|
-
`)),process.exit(1));let s=o.project;return{token:n,projectId:s}}function
|
|
7
|
+
`)),process.exit(1));let s=o.project;return{token:n,projectId:s}}function L(o){let e=new Date(o);if(process.env.ZIBBY_LOGS_UTC==="1")return e.toISOString().replace("T"," ").replace("Z","");let t=(n,s=2)=>String(n).padStart(s,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}.${t(e.getMilliseconds(),3)}`}async function J(o,e){let t=await fetch(o,{headers:{Authorization:`Bearer ${e}`}});if(!t.ok){let n=await t.text();throw new Error(`API ${t.status}: ${n}`)}return t.json()}async function ge(o,e,t,n){return o||(console.log(i.red(`
|
|
8
8
|
Workflow UUID is required`)),console.log(i.gray(" Usage: zibby workflow logs <workflow-uuid>")),console.log(i.gray(` zibby workflow logs <workflow-uuid> -t
|
|
9
|
-
`)),process.exit(1)),o}function
|
|
10
|
-
`),s=n.pop()||"",
|
|
9
|
+
`)),process.exit(1)),o}function W(o,e){let n=((o||"")+e).split(`
|
|
10
|
+
`),s=n.pop()||"",a=[],c=null,l=null;for(let r=0;r<n.length;r++){let f=n[r];if(f.trim()){if(f.startsWith("id:")){c=f.slice(3).trim();continue}if(f.startsWith("event:")){let u=f.slice(6).trim();if(u==="log")continue;if(u==="status"){let p=n[r+1];if(p&&p.startsWith("data:"))try{let g=JSON.parse(p.slice(5).trim());g.status==="new_execution"?a.push({type:"newExecution",executionId:g.executionId,taskId:g.taskId}):g.status==="waiting"&&a.push({type:"waiting"})}catch{}continue}if(u==="complete"){a.push({type:"complete"});continue}if(u==="error"){let p=n[r+1];if(p&&p.startsWith("data:"))try{if(JSON.parse(p.slice(5).trim()).error==="No executions found for workflow"){l={type:"notFound"};break}}catch{}l={type:"failed"};break}continue}if(f.startsWith("data:")){let u=f.slice(5).trim();if(!u)continue;try{let p=JSON.parse(u);p.timestamp&&p.message&&a.push({type:"log",timestamp:p.timestamp,message:p.message,taskId:p.taskId})}catch{}}}}return{actions:a,remainder:s,lastEventId:c,returnSignal:l}}async function me({token:o,executionId:e,sseEndpoint:t,stopped:n}){let s=null;try{let h=function(){let $=Array.from(y.entries()).slice(0,p);y.clear();for(let[I,w]of $)y.set(I,w);d=new Set(Array.from(y.values()).map(I=>I.taskId).filter(Boolean));for(let I of[...m.keys()])y.has(I)||m.delete(I)},S=function(b){for(let[$,I]of y)if(I.taskId===b)return $;return null},T=function(b){let $=y.get(b);!$||$.headerPrinted||(console.log(i.cyan(`
|
|
11
11
|
\u250C\u2500 Execution: ${$.shortId} (task: ${$.taskSuffix})`)),console.log(i.cyan(` \u2514\u2500 Streaming logs...
|
|
12
|
-
`)),$.headerPrinted=!0)},
|
|
13
|
-
Waiting for next execution...`));break;case"complete":R(),
|
|
12
|
+
`)),$.headerPrinted=!0)},U=function(b){let $=i.gray(L(b.timestamp)),I=b.taskId?i.gray(`(${b.taskId.slice(-8)}) `):"";console.log(`${$} ${I}${b.message.replace(/\n$/,"")}`)},R=function(){if(!k)return;k=!1,x&&(clearTimeout(x),x=null);let b=Array.from(y.entries()).reverse();for(let[$]of b){let I=m.get($);if(!(!I||I.length===0)){T($);for(let w of I)U(w)}}m.clear()},P=function(){k&&(x&&clearTimeout(x),x=setTimeout(R,g))},a=new URL(t);a.searchParams.set("jobId",e),s&&a.searchParams.set("lastEventId",s);let c=await fetch(a.toString(),{headers:{Authorization:`Bearer ${o}`,Accept:"text/event-stream"}});if(!c.ok)throw new Error(`SSE connection failed: ${c.status} ${c.statusText}`);let l=c.body.getReader(),r=new TextDecoder,f="",u=!1,p=Number(process.env.ZIBBY_LOGS_HISTORY_LIMIT)||10,g=Number(process.env.ZIBBY_LOGS_REPLAY_TIMEOUT_MS)||3e3,y=new Map,d=new Set,m=new Map,k=!0,x=null;for(P();!n.value;){let{done:b,value:$}=await l.read();if(b)break;let I=W(f,r.decode($,{stream:!0}));f=I.remainder,I.lastEventId&&(s=I.lastEventId);for(let w of I.actions)switch(w.type){case"newExecution":{let E=`${w.executionId.slice(0,8)}...${w.executionId.slice(-4)}`,N=w.taskId?w.taskId.slice(-8):"pending";y.set(w.executionId,{shortId:E,taskSuffix:N,taskId:w.taskId||null,headerPrinted:!1}),m.has(w.executionId)||m.set(w.executionId,[]),h(),P();break}case"waiting":R(),console.log(i.gray(`
|
|
13
|
+
Waiting for next execution...`));break;case"complete":R(),u=!0;break;case"log":{if(w.taskId&&d.size>0&&!d.has(w.taskId))break;if(k){let E=w.taskId?S(w.taskId):null;if(E){let N=m.get(E)||[];N.push(w),m.set(E,N),P()}else U(w)}else{if(w.taskId){let E=S(w.taskId);E&&T(E)}U(w)}break}}if(I.returnSignal)return I.returnSignal.type==="notFound"?{notFound:!0}:{failed:!0}}return R(),{completed:u}}catch(a){if(a.name==="AbortError")return{aborted:!0};throw a}}function G(o,{baseMs:e=500,capMs:t=3e4,rand:n=Math.random}={}){let s=Math.min(t,e*Math.pow(2,Math.max(0,o)));return Math.floor(n()*s)}async function V({attemptStream:o,stopped:e,follow:t,logger:n,sleep:s=r=>new Promise(f=>setTimeout(f,r)),exit:a=r=>{throw new Error(`exit:${r}`)},backoff:c=G,notFoundPollMs:l=5e3}){let r=0,f=!1;for(;!e.value;){let u;try{u=await o(),r=0}catch(p){if(p.name==="AbortError"||e.value)return{reason:"aborted"};if(f||(n.error(` SSE Error: ${p.message}`),t&&n.gray(" Reconnecting..."),f=!0),!t)return a("error")??{reason:"error"};let g=c(r);r++,await s(g);continue}if(u.aborted||e.value)return{reason:"aborted"};if(u.notFound){if(t){f||(n.yellow(" No executions found yet. Waiting for workflow to be triggered..."),n.gray(" Press Ctrl+C to stop."),f=!0),await s(l);continue}return n.yellow(`
|
|
14
14
|
No executions found for this workflow. Trigger the workflow first.
|
|
15
|
-
`),
|
|
16
|
-
`),f=!1),
|
|
17
|
-
Execution failed.`),t?{reason:"failed"}:
|
|
18
|
-
`):"");let
|
|
19
|
-
`)),
|
|
15
|
+
`),a("notFound")??{reason:"notFound"}}if(f&&(n.gray(` Reconnected.
|
|
16
|
+
`),f=!1),u.failed)return n.red(`
|
|
17
|
+
Execution failed.`),t?{reason:"failed"}:a("failed")??{reason:"failed"};if(u.completed)return a("completed")??{reason:"completed"};if(!t)return{reason:"disconnected"}}return{reason:"stopped"}}async function K(o){if(process.env.ZIBBY_SSE_NO_WAKE==="1")return{state:"unknown"};try{let e=v().replace(/\/$/,""),t=await fetch(`${e}/logs/wake`,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"}});if(!t.ok)return{state:"unknown"};let n=await t.json().catch(()=>({}));return n&&(n.state==="ready"||n.state==="warming")?{state:n.state}:{state:"unknown"}}catch{return{state:"unknown"}}}async function ye(o,{timeoutMs:e=9e4,pollMs:t=3e3}={}){let n=Date.now(),s=0,a=process.stderr.isTTY,c=()=>{if(!a)return;let f=Math.round((Date.now()-n)/1e3),u=Z[s++%Z.length];try{B(2,`\r ${i.cyan(u)} Starting log stream\u2026 (~60s on first connect) ${i.gray(`${f}s`)} `)}catch{}},l=()=>{if(a)try{B(2,`\r${" ".repeat(64)}\r`)}catch{}};a||console.log(i.gray(" Starting log stream\u2026 (~60s on first connect)"));let r=a?setInterval(c,120):null;try{for(;Date.now()-n<e;){let{state:f}=await K(o);if(f==="ready")break;await new Promise(u=>setTimeout(u,t))}}finally{r&&clearInterval(r),l()}}async function we({token:o,jobId:e,follow:t,projectId:n}){(await K(o)).state==="warming"&&await ye(o),console.log(i.gray(` Streaming logs for workflow ${i.cyan(e)}...`)),console.log(t?i.gray(` Press Ctrl+C to stop.
|
|
18
|
+
`):"");let a=await ue(o);if(!a)return console.log(i.yellow(` SSE endpoint not configured, using CloudWatch polling...
|
|
19
|
+
`)),q({token:o,projectId:null,jobId:e,follow:t,limit:1e5});let c={value:!1},l=()=>{c.value=!0;try{B(2,`
|
|
20
20
|
Stopped streaming.
|
|
21
|
-
`)}catch{}process.exit(0)};process.prependListener("SIGINT",
|
|
21
|
+
`)}catch{}process.exit(0)};process.prependListener("SIGINT",l),process.prependListener("SIGTERM",l),await V({attemptStream:()=>me({token:o,executionId:e,sseEndpoint:a,stopped:c}),stopped:c,follow:t,logger:{gray:r=>console.log(i.gray(r)),red:r=>console.log(i.red(r)),yellow:r=>console.log(i.yellow(r)),error:r=>console.error(i.red(r))},exit:r=>{r==="completed"&&process.exit(0),(r==="error"||r==="notFound"||r==="failed")&&process.exit(1)}})}async function q({token:o,projectId:e,jobId:t,follow:n,limit:s}){let a=e?`${C}/logs/${e}/${t}`:`${C}/job/${t}`,c=null,l=0,r=new Set,f=!1,u=0,p=5,g=()=>{f=!0,console.log(i.gray(`
|
|
22
22
|
Stopped tailing.
|
|
23
23
|
`)),process.exit(0)};for(process.on("SIGINT",g),process.on("SIGTERM",g),console.log(i.gray(` Fetching logs for workflow ${i.cyan(t)}...`)),console.log(n?i.gray(` Press Ctrl+C to stop.
|
|
24
|
-
`):"");!f;)try{let y=new URLSearchParams({limit:String(s)});
|
|
25
|
-
Job ${
|
|
26
|
-
Status: ${
|
|
24
|
+
`):"");!f;)try{let y=new URLSearchParams({limit:String(s)});c&&y.set("nextToken",c);let d=await J(`${a}?${y}`,o);u=0,d.message&&d.lines?.length===0&&l===0&&console.log(i.gray(` ${d.message}`)),d.status==="starting"&&d.lines?.length===0&&l===0&&console.log(i.gray(" Container starting..."));for(let h of d.lines||[]){let S=`${h.timestamp}:${h.message}`;if(r.has(S))continue;r.add(S);let T=i.gray(L(h.timestamp)),U=d.taskId?i.gray(`(${d.taskId.slice(-8)}) `):"";console.log(`${T} ${U}${h.message.replace(/\n$/,"")}`)}if(l=d.lines?.length>0?0:l+1,c=d.nextForwardToken||null,d.status==="completed"||d.status==="failed"){let h=d.status==="completed"?i.green:i.red;console.log(h(`
|
|
25
|
+
Job ${d.status}.`)),process.exit(d.status==="completed"?0:1)}if(!n){d.status&&console.log(i.gray(`
|
|
26
|
+
Status: ${d.status}`));break}let x=d.lines?.length>0?500:l>5?5e3:2e3;await new Promise(h=>setTimeout(h,x))}catch(y){if(y.name==="AbortError")break;y.message.match(/API (400|401|403|404):/)&&(console.error(i.red(`
|
|
27
27
|
${y.message}
|
|
28
|
-
`)),process.exit(1)),
|
|
28
|
+
`)),process.exit(1)),u++,console.error(i.red(` Error: ${y.message}`)),u>=p&&(console.error(i.red(`
|
|
29
29
|
Too many consecutive errors (${p}). Stopping.
|
|
30
|
-
`)),process.exit(1)),n||process.exit(1),await new Promise(m=>setTimeout(m,3e3))}}async function
|
|
30
|
+
`)),process.exit(1)),n||process.exit(1),await new Promise(m=>setTimeout(m,3e3))}}async function he({token:o,projectId:e,workflow:t,follow:n,limit:s}){let a=`${C}/all/${e}`,c=null,l=0,r=new Set,f=null,u=!1,p=0,g=5,y=()=>{u=!0,console.log(i.gray(`
|
|
31
31
|
Stopped tailing.
|
|
32
32
|
`)),process.exit(0)};for(process.on("SIGINT",y),process.on("SIGTERM",y),console.log(i.gray(`
|
|
33
33
|
Tailing all runs for ${i.cyan(t)}...`)),console.log(n?i.gray(` Press Ctrl+C to stop.
|
|
34
|
-
`):"");!
|
|
35
|
-
... more logs available. Run again or use --follow to stream.`)),m.jobCount&&console.log(i.gray(` ${m.jobCount} job(s) found.`));break}if(!m.hasRunning&&!
|
|
36
|
-
No running jobs. All caught up.`));break}let x=m.lines?.length>0?500:
|
|
37
|
-
${
|
|
38
|
-
`)),process.exit(1)),p++,console.error(i.red(` Error: ${
|
|
34
|
+
`):"");!u;)try{let d=new URLSearchParams({workflow:t,limit:String(s)});c&&d.set("nextToken",c);let m=await J(`${a}?${d}`,o);p=0,m.message&&m.lines?.length===0&&l===0&&console.log(i.gray(` ${m.message}`));for(let h of m.lines||[]){let S=`${h.timestamp}:${h.jobId}:${h.message}`;if(r.has(S))continue;r.add(S),h.jobId!==f&&(f!==null&&console.log(""),console.log(i.dim(` \u2500\u2500 ${h.jobId} \u2500\u2500`)),f=h.jobId);let T=i.gray(L(h.timestamp));console.log(`${T} ${h.message.replace(/\n$/,"")}`)}if(l=m.lines?.length>0?0:l+1,c=m.nextToken||null,!n){c&&console.log(i.gray(`
|
|
35
|
+
... more logs available. Run again or use --follow to stream.`)),m.jobCount&&console.log(i.gray(` ${m.jobCount} job(s) found.`));break}if(!m.hasRunning&&!c&&l>2){console.log(i.gray(`
|
|
36
|
+
No running jobs. All caught up.`));break}let x=m.lines?.length>0?500:l>5?5e3:2e3;await new Promise(h=>setTimeout(h,x))}catch(d){if(d.name==="AbortError")break;d.message.match(/API (400|401|403|404):/)&&(console.error(i.red(`
|
|
37
|
+
${d.message}
|
|
38
|
+
`)),process.exit(1)),p++,console.error(i.red(` Error: ${d.message}`)),p>=g&&(console.error(i.red(`
|
|
39
39
|
Too many consecutive errors (${g}). Stopping.
|
|
40
|
-
`)),process.exit(1)),n||process.exit(1),await new Promise(k=>setTimeout(k,3e3))}}async function
|
|
40
|
+
`)),process.exit(1)),n||process.exit(1),await new Promise(k=>setTimeout(k,3e3))}}async function Ie(o,e){let{token:t,projectId:n}=de(e),s=e.follow===!0,a=e.lines?parseInt(e.lines,10):1e5;if(e.all){let l=e.workflow;return l||(console.log(i.red(`
|
|
41
41
|
--workflow is required with --all`)),console.log(i.gray(` Example: zibby workflow logs --workflow ticket-triage --all --project <id>
|
|
42
|
-
`)),process.exit(1)),
|
|
42
|
+
`)),process.exit(1)),he({token:t,projectId:n,workflow:l,follow:s,limit:a})}let c=await ge(o,e,t,n);return s?we({token:t,jobId:c,follow:s,projectId:n}):q({token:t,projectId:n,jobId:c,follow:!1,limit:a})}var C,pe,_,Z,X=z(()=>{A();C="https://logs.workflows.zibby.app",pe="https://logs-stream.zibby.app/",_=null;Z=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"]});A();import O from"ora";import{select as Q}from"@inquirer/prompts";import{readFileSync as $e,existsSync as be}from"fs";import{homedir as ke}from"os";import{join as xe}from"path";var te=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function D(o){return o?te.test(o)?{ok:!0}:{ok:!1,error:`'${o}' is not a UUID. Cloud workflows are identified by UUID only. Run \`zibby workflow list\` to find yours, or run \`zibby workflow trigger\` with no argument for interactive selection.`}:{ok:!0}}import{existsSync as ne,readFileSync as re}from"fs";import{resolve as se}from"path";function F(o){return o==="true"?!0:o==="false"?!1:o==="null"?null:o!==""&&!isNaN(Number(o))?Number(o):o}function Y(o){let e={};for(let t of o||[]){let n=t.indexOf("=");if(n===-1){console.warn(` Warning: ignored param "${t}" \u2014 expected key=value format`);continue}let s=t.slice(0,n).trim(),a=F(t.slice(n+1)),c=s.split("."),l=e;for(let r=0;r<c.length-1;r++)(typeof l[c[r]]!="object"||l[c[r]]===null)&&(l[c[r]]={}),l=l[c[r]];l[c[c.length-1]]=a}return e}function ie(o){let e=se(o);ne(e)||(console.log(`
|
|
43
43
|
Error: --input-file not found: ${o}
|
|
44
|
-
`),process.exit(1));try{return JSON.parse(
|
|
44
|
+
`),process.exit(1));try{return JSON.parse(re(e,"utf-8"))}catch(t){console.log(`
|
|
45
45
|
Error: --input-file is not valid JSON: ${t.message}
|
|
46
|
-
`),process.exit(1)}}function
|
|
46
|
+
`),process.exit(1)}}function M(o){let e={};if(o.inputFile&&(e={...ie(o.inputFile)}),o.input)try{e={...e,...JSON.parse(o.input)}}catch(t){console.log(`
|
|
47
47
|
Error: --input is not valid JSON`),console.log(` ${t.message}
|
|
48
|
-
`),process.exit(1)}return o.param?.length&&(e={...e,...
|
|
48
|
+
`),process.exit(1)}return o.param?.length&&(e={...e,...Y(o.param)}),e}function Se(){let o=xe(ke(),".zibby","config.json");if(be(o))try{let t=JSON.parse($e(o,"utf-8"));if(t.sessionToken)return t.sessionToken}catch{}let e=process.env.ZIBBY_API_KEY;if(e)return e;console.log(`
|
|
49
49
|
Not authenticated`),console.log(" Run: zibby login"),console.log(` OR set ZIBBY_API_KEY env var (for CI/CD)
|
|
50
|
-
`),process.exit(1)}async function
|
|
50
|
+
`),process.exit(1)}async function Ee(o){let e=v(),t=O("Fetching projects...").start();try{let n=await fetch(`${e}/projects`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`}});n.ok||(t.fail("Failed to fetch projects"),process.exit(1));let s=await n.json();Array.isArray(s)||(s.projects?s=s.projects:s.data&&(s=s.data)),(!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 a=s.map(c=>({name:`${c.name||"Unnamed"} (${c.projectId||c.id})`,value:c.projectId||c.id}));return await Q({message:"Select a project:",choices:a})}catch(n){t.fail(`Error: ${n.message}`),process.exit(1)}}async function ve(o,e){let t=v(),n=O("Fetching deployed workflows...").start();try{let s=["analysis","implementation","run_test"],a=[];for(let l of s){let r=await fetch(`${t}/projects/${o}/workflows/${l}`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`}});if(r.ok){let f=await r.json();f.graph&&a.push({name:l,version:f.version||0,isDefault:f.isDefault!==!1})}}a.length===0&&(n.fail("No deployed workflows found for this project"),process.exit(1)),n.succeed(`Found ${a.length} deployed workflow${a.length===1?"":"s"}`),console.log("");let c=a.map(l=>({name:`${l.name} (v${l.version})${l.isDefault?" [default]":""}`,value:l.name}));return await Q({message:"Select a workflow to trigger:",choices:c})}catch(s){n.fail(`Error: ${s.message}`),process.exit(1)}}async function We(o,e={}){let t=D(o);t.ok||(console.log(`
|
|
51
51
|
Error: ${t.error}
|
|
52
|
-
`),process.exit(1));let n
|
|
53
|
-
\u2713 Found workflow "${
|
|
54
|
-
`);break}}}(!
|
|
52
|
+
`),process.exit(1));let n=Se(),s=e.project||process.env.ZIBBY_PROJECT_ID,a;if(o){let r=v();try{let f=await fetch(`${r}/projects`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`}});if(f.ok){let p=(await f.json()).projects||[];for(let g of p){let y=await fetch(`${r}/projects/${g.projectId}/workflows`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`}});if(y.ok){let m=(await y.json()).find(k=>k.uuid===o);if(m){s=g.projectId,a=m.workflowType||m.name,console.log(`
|
|
53
|
+
\u2713 Found workflow "${a}" (UUID: ${o})
|
|
54
|
+
`);break}}}(!a||a===o)&&(console.log(`
|
|
55
55
|
Error: Workflow with UUID "${o}" not found`),console.log(` Check: zibby workflow list
|
|
56
56
|
`),process.exit(1))}}catch(f){console.log(`
|
|
57
57
|
Error looking up workflow UUID: ${f.message}
|
|
58
|
-
`),process.exit(1)}}s||(console.log(""),s=await
|
|
58
|
+
`),process.exit(1)}}s||(console.log(""),s=await Ee(n)),a||(console.log(""),a=await ve(s,n));let c=M(e);if(console.log(`
|
|
59
59
|
Triggering Workflow
|
|
60
|
-
`),console.log(" ".padEnd(60,"-")),console.log(` Workflow: ${
|
|
61
|
-
Your workflow execution quota has been exceeded`),g.quotaInfo&&(console.log(` Used: ${g.quotaInfo.used}/${g.quotaInfo.limit} executions`),console.log(` Plan: ${g.quotaInfo.planId}`),g.quotaInfo.periodEnd&&console.log(` Resets: ${new Date(g.quotaInfo.periodEnd).toLocaleDateString()}`)),console.log(""),process.exit(1)),
|
|
62
|
-
`),process.exit(1)}let p=await
|
|
63
|
-
`),process.exit(1)}}export{
|
|
60
|
+
`),console.log(" ".padEnd(60,"-")),console.log(` Workflow: ${a}`),console.log(` Project: ${s}`),Object.keys(c).length>0){let r=JSON.stringify(c);console.log(` Input: ${r.length>60?`${r.substring(0,57)}...`:r}`)}e.idempotencyKey&&console.log(` Idempotency: ${e.idempotencyKey}`),console.log(" ".padEnd(60,"-")),console.log("");let l=O("Triggering workflow execution...").start();try{let r=v(),f={input:c};e.idempotencyKey&&(f.idempotencyKey=e.idempotencyKey);let u=await fetch(`${r}/projects/${s}/workflows/${a}/trigger`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`},body:JSON.stringify(f)});if(!u.ok){let g=await u.json().catch(()=>({}));u.status===429&&(l.fail("Quota exceeded"),console.log(`
|
|
61
|
+
Your workflow execution quota has been exceeded`),g.quotaInfo&&(console.log(` Used: ${g.quotaInfo.used}/${g.quotaInfo.limit} executions`),console.log(` Plan: ${g.quotaInfo.planId}`),g.quotaInfo.periodEnd&&console.log(` Resets: ${new Date(g.quotaInfo.periodEnd).toLocaleDateString()}`)),console.log(""),process.exit(1)),l.fail("Trigger failed"),console.log(` Error: ${g.message||u.statusText}
|
|
62
|
+
`),process.exit(1)}let p=await u.json();if(l.succeed("Workflow triggered successfully"),console.log(""),console.log(" Job Details:"),console.log(` Job ID: ${p.jobId}`),console.log(` Status: ${p.status}`),console.log(` Version: ${p.version}`),console.log(` Triggered: ${new Date(p.triggeredAt).toLocaleString()}`),console.log(""),e.follow){console.log(" Streaming logs (Ctrl+C to stop)..."),console.log("");let{logsCommand:g}=await Promise.resolve().then(()=>(X(),H));return g(p.jobId,{follow:!0,project:s,apiKey:e.apiKey})}console.log(" Monitor execution:"),o?(console.log(` zibby workflow logs ${o}`),console.log(` zibby workflow logs ${o} -t`)):(console.log(` zibby workflow logs --workflow ${a} --project ${s}`),console.log(` zibby workflow logs --workflow ${a} --project ${s} -t`)),console.log("")}catch(r){l.fail("Trigger failed"),console.log(` Error: ${r.message}
|
|
63
|
+
`),process.exit(1)}}export{F as coerceValue,Y as parseParams,M as resolveInput,We as triggerWorkflowCommand};
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zibby/cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "Zibby CLI - Test automation generator and runner",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"homepage": "https://zibby.dev",
|
|
28
28
|
"repository": {
|
|
29
29
|
"type": "git",
|
|
30
|
-
"url": "https://github.com/
|
|
30
|
+
"url": "https://github.com/ZibbyDev/zibby-agent"
|
|
31
31
|
},
|
|
32
32
|
"bugs": {
|
|
33
|
-
"url": "https://github.com/
|
|
33
|
+
"url": "https://github.com/ZibbyDev/zibby-agent/issues"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@aws-sdk/client-sqs": "^3.1038.0",
|
|
@@ -26,7 +26,7 @@ For goal-mode instances, an upgrade gives the supervisor newer tool definitions,
|
|
|
26
26
|
```
|
|
27
27
|
Bash(zibby app status <instanceId>)
|
|
28
28
|
```
|
|
29
|
-
Look at `agentOpsVersion` (or the equivalent — it's in the JSON). Compare to the latest tag at https://github.com/
|
|
29
|
+
Look at `agentOpsVersion` (or the equivalent — it's in the JSON). Compare to the latest tag at https://github.com/ZibbyDev/agent-ops/releases.
|
|
30
30
|
|
|
31
31
|
3. **Decide the target.**
|
|
32
32
|
- If user said "upgrade" without specifying → use `--version` of the latest stable tag (don't blindly use `:latest` floating tag; pin it).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zibby/cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "Zibby CLI - Test automation generator and runner",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"homepage": "https://zibby.dev",
|
|
28
28
|
"repository": {
|
|
29
29
|
"type": "git",
|
|
30
|
-
"url": "https://github.com/
|
|
30
|
+
"url": "https://github.com/ZibbyDev/zibby-agent"
|
|
31
31
|
},
|
|
32
32
|
"bugs": {
|
|
33
|
-
"url": "https://github.com/
|
|
33
|
+
"url": "https://github.com/ZibbyDev/zibby-agent/issues"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@aws-sdk/client-sqs": "^3.1038.0",
|
|
@@ -26,7 +26,7 @@ For goal-mode instances, an upgrade gives the supervisor newer tool definitions,
|
|
|
26
26
|
```
|
|
27
27
|
Bash(zibby app status <instanceId>)
|
|
28
28
|
```
|
|
29
|
-
Look at `agentOpsVersion` (or the equivalent — it's in the JSON). Compare to the latest tag at https://github.com/
|
|
29
|
+
Look at `agentOpsVersion` (or the equivalent — it's in the JSON). Compare to the latest tag at https://github.com/ZibbyDev/agent-ops/releases.
|
|
30
30
|
|
|
31
31
|
3. **Decide the target.**
|
|
32
32
|
- If user said "upgrade" without specifying → use `--version` of the latest stable tag (don't blindly use `:latest` floating tag; pin it).
|