@zibby/skills 0.2.21 → 0.2.23

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.d.ts CHANGED
@@ -7,4 +7,21 @@
7
7
  * Call resolve({ sessionPath, workspace }) to get a ready-to-use MCP server
8
8
  * config with session-specific args (video dir, viewport, etc.).
9
9
  */
10
+ /**
11
+ * Dev-server preview guidance — appended ONLY when the platform injected the
12
+ * preview env into this run (self-host dispatcher; absent ⇒ the fragment is
13
+ * byte-identical to the historical one). This is the ONE place the recipe
14
+ * lives: every node that binds the browser skill inherits it automatically,
15
+ * so no template author has to remember the URL shape.
16
+ *
17
+ * EXPORTED because binding the browser SKILL is not the only way a node gets a
18
+ * browser: an agent can be handed one as a custom MCP server (row data), and
19
+ * that path carries no prompt fragment at all — so the recipe never rendered
20
+ * and the agent rediscovered the URL shape by trial and error, navigating to
21
+ * localhost first (measured, 2026-08-18). A template in that position imports
22
+ * THIS function rather than restating the recipe. Env-var NAMES only —
23
+ * the token value itself never goes into a persisted prompt (security
24
+ * invariant #4); the model materializes it via Bash at use time.
25
+ */
26
+ export declare function devServerPreviewRecipe(): string;
10
27
  export declare const browserSkill: any;
package/dist/browser.js CHANGED
@@ -1,6 +1,6 @@
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.
1
+ import{createRequire as c}from"module";import{join as u}from"path";var v=c(import.meta.url);function h(){if(process.env.MCP_BROWSER_PATH)return process.env.MCP_BROWSER_PATH;try{return v.resolve("@zibby/mcp-browser/dist/bin/mcp-browser-zibby.js")}catch{return null}}var p="1280x720",b="1280x720";function d({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 w(e,r){let t=(e||[]).filter(o=>o!=="--headless");return r?[...t,"--headless"]:t}var f=`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: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.
3
+ DO NOT return success: true unless you ACTUALLY called browser tools.`;function y(){return!process.env.PREVIEW_BASE_URL||!process.env.PREVIEW_TOKEN?"":"\n\n## Previewing a server YOU start in this container (dev-server preview)\nThe browser runs in an ISOLATED container: localhost/private URLs are unreachable from it \u2014 NEVER navigate to http://localhost:<port>. To let the browser view a server you start in this run (npm run dev, vite, a mock API \u2014 anything HTTP):\n1. Start the server bound to 0.0.0.0 (e.g. `npm run dev -- --host` or `HOST=0.0.0.0`); a localhost-only bind is unreachable from outside this container.\n2. Build the preview URL from this run's injected env (Bash): `echo \"$PREVIEW_BASE_URL/<port>/?pvt=$PREVIEW_TOKEN\"` \u2014 substitute your server's actual port.\n3. Serve your app at its own ROOT and leave the URL prefix alone \u2014 do NOT set a base path for the preview (Vite `base`, Next.js `basePath`, CRA `PUBLIC_URL`). The platform routes this page's root-absolute requests (`/assets/\u2026`, `/@vite/client`, XHR) back to your server for you. Setting a base to the preview prefix makes the dev server redirect to it in a LOOP, and re-adding the prefix by hand is never needed.\n4. browser_navigate to that exact URL. The first load does a cookie handshake and redirects; after that, assets, XHR and hot-reload all work \u2014 screenshots and video too.\nThe preview lives only as long as this run. Do not put PREVIEW_TOKEN anywhere except that URL."}var R={id:"browser",serverName:"playwright",cursorKey:"playwright-official",allowedTools:["mcp__playwright__*"],sessionEnvKey:"ZIBBY_SESSION_INFO",description:"Playwright Browser MCP Server",envKeys:[],tools:[],promptFragment:()=>f+y(),resolve({sessionPath:e,workspace:r,nodeName:t,headless:o}={}){let i=h(),s=e&&t?u(e,t):null,n=s||e||r||"test-results",l=d({headless:o}),a={};if(s&&(a.ZIBBY_NODE_SESSION_PATH=s),e&&(a.ZIBBY_SESSION_PATH=e),!i)throw new Error(`@zibby/mcp-browser is not installed.
4
4
  Cloud: verify the Fargate image has it (packages/Dockerfile installs it globally alongside @zibby/cli).
5
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};
6
+ Override: set MCP_BROWSER_PATH to the path of mcp-browser-zibby.js.`);return{command:"node",args:w([i,"--isolated",`--save-video=${p}`,`--viewport-size=${b}`,`--output-dir=${n}`],l),env:a}}};export{R as browserSkill,y as devServerPreviewRecipe};
@@ -1,4 +1,4 @@
1
- import{existsSync as b}from"fs";import{fileURLToPath as S}from"url";import{dirname as v,resolve as N}from"path";import{resolveIntegrationToken as O}from"@zibby/core/backend-client.js";var k=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",LARK_DOCS:"lark_docs",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",VIKUNJA:"vikunja",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),J=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark",connectPath:"/integrations?provider=lark"},lark_docs:{id:"lark_docs",name:"Lark Docs",connectPath:"/integrations?provider=lark_docs"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},vikunja:{id:"vikunja",name:"Vikunja",connectPath:"/integrations?provider=vikunja"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},hubspot:{id:"hubspot",name:"HubSpot",connectPath:"/integrations?provider=hubspot"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});function I(){if(process.env.MCP_SLACK_PATH)return process.env.MCP_SLACK_PATH;let r=v(S(import.meta.url)),e=N(r,"..","bin","mcp-slack.mjs");return b(e)?e:null}async function d(r,e={}){let{token:t}=await O("slack"),s=["conversations.list","users.list","users.profile.get","users.lookupByEmail","usergroups.list","usergroups.users.list","conversations.history","conversations.replies"].includes(r),n=`https://slack.com/api/${r}`,a={Authorization:`Bearer ${t}`},u;if(s){let l=new URLSearchParams(e).toString();l&&(n+=`?${l}`)}else a["Content-Type"]="application/json; charset=utf-8",u=JSON.stringify(e);let i=await(await fetch(n,{method:s?"GET":"POST",headers:a,body:u})).json();if(!i.ok)throw new Error(`Slack API error: ${i.error}`);return i}var _={id:"slack",callsBackend:!0,serverName:"slack",allowedTools:["mcp__slack__*"],requiresIntegration:k.SLACK,envKeys:["SLACK_BOT_TOKEN","SLACK_TEAM_ID"],description:"Slack MCP Server",promptFragment:`## Slack
1
+ import{existsSync as b}from"fs";import{fileURLToPath as S}from"url";import{dirname as v,resolve as N}from"path";import{resolveIntegrationToken as O}from"@zibby/core/backend-client.js";var k=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",LARK_DOCS:"lark_docs",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",VIKUNJA:"vikunja",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),J=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark Chat",connectPath:"/integrations?provider=lark"},lark_docs:{id:"lark_docs",name:"Lark App",connectPath:"/integrations?provider=lark_docs"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},vikunja:{id:"vikunja",name:"Vikunja",connectPath:"/integrations?provider=vikunja"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},hubspot:{id:"hubspot",name:"HubSpot",connectPath:"/integrations?provider=hubspot"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});function I(){if(process.env.MCP_SLACK_PATH)return process.env.MCP_SLACK_PATH;let r=v(S(import.meta.url)),e=N(r,"..","bin","mcp-slack.mjs");return b(e)?e:null}async function d(r,e={}){let{token:t}=await O("slack"),s=["conversations.list","users.list","users.profile.get","users.lookupByEmail","usergroups.list","usergroups.users.list","conversations.history","conversations.replies"].includes(r),n=`https://slack.com/api/${r}`,a={Authorization:`Bearer ${t}`},u;if(s){let l=new URLSearchParams(e).toString();l&&(n+=`?${l}`)}else a["Content-Type"]="application/json; charset=utf-8",u=JSON.stringify(e);let i=await(await fetch(n,{method:s?"GET":"POST",headers:a,body:u})).json();if(!i.ok)throw new Error(`Slack API error: ${i.error}`);return i}var _={id:"slack",callsBackend:!0,serverName:"slack",allowedTools:["mcp__slack__*"],requiresIntegration:k.SLACK,envKeys:["SLACK_BOT_TOKEN","SLACK_TEAM_ID"],description:"Slack MCP Server",promptFragment:`## Slack
2
2
  You have access to the user's Slack workspace. Use these tools:
3
3
  - slack_list_channels, slack_post_message, slack_reply_to_thread
4
4
  - slack_add_reaction, slack_get_channel_history, slack_get_thread_replies
@@ -1,4 +1,4 @@
1
- import{existsSync as x}from"fs";import{fileURLToPath as J}from"url";import{dirname as D,resolve as j}from"path";import{existsSync as S}from"fs";import{fileURLToPath as b}from"url";import{dirname as N,resolve as v}from"path";import{resolveIntegrationToken as I}from"@zibby/core/backend-client.js";var g=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",LARK_DOCS:"lark_docs",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",VIKUNJA:"vikunja",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),G=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark",connectPath:"/integrations?provider=lark"},lark_docs:{id:"lark_docs",name:"Lark Docs",connectPath:"/integrations?provider=lark_docs"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},vikunja:{id:"vikunja",name:"Vikunja",connectPath:"/integrations?provider=vikunja"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},hubspot:{id:"hubspot",name:"HubSpot",connectPath:"/integrations?provider=hubspot"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});function O(){if(process.env.MCP_SLACK_PATH)return process.env.MCP_SLACK_PATH;let s=N(b(import.meta.url)),e=v(s,"..","bin","mcp-slack.mjs");return S(e)?e:null}async function _(s,e={}){let{token:t}=await I("slack"),r=["conversations.list","users.list","users.profile.get","users.lookupByEmail","usergroups.list","usergroups.users.list","conversations.history","conversations.replies"].includes(s),n=`https://slack.com/api/${s}`,a={Authorization:`Bearer ${t}`},m;if(r){let l=new URLSearchParams(e).toString();l&&(n+=`?${l}`)}else a["Content-Type"]="application/json; charset=utf-8",m=JSON.stringify(e);let i=await(await fetch(n,{method:r?"GET":"POST",headers:a,body:m})).json();if(!i.ok)throw new Error(`Slack API error: ${i.error}`);return i}var f={id:"slack",callsBackend:!0,serverName:"slack",allowedTools:["mcp__slack__*"],requiresIntegration:g.SLACK,envKeys:["SLACK_BOT_TOKEN","SLACK_TEAM_ID"],description:"Slack MCP Server",promptFragment:`## Slack
1
+ import{existsSync as x}from"fs";import{fileURLToPath as J}from"url";import{dirname as D,resolve as j}from"path";import{existsSync as S}from"fs";import{fileURLToPath as b}from"url";import{dirname as N,resolve as v}from"path";import{resolveIntegrationToken as I}from"@zibby/core/backend-client.js";var g=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",LARK_DOCS:"lark_docs",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",VIKUNJA:"vikunja",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),G=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark Chat",connectPath:"/integrations?provider=lark"},lark_docs:{id:"lark_docs",name:"Lark App",connectPath:"/integrations?provider=lark_docs"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},vikunja:{id:"vikunja",name:"Vikunja",connectPath:"/integrations?provider=vikunja"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},hubspot:{id:"hubspot",name:"HubSpot",connectPath:"/integrations?provider=hubspot"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});function O(){if(process.env.MCP_SLACK_PATH)return process.env.MCP_SLACK_PATH;let s=N(b(import.meta.url)),e=v(s,"..","bin","mcp-slack.mjs");return S(e)?e:null}async function _(s,e={}){let{token:t}=await I("slack"),r=["conversations.list","users.list","users.profile.get","users.lookupByEmail","usergroups.list","usergroups.users.list","conversations.history","conversations.replies"].includes(s),n=`https://slack.com/api/${s}`,a={Authorization:`Bearer ${t}`},m;if(r){let l=new URLSearchParams(e).toString();l&&(n+=`?${l}`)}else a["Content-Type"]="application/json; charset=utf-8",m=JSON.stringify(e);let i=await(await fetch(n,{method:r?"GET":"POST",headers:a,body:m})).json();if(!i.ok)throw new Error(`Slack API error: ${i.error}`);return i}var f={id:"slack",callsBackend:!0,serverName:"slack",allowedTools:["mcp__slack__*"],requiresIntegration:g.SLACK,envKeys:["SLACK_BOT_TOKEN","SLACK_TEAM_ID"],description:"Slack MCP Server",promptFragment:`## Slack
2
2
  You have access to the user's Slack workspace. Use these tools:
3
3
  - slack_list_channels, slack_post_message, slack_reply_to_thread
4
4
  - slack_add_reaction, slack_get_channel_history, slack_get_thread_replies
package/dist/discord.js CHANGED
@@ -1,4 +1,4 @@
1
- import{existsSync as h}from"fs";import{fileURLToPath as g}from"url";import{dirname as u,resolve as m}from"path";import{resolveIntegrationToken as _}from"@zibby/core/backend-client.js";var d=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",LARK_DOCS:"lark_docs",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",VIKUNJA:"vikunja",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),O=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark",connectPath:"/integrations?provider=lark"},lark_docs:{id:"lark_docs",name:"Lark Docs",connectPath:"/integrations?provider=lark_docs"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},vikunja:{id:"vikunja",name:"Vikunja",connectPath:"/integrations?provider=vikunja"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},hubspot:{id:"hubspot",name:"HubSpot",connectPath:"/integrations?provider=hubspot"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});function I(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let t=u(g(import.meta.url)),e=m(t,"..","bin","mcp-skill.mjs");return h(e)?e:null}var v=process.env.DISCORD_API_URL||"https://discord.com/api/v10",k=2e3;function D(t,e=k){let n=String(t??"");if(!n.trim())return[];if(n.length<=e)return[n];let r=[],o=n;for(;o.length>e;){let i=o.slice(0,e).lastIndexOf(`
1
+ import{existsSync as h}from"fs";import{fileURLToPath as g}from"url";import{dirname as u,resolve as m}from"path";import{resolveIntegrationToken as _}from"@zibby/core/backend-client.js";var d=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",LARK_DOCS:"lark_docs",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",VIKUNJA:"vikunja",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),O=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark Chat",connectPath:"/integrations?provider=lark"},lark_docs:{id:"lark_docs",name:"Lark App",connectPath:"/integrations?provider=lark_docs"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},vikunja:{id:"vikunja",name:"Vikunja",connectPath:"/integrations?provider=vikunja"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},hubspot:{id:"hubspot",name:"HubSpot",connectPath:"/integrations?provider=hubspot"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});function I(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let t=u(g(import.meta.url)),e=m(t,"..","bin","mcp-skill.mjs");return h(e)?e:null}var v=process.env.DISCORD_API_URL||"https://discord.com/api/v10",k=2e3;function D(t,e=k){let n=String(t??"");if(!n.trim())return[];if(n.length<=e)return[n];let r=[],o=n;for(;o.length>e;){let i=o.slice(0,e).lastIndexOf(`
2
2
  `),a=i>e/2?i+1:e;r.push(o.slice(0,a)),o=o.slice(a)}return o&&r.push(o),r}async function p(){let t=(process.env.DISCORD_BOT_TOKEN||"").trim();if(t)return{token:t,guildId:(process.env.DISCORD_GUILD_ID||"").trim()};let e=await _(d.DISCORD),n=(e&&e.token?String(e.token):"").trim();if(!n)throw new Error("Discord is not connected: connect Discord in the Zibby dashboard or set DISCORD_BOT_TOKEN.");return{token:n,guildId:(e.guildId||"").trim()}}async function l(t,e,{token:n,body:r}={}){let o=n.startsWith("Bot ")?n:`Bot ${n}`,s=await fetch(`${v}${e}`,{method:t,headers:{Authorization:o,...r!==void 0?{"Content-Type":"application/json"}:{}},...r!==void 0?{body:JSON.stringify(r)}:{}}),i=await s.json().catch(()=>null);if(!s.ok){let a=i&&(i.message||i.error)?i.message||i.error:`HTTP ${s.status}`;throw new Error(`Discord API error (${s.status}): ${a}`)}return i}async function f({token:t,guildId:e},n){let r=String(n||"").trim()||e||(process.env.DISCORD_GUILD_ID||"").trim();if(r)return r;let o=await l("GET","/users/@me/guilds",{token:t}),s=Array.isArray(o)?o:[];if(s.length===1)return s[0].id;if(s.length===0)throw new Error("The bot is not in any Discord server \u2014 invite it to a server first.");let i=s.slice(0,10).map(a=>`${a.name} (${a.id})`).join(", ");throw new Error(`The bot is in ${s.length} servers \u2014 pass guildId explicitly. Servers: ${i}`)}var A={id:"discord",callsBackend:!0,serverName:"discord",allowedTools:["mcp__discord__*"],requiresIntegration:d.DISCORD,envKeys:["DISCORD_BOT_TOKEN","DISCORD_GUILD_ID"],description:"Discord bot tools (send messages, list channels)",promptFragment:`## Discord
3
3
  You can post to the user's Discord server as their bot. Tools:
4
4
  - discord_send_message(channelId, text) \u2014 post a message to a channel (long text is auto-chunked to Discord's 2000-char limit)
package/dist/figma.js CHANGED
@@ -1,4 +1,4 @@
1
- import{existsSync as b}from"fs";import{fileURLToPath as S}from"url";import{dirname as k,resolve as N}from"path";import{resolveIntegrationToken as O}from"@zibby/core/backend-client.js";var h=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",LARK_DOCS:"lark_docs",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",VIKUNJA:"vikunja",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),A=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark",connectPath:"/integrations?provider=lark"},lark_docs:{id:"lark_docs",name:"Lark Docs",connectPath:"/integrations?provider=lark_docs"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},vikunja:{id:"vikunja",name:"Vikunja",connectPath:"/integrations?provider=vikunja"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},hubspot:{id:"hubspot",name:"HubSpot",connectPath:"/integrations?provider=hubspot"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});function L(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let e=k(S(import.meta.url)),n=N(e,"..","bin","mcp-skill.mjs");return b(n)?n:null}async function f(e,n={}){let{token:i}=await O("figma"),o=e.startsWith("https://")?e:`https://api.figma.com${e}`,s={"X-Figma-Token":i,Accept:"application/json",...n.body?{"Content-Type":"application/json"}:{}},r=await fetch(o,{method:n.method||"GET",headers:s,body:n.body?JSON.stringify(n.body):void 0});if(!r.ok){let a=await r.text().catch(()=>"");throw new Error(`Figma API ${r.status}: ${a.slice(0,300)}`)}return r.json()}function g(e){let n=String(e||"").trim(),i=n.match(/figma\.com\/(?:file|design|board|proto)\/([A-Za-z0-9]+)/i);return i?i[1]:n}function u(e){return e==null?void 0:(Array.isArray(e)?e:String(e).split(",")).map(i=>String(i).trim().replace(/-/g,":")).filter(Boolean).join(",")}function I(e){let n=String(e||"").match(/[?&]node-id=([^&]+)/i);return n?decodeURIComponent(n[1]).replace(/-/g,":"):void 0}var p=e=>typeof e=="number"?Math.round(e*100)/100:e;function _(e){if(!e)return null;let n=o=>Math.round((o??0)*255).toString(16).padStart(2,"0"),i={hex:`#${n(e.r)}${n(e.g)}${n(e.b)}`.toUpperCase()};return e.a!=null&&e.a<1&&(i.opacity=p(e.a)),i}function v(e){return!e||e.visible===!1?null:e.type==="SOLID"?{type:"SOLID",..._(e.color),...e.opacity!=null?{opacity:e.opacity}:{}}:{type:e.type,...e.opacity!=null?{opacity:e.opacity}:{},...e.gradientStops?{stops:e.gradientStops.map(n=>({position:p(n.position),..._(n.color)}))}:{}}}function R(e,n){let i=e.absoluteBoundingBox,o={id:e.id,name:e.name,type:e.type};i&&(o.size={w:p(i.width),h:p(i.height)},o.position={x:p(i.x),y:p(i.y)}),e.opacity!=null&&e.opacity!==1&&(o.opacity=e.opacity),e.cornerRadius!=null&&(o.cornerRadius=e.cornerRadius),Array.isArray(e.rectangleCornerRadii)&&(o.cornerRadii=e.rectangleCornerRadii);let s=(e.fills||[]).map(v).filter(Boolean);s.length&&(o.fills=s);let r=(e.strokes||[]).map(v).filter(Boolean);r.length&&(o.strokes=r,e.strokeWeight!=null&&(o.strokeWeight=e.strokeWeight));let a=(e.effects||[]).filter(t=>t.visible!==!1).map(t=>({type:t.type,...t.radius!=null?{radius:t.radius}:{},...t.offset?{offset:{x:p(t.offset.x),y:p(t.offset.y)}}:{},...t.spread?{spread:t.spread}:{},...t.color?_(t.color):{}}));if(a.length&&(o.effects=a),e.layoutMode&&e.layoutMode!=="NONE"&&(o.autoLayout={direction:e.layoutMode,padding:{l:e.paddingLeft??0,r:e.paddingRight??0,t:e.paddingTop??0,b:e.paddingBottom??0},gap:e.itemSpacing??0,align:{primary:e.primaryAxisAlignItems,counter:e.counterAxisAlignItems}}),e.type==="TEXT"){let t=e.style||{};o.text=e.characters,o.textStyle={fontFamily:t.fontFamily,fontWeight:t.fontWeight,fontSize:t.fontSize,lineHeightPx:t.lineHeightPx!=null?p(t.lineHeightPx):void 0,letterSpacing:t.letterSpacing!=null?p(t.letterSpacing):void 0,align:t.textAlignHorizontal,case:t.textCase}}return n>0&&Array.isArray(e.children)&&e.children.length&&(o.children=e.children.map(t=>R(t,n-1))),o}var F={id:"figma",callsBackend:!0,serverName:"figma",allowedTools:["mcp__figma__*"],requiresIntegration:h.FIGMA,envKeys:["PROJECT_API_TOKEN","ZIBBY_ACCOUNT_API_URL","ZIBBY_ENV"],description:"Figma \u2014 read files, nodes and comments; extract dev-handoff specs (sizes/colors/fonts/auto-layout); list versions and image fills; render frames to PNG/JPG/SVG/PDF; browse team projects/files; and post comments",promptFragment:`## Figma
1
+ import{existsSync as b}from"fs";import{fileURLToPath as S}from"url";import{dirname as k,resolve as N}from"path";import{resolveIntegrationToken as O}from"@zibby/core/backend-client.js";var h=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",LARK_DOCS:"lark_docs",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",VIKUNJA:"vikunja",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),A=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark Chat",connectPath:"/integrations?provider=lark"},lark_docs:{id:"lark_docs",name:"Lark App",connectPath:"/integrations?provider=lark_docs"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},vikunja:{id:"vikunja",name:"Vikunja",connectPath:"/integrations?provider=vikunja"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},hubspot:{id:"hubspot",name:"HubSpot",connectPath:"/integrations?provider=hubspot"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});function L(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let e=k(S(import.meta.url)),n=N(e,"..","bin","mcp-skill.mjs");return b(n)?n:null}async function f(e,n={}){let{token:i}=await O("figma"),o=e.startsWith("https://")?e:`https://api.figma.com${e}`,s={"X-Figma-Token":i,Accept:"application/json",...n.body?{"Content-Type":"application/json"}:{}},r=await fetch(o,{method:n.method||"GET",headers:s,body:n.body?JSON.stringify(n.body):void 0});if(!r.ok){let a=await r.text().catch(()=>"");throw new Error(`Figma API ${r.status}: ${a.slice(0,300)}`)}return r.json()}function g(e){let n=String(e||"").trim(),i=n.match(/figma\.com\/(?:file|design|board|proto)\/([A-Za-z0-9]+)/i);return i?i[1]:n}function u(e){return e==null?void 0:(Array.isArray(e)?e:String(e).split(",")).map(i=>String(i).trim().replace(/-/g,":")).filter(Boolean).join(",")}function I(e){let n=String(e||"").match(/[?&]node-id=([^&]+)/i);return n?decodeURIComponent(n[1]).replace(/-/g,":"):void 0}var p=e=>typeof e=="number"?Math.round(e*100)/100:e;function _(e){if(!e)return null;let n=o=>Math.round((o??0)*255).toString(16).padStart(2,"0"),i={hex:`#${n(e.r)}${n(e.g)}${n(e.b)}`.toUpperCase()};return e.a!=null&&e.a<1&&(i.opacity=p(e.a)),i}function v(e){return!e||e.visible===!1?null:e.type==="SOLID"?{type:"SOLID",..._(e.color),...e.opacity!=null?{opacity:e.opacity}:{}}:{type:e.type,...e.opacity!=null?{opacity:e.opacity}:{},...e.gradientStops?{stops:e.gradientStops.map(n=>({position:p(n.position),..._(n.color)}))}:{}}}function R(e,n){let i=e.absoluteBoundingBox,o={id:e.id,name:e.name,type:e.type};i&&(o.size={w:p(i.width),h:p(i.height)},o.position={x:p(i.x),y:p(i.y)}),e.opacity!=null&&e.opacity!==1&&(o.opacity=e.opacity),e.cornerRadius!=null&&(o.cornerRadius=e.cornerRadius),Array.isArray(e.rectangleCornerRadii)&&(o.cornerRadii=e.rectangleCornerRadii);let s=(e.fills||[]).map(v).filter(Boolean);s.length&&(o.fills=s);let r=(e.strokes||[]).map(v).filter(Boolean);r.length&&(o.strokes=r,e.strokeWeight!=null&&(o.strokeWeight=e.strokeWeight));let a=(e.effects||[]).filter(t=>t.visible!==!1).map(t=>({type:t.type,...t.radius!=null?{radius:t.radius}:{},...t.offset?{offset:{x:p(t.offset.x),y:p(t.offset.y)}}:{},...t.spread?{spread:t.spread}:{},...t.color?_(t.color):{}}));if(a.length&&(o.effects=a),e.layoutMode&&e.layoutMode!=="NONE"&&(o.autoLayout={direction:e.layoutMode,padding:{l:e.paddingLeft??0,r:e.paddingRight??0,t:e.paddingTop??0,b:e.paddingBottom??0},gap:e.itemSpacing??0,align:{primary:e.primaryAxisAlignItems,counter:e.counterAxisAlignItems}}),e.type==="TEXT"){let t=e.style||{};o.text=e.characters,o.textStyle={fontFamily:t.fontFamily,fontWeight:t.fontWeight,fontSize:t.fontSize,lineHeightPx:t.lineHeightPx!=null?p(t.lineHeightPx):void 0,letterSpacing:t.letterSpacing!=null?p(t.letterSpacing):void 0,align:t.textAlignHorizontal,case:t.textCase}}return n>0&&Array.isArray(e.children)&&e.children.length&&(o.children=e.children.map(t=>R(t,n-1))),o}var F={id:"figma",callsBackend:!0,serverName:"figma",allowedTools:["mcp__figma__*"],requiresIntegration:h.FIGMA,envKeys:["PROJECT_API_TOKEN","ZIBBY_ACCOUNT_API_URL","ZIBBY_ENV"],description:"Figma \u2014 read files, nodes and comments; extract dev-handoff specs (sizes/colors/fonts/auto-layout); list versions and image fills; render frames to PNG/JPG/SVG/PDF; browse team projects/files; and post comments",promptFragment:`## Figma
2
2
  You have access to the user's Figma files via the Figma REST API. Every tool that takes a file accepts EITHER the raw file key OR a full figma.com URL (figma.com/file|design/<key>/...). Node ids accept URL form \`1-23\` or API form \`1:23\` interchangeably. Tools:
3
3
 
4
4
  ### Identity