@beepflow/mcp 2026.4.4 → 2026.4.7

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.
Files changed (3) hide show
  1. package/README.md +14 -12
  2. package/dist/index.js +57 -5
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -15,21 +15,23 @@ claude mcp add beepflow -- npx -y @beepflow/mcp
15
15
  ```
16
16
 
17
17
  ### OpenCode
18
- Add to `opencode.json` (or `opencode.jsonc`):
19
- ```json
20
- {
21
- "$schema": "https://opencode.ai/config.json",
22
- "mcp": {
23
- "beepflow": {
24
- "type": "local",
25
- "command": ["npx", "-y", "@beepflow/mcp"],
26
- "enabled": true
27
- }
28
- }
29
- }
18
+ ```sh
19
+ opencode mcp add
30
20
  ```
21
+ Follow prompts: name `beepflow`, server type `local`, command `npx -y @beepflow/mcp`.
31
22
 
32
23
  ### Gemini CLI
33
24
  ```sh
34
25
  gemini mcp add beepflow npx -y @beepflow/mcp
35
26
  ```
27
+
28
+ ## Resource Schemas
29
+
30
+ The server exposes item schemas for every resource:
31
+
32
+ ```text
33
+ beepflow://resource-schemas
34
+ beepflow://resource-schemas/<resource>
35
+ ```
36
+
37
+ Use `resource_schema_get` before constructing `resource_upsert` items unless editing an item already read from the same resource. Upserts send whole item state, not JSON patches.
package/dist/index.js CHANGED
@@ -1,6 +1,58 @@
1
1
  #!/usr/bin/env node
2
- import{stdin as k,stdout as R}from"node:process";function U(e){let t=new Map;for(let p of e.tools)t.set(p.name,p);let n=!1,o="",s={start:()=>{k.setEncoding("utf8"),k.on("data",p=>c(typeof p=="string"?p:p.toString("utf8"))),k.on("end",()=>r("stdin-end")),k.on("error",()=>r("stdin-error"))}};function r(p){if(!n){n=!0;try{R.write(JSON.stringify({jsonrpc:"2.0",method:"notifications/message",params:{level:"info",data:`server closing: ${p}`}})+`
3
- `)}catch{}}}function c(p){for(o+=p;;){let d=o.indexOf(`
4
- `);if(d===-1)return;let u=o.slice(0,d).trim();if(o=o.slice(d+1),!u)continue;let f;try{f=JSON.parse(u)}catch{continue}i(f)}}async function i(p){if(n)return;let d=p.id===void 0,u=p.id??null;try{switch(p.method){case"initialize":{let h={protocolVersion:(p.params??{}).protocolVersion??"2024-11-05",serverInfo:{name:e.serverName,version:e.serverVersion},capabilities:{tools:{}}};if(d)return;a({jsonrpc:"2.0",id:u,result:h});return}case"notifications/initialized":return;case"notifications/cancelled":return;case"logging/setLevel":{if(d)return;a({jsonrpc:"2.0",id:u,result:{}});return}case"ping":{if(d)return;a({jsonrpc:"2.0",id:u,result:{}});return}case"tools/list":{if(d)return;let f=e.tools.map(m=>({name:m.name,description:m.description,inputSchema:m.inputSchema}));a({jsonrpc:"2.0",id:u,result:{tools:f}});return}case"tools/call":{if(d)return;let f=p.params??{},m=typeof f.name=="string"?f.name:"",h=t.get(m);if(!h){a({jsonrpc:"2.0",id:u,error:{code:-32601,message:`unknown tool: ${m}`}});return}let G=await h.call(f.arguments);a({jsonrpc:"2.0",id:u,result:G});return}case"resources/list":{if(d)return;a({jsonrpc:"2.0",id:u,result:{resources:[]}});return}case"prompts/list":{if(d)return;a({jsonrpc:"2.0",id:u,result:{prompts:[]}});return}default:{if(d)return;a({jsonrpc:"2.0",id:u,error:{code:-32601,message:`method not found: ${p.method}`}})}}}catch(f){if(d)return;a({jsonrpc:"2.0",id:u,error:{code:-32603,message:f?.message??"internal error"}})}}function a(p){n||R.write(JSON.stringify(p)+`
5
- `)}return{server:s,closeServer:r}}import H from"node:os";import b from"node:path";var V={dev:{name:"dev",workspaceUrl:"http://localhost:2451/api",authUrl:"https://auth.fewlogs.com",authDomain:"beepflow.com"},live:{name:"live",workspaceUrl:"https://beepflow.com/api",authUrl:"https://auth.fewlogs.com",authDomain:"beepflow.com"}};function z(e){let n=W(e,"--env")??W(e,"--environment")??process.env.BEEPFLOW_ENV??"live";if(n==="dev"||n==="live")return n;throw new Error(`invalid BEEPFLOW_ENV: ${n}`)}function B(e){let t=z(e);return V[t]}function W(e,t){for(let n=0;n<e.length;n+=1){let o=e[n];if(o===t){let r=e[n+1];if(!r)throw new Error(`missing value for ${t}`);return r}let s=`${t}=`;if(o&&o.startsWith(s)){let r=o.slice(s.length);if(!r)throw new Error(`missing value for ${t}`);return r}}}function l(){let e=process.argv.slice(2),t=B(e),n=E("workspace url",[w(e,"--workspace-url"),process.env.BEEPFLOW_WORKSPACE_URL,t.workspaceUrl]),o=E("auth url",[w(e,"--auth-url"),process.env.BEEPFLOW_AUTH_URL,t.authUrl]),s=E("auth domain",[w(e,"--auth-domain"),process.env.BEEPFLOW_AUTH_DOMAIN,t.authDomain]),r=w(e,"--token-store-path")??process.env.BEEPFLOW_TOKEN_STORE_PATH??Q();return{environmentName:t.name,workspaceUrl:n.replace(/\/+$/,""),authUrl:o.replace(/\/+$/,""),authDomain:s,jwtFromEnvironment:w(e,"--jwt")??process.env.BEEPFLOW_JWT,tokenStorePath:r}}function w(e,t){for(let n=0;n<e.length;n+=1){let o=e[n];if(o===t){let r=e[n+1];if(!r)throw new Error(`missing value for ${t}`);return r}let s=`${t}=`;if(o&&o.startsWith(s)){let r=o.slice(s.length);if(!r)throw new Error(`missing value for ${t}`);return r}}}function Q(){let e=process.env.APPDATA;if(e)return b.join(e,"beepflow-mcp","workspace-access-tokens.json");let t=process.env.XDG_CONFIG_HOME;return t?b.join(t,"beepflow-mcp","workspace-access-tokens.json"):b.join(H.homedir(),".config","beepflow-mcp","workspace-access-tokens.json")}function E(e,t){for(let n of t)if(typeof n=="string"&&n.trim())return n;throw new Error(`missing ${e}`)}import x from"node:fs/promises";import Y from"node:path";import K from"node:crypto";function y(e){let t=e.split(".");if(t.length<2)return{accessToken:e,email:void 0,exp:void 0,provider:void 0};let n=X(t[1]??"");if(!n)return{accessToken:e,email:void 0,exp:void 0,provider:void 0};let o;try{o=JSON.parse(n)}catch{return{accessToken:e,email:void 0,exp:void 0,provider:void 0}}let s=typeof o.email=="string"?o.email.toLowerCase():void 0,r=typeof o.exp=="number"?o.exp:void 0,c=typeof o.provider=="string"?o.provider:void 0;return{accessToken:e,email:s,exp:r,provider:c}}function P(e){return e?e.length<=12?`${e.slice(0,4)}\u2026`:`${e.slice(0,6)}\u2026${e.slice(-4)}`:""}function j(){return K.randomBytes(9).toString("base64url")}function X(e){if(!e)return;let t=e.replace(/-/g,"+").replace(/_/g,"/"),n=(4-t.length%4)%4,o=t+"=".repeat(n);try{return Buffer.from(o,"base64").toString("utf8")}catch{return}}async function J(){let e=l();return e.jwtFromEnvironment?e.jwtFromEnvironment:(await Z(e.tokenStorePath,e.workspaceUrl))?.accessToken}async function g(e){let t=l(),n=y(e),o={accessToken:e,email:n.email,provider:n.provider,exp:n.exp};return await ee(t.tokenStorePath,t.workspaceUrl,o),o}async function _(){let e=l(),t=await T(e.tokenStorePath),n=t[e.workspaceUrl]!==void 0;return delete t[e.workspaceUrl],await $(e.tokenStorePath,t),{workspaceUrl:e.workspaceUrl,deleted:n}}function v(e){return{email:e.email,provider:e.provider,exp:e.exp,accessToken:P(e.accessToken)}}async function Z(e,t){return(await T(e))[t]}async function ee(e,t,n){let o=await T(e);o[t]=n,await $(e,o)}async function T(e){try{let t=await x.readFile(e,"utf8"),n=JSON.parse(t);return!n||typeof n!="object"?{}:n}catch{return{}}}async function $(e,t){await x.mkdir(Y.dirname(e),{recursive:!0}),await x.writeFile(e,JSON.stringify(t,null,2)+`
6
- `,"utf8")}async function O(e){let t=l(),n=await fetch(`${t.authUrl}/email/request-code`,{method:"POST",headers:{"content-type":"application/json",domain:t.authDomain},body:JSON.stringify({email:e})});if(!n.ok){let o=await n.text().catch(()=>"");throw new Error(`email/request-code failed: ${n.status} ${o}`.trim())}}async function I(e,t){let n=l(),o=await fetch(`${n.authUrl}/email/verify-code`,{method:"POST",headers:{"content-type":"application/json",domain:n.authDomain},body:JSON.stringify({email:e,code:t})}),s=await o.json().catch(()=>{});if(!o.ok)throw new Error(`email/verify-code failed: ${o.status}`);let r=typeof s?.access_token=="string"?s.access_token:"";if(!r)throw new Error("email/verify-code failed: missing access_token");let c=await g(r);return{workspaceUrl:n.workspaceUrl,...v(c)}}import te from"node:crypto";async function A(e){let t=l(),n=te.randomUUID(),o=new URL(`${t.authUrl}/google-form`);return o.searchParams.set("requestId",n),o.searchParams.set("scopes",e),{requestId:n,url:o.toString()}}async function C(e){let t=l(),n=new URL(`${t.authUrl}/google-auth-token`);n.searchParams.set("id",e);let o=await fetch(n.toString(),{headers:{domain:t.authDomain}}),s=await o.json().catch(()=>{});if(!o.ok)throw new Error(`google-auth-token failed: ${o.status}`);let r=typeof s?.access_token=="string"?s.access_token:"";if(!r)throw new Error("google-auth-token failed: missing access_token");let c=await g(r);return{workspaceUrl:t.workspaceUrl,...v(c)}}async function N(e){let t=l(),n=await fetch(`${t.workspaceUrl}/users/is-member`,{method:"GET",headers:{Authorization:`Bearer ${e}`}});if(!n.ok){let s=await n.text().catch(()=>"");throw new Error(`users/is-member failed: ${n.status} ${s}`.trim())}if((await n.json().catch(()=>{}))?.isMember!==!0)throw new Error("user not member of workspace")}async function M(e){let t=y(e);if(t.provider!=="google"||!t.exp)return e;let n=Date.now(),o=t.exp*1e3,s=300*1e3;if(o-n>=s)return e;let r=l(),c=await fetch(`${r.authUrl}/google-refresh`,{method:"GET",headers:{Authorization:`Bearer ${e}`}}),i=await c.json().catch(()=>{});if(!c.ok)return e;let a=typeof i?.access_token=="string"?i.access_token:"";return a?(await g(a),a):e}async function q(e,t,n,o,s){let r=l(),c=ne(r.workspaceUrl,e,t),i=await re(c,s);try{let a={resource:n,action:"snapshot",value:o};return i.send(oe("replicated-state",JSON.stringify(a))),await se(i,n,s)}finally{i.close()}}function ne(e,t,n){let o=e.replace(/^http/,"ws"),s=encodeURIComponent(t),r=encodeURIComponent(n);return`${o}/base/${s}/${r}`}function oe(e,t){return`${e};${t}`}async function re(e,t){let n=new WebSocket(e,"echo"),o=await new Promise(s=>{let r=setTimeout(()=>s({ok:!1,reason:"timeout"}),t);n.onopen=()=>{clearTimeout(r),s({ok:!0})},n.onerror=()=>{clearTimeout(r),s({ok:!1,reason:"error"})}});if(!o.ok)throw n.close(),new Error(`websocket open failed: ${o.reason??"unknown"}`);return n}async function se(e,t,n){return await new Promise((o,s)=>{let r=setTimeout(()=>s(new Error("snapshot timeout")),n);e.onerror=()=>{clearTimeout(r),s(new Error("websocket error during snapshot wait"))},e.onclose=()=>{clearTimeout(r),s(new Error("websocket closed during snapshot wait"))},e.onmessage=c=>{let i=typeof c.data=="string"?c.data:"",a=i.indexOf(";");if(a===-1||i.slice(0,a)!=="replicated-state")return;let d=i.slice(a+1),u;try{u=JSON.parse(d)}catch{return}u.action==="snapshot"&&u.resource===t&&(!u.value||typeof u.value!="object"||(clearTimeout(r),o(u.value)))}})}async function D(){let e=await J();if(!e)throw new Error("missing jwt: set BEEPFLOW_JWT or run auth tool to persist token");let t=await M(e);await N(t);let n=j(),o=await q(t,n,"spaces",{all:!0},15e3),s=[];for(let r in o){let c=o[r];if(!c||typeof c!="object")continue;let i=c,a=i.id;if(typeof a!="string"||!a)continue;let p={id:a,updatedAt:typeof i.updatedAt=="number"?i.updatedAt:void 0,label:typeof i.label=="string"?i.label:void 0,thumbnailUrl:typeof i.thumbnailUrl=="string"?i.thumbnailUrl:void 0,description:typeof i.description=="string"?i.description:void 0,isUserSpace:typeof i.isUserSpace=="boolean"?i.isUserSpace:void 0};s.push(p)}return s.sort((r,c)=>{let i=(r.label??"").toLowerCase(),a=(c.label??"").toLowerCase();return i<a?-1:i>a?1:r.id<c.id?-1:r.id>c.id?1:0}),s}function L(){return[{name:"spaces_list",description:"List authorized Beepflow spaces for current JWT.",inputSchema:{type:"object",additionalProperties:!1,properties:{}},call:async()=>{let e=await D();return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}},{name:"auth_email_request_code",description:"Request email login code via Beepflow auth service.",inputSchema:{type:"object",additionalProperties:!1,required:["email"],properties:{email:{type:"string"}}},call:async e=>{let t=S(e,"email");return await O(t),{content:[{type:"text",text:`code sent to ${t}`}]}}},{name:"auth_email_verify_code",description:"Verify email login code, persist JWT for workspace.",inputSchema:{type:"object",additionalProperties:!1,required:["email","code"],properties:{email:{type:"string"},code:{type:"string"}}},call:async e=>{let t=S(e,"email"),n=S(e,"code"),o=await I(t,n);return{content:[{type:"text",text:JSON.stringify(o,null,2)}]}}},{name:"auth_google_start",description:"Create Google OAuth login URL + request id.",inputSchema:{type:"object",additionalProperties:!1,properties:{scopes:{type:"string"}}},call:async e=>{let t=ie(e,"scopes")??"openid email profile",n=await A(t);return{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}},{name:"auth_google_get_token",description:"Fetch Google OAuth token using request id, persist JWT for workspace.",inputSchema:{type:"object",additionalProperties:!1,required:["requestId"],properties:{requestId:{type:"string"}}},call:async e=>{let t=S(e,"requestId"),n=await C(t);return{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}},{name:"auth_sign_out",description:"Delete stored JWT for current workspace.",inputSchema:{type:"object",additionalProperties:!1,properties:{}},call:async()=>{let e=await _();return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}}]}function S(e,t){if(!e||typeof e!="object")throw new Error("invalid tool arguments: expected object");let o=e[t];if(typeof o!="string"||!o.trim())throw new Error(`invalid tool arguments: ${t} must be non-empty string`);return o}function ie(e,t){if(e===void 0)return;if(!e||typeof e!="object")throw new Error("invalid tool arguments: expected object");let o=e[t];if(o!=null){if(typeof o!="string")throw new Error(`invalid tool arguments: ${t} must be string`);return o}}var{server:ae,closeServer:F}=U({serverName:"mcp",serverVersion:"0.1.0",tools:L()});process.on("SIGINT",()=>F("SIGINT"));process.on("SIGTERM",()=>F("SIGTERM"));ae.start();
2
+ import{stdin as ne,stdout as Le}from"node:process";function ze(t){let e=new Map;for(let p of t.tools)e.set(p.name,p);let n=new Map;for(let p of t.resources??[])n.set(p.uri,p);let r=!1,o="",i={start:()=>{ne.setEncoding("utf8"),ne.on("data",p=>c(typeof p=="string"?p:p.toString("utf8"))),ne.on("end",()=>s("stdin-end")),ne.on("error",()=>s("stdin-error"))}};function s(p){if(!r){r=!0;try{Le.write(JSON.stringify({jsonrpc:"2.0",method:"notifications/message",params:{level:"info",data:`server closing: ${p}`}})+`
3
+ `)}catch{}}}function c(p){for(o+=p;;){let y=o.indexOf(`
4
+ `);if(y===-1)return;let m=o.slice(0,y).trim();if(o=o.slice(y+1),!m)continue;let b;try{b=JSON.parse(m)}catch{continue}u(b)}}async function u(p){if(r)return;let y=p.id===void 0,m=p.id??null;try{switch(p.method){case"initialize":{let W={protocolVersion:(p.params??{}).protocolVersion??"2024-11-05",serverInfo:{name:t.serverName,version:t.serverVersion},capabilities:{tools:{},resources:{}},...t.instructions?{instructions:t.instructions}:{}};if(y)return;d({jsonrpc:"2.0",id:m,result:W});return}case"notifications/initialized":{t.onInitialized?.();return}case"notifications/cancelled":return;case"logging/setLevel":{if(y)return;d({jsonrpc:"2.0",id:m,result:{}});return}case"ping":{if(y)return;d({jsonrpc:"2.0",id:m,result:{}});return}case"tools/list":{if(y)return;let b=t.tools.map(S=>({name:S.name,description:S.description,inputSchema:S.inputSchema}));d({jsonrpc:"2.0",id:m,result:{tools:b}});return}case"tools/call":{if(y)return;let b=p.params??{},S=typeof b.name=="string"?b.name:"",W=e.get(S);if(!W){d({jsonrpc:"2.0",id:m,error:{code:-32601,message:`unknown tool: ${S}`}});return}let be=await W.call(b.arguments);d({jsonrpc:"2.0",id:m,result:be});return}case"resources/list":{if(y)return;let b=(t.resources??[]).map(S=>({uri:S.uri,name:S.name,description:S.description,mimeType:S.mimeType}));d({jsonrpc:"2.0",id:m,result:{resources:b}});return}case"resources/read":{if(y)return;let b=p.params??{},S=typeof b.uri=="string"?b.uri:"",W=n.get(S);if(!W){d({jsonrpc:"2.0",id:m,error:{code:-32602,message:`unknown resource: ${S}`}});return}let be=await W.read();d({jsonrpc:"2.0",id:m,result:be});return}case"prompts/list":{if(y)return;d({jsonrpc:"2.0",id:m,result:{prompts:[]}});return}default:{if(y)return;d({jsonrpc:"2.0",id:m,error:{code:-32601,message:`method not found: ${p.method}`}})}}}catch(b){if(y)return;d({jsonrpc:"2.0",id:m,error:{code:-32603,message:b?.message??"internal error"}})}}function d(p){r||Le.write(JSON.stringify(p)+`
5
+ `)}return{server:i,closeServer:s}}import{createHash as hr}from"node:crypto";import Ve from"node:os";import G from"node:path";var Gt={dev:{name:"dev",workspaceUrl:"http://localhost:2451/api",authUrl:"https://auth.fewlogs.com",authDomain:"beepflow.com"},live:{name:"live",workspaceUrl:"https://beepflow.com/api",authUrl:"https://auth.fewlogs.com",authDomain:"beepflow.com"}};function Qt(t){let n=Ge(t,"--env")??Ge(t,"--environment")??process.env.BEEPFLOW_ENV??"live";if(n==="dev"||n==="live")return n;throw new Error(`invalid BEEPFLOW_ENV: ${n}`)}function Qe(t){let e=Qt(t);return Gt[e]}function Ge(t,e){for(let n=0;n<t.length;n+=1){let r=t[n];if(r===e){let i=t[n+1];if(!i)throw new Error(`missing value for ${e}`);return i}let o=`${e}=`;if(r&&r.startsWith(o)){let i=r.slice(o.length);if(!i)throw new Error(`missing value for ${e}`);return i}}}function w(){let t=process.argv.slice(2),e=Qe(t),n=Re("workspace url",[z(t,"--workspace-url"),process.env.BEEPFLOW_WORKSPACE_URL,e.workspaceUrl]),r=Re("auth url",[z(t,"--auth-url"),process.env.BEEPFLOW_AUTH_URL,e.authUrl]),o=Re("auth domain",[z(t,"--auth-domain"),process.env.BEEPFLOW_AUTH_DOMAIN,e.authDomain]),i=z(t,"--token-store-path")??process.env.BEEPFLOW_TOKEN_STORE_PATH??Vt(),s=z(t,"--replicated-state-db-path")??process.env.BEEPFLOW_REPLICATED_STATE_DB_PATH??Kt();return{environmentName:e.name,workspaceUrl:n.replace(/\/+$/,""),authUrl:r.replace(/\/+$/,""),authDomain:o,jwtFromEnvironment:z(t,"--jwt")??process.env.BEEPFLOW_JWT,tokenStorePath:i,replicatedStateDatabasePath:s}}function z(t,e){for(let n=0;n<t.length;n+=1){let r=t[n];if(r===e){let i=t[n+1];if(!i)throw new Error(`missing value for ${e}`);return i}let o=`${e}=`;if(r&&r.startsWith(o)){let i=r.slice(o.length);if(!i)throw new Error(`missing value for ${e}`);return i}}}function Vt(){let t=process.env.APPDATA;if(t)return G.join(t,"beepflow-mcp","workspace-access-tokens.json");let e=process.env.XDG_CONFIG_HOME;return e?G.join(e,"beepflow-mcp","workspace-access-tokens.json"):G.join(Ve.homedir(),".config","beepflow-mcp","workspace-access-tokens.json")}function Kt(){let t=process.env.LOCALAPPDATA;if(t)return G.join(t,"beepflow-mcp","replicated-state.sqlite");let e=process.env.XDG_CACHE_HOME;return e?G.join(e,"beepflow-mcp","replicated-state.sqlite"):G.join(Ve.homedir(),".cache","beepflow-mcp","replicated-state.sqlite")}function Re(t,e){for(let n of e)if(typeof n=="string"&&n.trim())return n;throw new Error(`missing ${t}`)}import Se from"node:fs/promises";import Xt from"node:path";import Ht from"node:crypto";function C(t){let e=t.split(".");if(e.length<2)return{accessToken:t,email:void 0,exp:void 0,provider:void 0};let n=Zt(e[1]??"");if(!n)return{accessToken:t,email:void 0,exp:void 0,provider:void 0};let r;try{r=JSON.parse(n)}catch{return{accessToken:t,email:void 0,exp:void 0,provider:void 0}}let o=typeof r.email=="string"?r.email.toLowerCase():void 0,i=typeof r.exp=="number"?r.exp:void 0,s=typeof r.provider=="string"?r.provider:void 0;return{accessToken:t,email:o,exp:i,provider:s}}function Ke(t){return t?t.length<=12?`${t.slice(0,4)}\u2026`:`${t.slice(0,6)}\u2026${t.slice(-4)}`:""}function re(){return Ht.randomBytes(9).toString("base64url")}function Zt(t){if(!t)return;let e=t.replace(/-/g,"+").replace(/_/g,"/"),n=(4-e.length%4)%4,r=e+"=".repeat(n);try{return Buffer.from(r,"base64").toString("utf8")}catch{return}}async function O(){let t=w();return t.jwtFromEnvironment?t.jwtFromEnvironment:(await Yt(t.tokenStorePath,t.workspaceUrl))?.accessToken}async function Q(t){let e=w(),n=C(t),r={accessToken:t,email:n.email,provider:n.provider,exp:n.exp};return await en(e.tokenStorePath,e.workspaceUrl,r),r}async function He(){let t=w(),e=await ve(t.tokenStorePath),n=e[t.workspaceUrl]!==void 0;return delete e[t.workspaceUrl],await Ze(t.tokenStorePath,e),{workspaceUrl:t.workspaceUrl,deleted:n}}function oe(t){return{email:t.email,provider:t.provider,exp:t.exp,accessToken:Ke(t.accessToken)}}async function Yt(t,e){return(await ve(t))[e]}async function en(t,e,n){let r=await ve(t);r[e]=n,await Ze(t,r)}async function ve(t){try{let e=await Se.readFile(t,"utf8"),n=JSON.parse(e);return!n||typeof n!="object"?{}:n}catch{return{}}}async function Ze(t,e){await Se.mkdir(Xt.dirname(t),{recursive:!0}),await Se.writeFile(t,JSON.stringify(e,null,2)+`
6
+ `,"utf8")}async function Xe(t){let e=w(),n=await fetch(`${e.authUrl}/email/request-code`,{method:"POST",headers:{"content-type":"application/json",domain:e.authDomain},body:JSON.stringify({email:t})});if(!n.ok){let r=await n.text().catch(()=>"");throw new Error(`email/request-code failed: ${n.status} ${r}`.trim())}}async function Ye(t,e){let n=w(),r=await fetch(`${n.authUrl}/email/verify-code`,{method:"POST",headers:{"content-type":"application/json",domain:n.authDomain},body:JSON.stringify({email:t,code:e})}),o=await r.json().catch(()=>{});if(!r.ok)throw new Error(`email/verify-code failed: ${r.status}`);let i=typeof o?.access_token=="string"?o.access_token:"";if(!i)throw new Error("email/verify-code failed: missing access_token");let s=await Q(i);return{workspaceUrl:n.workspaceUrl,...oe(s)}}import tn from"node:crypto";async function et(t){let e=w(),n=tn.randomUUID(),r=new URL(`${e.authUrl}/google-form`);return r.searchParams.set("requestId",n),r.searchParams.set("scopes",t),{requestId:n,url:r.toString()}}async function tt(t){let e=w(),n=new URL(`${e.authUrl}/google-auth-token`);n.searchParams.set("id",t);let r=await fetch(n.toString(),{headers:{domain:e.authDomain}}),o=await r.json().catch(()=>{});if(!r.ok)throw new Error(`google-auth-token failed: ${r.status}`);let i=typeof o?.access_token=="string"?o.access_token:"";if(!i)throw new Error("google-auth-token failed: missing access_token");let s=await Q(i);return{workspaceUrl:e.workspaceUrl,...oe(s)}}async function q(t){let e=C(t);if(e.provider!=="google"||!e.exp)return t;let n=Date.now(),r=e.exp*1e3,o=300*1e3;if(r-n>=o)return t;let i=w(),s=await fetch(`${i.authUrl}/google-refresh`,{method:"GET",headers:{Authorization:`Bearer ${t}`}}),c=await s.json().catch(()=>{});if(!s.ok)return t;let u=typeof c?.access_token=="string"?c.access_token:"";return u?(await Q(u),u):t}async function nt(t){let e=w(),n=await fetch(`${e.workspaceUrl}/users/is-member`,{method:"GET",headers:{Authorization:`Bearer ${t}`}});if(!n.ok){let o=await n.text().catch(()=>"");throw new Error(`users/is-member failed: ${n.status} ${o}`.trim())}if((await n.json().catch(()=>{}))?.isMember!==!0)throw new Error("user not member of workspace")}import{isDeepStrictEqual as xn}from"node:util";import nn from"node:crypto";import rn from"node:fs";import on from"node:path";import{DatabaseSync as sn}from"node:sqlite";var ie=class{database;databasePath;scope;constructor(e,n){this.databasePath=e,this.scope=n}async loadItems(e){let n=this.getDatabase().prepare("select key, value_json from replicated_items where scope = ? and resource = ?").all(this.scope,e),r={};for(let o of n)r[o.key]=JSON.parse(o.value_json);return n.length>0?r:null}async persistItem(e,n,r){this.getDatabase().prepare(`insert into replicated_items (scope, resource, key, value_json, saved_at_ms)
7
+ values (?, ?, ?, ?, ?)
8
+ on conflict(scope, resource, key) do update set
9
+ value_json = excluded.value_json,
10
+ saved_at_ms = excluded.saved_at_ms`).run(this.scope,e,n,JSON.stringify(r),Date.now())}async deleteResource(e){this.getDatabase().prepare("delete from replicated_items where scope = ? and resource = ?").run(this.scope,e)}async clearAll(){this.getDatabase().prepare("delete from replicated_items where scope = ?").run(this.scope)}close(){this.database?.close(),this.database=void 0}getDatabase(){return this.database?this.database:(rn.mkdirSync(on.dirname(this.databasePath),{recursive:!0}),this.database=new sn(this.databasePath),this.database.exec(`
11
+ create table if not exists replicated_items (
12
+ scope text not null,
13
+ resource text not null,
14
+ key text not null,
15
+ value_json text not null,
16
+ saved_at_ms integer not null,
17
+ primary key (scope, resource, key)
18
+ )
19
+ `),this.database)}};function rt(t,e){let n=e??"unknown-user";return nn.createHash("sha256").update(`${t}
20
+ ${n}`).digest("hex")}function ot(t,e,n){let r=t.replace(/^http/,"ws"),o=encodeURIComponent(e),i=encodeURIComponent(n);return`${r}/base/${o}/${i}`}var se=class{websocket;sessionId=re();workspaceUrl;accessToken;channelListeners=new Map;disconnectListeners=new Set;ackWaiters=new Map;intentionallyClosed=!1;constructor(e,n){this.workspaceUrl=e,this.accessToken=n}async connect(e){this.intentionallyClosed=!1,this.sessionId=re();let n=ot(this.workspaceUrl,this.accessToken,this.sessionId),r=new WebSocket(n,"echo");this.websocket=r,await new Promise((o,i)=>{let s=setTimeout(()=>i(new Error("websocket open timeout")),e);r.onopen=()=>{clearTimeout(s),o()},r.onerror=()=>{clearTimeout(s),i(new Error("websocket open failed"))}}),r.onmessage=o=>this.processMessage(o.data),r.onclose=()=>this.processClose(),r.onerror=()=>this.processClose()}getSessionId(){return this.sessionId}send(e,n){if(!this.websocket||this.websocket.readyState!==WebSocket.OPEN)throw new Error("workspace websocket not connected");this.websocket.send(`${e};${JSON.stringify(n)}`)}sendWithAck(e,n,r=5e3){let o=re(),i={...n,eventId:o};return new Promise(s=>{let c=setTimeout(()=>{this.ackWaiters.delete(o),s({ok:!1,reason:"timeout"})},r);this.ackWaiters.set(o,{resolve:s,timeout:c}),this.send(e,i)})}onChannel(e,n){return this.channelListeners.has(e)||this.channelListeners.set(e,new Set),this.channelListeners.get(e).add(n),()=>this.channelListeners.get(e)?.delete(n)}onDisconnected(e){return this.disconnectListeners.add(e),()=>this.disconnectListeners.delete(e)}waitForChannelEvent(e,n,r){return new Promise((o,i)=>{let s=setTimeout(()=>{c(),i(new Error(`channel event timeout: ${e}`))},r),c=this.onChannel(e,u=>{n(u)&&(clearTimeout(s),c(),o(u))})})}collectChannelEvents(e,n,r,o){return new Promise((i,s)=>{let c=[],u,d=setTimeout(()=>{y(),u&&clearTimeout(u),s(new Error(`channel event timeout: ${e}`))},r),p=()=>{clearTimeout(d),y(),i(c)},y=this.onChannel(e,m=>{n(m)&&(c.push(m),u&&clearTimeout(u),u=setTimeout(p,o))})})}close(){this.intentionallyClosed=!0,this.websocket?.close(),this.websocket=void 0;for(let e of this.ackWaiters.values())clearTimeout(e.timeout),e.resolve({ok:!1,reason:"closed"});this.ackWaiters.clear()}processMessage(e){let n=typeof e=="string"?e:"",r=n.indexOf(";");if(r===-1)return;let o=n.slice(0,r),i=n.slice(r+1),s;try{s=JSON.parse(i)}catch{return}if(o.startsWith("ack:")){this.resolveAck(o.slice(4),s);return}s=an(s);let c=this.channelListeners.get(o);if(c)for(let u of c)u(s)}resolveAck(e,n){let r=this.ackWaiters.get(e);r&&(this.ackWaiters.delete(e),clearTimeout(r.timeout),r.resolve(n.value??{ok:!1}))}processClose(){if(!this.intentionallyClosed)for(let e of this.disconnectListeners)e()}};function an(t){if(t.resource!=="connections")return t;switch(t.action){case"snapshot":return{...t,value:cn(t.value)};case"delta":return{...t,value:un(t.value)};default:return t}}function cn(t){if(!Te(t))return t;let e={};for(let n in t)e[n]=st(t[n]);return e}function un(t){return Te(t)?{...t,pre:it(t.pre),post:it(t.post)}:t}function it(t){return t===null?null:st(t)}function st(t){if(!Te(t))return t;let e={...t};return delete e.config,e}function Te(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}var Ie="beepflow://resource-schemas/",h={type:"number",description:"Nanoseconds since Unix epoch. Replicated state manages updatedAt after writes."},a={type:"string"},j={type:"number"},ae={type:"integer"},k={type:"boolean"};var at={type:"object",additionalProperties:!0},ct={type:"object",additionalProperties:a},Pe={type:"object",additionalProperties:k},ce={type:"object",additionalProperties:{type:"object",additionalProperties:k,properties:{list:k,detail:k,create:k,edit:k,delete:k,authorize:k}}},M=["boolean","string","number","datetime","map","binary","wildcard","list of boolean","list of string","list of number","list of datetime","list of map","list of binary","list of wildcard"],ue=["ManualTick","AerospikeSet","ApacheKafkaTopic","MQTTTopic","KaggleFile","RabbitMQQueue","RabbitMQStream","ShopifyWebhook","QdrantCollection","BaseVectorCollection","BaseEventCollection","BaseLookupCollection","GorgiasEvent","GorgiasTicket","GoogleDriveFile","GmailMessage","GmailThread","GmailEvent"],$={anyOf:[k,{type:"null"}]},pn=["Use resource_query first when editing existing items; upsert sends whole item state, not a JSON patch.","Omit updatedAt on creates and manual edits unless preserving an existing value; replicated state updates it after accepted writes."];function g(t,e,n){let r=`${Ie}${t}`;return{resource:t,uri:r,sourceType:e,notes:pn,itemSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",title:`Beepflow ${t} item`,type:"object",additionalProperties:!1,required:n.required,properties:n.properties,...n.defs?{$defs:n.defs}:{}}}}var xe={$ref:"#/$defs/operatorType"},dn={type:"object",additionalProperties:!1,required:["value"],properties:{value:{description:"Raw option value written to node input literal when selected."},label:{...a,description:"Optional label shown in operator input dropdowns."}}},ln={type:"object",additionalProperties:!1,required:["type"],properties:{type:{type:"string",enum:M,description:'Blueprint value type name. Use "list of X" for lists, never "list".'},options:{anyOf:[{type:"array",items:dn},{type:"null"}],description:"Allowed literal values for dropdown-style widgets."},isArray:{type:"boolean",description:"Whether this pin accepts multiple values."},allowedTypes:{anyOf:[{type:"array",items:xe},{type:"null"}],description:"Allowed concrete types for wildcard pins."},linkType:{...a,description:"Type-linking group used to propagate wildcard types across pins."},widgetType:{...a,description:'Frontend input widget id. Supports built-in widgets, integration selectors, and "<IntegrationType>-connection" connection dropdowns.'},defaultValue:{description:"Default literal value used when node input omits a value."},defaultValueForArrayElement:{description:"Default literal value for newly added array input elements."}}},fn={type:"object",additionalProperties:!1,required:["name","doc","type"],properties:{name:{...a,description:"Output pin name."},doc:{...a,description:"Operator output documentation shown to users."},type:xe}},mn={type:"object",additionalProperties:!1,required:["name","doc","type"],properties:{name:{...a,description:"Input pin name; node inputs are keyed by this value."},doc:{...a,description:"Operator input documentation shown to users."},type:xe,isLiteral:{...k,description:"Whether this input must be edited as literal value instead of upstream connection."}}},ut=g("blueprint-operators","frontend/src/tabs/blueprint/types.ts:Operator",{required:["id","type","name","doc","categoryPath","inputs"],properties:{id:{...a,description:"Stable registered operator id referenced by blueprint nodes."},type:{...a,description:"Operator kind, usually function, variable, or localVariable."},name:{...a,description:"Display name used in operator search and node labels."},aliases:{type:"array",items:a,description:"Additional search terms for this operator."},doc:{...a,description:"Operator documentation shown to users."},categoryPath:{type:"array",items:a,description:"Menu category path segments."},inputs:{type:"array",items:mn,description:"Input pins in display order."},output:{anyOf:[fn,{type:"null"}],description:"Output pin definition, or null for side-effect-only operators."},isDeprecated:{...k,description:"Whether operator is deprecated and hidden from default search."},hidden:{...k,description:"Whether operator is hidden from menus and search."},canMock:{...k,description:"Whether test mode can mock this operator."},updatedAt:h},defs:{operatorType:ln}});var hn={type:"object",additionalProperties:!1,required:["x","y"],properties:{x:{...j,description:"Node world x coordinate in blueprint editor."},y:{...j,description:"Node world y coordinate in blueprint editor."},title:{...a,description:"Optional display title shown on node."},comment:{...a,description:"Optional user-authored node comment."}}},gn={type:"object",additionalProperties:!0,description:"Blueprint view node. Known visualization blocks are intentionally accepted as additional properties.",required:["id","style"],properties:{id:{...a,description:"Node id; must match key in blueprint view nodes record."},style:hn}},pt=g("blueprint-views","frontend/src/tabs/blueprint/types.ts:BlueprintView",{required:["id","nodes"],properties:{id:{...a,description:"Blueprint tab id; must match tabs and blueprints resource id."},updatedAt:h,nodes:{type:"object",additionalProperties:gn,description:"Editor view state keyed by node id."}}});var yn={type:"object",additionalProperties:!1,required:["literal"],properties:{literal:{description:"Literal JSON value for this input element; null is valid when connected upstream."},nodeId:{...a,description:"Upstream node id when this value is connected to another node output."},operatorInputId:{...a,description:"Upstream output pin name used by this connection."},nodeInputIndex:{...a,description:'CRDT list index of upstream output value, usually "0".'}}},wn={type:"object",additionalProperties:!1,required:["values"],properties:{isArray:{...$,description:"Whether input accepts multiple values for one operator input."},values:{type:"object",additionalProperties:yn,description:"Input values keyed by CRDT list index strings."},type:{type:"string",enum:M,description:"Resolved input type override."},forceZipping:{...$,description:"Force list zipping behavior for multiple upstream values."}}},kn={type:"object",additionalProperties:!1,required:["id","operatorId","inputs"],properties:{id:{...a,description:"Stable node id; must match key in blueprint nodes record."},operatorId:{...a,description:"Id of registered blueprint operator this node executes."},inputs:{type:"object",additionalProperties:wn,description:"Node inputs keyed by operator input name."},mockNever:{...$,description:"Disable mocking for this node while testing."},skipBehavior:{type:"string",enum:["skip","null"],description:"Behavior when upstream value is skipped."},disabled:{...$,description:"Whether this node and downstream dependent nodes are disabled."},outputType:{type:"string",enum:M,description:"Resolved output type for wildcard operators."}}},Ee={type:"object",additionalProperties:!1,required:["enabled"],properties:{enabled:{...k,description:"Whether this trigger is enabled."}}},bn={type:"object",additionalProperties:!1,minProperties:1,maxProperties:1,description:"Blueprint trigger configuration. Required for explore mode, ignored by test mode. Set exactly one trigger branch; runtime checks branches in executor, webhook, blueprint, manual, cron, then loop order if multiple branches somehow exist.",properties:{manual:{type:"object",additionalProperties:!1,required:["count"],description:"Run executor immediately when explore runtime starts or restarts. Use for finite or manually sampled resource types.",properties:{count:{...ae,description:"Number of executions; backend treats values below 1 as 1."}}},cron:{type:"object",additionalProperties:!1,required:["expression"],description:"Run executor on a schedule while explore runtime is active.",properties:{expression:{...a,description:"Cron expression with seconds field, parsed by robfig/cron."},timezone:{...a,description:"Optional IANA timezone name; UTC when omitted or empty."}}},loop:{type:"object",additionalProperties:!1,required:["delayMs"],description:"Run executor immediately, then repeat after delayMs while explore runtime is active. Use positive delayMs; zero can create a hot loop.",properties:{delayMs:{...ae,description:"Delay between executions in milliseconds."}}},blueprint:{...Ee,description:"Wait for another blueprint or Trigger Self operator to call this blueprint while it is active. Requires enabled true. Trigger argument is available through Get Trigger Argument."},webhook:{...Ee,description:"Wait for generic GET/POST /:tabId/trigger calls while blueprint is active. Requires enabled true. Request method, URL, body, headers, and timestamp become trigger argument. Not the same as integration-specific webhook executors such as ShopifyWebhook or GorgiasEvent."},executor:{...Ee,description:"Run integration-specific executor directly. Requires enabled true. Use for resource types whose default trigger is executor; frontend hides executor trigger config and does not let users select it from the trigger dropdown."}}},Rn={type:"object",additionalProperties:!1,required:["type","trigger"],properties:{type:{type:"string",enum:ue,description:"Integration resource type this blueprint processes. Runtime-supported blueprint types with default manual trigger: ManualTick, AerospikeSet, KaggleFile, QdrantCollection, BaseVectorCollection, BaseLookupCollection, GorgiasTicket, GoogleDriveFile. Runtime-supported blueprint types with default executor trigger: ApacheKafkaTopic, MQTTTopic, RabbitMQStream, ShopifyWebhook, BaseEventCollection, GorgiasEvent, GmailMessage, GmailThread, GmailEvent. RabbitMQQueue is in enum but currently has no blueprint executor or event getter; do not use it for blueprints."},trigger:bn,config:{...at,description:"Integration-specific context configuration."}}},dt=g("blueprints","frontend/src/tabs/blueprint/types.ts:Blueprint",{required:["id","mode","nodes","context"],properties:{id:{...a,description:"Blueprint tab id; must match tabs resource id."},updatedAt:h,mode:{type:"string",enum:["test","explore"],description:"Execution mode; result id is blueprint id plus this mode."},nodes:{type:"object",additionalProperties:kn,description:"Blueprint nodes keyed by node id."},context:Rn,testRecordsAmount:{...ae,description:"Target number of test records to keep for test mode."},recomputeOnChange:{type:"string",enum:["always","manual"],description:"Whether edits automatically restart execution."},mockNever:{...k,description:"Global flag to disable node mocking while testing."},desiredState:{type:"string",enum:["active","inactive"],description:"Requested runtime state for test or explore mode."}}});var Sn=["Aerospike","ApacheKafka","MQTT","Kaggle","FacebookAds","RabbitMQ","Shopify","YouTube","Webshare","Playwright","AWS","Qdrant","OpenAI","BaseVector","BaseEvent","BaseLookup","Gorgias","LMStudio","OpenRouter","VoyageAI","GoogleDrive","GoogleSheets","Gmail","DiscordChannelWebhook"],lt=g("connections","frontend/src/integrations/types.ts:Connection",{required:["id","label","type","spaceId"],properties:{id:a,updatedAt:h,label:a,type:{type:"string",enum:Sn},spaceId:a}});var ft=g("roles","frontend/src/auth/roles/types.ts:Role",{required:["id","label","authorizations"],properties:{id:a,updatedAt:h,label:a,authorizations:ce}});var mt=g("schemas","frontend/src/integrations/types.ts:Schema",{required:["id","type","connectionId","path","schema"],properties:{id:a,updatedAt:h,type:{type:"string",enum:ue},connectionId:a,path:ct,schema:{type:"object",additionalProperties:{type:"string",enum:M}},keySerdeType:{type:"string"},valueSerdeType:{type:"string"}}});var ht=g("space-join-requests","frontend/src/spaces/space-join-requests/types.ts:SpaceJoinRequest",{required:["id","createdAt","requestedBy","kind","status","spaceId","userId"],properties:{id:a,createdAt:{type:"number",description:"Nanoseconds since Unix epoch."},updatedAt:h,requestedBy:a,kind:{type:"string",enum:["invite","request"]},status:{type:"string",enum:["pending","granted","denied"]},spaceId:a,userId:a}});var gt=g("spaces","frontend/src/spaces/types.ts:Space",{required:["id","label"],properties:{id:a,updatedAt:h,label:a,thumbnailUrl:a,description:a,isUserSpace:$}});var yt=g("tabs","frontend/src/tabs/types.ts:Tab",{required:["id","name","order","type","parent","spaceId"],properties:{id:a,updatedAt:h,name:a,order:j,type:{type:"string",enum:["blueprint","folder"]},parent:a,spaceId:a}});var wt=g("user-locations","frontend/src/workspace/user-location/types.ts:UserLocation",{required:["id"],properties:{id:a,updatedAt:h,blueprint:{type:"object",additionalProperties:!1,required:["id"],properties:{id:a,worldPosition:{type:"object",additionalProperties:!1,required:["x","y"],properties:{x:j,y:j}}}}}});var kt=g("users","frontend/src/auth/users/types.ts:User",{required:["id","displayName","roleIds","authorizations","spaces"],properties:{id:a,updatedAt:h,displayName:a,avatarUrl:a,roleIds:Pe,authorizations:ce,spaces:Pe}});var pe=[kt,ft,gt,yt,lt,mt,dt,pt,ut,wt,ht];function de(t){return pe.find(e=>e.resource===t)}var U=[I("users","Workspace users and authorizations.",!0),I("roles","Workspace roles and resource authorizations.",!0),I("spaces","Workspace spaces.",!0),I("tabs","Tabs and folders visible to authorized user.",!0),I("connections","Integration connections without secret-bearing config.",!1),I("schemas","Integration schema metadata.",!0),I("blueprints","Blueprint definitions by tab id.",!0),I("blueprint-views","Blueprint editor view state by tab id.",!0),I("blueprint-operators","Registered blueprint operator definitions.",!1),I("user-locations","Live user location records.",!0),I("space-join-requests","Space invitation and join requests.",!0)],F=U.map(t=>t.name);function bt(t){return U.find(e=>e.name===t)}function H(t){if(bt(t))return t;throw new Error(`unsupported resource: ${t}`)}function Ae(t){let e=bt(t);if(!e)throw new Error(`unsupported resource: ${t}`);if(!e.writable)throw new Error(`resource is read-only: ${t}`);return e.name}function I(t,e,n){return{name:t,description:e,writable:n,schemaUri:`${Ie}${t}`}}function Ce(t,e){if(t===null&&e===null)return{pre:null,post:null};if(t===null&&e!==null)return{pre:null,post:e};if(t!==null&&e===null)return{pre:t,post:null};if(typeof t!="object"||typeof e!="object")return t!==e?{pre:t,post:e}:{pre:null,post:null};if(Array.isArray(t)||Array.isArray(e))return{pre:null,post:null};let{pre:n,post:r}=Rt(t,e);return n===null&&r===null?{pre:null,post:null}:{pre:n,post:r}}function Rt(t,e){let n={},r={},o=!1,i=new Set([...E(t),...E(e)]);for(let s of i){if(s==="updatedAt")continue;let c=t[s],u=e[s];if(Array.isArray(c)||Array.isArray(u))continue;let d=B(c),p=B(u);if(!(s in e))d||(n[s]=c,r[s]=null,o=!0);else if(!(s in t))p||(n[s]=null,r[s]=u,o=!0);else{if(d&&p)continue;if(d&&!p)n[s]=null,r[s]=u,o=!0;else if(!d&&p)n[s]=c,r[s]=null,o=!0;else{let{pre:y,post:m}=vn(c,u);(y!==void 0||m!==void 0)&&(y!==void 0&&(n[s]=De(y)),m!==void 0&&(r[s]=De(m)),o=!0)}}}return o?E(n).length===0&&E(r).length===0?{pre:null,post:null}:E(n).length===0?{pre:null,post:r}:E(r).length===0?{pre:n,post:null}:{pre:n,post:r}:{pre:null,post:null}}function vn(t,e){if(Tn(t,e))return{pre:void 0,post:void 0};let n=B(t),r=B(e);if(n&&r)return{pre:void 0,post:void 0};if(n)return{pre:null,post:e};if(r)return{pre:t,post:null};if(Array.isArray(t)||Array.isArray(e))return{pre:void 0,post:void 0};if(typeof t!=typeof e)return{pre:t,post:e};if(typeof t=="object"&&t!==null&&typeof e=="object"&&e!==null){let{pre:o,post:i}=Rt(t,e);return o===null&&i===null?{pre:void 0,post:void 0}:{pre:o===null?void 0:o,post:i===null?void 0:i}}return{pre:t,post:e}}function B(t){return t==null?!0:typeof t=="object"&&t!==null?Array.isArray(t)?t.length===0:E(t).length===0:!1}function Tn(t,e){return B(t)&&B(e)?!0:je(t,e)}function je(t,e){if(t===e)return!0;if(t==null||e==null||typeof t!="object"||typeof e!="object")return!1;let n=E(t),r=E(e);if(n.length!==r.length)return!1;for(let o of n)if(!(o in e)||!je(t[o],e[o]))return!1;return!0}function le(t,e){return e.pre===null?t===null:t===null||typeof t!="object"||Array.isArray(t)?!1:St(t,e.pre)}function St(t,e){for(let n in e)if(n!=="updatedAt"&&!In(t[n],e[n]))return!1;return!0}function In(t,e){return e===null||Pn(e)?B(t):t===void 0?!1:typeof e=="object"&&e!==null&&!Array.isArray(e)&&typeof t=="object"&&t!==null&&!Array.isArray(t)?St(t,e):je(t,e)}function Pn(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)&&E(t).length===0}function De(t){if(t==null)return null;if(typeof t=="object"&&t!==null){if(Array.isArray(t)&&t.length===0)return null;if(!Array.isArray(t)){let e={},n=!1;for(let r in t)e[r]=De(t[r]),e[r]!==void 0&&(n=!0);return n?e:null}}return t}function Be(t,e){let n=_e(t,e);return n!==null&&typeof n=="object"&&!Array.isArray(n)&&(n.updatedAt=e.updatedAt),n}function _e(t,e){return e.post===null?null:t===null?e.post:typeof t!="object"||Array.isArray(t)?e.post:vt(t,e.post)}function vt(t,e){let n={};for(let r in t)if(r in e){let o=e[r];if(o===null)continue;typeof o=="object"&&!Array.isArray(o)&&typeof t[r]=="object"&&!Array.isArray(t[r])&&t[r]!==null?n[r]=vt(t[r],o):n[r]=o}else n[r]=t[r];for(let r in e)!(r in t)&&e[r]!==null&&(n[r]=e[r]);return n}function E(t){let e=[];for(let n in t)e.push(n);return e}var Tt="replicated-state",fe=class{ackedResources={};dirtyResources={};unauthorizedKeys={};loadingResources={};loadingPromises=new Map;loadedResources=new Set;registeredResources=new Set;resourceChangeListeners=new Set;snapshotWaiters=new Map;storage;socketSession;logger;inflightItems=new Map;constructor(e,n,r){this.storage=e,this.socketSession=n,this.logger=r}onResourceChange(e){return this.resourceChangeListeners.add(e),()=>this.resourceChangeListeners.delete(e)}registerResource(e){this.registeredResources.add(e),this.initializeResource(e)}isResourceRegistered(e){return this.registeredResources.has(e)}getRegisteredResources(){return Array.from(this.registeredResources)}setDirtyItems(e,n){this.registerResource(e),this.dirtyResources[e]=v(n)}setDirtyItem(e,n,r){if(this.registerResource(e),r===void 0){delete this.dirtyResources[e][n];return}this.dirtyResources[e][n]=v(r)}clearSessionState(){this.ackedResources={},this.loadingResources={},this.loadingPromises.clear(),this.loadedResources.clear(),this.inflightItems.clear();for(let e of this.registeredResources)this.dirtyResources[e]={},this.unauthorizedKeys[e]={},this.loadingResources[e]=!0,this.emitResourceChange(e)}async loadRegisteredResourcesFromStorage(){await Promise.all(Array.from(this.registeredResources,e=>this.loadResourceFromStorage(e)))}async hydrate(e,n){this.registerResource(e),await this.loadResourceFromStorage(e),this.logger.info(`Calculating lastUpdatedAtSeen from ${Pt(this.ackedResources[e])} items`);let r=this.prepareSnapshotQuery(e,n);this.logger.info(`\u{1F4F8} ${e} requested with query:`,r),this.socketSession.send(Tt,{resource:e,action:"snapshot",value:r})}hydrateAll(e){return this.hydrate(e,{all:!0})}async waitForSnapshot(e,n){await new Promise((r,o)=>{let i,s=()=>{clearTimeout(i),r()};i=setTimeout(()=>{this.snapshotWaiters.get(e)?.delete(s),o(new Error(`snapshot timeout for ${e}`))},n),this.snapshotWaiters.has(e)||this.snapshotWaiters.set(e,new Set),this.snapshotWaiters.get(e).add(s)})}processSocketEvent(e){switch(e.action){case"snapshot":this.applySnapshot(e.resource,e.value??{});break;case"delta":this.applyRemoteDelta(e);break}}async upsertItem(e,n){this.registerResource(e);let r=this.getAckedValue(e,n.id),o=Ce(r,n);return o.pre===null&&o.post===null?!0:this.sendDelta(e,n.id,o,n)}async deleteItem(e,n){this.registerResource(e);let r=this.getAckedValue(e,n),o=Ce(r,null);return o.pre===null&&o.post===null?!0:this.sendDelta(e,n,o,null)}isItemInflight(e,n){return this.inflightItems.get(e)?.has(n)===!0}async sendDelta(e,n,r,o){this.registerResource(e),this.inflightItems.has(e)||this.inflightItems.set(e,new Set);let i=this.inflightItems.get(e);if(i.has(n))return!1;let s=this.getDirtyValue(e,n);le(s,r)&&(arguments.length>=4?this.setDirtyValue(e,n,v(o)):this.setDirtyValue(e,n,_e(s,v(r))),this.emitResourceChange(e)),i.add(n);let c;try{c=await this.socketSession.sendWithAck(Tt,{resource:e,action:"delta",key:n,value:r})}catch(u){c={ok:!1,reason:u instanceof Error?u.message:"error"}}return i.delete(n),c.ok?!0:(this.revertDirtyToAckedValue(e,n),this.emitResourceChange(e),this.logger.error(`!ack[${e}] Reverting to acked state for ${e}:${n}`,c.reason),!1)}getAckedValue(e,n){return this.initializeResource(e),this.ackedResources[e][n]??null}getDirtyValue(e,n){return this.initializeResource(e),this.dirtyResources[e][n]??null}getVisibleItems(e){this.initializeResource(e);let n={};for(let r in this.dirtyResources[e]){let o=this.dirtyResources[e][r];o!=null&&(n[r]=o)}return n}getRawItems(e){return this.initializeResource(e),v(this.dirtyResources[e])}getAckedItems(e){return this.initializeResource(e),v(this.ackedResources[e])}getUnauthorizedKeys(e){return this.initializeResource(e),v(this.unauthorizedKeys[e])}isResourceLoading(e){return this.initializeResource(e),this.loadingResources[e]}initializeResource(e){this.ackedResources[e]===void 0&&(this.ackedResources[e]={}),this.dirtyResources[e]===void 0&&(this.dirtyResources[e]={}),this.unauthorizedKeys[e]===void 0&&(this.unauthorizedKeys[e]={}),this.loadingResources[e]===void 0&&(this.loadingResources[e]=!0)}prepareSnapshotQuery(e,n){this.initializeResource(e);let r=v(n);if(r.lastUpdatedAtSeen!==void 0)return r;let o=this.buildLastUpdatedAtSeen(e,r);return It(o)||(r.lastUpdatedAtSeen=o),r}async loadResourceFromStorage(e){if(this.initializeResource(e),this.loadedResources.has(e))return;if(this.loadingPromises.has(e))return this.loadingPromises.get(e);let n=this.loadResourceItemsFromStorage(e);this.loadingPromises.set(e,n);try{await n}finally{this.loadingPromises.delete(e),this.loadedResources.add(e)}}async loadResourceItemsFromStorage(e){let n=!1,r=0;try{let o=await this.storage.loadItems(e);if(o&&It(this.ackedResources[e])){n=!0;for(let i in o)this.applyCachedItem(e,i,o[i])&&(r+=1)}}catch(o){this.logger.warn(`Failed to load cached ${e}: ${String(o)}`)}finally{this.loadingResources[e]=!1,this.emitResourceChange(e),n?this.logger.info(`\u{1F4C2} ${r}x ${e} from cache`):this.logger.info(`\u{1F4C2} no cached data for ${e}`)}}applyCachedItem(e,n,r){return r===null?(this.ackedResources[e][n]=null,this.dirtyResources[e][n]=null,!0):r==="unauthorized"?(this.unauthorizedKeys[e][n]=!0,!1):(this.ackedResources[e][n]=v(r),this.dirtyResources[e][n]=v(r),!0)}applySnapshot(e,n){this.initializeResource(e);for(let r in n){let o=n[r];o===null?(this.ackedResources[e][r]=null,this.dirtyResources[e][r]=null,delete this.unauthorizedKeys[e][r]):o==="unauthorized"?(delete this.ackedResources[e][r],delete this.dirtyResources[e][r],this.unauthorizedKeys[e][r]=!0):(this.ackedResources[e][r]=v(o),this.dirtyResources[e][r]=v(o),delete this.unauthorizedKeys[e][r]),this.storage.persistItem(e,r,o).catch(i=>{this.logger.warn(`Failed to persist ${e}:${r}: ${String(i)}`)})}this.loadingResources[e]=!1,this.emitResourceChange(e),this.logger.info(`\u{1F4F8} ${Pt(n)}x ${e} `),this.resolveSnapshotWaiters(e)}applyRemoteDelta(e){let n=e.resource,r=e.key;if(!r)return;this.initializeResource(n);let o=e.value,i={pre:o.pre,post:o.post},s=this.getAckedValue(n,r);if(!le(s,i))this.logger.error(`\u{1D6AB}S precondition invalid on last acked for ${n}:${r}`,{pre:i.pre,post:i.post,current:s});else{let u=Be(s,v(o));this.ackedResources[n][r]=u,this.storage.persistItem(n,r,u).catch(d=>{this.logger.warn(`Failed to persist ${n}:${r}: ${String(d)}`)}),this.logger.info(We(`\u{1D6AB}S[${n}] acked`,i))}let c=this.getDirtyValue(n,r);e.by!==this.socketSession.getSessionId()?le(c,i)?i.post===null?(this.dirtyResources[n][r]=null,this.logger.info(We(`\u{1D6AB}S[${n}] dirty`,i))):(this.dirtyResources[n][r]=Be(c,v(o)),this.logger.info(We(`\u{1D6AB}S[${n}] dirty`,i))):(this.logger.warn(`Skip delta on dirty for ${n}:${r}`,{pre:i.pre,post:i.post,current:s}),this.revertDirtyToAckedValue(n,r)):i.post!=null&&c!=null&&typeof c=="object"&&(c.updatedAt=o.updatedAt,this.dirtyResources[n][r]=c,this.logger.info(`\u{1D6AB}S[${n}] dirty updatedAt for ${r}`)),this.emitResourceChange(n)}buildLastUpdatedAtSeen(e,n){let r=this.ackedResources[e],o={};if(n.all){for(let i in r)this.copyItemUpdatedAt(r[i],i,o);return o}if(n.keys&&n.keys.length>0)for(let i of n.keys)this.copyItemUpdatedAt(r[i],i,o);return o}copyItemUpdatedAt(e,n,r){e&&typeof e=="object"&&typeof e.updatedAt=="number"&&(r[n]=e.updatedAt)}setDirtyValue(e,n,r){if(r===null){this.dirtyResources[e][n]=null;return}this.dirtyResources[e][n]=r}revertDirtyToAckedValue(e,n){let r=this.ackedResources[e][n];if(r===void 0){delete this.dirtyResources[e][n];return}if(r===null){this.dirtyResources[e][n]=null;return}this.dirtyResources[e][n]=v(r)}emitResourceChange(e){let n={resource:e,acked:this.getAckedItems(e),dirty:this.getRawItems(e),unauthorized:this.getUnauthorizedKeys(e),loading:this.loadingResources[e]};for(let r of this.resourceChangeListeners)r(n)}resolveSnapshotWaiters(e){let n=this.snapshotWaiters.get(e);if(n){this.snapshotWaiters.delete(e);for(let r of n)r()}}};function v(t){if(t===void 0)return t;if(typeof structuredClone=="function")try{return structuredClone(t)}catch{}try{return JSON.parse(JSON.stringify(t))}catch{return t}}function It(t){for(let e in t)return!1;return!0}function Pt(t){let e=0;for(let n in t)e+=1;return e}function We(t,e){return`${t}
21
+ delta.pre: ${JSON.stringify(e.pre)}
22
+ delta.post: ${JSON.stringify(e.post)}`}var me=15e3,En=2e3,Me=class{replicatedState;recordStorage;socketSession;startPromise;reconnectTimer;registeredResources=new Set(F);closed=!1;start(){return this.startPromise?this.startPromise:(this.closed=!1,this.startPromise=this.connectAndHydrate().catch(e=>{throw this.startPromise=void 0,e}),this.startPromise)}async hydrateResource(e,n={all:!0}){this.registerResource(e),await this.start(),await this.hydrateConnectedResource(e,n)}async readResourceItems(e,n={all:!0}){return this.registerResource(e),await this.start(),this.filterVisibleItems(e,n)}async readResourceItem(e,n){this.registerResource(e),await this.start();let r=this.replicatedState?.getVisibleItems(e)[n]??null;return xt(e,r)}async upsertResourceItem(e,n){if(this.registerResource(e),await this.start(),!this.replicatedState)throw new Error("replicated state not initialized");return this.replicatedState.upsertItem(e,n)}async deleteResourceItem(e,n){if(this.registerResource(e),await this.start(),!this.replicatedState)throw new Error("replicated state not initialized");return this.replicatedState.deleteItem(e,n)}waitForChannelEvent(e,n,r=me){if(!this.socketSession)throw new Error("workspace websocket not connected");return this.socketSession.waitForChannelEvent(e,o=>n(o),r)}collectChannelEvents(e,n,r=me,o=250){if(!this.socketSession)throw new Error("workspace websocket not connected");return this.socketSession.collectChannelEvents(e,i=>n(i),r,o)}sendChannelEvent(e,n){if(!this.socketSession)throw new Error("workspace websocket not connected");this.socketSession.send(e,n)}close(){this.closed=!0,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.startPromise=void 0,this.socketSession?.close(),this.recordStorage?.close(),this.socketSession=void 0,this.recordStorage=void 0,this.replicatedState=void 0}registerResource(e){H(e),this.registeredResources.add(e),this.replicatedState?.registerResource(e)}async connectAndHydrate(){let e=await O();if(!e)throw new Error("missing jwt: set BEEPFLOW_JWT or run auth tool to persist token");let n=await q(e);await nt(n);let r=w(),o=C(n),i=rt(r.workspaceUrl,o.email);this.socketSession?.close(),this.recordStorage?.close(),this.recordStorage=new ie(r.replicatedStateDatabasePath,i),this.socketSession=new se(r.workspaceUrl,n),this.replicatedState=new fe(this.recordStorage,this.socketSession,jn),this.socketSession.onChannel("replicated-state",s=>this.replicatedState?.processSocketEvent(s)),this.socketSession.onDisconnected(()=>this.scheduleReconnect());for(let s of this.registeredResources)this.replicatedState.registerResource(s);await this.socketSession.connect(me),await this.replicatedState.loadRegisteredResourcesFromStorage(),await this.hydrateRegisteredResources()}async hydrateRegisteredResources(){await Promise.all(Array.from(this.registeredResources,e=>this.hydrateConnectedResource(e,{all:!0})))}async hydrateConnectedResource(e,n){if(!this.replicatedState)throw new Error("replicated state not initialized");let r=this.replicatedState.waitForSnapshot(e,me);await this.replicatedState.hydrate(e,n),await r}filterVisibleItems(e,n){let r=this.replicatedState?.getVisibleItems(e)??{},o={};for(let i in r)An(i,r[i],n)&&(o[i]=xt(e,r[i]));return o}scheduleReconnect(){this.closed||this.reconnectTimer||(this.startPromise=void 0,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,this.start().catch(()=>this.scheduleReconnect())},En))}};function An(t,e,n){return Dn(t,e,n.lastUpdatedAtSeen)?!!(n.all||n.keys?.includes(t)||Cn(e,n.fieldEqualTo)):!1}function xt(t,e){if(t!=="connections"||!e||typeof e!="object"||Array.isArray(e))return e;let n={...e};return delete n.config,n}function Dn(t,e,n){let r=n?.[t];if(r===void 0||!e||typeof e!="object")return!0;let o=e.updatedAt;return typeof o!="number"||o>r}function Cn(t,e){if(!e||!t||typeof t!="object")return!1;let n=t,r=!1;for(let o in e)if(r=!0,!xn(n[o],e[o]))return!1;return r}var jn={info(t,e){Oe("info",t,e)},warn(t,e){Oe("warn",t,e)},error(t,e){Oe("error",t,e)}};function Oe(t,e,n){let r=n===void 0?"":` ${JSON.stringify(n)}`;process.stderr.write(`[replicated-state:${t}] ${e}${r}
23
+ `)}var qe;function V(){return qe||(qe=new Me),qe}import{isDeepStrictEqual as Bn}from"node:util";function At(t,e){let n=de(t);if(!n)throw new Error(`missing schema for resource: ${t}`);let r={failures:[],rootSchema:n.itemSchema};if(K(n.itemSchema,e,"$",r),r.failures.length===0)return;let o=r.failures.slice(0,5).map(i=>`${i.path} ${i.message}`).join("; ");throw new Error(`item does not match ${t} schema: ${o}`)}function K(t,e,n,r){if(t===!0)return;if(t===!1)return A(r,n,"is not allowed");if(!Ln(t))return;let o=t.$ref;if(typeof o=="string"){K(Nn(o,r.rootSchema),e,n,r);return}_n(t,e,n,r)&&(Wn(t,e,n,r),On(t,e,n,r),qn(t,e,n,r),$n(t,e,n,r))}function _n(t,e,n,r){if(!Array.isArray(t.anyOf))return!0;for(let o of t.anyOf){let i={failures:[],rootSchema:r.rootSchema};if(K(o,e,n,i),i.failures.length===0)return!1}return A(r,n,"does not match any allowed schema"),!1}function Wn(t,e,n,r){let o=t.enum;if(Array.isArray(o)){for(let i of o)if(Bn(e,i))return;A(r,n,`must be one of ${o.map(String).join(", ")}`)}}function On(t,e,n,r){let o=t.type;if(typeof o=="string"&&!Et(e,o)){A(r,n,`must be ${o}`);return}if(Array.isArray(o)){for(let i of o)if(typeof i=="string"&&Et(e,i))return;A(r,n,`must be ${o.map(String).join(" or ")}`)}}function qn(t,e,n,r){if(t.type!=="object"||!Z(e))return;let o=Z(t.properties)?t.properties:{};Mn(t,e,n,r);for(let i of Fn(t))i in e||A(r,`${n}.${i}`,"is required");for(let i in e){if(i in o){K(o[i],e[i],`${n}.${i}`,r);continue}Un(t,e[i],`${n}.${i}`,r)}}function Mn(t,e,n,r){let o=0;for(let c in e)Object.prototype.hasOwnProperty.call(e,c)&&o++;let i=t.minProperties;typeof i=="number"&&o<i&&A(r,n,`must have at least ${i} properties`);let s=t.maxProperties;typeof s=="number"&&o>s&&A(r,n,`must have at most ${s} properties`)}function $n(t,e,n,r){if(t.type!=="array"||!Array.isArray(e))return;let o=t.items;if(o!==void 0)for(let i=0;i<e.length;i++)K(o,e[i],`${n}[${i}]`,r)}function Un(t,e,n,r){let o=t.additionalProperties;if(o===!1){A(r,n,"is not allowed");return}o===void 0||o===!0||K(o,e,n,r)}function Fn(t){return Array.isArray(t.required)?t.required.filter(e=>typeof e=="string"):[]}function Nn(t,e){if(!t.startsWith("#/"))return!1;let n=e,r=t.slice(2).split("/").map(Jn);for(let o of r){if(!Z(n)||!(o in n))return!1;n=n[o]}return n}function Jn(t){return t.replace(/~1/g,"/").replace(/~0/g,"~")}function Et(t,e){switch(e){case"array":return Array.isArray(t);case"boolean":return typeof t=="boolean";case"integer":return Number.isInteger(t);case"null":return t===null;case"number":return typeof t=="number"&&Number.isFinite(t);case"object":return Z(t);case"string":return typeof t=="string";default:return!0}}function Ln(t){return Z(t)}function Z(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function A(t,e,n){t.failures.push({path:e,message:n})}import $e from"node:fs/promises";import zn from"node:os";import Dt from"node:path";var Gn=15e3;async function Ue(t){let e=await jt({method:"GET",path:t});if(!e.ok)throw await Bt(t,e);return await e.json()}async function Ct(t){let e=await jt(t),n={status:e.status,statusText:e.statusText,headers:Xn(e.headers)};if(e.status>=300&&e.status<400)return{...n,location:e.headers.get("location")};if(!e.ok)throw await Bt(t.path,e);return t.responseMode==="binary"?await nr(e,t,n):(e.headers.get("content-type")??"").includes("application/json")?{...n,body:await e.json().catch(()=>null)}:{...n,body:await e.text().catch(()=>"")}}async function jt(t){let e=await Vn(),n=Hn(t.path,t.query),r=new Headers({Authorization:`Bearer ${e}`}),o=t.timeoutMs??Gn;Kn(r,t.headers);let i={method:t.method,headers:r,redirect:"manual",signal:AbortSignal.timeout(o)};t.requestMode==="multipart"?i.body=await Yn(t):t.requestMode==="form"?(i.body=tr(t.body),r.set("Content-Type","application/x-www-form-urlencoded")):t.body!==void 0&&t.method!=="GET"&&t.method!=="HEAD"&&(r.set("Content-Type","application/json"),i.body=JSON.stringify(t.body));try{return await fetch(n,i)}catch(s){throw Qn(s)?new Error(`workspace endpoint timed out after ${o}ms: ${t.path}`):s}}function Qn(t){return t instanceof DOMException&&(t.name==="TimeoutError"||t.name==="AbortError")}async function Vn(){let t=await O();if(!t)throw new Error("missing jwt: set BEEPFLOW_JWT or run auth tool to persist token");return await q(t)}function Kn(t,e){if(e)for(let n in e){let r=e[n];r!=null&&t.set(n,String(r))}}function Hn(t,e){if(!t.startsWith("/"))throw new Error(`workspace endpoint path must start with /: ${t}`);let n=w(),r=new URL(`${n.workspaceUrl}${t}`);return Zn(r,e),r.toString()}function Zn(t,e){if(e)for(let n in e){let r=e[n];if(r!=null){if(Array.isArray(r)){for(let o of r)t.searchParams.append(n,String(o));continue}t.searchParams.set(n,String(r))}}}function Xn(t){let e={};return t.forEach((n,r)=>{e[r]=n}),e}async function Yn(t){let e=new FormData,n=t.body;if(n&&typeof n=="object"&&!Array.isArray(n))for(let o in n){let i=n[o];i!=null&&e.set(o,String(i))}let r=t.files??{};for(let o in r)e.set(o,await er(r[o]),r[o].fileName??o);return e}async function er(t){if(t.filePath)return new Blob([await $e.readFile(t.filePath)],{type:t.contentType});if(t.base64)return new Blob([Buffer.from(t.base64,"base64")],{type:t.contentType});throw new Error("multipart file input must include filePath or base64")}function tr(t){let e=new URLSearchParams;if(!t||typeof t!="object"||Array.isArray(t))return e;for(let n in t){let r=t[n];r!=null&&e.set(n,String(r))}return e}async function nr(t,e,n){let r=Buffer.from(await t.arrayBuffer()),o=e.outputFilePath??rr(t);return await $e.mkdir(Dt.dirname(o),{recursive:!0}),await $e.writeFile(o,r),{...n,filePath:o,sizeBytes:r.byteLength,contentType:t.headers.get("content-type")}}function rr(t){let e=t.headers.get("content-disposition")??"",r=/filename="?([^";]+)"?/i.exec(e)?.[1]?.replace(/[^A-Za-z0-9._-]/g,"_")||`beepflow-download-${Date.now()}.bin`;return Dt.join(zn.tmpdir(),"beepflow-mcp-downloads",r)}async function Bt(t,e){let n=await e.text().catch(()=>"");return new Error(`${t} failed: ${e.status} ${n}`.trim())}async function Fe(t){return or(await Ne(t))}async function _t(){return await Ue("/integrations")}async function Ne(t){return await Ue(`/integrations/${encodeURIComponent(t)}/openapi`)}async function Wt(t){let n=(await Fe(t.integrationType)).find(r=>r.operationId===t.operationId);if(!n)throw new Error(`unsupported integration endpoint: ${t.operationId}`);return dr(n,t.confirm),await Ct({method:n.method,path:lr(n,t.path),query:t.query,headers:t.headers,body:t.body,requestMode:n.requestMode,responseMode:n.responseMode,files:t.files,outputFilePath:t.outputFilePath})}function or(t){let e=he(t,"paths"),n=[];for(let r in e){let o=e[r];if(R(o))for(let i in o){let s=o[i];R(s)&&n.push(ir(i.toUpperCase(),r,s))}}return n}function ir(t,e,n){let r=he(n,"x-beepflow");return{operationId:N(n,"operationId"),integrationType:N(r,"integrationType"),resourceType:mr(r,"resourceType"),method:t,path:e,originalPath:N(r,"originalPath"),summary:N(n,"summary"),access:N(r,"access"),sideEffect:N(r,"sideEffect"),mcpExposure:N(r,"mcpExposure"),requestMode:ar(n),responseMode:cr(n),requiresConnectionId:pr(n),pathParameters:fr(e),parameters:sr(n),requestBody:ge(n,"requestBody"),responses:he(n,"responses")}}function sr(t){let e=t.parameters;if(e==null)return[];if(!Array.isArray(e))throw new Error("invalid integration OpenAPI schema: parameters must be array");return e}function ar(t){let e=ge(t,"requestBody");if(!e)return"none";let n=ge(e,"content");return n?R(n["multipart/form-data"])?"multipart":R(n["application/x-www-form-urlencoded"])?"form":(R(n["application/json"]),"json"):"none"}function cr(t){let e=he(t,"responses");for(let o in e)if(o.startsWith("3")&&R(e[o]))return"redirect";let n=ur(e);if(!n)return"empty";let r=ge(n,"content");return r?R(r["application/octet-stream"])?"binary":R(r["text/plain"])?"text":(R(r["application/json"]),"json"):"empty"}function ur(t){if(R(t[200]))return t[200];for(let e in t)if(e.startsWith("2")&&R(t[e]))return t[e];return null}function pr(t){let e=t.parameters;return Array.isArray(e)?e.some(n=>R(n)&&n.name==="connectionId"&&n.in==="query"&&n.required===!0):!1}function dr(t,e){if(!(t.mcpExposure==="safe"&&t.sideEffect!=="destructive")&&e!==!0)throw new Error(`integration endpoint requires confirm=true: ${t.operationId}`)}function lr(t,e){let n=t.path;for(let r of t.pathParameters){let o=e?.[r];if(typeof o!="string"&&typeof o!="number")throw new Error(`integration endpoint path parameter required: ${r}`);n=n.replace(`{${r}}`,encodeURIComponent(String(o)))}return n}function fr(t){let e=[];for(let n of t.matchAll(/\{([^}]+)\}/g))n[1]&&e.push(n[1]);return e}function he(t,e){if(!R(t)||!R(t[e]))throw new Error(`invalid integration OpenAPI schema: ${e} must be object`);return t[e]}function ge(t,e){if(!R(t)||t[e]===void 0||t[e]===null)return null;if(!R(t[e]))throw new Error(`invalid integration OpenAPI schema: ${e} must be object`);return t[e]}function N(t,e){if(typeof t[e]!="string")throw new Error(`invalid integration OpenAPI schema: ${e} must be string`);return t[e]}function mr(t,e){if(t[e]===void 0||t[e]===null)return null;if(typeof t[e]!="string")throw new Error(`invalid integration OpenAPI schema: ${e} must be string`);return t[e]}function R(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var _={type:"object",additionalProperties:!0},ee={type:"object",additionalProperties:!1,properties:{}},Mt=["kafka-topic:offset-extents","rabbitmq-stream:offset-extents","base-event-collection:offset-extents","shopify-webhook:offset-extents"],$t=["memory","storage-metrics","metrics-worker-ownership"],gr=["ticket-message-created","ticket-message-failed"];function Ut(t=V()){return[...yr(t),...wr(t),...kr(t),...br(t),...Rr(t),...vr(t)]}function yr(t){return[{name:"resources_list",description:"List Beepflow resources supported by this MCP server, including item schema URIs.",inputSchema:ee,call:async()=>l(U)},{name:"resource_schema_get",description:"Read JSON Schema and mutation notes for one Beepflow resource item. Use before constructing an upsert item unless modifying an item read from the same resource.",inputSchema:{type:"object",additionalProperties:!1,required:["resource"],properties:{resource:{type:"string",enum:F}}},call:async e=>{let n=H(f(e,"resource"));return l(de(n))}},{name:"resource_query",description:"Query a Beepflow resource with all, keys, or fieldEqualTo snapshot filters. Returns an item map.",inputSchema:{type:"object",additionalProperties:!1,required:["resource"],properties:{resource:{type:"string",enum:F},all:{type:"boolean"},keys:{type:"array",items:{type:"string"}},fieldEqualTo:_}},call:async e=>{let n=H(f(e,"resource")),r=eo(e),o=await t.readResourceItems(n,r);return l(o)}},{name:"resource_upsert",description:"Create or update one writable Beepflow resource item. Read schema first with resource_schema_get unless editing an item read from the same resource.",inputSchema:{type:"object",additionalProperties:!1,required:["resource","item"],properties:{resource:{type:"string",enum:F},item:_}},call:async e=>{let n=Ae(f(e,"resource")),r=ye(e,"item"),o=r.id;if(typeof o!="string"||!o)throw new Error("item.id must be non-empty string");At(n,r);let i=await t.upsertResourceItem(n,r);return l({ok:i})}},{name:"resource_delete",description:"Delete one writable Beepflow resource item by key.",inputSchema:{type:"object",additionalProperties:!1,required:["resource","key"],properties:{resource:{type:"string",enum:F},key:{type:"string"}}},call:async e=>{let n=Ae(f(e,"resource")),r=f(e,"key"),o=await t.deleteResourceItem(n,r);return l({ok:o})}}]}function wr(t){return[{name:"current_user_location_read",description:"Read current authenticated user location for current tab, blueprint, or location questions, including current tab id, tab, blueprint, blueprint view, used operator definitions, and context fields when on a blueprint tab. Not a generic setup step for integration endpoint calls.",inputSchema:ee,call:async()=>Pr(t)}]}function kr(t){return[{name:"workspace_channel_request",description:"Send raw workspace websocket event and wait for matching channel response.",inputSchema:po(),call:async e=>Gr(t,e)},{name:"results_read",description:"Read current blueprint result events for a result id such as tabId-test or tabId-explore.",inputSchema:lo(),call:async e=>Vr(t,e)},{name:"results_delete_state",description:"Stop and delete persisted result state for a result id.",inputSchema:fo(),call:async e=>Kr(t,e)},{name:"results_set_offsets",description:"Set current stream offsets for a result id.",inputSchema:mo(),call:async e=>Hr(t,e)},{name:"metrics_read",description:"Read one live workspace metrics channel.",inputSchema:ho(),call:async e=>Zr(t,e)},{name:"socket_latency_ping",description:"Measure workspace websocket latency.",inputSchema:ee,call:async()=>Xr(t)},{name:"stream_offset_extents_read",description:"Read stream partition offset extents from supported frontend live channels.",inputSchema:go(),call:async e=>Yr(t,e)}]}function br(t){return[{name:"blueprint_operators_search",description:"Search blueprint operators with the same vector endpoint used by the editor menu.",inputSchema:ao(),call:async e=>Tr(t,e)},{name:"blueprint_context_fields_search",description:"Search contextual fields available to a blueprint using the editor menu field matching rules.",inputSchema:co(),call:async e=>Ir(t,e)}]}function Rr(t){return[{name:"integrations_list",description:"List integration types available from the workspace integration API.",inputSchema:ee,call:async()=>l(await _t())},{name:"integration_endpoints_list",description:"List backend integration endpoints for one integration type from workspace OpenAPI metadata, including access, side effect, request, response, confirmation metadata, and requiresConnectionId. If requiresConnectionId is true, use integration_connections_list before integration_endpoint_call.",inputSchema:{type:"object",additionalProperties:!1,required:["integrationType"],properties:{integrationType:{type:"string"}}},call:async e=>l(await Fe(f(e,"integrationType")))},{name:"integration_connections_list",description:"List redacted workspace connections for one integration type. Use this to find connectionId before integration_endpoint_call when endpoint metadata requiresConnectionId. Use current_user_location_read only to disambiguate by current space when multiple matching connections exist.",inputSchema:{type:"object",additionalProperties:!1,required:["integrationType"],properties:{integrationType:{type:"string"},spaceId:{type:"string"}}},call:async e=>Sr(t,e)},{name:"integration_endpoint_schema_get",description:"Read OpenAPI 3.1 schema for one integration type.",inputSchema:{type:"object",additionalProperties:!1,required:["integrationType"],properties:{integrationType:{type:"string"}}},call:async e=>l(await Ne(f(e,"integrationType")))},{name:"integration_endpoint_call",description:"Call one allowlisted backend integration endpoint by integrationType and operationId. For endpoints requiring connectionId, first call integration_connections_list and pass selected id as query.connectionId. Mutating or destructive endpoints require confirm=true. Supports JSON, form, multipart files, request headers, redirects, and binary downloads.",inputSchema:uo(),call:async e=>l(await Wt(so(e)))}]}async function Sr(t,e){let n={type:f(e,"integrationType")},r=J(e,"spaceId");return r&&(n.spaceId=r),l(await t.readResourceItems("connections",{fieldEqualTo:n}))}function vr(t){return[{name:"auth_email_request_code",description:"Request email login code via Beepflow auth service.",inputSchema:{type:"object",additionalProperties:!1,required:["email"],properties:{email:{type:"string"}}},call:async e=>{let n=f(e,"email");return await Xe(n),ro(`code sent to ${n}`)}},{name:"auth_email_verify_code",description:"Verify email login code, persist JWT for workspace.",inputSchema:{type:"object",additionalProperties:!1,required:["email","code"],properties:{email:{type:"string"},code:{type:"string"}}},call:async e=>{let n=await Ye(f(e,"email"),f(e,"code"));return t.close(),l(n)}},{name:"auth_google_start",description:"Create Google OAuth login URL + request id.",inputSchema:{type:"object",additionalProperties:!1,properties:{scopes:{type:"string"}}},call:async e=>{let n=J(e,"scopes")??"openid email profile";return l(await et(n))}},{name:"auth_google_get_token",description:"Fetch Google OAuth token using request id, persist JWT for workspace.",inputSchema:{type:"object",additionalProperties:!1,required:["requestId"],properties:{requestId:{type:"string"}}},call:async e=>{let n=await tt(f(e,"requestId"));return t.close(),l(n)}},{name:"auth_sign_out",description:"Delete stored JWT for current workspace.",inputSchema:ee,call:async()=>(t.close(),l(await He()))}]}async function Tr(t,e){let n=f(e,"query"),r=L(e,"limit")??25,o=Je(e,"includeDeprecated")??!1,[i,s]=await Promise.all([Cr(n,r),t.readResourceItems("blueprint-operators")]),c=[];for(let u of i){let d=s[u.operatorId];d?.hidden!==!0&&(!o&&d?.isDeprecated===!0||c.push(jr(u,d)))}return l({results:c})}async function Ir(t,e){let n=f(e,"blueprintId"),r=f(e,"query"),o=L(e,"limit")??25,i=J(e,"connectionId"),[s,c,u]=await Promise.all([t.readResourceItem("blueprints",n),t.readResourceItems("schemas"),t.readResourceItems("connections")]);if(!s)return l({results:[]});let d=Ft(s,c,u,i),p=Wr(d,r,o);return l({results:p})}async function Pr(t){let e=await Ar(),n=await t.readResourceItem("user-locations",e),r=Dr(n);if(!r)return l({email:e,tabId:null,location:n,tab:null,blueprint:null,blueprintView:null,blueprintOperators:{},contextFields:[]});let o=await t.readResourceItem("tabs",r);if(o?.type!=="blueprint")return l({email:e,tabId:r,location:n,tab:o,blueprint:null,blueprintView:null,blueprintOperators:{},contextFields:[]});let[i,s]=await Promise.all([t.readResourceItem("blueprints",r),t.readResourceItem("blueprint-views",r)]);if(!i)return l({email:e,tabId:r,location:n,tab:o,blueprint:null,blueprintView:s,blueprintOperators:{},contextFields:[]});let[c,u,d]=await Promise.all([xr(t,i),t.readResourceItems("schemas"),t.readResourceItems("connections")]),p=Ft(i,u,d,void 0);return l({email:e,tabId:r,location:n,tab:o,blueprint:i,blueprintView:s,blueprintOperators:c,contextFields:p})}async function xr(t,e){let n=Er(e),r=await t.readResourceItems("blueprint-operators"),o={};for(let i in n)o[i]=r[i]??null;return o}function Er(t){let e=t.nodes,n={};if(!x(e))return n;for(let r in e){let o=e[r];if(!x(o))continue;let i=o.operatorId;typeof i=="string"&&i.trim()&&(n[i]=!0)}return n}async function Ar(){let t=await O();if(!t)throw new Error("missing jwt: set BEEPFLOW_JWT or run auth tool to persist token");let e=await q(t),n=C(e).email;if(!n)throw new Error("current jwt does not include email");return n}function Dr(t){let e=t?.blueprint;if(!x(e))return;let n=e.id;return typeof n=="string"&&n.trim()?n:void 0}async function Cr(t,e){let n=await O();if(!n)throw new Error("missing jwt: set BEEPFLOW_JWT or run auth tool to persist token");let r=await q(n),o=w(),i=await fetch(`${o.workspaceUrl}/blueprint/operators/search`,{method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},body:JSON.stringify({query:t,limit:e})});if(!i.ok){let u=await i.text().catch(()=>"");throw new Error(`blueprint/operators/search failed: ${i.status} ${u}`.trim())}let s=await i.json().catch(()=>{});if(!Array.isArray(s))throw new Error("blueprint/operators/search returned invalid payload");let c=[];for(let u of s){if(!x(u))continue;let d=u.operatorId,p=u.score;typeof d!="string"||typeof p!="number"||c.push({operatorId:d,score:p})}return c}function jr(t,e){return{kind:"operator",id:t.operatorId,name:Y(e,"name"),categoryPath:qt(e,"categoryPath"),aliases:qt(e,"aliases"),doc:Y(e,"doc"),inputs:Lr(e),output:zr(e),score:t.score}}function Ft(t,e,n,r){let o=Br(t.context,e),i=[];for(let s of o){if(!s.connectionId||r&&s.connectionId!==r)continue;let c=n[s.connectionId],u=Fr(s.path);for(let d in s.schema)i.push({kind:"contextField",connectionId:s.connectionId,connectionLabel:c?.label??"???",path:u,field:d,type:s.schema[d]??"wildcard",score:0})}return i}function Br(t,e){if(!t?.type)return[];let n=_r(t);if(n){let i=e[n];return i?[i]:[]}let r=P(t.config,"connectionId"),o=[];for(let i in e){let s=e[i];if(s)switch(!0){case!!r:s.connectionId===r&&o.push(s);break;case s.type===t.type:o.push(s);break}}return o}function _r(t){let e=t.config,n=P(e,"connectionId");if(n)switch(t.type){case"ApacheKafkaTopic":return T(n,{topicName:P(e,"topicName")});case"ShopifyWebhook":return T(n,{topicName:Nr(e)});case"RabbitMQStream":case"MQTTTopic":return T(n,{streamPattern:P(e,"streamPattern")});case"QdrantCollection":case"BaseVectorCollection":case"BaseLookupCollection":case"BaseEventCollection":return T(n,{collectionName:P(e,"collectionName")});case"AerospikeSet":return T(n,{namespace:P(e,"namespace"),setName:P(e,"setName")});case"KaggleFile":return T(n,{datasetRef:P(e,"datasetRef"),fileName:P(e,"filePath")});case"GoogleDriveFile":return T(n,{fileId:P(e,"fileId"),parser:P(e,"parser")});case"GmailMessage":return T(n,{resource:"message"});case"GmailThread":return T(n,{resource:"thread"});case"GmailEvent":return T(n,{resource:"event"});case"GorgiasEvent":return T(n,{resource:"event",variant:Jr(e)?"message":"ticket"});case"GorgiasTicket":return T(n,{resource:"ticket"})}}function Wr(t,e,n){let r=[];return t.forEach((o,i)=>{let s=qr(e,Or(o));s!==void 0&&r.push({field:{...o,score:s},index:i})}),r.sort((o,i)=>i.field.score-o.field.score||o.index-i.index).slice(0,n).map(o=>o.field)}function Or(t){return[t.connectionLabel,t.path,t.field,t.type].join(" ")}function qr(t,e){let n=Ot(t);if(n.length===0)return;let r=e.toLowerCase(),o=Ot(e),i=0;for(let s of n){let c=Mr(s,o),u=Math.max(c,r.includes(s)?.82:0);if(u<=0)return;i+=u}return Number((i/n.length).toFixed(4))}function Mr(t,e){let n=0;for(let r of e)switch(!0){case r===t:n=Math.max(n,1);break;case r.startsWith(t):n=Math.max(n,.92);break;case r.includes(t):n=Math.max(n,.82);break;case(t.length>=3&&r.length>=3):n=Math.max(n,$r(t,r));break}return n}function $r(t,e){let n=Math.max(t.length,e.length);if(n===0)return 0;let r=1-Ur(t,e)/n;return r>=.72?r*.7:0}function Ur(t,e){let n=Array.from({length:e.length+1},(o,i)=>i),r=Array.from({length:e.length+1},()=>0);for(let o=1;o<=t.length;o+=1){r[0]=o;for(let i=1;i<=e.length;i+=1){let s=t[o-1]===e[i-1]?0:1;r[i]=Math.min(n[i]+1,r[i-1]+1,n[i-1]+s)}for(let i=0;i<n.length;i+=1)n[i]=r[i]??0}return n[e.length]??0}function Ot(t){return t.toLowerCase().split(/[^a-z0-9]+/).map(e=>e.trim()).filter(Boolean)}function T(t,e){let n="";for(let r in e){let o=e[r];if(!o)return;n+=`${r} = ${o} `}if(n=n.trim(),!!n)return hr("md5").update(`${t} ${n}`).digest("hex")}function Fr(t){if(!t)return"";let e=[];for(let n in t)e.push(t[n]??"");return e.filter(Boolean).join("/")}function Nr(t){let e=t?.webhookTopics;if(x(e)){for(let n in e)if(e[n]===!0)return n}}function Jr(t){let e=t?.webhookTriggers;if(!x(e))return!1;for(let n in e)if(e[n]===!0&&gr.includes(n))return!0;return!1}function P(t,e){let n=t?.[e];return typeof n=="string"&&n.trim()?n:void 0}function Y(t,e){let n=t?.[e];return typeof n=="string"?n:void 0}function qt(t,e){let n=t?.[e];return Array.isArray(n)?n.filter(r=>typeof r=="string"):[]}function Lr(t){return Array.isArray(t?.inputs)?t.inputs.map(e=>Nt(e)).filter(e=>e.name):[]}function zr(t){let e=t?.output;if(!x(e))return;let n=Nt(e);return n.name?n:void 0}function Nt(t){let e=x(t)?t:void 0,n=x(e?.type)?e.type:void 0;return{name:Y(e,"name")??"",type:Y(n,"type")??"",doc:Y(e,"doc")}}async function Gr(t,e){let n=f(e,"channel"),r=ye(e,"event"),o=J(e,"responseChannel")??n,i=J(e,"responseResource"),s=J(e,"responseAction"),c=io(e,"responseKey"),u=L(e,"timeoutMs")??15e3;Qr(n,r),await t.start();let d=t.waitForChannelEvent(o,p=>no(p,i,s,c),u);return t.sendChannelEvent(n,r),l(await d)}function Qr(t,e){if(t==="replicated-state"&&e.resource==="connections"&&e.action!=="snapshot")throw new Error("connections are read-only through MCP")}async function Vr(t,e){let n=f(e,"resultId"),r=L(e,"timeoutMs")??15e3,o=L(e,"quietMs")??250,i=`${n}:events`,s=`results:${i}`;await t.start();let c=t.collectChannelEvents(s,u=>u.key===i,r,o);t.sendChannelEvent("results",{resource:"results",key:i,action:"subscribe-key"});try{return l(to(await c))}finally{t.sendChannelEvent("results",{resource:"results",key:i,action:"unsubscribe-key"})}}async function Kr(t,e){let n=f(e,"resultId");return await t.start(),t.sendChannelEvent("results",{resource:"results",key:n,action:"delete-state"}),l({ok:!0})}async function Hr(t,e){let n=f(e,"resultId"),r=ye(e,"offsets");return await t.start(),t.sendChannelEvent("results",{resource:"results",key:n,action:"set-offsets",value:r}),l({ok:!0})}async function Zr(t,e){let n=f(e,"channel");if(!$t.includes(n))throw new Error(`unsupported metrics channel: ${n}`);let r=L(e,"timeoutMs")??15e3;await t.start();let o=t.waitForChannelEvent(n,i=>i.resource===n,r);return t.sendChannelEvent(n,{resource:n,action:"subscribe-resource"}),l(await o)}async function Xr(t){let e=globalThis.crypto.randomUUID(),n=Date.now();await t.start();let r=t.waitForChannelEvent("socket-latency",i=>i.eventId===e,15e3);t.sendChannelEvent("socket-latency",{resource:"socket-latency",action:"ping",eventId:e});let o=await r;return l({...o,clientRoundtripMs:Date.now()-n})}async function Yr(t,e){let n=f(e,"channel");if(!Mt.includes(n))throw new Error(`unsupported offset extent channel: ${n}`);let r=ye(e,"key"),o=L(e,"timeoutMs")??15e3;await t.start();let i=t.waitForChannelEvent(n,s=>JSON.stringify(s.key)===JSON.stringify(r),o);t.sendChannelEvent(n,{resource:n,key:r,action:"on"});try{return l(await i)}finally{t.sendChannelEvent(n,{resource:n,key:r,action:"off"})}}function eo(t){let e=oo(t,"keys"),n=X(t,"fieldEqualTo"),r=Je(t,"all")??(!e&&!n),o={};return r&&(o.all=!0),e&&(o.keys=e),n&&(o.fieldEqualTo=n),o}function to(t){let e={},n;for(let r of t){let o=r.value;switch(o?.kind){case"blueprint":n=o.value;break;case"node":{let i=o.nodeId;typeof i=="string"&&(e[i]=o.value);break}case"reset":n=void 0;for(let i in e)delete e[i];break}}return{public:n,publicByNode:e,events:t}}function no(t,e,n,r){return!(e!==void 0&&t.resource!==e||n!==void 0&&t.action!==n||r!==void 0&&JSON.stringify(t.key)!==JSON.stringify(r))}function l(t){return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}function ro(t){return{content:[{type:"text",text:t}]}}function f(t,e){let n=D(t)[e];if(typeof n!="string"||!n.trim())throw new Error(`invalid tool arguments: ${e} must be non-empty string`);return n}function J(t,e){if(t===void 0)return;let n=D(t)[e];if(n!=null){if(typeof n!="string")throw new Error(`invalid tool arguments: ${e} must be string`);return n}}function ye(t,e){let n=D(t)[e];if(!x(n))throw new Error(`invalid tool arguments: ${e} must be object`);return n}function X(t,e){let n=D(t)[e];if(n!=null){if(!x(n))throw new Error(`invalid tool arguments: ${e} must be object`);return n}}function oo(t,e){let n=D(t)[e];if(n!=null){if(!Array.isArray(n)||n.some(r=>typeof r!="string"))throw new Error(`invalid tool arguments: ${e} must be string array`);return n}}function Je(t,e){let n=D(t)[e];if(n!=null){if(typeof n!="boolean")throw new Error(`invalid tool arguments: ${e} must be boolean`);return n}}function L(t,e){let n=D(t)[e];if(n!=null){if(typeof n!="number"||!Number.isInteger(n)||n<=0)throw new Error(`invalid tool arguments: ${e} must be positive integer`);return n}}function io(t,e){return D(t)[e]}function so(t){let e=D(t);return{integrationType:f(t,"integrationType"),operationId:f(t,"operationId"),path:X(t,"path"),query:X(t,"query"),headers:X(t,"headers"),body:e.body,files:X(t,"files"),outputFilePath:J(t,"outputFilePath"),confirm:Je(t,"confirm")}}function D(t){if(!t||typeof t!="object"||Array.isArray(t))throw new Error("invalid tool arguments: expected object");return t}function x(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function ao(){return{type:"object",additionalProperties:!1,required:["query"],properties:{query:{type:"string"},limit:{type:"integer",minimum:1},includeDeprecated:{type:"boolean"}}}}function co(){return{type:"object",additionalProperties:!1,required:["blueprintId","query"],properties:{blueprintId:{type:"string"},query:{type:"string"},limit:{type:"integer",minimum:1},connectionId:{type:"string"}}}}function uo(){return{type:"object",additionalProperties:!1,required:["integrationType","operationId"],properties:{integrationType:{type:"string"},operationId:{type:"string"},path:_,query:_,headers:_,body:{},files:{type:"object",additionalProperties:{type:"object",additionalProperties:!1,properties:{filePath:{type:"string"},base64:{type:"string"},fileName:{type:"string"},contentType:{type:"string"}}}},outputFilePath:{type:"string"},confirm:{type:"boolean"}}}}function po(){return{type:"object",additionalProperties:!1,required:["channel","event"],properties:{channel:{type:"string"},event:_,responseChannel:{type:"string"},responseResource:{type:"string"},responseAction:{type:"string"},responseKey:{},timeoutMs:{type:"integer",minimum:1}}}}function lo(){return{type:"object",additionalProperties:!1,required:["resultId"],properties:{resultId:{type:"string"},timeoutMs:{type:"integer",minimum:1},quietMs:{type:"integer",minimum:1}}}}function fo(){return{type:"object",additionalProperties:!1,required:["resultId"],properties:{resultId:{type:"string"}}}}function mo(){return{type:"object",additionalProperties:!1,required:["resultId","offsets"],properties:{resultId:{type:"string"},offsets:_}}}function ho(){return{type:"object",additionalProperties:!1,required:["channel"],properties:{channel:{type:"string",enum:$t},timeoutMs:{type:"integer",minimum:1}}}}function go(){return{type:"object",additionalProperties:!1,required:["channel","key"],properties:{channel:{type:"string",enum:Mt},key:_,timeoutMs:{type:"integer",minimum:1}}}}var te="application/json";function Jt(t=V()){return[{uri:"beepflow://resources",name:"Beepflow workspace resource registry",description:"Resource registry supported by this MCP server, including item schema URIs.",mimeType:te,read:async()=>we("beepflow://resources",U)},{uri:"beepflow://resource-schemas",name:"Beepflow workspace resource schema registry",description:"JSON Schema registry for resource items supported by this MCP server.",mimeType:te,read:async()=>we("beepflow://resource-schemas",pe)},...pe.map(e=>({uri:e.uri,name:`Beepflow ${e.resource} item schema`,description:`JSON Schema for ${e.resource} resource items.`,mimeType:te,read:async()=>we(e.uri,e)})),...U.map(e=>({uri:`beepflow://resources/${e.name}`,name:`Beepflow ${e.name}`,description:e.description,mimeType:te,read:async()=>{let n=await t.readResourceItems(e.name);return we(`beepflow://resources/${e.name}`,n)}}))]}function we(t,e){return{contents:[{uri:t,mimeType:te,text:JSON.stringify(e,null,2)}]}}var Lt=`Use this Beepflow MCP server to inspect and safely operate the authenticated Beepflow workspace. It exposes workspace resources, blueprint context, live results and metrics, integration OpenAPI endpoints, and auth helpers.
24
+
25
+ Default workflow:
26
+ - For current tab, current blueprint, current location, or current blueprint context questions, call current_user_location_read first.
27
+ - Discover resources with resources_list or beepflow://resources.
28
+ - Read item schemas with resource_schema_get or beepflow://resource-schemas/<resource>.
29
+ - Before resource_upsert, read schema unless editing an item already read from the same resource.
30
+ - For existing resource items, read with resource_query first.
31
+ - Upserts send full item state, not JSON patches. Preserve unchanged fields.
32
+ - Omit updatedAt on creates and manual edits unless preserving an existing value. createdAt and updatedAt values are nanoseconds since Unix epoch.
33
+ - Writable resources: users, roles, spaces, tabs, schemas, blueprints, blueprint-views, user-locations, space-join-requests.
34
+ - Read-only resources: connections, blueprint-operators.
35
+ - connections.config is redacted and cannot be read through MCP.
36
+ - Prefer typed tools over workspace_channel_request. Use raw websocket requests only when no typed tool fits and user intent is clear.
37
+ - Run independent tool calls in parallel whenever possible, including writes. Serialize only when one call needs another call's result, targets the same resource/key, changes auth/session state, or uses the same live subscription target.
38
+
39
+ Blueprint workflow:
40
+ - Tabs are navigation items. A blueprint tab normally has matching blueprints and blueprint-views records keyed by the same tab id.
41
+ - Use blueprint_operators_search to find valid operator ids plus input/output metadata.
42
+ - Use blueprint_context_fields_search to find fields available from the blueprint context schemas.
43
+ - Blueprint modes are test and explore. Result ids are tabId-test and tabId-explore.
44
+ - Use results_read for blueprint result events.
45
+ - Use metrics_read, socket_latency_ping, and stream_offset_extents_read for runtime diagnostics.
46
+ - results_delete_state and results_set_offsets change state.
47
+
48
+ Integration workflow:
49
+ - Use integrations_list, integration_endpoints_list, and integration_endpoint_schema_get before integration_endpoint_call.
50
+ - For endpoints requiring connectionId, query connections by integration type first. Use current_user_location_read only to disambiguate by current space when multiple matching connections exist.
51
+ - integration_endpoint_call can cause external reads or writes, read local files for multipart uploads, and write binary downloads to disk.
52
+ - Only call mutating or destructive integration endpoints when the user explicitly requested it. Pass confirm=true only after explicit confirmation or unmistakable user intent.
53
+
54
+ Auth workflow:
55
+ - Tools require workspace auth from BEEPFLOW_JWT, --jwt, or persisted auth tools.
56
+ - auth_email_verify_code, auth_google_get_token, token refresh, and auth_sign_out modify stored credentials.
57
+
58
+ When uncertain, inspect schemas and resources first. Ask before destructive actions.`;var ke=V(),{server:yo,closeServer:wo}=ze({serverName:"mcp",serverVersion:"0.1.0",instructions:Lt,tools:Ut(ke),resources:Jt(ke),onInitialized:()=>{ke.start().catch(()=>{})}});process.on("SIGINT",()=>zt("SIGINT"));process.on("SIGTERM",()=>zt("SIGTERM"));yo.start();function zt(t){ke.close(),wo(t)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beepflow/mcp",
3
- "version": "2026.4.4",
3
+ "version": "2026.4.7",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=24.6.0"
@@ -16,7 +16,7 @@
16
16
  ],
17
17
  "scripts": {
18
18
  "start:src": "node --experimental-strip-types ./src/index.ts",
19
- "test:src": "node --experimental-strip-types --test ./src/**/*.test.ts",
19
+ "test:src": "node --experimental-strip-types --test \"./src/**/*.test.ts\" \"../shared/replicated-state/**/*.test.ts\"",
20
20
  "build": "node --input-type=module -e \"import fs from 'node:fs'; fs.rmSync('dist', { recursive: true, force: true });\" && tsc -p tsconfig.json --noEmit && esbuild src/index.ts --bundle --platform=node --format=esm --target=node24 --minify --banner:js='#!/usr/bin/env node' --outfile=dist/index.js && node --input-type=module -e \"import fs from 'node:fs'; fs.chmodSync('dist/index.js', 0o755);\"",
21
21
  "start": "node ./dist/index.js",
22
22
  "test": "yarn test:src && yarn build && node ./dist/index.js < /dev/null",