@beepflow/mcp 2026.4.8 → 2026.5.1

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 +1 -1
  2. package/dist/index.js +30 -43
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -11,7 +11,7 @@ codex mcp add beepflow -- npx -y @beepflow/mcp
11
11
 
12
12
  ### Claude Code
13
13
  ```sh
14
- claude mcp add beepflow -- npx -y @beepflow/mcp
14
+ claude mcp add --scope user beepflow -- npx -y @beepflow/mcp
15
15
  ```
16
16
 
17
17
  ### OpenCode
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import{stdin as ne,stdout as Le}from"node:process";function ze(t){let e=new Map;for(let d of t.tools)e.set(d.name,d);let n=new Map;for(let d of t.resources??[])n.set(d.uri,d);let r=!1,o="",i={start:()=>{ne.setEncoding("utf8"),ne.on("data",d=>c(typeof d=="string"?d:d.toString("utf8"))),ne.on("end",()=>s("stdin-end")),ne.on("error",()=>s("stdin-error"))}};function s(d){if(!r){r=!0;try{Le.write(JSON.stringify({jsonrpc:"2.0",method:"notifications/message",params:{level:"info",data:`server closing: ${d}`}})+`
3
- `)}catch{}}}function c(d){for(o+=d;;){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(d){if(r)return;let y=d.id===void 0,m=d.id??null;try{switch(d.method){case"initialize":{let W={protocolVersion:(d.params??{}).protocolVersion??"2024-11-05",serverInfo:{name:t.serverName,version:t.serverVersion},capabilities:{tools:{},resources:{}},...t.instructions?{instructions:t.instructions}:{}};if(y)return;p({jsonrpc:"2.0",id:m,result:W});return}case"notifications/initialized":{t.onInitialized?.();return}case"notifications/cancelled":return;case"logging/setLevel":{if(y)return;p({jsonrpc:"2.0",id:m,result:{}});return}case"ping":{if(y)return;p({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}));p({jsonrpc:"2.0",id:m,result:{tools:b}});return}case"tools/call":{if(y)return;let b=d.params??{},S=typeof b.name=="string"?b.name:"",W=e.get(S);if(!W){p({jsonrpc:"2.0",id:m,error:{code:-32601,message:`unknown tool: ${S}`}});return}let be=await W.call(b.arguments);p({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}));p({jsonrpc:"2.0",id:m,result:{resources:b}});return}case"resources/read":{if(y)return;let b=d.params??{},S=typeof b.uri=="string"?b.uri:"",W=n.get(S);if(!W){p({jsonrpc:"2.0",id:m,error:{code:-32602,message:`unknown resource: ${S}`}});return}let be=await W.read();p({jsonrpc:"2.0",id:m,result:be});return}case"prompts/list":{if(y)return;p({jsonrpc:"2.0",id:m,result:{prompts:[]}});return}default:{if(y)return;p({jsonrpc:"2.0",id:m,error:{code:-32601,message:`method not found: ${d.method}`}})}}}catch(b){if(y)return;p({jsonrpc:"2.0",id:m,error:{code:-32603,message:b?.message??"internal error"}})}}function p(d){r||Le.write(JSON.stringify(d)+`
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)
2
+ import{stdin as ze,stdout as tr}from"node:process";function rr(t){let e=new Map;for(let l of t.tools)e.set(l.name,l);let r=new Map;for(let l of t.resources??[])r.set(l.uri,l);let n=!1,o="",i={start:()=>{ze.setEncoding("utf8"),ze.on("data",l=>a(typeof l=="string"?l:l.toString("utf8"))),ze.on("end",()=>s("stdin-end")),ze.on("error",()=>s("stdin-error"))}};function s(l){if(!n){n=!0;try{tr.write(JSON.stringify({jsonrpc:"2.0",method:"notifications/message",params:{level:"info",data:`server closing: ${l}`}})+`
3
+ `)}catch{}}}function a(l){for(o+=l;;){let h=o.indexOf(`
4
+ `);if(h===-1)return;let y=o.slice(0,h).trim();if(o=o.slice(h+1),!y)continue;let T;try{T=JSON.parse(y)}catch{continue}c(T)}}async function c(l){if(n)return;let h=l.id===void 0,y=l.id??null;try{switch(l.method){case"initialize":{let de={protocolVersion:(l.params??{}).protocolVersion??"2024-11-05",serverInfo:{name:t.serverName,version:t.serverVersion},capabilities:{tools:{},resources:{}},...t.instructions?{instructions:t.instructions}:{}};if(h)return;u({jsonrpc:"2.0",id:y,result:de});return}case"notifications/initialized":{t.onInitialized?.();return}case"notifications/cancelled":return;case"logging/setLevel":{if(h)return;u({jsonrpc:"2.0",id:y,result:{}});return}case"ping":{if(h)return;u({jsonrpc:"2.0",id:y,result:{}});return}case"tools/list":{if(h)return;let T=t.tools.map(D=>({name:D.name,description:D.description,inputSchema:D.inputSchema}));u({jsonrpc:"2.0",id:y,result:{tools:T}});return}case"tools/call":{if(h)return;let T=l.params??{},D=typeof T.name=="string"?T.name:"",de=e.get(D);if(!de){u({jsonrpc:"2.0",id:y,error:{code:-32601,message:`unknown tool: ${D}`}});return}let Tt=await de.call(T.arguments);u({jsonrpc:"2.0",id:y,result:Tt});return}case"resources/list":{if(h)return;let T=(t.resources??[]).map(D=>({uri:D.uri,name:D.name,description:D.description,mimeType:D.mimeType}));u({jsonrpc:"2.0",id:y,result:{resources:T}});return}case"resources/read":{if(h)return;let T=l.params??{},D=typeof T.uri=="string"?T.uri:"",de=r.get(D);if(!de){u({jsonrpc:"2.0",id:y,error:{code:-32602,message:`unknown resource: ${D}`}});return}let Tt=await de.read();u({jsonrpc:"2.0",id:y,result:Tt});return}case"prompts/list":{if(h)return;u({jsonrpc:"2.0",id:y,result:{prompts:[]}});return}default:{if(h)return;u({jsonrpc:"2.0",id:y,error:{code:-32601,message:`method not found: ${l.method}`}})}}}catch(T){if(h)return;u({jsonrpc:"2.0",id:y,error:{code:-32603,message:T?.message??"internal error"}})}}function u(l){n||tr.write(JSON.stringify(l)+`
5
+ `)}return{server:i,closeServer:s}}import{createHash as us}from"node:crypto";import ir from"node:os";import ye from"node:path";var io={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 so(t){let r=nr(t,"--env")??nr(t,"--environment")??process.env.BEEPFLOW_ENV??"live";if(r==="dev"||r==="live")return r;throw new Error(`invalid BEEPFLOW_ENV: ${r}`)}function or(t){let e=so(t);return io[e]}function nr(t,e){for(let r=0;r<t.length;r+=1){let n=t[r];if(n===e){let i=t[r+1];if(!i)throw new Error(`missing value for ${e}`);return i}let o=`${e}=`;if(n&&n.startsWith(o)){let i=n.slice(o.length);if(!i)throw new Error(`missing value for ${e}`);return i}}}function k(){let t=process.argv.slice(2),e=or(t),r=St("workspace url",[he(t,"--workspace-url"),process.env.BEEPFLOW_WORKSPACE_URL,e.workspaceUrl]),n=St("auth url",[he(t,"--auth-url"),process.env.BEEPFLOW_AUTH_URL,e.authUrl]),o=St("auth domain",[he(t,"--auth-domain"),process.env.BEEPFLOW_AUTH_DOMAIN,e.authDomain]),i=he(t,"--token-store-path")??process.env.BEEPFLOW_TOKEN_STORE_PATH??ao(),s=he(t,"--replicated-state-db-path")??process.env.BEEPFLOW_REPLICATED_STATE_DB_PATH??co();return{environmentName:e.name,workspaceUrl:r.replace(/\/+$/,""),authUrl:n.replace(/\/+$/,""),authDomain:o,jwtFromEnvironment:he(t,"--jwt")??process.env.BEEPFLOW_JWT,tokenStorePath:i,replicatedStateDatabasePath:s}}function he(t,e){for(let r=0;r<t.length;r+=1){let n=t[r];if(n===e){let i=t[r+1];if(!i)throw new Error(`missing value for ${e}`);return i}let o=`${e}=`;if(n&&n.startsWith(o)){let i=n.slice(o.length);if(!i)throw new Error(`missing value for ${e}`);return i}}}function ao(){let t=process.env.APPDATA;if(t)return ye.join(t,"beepflow-mcp","workspace-access-tokens.json");let e=process.env.XDG_CONFIG_HOME;return e?ye.join(e,"beepflow-mcp","workspace-access-tokens.json"):ye.join(ir.homedir(),".config","beepflow-mcp","workspace-access-tokens.json")}function co(){let t=process.env.LOCALAPPDATA;if(t)return ye.join(t,"beepflow-mcp","replicated-state.sqlite");let e=process.env.XDG_CACHE_HOME;return e?ye.join(e,"beepflow-mcp","replicated-state.sqlite"):ye.join(ir.homedir(),".cache","beepflow-mcp","replicated-state.sqlite")}function St(t,e){for(let r of e)if(typeof r=="string"&&r.trim())return r;throw new Error(`missing ${t}`)}import It from"node:fs/promises";import lo from"node:path";import po from"node:crypto";function te(t){let e=t.split(".");if(e.length<2)return{accessToken:t,email:void 0,exp:void 0,provider:void 0};let r=uo(e[1]??"");if(!r)return{accessToken:t,email:void 0,exp:void 0,provider:void 0};let n;try{n=JSON.parse(r)}catch{return{accessToken:t,email:void 0,exp:void 0,provider:void 0}}let o=typeof n.email=="string"?n.email.toLowerCase():void 0,i=typeof n.exp=="number"?n.exp:void 0,s=typeof n.provider=="string"?n.provider:void 0;return{accessToken:t,email:o,exp:i,provider:s}}function sr(t){return t?t.length<=12?`${t.slice(0,4)}\u2026`:`${t.slice(0,6)}\u2026${t.slice(-4)}`:""}function Ve(){return po.randomBytes(9).toString("base64url")}function uo(t){if(!t)return;let e=t.replace(/-/g,"+").replace(/_/g,"/"),r=(4-e.length%4)%4,n=e+"=".repeat(r);try{return Buffer.from(n,"base64").toString("utf8")}catch{return}}async function Z(){let t=k();return t.jwtFromEnvironment?t.jwtFromEnvironment:(await fo(t.tokenStorePath,t.workspaceUrl))?.accessToken}async function be(t){let e=k(),r=te(t),n={accessToken:t,email:r.email,provider:r.provider,exp:r.exp};return await mo(e.tokenStorePath,e.workspaceUrl,n),n}async function ar(){let t=k(),e=await vt(t.tokenStorePath),r=e[t.workspaceUrl]!==void 0;return delete e[t.workspaceUrl],await cr(t.tokenStorePath,e),{workspaceUrl:t.workspaceUrl,deleted:r}}function Ge(t){return{email:t.email,provider:t.provider,exp:t.exp,accessToken:sr(t.accessToken)}}async function fo(t,e){return(await vt(t))[e]}async function mo(t,e,r){let n=await vt(t);n[e]=r,await cr(t,n)}async function vt(t){try{let e=await It.readFile(t,"utf8"),r=JSON.parse(e);return!r||typeof r!="object"?{}:r}catch{return{}}}async function cr(t,e){await It.mkdir(lo.dirname(t),{recursive:!0}),await It.writeFile(t,JSON.stringify(e,null,2)+`
6
+ `,"utf8")}async function pr(t){let e=k(),r=await fetch(`${e.authUrl}/email/request-code`,{method:"POST",headers:{"content-type":"application/json",domain:e.authDomain},body:JSON.stringify({email:t})});if(!r.ok){let n=await r.text().catch(()=>"");throw new Error(`email/request-code failed: ${r.status} ${n}`.trim())}}async function dr(t,e){let r=k(),n=await fetch(`${r.authUrl}/email/verify-code`,{method:"POST",headers:{"content-type":"application/json",domain:r.authDomain},body:JSON.stringify({email:t,code:e})}),o=await n.json().catch(()=>{});if(!n.ok)throw new Error(`email/verify-code failed: ${n.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 be(i);return{workspaceUrl:r.workspaceUrl,...Ge(s)}}import go from"node:crypto";async function ur(){let t=k(),e=go.randomUUID(),r=new URL(`${t.authUrl}/google-form`);return r.searchParams.set("requestId",e),r.searchParams.set("scopes","openid email profile"),{requestId:e,url:r.toString()}}async function lr(t){let e=k(),r=new URL(`${e.authUrl}/google-auth-token`);r.searchParams.set("id",t);let n=await fetch(r.toString(),{headers:{domain:e.authDomain}}),o=await n.json().catch(()=>{});if(!n.ok)throw new Error(`google-auth-token failed: ${n.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 be(i);return{workspaceUrl:e.workspaceUrl,...Ge(s)}}async function X(t){let e=te(t);if(e.provider!=="google"||!e.exp)return t;let r=Date.now(),n=e.exp*1e3,o=300*1e3;if(n-r>=o)return t;let i=k(),s=await fetch(`${i.authUrl}/google-refresh`,{method:"GET",headers:{Authorization:`Bearer ${t}`}}),a=await s.json().catch(()=>{});if(!s.ok)return t;let c=typeof a?.access_token=="string"?a.access_token:"";return c?(await be(c),c):t}async function fr(t){let e=k(),r=await fetch(`${e.workspaceUrl}/users/is-member`,{method:"GET",headers:{Authorization:`Bearer ${t}`}});if(!r.ok){let o=await r.text().catch(()=>"");throw new Error(`users/is-member failed: ${r.status} ${o}`.trim())}if((await r.json().catch(()=>{}))?.isMember!==!0)throw new Error("user not member of workspace")}import{isDeepStrictEqual as Lo}from"node:util";import ho from"node:crypto";import yo from"node:fs";import bo from"node:path";import{DatabaseSync as wo}from"node:sqlite";var Ke=class{database;databasePath;scope;constructor(e,r){this.databasePath=e,this.scope=r}async loadItems(e){let r=this.getDatabase().prepare("select key, value_json from replicated_items where scope = ? and resource = ?").all(this.scope,e),n={};for(let o of r)n[o.key]=JSON.parse(o.value_json);return r.length>0?n:null}async persistItem(e,r,n){this.getDatabase().prepare(`insert into replicated_items (scope, resource, key, value_json, saved_at_ms)
7
7
  values (?, ?, ?, ?, ?)
8
8
  on conflict(scope, resource, key) do update set
9
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(`
10
+ saved_at_ms = excluded.saved_at_ms`).run(this.scope,e,r,JSON.stringify(n),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:(yo.mkdirSync(bo.dirname(this.databasePath),{recursive:!0}),this.database=new wo(this.databasePath),this.database.exec(`
11
11
  create table if not exists replicated_items (
12
12
  scope text not null,
13
13
  resource text not null,
@@ -16,45 +16,32 @@ import{stdin as ne,stdout as Le}from"node:process";function ze(t){let e=new Map;
16
16
  saved_at_ms integer not null,
17
17
  primary key (scope, resource, key)
18
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,p=setTimeout(()=>{y(),u&&clearTimeout(u),s(new Error(`channel event timeout: ${e}`))},r),d=()=>{clearTimeout(p),y(),i(c)},y=this.onChannel(e,m=>{n(m)&&(c.push(m),u&&clearTimeout(u),u=setTimeout(d,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"}]},dn=["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:dn,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"},pn={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:pn},{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. Omit style when coordinates should be computed by the frontend after dynamic node dimensions are measured. Known visualization blocks are intentionally accepted as additional properties.",required:["id"],properties:{id:{...a,description:"Node id; must match key in blueprint view nodes record."},style:hn}},dt=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."}}},pt=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 de=[kt,ft,gt,yt,lt,mt,pt,dt,ut,wt,ht];function pe(t){return de.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 p=B(c),d=B(u);if(!(s in e))p||(n[s]=c,r[s]=null,o=!0);else if(!(s in t))d||(n[s]=null,r[s]=u,o=!0);else{if(p&&d)continue;if(p&&!d)n[s]=null,r[s]=u,o=!0;else if(!p&&d)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(p=>{this.logger.warn(`Failed to persist ${n}:${r}: ${String(p)}`)}),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}
19
+ `),this.database)}};function mr(t,e){let r=e??"unknown-user";return ho.createHash("sha256").update(`${t}
20
+ ${r}`).digest("hex")}function gr(t,e,r){let n=t.replace(/^http/,"ws"),o=encodeURIComponent(e),i=encodeURIComponent(r);return`${n}/base/${o}/${i}`}var Qe=class{websocket;sessionId=Ve();workspaceUrl;accessToken;channelListeners=new Map;disconnectListeners=new Set;ackWaiters=new Map;intentionallyClosed=!1;constructor(e,r){this.workspaceUrl=e,this.accessToken=r}async connect(e){this.intentionallyClosed=!1,this.sessionId=Ve();let r=gr(this.workspaceUrl,this.accessToken,this.sessionId),n=new WebSocket(r,"echo");this.websocket=n,await new Promise((o,i)=>{let s=setTimeout(()=>i(new Error("websocket open timeout")),e);n.onopen=()=>{clearTimeout(s),o()},n.onerror=()=>{clearTimeout(s),i(new Error("websocket open failed"))}}),n.onmessage=o=>this.processMessage(o.data),n.onclose=()=>this.processClose(),n.onerror=()=>this.processClose()}getSessionId(){return this.sessionId}send(e,r){if(!this.websocket||this.websocket.readyState!==WebSocket.OPEN)throw new Error("workspace websocket not connected");this.websocket.send(`${e};${JSON.stringify(r)}`)}sendWithAck(e,r,n=5e3){let o=Ve(),i={...r,eventId:o};return new Promise(s=>{let a=setTimeout(()=>{this.ackWaiters.delete(o),s({ok:!1,reason:"timeout"})},n);this.ackWaiters.set(o,{resolve:s,timeout:a}),this.send(e,i)})}onChannel(e,r){return this.channelListeners.has(e)||this.channelListeners.set(e,new Set),this.channelListeners.get(e).add(r),()=>this.channelListeners.get(e)?.delete(r)}onDisconnected(e){return this.disconnectListeners.add(e),()=>this.disconnectListeners.delete(e)}waitForChannelEvent(e,r,n){return new Promise((o,i)=>{let s=setTimeout(()=>{a(),i(new Error(`channel event timeout: ${e}`))},n),a=this.onChannel(e,c=>{r(c)&&(clearTimeout(s),a(),o(c))})})}collectChannelEvents(e,r,n,o){return new Promise((i,s)=>{let a=[],c,u=setTimeout(()=>{h(),c&&clearTimeout(c),s(new Error(`channel event timeout: ${e}`))},n),l=()=>{clearTimeout(u),h(),i(a)},h=this.onChannel(e,y=>{r(y)&&(a.push(y),c&&clearTimeout(c),c=setTimeout(l,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 r=typeof e=="string"?e:"",n=r.indexOf(";");if(n===-1)return;let o=r.slice(0,n),i=r.slice(n+1),s;try{s=JSON.parse(i)}catch{return}if(o.startsWith("ack:")){this.resolveAck(o.slice(4),s);return}s=Ro(s);let a=this.channelListeners.get(o);if(a)for(let c of a)c(s)}resolveAck(e,r){let n=this.ackWaiters.get(e);n&&(this.ackWaiters.delete(e),clearTimeout(n.timeout),n.resolve(r.value??{ok:!1}))}processClose(){if(!this.intentionallyClosed)for(let e of this.disconnectListeners)e()}};function Ro(t){if(t.resource!=="connections")return t;switch(t.action){case"snapshot":return{...t,value:ko(t.value)};case"delta":return{...t,value:To(t.value)};default:return t}}function ko(t){if(!xt(t))return t;let e={};for(let r in t)e[r]=yr(t[r]);return e}function To(t){return xt(t)?{...t,pre:hr(t.pre),post:hr(t.post)}:t}function hr(t){return t===null?null:yr(t)}function yr(t){if(!xt(t))return t;let e={...t};return delete e.config,e}function xt(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}var Bt="beepflow://resource-schemas/",S={type:"number",description:"Nanoseconds since Unix epoch. Omit updatedAt on creates and manual edits unless preserving an existing value; replicated state updates it after accepted writes."},d={type:"string"},re={type:"number"},Ne={type:"integer"},x={type:"boolean"};var br={type:"object",additionalProperties:!0},wr={type:"object",additionalProperties:d},Pt={type:"object",additionalProperties:x},He={type:"object",additionalProperties:{type:"object",additionalProperties:x,properties:{list:x,detail:x,create:x,edit:x,delete:x,authorize:x}}},ue=["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"],Ze=["ManualTick","AerospikeSet","ApacheKafkaTopic","MQTTTopic","KaggleFile","RabbitMQQueue","RabbitMQStream","ShopifyWebhook","QdrantCollection","BaseVectorCollection","BaseEventCollection","BaseLookupCollection","GorgiasEvent","GorgiasTicket","GoogleDriveFile","GmailMessage","GmailThread","GmailEvent"],le={anyOf:[x,{type:"null"}]},So=["Use resource_query first when editing existing items; upsert sends whole item state, not a JSON patch. Preserve unchanged fields.","Omit updatedAt on creates and manual edits unless preserving an existing value; replicated state updates it after accepted writes."];function I(t,e,r){let n=`${Bt}${t}`;return{resource:t,uri:n,sourceType:e,notes:So,itemSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",title:`Beepflow ${t} item`,type:"object",additionalProperties:!1,required:r.required,properties:r.properties,...r.defs?{$defs:r.defs}:{}}}}var Et={$ref:"#/$defs/operatorType"},Io={type:"object",additionalProperties:!1,required:["value"],properties:{value:{description:"Raw option value written to node input literal when selected."},label:{...d,description:"Optional label shown in operator input dropdowns."}}},vo={type:"object",additionalProperties:!1,required:["type"],properties:{type:{type:"string",enum:ue,description:'Blueprint value type name. Use "list of X" for lists, never "list".'},options:{anyOf:[{type:"array",items:Io},{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:Et},{type:"null"}],description:"Allowed concrete types for wildcard pins."},linkType:{...d,description:"Type-linking group used to propagate wildcard types across pins."},widgetType:{...d,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."}}},xo={type:"object",additionalProperties:!1,required:["name","doc","type"],properties:{name:{...d,description:"Output pin name."},doc:{...d,description:"Operator output documentation shown to users."},type:Et}},Bo={type:"object",additionalProperties:!1,required:["name","doc","type"],properties:{name:{...d,description:"Input pin name; node inputs are keyed by this value."},doc:{...d,description:"Operator input documentation shown to users."},type:Et,isLiteral:{...x,description:"Whether this input must be edited as literal value instead of upstream connection."}}},Rr=I("blueprint-operators","frontend/src/tabs/blueprint/types.ts:Operator",{required:["id","type","name","doc","categoryPath","inputs"],properties:{id:{...d,description:"Stable registered operator id referenced by blueprint nodes."},type:{...d,description:"Operator kind, usually function, variable, or localVariable."},name:{...d,description:"Display name used in operator search and node labels."},aliases:{type:"array",items:d,description:"Additional search terms for this operator."},doc:{...d,description:"Operator documentation shown to users."},categoryPath:{type:"array",items:d,description:"Menu category path segments."},inputs:{type:"array",items:Bo,description:"Input pins in display order."},output:{anyOf:[xo,{type:"null"}],description:"Output pin definition, or null for side-effect-only operators."},isDeprecated:{...x,description:"Whether operator is deprecated and hidden from default search."},hidden:{...x,description:"Whether operator is hidden from menus and search."},canMock:{...x,description:"Whether test mode can mock this operator."},updatedAt:S},defs:{operatorType:vo}});var Po={type:"object",additionalProperties:!1,properties:{x:{...re,description:"Optional node world x coordinate in blueprint editor. For new nodes, never specify style.x; omit it so the frontend can place nodes after measuring dimensions."},y:{...re,description:"Optional node world y coordinate in blueprint editor. For new nodes, never specify style.y; omit it so the frontend can place nodes after measuring dimensions."},title:{...d,description:"Optional display title shown on node."},comment:{...d,description:"Optional user-authored node comment."}}},Eo={type:"object",additionalProperties:!0,description:"Blueprint view node. For new nodes, never specify style.x or style.y; omit coordinates so the frontend can place nodes after measuring dimensions. Known visualization blocks are intentionally accepted as additional properties.",required:["id"],properties:{id:{...d,description:"Node id; must match key in blueprint view nodes record."},style:Po}},kr=I("blueprint-views","frontend/src/tabs/blueprint/types.ts:BlueprintView",{required:["id","nodes"],properties:{id:{...d,description:"Blueprint tab id; must match tabs and blueprints resource id."},updatedAt:S,nodes:{type:"object",additionalProperties:Eo,description:"Editor view state keyed by node id."}}});var Ao={type:"object",additionalProperties:!1,required:["literal"],properties:{literal:{description:"Literal JSON value for this input element; null is valid when connected upstream."},nodeId:{...d,description:"Upstream node id when this value is connected to another node output."},operatorInputId:{...d,description:"Upstream output pin name used by this connection."},nodeInputIndex:{...d,description:'CRDT list index of upstream output value. Use "0.5" for any connected node output.'}}},No={type:"object",additionalProperties:!1,required:["values"],properties:{isArray:{...le,description:"Whether input accepts multiple values for one operator input."},values:{type:"object",additionalProperties:Ao,description:"Input values keyed by CRDT list index strings."},type:{type:"string",enum:ue,description:"Resolved input type override."},forceZipping:{...le,description:"Force list zipping behavior for multiple upstream values."}}},Oo={type:"object",additionalProperties:!1,required:["id","operatorId","inputs"],properties:{id:{...d,description:"Stable node id; must match key in blueprint nodes record."},operatorId:{...d,description:"Id of registered blueprint operator this node executes."},inputs:{type:"object",additionalProperties:No,description:"Node inputs keyed by operator input name."},mockNever:{...le,description:"Disable mocking for this node while testing."},skipBehavior:{type:"string",enum:["skip","null"],description:"Behavior when upstream value is skipped."},disabled:{...le,description:"Whether this node and downstream dependent nodes are disabled."},outputType:{type:"string",enum:ue,description:"Resolved output type for wildcard operators."}}},Tr={type:"object",additionalProperties:!1,required:["enabled"],properties:{enabled:{...x,description:"Whether this trigger is enabled."}}},Do={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:{...Ne,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:{...d,description:"Cron expression with seconds field, parsed by robfig/cron."},timezone:{...d,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:{...Ne,description:"Delay between executions in milliseconds."}}},blueprint:{...Tr,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:{type:"object",additionalProperties:!1,required:["enabled"],description:"Wait for generic GET/POST /:tabId/trigger calls while blueprint is active. Requires enabled true. Request method, URL, parsed body, headers, and timestamp become trigger argument. Not the same as integration-specific webhook executors such as ShopifyWebhook or GorgiasEvent.",properties:{enabled:{...x,description:"Whether this trigger is enabled."},timeoutMs:{...Ne,description:"Maximum synchronous webhook execution time in milliseconds. Runtime uses 30000 when omitted or below 1."},contentType:{type:"string",enum:["auto","application/json","text/plain","application/x-www-form-urlencoded","multipart/form-data","application/octet-stream"],description:"Request body parser. Runtime uses auto when omitted; auto infers from incoming Content-Type and falls back to JSON sniffing, UTF-8 text, then binary."}}},executor:{...Tr,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."}}},Co={type:"object",additionalProperties:!1,required:["type","trigger"],properties:{type:{type:"string",enum:Ze,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:Do,config:{...br,description:"Integration-specific context configuration."}}},Sr=I("blueprints","frontend/src/tabs/blueprint/types.ts:Blueprint",{required:["id","mode","nodes","context"],properties:{id:{...d,description:"Blueprint tab id; must match tabs resource id."},updatedAt:S,mode:{type:"string",enum:["test","explore"],description:'Execution mode; result id is blueprint id plus "-test" or "-explore".'},nodes:{type:"object",additionalProperties:Oo,description:"Blueprint nodes keyed by node id."},context:Co,testRecordsAmount:{...Ne,description:"Target number of test records to keep for test mode."},recomputeOnChange:{type:"string",enum:["always","manual"],description:"Whether edits automatically restart execution."},mockNever:{...x,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 _o=["Aerospike","ApacheKafka","MQTT","Kaggle","FacebookAds","RabbitMQ","Shopify","YouTube","Webshare","Playwright","AWS","Qdrant","OpenAI","BaseVector","BaseEvent","BaseLookup","Gorgias","LMStudio","OpenRouter","VoyageAI","GoogleDrive","GoogleSheets","Gmail","DiscordChannelWebhook"],Ir=I("connections","frontend/src/integrations/types.ts:Connection",{required:["id","label","type","spaceId"],properties:{id:d,updatedAt:S,label:d,type:{type:"string",enum:_o},spaceId:d}});var vr=I("roles","frontend/src/auth/roles/types.ts:Role",{required:["id","label","authorizations"],properties:{id:d,updatedAt:S,label:d,authorizations:He}});var xr=I("schemas","frontend/src/integrations/types.ts:Schema",{required:["id","type","connectionId","path","schema"],properties:{id:d,updatedAt:S,type:{type:"string",enum:Ze},connectionId:d,path:wr,schema:{type:"object",additionalProperties:{type:"string",enum:ue}},keySerdeType:{type:"string"},valueSerdeType:{type:"string"}}});var Br=I("space-join-requests","frontend/src/spaces/space-join-requests/types.ts:SpaceJoinRequest",{required:["id","createdAt","requestedBy","kind","status","spaceId","userId"],properties:{id:d,createdAt:{type:"number",description:"Nanoseconds since Unix epoch."},updatedAt:S,requestedBy:d,kind:{type:"string",enum:["invite","request"]},status:{type:"string",enum:["pending","granted","denied"]},spaceId:d,userId:d}});var Pr=I("spaces","frontend/src/spaces/types.ts:Space",{required:["id","label"],properties:{id:d,updatedAt:S,label:d,thumbnailUrl:d,description:d,isUserSpace:le}});var Er=I("tabs","frontend/src/tabs/types.ts:Tab",{required:["id","name","order","type","parent","spaceId"],properties:{id:{...d,description:"Stable tab id. Blueprint tabs normally have matching blueprints and blueprint-views records keyed by this id."},updatedAt:S,name:d,order:re,type:{type:"string",enum:["blueprint","folder"],description:"Navigation item kind; blueprint tabs normally have matching blueprints and blueprint-views records."},parent:d,spaceId:d}});var Ar=I("user-locations","frontend/src/workspace/user-location/types.ts:UserLocation",{required:["id"],properties:{id:d,updatedAt:S,blueprint:{type:"object",additionalProperties:!1,required:["id"],properties:{id:d,worldPosition:{type:"object",additionalProperties:!1,required:["x","y"],properties:{x:re,y:re}}}}}});var Nr=I("users","frontend/src/auth/users/types.ts:User",{required:["id","displayName","roleIds","authorizations","spaces"],properties:{id:d,updatedAt:S,displayName:d,avatarUrl:d,roleIds:Pt,authorizations:He,spaces:Pt}});var Xe=[Nr,vr,Pr,Er,Ir,xr,Sr,kr,Rr,Ar,Br];function Ye(t){return Xe.find(e=>e.resource===t)}var At=[j("users","Workspace users and authorizations.",!0),j("roles","Workspace roles and resource authorizations.",!0),j("spaces","Workspace spaces.",!0),j("tabs","Tabs and folders visible to authorized user; blueprint tabs normally share an id with blueprints and blueprint-views records.",!0),j("connections","Read-only integration connections without secret-bearing config; config is redacted and cannot be read through MCP.",!1),j("schemas","Integration schema metadata.",!0),j("blueprints","Blueprint definitions keyed by matching blueprint tab id.",!0),j("blueprint-views","Blueprint editor view state keyed by matching blueprint tab id.",!0),j("blueprint-operators","Registered blueprint operator definitions.",!1),j("user-locations","Live user location records.",!0),j("space-join-requests","Space invitation and join requests.",!0)],Wo=["tabs","blueprints","blueprint-views"],Nt=new Set(Wo),fe=At.filter(t=>!Nt.has(t.name)),Oe=fe.map(t=>t.name),Or=At.map(t=>t.name);function Mo(t){return At.find(e=>e.name===t)}function Dr(t){return fe.find(e=>e.name===t)}function Cr(t){if(Mo(t))return t;throw new Error(`unsupported resource: ${t}`)}function Ot(t){if(Nt.has(t))throw new Error(`dedicated resource ${t}: use tab and blueprint intent tools instead of generic resource_* tools`);if(Dr(t))return t;throw new Error(`unsupported resource: ${t}`)}function Dt(t){let e=Dr(t);if(Nt.has(t))throw new Error(`dedicated resource ${t}: use tab and blueprint intent tools instead of generic resource_* tools`);if(!e)throw new Error(`unsupported resource: ${t}`);if(!e.writable)throw new Error(`resource is read-only: ${t}`);return e.name}function j(t,e,r){return{name:t,description:e,writable:r,schemaUri:`${Bt}${t}`}}function z(){return Date.now()*1e6}function _t(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:r,post:n}=_r(t,e);return r===null&&n===null?{pre:null,post:null}:{pre:r,post:n}}function _r(t,e){let r={},n={},o=!1,i=new Set([...J(t),...J(e)]);for(let s of i){if(s==="updatedAt")continue;let a=t[s],c=e[s];if(Array.isArray(a)||Array.isArray(c))continue;let u=ne(a),l=ne(c);if(!(s in e))u||(r[s]=a,n[s]=null,o=!0);else if(!(s in t))l||(r[s]=null,n[s]=c,o=!0);else{if(u&&l)continue;if(u&&!l)r[s]=null,n[s]=c,o=!0;else if(!u&&l)r[s]=a,n[s]=null,o=!0;else{let{pre:h,post:y}=Fo(a,c);(h!==void 0||y!==void 0)&&(h!==void 0&&(r[s]=Ct(h)),y!==void 0&&(n[s]=Ct(y)),o=!0)}}}return o?J(r).length===0&&J(n).length===0?{pre:null,post:null}:J(r).length===0?{pre:null,post:n}:J(n).length===0?{pre:r,post:null}:{pre:r,post:n}:{pre:null,post:null}}function Fo(t,e){if($o(t,e))return{pre:void 0,post:void 0};let r=ne(t),n=ne(e);if(r&&n)return{pre:void 0,post:void 0};if(r)return{pre:null,post:e};if(n)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}=_r(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 ne(t){return t==null?!0:typeof t=="object"&&t!==null?Array.isArray(t)?t.length===0:J(t).length===0:!1}function $o(t,e){return ne(t)&&ne(e)?!0:Wt(t,e)}function Wt(t,e){if(t===e)return!0;if(t==null||e==null||typeof t!="object"||typeof e!="object")return!1;let r=J(t),n=J(e);if(r.length!==n.length)return!1;for(let o of r)if(!(o in e)||!Wt(t[o],e[o]))return!1;return!0}function et(t,e){return e.pre===null?t===null:t===null||typeof t!="object"||Array.isArray(t)?!1:Wr(t,e.pre)}function Wr(t,e){for(let r in e)if(r!=="updatedAt"&&!qo(t[r],e[r]))return!1;return!0}function qo(t,e){return e===null||jo(e)?ne(t):t===void 0?!1:typeof e=="object"&&e!==null&&!Array.isArray(e)&&typeof t=="object"&&t!==null&&!Array.isArray(t)?Wr(t,e):Wt(t,e)}function jo(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)&&J(t).length===0}function Ct(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={},r=!1;for(let n in t)e[n]=Ct(t[n]),e[n]!==void 0&&(r=!0);return r?e:null}}return t}function Mt(t,e){let r=Ft(t,e);return r!==null&&typeof r=="object"&&!Array.isArray(r)&&(r.updatedAt=e.updatedAt),r}function Ft(t,e){return e.post===null?null:t===null?e.post:typeof t!="object"||Array.isArray(t)?e.post:Mr(t,e.post)}function Mr(t,e){let r={};for(let n in t)if(n in e){let o=e[n];if(o===null)continue;typeof o=="object"&&!Array.isArray(o)&&typeof t[n]=="object"&&!Array.isArray(t[n])&&t[n]!==null?r[n]=Mr(t[n],o):r[n]=o}else r[n]=t[n];for(let n in e)!(n in t)&&e[n]!==null&&(r[n]=e[n]);return r}function J(t){let e=[];for(let r in t)e.push(r);return e}var Fr="replicated-state",tt=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,r,n){this.storage=e,this.socketSession=r,this.logger=n}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,r){this.registerResource(e),this.dirtyResources[e]=C(r)}setDirtyItem(e,r,n){if(this.registerResource(e),n===void 0){delete this.dirtyResources[e][r];return}this.dirtyResources[e][r]=C(n)}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,r){this.registerResource(e),await this.loadResourceFromStorage(e),this.logger.info(`Calculating lastUpdatedAtSeen from ${qr(this.ackedResources[e])} items`);let n=this.prepareSnapshotQuery(e,r);this.logger.info(`\u{1F4F8} ${e} requested with query:`,n),this.socketSession.send(Fr,{resource:e,action:"snapshot",value:n})}hydrateAll(e){return this.hydrate(e,{all:!0})}async waitForSnapshot(e,r){await new Promise((n,o)=>{let i,s=()=>{clearTimeout(i),n()};i=setTimeout(()=>{this.snapshotWaiters.get(e)?.delete(s),o(new Error(`snapshot timeout for ${e}`))},r),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,r){this.registerResource(e);let n=this.getAckedValue(e,r.id),o=_t(n,r);return o.pre===null&&o.post===null?!0:this.sendDelta(e,r.id,o,r)}async deleteItem(e,r){this.registerResource(e);let n=this.getAckedValue(e,r),o=_t(n,null);return o.pre===null&&o.post===null?!0:this.sendDelta(e,r,o,null)}isItemInflight(e,r){return this.inflightItems.get(e)?.has(r)===!0}async sendDelta(e,r,n,o){this.registerResource(e),this.inflightItems.has(e)||this.inflightItems.set(e,new Set);let i=this.inflightItems.get(e);if(i.has(r))return!1;let s=this.getDirtyValue(e,r);et(s,n)&&(arguments.length>=4?this.setDirtyValue(e,r,C(o)):this.setDirtyValue(e,r,Ft(s,C(n))),this.emitResourceChange(e)),i.add(r);let a;try{a=await this.socketSession.sendWithAck(Fr,{resource:e,action:"delta",key:r,value:n})}catch(c){a={ok:!1,reason:c instanceof Error?c.message:"error"}}return i.delete(r),a.ok?!0:(this.revertDirtyToAckedValue(e,r),this.emitResourceChange(e),this.logger.error(`!ack[${e}] Reverting to acked state for ${e}:${r}`,a.reason),!1)}getAckedValue(e,r){return this.initializeResource(e),this.ackedResources[e][r]??null}getDirtyValue(e,r){return this.initializeResource(e),this.dirtyResources[e][r]??null}getVisibleItems(e){this.initializeResource(e);let r={};for(let n in this.dirtyResources[e]){let o=this.dirtyResources[e][n];o!=null&&(r[n]=o)}return r}getRawItems(e){return this.initializeResource(e),C(this.dirtyResources[e])}getAckedItems(e){return this.initializeResource(e),C(this.ackedResources[e])}getUnauthorizedKeys(e){return this.initializeResource(e),C(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,r){this.initializeResource(e);let n=C(r);if(n.lastUpdatedAtSeen!==void 0)return n;let o=this.buildLastUpdatedAtSeen(e,n);return $r(o)||(n.lastUpdatedAtSeen=o),n}async loadResourceFromStorage(e){if(this.initializeResource(e),this.loadedResources.has(e))return;if(this.loadingPromises.has(e))return this.loadingPromises.get(e);let r=this.loadResourceItemsFromStorage(e);this.loadingPromises.set(e,r);try{await r}finally{this.loadingPromises.delete(e),this.loadedResources.add(e)}}async loadResourceItemsFromStorage(e){let r=!1,n=0;try{let o=await this.storage.loadItems(e);if(o&&$r(this.ackedResources[e])){r=!0;for(let i in o)this.applyCachedItem(e,i,o[i])&&(n+=1)}}catch(o){this.logger.warn(`Failed to load cached ${e}: ${String(o)}`)}finally{this.loadingResources[e]=!1,this.emitResourceChange(e),r?this.logger.info(`\u{1F4C2} ${n}x ${e} from cache`):this.logger.info(`\u{1F4C2} no cached data for ${e}`)}}applyCachedItem(e,r,n){return n===null?(this.ackedResources[e][r]=null,this.dirtyResources[e][r]=null,!0):n==="unauthorized"?(this.unauthorizedKeys[e][r]=!0,!1):(this.ackedResources[e][r]=C(n),this.dirtyResources[e][r]=C(n),!0)}applySnapshot(e,r){this.initializeResource(e);for(let n in r){let o=r[n];o===null?(this.ackedResources[e][n]=null,this.dirtyResources[e][n]=null,delete this.unauthorizedKeys[e][n]):o==="unauthorized"?(delete this.ackedResources[e][n],delete this.dirtyResources[e][n],this.unauthorizedKeys[e][n]=!0):(this.ackedResources[e][n]=C(o),this.dirtyResources[e][n]=C(o),delete this.unauthorizedKeys[e][n]),this.storage.persistItem(e,n,o).catch(i=>{this.logger.warn(`Failed to persist ${e}:${n}: ${String(i)}`)})}this.loadingResources[e]=!1,this.emitResourceChange(e),this.logger.info(`\u{1F4F8} ${qr(r)}x ${e} `),this.resolveSnapshotWaiters(e)}applyRemoteDelta(e){let r=e.resource,n=e.key;if(!n)return;this.initializeResource(r);let o=e.value,i={pre:o.pre,post:o.post},s=this.getAckedValue(r,n);if(!et(s,i))this.logger.error(`\u{1D6AB}S precondition invalid on last acked for ${r}:${n}`,{pre:i.pre,post:i.post,current:s});else{let c=Mt(s,C(o));this.ackedResources[r][n]=c,this.storage.persistItem(r,n,c).catch(u=>{this.logger.warn(`Failed to persist ${r}:${n}: ${String(u)}`)}),this.logger.info($t(`\u{1D6AB}S[${r}] acked`,i))}let a=this.getDirtyValue(r,n);e.by!==this.socketSession.getSessionId()?et(a,i)?i.post===null?(this.dirtyResources[r][n]=null,this.logger.info($t(`\u{1D6AB}S[${r}] dirty`,i))):(this.dirtyResources[r][n]=Mt(a,C(o)),this.logger.info($t(`\u{1D6AB}S[${r}] dirty`,i))):(this.logger.warn(`Skip delta on dirty for ${r}:${n}`,{pre:i.pre,post:i.post,current:s}),this.revertDirtyToAckedValue(r,n)):i.post!=null&&a!=null&&typeof a=="object"&&(a.updatedAt=o.updatedAt,this.dirtyResources[r][n]=a,this.logger.info(`\u{1D6AB}S[${r}] dirty updatedAt for ${n}`)),this.emitResourceChange(r)}buildLastUpdatedAtSeen(e,r){let n=this.ackedResources[e],o={};if(r.all){for(let i in n)this.copyItemUpdatedAt(n[i],i,o);return o}if(r.keys&&r.keys.length>0)for(let i of r.keys)this.copyItemUpdatedAt(n[i],i,o);return o}copyItemUpdatedAt(e,r,n){e&&typeof e=="object"&&typeof e.updatedAt=="number"&&(n[r]=e.updatedAt)}setDirtyValue(e,r,n){if(n===null){this.dirtyResources[e][r]=null;return}this.dirtyResources[e][r]=n}revertDirtyToAckedValue(e,r){let n=this.ackedResources[e][r];if(n===void 0){delete this.dirtyResources[e][r];return}if(n===null){this.dirtyResources[e][r]=null;return}this.dirtyResources[e][r]=C(n)}emitResourceChange(e){let r={resource:e,acked:this.getAckedItems(e),dirty:this.getRawItems(e),unauthorized:this.getUnauthorizedKeys(e),loading:this.loadingResources[e]};for(let n of this.resourceChangeListeners)n(r)}resolveSnapshotWaiters(e){let r=this.snapshotWaiters.get(e);if(r){this.snapshotWaiters.delete(e);for(let n of r)n()}}};function C(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 $r(t){for(let e in t)return!1;return!0}function qr(t){let e=0;for(let r in t)e+=1;return e}function $t(t,e){return`${t}
21
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=pe(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 pr(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:dr(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 dr(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 pr(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(pe(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 p=s[u.operatorId];p?.hidden!==!0&&(!o&&p?.isDeprecated===!0||c.push(jr(u,p)))}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 p=Ft(s,c,u,i),d=Wr(p,r,o);return l({results:d})}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,p]=await Promise.all([xr(t,i),t.readResourceItems("schemas"),t.readResourceItems("connections")]),d=Ft(i,u,p,void 0);return l({email:e,tabId:r,location:n,tab:o,blueprint:i,blueprintView:s,blueprintOperators:c,contextFields:d})}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 p=u.operatorId,d=u.score;typeof p!="string"||typeof d!="number"||c.push({operatorId:p,score:d})}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 p in s.schema)i.push({kind:"contextField",connectionId:s.connectionId,connectionLabel:c?.label??"???",path:u,field:p,type:s.schema[p]??"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 p=t.waitForChannelEvent(o,d=>no(d,i,s,c),u);return t.sendChannelEvent(n,r),l(await p)}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",de)},...de.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.
22
+ delta.post: ${JSON.stringify(e.post)}`}var rt=15e3,Uo=2e3,Lt=class{replicatedState;recordStorage;socketSession;startPromise;reconnectTimer;registeredResources=new Set(Or);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,r={all:!0}){this.registerResource(e),await this.start(),await this.hydrateConnectedResource(e,r)}async readResourceItems(e,r={all:!0}){return this.registerResource(e),await this.start(),this.filterVisibleItems(e,r)}async readResourceItem(e,r){this.registerResource(e),await this.start();let n=this.replicatedState?.getVisibleItems(e)[r]??null;return jr(e,n)}async upsertResourceItem(e,r){if(this.registerResource(e),await this.start(),!this.replicatedState)throw new Error("replicated state not initialized");return this.replicatedState.upsertItem(e,r)}async deleteResourceItem(e,r){if(this.registerResource(e),await this.start(),!this.replicatedState)throw new Error("replicated state not initialized");return this.replicatedState.deleteItem(e,r)}waitForChannelEvent(e,r,n=rt){if(!this.socketSession)throw new Error("workspace websocket not connected");return this.socketSession.waitForChannelEvent(e,o=>r(o),n)}collectChannelEvents(e,r,n=rt,o=250){if(!this.socketSession)throw new Error("workspace websocket not connected");return this.socketSession.collectChannelEvents(e,i=>r(i),n,o)}sendChannelEvent(e,r){if(!this.socketSession)throw new Error("workspace websocket not connected");this.socketSession.send(e,r)}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){Cr(e),this.registeredResources.add(e),this.replicatedState?.registerResource(e)}async connectAndHydrate(){let e=await Z();if(!e)throw new Error("missing jwt: set BEEPFLOW_JWT or run auth tool to persist token");let r=await X(e);await fr(r);let n=k(),o=te(r),i=mr(n.workspaceUrl,o.email);this.socketSession?.close(),this.recordStorage?.close(),this.recordStorage=new Ke(n.replicatedStateDatabasePath,i),this.socketSession=new Qe(n.workspaceUrl,r),this.replicatedState=new tt(this.recordStorage,this.socketSession,Go),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(rt),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,r){if(!this.replicatedState)throw new Error("replicated state not initialized");let n=this.replicatedState.waitForSnapshot(e,rt);await this.replicatedState.hydrate(e,r),await n}filterVisibleItems(e,r){let n=this.replicatedState?.getVisibleItems(e)??{},o={};for(let i in n)Jo(i,n[i],r)&&(o[i]=jr(e,n[i]));return o}scheduleReconnect(){this.closed||this.reconnectTimer||(this.startPromise=void 0,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,this.start().catch(()=>this.scheduleReconnect())},Uo))}};function Jo(t,e,r){return zo(t,e,r.lastUpdatedAtSeen)?!!(r.all||r.keys?.includes(t)||Vo(e,r.fieldEqualTo)):!1}function jr(t,e){if(t!=="connections"||!e||typeof e!="object"||Array.isArray(e))return e;let r={...e};return delete r.config,r}function zo(t,e,r){let n=r?.[t];if(n===void 0||!e||typeof e!="object")return!0;let o=e.updatedAt;return typeof o!="number"||o>n}function Vo(t,e){if(!e||!t||typeof t!="object")return!1;let r=t,n=!1;for(let o in e)if(n=!0,!Lo(r[o],e[o]))return!1;return n}var Go={info(t,e){qt("info",t,e)},warn(t,e){qt("warn",t,e)},error(t,e){qt("error",t,e)}};function qt(t,e,r){let n=r===void 0?"":` ${JSON.stringify(r)}`;process.stderr.write(`[replicated-state:${t}] ${e}${n}
23
+ `)}var jt;function we(){return jt||(jt=new Lt),jt}import{isDeepStrictEqual as Ko}from"node:util";function E(t,e){let r=Ye(t);if(!r)throw new Error(`missing schema for resource: ${t}`);let n={failures:[],rootSchema:r.itemSchema};if(Re(r.itemSchema,e,"$",n),n.failures.length===0)return;let o=n.failures.slice(0,5).map(i=>`${i.path} ${i.message}`).join("; ");throw new Error(`item does not match ${t} schema: ${o}`)}function Re(t,e,r,n){if(t===!0)return;if(t===!1)return V(n,r,"is not allowed");if(!ii(t))return;let o=t.$ref;if(typeof o=="string"){Re(ni(o,n.rootSchema),e,r,n);return}Qo(t,e,r,n)&&(Ho(t,e,r,n),Zo(t,e,r,n),Xo(t,e,r,n),ei(t,e,r,n))}function Qo(t,e,r,n){if(!Array.isArray(t.anyOf))return!0;for(let o of t.anyOf){let i={failures:[],rootSchema:n.rootSchema};if(Re(o,e,r,i),i.failures.length===0)return!1}return V(n,r,"does not match any allowed schema"),!1}function Ho(t,e,r,n){let o=t.enum;if(Array.isArray(o)){for(let i of o)if(Ko(e,i))return;V(n,r,`must be one of ${o.map(String).join(", ")}`)}}function Zo(t,e,r,n){let o=t.type;if(typeof o=="string"&&!Lr(e,o)){V(n,r,`must be ${o}`);return}if(Array.isArray(o)){for(let i of o)if(typeof i=="string"&&Lr(e,i))return;V(n,r,`must be ${o.map(String).join(" or ")}`)}}function Xo(t,e,r,n){if(t.type!=="object"||!De(e))return;let o=De(t.properties)?t.properties:{};Yo(t,e,r,n);for(let i of ri(t))(!(i in e)||e[i]===void 0)&&V(n,`${r}.${i}`,"is required");for(let i in e){if(e[i]===void 0){V(n,`${r}.${i}`,"must not be undefined");continue}if(i in o){Re(o[i],e[i],`${r}.${i}`,n);continue}ti(t,e[i],`${r}.${i}`,n)}}function Yo(t,e,r,n){let o=0;for(let a in e)Object.prototype.hasOwnProperty.call(e,a)&&o++;let i=t.minProperties;typeof i=="number"&&o<i&&V(n,r,`must have at least ${i} properties`);let s=t.maxProperties;typeof s=="number"&&o>s&&V(n,r,`must have at most ${s} properties`)}function ei(t,e,r,n){if(t.type!=="array"||!Array.isArray(e))return;let o=t.items;if(o!==void 0)for(let i=0;i<e.length;i++)Re(o,e[i],`${r}[${i}]`,n)}function ti(t,e,r,n){let o=t.additionalProperties;if(o===!1){V(n,r,"is not allowed");return}o===void 0||o===!0||Re(o,e,r,n)}function ri(t){return Array.isArray(t.required)?t.required.filter(e=>typeof e=="string"):[]}function ni(t,e){if(!t.startsWith("#/"))return!1;let r=e,n=t.slice(2).split("/").map(oi);for(let o of n){if(!De(r)||!(o in r))return!1;r=r[o]}return r}function oi(t){return t.replace(/~1/g,"/").replace(/~0/g,"~")}function Lr(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 De(t);case"string":return typeof t=="string";default:return!0}}function ii(t){return De(t)}function De(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function V(t,e,r){t.failures.push({path:e,message:r})}import Ut from"node:fs/promises";import si from"node:os";import Ur from"node:path";var ai=15e3;async function nt(t){let e=await zr({method:"GET",path:t});if(!e.ok)throw await Vr(t,e);return await e.json()}async function Jr(t){let e=await zr(t),r={status:e.status,statusText:e.statusText,headers:fi(e.headers)};if(e.status>=300&&e.status<400)return{...r,location:e.headers.get("location")};if(!e.ok)throw await Vr(t.path,e);return t.responseMode==="binary"?await yi(e,t,r):(e.headers.get("content-type")??"").includes("application/json")?{...r,body:await e.json().catch(()=>null)}:{...r,body:await e.text().catch(()=>"")}}async function zr(t){let e=await pi(),r=ui(t.path,t.query),n=new Headers({Authorization:`Bearer ${e}`}),o=t.timeoutMs??ai;di(n,t.headers);let i={method:t.method,headers:n,redirect:"manual",signal:AbortSignal.timeout(o)};t.requestMode==="multipart"?i.body=await mi(t):t.requestMode==="form"?(i.body=hi(t.body),n.set("Content-Type","application/x-www-form-urlencoded")):t.body!==void 0&&t.method!=="GET"&&t.method!=="HEAD"&&(n.set("Content-Type","application/json"),i.body=JSON.stringify(t.body));try{return await fetch(r,i)}catch(s){throw ci(s)?new Error(`workspace endpoint timed out after ${o}ms: ${t.path}`):s}}function ci(t){return t instanceof DOMException&&(t.name==="TimeoutError"||t.name==="AbortError")}async function pi(){let t=await Z();if(!t)throw new Error("missing jwt: set BEEPFLOW_JWT or run auth tool to persist token");return await X(t)}function di(t,e){if(e)for(let r in e){let n=e[r];n!=null&&t.set(r,String(n))}}function ui(t,e){if(!t.startsWith("/"))throw new Error(`workspace endpoint path must start with /: ${t}`);let r=k(),n=new URL(`${r.workspaceUrl}${t}`);return li(n,e),n.toString()}function li(t,e){if(e)for(let r in e){let n=e[r];if(n!=null){if(Array.isArray(n)){for(let o of n)t.searchParams.append(r,String(o));continue}t.searchParams.set(r,String(n))}}}function fi(t){let e={};return t.forEach((r,n)=>{e[n]=r}),e}async function mi(t){let e=new FormData,r=t.body;if(r&&typeof r=="object"&&!Array.isArray(r))for(let o in r){let i=r[o];i!=null&&e.set(o,String(i))}let n=t.files??{};for(let o in n)e.set(o,await gi(n[o]),n[o].fileName??o);return e}async function gi(t){if(t.filePath)return new Blob([await Ut.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 hi(t){let e=new URLSearchParams;if(!t||typeof t!="object"||Array.isArray(t))return e;for(let r in t){let n=t[r];n!=null&&e.set(r,String(n))}return e}async function yi(t,e,r){let n=Buffer.from(await t.arrayBuffer()),o=e.outputFilePath??bi(t);return await Ut.mkdir(Ur.dirname(o),{recursive:!0}),await Ut.writeFile(o,n),{...r,filePath:o,sizeBytes:n.byteLength,contentType:t.headers.get("content-type")}}function bi(t){let e=t.headers.get("content-disposition")??"",n=/filename="?([^";]+)"?/i.exec(e)?.[1]?.replace(/[^A-Za-z0-9._-]/g,"_")||`beepflow-download-${Date.now()}.bin`;return Ur.join(si.tmpdir(),"beepflow-mcp-downloads",n)}async function Vr(t,e){let r=await e.text().catch(()=>"");return new Error(`${t} failed: ${e.status} ${r}`.trim())}async function Jt(t){return wi(await zt(t))}async function Kr(){return await nt("/integrations")}async function Qr(t,e){let r=t?`/integrations/${encodeURIComponent(t)}/blueprint-contexts${Gr(e)}`:`/integrations/blueprint-contexts${Gr(e)}`;return await nt(r)}async function zt(t){return await nt(`/integrations/${encodeURIComponent(t)}/openapi`)}function Gr(t){return t?`?resourceType=${encodeURIComponent(t)}`:""}async function Hr(t){let r=(await Jt(t.integrationType)).find(n=>n.operationId===t.operationId);if(!r)throw new Error(`unsupported integration endpoint: ${t.operationId}`);return xi(r,t.confirm),await Jr({method:r.method,path:Bi(r,t.path),query:t.query,headers:t.headers,body:t.body,requestMode:r.requestMode,responseMode:r.responseMode,files:t.files,outputFilePath:t.outputFilePath})}function wi(t){let e=ot(t,"paths"),r=[];for(let n in e){let o=e[n];if(A(o))for(let i in o){let s=o[i];A(s)&&r.push(Ri(i.toUpperCase(),n,s))}}return r}function Ri(t,e,r){let n=ot(r,"x-beepflow");return{operationId:me(r,"operationId"),integrationType:me(n,"integrationType"),resourceType:Ei(n,"resourceType"),method:t,path:e,originalPath:me(n,"originalPath"),summary:me(r,"summary"),access:me(n,"access"),sideEffect:me(n,"sideEffect"),mcpExposure:me(n,"mcpExposure"),requestMode:Ti(r),responseMode:Si(r),requiresConnectionId:vi(r),pathParameters:Pi(e),parameters:ki(r),requestBody:it(r,"requestBody"),responses:ot(r,"responses")}}function ki(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 Ti(t){let e=it(t,"requestBody");if(!e)return"none";let r=it(e,"content");return r?A(r["multipart/form-data"])?"multipart":A(r["application/x-www-form-urlencoded"])?"form":(A(r["application/json"]),"json"):"none"}function Si(t){let e=ot(t,"responses");for(let o in e)if(o.startsWith("3")&&A(e[o]))return"redirect";let r=Ii(e);if(!r)return"empty";let n=it(r,"content");return n?A(n["application/octet-stream"])?"binary":A(n["text/plain"])?"text":(A(n["application/json"]),"json"):"empty"}function Ii(t){if(A(t[200]))return t[200];for(let e in t)if(e.startsWith("2")&&A(t[e]))return t[e];return null}function vi(t){let e=t.parameters;return Array.isArray(e)?e.some(r=>A(r)&&r.name==="connectionId"&&r.in==="query"&&r.required===!0):!1}function xi(t,e){if(!(t.mcpExposure==="safe"&&t.sideEffect!=="destructive")&&e!==!0)throw new Error(`integration endpoint requires confirm=true: ${t.operationId}`)}function Bi(t,e){let r=t.path;for(let n of t.pathParameters){let o=e?.[n];if(typeof o!="string"&&typeof o!="number")throw new Error(`integration endpoint path parameter required: ${n}`);r=r.replace(`{${n}}`,encodeURIComponent(String(o)))}return r}function Pi(t){let e=[];for(let r of t.matchAll(/\{([^}]+)\}/g))r[1]&&e.push(r[1]);return e}function ot(t,e){if(!A(t)||!A(t[e]))throw new Error(`invalid integration OpenAPI schema: ${e} must be object`);return t[e]}function it(t,e){if(!A(t)||t[e]===void 0||t[e]===null)return null;if(!A(t[e]))throw new Error(`invalid integration OpenAPI schema: ${e} must be object`);return t[e]}function me(t,e){if(typeof t[e]!="string")throw new Error(`invalid integration OpenAPI schema: ${e} must be string`);return t[e]}function Ei(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 A(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var Zr="For Beepflow tasks, call status first and follow the instructions field returned in the status response.",Ce=`
24
+ Use Beepflow MCP to inspect authenticated workspace resources, blueprint context, live results, integration OpenAPI endpoints, and auth.
24
25
 
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.
26
+ Global:
27
+ - Run independent calls in parallel, including writes. Serialize dependent calls, same resource/key, auth/session changes, or shared live subscriptions.
28
+ - Auth comes from BEEPFLOW_JWT, --jwt, or persisted auth tools.
29
+ - Tool descriptions and schemas document workflow, writable/read-only status, mutation notes, and fields.
38
30
 
39
- Blueprint workflow:
40
- - The index for any node output is "0.5"
41
- - Prefer omitting blueprint-view node coordinates for new nodes. The frontend computes coordinates after it measures dynamic node dimensions and connections. If setting coordinates manually, include both style.x and style.y.
42
- - Tabs are navigation items. A blueprint tab normally has matching blueprints and blueprint-views records keyed by the same tab id.
43
- - Use blueprint_operators_search to find valid operator ids plus input/output metadata.
44
- - Use blueprint_context_fields_search to find fields available from the blueprint context schemas.
45
- - Blueprint modes are test and explore. Result ids are tabId-test and tabId-explore.
46
- - Use results_read for blueprint result events.
47
- - Use metrics_read, socket_latency_ping, and stream_offset_extents_read for runtime diagnostics.
48
- - results_delete_state and results_set_offsets change state.
31
+ Blueprint modes:
32
+ - Test mode is normal development and output-shape discovery with cached samples/no external writes. Result id: blueprintId-test. results_read returns public.testResults, public.testResults[].values[nodeId], and publicByNode[nodeId].
33
+ - Explore mode is active trigger/runtime mode using triggers/desiredState. Result id: blueprintId-explore. Use after test validates wiring/shapes.
49
34
 
50
- Integration workflow:
51
- - Use integrations_list, integration_endpoints_list, and integration_endpoint_schema_get before integration_endpoint_call.
52
- - 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.
53
- - integration_endpoint_call can cause external reads or writes, read local files for multipart uploads, and write binary downloads to disk.
54
- - Only call mutating or destructive integration endpoints when the user explicitly requested it. Pass confirm=true only after explicit confirmation or unmistakable user intent.
35
+ Blueprint flow:
36
+ - Start with status for MCP instructions, current tab, blueprint, view, nodes, used operators, and context fields.
37
+ - Search operators with blueprint_operators_search before edits. Static map/wildcard metadata may hide runtime keys from inputs/responses.
38
+ - Read blueprints and blueprint-views schemas before editing nodes, and keep blueprint and view records aligned.
39
+ - When adding operator nodes, include known inputConnections and inputLiterals in blueprint_operator_node_add. Avoid create-then-connect or create-then-set-literal unless source data is unknown until after runtime inspection.
40
+ - If downstream input needs operator output shape, do not guess nested fields. Use test mode, wire smallest runnable partial graph, let it recompute or activate it, then call results_read on blueprintId-test. Discover shapes from public.testResults[].values[nodeId] and publicByNode[nodeId]. Iterate after shapes are observed.
41
+ - For live diagnostics, call results_read on blueprintId-explore.
55
42
 
56
- Auth workflow:
57
- - Tools require workspace auth from BEEPFLOW_JWT, --jwt, or persisted auth tools.
58
- - auth_email_verify_code, auth_google_get_token, token refresh, and auth_sign_out modify stored credentials.
59
-
60
- 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)}
43
+ Safety:
44
+ - Ask before destructive actions unless user intent is explicit.
45
+ - Pass confirm=true only after explicit confirmation or unmistakable user intent.
46
+ - When uncertain, inspect schemas and resources first.
47
+ `.trim();function p(t,e){let r=N(t)[e];if(typeof r!="string"||!r.trim())throw new Error(`invalid tool arguments: ${e} must be non-empty string`);return r}function b(t,e){let r=N(t)[e];if(r!=null){if(typeof r!="string")throw new Error(`invalid tool arguments: ${e} must be string`);return r}}function oe(t,e){let r=N(t)[e];if(typeof r!="boolean")throw new Error(`invalid tool arguments: ${e} must be boolean`);return r}function st(t,e){let r=N(t)[e];if(r!=null){if(typeof r!="boolean")throw new Error(`invalid tool arguments: ${e} must be boolean`);return r}}function at(t,e){let r=N(t)[e];if(!se(r))throw new Error(`invalid tool arguments: ${e} must be object`);return r}function ct(t,e){if(t===void 0)return;let r=N(t)[e];if(r!=null){if(!se(r))throw new Error(`invalid tool arguments: ${e} must be object`);return r}}function ie(t,e){let r=Xr(t,e);if(!r)throw new Error(`invalid tool arguments: ${e} must be string array`);return r}function Xr(t,e){let r=N(t)[e];if(r!=null){if(!Array.isArray(r)||r.some(n=>typeof n!="string"))throw new Error(`invalid tool arguments: ${e} must be string array`);return r}}function Yr(t,e){let r=Vt(t,e);if(r===void 0)throw new Error(`invalid tool arguments: ${e} must be positive integer`);return r}function Vt(t,e){let r=N(t)[e];if(r!=null){if(typeof r!="number"||!Number.isInteger(r)||r<=0)throw new Error(`invalid tool arguments: ${e} must be positive integer`);return r}}function en(t,e){let r=N(t)[e];if(r!=null){if(typeof r!="number"||!Number.isFinite(r))throw new Error(`invalid tool arguments: ${e} must be number`);return r}}function M(t,e,r){let n=p(t,e);if(!r.includes(n))throw new Error(`invalid tool arguments: ${e} must be one of ${r.join(", ")}`);return n}function ke(t,e,r){let n=b(t,e);if(n!==void 0){if(!r.includes(n))throw new Error(`invalid tool arguments: ${e} must be one of ${r.join(", ")}`);return n}}function pt(t){if(t!==void 0)return Xr(t,"ids")}function N(t){if(!t||typeof t!="object"||Array.isArray(t))throw new Error("invalid tool arguments: expected object");return t}function se(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var tn={type:"object",additionalProperties:!0},Te={type:"object",additionalProperties:!0},dt={type:"object",additionalProperties:!1,required:["type","trigger"],properties:{type:{type:"string",description:"Integration resource type processed by this blueprint, such as ApacheKafkaTopic or QdrantCollection. Call integration_blueprint_contexts_list first; use only resource types returned by that tool. The returned executionKind determines trigger choice: managed resources use executor, finite resources use manual/cron/loop/blueprint/webhook based on user intent."},trigger:{type:"object",additionalProperties:!1,description:"Exactly one trigger branch. For executionKind=managed from integration_blueprint_contexts_list, use executor. For executionKind=finite, choose manual for ad hoc/sample/start-once runs, cron for scheduled refresh, loop for fixed-delay polling, blueprint for invocation by another blueprint, or webhook for generic GET/POST /:tabId/trigger HTTP calls.",properties:{manual:{...Te,description:"Run immediately count times when explore runtime starts or restarts. Best for finite resource sampling and ad hoc runs. Shape: { count: integer }; backend treats values below 1 as 1."},cron:{...Te,description:"Run on a seconds-field cron schedule while explore runtime is active. Best for scheduled finite-resource refresh. Shape: { expression: string, timezone?: IANA timezone }; UTC is used when timezone is omitted or empty."},loop:{...Te,description:"Run immediately, then repeat after delayMs while explore runtime is active. Use only for deliberate fixed-delay polling; delayMs must be positive to avoid a hot loop. Shape: { delayMs: integer }."},blueprint:{...Te,description:"Wait while active until another blueprint or Trigger Self operator invokes this blueprint. Trigger argument is available through Get Trigger Argument. Shape: { enabled: true }."},webhook:{...Te,description:"Wait while active for generic GET/POST /:tabId/trigger HTTP calls. Not for integration webhook resources such as ShopifyWebhook or GorgiasEvent; those are managed resources and should use executor. Shape: { enabled: true, timeoutMs?: integer, contentType?: auto|application/json|text/plain|application/x-www-form-urlencoded|multipart/form-data|application/octet-stream }."},executor:{...Te,description:"Use for managed integration resources where runtime owns stream, event, webhook, or poll lifecycle, such as ApacheKafkaTopic, RabbitMQStream, ShopifyWebhook, GorgiasEvent, GmailMessage, GmailThread, GmailEvent, BaseEventCollection, and MQTTTopic. Shape: { enabled: true }."}},oneOf:[{required:["manual"]},{required:["cron"]},{required:["loop"]},{required:["blueprint"]},{required:["webhook"]},{required:["executor"]}]},config:{...tn,description:"Integration-specific config for context.type. Start from contextTemplate.config returned by integration_blueprint_contexts_list, fill every configFields item where required=true, and preserve optional defaults such as consumerGroupId, clientId, parser, offsetResetStrategy, orderBy, or webhook topic maps when provided."}}};var Se=["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"];function ut(t){return{type:"object",additionalProperties:!1,properties:{ids:Y(t),fieldEqualTo:{...tn,description:"Return items whose top-level fields equal these exact values."}}}}function m(t,e=["id"]){return{type:"object",additionalProperties:!1,required:e,properties:{id:{type:"string",description:"Tab/blueprint id."},...t}}}function G(t,e){return m({nodeId:{type:"string",description:"Blueprint node id."},inputName:{type:"string",description:"Operator input name."},...t},e)}function Ie(t,e){return m(t,e)}function Y(t){return{type:"array",items:{type:"string"},description:t}}function _(){return{type:"string",description:"CRDT list index. Defaults to 0.5 where supported."}}function f(t){return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}function lt(t,e){let r={};return t&&(r.keys=t),e&&(r.fieldEqualTo=e),!t&&!e&&(r.all=!0),r}async function F(t,e,r){return t.readResourceItems("tabs",lt(e,r))}async function rn(t,e){let r=await t.readResourceItem("tabs",e);if(!r)throw new Error(`tab not found: ${e}`);return r}function nn(t){return{name:"tabs_query",description:"Query visible tabs and folders. Use ids for exact tabs or fieldEqualTo for exact top-level field matches; with no filters, returns all visible tabs.",inputSchema:ut("Tab ids to read."),call:async e=>f(await F(t,pt(e),ct(e,"fieldEqualTo")))}}var Ai=(t=6)=>{let r="abcdefghijklmnopqrstuvwxyz",o=`1234567890${r}${r.toUpperCase()}`.split(""),i=new Uint8Array(t);return crypto.getRandomValues(i),i.reduce((s,a)=>`${s}${o[a&61]}`,"")},K=Ai;function mt(t,e){if(e.insertAfterTabId){let o=t[e.insertAfterTabId];return o?_e(t,o):.5}let r=ft(t).find(o=>o.parent===e.parent);return r?(r.order??1)*.5:(ft(t)[0]?.order??1)*.5}function _e(t,e){let r=ft(t),n=r.findIndex(i=>i.id===e.id),o=n>=0?r[n+1]:void 0;return e.order*.5+(o?.order??1)*.5}function on(t,e){let r=ft(t).filter(o=>o.parent===e.parent),n=r.findIndex(o=>o.id===e.id);return((r[n-1]?.order??0)+e.order)*.5}function sn(t,e){let r=0;for(let n in t){let o=t[n];o.parent===e&&o.order>r&&(r=o.order)}return r*.5+.5}function ft(t){let e=[];for(let r in t)e.push(t[r]);return e.sort((r,n)=>r.order-n.order)}function gt(t,e){if(e)return e;for(let r in t)return t[r].parent;throw new Error("parent is required when no existing tab can provide a default parent")}function ve(t,e){if(e.startsWith("spaces:"))return e.split(":")[1]??"";if(e.startsWith("tabs:")){let r=e.split(":")[1],n=r?t[r]?.spaceId:void 0;if(n)return n}throw new Error(`could not find spaceId for parent: ${e}`)}function We(t,e){let r=t[e];if(!r)throw new Error(`tab not found: ${e}`);return r}async function xe(t,e){return E("tabs",e),t.upsertResourceItem("tabs",e)}function an(t){return{name:"folder_tab_create",description:"Create a folder tab under a parent such as spaces:<spaceId> or tabs:<folderId>. Computes frontend-compatible order and parent space.",inputSchema:{type:"object",additionalProperties:!1,properties:{parent:{type:"string",description:"Parent id, normally spaces:<spaceId> or tabs:<folderId>. Optional only when an existing tab can provide a default parent."},name:{type:"string",description:"Folder name. Defaults to Untitled folder."},insertAfterTabId:{type:"string",description:"Optional tab id after which to insert in global frontend tab order."}}},call:async e=>f(await Ni(t,{parent:b(e,"parent"),name:b(e,"name"),insertAfterTabId:b(e,"insertAfterTabId")}))}}async function Ni(t,e){let r=await F(t),n=gt(r,e.parent),o=ve(r,n),i={id:K(),updatedAt:z(),name:e.name??"Untitled folder",order:mt(r,{parent:n,insertAfterTabId:e.insertAfterTabId}),type:"folder",parent:n,spaceId:o};return await xe(t,i),i}function cn(t){return{name:"tab_rename",description:"Rename an existing tab or folder by preserving all other tab fields and upserting only the full updated tab record.",inputSchema:m({name:{type:"string",description:"New non-empty tab name."}},["id","name"]),call:async e=>{let r=p(e,"id"),n=await rn(t,r);return n.name=p(e,"name"),await xe(t,n),f(n)}}}function pn(t){return{name:"tab_move",description:"Move or reorder a tab. Supports explicit order, insertBeforeTabId, insertAfterTabId, or appending to a parent while updating parent spaceId like frontend drag/drop.",inputSchema:m({parent:{type:"string",description:"New parent id, normally spaces:<spaceId> or tabs:<folderId>."},order:{type:"number",description:"Explicit order value. Overrides insert and append order computation."},insertBeforeTabId:{type:"string",description:"Move before this sibling tab."},insertAfterTabId:{type:"string",description:"Move after this tab using frontend global ordering."}}),call:async e=>{let r=p(e,"id"),n=await F(t),o=n[r];if(!o)throw new Error(`tab not found: ${r}`);let i=Oi(n,o,e);return o.parent=i.parent,o.spaceId=i.spaceId,o.order=i.order,await xe(t,o),f(o)}}}function Oi(t,e,r){let n=en(r,"order"),o=b(r,"insertBeforeTabId"),i=b(r,"insertAfterTabId"),s=o?We(t,o):i?We(t,i):void 0,a=b(r,"parent")??s?.parent??e.parent,c=s?.spaceId??ve(t,a),u=n??(o?on(t,We(t,o)):i?_e(t,We(t,i)):sn(t,a));return{parent:a,spaceId:c,order:u}}function dn(t){return{name:"tab_delete",description:"Delete a tab tree recursively. Folder tabs delete children; blueprint tabs delete matching blueprints and blueprint-views before deleting the tab.",inputSchema:m({},["id"]),call:async e=>f(await Di(t,p(e,"id")))}}async function Di(t,e){let r=await F(t),n=r[e];if(!n)throw new Error(`tab not found: ${e}`);let o=[],i=[],s=[];return await un(t,r,n,o,i,s),{deletedTabs:o,deletedBlueprints:i,deletedBlueprintViews:s}}async function un(t,e,r,n,o,i){let s=`tabs:${r.id}`;for(let a in e){let c=e[a];c.parent===s&&await un(t,e,c,n,o,i)}r.type==="blueprint"?(await Promise.all([t.deleteResourceItem("blueprints",r.id),t.deleteResourceItem("blueprint-views",r.id),t.deleteResourceItem("tabs",r.id)]),o.push(r.id),i.push(r.id)):await t.deleteResourceItem("tabs",r.id),n.push(r.id)}async function ln(t,e,r){return t.readResourceItems("blueprints",lt(e,r))}function fn(t){return{name:"blueprints_query",description:"Query visible blueprint definitions. Use ids for exact blueprints or fieldEqualTo for exact top-level field matches; with no filters, returns all visible blueprints.",inputSchema:ut("Blueprint ids to read."),call:async e=>f(await ln(t,pt(e),ct(e,"fieldEqualTo")))}}function Gt(t){if(!t)throw new Error("blueprint context trigger is required");let e=0;for(let r of["manual","cron","loop","blueprint","webhook","executor"])t[r]!==void 0&&e++;if(e!==1)throw new Error("blueprint context trigger must contain exactly one branch")}function ht(t){let e=t.type,r=t.trigger;if(typeof e!="string"||!e.trim())throw new Error("context.type must be non-empty string");if(!se(r))throw new Error("context.trigger must be object");Gt(r);let n={type:e,trigger:r};return se(t.config)&&(n.config=t.config),n}function mn(t){return{name:"blueprint_tab_create",description:"Create a blueprint tab plus matching blueprint and blueprint-view records with one shared id. Requires context with exactly one trigger branch.",inputSchema:{type:"object",additionalProperties:!1,required:["context"],properties:{context:{...dt,description:"Blueprint context with type, trigger, and optional config. Trigger must have exactly one branch."},parent:{type:"string",description:"Parent id, normally spaces:<spaceId> or tabs:<folderId>. Optional only when existing tabs can provide a default."},name:{type:"string",description:"Tab name. Defaults to Untitled."},mode:{type:"string",enum:["test","explore"],description:"Initial mode. Defaults to test."},testRecordsAmount:{type:"integer",minimum:1,description:"Initial number of test records. Defaults to 1."},insertAfterTabId:{type:"string",description:"Optional tab id after which to insert."}}},call:async e=>f(await Ci(t,{context:ht(at(e,"context")),parent:b(e,"parent"),name:b(e,"name"),mode:ke(e,"mode",["test","explore"]),testRecordsAmount:Vt(e,"testRecordsAmount"),insertAfterTabId:b(e,"insertAfterTabId")}))}}async function Ci(t,e){let r=await F(t),n=K(),o=gt(r,e.parent),i=ve(r,o),s={id:n,updatedAt:z(),name:e.name??"Untitled",order:mt(r,{parent:o,insertAfterTabId:e.insertAfterTabId}),type:"blueprint",parent:o,spaceId:i},a={id:n,updatedAt:z(),mode:e.mode??"test",nodes:{},context:e.context,testRecordsAmount:e.testRecordsAmount??1,desiredState:"inactive"},c={id:n,updatedAt:z(),nodes:{}};return Gt(a.context.trigger),E("tabs",s),E("blueprints",a),E("blueprint-views",c),await Promise.all([t.upsertResourceItem("tabs",s),t.upsertResourceItem("blueprints",a),t.upsertResourceItem("blueprint-views",c)]),{tab:s,blueprint:a,blueprintView:c}}async function g(t,e){let[r,n,o]=await Promise.all([t.readResourceItem("tabs",e),t.readResourceItem("blueprints",e),t.readResourceItem("blueprint-views",e)]);if(!r)throw new Error(`tab not found: ${e}`);if(r.type!=="blueprint")throw new Error(`tab is not a blueprint: ${e}`);if(!n)throw new Error(`blueprint not found: ${e}`);if(!o)throw new Error(`blueprint view not found: ${e}`);return _i(n),Wi(o),{tab:r,blueprint:n,blueprintView:o}}function _i(t){t.nodes??={}}function Wi(t){t.nodes??={}}function gn(t){return{name:"blueprint_tab_duplicate",description:"Duplicate a blueprint tab by cloning tab, blueprint, and blueprint-view with a new shared id. Only top-level ids are remapped; node ids are preserved like frontend tab duplicate.",inputSchema:m({name:{type:"string",description:"Optional duplicated tab name. Defaults to source name plus *."}}),call:async e=>f(await Mi(t,p(e,"id"),b(e,"name")))}}async function Mi(t,e,r){let n=await F(t),o=await g(t,e),i=K(),s=structuredClone(o.tab);s.id=i,s.updatedAt=z(),s.name=r??`${o.tab.name}*`,s.order=_e(n,o.tab);let a=structuredClone(o.blueprint);a.id=i,a.updatedAt=z(),a.mode=a.mode??"test";let c=structuredClone(o.blueprintView);return c.id=i,c.updatedAt=z(),E("tabs",s),E("blueprints",a),E("blueprint-views",c),await Promise.all([t.upsertResourceItem("tabs",s),t.upsertResourceItem("blueprints",a),t.upsertResourceItem("blueprint-views",c)]),{tab:s,blueprint:a,blueprintView:c}}async function B(t,e){return Kt(e),E("blueprints",e),t.upsertResourceItem("blueprints",e)}function Kt(t){for(let e in t.nodes){let r=t.nodes[e];for(let n in r.inputs){let o=r.inputs[n];for(let i in o.values)Fi(o.values[i])}}}function Fi(t){(!Object.prototype.hasOwnProperty.call(t,"literal")||t.literal===void 0)&&(t.literal=null)}function hn(t){return{name:"blueprint_context_update",description:"Replace blueprint context as one unit, including type, config, and exactly one trigger branch.",inputSchema:m({context:{...dt,description:"Full replacement context with type, trigger, and optional config. Trigger must have exactly one branch."}},["id","context"]),call:async e=>{let{blueprint:r}=await g(t,p(e,"id"));return r.context=ht(at(e,"context")),await B(t,r),f(r)}}}async function ae(t,e,r){let n=await Z();if(!n)throw new Error("missing jwt: set BEEPFLOW_JWT or run auth tool to persist token");let o=await X(n),i=k(),s=await fetch(`${i.workspaceUrl}/blueprints/${t}/modes/${e}/${r}`,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"}});if(!s.ok){let a=await s.text().catch(()=>"");throw new Error(`blueprint runtime action failed: ${s.status} ${a}`.trim())}return{ok:!0,status:s.status,blueprintId:t,mode:e,action:r}}function ce(t,e,r,n,o){return{name:e,description:r,inputSchema:m({mode:{type:"string",enum:["test","explore"],description:n?"Target mode.":"Mode to use. Defaults to current blueprint mode."}},n?["id","mode"]:["id"]),call:async i=>{let s=p(i,"id"),c=ke(i,"mode",["test","explore"])??(await g(t,s)).blueprint.mode;return f(await o(s,c))}}}function yn(t){return ce(t,"blueprint_mode_set","Switch blueprint mode through backend runtime endpoint to preserve side effects.",!0,async(e,r)=>ae(e,r,"switch-mode"))}function bn(t){return{name:"blueprint_test_records_set",description:"Set blueprint testRecordsAmount for test mode data generation. Uses replicated blueprint upsert; value must be at least 1.",inputSchema:m({amount:{type:"integer",minimum:1,description:"Number of test records."}},["id","amount"]),call:async e=>{let{blueprint:r}=await g(t,p(e,"id"));return r.testRecordsAmount=Yr(e,"amount"),await B(t,r),f(r)}}}function wn(t){return ce(t,"blueprint_test_records_shuffle","Regenerate test records through backend /modes/test/shuffle-records endpoint.",!1,async e=>ae(e,"test","shuffle-records"))}function Rn(t){return ce(t,"blueprint_runtime_start","Start blueprint runtime for supplied mode or current blueprint mode through backend endpoint.",!1,async(e,r)=>ae(e,r,"start"))}function kn(t){return ce(t,"blueprint_runtime_stop","Stop blueprint runtime for supplied mode or current blueprint mode through backend endpoint.",!1,async(e,r)=>ae(e,r,"stop"))}function Tn(t){return{name:"blueprint_recompute_on_change_set",description:"Set recomputeOnChange to always or manual. Frontend treats undefined as always; this tool stores explicit value for clarity.",inputSchema:m({value:{type:"string",enum:["always","manual"],description:"Recompute behavior."}},["id","value"]),call:async e=>{let{blueprint:r}=await g(t,p(e,"id"));return r.recomputeOnChange=M(e,"value",["always","manual"]),await B(t,r),f(r)}}}function Sn(t){return{name:"blueprint_mock_never_set",description:"Set or clear blueprint-level mockNever. enabled=true stores true; enabled=false clears the optional field like frontend toggle.",inputSchema:m({enabled:{type:"boolean",description:"Whether to disable mocking for all nodes."}},["id","enabled"]),call:async e=>{let{blueprint:r}=await g(t,p(e,"id"));return oe(e,"enabled")?r.mockNever=!0:delete r.mockNever,await B(t,r),f(r)}}}async function Q(t,e){let r=await t.readResourceItems("blueprint-operators"),n={};for(let o in e.nodes){let i=r[e.nodes[o].operatorId];i&&(n[i.id]=i)}return{...r,...n}}function Qt(t){if(Object.keys(t).length===0)return;let e=null,r=null;for(let n in t)isNaN(parseFloat(n))||(r===null||parseFloat(n)<r)&&(e=n,r=parseFloat(n));return r!==null?t[e]:void 0}function In(t){let e=Object.keys(t).filter(i=>!isNaN(parseFloat(i))).sort((i,s)=>parseFloat(i)-parseFloat(s));if(e.length===0)return"0.5";let r=e[e.length-1],n=parseFloat(r);return((n+(Math.floor(n)+1))/2).toPrecision(15).replace(/0+$/,"").replace(/\.$/,"")}function Be(t,e){let r=In(t);return t[r]=e,r}var vn=new Set(["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"]);function R(t,e){let r=t.nodes[e];if(!r)throw new Error(`blueprint node not found: ${e}`);return r}function W(t,e){let r=t.inputs[e];if(!r)throw new Error(`node input not found: ${t.id}.${e}`);return r.values??={},r}function yt(t,e,r,n){let i=W(R(t,e),r).values[n];if(!i)throw new Error(`input value not found: ${e}.${r}[${n}]`);return i}function Me(t,e){let r=t[e];if(!r)throw new Error(`blueprint operator not found: ${e}`);return r}function Pe(t,e){let r=t.inputs.find(n=>n.name===e);if(!r)throw new Error(`operator input not found: ${t.id}.${e}`);return r}function bt(t,e){let r=t.output;if(!r||r.name!==e)throw new Error(`operator output not found: ${t.id}.${e}`);return r}function $(t){delete t.nodeId,delete t.operatorInputId,delete t.nodeInputIndex}function xn(t,e){t.nodeId=e.nodeId,t.operatorInputId=e.operatorInputId,t.nodeInputIndex=e.nodeInputIndex}function Ee(t,e,r,n,o){let i=R(t,r.nodeId),s=R(t,n.nodeId),a=Me(e,i.operatorId),c=Me(e,s.operatorId);bt(a,r.pinName);let u=Pe(c,n.pinName),l=W(s,n.pinName),h=r.index??"0.5",y=$i(l,u,n.index,o),T=l.values[y];return T.nodeId=i.id,T.operatorInputId=r.pinName,T.nodeInputIndex=h,y}function Bn(t,e){let r=R(t,e.nodeId),n=e.index??"0.5";if(e.pinPosition==="input"){let o=yt(t,r.id,e.pinName,n);$(o);return}for(let o in t.nodes)for(let i in t.nodes[o].inputs)for(let s in t.nodes[o].inputs[i].values){let a=t.nodes[o].inputs[i].values[s];a.nodeId===r.id&&a.operatorInputId===e.pinName&&a.nodeInputIndex===n&&$(a)}}function $i(t,e,r,n){if(n)return Be(t.values,{literal:null});if(r){if(!(r in t.values))throw new Error(`input value not found: ${e.name}[${r}]`);return r}return e.type.isArray?Be(t.values,{literal:null}):"0.5"in t.values?"0.5":(t.values["0.5"]={literal:null},"0.5")}function Pn(t){return{name:"blueprint_pins_connect",description:"Connect one output pin to one input pin by writing pointer fields on target input value. Validates nodes and pin names; can create target array element. For newly created operator nodes, prefer passing inputConnections to blueprint_operator_node_add instead of calling this after creation, so layout sees graph edges before assigning coordinates.",inputSchema:m({sourceNodeId:{type:"string"},sourceOutputName:{type:"string"},sourceIndex:_(),targetNodeId:{type:"string"},targetInputName:{type:"string"},targetIndex:_(),createTargetArrayElement:{type:"boolean",description:"Append target input value before connecting."}},["id","sourceNodeId","sourceOutputName","targetNodeId","targetInputName"]),call:async e=>{let r=await g(t,p(e,"id")),n=Ee(r.blueprint,await Q(t,r.blueprint),{nodeId:p(e,"sourceNodeId"),pinName:p(e,"sourceOutputName"),index:b(e,"sourceIndex")},{nodeId:p(e,"targetNodeId"),pinName:p(e,"targetInputName"),index:b(e,"targetIndex")},st(e,"createTargetArrayElement")??!1);return await B(t,r.blueprint),f({targetIndex:n,blueprint:r.blueprint})}}}function O(t,e,r,n,o){return{name:t,description:e,inputSchema:r,call:async i=>{let{blueprint:s}=await g(n,p(i,"id"));return o(s,i),await B(n,s),f(s)}}}function En(t){return O("blueprint_pin_unlink","Unlink an input pin value or all downstream links from an output pin.",m({nodeId:{type:"string"},pinName:{type:"string"},pinPosition:{type:"string",enum:["input","output"]},index:_()},["id","nodeId","pinName","pinPosition"]),t,(e,r)=>Bn(e,{nodeId:p(r,"nodeId"),pinName:p(r,"pinName"),pinPosition:M(r,"pinPosition",["input","output"]),index:b(r,"index")}))}async function ee(t,e){let r=await t.readResourceItem("blueprint-operators",e);if(!r)throw new Error(`blueprint operator not found: ${e}`);if(!Array.isArray(r.inputs))throw new Error(`blueprint operator has invalid inputs: ${e}`);return r}async function H(t,e,r){Kt(e),E("blueprints",e),E("blueprint-views",r);let[n,o]=await Promise.all([t.upsertResourceItem("blueprints",e),t.upsertResourceItem("blueprint-views",r)]);return{blueprintOk:n,blueprintViewOk:o}}function qi(t,e=K()){let r={id:e,operatorId:t.id,inputs:{}};for(let n of t.inputs)n.type.isArray?r.inputs[n.name]={isArray:!0,values:{}}:r.inputs[n.name]={values:{"0.5":{literal:null}}};return r}function Ae(t,e,r){let n=qi(r);return t.nodes[n.id]=n,e.nodes[n.id]={id:n.id},n}function An(t){return{name:"blueprint_node_input_literal_set",description:"Set a node input literal at a CRDT value index. Defaults index to 0.5. With disconnect=true, clears upstream pointer fields first. For newly created operator nodes, prefer inputLiterals on blueprint_operator_node_add instead of setting literals afterward.",inputSchema:G({literal:{description:"JSON literal value to set."},index:_(),disconnect:{type:"boolean",description:"Clear upstream connection fields when true."}},["id","nodeId","inputName","literal"]),call:async e=>{let{blueprint:r}=await g(t,p(e,"id")),n=Ht(r,p(e,"nodeId"),p(e,"inputName"),b(e,"index")??"0.5",N(e).literal,st(e,"disconnect")??!1);return await B(t,r),f({value:n,blueprint:r})}}}function Ht(t,e,r,n,o,i){let s=yt(t,e,r,n);return s.literal=o,i&&$(s),s}function Nn(t){return{name:"blueprint_operator_node_add",description:"Add an operator node using frontend default input creation. Leaves view position unset so frontend can place it after measuring dimensions. When creating connected or configured nodes, set inputConnections and inputLiterals in this same call. Prefer this over blueprint_pins_connect and blueprint_node_input_literal_set immediately after creation because frontend uses connections present at first render to place missing-position nodes correctly.",inputSchema:Ie({operatorId:{type:"string",description:"Registered blueprint operator id."},inputConnections:{type:"array",description:"Input connections to apply before first write. Use for all known input links when creating a node; prefer this over blueprint_pins_connect after creation because frontend layout uses these connections before assigning coordinates.",items:{type:"object",additionalProperties:!1,required:["inputName","sourceNodeId","sourceOutputName","sourceIndex"],properties:{inputName:{type:"string",description:"Input pin name on the new node."},sourceNodeId:{type:"string",description:"Existing source node id."},sourceOutputName:{type:"string",description:"Source output pin name."},sourceIndex:{type:"string",description:"Source output CRDT index."},targetIndex:{type:"string",description:"Target input CRDT index. Defaults to 0.5 for scalar inputs."},createTargetArrayElement:{type:"boolean",description:"Append target input value before connecting."}}}},inputLiterals:{type:"array",description:"Input literals to apply before first write. Use for all known literal inputs when creating a node; prefer this over blueprint_node_input_literal_set immediately after creation. Same behavior as blueprint_node_input_literal_set.",items:{type:"object",additionalProperties:!1,required:["inputName","literal"],properties:{inputName:{type:"string",description:"Input pin name on the new node."},literal:{description:"JSON literal value to set."},index:{type:"string",description:"Target input CRDT index. Defaults to 0.5."},disconnect:{type:"boolean",description:"Clear upstream connection fields when true."}}}}},["id","operatorId"]),call:async e=>{let r=await g(t,p(e,"id")),n=await ee(t,p(e,"operatorId")),o=Ae(r.blueprint,r.blueprintView,n),i=Ui(e);return i.length>0&&Li(r.blueprint,await Q(t,r.blueprint),o.id,i),ji(r.blueprint,o.id,Ji(e)),await H(t,r.blueprint,r.blueprintView),f({node:o,blueprint:r.blueprint,blueprintView:r.blueprintView})}}}function ji(t,e,r){for(let n of r)Ht(t,e,n.inputName,n.index??"0.5",n.literal,n.disconnect??!1)}function Li(t,e,r,n){for(let o of n)Ee(t,e,{nodeId:o.sourceNodeId,pinName:o.sourceOutputName,index:o.sourceIndex},{nodeId:r,pinName:o.inputName,index:o.targetIndex},o.createTargetArrayElement??!1)}function Ui(t){let e=N(t).inputConnections;if(e==null)return[];if(!Array.isArray(e))throw new Error("invalid tool arguments: inputConnections must be array");let r=[];for(let n=0;n<e.length;n++){let o=e[n];if(!se(o))throw new Error(`invalid tool arguments: inputConnections[${n}] must be object`);let i=o.inputName,s=o.sourceNodeId,a=o.sourceOutputName,c=o.sourceIndex,u=o.targetIndex,l=o.createTargetArrayElement;if(typeof i!="string"||!i.trim())throw new Error(`invalid tool arguments: inputConnections[${n}].inputName must be non-empty string`);if(typeof s!="string"||!s.trim())throw new Error(`invalid tool arguments: inputConnections[${n}].sourceNodeId must be non-empty string`);if(typeof a!="string"||!a.trim())throw new Error(`invalid tool arguments: inputConnections[${n}].sourceOutputName must be non-empty string`);if(typeof c!="string"||!c.trim())throw new Error(`invalid tool arguments: inputConnections[${n}].sourceIndex must be non-empty string`);if(u!==void 0&&typeof u!="string")throw new Error(`invalid tool arguments: inputConnections[${n}].targetIndex must be string`);if(l!==void 0&&typeof l!="boolean")throw new Error(`invalid tool arguments: inputConnections[${n}].createTargetArrayElement must be boolean`);r.push({inputName:i,sourceNodeId:s,sourceOutputName:a,sourceIndex:c,targetIndex:u,createTargetArrayElement:l})}return r}function Ji(t){let e=N(t).inputLiterals;if(e==null)return[];if(!Array.isArray(e))throw new Error("invalid tool arguments: inputLiterals must be array");let r=[];for(let n=0;n<e.length;n++){let o=e[n];if(!se(o))throw new Error(`invalid tool arguments: inputLiterals[${n}] must be object`);let i=o.inputName,s=o.literal,a=o.index,c=o.disconnect;if(typeof i!="string"||!i.trim())throw new Error(`invalid tool arguments: inputLiterals[${n}].inputName must be non-empty string`);if(!("literal"in o))throw new Error(`invalid tool arguments: inputLiterals[${n}].literal is required`);if(a!==void 0&&typeof a!="string")throw new Error(`invalid tool arguments: inputLiterals[${n}].index must be string`);if(c!==void 0&&typeof c!="boolean")throw new Error(`invalid tool arguments: inputLiterals[${n}].disconnect must be boolean`);r.push({inputName:i,literal:s,index:a,disconnect:c})}return r}function On(t){return{name:"blueprint_context_field_node_add",description:"Add a context field getter node using Base/function/blueprint/field-wildcard, setting outputType and Path literal. Apache Kafka context config is initialized from field connection/path when unset.",inputSchema:Ie({connectionId:{type:"string",description:"Context field connection id."},path:{type:"string",description:"Context field path such as topic or collection."},field:{type:"string",description:"Field name to store in Path literal."},type:{type:"string",enum:Se,description:"Field output type."}},["id","connectionId","path","field","type"]),call:async e=>{let r=await g(t,p(e,"id")),n=await ee(t,"Base/function/blueprint/field-wildcard"),o=Ae(r.blueprint,r.blueprintView,n);return o.outputType=M(e,"type",Se),o.inputs.Path.values["0.5"]={literal:p(e,"field")},zi(r.blueprint.context,p(e,"connectionId"),p(e,"path")),await H(t,r.blueprint,r.blueprintView),f({node:o,blueprint:r.blueprint,blueprintView:r.blueprintView})}}}function zi(t,e,r){t.type==="ApacheKafkaTopic"&&(t.config??={},t.config.topicName===void 0&&(t.config.connectionId=e,t.config.topicName=r))}function Dn(t){return{name:"blueprint_node_result_field_node_add",description:"Add a map/get node for a field inferred from an upstream node result. Sets Path literal and optionally connects source output to Target input.",inputSchema:Ie({path:{type:"string",description:"Result field path to store in Path literal."},sourceNodeId:{type:"string",description:"Optional upstream source node id to connect into Target."},sourceOutputName:{type:"string",description:"Optional upstream output name. Defaults to source operator output."}},["id","path"]),call:async e=>{let r=await g(t,p(e,"id")),n=await ee(t,"Base/function/map/get"),o=Ae(r.blueprint,r.blueprintView,n);o.inputs.Path.values["0.5"]={literal:p(e,"path")};let i=b(e,"sourceNodeId");return i&&Ee(r.blueprint,await Q(t,r.blueprint),{nodeId:i,pinName:b(e,"sourceOutputName")??await Vi(t,r.blueprint,i)},{nodeId:o.id,pinName:"Target",index:"0.5"},!1),await H(t,r.blueprint,r.blueprintView),f({node:o,blueprint:r.blueprint,blueprintView:r.blueprintView})}}}async function Vi(t,e,r){let n=e.nodes[r];if(!n)throw new Error(`source node not found: ${r}`);let o=await ee(t,n.operatorId);if(!o.output?.name)throw new Error(`source node operator has no output: ${n.operatorId}`);return o.output.name}function Cn(t){return{name:"blueprint_node_array_input_add",description:"Append an element to an array input using frontend CRDT list index generation. Returns new index.",inputSchema:G({literal:{description:"Optional initial literal value. Defaults to null."}},["id","nodeId","inputName"]),call:async e=>{let r=await g(t,p(e,"id")),n=r.blueprint.nodes[p(e,"nodeId")];if(!n)throw new Error("node not found");let o=await ee(t,n.operatorId),i=N(e),s=Object.prototype.hasOwnProperty.call(i,"literal")?i.literal:null,a=Gi(r.blueprint,o,n.id,p(e,"inputName"),s);return await B(t,r.blueprint),f({index:a,blueprint:r.blueprint})}}}function Gi(t,e,r,n,o){let i=R(t,r);if(!Pe(e,n).type.isArray)throw new Error(`operator input is not an array: ${n}`);let a=W(i,n);return Be(a.values,{literal:o===void 0?null:o})}function _n(t){return O("blueprint_node_array_input_remove","Remove one CRDT-indexed value from a node array input.",G({index:_()},["id","nodeId","inputName","index"]),t,(e,r)=>Ki(e,p(r,"nodeId"),p(r,"inputName"),p(r,"index")))}function Ki(t,e,r,n){let o=W(R(t,e),r);if(!(n in o.values))throw new Error(`input value not found: ${e}.${r}[${n}]`);delete o.values[n]}function Wn(t){return O("blueprint_node_array_input_move","Move array input values by swapping two CRDT entries. Provide indexA/indexB or index plus direction up/down.",G({indexA:_(),indexB:_(),index:_(),direction:{type:"string",enum:["up","down"],description:"Adjacent move direction when indexA/indexB are omitted."}},["id","nodeId","inputName"]),t,(e,r)=>{let n=p(r,"inputName"),o=e.nodes[p(r,"nodeId")];if(!o)throw new Error("node not found");let i=b(r,"indexA")??p(r,"index"),s=b(r,"indexB")??Hi(o.inputs[n]?.values??{},i,M(r,"direction",["up","down"]));Qi(e,o.id,n,i,s)})}function Qi(t,e,r,n,o){let i=W(R(t,e),r);if(!(n in i.values))throw new Error(`input value not found: ${e}.${r}[${n}]`);if(!(o in i.values))throw new Error(`input value not found: ${e}.${r}[${o}]`);let s=i.values[n];i.values[n]=i.values[o],i.values[o]=s}function Hi(t,e,r){let n=[];for(let s in t)Number.isNaN(parseFloat(s))||n.push(s);n.sort((s,a)=>parseFloat(s)-parseFloat(a));let o=n.indexOf(e),i=r==="up"?n[o-1]:n[o+1];if(!i)throw new Error(`no adjacent input value ${r} from index ${e}`);return i}function Mn(t){return O("blueprint_node_input_zipping_set","Set or clear forceZipping on a node input. enabled=false clears the optional field like frontend.",G({enabled:{type:"boolean",description:"Whether to force zipping."}},["id","nodeId","inputName","enabled"]),t,(e,r)=>Zi(e,p(r,"nodeId"),p(r,"inputName"),oe(r,"enabled")))}function Zi(t,e,r,n){let o=W(R(t,e),r);n?o.forceZipping=!0:delete o.forceZipping}function Fn(t,e,r,n,o,i){if(i!==void 0&&!vn.has(i))throw new Error(`unsupported type: ${i}`);let s=R(t,r),a=Me(e,s.operatorId);n==="output"?Xi(t,e,s,a,o,i):es(t,e,s,a,o,i)}function Xt(t,e){return t.outputType??e.output?.type.type}function Xi(t,e,r,n,o,i){let s=bt(n,o);i===void 0||i===s.type.type?delete r.outputType:r.outputType=i;let a=i??s.type.type;for(let c in t.nodes)Yi(t.nodes[c],e,r,o,a)}function Yi(t,e,r,n,o){let i=e[t.operatorId];if(i)for(let s in t.inputs){let a=i.inputs.find(c=>c.name===s);if(a)for(let c in t.inputs[s].values){let u=t.inputs[s].values[c];u.nodeId!==r.id||u.operatorInputId!==n||(rs(o,t.inputs[s].type??a.type.type,a.type)?t.inputs[s].type=o:$(u))}}}function es(t,e,r,n,o,i){let s=Pe(n,o),a=W(r,o);i===void 0||i===s.type.type?delete a.type:a.type=i;let c=i??s.type.type;for(let u in a.values){let l=a.values[u];if(!l.nodeId||!l.operatorInputId)continue;let h=t.nodes[l.nodeId],y=h?e[h.operatorId]:void 0;if(!h||!y?.output)continue;let T=Xt(h,y);ns(T,c)||$(l)}ts(r,n,s.type,i)}function ts(t,e,r,n){let o=Zt(r);if(o){for(let i of e.inputs)Zt(i.type)===o&&(n?t.inputs[i.name].type=n:delete t.inputs[i.name].type);e.output&&Zt(e.output.type)===o&&(n?t.outputType=n:delete t.outputType)}}function rs(t,e,r){return wt(e)?!r.allowedTypes||r.allowedTypes.length===0?!0:r.allowedTypes.some(n=>Fe(t)?t.includes(n.type):n.type===t):Fe(t)?t.includes(e):t===e}function ns(t,e){return!t||!e?!1:t==="list of wildcard"||e==="list of wildcard"?Fe(t)&&Fe(e):!wt(t)&&!wt(e)?Fe(t)?t.includes(e):t===e:!0}function Fe(t){return t?.startsWith("list of ")??!1}function wt(t){return t==="wildcard"||t==="list of wildcard"}function Zt(t){if(t&&wt(t.type))return t.linkType??"_"}function $n(t,e){let r=new Set(e);for(let n of r)os(t,n);for(let n in t.nodes){let o=t.nodes[n];for(let i in o.inputs)for(let s in o.inputs[i].values){let a=o.inputs[i].values[s];(r.has(o.id)||a.nodeId&&r.has(a.nodeId))&&$(a)}}}function qn(t,e,r){let n={};for(let o of r){let i=t.nodes[o],s=i?e[i.operatorId]:void 0,a=s?.inputs[0];if(!i||!s?.output||!a)continue;let c=Xt(i,s),u=i.inputs[a.name]?.type??a.type.type;if(c!==u)continue;let l=Qt(i.inputs[a.name]?.values??{});l?.nodeId&&(n[i.id]=structuredClone(l))}return n}function jn(t,e,r){for(let n in t.inputs)for(let o in t.inputs[n].values){let i=t.inputs[n].values[o];i.nodeId&&(e[i.nodeId]?i.nodeId=e[i.nodeId]:r.has(i.nodeId)||$(i))}}function Ln(t,e){e?xn(t,e):$(t)}function os(t,e){if(!t.nodes[e])throw new Error(`blueprint node not found: ${e}`)}function Un(t){return O("blueprint_node_connections_remove","Remove selected nodes input links and downstream links pointing to selected nodes.",m({nodeIds:Y("Node ids whose connections should be removed.")},["id","nodeIds"]),t,(e,r)=>$n(e,ie(r,"nodeIds")))}function Jn(t){return{name:"blueprint_node_type_set",description:"Set or clear an input/output resolved type. Omitting type or setting base type clears override; incompatible existing links are disconnected.",inputSchema:m({nodeId:{type:"string"},xputType:{type:"string",enum:["input","output"]},pinName:{type:"string"},type:{type:"string",enum:Se,description:"Resolved type override. Omit to reset to operator base type."}},["id","nodeId","xputType","pinName"]),call:async e=>{let r=await g(t,p(e,"id"));return Fn(r.blueprint,await Q(t,r.blueprint),p(e,"nodeId"),M(e,"xputType",["input","output"]),p(e,"pinName"),ke(e,"type",Se)),await B(t,r.blueprint),f(r.blueprint)}}}function zn(t){return O("blueprint_nodes_disabled_set","Set or clear disabled on selected nodes. disabled=false clears optional field like frontend.",m({nodeIds:Y("Node ids to update."),disabled:{type:"boolean",description:"Whether nodes should be disabled."}},["id","nodeIds","disabled"]),t,(e,r)=>is(e,ie(r,"nodeIds"),oe(r,"disabled")))}function is(t,e,r){for(let n of e){let o=R(t,n);r?o.disabled=!0:delete o.disabled}}function Vn(t){return O("blueprint_node_mock_never_set","Set or clear node-level mockNever. enabled=false clears optional field like frontend.",m({nodeId:{type:"string"},enabled:{type:"boolean"}},["id","nodeId","enabled"]),t,(e,r)=>ss(e,p(r,"nodeId"),oe(r,"enabled")))}function ss(t,e,r){let n=R(t,e);r?n.mockNever=!0:delete n.mockNever}function Gn(t){return O("blueprint_node_skip_behavior_set","Set On Skip behavior. behavior=skip clears stored value because frontend default skip is undefined; behavior=null stores string null.",m({nodeId:{type:"string"},behavior:{type:"string",enum:["skip","null"]}},["id","nodeId","behavior"]),t,(e,r)=>as(e,p(r,"nodeId"),M(r,"behavior",["skip","null"])))}function as(t,e,r){let n=R(t,e);r==="skip"?delete n.skipBehavior:n.skipBehavior="null"}function Kn(t){return{name:"blueprint_nodes_delete",description:"Delete blueprint nodes and view nodes. Mirrors frontend rewire behavior for deleted nodes whose first input type matches output type.",inputSchema:m({nodeIds:Y("Node ids to delete.")},["id","nodeIds"]),call:async e=>{let r=await g(t,p(e,"id"));return cs(r.blueprint,r.blueprintView,await Q(t,r.blueprint),ie(e,"nodeIds")),await H(t,r.blueprint,r.blueprintView),f({blueprint:r.blueprint,blueprintView:r.blueprintView})}}}function cs(t,e,r,n){let o=new Set(n);for(let s of o)R(t,s);let i=qn(t,r,o);for(let s in t.nodes)for(let a in t.nodes[s].inputs)for(let c in t.nodes[s].inputs[a].values){let u=t.nodes[s].inputs[a].values[c];!u.nodeId||!o.has(u.nodeId)||Ln(u,i[u.nodeId])}for(let s of o)delete t.nodes[s],delete e.nodes[s]}function Qn(t){return{name:"blueprint_nodes_duplicate",description:"Duplicate selected nodes and view nodes. Remaps internal copied-node references, drops missing-node references, and leaves new node positions for the frontend layout pass.",inputSchema:m({nodeIds:Y("Node ids to duplicate.")},["id","nodeIds"]),call:async e=>{let r=await g(t,p(e,"id")),n=ps(r.blueprint,r.blueprintView,ie(e,"nodeIds"));return await H(t,r.blueprint,r.blueprintView),f({nodeIds:n,blueprint:r.blueprint,blueprintView:r.blueprintView})}}}function ps(t,e,r){let n=new Set(r);for(let a of n)R(t,a);let o={},i=r.map(a=>structuredClone(t.nodes[a])),s=new Set;for(let a in t.nodes)s.add(a);for(let a of i){let c=K();o[a.id]=c,a.id=c}for(let a of i)jn(a,o,s);for(let a of i)t.nodes[a.id]=a;for(let a of r){let c=structuredClone(e.nodes[a]??{id:a}),u=o[a];c.id=u,ds(c),e.nodes[u]=c}return r.map(a=>o[a])}function ds(t){if(!t.style)return;let e={...t.style};delete e.x,delete e.y;for(let r in e){t.style=e;return}delete t.style}function Hn(t){return[nn(t),fn(t),an(t),cn(t),pn(t),dn(t),mn(t),gn(t),hn(t),yn(t),bn(t),wn(t),Rn(t),kn(t),Tn(t),Sn(t),Nn(t),On(t),Dn(t),An(t),Cn(t),_n(t),Wn(t),Mn(t),Pn(t),En(t),Un(t),Jn(t),zn(t),Vn(t),Gn(t),Kn(t),Qn(t)]}var ge={type:"object",additionalProperties:!0},je={type:"object",additionalProperties:!1,properties:{}},Yn=["kafka-topic:offset-extents","rabbitmq-stream:offset-extents","base-event-collection:offset-extents","shopify-webhook:offset-extents"],ls=["ticket-message-created","ticket-message-failed"];function eo(t=we()){return[...fs(t),...ms(t),...gs(t),...Hn(t),...hs(t),...ys(t),...ws(t)]}function fs(t){return[{name:"resources_list",description:"Discover Beepflow resources supported by this MCP server, including writable flags and item schema URIs.",inputSchema:je,call:async()=>w({resources:fe,note:"tabs, blueprints, and blueprint-views are dedicated resources; use tabs_query, blueprints_query, and blueprint intent tools instead of generic resource_* tools."})},{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:Oe,description:"Resource whose item JSON Schema and mutation notes should be read."}}},call:async e=>{let r=Ot(v(e,"resource"));return w(Ye(r))}},{name:"resource_query",description:"Query a Beepflow resource with all, keys, or fieldEqualTo snapshot filters. Returns an item map. Use before editing existing resource items.",inputSchema:{type:"object",additionalProperties:!1,required:["resource"],properties:{resource:{type:"string",enum:Oe,description:"Resource collection to query."},all:{type:"boolean",description:"Return whole resource collection."},keys:{type:"array",items:{type:"string"},description:"Return items with these ids."},fieldEqualTo:{...ge,description:"Return items whose fields equal these exact values."}}},call:async e=>{let r=Ot(v(e,"resource")),n=Vs(e),o=await t.readResourceItems(r,n);return w(o)}},{name:"resource_upsert",description:"Create or update one writable Beepflow resource item. Mandatory: before calling resource_upsert, first call resource_schema_get for the same resource and ensure item matches that resource schema. Send full item state, not JSON patches; preserve unchanged fields.",inputSchema:{type:"object",additionalProperties:!1,required:["resource","item"],properties:{resource:{type:"string",enum:Oe,description:"Writable resource collection to create or update."},item:{...ge,description:"Full item state with non-empty id; not a JSON patch."}}},call:async e=>{let r=Dt(v(e,"resource")),n=Yt(e,"item"),o=n.id;if(typeof o!="string"||!o)throw new Error("item.id must be non-empty string");E(r,n);let i=await t.upsertResourceItem(r,n);return w({ok:i})}},{name:"resource_delete",description:"Delete one writable Beepflow resource item by key. Destructive; use only when user intent is explicit.",inputSchema:{type:"object",additionalProperties:!1,required:["resource","key"],properties:{resource:{type:"string",enum:Oe,description:"Writable resource collection to delete from."},key:{type:"string",description:"Item id to delete."}}},call:async e=>{let r=Dt(v(e,"resource")),n=v(e,"key"),o=await t.deleteResourceItem(r,n);return w({ok:o})}}]}function ms(t){return[{name:"status",description:"Mandatory first call before any Beepflow task. Call status at least once whenever user wants to inspect, edit, debug, or operate Beepflow, so agent has latest user status and MCP instructions. Returns MCP instructions, current authenticated user location, current tab id, tab, blueprint, blueprint view, used operator definitions, and context fields when on a blueprint tab.",inputSchema:je,call:async()=>Ts(t)}]}function gs(t){return[{name:"results_read",description:"Read current blueprint result events for a result id such as tabId-test or tabId-explore. Blueprint result ids are tabId-test and tabId-explore.",inputSchema:ea(),call:async e=>Ls(t,e)},{name:"results_delete_state",description:"Stop and delete persisted result state for a result id. State-changing; use only when user intent is explicit.",inputSchema:ta(),call:async e=>Us(t,e)},{name:"results_set_offsets",description:"Set current stream offsets for a result id. State-changing; use only when user intent is explicit.",inputSchema:ra(),call:async e=>Js(t,e)},{name:"stream_offset_extents_read",description:"Read stream partition offset extents from supported frontend live channels for runtime diagnostics.",inputSchema:na(),call:async e=>zs(t,e)}]}function hs(t){return[{name:"blueprint_operators_search",description:"Search blueprint operators with the same vector endpoint used by the editor menu. Use to find valid operator ids plus input/output metadata before editing blueprint nodes.",inputSchema:Zs(),call:async e=>Rs(t,e)},{name:"blueprint_context_fields_search",description:"Search contextual fields available to a blueprint using the editor menu field matching rules. Use to find fields available from blueprint context schemas.",inputSchema:Xs(),call:async e=>ks(t,e)}]}function ys(t){return[{name:"integrations_list",description:"List integration types available from the workspace integration API. Use before listing endpoints for an integration type.",inputSchema:je,call:async()=>w(await Kr())},{name:"integration_blueprint_contexts_list",description:"List backend-defined blueprint context resource types, including executionKind, config fields, and type/config templates. If a resource type is absent, do not use it for blueprint context. Use before blueprint_tab_create or blueprint_context_update when choosing context.type, context.trigger, and context.config. executionKind=managed means choose trigger { executor: { enabled: true } } because integration runtime owns stream/event/poll lifecycle. executionKind=finite means choose trigger from user intent: manual for ad hoc/sample/start-once execution, cron for scheduled refresh, loop for fixed-delay repeated polling, blueprint for upstream blueprint invocation, and webhook only for generic GET/POST /:tabId/trigger HTTP calls, not integration webhooks.",inputSchema:{type:"object",additionalProperties:!1,properties:{integrationType:{type:"string",description:"Optional integration type from integrations_list; omit to return all blueprint context resource definitions including ManualTick."},resourceType:{type:"string",description:"Optional integration resource type to return one matching blueprint context definition."}}},call:async e=>w(await Qr(Le(e,"integrationType"),Le(e,"resourceType")))},{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",description:"Integration type from integrations_list."}}},call:async e=>w(await Jt(v(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 status only to disambiguate by current space when multiple matching connections exist.",inputSchema:{type:"object",additionalProperties:!1,required:["integrationType"],properties:{integrationType:{type:"string",description:"Integration type whose connections should be listed."},spaceId:{type:"string",description:"Optional space id to restrict connection matches."}}},call:async e=>bs(t,e)},{name:"integration_endpoint_schema_get",description:"Read OpenAPI 3.1 schema for one integration type. Use before integration_endpoint_call when full request/response schema details are needed.",inputSchema:{type:"object",additionalProperties:!1,required:["integrationType"],properties:{integrationType:{type:"string",description:"Integration type whose OpenAPI schema should be read."}}},call:async e=>w(await zt(v(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. Can cause external reads or writes, read local files for multipart uploads, and write binary downloads to disk. Mutating or destructive endpoints require confirm=true. Supports JSON, form, multipart files, request headers, redirects, and binary downloads.",inputSchema:Ys(),call:async e=>w(await Hr(Hs(e)))}]}async function bs(t,e){let r={type:v(e,"integrationType")},n=Le(e,"spaceId");return n&&(r.spaceId=n),w(await t.readResourceItems("connections",{fieldEqualTo:r}))}function ws(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 r=v(e,"email");return await pr(r),Ks(`code sent to ${r}`)}},{name:"auth_email_verify_code",description:"Verify email login code and persist JWT for workspace. Modifies stored credentials.",inputSchema:{type:"object",additionalProperties:!1,required:["email","code"],properties:{email:{type:"string"},code:{type:"string"}}},call:async e=>{let r=await dr(v(e,"email"),v(e,"code"));return t.close(),w(r)}},{name:"auth_google_start",description:"Create Google OAuth login URL + request id.",inputSchema:je,call:async()=>w(await ur())},{name:"auth_google_get_token",description:"Fetch Google OAuth token using request id and persist JWT for workspace. Modifies stored credentials.",inputSchema:{type:"object",additionalProperties:!1,required:["requestId"],properties:{requestId:{type:"string"}}},call:async e=>{let r=await lr(v(e,"requestId"));return t.close(),w(r)}},{name:"auth_sign_out",description:"Delete stored JWT for current workspace. Modifies stored credentials.",inputSchema:je,call:async()=>(t.close(),w(await ar()))}]}async function Rs(t,e){let r=v(e,"query"),n=Ue(e,"limit")??25,o=er(e,"includeDeprecated")??!1,[i,s]=await Promise.all([Bs(r,n),t.readResourceItems("blueprint-operators")]),a=[];for(let c of i){let u=s[c.operatorId];u?.hidden!==!0&&(!o&&u?.isDeprecated===!0||a.push(Ps(c,u)))}return w({results:a})}async function ks(t,e){let r=v(e,"blueprintId"),n=v(e,"query"),o=Ue(e,"limit")??25,i=Le(e,"connectionId"),[s,a,c]=await Promise.all([t.readResourceItem("blueprints",r),t.readResourceItems("schemas"),t.readResourceItems("connections")]);if(!s)return w({results:[]});let u=to(s,a,c,i),l=Ns(u,n,o);return w({results:l})}async function Ts(t){let e=await vs(),r=await t.readResourceItem("user-locations",e),n=xs(r);if(!n)return w({instructions:Ce,email:e,tabId:null,location:r,tab:null,blueprint:null,blueprintView:null,blueprintOperators:{},contextFields:[]});let o=await t.readResourceItem("tabs",n);if(o?.type!=="blueprint")return w({instructions:Ce,email:e,tabId:n,location:r,tab:o,blueprint:null,blueprintView:null,blueprintOperators:{},contextFields:[]});let[i,s]=await Promise.all([t.readResourceItem("blueprints",n),t.readResourceItem("blueprint-views",n)]);if(!i)return w({instructions:Ce,email:e,tabId:n,location:r,tab:o,blueprint:null,blueprintView:s,blueprintOperators:{},contextFields:[]});let[a,c,u]=await Promise.all([Ss(t,i),t.readResourceItems("schemas"),t.readResourceItems("connections")]),l=to(i,c,u,void 0);return w({instructions:Ce,email:e,tabId:n,location:r,tab:o,blueprint:i,blueprintView:s,blueprintOperators:a,contextFields:l})}async function Ss(t,e){let r=Is(e),n=await t.readResourceItems("blueprint-operators"),o={};for(let i in r)o[i]=n[i]??null;return o}function Is(t){let e=t.nodes,r={};if(!U(e))return r;for(let n in e){let o=e[n];if(!U(o))continue;let i=o.operatorId;typeof i=="string"&&i.trim()&&(r[i]=!0)}return r}async function vs(){let t=await Z();if(!t)throw new Error("missing jwt: set BEEPFLOW_JWT or run auth tool to persist token");let e=await X(t),r=te(e).email;if(!r)throw new Error("current jwt does not include email");return r}function xs(t){let e=t?.blueprint;if(!U(e))return;let r=e.id;return typeof r=="string"&&r.trim()?r:void 0}async function Bs(t,e){let r=await Z();if(!r)throw new Error("missing jwt: set BEEPFLOW_JWT or run auth tool to persist token");let n=await X(r),o=k(),i=await fetch(`${o.workspaceUrl}/blueprint/operators/search`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify({query:t,limit:e})});if(!i.ok){let c=await i.text().catch(()=>"");throw new Error(`blueprint/operators/search failed: ${i.status} ${c}`.trim())}let s=await i.json().catch(()=>{});if(!Array.isArray(s))throw new Error("blueprint/operators/search returned invalid payload");let a=[];for(let c of s){if(!U(c))continue;let u=c.operatorId,l=c.score;typeof u!="string"||typeof l!="number"||a.push({operatorId:u,score:l})}return a}function Ps(t,e){return{kind:"operator",id:t.operatorId,name:qe(e,"name"),categoryPath:Xn(e,"categoryPath"),aliases:Xn(e,"aliases"),doc:qe(e,"doc"),inputs:qs(e),output:js(e),score:t.score}}function to(t,e,r,n){let o=Es(t.context,e),i=[];for(let s of o){if(!s.connectionId||n&&s.connectionId!==n)continue;let a=r[s.connectionId],c=Ms(s.path);for(let u in s.schema)i.push({kind:"contextField",connectionId:s.connectionId,connectionLabel:a?.label??"???",path:c,field:u,type:s.schema[u]??"wildcard",score:0})}return i}function Es(t,e){if(!t?.type)return[];let r=As(t);if(r){let i=e[r];return i?[i]:[]}let n=L(t.config,"connectionId"),o=[];for(let i in e){let s=e[i];if(s)switch(!0){case!!n:s.connectionId===n&&o.push(s);break;case s.type===t.type:o.push(s);break}}return o}function As(t){let e=t.config,r=L(e,"connectionId");if(r)switch(t.type){case"ApacheKafkaTopic":return q(r,{topicName:L(e,"topicName")});case"ShopifyWebhook":return q(r,{topicName:Fs(e)});case"RabbitMQStream":case"MQTTTopic":return q(r,{streamPattern:L(e,"streamPattern")});case"QdrantCollection":case"BaseVectorCollection":case"BaseLookupCollection":case"BaseEventCollection":return q(r,{collectionName:L(e,"collectionName")});case"AerospikeSet":return q(r,{namespace:L(e,"namespace"),setName:L(e,"setName")});case"KaggleFile":return q(r,{datasetRef:L(e,"datasetRef"),fileName:L(e,"filePath")});case"GoogleDriveFile":return q(r,{fileId:L(e,"fileId"),parser:L(e,"parser")});case"GmailMessage":return q(r,{resource:"message"});case"GmailThread":return q(r,{resource:"thread"});case"GmailEvent":return q(r,{resource:"event"});case"GorgiasEvent":return q(r,{resource:"event",variant:$s(e)?"message":"ticket"});case"GorgiasTicket":return q(r,{resource:"ticket"})}}function Ns(t,e,r){let n=[];return t.forEach((o,i)=>{let s=Ds(e,Os(o));s!==void 0&&n.push({field:{...o,score:s},index:i})}),n.sort((o,i)=>i.field.score-o.field.score||o.index-i.index).slice(0,r).map(o=>o.field)}function Os(t){return[t.connectionLabel,t.path,t.field,t.type].join(" ")}function Ds(t,e){let r=Zn(t);if(r.length===0)return;let n=e.toLowerCase(),o=Zn(e),i=0;for(let s of r){let a=Cs(s,o),c=Math.max(a,n.includes(s)?.82:0);if(c<=0)return;i+=c}return Number((i/r.length).toFixed(4))}function Cs(t,e){let r=0;for(let n of e)switch(!0){case n===t:r=Math.max(r,1);break;case n.startsWith(t):r=Math.max(r,.92);break;case n.includes(t):r=Math.max(r,.82);break;case(t.length>=3&&n.length>=3):r=Math.max(r,_s(t,n));break}return r}function _s(t,e){let r=Math.max(t.length,e.length);if(r===0)return 0;let n=1-Ws(t,e)/r;return n>=.72?n*.7:0}function Ws(t,e){let r=Array.from({length:e.length+1},(o,i)=>i),n=Array.from({length:e.length+1},()=>0);for(let o=1;o<=t.length;o+=1){n[0]=o;for(let i=1;i<=e.length;i+=1){let s=t[o-1]===e[i-1]?0:1;n[i]=Math.min(r[i]+1,n[i-1]+1,r[i-1]+s)}for(let i=0;i<r.length;i+=1)r[i]=n[i]??0}return r[e.length]??0}function Zn(t){return t.toLowerCase().split(/[^a-z0-9]+/).map(e=>e.trim()).filter(Boolean)}function q(t,e){let r="";for(let n in e){let o=e[n];if(!o)return;r+=`${n} = ${o} `}if(r=r.trim(),!!r)return us("md5").update(`${t} ${r}`).digest("hex")}function Ms(t){if(!t)return"";let e=[];for(let r in t)e.push(t[r]??"");return e.filter(Boolean).join("/")}function Fs(t){let e=t?.webhookTopics;if(U(e)){for(let r in e)if(e[r]===!0)return r}}function $s(t){let e=t?.webhookTriggers;if(!U(e))return!1;for(let r in e)if(e[r]===!0&&ls.includes(r))return!0;return!1}function L(t,e){let r=t?.[e];return typeof r=="string"&&r.trim()?r:void 0}function qe(t,e){let r=t?.[e];return typeof r=="string"?r:void 0}function Xn(t,e){let r=t?.[e];return Array.isArray(r)?r.filter(n=>typeof n=="string"):[]}function qs(t){return Array.isArray(t?.inputs)?t.inputs.map(e=>ro(e)).filter(e=>e.name):[]}function js(t){let e=t?.output;if(!U(e))return;let r=ro(e);return r.name?r:void 0}function ro(t){let e=U(t)?t:void 0,r=U(e?.type)?e.type:void 0;return{name:qe(e,"name")??"",type:qe(r,"type")??"",doc:qe(e,"doc")}}async function Ls(t,e){let r=v(e,"resultId"),n=Ue(e,"timeoutMs")??15e3,o=Ue(e,"quietMs")??250,i=`${r}:events`,s=`results:${i}`;await t.start();let a=t.collectChannelEvents(s,c=>c.key===i,n,o);t.sendChannelEvent("results",{resource:"results",key:i,action:"subscribe-key"});try{return w(Gs(await a))}finally{t.sendChannelEvent("results",{resource:"results",key:i,action:"unsubscribe-key"})}}async function Us(t,e){let r=v(e,"resultId");return await t.start(),t.sendChannelEvent("results",{resource:"results",key:r,action:"delete-state"}),w({ok:!0})}async function Js(t,e){let r=v(e,"resultId"),n=Yt(e,"offsets");return await t.start(),t.sendChannelEvent("results",{resource:"results",key:r,action:"set-offsets",value:n}),w({ok:!0})}async function zs(t,e){let r=v(e,"channel");if(!Yn.includes(r))throw new Error(`unsupported offset extent channel: ${r}`);let n=Yt(e,"key"),o=Ue(e,"timeoutMs")??15e3;await t.start();let i=t.waitForChannelEvent(r,s=>JSON.stringify(s.key)===JSON.stringify(n),o);t.sendChannelEvent(r,{resource:r,key:n,action:"on"});try{return w(await i)}finally{t.sendChannelEvent(r,{resource:r,key:n,action:"off"})}}function Vs(t){let e=Qs(t,"keys"),r=$e(t,"fieldEqualTo"),n=er(t,"all")??(!e&&!r),o={};return n&&(o.all=!0),e&&(o.keys=e),r&&(o.fieldEqualTo=r),o}function Gs(t){let e={},r;for(let n of t){let o=n.value;switch(o?.kind){case"blueprint":r=o.value;break;case"node":{let i=o.nodeId;typeof i=="string"&&(e[i]=o.value);break}case"reset":r=void 0;for(let i in e)delete e[i];break}}return{public:r,publicByNode:e,events:t}}function w(t){return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}function Ks(t){return{content:[{type:"text",text:t}]}}function v(t,e){let r=pe(t)[e];if(typeof r!="string"||!r.trim())throw new Error(`invalid tool arguments: ${e} must be non-empty string`);return r}function Le(t,e){if(t===void 0)return;let r=pe(t)[e];if(r!=null){if(typeof r!="string")throw new Error(`invalid tool arguments: ${e} must be string`);return r}}function Yt(t,e){let r=pe(t)[e];if(!U(r))throw new Error(`invalid tool arguments: ${e} must be object`);return r}function $e(t,e){let r=pe(t)[e];if(r!=null){if(!U(r))throw new Error(`invalid tool arguments: ${e} must be object`);return r}}function Qs(t,e){let r=pe(t)[e];if(r!=null){if(!Array.isArray(r)||r.some(n=>typeof n!="string"))throw new Error(`invalid tool arguments: ${e} must be string array`);return r}}function er(t,e){let r=pe(t)[e];if(r!=null){if(typeof r!="boolean")throw new Error(`invalid tool arguments: ${e} must be boolean`);return r}}function Ue(t,e){let r=pe(t)[e];if(r!=null){if(typeof r!="number"||!Number.isInteger(r)||r<=0)throw new Error(`invalid tool arguments: ${e} must be positive integer`);return r}}function Hs(t){let e=pe(t);return{integrationType:v(t,"integrationType"),operationId:v(t,"operationId"),path:$e(t,"path"),query:$e(t,"query"),headers:$e(t,"headers"),body:e.body,files:$e(t,"files"),outputFilePath:Le(t,"outputFilePath"),confirm:er(t,"confirm")}}function pe(t){if(!t||typeof t!="object"||Array.isArray(t))throw new Error("invalid tool arguments: expected object");return t}function U(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Zs(){return{type:"object",additionalProperties:!1,required:["query"],properties:{query:{type:"string",description:"Operator name, alias, category, or behavior to search for."},limit:{type:"integer",minimum:1,description:"Maximum number of operator matches to return."},includeDeprecated:{type:"boolean",description:"Include deprecated operators in results when true."}}}}function Xs(){return{type:"object",additionalProperties:!1,required:["blueprintId","query"],properties:{blueprintId:{type:"string",description:"Blueprint id whose context schemas should be searched."},query:{type:"string",description:"Field name, path, connection label, or type to search for."},limit:{type:"integer",minimum:1,description:"Maximum number of context fields to return."},connectionId:{type:"string",description:"Optional connection id to restrict context field matches."}}}}function Ys(){return{type:"object",additionalProperties:!1,required:["integrationType","operationId"],properties:{integrationType:{type:"string",description:"Integration type from integrations_list."},operationId:{type:"string",description:"Operation id from integration_endpoints_list or integration_endpoint_schema_get."},path:{...ge,description:"Path parameter values keyed by parameter name."},query:{...ge,description:"Query parameter values. For endpoints requiring connectionId, pass selected connection id as query.connectionId."},headers:{...ge,description:"Request headers to send to endpoint."},body:{description:"JSON, form, or multipart body matching endpoint metadata."},files:{type:"object",description:"Multipart file inputs keyed by form field name. Reads local files when filePath is provided.",additionalProperties:{type:"object",additionalProperties:!1,properties:{filePath:{type:"string",description:"Local file path to read and upload."},base64:{type:"string",description:"Base64-encoded file content."},fileName:{type:"string",description:"File name to send for base64 content."},contentType:{type:"string",description:"MIME type for uploaded content."}}}},outputFilePath:{type:"string",description:"Local path where binary response downloads should be written."},confirm:{type:"boolean",description:"Required true for mutating or destructive endpoints after explicit user intent."}}}}function ea(){return{type:"object",additionalProperties:!1,required:["resultId"],properties:{resultId:{type:"string",description:"Blueprint result id, normally tabId-test or tabId-explore."},timeoutMs:{type:"integer",minimum:1,description:"Maximum wait in milliseconds."},quietMs:{type:"integer",minimum:1,description:"Quiet period before returning collected events."}}}}function ta(){return{type:"object",additionalProperties:!1,required:["resultId"],properties:{resultId:{type:"string",description:"Blueprint result id, normally tabId-test or tabId-explore."}}}}function ra(){return{type:"object",additionalProperties:!1,required:["resultId","offsets"],properties:{resultId:{type:"string",description:"Blueprint result id, normally tabId-test or tabId-explore."},offsets:{...ge,description:"Stream offsets to set for current result state."}}}}function na(){return{type:"object",additionalProperties:!1,required:["channel","key"],properties:{channel:{type:"string",enum:Yn,description:"Offset extent live channel to read."},key:{...ge,description:"Stream partition key to read extents for."},timeoutMs:{type:"integer",minimum:1,description:"Maximum wait in milliseconds."}}}}var Je="application/json";function no(t=we()){return[{uri:"beepflow://resources",name:"Beepflow workspace resource registry",description:"Resource registry supported by this MCP server, including item schema URIs.",mimeType:Je,read:async()=>Rt("beepflow://resources",fe)},{uri:"beepflow://resource-schemas",name:"Beepflow workspace resource schema registry",description:"JSON Schema registry for resource items supported by this MCP server.",mimeType:Je,read:async()=>Rt("beepflow://resource-schemas",Xe)},...Xe.map(e=>({uri:e.uri,name:`Beepflow ${e.resource} item schema`,description:`JSON Schema for ${e.resource} resource items.`,mimeType:Je,read:async()=>Rt(e.uri,e)})),...fe.map(e=>({uri:`beepflow://resources/${e.name}`,name:`Beepflow ${e.name}`,description:e.description,mimeType:Je,read:async()=>{let r=await t.readResourceItems(e.name);return Rt(`beepflow://resources/${e.name}`,r)}}))]}function Rt(t,e){return{contents:[{uri:t,mimeType:Je,text:JSON.stringify(e,null,2)}]}}var kt=we(),{server:oa,closeServer:ia}=rr({serverName:"mcp",serverVersion:"0.1.0",instructions:Zr,tools:eo(kt),resources:no(kt),onInitialized:()=>{kt.start().catch(()=>{})}});process.on("SIGINT",()=>oo("SIGINT"));process.on("SIGTERM",()=>oo("SIGTERM"));oa.start();function oo(t){kt.close(),ia(t)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beepflow/mcp",
3
- "version": "2026.4.8",
3
+ "version": "2026.5.1",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=24.6.0"
@@ -16,8 +16,8 @@
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\" \"../shared/replicated-state/**/*.test.ts\"",
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);\"",
19
+ "test:src": "tsc -b ../shared/tsconfig.json && node --experimental-strip-types --test \"./src/**/*.test.ts\" \"../shared/replicated-state/**/*.test.ts\"",
20
+ "build": "node --input-type=module -e \"import fs from 'node:fs'; fs.rmSync('dist', { recursive: true, force: true });\" && tsc -b ../shared/tsconfig.json && 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",
23
23
  "prepack": "yarn build"