@zibby/skills 0.1.14 → 0.1.16

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/browser.js CHANGED
@@ -1,3 +1,6 @@
1
- import{createRequire as w}from"module";import{join as f}from"path";var d=w(import.meta.url);function v(){if(process.env.MCP_BROWSER_PATH)return process.env.MCP_BROWSER_PATH;try{return d.resolve("@zibby/mcp-browser/dist/bin/mcp-browser-zibby.js")}catch{return null}}var a="1280x720",c="1280x720";function S({headless:e}={}){if(e===!0)return!0;if(e===!1)return!1;let r=process.env.ZIBBY_HEADLESS;return r==="1"||String(r).toLowerCase()==="true"}function p(e,r){let t=(e||[]).filter(s=>s!=="--headless");return r?[...t,"--headless"]:t}var m={id:"browser",serverName:"playwright",cursorKey:"playwright-official",allowedTools:["mcp__playwright__*"],sessionEnvKey:"ZIBBY_SESSION_INFO",description:"Playwright Browser MCP Server",envKeys:[],tools:[],promptFragment:`Execute this test using the browser tools available to you. You MUST make actual browser tool calls \u2014 do not fabricate results.
1
+ import{createRequire as c}from"module";import{join as u}from"path";var b=c(import.meta.url);function w(){if(process.env.MCP_BROWSER_PATH)return process.env.MCP_BROWSER_PATH;try{return b.resolve("@zibby/mcp-browser/dist/bin/mcp-browser-zibby.js")}catch{return null}}var p="1280x720",f="1280x720";function y({headless:e}={}){if(e===!0)return!0;if(e===!1)return!1;let r=process.env.ZIBBY_HEADLESS;return r==="1"||String(r).toLowerCase()==="true"}function d(e,r){let o=(e||[]).filter(s=>s!=="--headless");return r?[...o,"--headless"]:o}var _={id:"browser",serverName:"playwright",cursorKey:"playwright-official",allowedTools:["mcp__playwright__*"],sessionEnvKey:"ZIBBY_SESSION_INFO",description:"Playwright Browser MCP Server",envKeys:[],tools:[],promptFragment:`Execute this test using the browser tools available to you. You MUST make actual browser tool calls \u2014 do not fabricate results.
2
2
  If you DO NOT have access to browser tools \u2192 return {"success": false, "steps": [], "browserClosed": false, "notes": "No browser tools available"}.
3
- DO NOT return success: true unless you ACTUALLY called browser tools.`,resolve({sessionPath:e,workspace:r,nodeName:t,headless:s}={}){let i=v(),n=e&&t?f(e,t):null,l=n||e||r||"test-results",u=S({headless:s}),o={};return n&&(o.ZIBBY_NODE_SESSION_PATH=n),e&&(o.ZIBBY_SESSION_PATH=e),i?{command:"node",args:p([i,"--isolated",`--save-video=${a}`,`--viewport-size=${c}`,`--output-dir=${l}`],u),env:o}:{command:"npx",args:p(["-y","@playwright/mcp","--isolated",`--save-video=${a}`,`--viewport-size=${c}`,"--output-dir",l],u),env:o}}};export{m as browserSkill};
3
+ DO NOT return success: true unless you ACTUALLY called browser tools.`,resolve({sessionPath:e,workspace:r,nodeName:o,headless:s}={}){let i=w(),t=e&&o?u(e,o):null,n=t||e||r||"test-results",a=y({headless:s}),l={};if(t&&(l.ZIBBY_NODE_SESSION_PATH=t),e&&(l.ZIBBY_SESSION_PATH=e),!i)throw new Error(`@zibby/mcp-browser is not installed.
4
+ Cloud: verify the Fargate image has it (packages/Dockerfile installs it globally alongside @zibby/cli).
5
+ Local: \`npm install @zibby/mcp-browser\` in your workflow, or use the global @zibby/cli install (which pulls it transitively).
6
+ Override: set MCP_BROWSER_PATH to the path of mcp-browser-zibby.js.`);return{command:"node",args:d([i,"--isolated",`--save-video=${p}`,`--viewport-size=${f}`,`--output-dir=${n}`],a),env:l}}};export{_ as browserSkill};
package/dist/git.js CHANGED
@@ -1,4 +1,4 @@
1
- import{spawn as T}from"child_process";import{existsSync as p,mkdirSync as O,readdirSync as $,statSync as j,readFileSync as R}from"fs";import{resolve as v,join as l,basename as C}from"path";var x=".zibby/repos";function w(u,n,r={}){return new Promise((o,i)=>{let e=T(u,{cwd:n,shell:!0,env:{...process.env,GIT_TERMINAL_PROMPT:"0",...r}}),c="",f="";e.stdout.on("data",s=>{c+=s.toString()}),e.stderr.on("data",s=>{f+=s.toString()}),e.on("close",s=>{s!==0?i(new Error(`Exit ${s}: ${f.trim()||c.trim()}`)):o(c.trim())}),e.on("error",s=>i(s))})}var A={id:"git",description:"Clone and manage git repositories for codebase analysis",envKeys:["GITHUB_TOKEN","GITLAB_TOKEN"],promptFragment:`## Git Repositories
1
+ import{spawn as C}from"child_process";import{existsSync as g,mkdirSync as T,readdirSync as O,statSync as j,readFileSync as L}from"fs";import{resolve as E,join as u,basename as A}from"path";var D="/workspace/repos",N=".zibby/repos";function $(a){return process.env.REPOS?D:E(a,N)}function R(){let a=process.env.REPOS;if(!a)return[];try{let i=JSON.parse(a);return Array.isArray(i)?i:[]}catch{return[]}}function S(a){return String(a).replace(/\//g,"-")}function x(a,i,e={}){return new Promise((r,d)=>{let s=C(a,{cwd:i,shell:!0,env:{...process.env,GIT_TERMINAL_PROMPT:"0",...e}}),t="",n="";s.stdout.on("data",c=>{t+=c.toString()}),s.stderr.on("data",c=>{n+=c.toString()}),s.on("close",c=>{c!==0?d(new Error(`Exit ${c}: ${n.trim()||t.trim()}`)):r(t.trim())}),s.on("error",c=>d(c))})}var M={id:"git",description:"Clone and manage git repositories for codebase analysis",envKeys:["GITHUB_TOKEN","GITLAB_TOKEN"],promptFragment:`## Git Repositories
2
2
  You can clone and explore git repositories locally for codebase analysis:
3
3
  - git_checkout: Clone a repo (or pull if already cloned). Supports GitHub and GitLab with auto-auth.
4
4
  - git_list_repos: List locally cloned repos
@@ -9,4 +9,4 @@ When a test ticket lacks context, use this workflow:
9
9
  2. Use git_explore to understand the project structure
10
10
  3. Use shell commands (grep, cat) to read specific files for deeper understanding
11
11
  4. Use GitHub/GitLab skills to read related PRs and commits
12
- 5. Build well-informed test specs and save them to files before running tests`,resolve(){return null},async handleToolCall(u,n,r){let o=r?.options?.workspace||process.cwd();try{switch(u){case"git_checkout":return await N(n,o);case"git_list_repos":return L(n,o);case"git_explore":return D(n,o);default:return JSON.stringify({error:`Unknown tool: ${u}`})}}catch(i){return JSON.stringify({error:i.message})}},tools:[{name:"git_checkout",description:"Clone a git repository locally (or pull latest if already cloned). Auto-authenticates with GitHub/GitLab tokens if available.",input_schema:{type:"object",properties:{url:{type:"string",description:'Repository URL (e.g. "https://github.com/org/repo" or "org/repo" shorthand for GitHub)'},branch:{type:"string",description:"Branch to checkout (default: repo default branch)"},shallow:{type:"boolean",description:"Shallow clone with depth 1 (default: true, faster)"},name:{type:"string",description:"Local directory name override (default: repo name from URL)"}},required:["url"]}},{name:"git_list_repos",description:"List locally cloned repositories",input_schema:{type:"object",properties:{}}},{name:"git_explore",description:"Quick structural overview of a cloned repo: key files, package.json info, directory tree (top 2 levels), detected framework/language",input_schema:{type:"object",properties:{repo:{type:"string",description:"Repo name (as listed by git_list_repos)"},depth:{type:"number",description:"Directory tree depth (default: 2)"}},required:["repo"]}}]};async function N(u,n){let{url:r,branch:o,shallow:i=!0,name:e}=u;!r.includes("://")&&!r.startsWith("git@")&&(r=`https://github.com/${r}`);let c=e||C(r.replace(/\.git$/,"")),f=v(n,x);O(f,{recursive:!0});let s=l(f,c),h=r,g=process.env.GITHUB_TOKEN,m=process.env.GITLAB_TOKEN,k=process.env.GITLAB_URL;if(r.includes("github.com")&&g)h=r.replace("https://github.com",`https://x-access-token:${g}@github.com`);else if(m&&k)try{let d=new URL(k).host;r.includes(d)&&(h=r.replace(`https://${d}`,`https://oauth2:${m}@${d}`))}catch{}if(p(l(s,".git"))){let d=o?`git -C "${s}" fetch origin ${o} && git -C "${s}" checkout ${o} && git -C "${s}" pull origin ${o}`:`git -C "${s}" pull`;await w(d,n);let b=await w(`git -C "${s}" log -1 --format="%h %s"`,n);return JSON.stringify({action:"updated",repo:c,path:s,branch:o||"default",head:b})}let t=["git","clone"];i&&t.push("--depth","1"),o&&t.push("--branch",o),t.push(`"${h}"`,`"${s}"`),await w(t.join(" "),n);let _=await w(`git -C "${s}" log -1 --format="%h %s"`,n);return JSON.stringify({action:"cloned",repo:c,path:s,branch:o||"default",shallow:i,head:_})}function L(u,n){let r=v(n,x);if(!p(r))return JSON.stringify({repos:[],message:"No repos cloned yet"});let o=[];for(let i of $(r,{withFileTypes:!0})){if(!i.isDirectory())continue;let e=l(r,i.name);if(!p(l(e,".git")))continue;let c=j(e);o.push({name:i.name,path:e,lastModified:c.mtime.toISOString()})}return JSON.stringify({repos:o,total:o.length,directory:r})}function D(u,n){let{repo:r,depth:o=2}=u,i=v(n,x,r);if(!p(i))return JSON.stringify({error:`Repo not found: ${r}. Run git_checkout first.`});let e={repo:r,path:i},c=l(i,"package.json");if(p(c))try{let t=JSON.parse(R(c,"utf-8"));e.packageJson={name:t.name,version:t.version,scripts:t.scripts?Object.keys(t.scripts):[],dependencies:t.dependencies?Object.keys(t.dependencies).slice(0,30):[],devDependencies:t.devDependencies?Object.keys(t.devDependencies).slice(0,20):[]},t.dependencies?.react?e.framework="React":t.dependencies?.next?e.framework="Next.js":t.dependencies?.vue?e.framework="Vue":t.dependencies?.angular?e.framework="Angular":t.dependencies?.express?e.framework="Express":t.dependencies?.fastify&&(e.framework="Fastify")}catch{}let f=l(i,"pyproject.toml");p(f)&&(e.language="Python");let s=l(i,"go.mod");p(s)&&(e.language="Go");let h=l(i,"Cargo.toml");p(h)&&(e.language="Rust"),p(c)&&(e.language=e.language||"JavaScript/TypeScript");let g=[];function m(t,_,d){if(d>o)return;let b;try{b=$(t,{withFileTypes:!0})}catch{return}let S=b.filter(a=>!a.name.startsWith(".")&&a.name!=="node_modules"&&a.name!=="__pycache__"&&a.name!=="dist"&&a.name!=="build"&&a.name!==".git").sort((a,y)=>a.isDirectory()!==y.isDirectory()?a.isDirectory()?-1:1:a.name.localeCompare(y.name));for(let a of S){let y=a.isDirectory();g.push(`${_}${y?"\u{1F4C1}":"\u{1F4C4}"} ${a.name}`),y&&d<o&&m(l(t,a.name),`${_} `,d+1)}}m(i,"",1),e.tree=g.slice(0,80),g.length>80&&(e.treeTruncated=!0);let k=["README.md","README.rst","src/App.tsx","src/App.jsx","src/App.js","src/routes.tsx","src/routes.js","app/routes.tsx","app/routes.js","src/index.tsx","src/index.ts","src/main.tsx","src/main.ts","pages/_app.tsx","pages/_app.js","app/layout.tsx","docker-compose.yml","Dockerfile",".env.example"];return e.keyFilesFound=k.filter(t=>p(l(i,t))),JSON.stringify(e)}export{A as gitSkill};
12
+ 5. Build well-informed test specs and save them to files before running tests`,resolve(){return null},async handleToolCall(a,i,e){let r=e?.options?.workspace||process.cwd();try{switch(a){case"git_checkout":return await U(i,r);case"git_list_repos":return G(i,r);case"git_explore":return J(i,r);default:return JSON.stringify({error:`Unknown tool: ${a}`})}}catch(d){return JSON.stringify({error:d.message})}},tools:[{name:"git_checkout",description:'Clone a git repository locally (or pull latest if already cloned). Auto-authenticates with GitHub/GitLab tokens if available. When running inside a Zibby workflow, `url` may be the name of a configured repo (e.g. "org/repo") and the platform-injected clone URL + token will be used automatically.',input_schema:{type:"object",properties:{url:{type:"string",description:'Full URL ("https://github.com/org/repo") OR a configured repo name from the project ("org/repo")'},branch:{type:"string",description:"Branch to checkout (default: repo default branch, or whatever was configured)"},shallow:{type:"boolean",description:"Shallow clone with depth 1 (default: true, faster)"},name:{type:"string",description:"Local directory name override (default: derived from URL/name)"}},required:["url"]}},{name:"git_list_repos",description:"List locally cloned repositories",input_schema:{type:"object",properties:{}}},{name:"git_explore",description:"Quick structural overview of a cloned repo: key files, package.json info, directory tree (top 2 levels), detected framework/language",input_schema:{type:"object",properties:{repo:{type:"string",description:"Repo name (as listed by git_list_repos)"},depth:{type:"number",description:"Directory tree depth (default: 2)"}},required:["repo"]}}]};async function U(a,i){let{url:e,branch:r,shallow:d=!0,name:s}=a,n=R().find(f=>f.name===e),c=null;n?(e=n.cloneUrl||n.url||e,c=n.provider||"github",s||(s=S(n.name)),!r&&n.branch&&(r=n.branch)):!e.includes("://")&&!e.startsWith("git@")&&(e=`https://github.com/${e}`);let y=s||A(e.replace(/\.git$/,"")),w=$(i);T(w,{recursive:!0});let p=u(w,y),m=e,_=process.env.GITHUB_TOKEN,o=process.env.GITLAB_TOKEN,k=process.env.GITLAB_URL;if(c==="gitlab"&&o)try{let f=new URL(e).host;m=e.replace(`https://${f}`,`https://oauth2:${o}@${f}`)}catch{}else if(e.includes("github.com")&&_)m=e.replace("https://github.com",`https://x-access-token:${_}@github.com`);else if(o&&k)try{let f=new URL(k).host;e.includes(f)&&(m=e.replace(`https://${f}`,`https://oauth2:${o}@${f}`))}catch{}if(g(u(p,".git"))){let f=r?`git -C "${p}" fetch origin ${r} && git -C "${p}" checkout ${r} && git -C "${p}" pull origin ${r}`:`git -C "${p}" pull`;await x(f,i);let l=await x(`git -C "${p}" log -1 --format="%h %s"`,i);return JSON.stringify({action:"updated",repo:y,path:p,branch:r||"default",head:l})}let h=["git","clone"];d&&h.push("--depth","1"),r&&h.push("--branch",r),h.push(`"${m}"`,`"${p}"`),await x(h.join(" "),i);let v=await x(`git -C "${p}" log -1 --format="%h %s"`,i);return JSON.stringify({action:"cloned",repo:y,path:p,branch:r||"default",shallow:d,head:v})}function G(a,i){let e=$(i),r=new Map;if(g(e))for(let t of O(e,{withFileTypes:!0})){if(!t.isDirectory())continue;let n=u(e,t.name);if(!g(u(n,".git")))continue;let c=j(n);r.set(t.name,{name:t.name,path:n,lastModified:c.mtime.toISOString(),cloned:!0})}let d=R(),s=[];for(let t of d){let n=S(t.name),c=r.get(n);s.push({name:t.name,path:u(e,n),cloned:!!c,lastModified:c?.lastModified||null,configured:!0}),r.delete(n)}for(let t of r.values())s.push({...t,configured:!1});return JSON.stringify({repos:s,total:s.length,directory:e})}function J(a,i){let{repo:e,depth:r=2}=a,d=$(i),s=g(u(d,e))?u(d,e):u(d,S(e));if(!g(s))return JSON.stringify({error:`Repo not found: ${e}. Run git_checkout first.`});let t={repo:e,path:s},n=u(s,"package.json");if(g(n))try{let o=JSON.parse(L(n,"utf-8"));t.packageJson={name:o.name,version:o.version,scripts:o.scripts?Object.keys(o.scripts):[],dependencies:o.dependencies?Object.keys(o.dependencies).slice(0,30):[],devDependencies:o.devDependencies?Object.keys(o.devDependencies).slice(0,20):[]},o.dependencies?.react?t.framework="React":o.dependencies?.next?t.framework="Next.js":o.dependencies?.vue?t.framework="Vue":o.dependencies?.angular?t.framework="Angular":o.dependencies?.express?t.framework="Express":o.dependencies?.fastify&&(t.framework="Fastify")}catch{}let c=u(s,"pyproject.toml");g(c)&&(t.language="Python");let y=u(s,"go.mod");g(y)&&(t.language="Go");let w=u(s,"Cargo.toml");g(w)&&(t.language="Rust"),g(n)&&(t.language=t.language||"JavaScript/TypeScript");let p=[];function m(o,k,h){if(h>r)return;let v;try{v=O(o,{withFileTypes:!0})}catch{return}let f=v.filter(l=>!l.name.startsWith(".")&&l.name!=="node_modules"&&l.name!=="__pycache__"&&l.name!=="dist"&&l.name!=="build"&&l.name!==".git").sort((l,b)=>l.isDirectory()!==b.isDirectory()?l.isDirectory()?-1:1:l.name.localeCompare(b.name));for(let l of f){let b=l.isDirectory();p.push(`${k}${b?"\u{1F4C1}":"\u{1F4C4}"} ${l.name}`),b&&h<r&&m(u(o,l.name),`${k} `,h+1)}}m(s,"",1),t.tree=p.slice(0,80),p.length>80&&(t.treeTruncated=!0);let _=["README.md","README.rst","src/App.tsx","src/App.jsx","src/App.js","src/routes.tsx","src/routes.js","app/routes.tsx","app/routes.js","src/index.tsx","src/index.ts","src/main.tsx","src/main.ts","pages/_app.tsx","pages/_app.js","app/layout.tsx","docker-compose.yml","Dockerfile",".env.example"];return t.keyFilesFound=_.filter(o=>g(u(s,o))),JSON.stringify(t)}export{M as gitSkill};