@zibby/cli 0.1.37 → 0.1.38
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/commands/init.js +49 -45
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/commands/init.js
CHANGED
|
@@ -1,46 +1,50 @@
|
|
|
1
|
-
import{mkdir as
|
|
1
|
+
import{mkdir as C,writeFile as u,readFile as w}from"fs/promises";import{existsSync as y,readdirSync as L}from"fs";import{join as s,resolve as D,dirname as Z}from"path";import{homedir as A}from"os";import O from"inquirer";import e from"chalk";import P from"ora";import{spawn as Y,execSync as K}from"child_process";import{fileURLToPath as j}from"url";const N=j(import.meta.url),G=Z(N);async function H(){try{const l=process.platform==="win32",o=K("npm config get prefix",{encoding:"utf-8"}).trim(),g=l?o:`${o}/bin`,d=g.replace(/^~/,A()),a=l?";":":";if(process.env.PATH.split(a).some(v=>{const M=v.replace(/^~/,A());return M===d||M===g}))return;console.log(e.yellow("\u26A0\uFE0F npm global bin not in PATH")),console.log(e.gray(` Location: ${d}`)),console.log();const{shouldAddPath:n}=await O.prompt([{type:"confirm",name:"shouldAddPath",message:"Add npm global bin to your shell PATH automatically?",default:!0}]);if(!n){l?(console.log(e.gray(`
|
|
2
2
|
\u{1F4A1} To add manually on Windows:`)),console.log(e.gray(' 1. Search "Environment Variables" in Start menu')),console.log(e.gray(' 2. Edit "Path" in User variables')),console.log(e.gray(` 3. Add: ${d}
|
|
3
3
|
`))):(console.log(e.gray(`
|
|
4
4
|
\u{1F4A1} To add manually, run:`)),console.log(e.gray(` echo 'export PATH="${d}:$PATH"' >> ~/.zshrc`)),console.log(e.gray(` source ~/.zshrc
|
|
5
|
-
`)));return}if(
|
|
6
|
-
`));return}const x=process.env.SHELL||"";let p="";if(x.includes("zsh"))p=
|
|
5
|
+
`)));return}if(l){console.log(e.yellow("\u26A0\uFE0F Cannot auto-add PATH on Windows")),console.log(e.gray(" Please add manually:")),console.log(e.gray(' 1. Search "Environment Variables" in Start menu')),console.log(e.gray(' 2. Edit "Path" in User variables')),console.log(e.gray(` 3. Add: ${d}
|
|
6
|
+
`));return}const x=process.env.SHELL||"";let p="";if(x.includes("zsh"))p=s(A(),".zshrc");else if(x.includes("bash"))p=y(s(A(),".bashrc"))?s(A(),".bashrc"):s(A(),".bash_profile");else{console.log(e.yellow(`\u26A0\uFE0F Unknown shell: ${x}`)),console.log(e.gray(" Please add manually:")),console.log(e.gray(` export PATH="${d}:$PATH"`));return}if(y(p)){const v=await w(p,"utf-8");if(v.includes(d)||v.includes("npm")&&v.includes("global")&&v.includes("bin")){console.log(e.yellow(`\u26A0\uFE0F PATH entry found in ${p} but not active`)),console.log(e.gray(` Run: source ${p}
|
|
7
7
|
`));return}}const b=`
|
|
8
8
|
# npm global bin (added by zibby)
|
|
9
9
|
export PATH="${d}:$PATH"
|
|
10
|
-
`;await
|
|
10
|
+
`;await u(p,(y(p)?await w(p,"utf-8"):"")+b),console.log(e.green(`\u2705 Added to ${p}`)),console.log(e.yellow(`
|
|
11
11
|
\u{1F4A1} Run this to activate in current session:`)),console.log(e.gray(` source ${p}
|
|
12
|
-
`))}catch{}}async function
|
|
12
|
+
`))}catch{}}async function de(l,o){console.log(e.bold.cyan(`
|
|
13
13
|
\u{1F3AD} Welcome to Zibby Test Automation!
|
|
14
|
-
`));const
|
|
15
|
-
\u274C Directory "${
|
|
16
|
-
`)),process.exit(1)),!y
|
|
14
|
+
`));const g=!o.skipMemory,d=["dolt","mem0"].includes(String(o.memoryBackend||"").toLowerCase())?String(o.memoryBackend).toLowerCase():"dolt";await H();const a=l?D(process.cwd(),l):process.cwd(),_=l||"zibby-tests",f=!!l;f&&y(a)&&(console.log(e.red(`
|
|
15
|
+
\u274C Directory "${l}" already exists!
|
|
16
|
+
`)),process.exit(1)),!f&&y(s(a,".zibby.config.mjs"))&&!o.force&&(console.log(e.yellow(`
|
|
17
17
|
\u26A0\uFE0F Zibby is already initialized in this directory!
|
|
18
18
|
`)),console.log(e.white("Config file found: .zibby.config.mjs")),console.log(e.gray(`Use --force or -f to reinitialize
|
|
19
|
-
`)),process.exit(0)),
|
|
19
|
+
`)),process.exit(0)),o.force&&!f&&console.log(e.cyan(`
|
|
20
20
|
Reinitializing Zibby configuration...
|
|
21
|
-
`));let n;if(
|
|
22
|
-
`)),n={agent:
|
|
21
|
+
`));let n;if(o.agent&&(o.headed||o.headless))console.log(e.cyan(`Setting up with provided options...
|
|
22
|
+
`)),n={agent:o.agent,browserMode:o.headless?"headless":"headed",apiKey:o.apiKey||null,cloudSync:!!(o.cloudSync||o.apiKey)};else{const b=[];o.agent||b.push({type:"select",name:"agent",message:"Which AI agent do you prefer?",choices:[{name:"Cursor",value:"cursor"},{name:"Claude (Anthropic)",value:"claude"},{name:"Codex (OpenAI)",value:"codex"},{name:"Gemini (Google)",value:"gemini"}],default:"cursor"}),!o.headed&&!o.headless&&b.push({type:"select",name:"browserMode",message:"Browser mode during live AI execution?",choices:[{name:"Headed - Visible browser (recommended for development)",value:"headed"},{name:"Headless - Hidden browser (for CI/CD)",value:"headless"}],default:"headed"}),o.apiKey||b.push({type:"input",name:"apiKey",message:"Enable cloud sync? Enter project ZIBBY_API_KEY (or press Enter to skip):"}),n=b.length>0?await O.prompt(b):{},n.agent=o.agent||n.agent,n.browserMode=o.headless?"headless":o.headed?"headed":n.browserMode,n.apiKey=o.apiKey||n.apiKey,n.cloudSync=!!(o.cloudSync||o.apiKey||n.apiKey&&n.apiKey.trim())}n.mcp="playwright",n.setupMcp=n.agent==="cursor";const p=P("Setting up Zibby...").start();try{if(f&&await C(a,{recursive:!0}),await C(s(a,"test-specs/examples"),{recursive:!0}),await C(s(a,"tests"),{recursive:!0}),await C(s(a,".zibby/output"),{recursive:!0}),await C(s(a,".zibby/commands"),{recursive:!0}),g&&d==="dolt")try{const{initMemory:t,DoltDB:r}=await import("@zibby/memory");if(r.isAvailable()){const{created:i}=t(a);i&&(p.text="Initialized test memory database (Dolt)...")}else p.text="Dolt not found \u2014 skipping memory database (brew install dolt)"}catch{}p.text="Scaffolding workflow graph...";const{TemplateFactory:b}=await import("@zibby/core/templates"),v=o.template||"browser-test-automation";try{const{graphPath:t,nodesPath:r,readmePath:i,resultHandlerPath:m,template:c}=b.getTemplateFiles(v),h=s(a,".zibby"),B=await w(t,"utf-8");if(await u(s(h,"graph.mjs"),B),m){const I=await w(m,"utf-8");await u(s(h,"result-handler.mjs"),I)}const z=await w(i,"utf-8");await u(s(h,"README.md"),z),await C(s(h,"nodes"),{recursive:!0});const{readdirSync:k}=await import("fs"),S=k(r);for(const I of S){let R=await w(s(r,I),"utf-8");!g&&I==="execute-live.mjs"&&(R=R.replace("skills: [SKILLS.BROWSER, SKILLS.MEMORY],","skills: [SKILLS.BROWSER],")),await u(s(h,"nodes",I),R)}const T=s(c.path,"chat.mjs");if(y(T)){const I=await w(T,"utf-8");await u(s(h,"chat.mjs"),I)}}catch(t){throw p.fail(`Failed to scaffold template: ${t.message}`),t}p.text="Generating configuration files...";const M=F(n,o,{memoryBackend:d});if(await u(s(a,".zibby.config.mjs"),M),await u(s(a,".env.example"),W(n,d)),n.apiKey&&n.apiKey.trim()){const t=s(a,".env"),r=n.apiKey.trim();if(y(t)){let i=await w(t,"utf8");/^ZIBBY_API_KEY=/m.test(i)?i=i.replace(/^ZIBBY_API_KEY=.*/m,`ZIBBY_API_KEY=${r}`):/^#\s*ZIBBY_API_KEY=/m.test(i)?i=i.replace(/^#\s*ZIBBY_API_KEY=.*/m,`ZIBBY_API_KEY=${r}`):i=i.trimEnd()+`
|
|
23
|
+
|
|
24
|
+
# Zibby Cloud Sync
|
|
25
|
+
ZIBBY_API_KEY=${r}
|
|
26
|
+
`,await u(t,i)}else await u(t,U(n,r,d))}if(f){const t=V(_,n,{memoryBackend:d});await u(s(a,"package.json"),t)}if(!y(s(a,".gitignore"))){const t=q();await u(s(a,".gitignore"),t)}if(!y(s(a,"playwright.config.js"))){const t=X("on");await u(s(a,"playwright.config.js"),t)}if(!y(s(a,"test-specs/examples/example-domain.txt"))){const t=J();await u(s(a,"test-specs/examples/example-domain.txt"),t)}const $=D(G,"../../../../examples/.zibby/commands");if(y($)){const t=L($).filter(r=>r.toLowerCase().endsWith(".md"));for(const r of t){const i=s(a,".zibby/commands",r);if(o.force||!y(i)){const m=await w(s($,r),"utf-8");await u(i,m)}}}if(!y(s(a,".zibby/commands/example.md"))){const t=Q();await u(s(a,".zibby/commands/example.md"),t)}if(f){const t=ee(_,n);await u(s(a,"README.md"),t)}if(p.succeed(f?"Project created!":"Zibby initialized!"),f&&!o.skipInstall){const t=P("Installing dependencies...").start();await new Promise((r,i)=>{Y("npm",["install"],{cwd:a,stdio:"pipe"}).on("close",c=>{c===0?(t.succeed("Dependencies installed!"),r()):(t.fail("Failed to install dependencies"),i(new Error("npm install failed")))})})}else f||console.log(e.gray(`
|
|
23
27
|
Make sure @zibby/cli is installed in your package.json
|
|
24
|
-
`));if(!
|
|
28
|
+
`));if(!f&&g&&d==="mem0"&&(console.log(e.yellow(`
|
|
25
29
|
Using mem0 backend requires mem0ai in your project dependencies.`)),console.log(e.gray("Run this manually in your project when ready:")),console.log(e.white(` npm install mem0ai
|
|
26
|
-
`))),!
|
|
30
|
+
`))),!o.skipInstall){const t=P("Installing Playwright browsers...").start();await new Promise(r=>{const i=Y("npx",["playwright","install","chromium"],{cwd:a,stdio:"pipe"});let m="";i.stdout.on("data",c=>{m+=c.toString()}),i.stderr.on("data",c=>{m+=c.toString()}),i.on("close",c=>{c===0?(m.includes("already installed")||m.includes("up to date")?t.succeed("Playwright browsers already installed"):t.succeed("Playwright browsers installed!"),r()):(t.warn("Could not verify Playwright browsers"),console.log(e.yellow(`
|
|
27
31
|
\u26A0\uFE0F If tests fail, run: npx playwright install
|
|
28
|
-
`)),
|
|
29
|
-
`))}}}if(n.agent==="gemini"&&!
|
|
30
|
-
`))}}const
|
|
31
|
-
`,"utf-8");let k="Gemini MCP configured";
|
|
32
|
-
`))}}if(n.agent==="cursor"&&n.setupMcp){const
|
|
32
|
+
`)),r())})})}if(n.agent==="codex"&&!o.skipInstall){const t=P("Checking Codex CLI...").start();try{K("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),t.succeed("Codex CLI already installed")}catch{t.text="Installing Codex CLI...";try{await new Promise((r,i)=>{Y("npm",["install","-g","@openai/codex"],{stdio:"pipe"}).on("close",c=>{c===0?(t.succeed("Codex CLI installed!"),r()):i(new Error("npm install -g @openai/codex failed"))})})}catch{t.fail("Could not install Codex CLI"),console.log(e.yellow(` Install manually: npm install -g @openai/codex
|
|
33
|
+
`))}}}if(n.agent==="gemini"&&!o.skipInstall){const t=P("Checking Gemini CLI...").start();try{K("gemini --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),t.succeed("Gemini CLI already installed")}catch{t.text="Installing Gemini CLI...";try{await new Promise((i,m)=>{Y("npm",["install","-g","@google/gemini-cli"],{stdio:"pipe"}).on("close",h=>{h===0?(t.succeed("Gemini CLI installed!"),i()):m(new Error("npm install -g @google/gemini-cli failed"))})})}catch{t.fail("Could not install Gemini CLI"),console.log(e.yellow(` Install manually: npm install -g @google/gemini-cli
|
|
34
|
+
`))}}const r=P("Configuring Gemini MCP servers...").start();try{const i=s(A(),".gemini"),m=s(i,"settings.json");y(i)||await C(i,{recursive:!0});let c={mcpServers:{}};if(y(m))try{const S=await w(m,"utf-8");c=JSON.parse(S),c.mcpServers||(c.mcpServers={})}catch{}let h;try{const{createRequire:S}=await import("module");h=S(import.meta.url).resolve("@zibby/mcp-browser/bin/mcp-browser-zibby.js")}catch{h="@playwright/mcp"}const B=n.browserMode!=="headless",z=h==="@playwright/mcp"?["-y","@playwright/mcp","--isolated","--save-video=1280x720","--viewport-size=1280x720","--output-dir","test-results"]:[h,"--isolated","--save-video=1280x720","--viewport-size=1280x720","--output-dir=test-results"];B||z.push("--headless"),c.mcpServers["playwright-official"]={command:h==="@playwright/mcp"?"npx":"node",args:z},await u(m,`${JSON.stringify(c,null,2)}
|
|
35
|
+
`,"utf-8");let k="Gemini MCP configured";B?k+=" (headed mode - visible browser)":k+=" (headless mode - hidden browser)",r.succeed(k)}catch(i){r.fail("MCP setup failed"),console.log(e.yellow(" You may need to configure ~/.gemini/settings.json manually")),console.log(e.gray(` Error: ${i.message}
|
|
36
|
+
`))}}if(n.agent==="cursor"&&n.setupMcp){const t=P("Setting up Playwright MCP...").start();try{const{setupPlaywrightMcpCommand:r}=await import("./setup-scripts.js"),i=n.cloudSync||!1,m=n.browserMode!=="headless";await r({headed:m,cloudSync:i,video:"on",viewport:{width:1280,height:720}});let c="Playwright MCP configured";m?c+=" (headed mode - visible browser)":c+=" (headless mode - hidden browser)",i&&(c+=" + Zibby MCP (cloud sync)"),t.succeed(c),i&&!(n.apiKey&&n.apiKey.trim())&&console.log(e.gray(`
|
|
33
37
|
Copy .env.example to .env and set ZIBBY_API_KEY to enable uploads
|
|
34
|
-
`))}catch(
|
|
35
|
-
`)),console.log(e.gray(` Error: ${
|
|
38
|
+
`))}catch(r){t.fail("MCP setup script failed"),console.log(e.yellow(" Check if MCP is already configured:")),console.log(e.gray(' \u2022 Open Cursor settings \u2192 Check "playwright-official" MCP')),console.log(e.gray(" \u2022 Run: cursor-agent mcp list")),console.log(e.gray(` \u2022 Or run manually: zibby setup-playwright
|
|
39
|
+
`)),console.log(e.gray(` Error: ${r.message}
|
|
36
40
|
`))}}console.log(e.bold.green(`
|
|
37
41
|
\u{1F389} All set!
|
|
38
|
-
`)),console.log(e.cyan("Start the Zibby Chat Agent:")),
|
|
42
|
+
`)),console.log(e.cyan("Start the Zibby Chat Agent:")),f&&console.log(e.white(` cd ${l}`)),console.log(e.white(` zibby
|
|
39
43
|
`)),console.log(e.cyan("Or run a test directly:")),console.log(e.white(` zibby run test-specs/examples/example-domain.txt
|
|
40
|
-
`)),console.log(e.cyan("Next steps:"));let
|
|
44
|
+
`)),console.log(e.cyan("Next steps:"));let E=1;console.log(e.white(` ${E++}. cp .env.example .env ${e.gray("# then add your API keys")}`)),g&&console.log(e.white(` ${E++}. Set ${e.bold("ZIBBY_MEMORY_BACKEND")} in .env ${e.gray(`# currently: ${d}`)}`)),console.log(e.white(` ${E++}. Type ${e.bold("zibby")} to chat with the AI testing assistant`)),console.log(e.white(` ${E++}. Write test specs in test-specs/`)),console.log(e.white(` ${E++}. Run: npx zibby run <spec-file>
|
|
41
45
|
`))}catch(b){p.fail("Failed to create project"),console.error(e.red(`
|
|
42
46
|
\u274C Error: ${b.message}
|
|
43
|
-
`)),process.exit(1)}}function
|
|
47
|
+
`)),process.exit(1)}}function F(l,o={},g={}){const d=["dolt","mem0"].includes(String(g.memoryBackend||"").toLowerCase())?String(g.memoryBackend).toLowerCase():"dolt",a={claude:`
|
|
44
48
|
claude: {
|
|
45
49
|
model: 'auto', // Options: 'auto', 'sonnet-4.6', 'opus-4.6', 'sonnet-4.5', 'opus-4.5'
|
|
46
50
|
maxTokens: 4096,
|
|
@@ -53,13 +57,13 @@ Using mem0 backend requires mem0ai in your project dependencies.`)),console.log(
|
|
|
53
57
|
},`,gemini:`
|
|
54
58
|
gemini: {
|
|
55
59
|
model: 'gemini-2.5-pro', // Options: 'auto', 'gemini-2.5-pro', 'gemini-2.5-flash'
|
|
56
|
-
},`},
|
|
60
|
+
},`},_=l.agent,f=Object.entries(a).filter(([n])=>n!==_).map(([,n])=>n.split(`
|
|
57
61
|
`).map(x=>x.trim()?` // ${x.trimStart()}`:x).join(`
|
|
58
62
|
`)).join(`
|
|
59
63
|
`);return`export default {
|
|
60
64
|
// AI agent settings
|
|
61
|
-
agent: {${
|
|
62
|
-
${
|
|
65
|
+
agent: {${a[_]}
|
|
66
|
+
${f}
|
|
63
67
|
strictMode: false,
|
|
64
68
|
},
|
|
65
69
|
|
|
@@ -67,7 +71,7 @@ ${y}
|
|
|
67
71
|
// and workflow config. Runtime strategies attach MCP per run (no global Gemini settings mutation).
|
|
68
72
|
browser: {
|
|
69
73
|
mcp: 'playwright',
|
|
70
|
-
headless: ${
|
|
74
|
+
headless: ${l.browserMode==="headless"},
|
|
71
75
|
},
|
|
72
76
|
|
|
73
77
|
// Chat memory backend adapter (dolt | mem0)
|
|
@@ -120,13 +124,13 @@ ${y}
|
|
|
120
124
|
},
|
|
121
125
|
|
|
122
126
|
// Cloud sync - auto-upload test results & videos (requires ZIBBY_API_KEY in .env)
|
|
123
|
-
cloudSync: ${
|
|
127
|
+
cloudSync: ${l.cloudSync||!1}
|
|
124
128
|
};
|
|
125
|
-
`}function
|
|
129
|
+
`}function W(l,o="dolt"){return`# Zibby Test Automation - Environment Variables
|
|
126
130
|
|
|
127
131
|
# AI Provider Keys
|
|
128
132
|
${{claude:"ANTHROPIC_API_KEY=sk-ant-your_key_here",cursor:`# Cursor Agent uses cursor-agent CLI \u2014 no API key needed
|
|
129
|
-
# Install: curl https://cursor.com/install -fsS | bash`,codex:"OPENAI_API_KEY=sk-your_key_here",gemini:"GEMINI_API_KEY=your_key_here"}[
|
|
133
|
+
# Install: curl https://cursor.com/install -fsS | bash`,codex:"OPENAI_API_KEY=sk-your_key_here",gemini:"GEMINI_API_KEY=your_key_here"}[l.agent]||""}
|
|
130
134
|
|
|
131
135
|
# Zibby Cloud Sync (for uploading test results & videos)
|
|
132
136
|
# Get your API key from: https://zibby.app/settings/tokens
|
|
@@ -138,14 +142,14 @@ ${{claude:"ANTHROPIC_API_KEY=sk-ant-your_key_here",cursor:`# Cursor Agent uses c
|
|
|
138
142
|
# ZIBBY_MEMORY_COMPACT_EVERY=1500 # Auto-compact every N runs (0 to disable)
|
|
139
143
|
|
|
140
144
|
# Chat memory backend
|
|
141
|
-
ZIBBY_MEMORY_BACKEND=${
|
|
142
|
-
`}function
|
|
145
|
+
ZIBBY_MEMORY_BACKEND=${o}
|
|
146
|
+
`}function U(l,o,g="dolt"){return`# Zibby Test Automation - Environment Variables
|
|
143
147
|
|
|
144
148
|
# AI Provider Keys
|
|
145
|
-
${{claude:"ANTHROPIC_API_KEY=sk-ant-your_key_here",cursor:"# Cursor Agent uses cursor-agent CLI \u2014 no API key needed",codex:"OPENAI_API_KEY=sk-your_key_here",gemini:"GEMINI_API_KEY=your_key_here"}[
|
|
149
|
+
${{claude:"ANTHROPIC_API_KEY=sk-ant-your_key_here",cursor:"# Cursor Agent uses cursor-agent CLI \u2014 no API key needed",codex:"OPENAI_API_KEY=sk-your_key_here",gemini:"GEMINI_API_KEY=your_key_here"}[l.agent]||""}
|
|
146
150
|
|
|
147
151
|
# Zibby Cloud Sync
|
|
148
|
-
ZIBBY_API_KEY=${
|
|
152
|
+
ZIBBY_API_KEY=${o}
|
|
149
153
|
|
|
150
154
|
# Test Memory (Dolt DB) - Auto-compaction settings
|
|
151
155
|
# ZIBBY_MEMORY_MAX_RUNS=3000 # Max test runs to keep per spec
|
|
@@ -153,8 +157,8 @@ ZIBBY_API_KEY=${t}
|
|
|
153
157
|
# ZIBBY_MEMORY_COMPACT_EVERY=1500 # Auto-compact every N runs (0 to disable)
|
|
154
158
|
|
|
155
159
|
# Chat memory backend
|
|
156
|
-
ZIBBY_MEMORY_BACKEND=${
|
|
157
|
-
`}function
|
|
160
|
+
ZIBBY_MEMORY_BACKEND=${g}
|
|
161
|
+
`}function V(l,o,g={}){const d={"@zibby/cli":"^0.1.25","@zibby/core":"^0.1.20"};return g.memoryBackend==="mem0"&&(d.mem0ai="^2.4.6"),JSON.stringify({name:l,version:"1.0.0",type:"module",private:!0,scripts:{"test:spec":"zibby run",test:"playwright test","test:headed":"playwright test --headed"},dependencies:d,devDependencies:{"@playwright/test":"^1.49.0",dotenv:"^17.2.3"}},null,2)}function q(){return`# Dependencies
|
|
158
162
|
node_modules/
|
|
159
163
|
|
|
160
164
|
# Test artifacts
|
|
@@ -182,11 +186,11 @@ Thumbs.db
|
|
|
182
186
|
# Zibby memory (Dolt DB synced separately via dolt remote, not git)
|
|
183
187
|
.zibby/memory/
|
|
184
188
|
.zibby/memory-context.md
|
|
185
|
-
`}function
|
|
189
|
+
`}function X(l="off",o=null){return`import { defineConfig} from '@playwright/test';
|
|
186
190
|
|
|
187
191
|
export default defineConfig({
|
|
188
192
|
testDir: './tests',
|
|
189
|
-
${
|
|
193
|
+
${o?` outputDir: '${o}',
|
|
190
194
|
`:` outputDir: 'test-results/playwright', // Keep Playwright artifacts separate from Zibby workflow output
|
|
191
195
|
`} timeout: 30000,
|
|
192
196
|
retries: 0,
|
|
@@ -204,7 +208,7 @@ ${t?` outputDir: '${t}',
|
|
|
204
208
|
['list']
|
|
205
209
|
],
|
|
206
210
|
});
|
|
207
|
-
`}function
|
|
211
|
+
`}function J(){return`Test Specification: Example Domain Navigation
|
|
208
212
|
==============================================
|
|
209
213
|
|
|
210
214
|
Application: Example Domain
|
|
@@ -241,7 +245,7 @@ Notes:
|
|
|
241
245
|
- Uses a stable, public domain (example.com) maintained by IANA
|
|
242
246
|
- No authentication required
|
|
243
247
|
- Suitable for CI/CD smoke testing
|
|
244
|
-
`}function
|
|
248
|
+
`}function Q(){return`# Example command template
|
|
245
249
|
|
|
246
250
|
Use this command when the user asks for a concise testing task breakdown.
|
|
247
251
|
|
|
@@ -252,7 +256,7 @@ Required output format:
|
|
|
252
256
|
4. Expected result
|
|
253
257
|
|
|
254
258
|
Keep the response actionable and short.
|
|
255
|
-
`}function
|
|
259
|
+
`}function ee(l,o){return`# ${l}
|
|
256
260
|
|
|
257
261
|
AI-powered test automation with Zibby.
|
|
258
262
|
|
|
@@ -266,7 +270,7 @@ npm install
|
|
|
266
270
|
2. Configure environment:
|
|
267
271
|
\`\`\`bash
|
|
268
272
|
cp .env.example .env
|
|
269
|
-
# Edit .env and add your ${{claude:"ANTHROPIC_API_KEY",codex:"OPENAI_API_KEY",gemini:"GEMINI_API_KEY",cursor:"CURSOR_API_KEY (optional)"}[
|
|
273
|
+
# Edit .env and add your ${{claude:"ANTHROPIC_API_KEY",codex:"OPENAI_API_KEY",gemini:"GEMINI_API_KEY",cursor:"CURSOR_API_KEY (optional)"}[o.agent]}
|
|
270
274
|
\`\`\`
|
|
271
275
|
|
|
272
276
|
3. Run example test:
|
|
@@ -317,13 +321,13 @@ npx playwright test --ui
|
|
|
317
321
|
Edit \`.zibby.config.mjs\` to customize:
|
|
318
322
|
- Agent settings (model, temperature)
|
|
319
323
|
- Browser settings (headless, viewport)
|
|
320
|
-
- Cloud sync${
|
|
324
|
+
- Cloud sync${o.cloudSync?" (enabled)":" (disabled)"}
|
|
321
325
|
- Self-healing behavior
|
|
322
326
|
|
|
323
327
|
## Project Structure
|
|
324
328
|
|
|
325
329
|
\`\`\`
|
|
326
|
-
${
|
|
330
|
+
${l}/
|
|
327
331
|
\u251C\u2500\u2500 .zibby/
|
|
328
332
|
\u2502 \u251C\u2500\u2500 graph.mjs # Workflow definition
|
|
329
333
|
\u2502 \u251C\u2500\u2500 nodes/ # Custom nodes
|
|
@@ -341,4 +345,4 @@ ${r}/
|
|
|
341
345
|
|
|
342
346
|
- Documentation: https://docs.zibby.dev
|
|
343
347
|
- Examples: https://github.com/zibby/examples
|
|
344
|
-
`}export{
|
|
348
|
+
`}export{de as initCommand};
|
package/dist/package.json
CHANGED