@membranehq/cli 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +11 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -138,16 +138,16 @@ ${t.comment}`:t.comment}this.doc.range[2]=t.offset;break}default:this.errors.pus
|
|
|
138
138
|
`)+1;for(;t!==0;)this.onNewLine(this.offset+t),t=this.source.indexOf(`
|
|
139
139
|
`,t)+1}yield*this.pop();break;default:yield*this.pop(),yield*this.step()}}*blockMap(e){const t=e.items[e.items.length-1];switch(this.type){case"newline":if(this.onKeyLine=!1,t.value){const n="end"in t.value?t.value.end:void 0;(Array.isArray(n)?n[n.length-1]:void 0)?.type==="comment"?n?.push(this.sourceToken):e.items.push({start:[this.sourceToken]})}else t.sep?t.sep.push(this.sourceToken):t.start.push(this.sourceToken);return;case"space":case"comment":if(t.value)e.items.push({start:[this.sourceToken]});else if(t.sep)t.sep.push(this.sourceToken);else{if(this.atIndentedComment(t.start,e.indent)){const r=e.items[e.items.length-2]?.value?.end;if(Array.isArray(r)){Array.prototype.push.apply(r,t.start),r.push(this.sourceToken),e.items.pop();return}}t.start.push(this.sourceToken)}return}if(this.indent>=e.indent){const n=!this.onKeyLine&&this.indent===e.indent,r=n&&(t.sep||t.explicitKey)&&this.type!=="seq-item-ind";let i=[];if(r&&t.sep&&!t.value){const o=[];for(let a=0;a<t.sep.length;++a){const l=t.sep[a];switch(l.type){case"newline":o.push(a);break;case"space":break;case"comment":l.indent>e.indent&&(o.length=0);break;default:o.length=0}}o.length>=2&&(i=t.sep.splice(o[1]))}switch(this.type){case"anchor":case"tag":r||t.value?(i.push(this.sourceToken),e.items.push({start:i}),this.onKeyLine=!0):t.sep?t.sep.push(this.sourceToken):t.start.push(this.sourceToken);return;case"explicit-key-ind":!t.sep&&!t.explicitKey?(t.start.push(this.sourceToken),t.explicitKey=!0):r||t.value?(i.push(this.sourceToken),e.items.push({start:i,explicitKey:!0})):this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken],explicitKey:!0}]}),this.onKeyLine=!0;return;case"map-value-ind":if(t.explicitKey)if(t.sep)if(t.value)e.items.push({start:[],key:null,sep:[this.sourceToken]});else if(Be(t.sep,"map-value-ind"))this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:i,key:null,sep:[this.sourceToken]}]});else if(Jo(t.key)&&!Be(t.sep,"newline")){const o=_t(t.start),a=t.key,l=t.sep;l.push(this.sourceToken),delete t.key,delete t.sep,this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:o,key:a,sep:l}]})}else i.length>0?t.sep=t.sep.concat(i,this.sourceToken):t.sep.push(this.sourceToken);else if(Be(t.start,"newline"))Object.assign(t,{key:null,sep:[this.sourceToken]});else{const o=_t(t.start);this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:o,key:null,sep:[this.sourceToken]}]})}else t.sep?t.value||r?e.items.push({start:i,key:null,sep:[this.sourceToken]}):Be(t.sep,"map-value-ind")?this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:[],key:null,sep:[this.sourceToken]}]}):t.sep.push(this.sourceToken):Object.assign(t,{key:null,sep:[this.sourceToken]});this.onKeyLine=!0;return;case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":{const o=this.flowScalar(this.type);r||t.value?(e.items.push({start:i,key:o,sep:[]}),this.onKeyLine=!0):t.sep?this.stack.push(o):(Object.assign(t,{key:o,sep:[]}),this.onKeyLine=!0);return}default:{const o=this.startBlockValue(e);if(o){if(o.type==="block-seq"){if(!t.explicitKey&&t.sep&&!Be(t.sep,"newline")){yield*this.pop({type:"error",offset:this.offset,message:"Unexpected block-seq-ind on same line with key",source:this.source});return}}else n&&e.items.push({start:i});this.stack.push(o);return}}}}yield*this.pop(),yield*this.step()}*blockSequence(e){const t=e.items[e.items.length-1];switch(this.type){case"newline":if(t.value){const n="end"in t.value?t.value.end:void 0;(Array.isArray(n)?n[n.length-1]:void 0)?.type==="comment"?n?.push(this.sourceToken):e.items.push({start:[this.sourceToken]})}else t.start.push(this.sourceToken);return;case"space":case"comment":if(t.value)e.items.push({start:[this.sourceToken]});else{if(this.atIndentedComment(t.start,e.indent)){const r=e.items[e.items.length-2]?.value?.end;if(Array.isArray(r)){Array.prototype.push.apply(r,t.start),r.push(this.sourceToken),e.items.pop();return}}t.start.push(this.sourceToken)}return;case"anchor":case"tag":if(t.value||this.indent<=e.indent)break;t.start.push(this.sourceToken);return;case"seq-item-ind":if(this.indent!==e.indent)break;t.value||Be(t.start,"seq-item-ind")?e.items.push({start:[this.sourceToken]}):t.start.push(this.sourceToken);return}if(this.indent>e.indent){const n=this.startBlockValue(e);if(n){this.stack.push(n);return}}yield*this.pop(),yield*this.step()}*flowCollection(e){const t=e.items[e.items.length-1];if(this.type==="flow-error-end"){let n;do yield*this.pop(),n=this.peek(1);while(n&&n.type==="flow-collection")}else if(e.end.length===0){switch(this.type){case"comma":case"explicit-key-ind":!t||t.sep?e.items.push({start:[this.sourceToken]}):t.start.push(this.sourceToken);return;case"map-value-ind":!t||t.value?e.items.push({start:[],key:null,sep:[this.sourceToken]}):t.sep?t.sep.push(this.sourceToken):Object.assign(t,{key:null,sep:[this.sourceToken]});return;case"space":case"comment":case"newline":case"anchor":case"tag":!t||t.value?e.items.push({start:[this.sourceToken]}):t.sep?t.sep.push(this.sourceToken):t.start.push(this.sourceToken);return;case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":{const r=this.flowScalar(this.type);!t||t.value?e.items.push({start:[],key:r,sep:[]}):t.sep?this.stack.push(r):Object.assign(t,{key:r,sep:[]});return}case"flow-map-end":case"flow-seq-end":e.end.push(this.sourceToken);return}const n=this.startBlockValue(e);n?this.stack.push(n):(yield*this.pop(),yield*this.step())}else{const n=this.peek(2);if(n.type==="block-map"&&(this.type==="map-value-ind"&&n.indent===e.indent||this.type==="newline"&&!n.items[n.items.length-1].sep))yield*this.pop(),yield*this.step();else if(this.type==="map-value-ind"&&n.type!=="flow-collection"){const r=es(n),i=_t(r);Ho(e);const o=e.end.splice(1,e.end.length);o.push(this.sourceToken);const a={type:"block-map",offset:e.offset,indent:e.indent,items:[{start:i,key:e,sep:o}]};this.onKeyLine=!0,this.stack[this.stack.length-1]=a}else yield*this.lineEnd(e)}}flowScalar(e){if(this.onNewLine){let t=this.source.indexOf(`
|
|
140
140
|
`)+1;for(;t!==0;)this.onNewLine(this.offset+t),t=this.source.indexOf(`
|
|
141
|
-
`,t)+1}return{type:e,offset:this.offset,indent:this.indent,source:this.source}}startBlockValue(e){switch(this.type){case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return this.flowScalar(this.type);case"block-scalar-header":return{type:"block-scalar",offset:this.offset,indent:this.indent,props:[this.sourceToken],source:""};case"flow-map-start":case"flow-seq-start":return{type:"flow-collection",offset:this.offset,indent:this.indent,start:this.sourceToken,items:[],end:[]};case"seq-item-ind":return{type:"block-seq",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken]}]};case"explicit-key-ind":{this.onKeyLine=!0;const t=es(e),n=_t(t);return n.push(this.sourceToken),{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:n,explicitKey:!0}]}}case"map-value-ind":{this.onKeyLine=!0;const t=es(e),n=_t(t);return{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:n,key:null,sep:[this.sourceToken]}]}}}return null}atIndentedComment(e,t){return this.type!=="comment"||this.indent<=t?!1:e.every(n=>n.type==="newline"||n.type==="space")}*documentEnd(e){this.type!=="doc-mode"&&(e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop()))}*lineEnd(e){switch(this.type){case"comma":case"doc-start":case"doc-end":case"flow-seq-end":case"flow-map-end":case"map-value-ind":yield*this.pop(),yield*this.step();break;case"newline":this.onKeyLine=!1;case"space":case"comment":default:e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop())}}}function Vo(s){const e=s.prettyErrors!==!1;return{lineCounter:s.lineCounter||e&&new Uo||null,prettyErrors:e}}c(Vo,"parseOptions");function Iu(s,e={}){const{lineCounter:t,prettyErrors:n}=Vo(e),r=new br(t?.addNewLine),i=new mr(e),o=Array.from(i.compose(r.parse(s)));if(n&&t)for(const a of o)a.errors.forEach(Vn(s,t)),a.warnings.forEach(Vn(s,t));return o.length>0?o:Object.assign([],{empty:!0},i.streamInfo())}c(Iu,"parseAllDocuments");function Go(s,e={}){const{lineCounter:t,prettyErrors:n}=Vo(e),r=new br(t?.addNewLine),i=new mr(e);let o=null;for(const a of i.compose(r.parse(s),!0,s.length))if(!o)o=a;else if(o.options.logLevel!=="silent"){o.errors.push(new Qe(a.range.slice(0,2),"MULTIPLE_DOCS","Source contains multiple documents; please use YAML.parseAllDocuments()"));break}return n&&t&&(o.errors.forEach(Vn(s,t)),o.warnings.forEach(Vn(s,t))),o}c(Go,"parseDocument");function $u(s,e,t){let n;typeof e=="function"?n=e:t===void 0&&e&&typeof e=="object"&&(t=e);const r=Go(s,t);if(!r)return null;if(r.warnings.forEach(i=>ro(r.options.logLevel,i)),r.errors.length>0){if(r.options.logLevel!=="silent")throw r.errors[0];r.errors=[]}return r.toJS(Object.assign({reviver:n},t))}c($u,"parse");function Nu(s,e,t){let n=null;if(typeof e=="function"||Array.isArray(e)?n=e:t===void 0&&e&&(t=e),typeof t=="string"&&(t=t.length),typeof t=="number"){const r=Math.round(t);t=r<1?void 0:r>8?{indent:8}:{indent:r}}if(s===void 0){const{keepUndefined:r}=t??e??{};if(!r)return}return Ge(s)&&!n?s.toString(t):new Rt(s,n,t).toString(t)}c(Nu,"stringify");var xu=Object.freeze({__proto__:null,Alias:$n,CST:Eu,Composer:mr,Document:Rt,Lexer:qo,LineCounter:Uo,Pair:se,Parser:br,Scalar:M,Schema:Es,YAMLError:lr,YAMLMap:ue,YAMLParseError:Qe,YAMLSeq:Ke,YAMLWarning:Oo,isAlias:Fe,isCollection:G,isDocument:Ge,isMap:dt,isNode:z,isPair:H,isScalar:W,isSeq:pt,parse:$u,parseAllDocuments:Iu,parseDocument:Go,stringify:Nu,visit:ze,visitAsync:In});const he={Updated:"updated",Deleted:"deleted",Stopped:"stopped"},Mu={ignored:ul,persistent:!0,ignoreInitial:!0,followSymlinks:!1,depth:20,awaitWriteFinish:{stabilityThreshold:500,pollInterval:100},ignorePermissionErrors:!0,atomic:!0,usePolling:!1,alwaysStat:!1,interval:1e3,binaryInterval:300};class Ru extends qs{static{c(this,"LocalElementWatcher")}constructor(e){super(),this.options=e,this.membraneDir=ht(this.options.cwd),this.lockTimeoutMs=this.options.lockTimeoutMs??1e3}isWatching=!1;watcher;membraneDir;contentCache={};ignoredPaths=new Set;lockTimeoutMs;async start(){this.isWatching||(P.existsSync(this.membraneDir)||P.mkdirSync(this.membraneDir,{recursive:!0}),this.initializeContentCache(),this.watcher=xc.watch(this.membraneDir,Mu),this.watcher.on("add",e=>this.handleFileSystemEvent(he.Updated,e)).on("change",e=>this.handleFileSystemEvent(he.Updated,e)).on("unlink",e=>this.handleFileSystemEvent(he.Deleted,e)).on("ready",()=>this.isWatching=!0))}async stop(){!this.isWatching||!this.watcher||(await this.watcher.close(),this.isWatching=!1,this.watcher=void 0,this.clearCache(),this.clearAllLocks(),this.emit(he.Stopped))}getCwd(){return this.options.cwd}async executeWithPathLock(e,t){const n=F.resolve(e);this.ignoredPaths.add(n);try{await t()}finally{setTimeout(()=>{this.ignoredPaths.delete(n)},this.lockTimeoutMs)}}isPathLocked(e){const t=F.resolve(e);if(this.ignoredPaths.has(t))return!0;for(const n of this.ignoredPaths)if(t.startsWith(n+F.sep))return!0;return!1}clearAllLocks(){this.ignoredPaths.clear()}handleFileSystemEvent(e,t){const n=F.relative(this.membraneDir,t);if(this.isPathLocked(t))return;if(e===he.Deleted){this.removeFromCache(n);const a={filePath:t,relativePath:n,data:void 0};b.info(`[local] ${e}: ${a.relativePath}`),this.emit(e,a);return}const r=this.readFileContent(t);if(!this.hasContentChanged(n,r))return;const o=this.processFileEvent(t,r);this.updateCache(n,r),o&&(b.info(`[local] ${e}: ${o.relativePath}`),this.emit(e,o))}readFileContent(e){return P.readFileSync(e,"utf8")}processFileEvent(e,t){const n=F.relative(this.membraneDir,e);let r;try{r=t?xu.parse(t):void 0}catch{r=void 0}return{filePath:e,relativePath:n,data:r}}hasContentChanged(e,t){if(!t)return this.contentCache[e]!==void 0;const n=this.getContentHash(t);return this.contentCache[e]!==n}getContentHash(e){return $c.createHash("sha256").update(e).digest("hex")}updateCache(e,t){if(!t){delete this.contentCache[e];return}this.contentCache[e]=this.getContentHash(t)}removeFromCache(e){delete this.contentCache[e]}clearCache(){Object.keys(this.contentCache).forEach(e=>{delete this.contentCache[e]})}initializeContentCache(){P.existsSync(this.membraneDir)&&this.scanDirectoryForCache(this.membraneDir)}scanDirectoryForCache(e){const t=P.readdirSync(e,{withFileTypes:!0});for(const n of t){const r=F.join(e,n.name);if(n.isDirectory())this.scanDirectoryForCache(r);else if(n.isFile())try{const i=P.readFileSync(r,"utf8"),o=F.relative(this.membraneDir,r);this.updateCache(o,i)}catch{}}}}var Sr=(s=>(s.Updated="updated",s.ConnectorFileUpdated="connector-file-updated",s.Connected="connected",s.Disconnected="disconnected",s.Error="error",s))(Sr||{});const Pu={debounceMs:2e3,reconnectIntervalMs:5e3,maxReconnectAttempts:5};class Lu extends qs{static{c(this,"RemoteElementWatcher")}constructor(e=Pu){super(),this.config=e}eventSource;debounceTimeouts=new Map;reconnectAttempts=0;reconnectTimeout;isStarted=!1;async start(){this.isStarted||(this.isStarted=!0,await this.connect())}async stop(){this.isStarted&&(this.isStarted=!1,this.clearReconnectTimeout(),this.clearAllDebounceTimeouts(),this.eventSource&&(this.eventSource.close(),this.eventSource=void 0))}async connect(){try{b.debug("[remote-events] Connecting to server");const e=await U.getClient(process.cwd()),t=await e.getToken();if(!t)throw new Error("No auth token available");const n=`${e.apiUri}/sse/workspace?token=${encodeURIComponent(t)}`;b.debug("[remote-events] Subscribing to workspace events"),this.eventSource=new Mc(n),this.setupEventSourceHandlers()}catch(e){b.error(`[remote-events] Failed to subscribe to workspace events: ${e}`),this.emit("error",{error:e}),this.scheduleReconnect()}}setupEventSourceHandlers(){this.eventSource&&(this.eventSource.onopen=()=>{b.debug("[remote-events] Connected to server"),this.reconnectAttempts=0,this.emit("connected",{})},this.eventSource.onmessage=e=>{try{const t=JSON.parse(e.data);this.handleElementUpdate(t)}catch(t){b.error(`[remote-events] Failed to parse workspace event: ${t}`)}},this.eventSource.onerror=e=>{b.error(`[remote-events] Connection error: ${JSON.stringify(e,null,2)}`),this.emit("disconnected",{}),this.isStarted&&this.scheduleReconnect()})}handleElementUpdate(e){if(e.type!==vc.ElementUpdate)return;const{elementId:t,elementType:n,data:r={}}=e;if(!(!t||!n)){if(n===B.Connector){const{filePath:i,eventType:o,newPath:a}=r;return b.debug(`[remote-watcher] Received connector event - elementId: ${t}, filePath: ${i}, eventType: ${o}`),this.scheduleConnectorFileUpdate(t,i,o,a)}return this.scheduleElementUpdate(t,n)}}scheduleElementUpdate(e,t){const n=this.debounceTimeouts.get(e);n&&clearTimeout(n);const r=setTimeout(()=>{this.debounceTimeouts.delete(e),this.emit("updated",{elementId:e,elementType:t})},this.config.debounceMs);this.debounceTimeouts.set(e,r)}scheduleConnectorFileUpdate(e,t,n,r){const i=JSON.stringify({connectorId:e,filePath:t}),o=this.debounceTimeouts.get(i);o&&clearTimeout(o);const a=setTimeout(()=>{this.debounceTimeouts.delete(i),this.emit("connector-file-updated",{connectorId:e,filePath:t,eventType:n,newPath:r})},this.config.debounceMs);this.debounceTimeouts.set(i,a)}scheduleReconnect(){if(!this.isStarted||this.reconnectAttempts>=this.config.maxReconnectAttempts){if(this.reconnectAttempts>=this.config.maxReconnectAttempts)throw new Error("Unable to re-connect to the server");return}this.reconnectAttempts++;const e=Math.min(this.config.reconnectIntervalMs*Math.pow(2,this.reconnectAttempts-1),3e4);b.debug(`[remote-watcher] Reconnecting in ${e}ms (attempt ${this.reconnectAttempts})`),this.reconnectTimeout=setTimeout(()=>{this.connect()},e)}clearReconnectTimeout(){this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=void 0)}clearAllDebounceTimeouts(){this.debounceTimeouts.forEach(e=>clearTimeout(e)),this.debounceTimeouts.clear()}}class zo{static{c(this,"ElementsCache")}elements=new Map;typeIndex=new Map;internalIdIndex=new Map;constructor(e){e&&this.addAll(e)}add(e){const t=e.id;this.elements.set(t,e),this.typeIndex.has(e.type)||this.typeIndex.set(e.type,new Set),this.typeIndex.get(e.type).add(t),e.data?.id&&this.internalIdIndex.set(e.data.id,t)}remove(e){const t=e.id,n=this.elements.delete(t);if(n){const r=this.typeIndex.get(e.type);r&&(r.delete(t),r.size===0&&this.typeIndex.delete(e.type)),e.data?.id&&this.internalIdIndex.delete(e.data.id)}return n}put(e){this.elements.has(e.id)&&this.remove(e),this.add(e)}get(e){return this.elements.get(e)}getByInternalId(e){const t=this.internalIdIndex.get(e);if(t)return this.elements.get(t)}getElementsByType(e){const t=this.typeIndex.get(e);return t?Array.from(t).map(n=>this.elements.get(n)).filter(n=>n!==void 0):[]}getAll(){return Array.from(this.elements.values())??[]}getTypes(){return Array.from(this.typeIndex.keys())}addAll(e){for(const t of e)t&&this.add(t)}removeAll(e){for(const t of e)this.remove(t)}getElementIdsByType(e){return this.typeIndex.get(e)}clear(){this.elements.clear(),this.typeIndex.clear(),this.internalIdIndex.clear()}getAllIds(){return new Set(this.elements.keys())}}async function Du(s="full"){const e={};b.info("[connectors] Getting remote workspace data");const t=await U.withClient(n=>n.integrations.findAll());e.integration=t.map(n=>vr("integration",n));for(const n of Object.keys(le)){const r=le[n];if(r.exportable===!1)continue;const i=[];b.info(`[connectors] Reading ${r.elements} from remote workspace`);const o=await U.withClient(a=>a[r.elements].findAll());if(i.push(...o.map(a=>vr(n,a))),r.integrationSpecific)for(const a of t){const l=await U.withClient(u=>u[r.elements].findAll({integrationId:a.id}));i.push(...l.map(u=>(u.integrationKey=a.key,vr(n,u))))}i.length>0&&s=="full"&&(console.table(i.map(a=>({key:a.key,integrationKey:a.integrationKey,universal:!a.integrationKey})).reduce((a,l)=>(a||(a={}),a[l.key]||(a[l.key]={}),l.universal&&(a[l.key].universal=!0),l.integrationKey&&(a[l.key].integration?a[l.key].integration+=` ${l.integrationKey}`:a[l.key].integration=l.integrationKey),a),{})),console.groupEnd()),e[n]=i}return b.success("[connectors] Remote workspace data retrieved successfully"),e}c(Du,"getWorkspaceData");function vr(s,e){return e=cl(e),le[s].exportCleanup?le[s].exportCleanup(e):e}c(vr,"cleanUpForExport");const Tt="connectors",Ne="development",Cr={};async function ju(){const s=await Du("minified"),t=(await U.withClient(l=>l.get("org-workspace-id"))).id,n={};b.info("[connectors] Loading custom connectors");const r=await U.withClient(l=>l.get(`/connectors?workspaceId=${t}`));b.info("[connectors] Loading public connectors"),s.connector=r;const i=qe(),a=(D.existsSync(i)?D.readdirSync(i):[]).filter(l=>{if(l.startsWith("."))return!1;const u=q.join(i,l);try{return D.statSync(u).isDirectory()}catch{return!1}});for(const l of a){b.info(`[connectors] Loading connector from: ${l}`);const u=D.readdirSync(q.join(i,l)),h=await kr(l);if(!h)continue;if("baseUri"in h&&delete h.baseUri,h.uuid&&s.connector?.find(p=>p.uuid==h.uuid))n[h.id]=s.connector.find(p=>p.uuid==h.uuid).id,b.info(`[connectors] Matched ${h.name} uuid: ${h.uuid}`);else if(!n[h.id]){let p=!1;try{const m=await _r({connectorId:h.id});m&&!m.workspaceId&&(p=!0)}catch{}if(!p){b.info(`[connectors] Creating custom connector ${h.name} (${h.key})`);const m=await U.withClient(y=>y.post("connectors",{...h,workspaceId:t}));n[h.id]=m.id}}const f=u.filter(p=>D.statSync(q.join(i,l,p)).isDirectory());for(const p of f)await Bu({connector:h,version:p,connectorId:n[h.id]})}return n}c(ju,"pushConnectors");async function Yo({connectorId:s,connectorVersion:e,allConnectors:t,pulledConnectors:n,pulledConnectorVersions:r}){if(!s||r[s]?.has(e))return;const i=Di(),o=await _r({connectorId:s});if(o.workspaceId||t){if(!o?.key){b.error(`[connectors] Connector ${s} has no key. Skipping..`);return}n.has(s)||(await qu({basePath:i,connector:o}),n.add(s)),r[s]||(r[s]=new Set),r[s].has(e)||(await Uu({connector:o,connectorVersion:e,basePath:i}),r[s].add(e))}}c(Yo,"pullRemoteConnector");function qe(){const s=Ws();return q.join(s.membraneDirPath,Tt)}c(qe,"getConnectorsPath");async function kr(s){const e=q.join(qe(),s,`${s}.yml`);return Js(e,!1)}c(kr,"readConnector");async function Fu(s,e){return b.info(`[connectors] Zipping ${s} into ${e}`),new Promise((t,n)=>{const r=D.createWriteStream(e),i=Rc("zip",{zlib:{level:9}});r.on("close",()=>{b.success(`[connectors] Successfully created ${e}`),t()}),r.on("end",()=>{b.info("[connectors] Data has been drained")}),i.on("warning",a=>{a.code==="ENOENT"?console.warn(a):n(a)}),i.on("error",a=>{n(a)}),i.pipe(r);const o=D.readdirSync(s);for(const a of o){const l=q.join(s,a),u=D.statSync(l);u.isFile()?i.file(l,{name:a}):u.isDirectory()&&i.directory(l,a)}i.finalize()})}c(Fu,"createZipArchive");async function Ku(s,e){return b.info(`[connectors] Unzipping into ${e}`),new Promise((t,n)=>{const r=Lc.Parse();r.on("entry",i=>{const o=i.path;if(i.type==="Directory"){const l=q.join(e,o);D.mkdirSync(l,{recursive:!0}),i.autodrain()}else{const l=q.join(e,o),u=q.dirname(l);D.mkdirSync(u,{recursive:!0});const h=D.createWriteStream(l);i.pipe(h),h.on("finish",()=>{})}}),r.on("end",()=>{b.success(`[connectors] Successfully extracted to ${e}`),t()}),r.on("error",i=>{n(i)}),r.write(s),r.end()})}c(Ku,"extractZipArchive");async function Bu({connector:s,version:e,connectorId:t}){const n=q.join(qe(),xe(s),Xo(e)),r=q.join(n,"src"),i=q.join(n,"src.zip"),o=D.existsSync(i);if(D.existsSync(r)&&(b.info(`[connectors] Archiving source code for ${s.name} version ${e}`),await Fu(r,i)),!D.existsSync(i)){b.warning(`[connectors] No source code found for ${s.name} version ${e}`);return}try{const a=new Pc;if(a.append("file",D.createReadStream(i),"file.zip"),b.info(`[connectors] Pushing connector version ${e} for ${s.name}`),e==Ne)b.info(`[connectors] Uploading connector ${t}`),await U.withClient(l=>l.post(`connectors/${t}/upload`,a,{headers:{...a.getHeaders()}}));else{if(a.append("version",e),a.append("changelog","Imported Version"),(await U.withClient(u=>u.get(`/connectors/${t}/versions`))).find(u=>u.version==e)){b.info(`[connectors] Version ${e} already published`);return}b.info(`[connectors] Publishing version ${e} of connector ${t}`),await U.withClient(u=>u.post(`connectors/${t}/publish-version`,a,{headers:{...a.getHeaders()}}))}b.success(`Successfully pushed connector version ${e} for ${s.name}`)}catch(a){b.error(`Error pushing connector version ${e} for ${s.name}: ${a}`)}finally{!o&&D.existsSync(i)&&(b.info(`[connectors] Cleaning up temporary zip file for ${s.name} version ${e}`),D.unlinkSync(i))}}c(Bu,"pushConnectorVersion");async function _r({connectorId:s}){if(s){if(Cr[s])return Cr[s];try{const e=await U.withClient(t=>t.get(`connectors/${s}`));return Cr[s]=e,e}catch(e){return b.error(`[connectors] Failed to get connector ${s}: ${e}`),null}}}c(_r,"getConnector");async function qu({basePath:s,connector:e}){const t=xe(e),n=q.join(s,Tt,t);D.mkdirSync(n,{recursive:!0});const r=q.join(n,`${xe(e)}.yml`);D.writeFileSync(r,Pt.dump(e)),b.info(`[connectors] Pulled connector ${e.name}`)}c(qu,"pullConnector");async function Uu({connector:s,connectorVersion:e,basePath:t}){const n=xe(s),r=Xo(e),i=q.join(t,"connectors",n,r),o=await U.withClient(l=>l.get(`connectors/${s.id}/download`,{version:e},{responseType:"arraybuffer",headers:{Accept:"application/zip"},timeout:1e6}));D.mkdirSync(i,{recursive:!0});const a=q.join(i,"src.zip");if(D.writeFileSync(a,o),!e){const l=q.join(i,"src");D.mkdirSync(l,{recursive:!0}),await Ku(o,l)}b.info(`[connectors] Pulled connector version: ${s.name} (${r})`)}c(Uu,"pullConnectorVersion");function xe(s){return s.key}c(xe,"getConnectorDirName");function Xo(s){return s??Ne}c(Xo,"getConnectorVersionDirName");function Wu(s){const e=Di(),t=xe(s);return q.join(e,Tt,t)}c(Wu,"getConnectorDirPath");function Ju(s){return s.match(`${Tt}/[^/]+/${Ne}/src/.*`)!==null}c(Ju,"isConnectorSourceFile");async function Hu(s){const e=s.match(`${Tt}/([^/]+)/${Ne}/src/(.*)`);if(!e)return;const t=e[1],n=e[2],r=await kr(t);if(!r){b.warning(`[connectors] Connector ${t} not found. Ignoring file change`);return}const i=r.id,o=D.readFileSync(s,"utf-8");await U.withClient(a=>a.put(`connectors/${i}/files/${n}`,o,{headers:{"Content-Type":"text/plain"}})),b.info(`[connectors] Pushed file ${n} for connector ${r.name}`)}c(Hu,"putConnectorFile");async function Vu(s){const e=s.match(`${Tt}/([^/]+)/${Ne}/src/(.*)`);if(!e)return;const t=e[1],n=e[2],r=await kr(t);if(!r){b.warning(`[connectors] Connector ${t} not found. Ignoring file change`);return}const i=r.id;await U.withClient(o=>o.delete(`connectors/${i}/files/${n}`)),b.info(`[connectors] Deleted file ${n} for connector ${r.name}`)}c(Vu,"deleteConnectorFile");async function Gu(s,e){try{const t=await U.withClient(o=>o.get(`connectors/${s}`));if(!t){b.warning(`[connectors] Connector ${s} not found`);return}const n=await U.withClient(o=>o.get(`connectors/${s}/files/${e}`)),r=xe(t),i=q.join(qe(),r,Ne,"src",e);D.mkdirSync(q.dirname(i),{recursive:!0}),n!=null?(D.writeFileSync(i,n),b.info(`[connectors] Pulled file ${e} for connector ${t.name}`)):D.existsSync(i)&&(D.unlinkSync(i),b.info(`[connectors] Deleted file ${e} for connector ${t.name}`))}catch(t){b.error(`[connectors] Failed to pull connector file ${e} for connector ${s}: ${t}`)}}c(Gu,"pullConnectorFile");async function zu(s,e){const t=await U.withClient(i=>i.get(`connectors/${s}`));if(!t){b.warning(`[connectors] Connector ${s} not found`);return}const n=xe(t),r=q.join(qe(),n,Ne,"src",e);D.existsSync(r)&&(D.unlinkSync(r),b.info(`[connectors] Deleted file ${e} for connector ${n}`))}c(zu,"deleteLocalConnectorFile");async function Yu(s,e,t){if(t&&e!==t)try{const n=await U.withClient(l=>l.get(`connectors/${s}`));if(!n){b.warning(`[connectors] Connector ${s} not found`);return}const r=xe(n),i=q.join(qe(),r,Ne,"src"),o=q.join(i,e),a=q.join(i,t);D.existsSync(o)&&(D.mkdirSync(q.dirname(a),{recursive:!0}),D.renameSync(o,a),b.info(`[connectors] Renamed directory from ${e} to ${t} for connector ${r}`))}catch(n){b.error(`[connectors] Failed to rename directory ${e} to ${t} for connector ${s}: ${n}`)}}c(Yu,"renameLocalConnectorDirectory");async function Xu(s,e){try{const t=await U.withClient(i=>i.get(`connectors/${s}`));if(!t){b.warning(`[connectors] Connector ${s} not found`);return}const n=xe(t),r=q.join(qe(),n,Ne,"src",e);if(D.existsSync(r)){const i=q.resolve(qe());if(!q.resolve(r).startsWith(i))return;D.rmSync(r,{recursive:!0,force:!0}),b.info(`[connectors] Deleted directory ${e} for connector ${n}`)}}catch(t){b.error(`[connectors] Failed to delete directory ${e} for connector ${s}: ${t}`)}}c(Xu,"deleteLocalConnectorDirectory");const Qo=[B.DataSource,B.FieldMapping,B.Action,B.Flow];class mn{static{c(this,"ElementSyncService")}localWatcher=void 0;remoteWatcher=void 0;notifier;changes=[];localCache;remoteCache;localRepo;remoteRepo;pulledConnectors=new Set;pulledConnectorVersions={};constructor(){this.notifier=Oe,this.localCache=new zo,this.remoteCache=new zo,this.localRepo=new Cl(this.localCache),this.remoteRepo=new kl(this.remoteCache)}clear(){this.changes=[]}needsForcedSync(){return this.changes.some(e=>e.isConflict)}needsSync(){return this.changes.length>0}async getStats(){const e=this.localCache.getAll(),t={};return e.forEach(n=>{t[n.type]=(t[n.type]||0)+1}),t}async fetchElements(){const e=await this.localRepo.getElements(),t=await this.remoteRepo.getElements();this.localCache.addAll(e),this.remoteCache.addAll(t)}async updateElement(e,t){const n=this.getHandler(t),r=this.getCache(t);try{const i=await n.putElement(e);r.put(i)}catch(i){throw b.error(`Failed to update element ${e.id}: ${i}`),i}}async deleteElement(e,t){const n=this.getHandler(t),r=this.getCache(t);try{await n.deleteElement(e,{elements:n.cache.getAll(),connectorsMapping:n.connectorsMapping}),r.remove(e)}catch(i){throw b.error(`Failed to delete element ${e.id}: ${i}`),i}}async pullConnectors(e=!1){const t=this.remoteCache.getElementsByType(B.Integration).map(n=>n.data);for(const n of t){const r=n.connectorId,i=n.connectorVersion;r&&await Yo({connectorId:r,connectorVersion:i,allConnectors:e,pulledConnectors:this.pulledConnectors,pulledConnectorVersions:this.pulledConnectorVersions})}}async pushConnectors(){const e=await ju();this.remoteRepo.setConnectorsMapping(e)}getHandler(e){return e===ae.INCOMING?this.localRepo:this.remoteRepo}getCache(e){return e===ae.INCOMING?this.localCache:this.remoteCache}async startWatching(){this.localWatcher=new Ru({cwd:process.cwd(),lockTimeoutMs:1e3}),this.localWatcher.on(he.Updated,e=>this.handleLocalEvent(e,he.Updated)),this.localWatcher.on(he.Deleted,e=>this.handleLocalEvent(e,he.Deleted)),await this.localWatcher.start(),b.success("[local] Tracking changes.."),this.remoteWatcher=new Lu,this.remoteWatcher.on(Sr.Updated,({elementId:e,elementType:t})=>this.handleRemoteElementEvent(e,t)),this.remoteWatcher.on(Sr.ConnectorFileUpdated,({connectorId:e,filePath:t,eventType:n,newPath:r})=>this.handleRemoteConnectorFileEvent(e,t,n,r)),await this.remoteWatcher.start(),b.success("[remote] Tracking changes..")}async stopWatching(){this.localWatcher&&(await this.localWatcher.stop(),this.localWatcher=void 0),this.remoteWatcher&&(await this.remoteWatcher.stop(),this.remoteWatcher=void 0)}async handleRemoteElementEvent(e,t){try{const n=await this.remoteRepo.getByInternalId(e,t),r=!!n?.data.archivedAt||!!n?.data.isDeactivated;if(!n||r){const o=n||this.remoteCache.getByInternalId(e);return o?(b.info(`[${this.getDirectionLabel(ae.INCOMING)}] Deleted: ${o.id}`),this.localWatcher?.executeWithPathLock(o.absolutePath,()=>this.deleteElement(o,ae.INCOMING))):void 0}if(b.info(`[${this.getDirectionLabel(ae.INCOMING)}] Updated: ${n.id}`),await this.localWatcher?.executeWithPathLock(n.absolutePath,async()=>this.updateElement(n,ae.INCOMING)),t===B.Integration){const o=n.data.connectorId,a=n.data.connectorVersion,l=await _r({connectorId:o});if(!l?.key)return;const u=Wu(l);await this.localWatcher?.executeWithPathLock(u,async()=>Yo({connectorId:o,connectorVersion:a,allConnectors:!1,pulledConnectors:this.pulledConnectors,pulledConnectorVersions:this.pulledConnectorVersions}))}}catch(n){b.error(`[sync] Error handling remote event: ${n}`)}}async handleRemoteConnectorFileEvent(e,t,n,r){try{switch(n){case Ms.ConnectorFileDeleted:await zu(e,t);break;case Ms.ConnectorDirectoryRenamed:await Yu(e,t,r);break;case Ms.ConnectorDirectoryDeleted:await Xu(e,t);break;default:await Gu(e,t);break}}catch(i){b.error(`[sync] Error handling remote connector file event: ${i}`)}}async handleLocalEvent(e,t){try{if(Ju(e.filePath))switch(t){case he.Updated:await Hu(e.filePath);break;case he.Deleted:await Vu(e.filePath);break}else{let n=Q.fromPathAndData(e.filePath,e.data);if(!n){const r=Q.idFromPath(e.filePath);if(!r||(n=this.remoteCache.get(r),!n))return}switch(b.info(`[${this.getDirectionLabel(ae.OUTGOING)}] ${al.toSentenceCase(t)}: ${n.id}`),t){case he.Updated:await this.updateElement(n,ae.OUTGOING);break;case he.Deleted:await this.deleteElement(n,ae.OUTGOING);break}}}catch(n){b.error(`[sync] Error handling local event: ${n}`)}}detectIncomingChanges(){this.clearChanges();const e=mn.getChanges(ae.INCOMING,this.remoteCache,this.localCache);return this.updateChanges(e),e}detectOutgoingChanges(){this.clearChanges();const e=mn.getChanges(ae.OUTGOING,this.localCache,this.remoteCache);return this.updateChanges(e),e}async resolveChanges(){if(!this.needsSync())return;b.info("[resolver] Resolving changes.."),b.info("[resolver] Resolving integration elements");const e=this.changes.filter(r=>r.element.type===B.Integration);await Promise.all(e.map(async r=>this.resolveChange(r))),e.length>0&&(await this.fetchElements(),this.changes=this.changes.length>0&&this.changes[0]?.direction===ae.INCOMING?this.detectIncomingChanges():this.detectOutgoingChanges(),this.changes=this.changes.filter(r=>r.element.type!==B.Integration)),b.info("[resolver] Resolving universal elements");const t=this.changes.filter(r=>!r.element.hasParent());for(const r of Qo){const i=t.filter(o=>o.element.type===r);b.info(`[resolver] Resolving ${r} elements`),await Promise.all(i.map(async o=>this.resolveChange(o)))}b.info("[resolver] Resolving integration level elements");const n=this.changes.filter(r=>r.element.hasParent());for(const r of Qo){const i=n.filter(o=>o.element.type===r);b.info(`[resolver] Resolving ${r} elements`),await Promise.all(i.map(async o=>this.resolveChange(o)))}b.success("[resolver] Resolved changes")}async resolveChange(e){switch(e.type){case Ae.DELETE:return this.deleteElement(e.element,e.direction);case Ae.CREATE:return this.updateElement(e.element,e.direction);case Ae.UPDATE:return this.updateElement(e.element,e.direction)}}static getChanges(e,t,n){const r=t.getAllIds(),i=n.getAllIds(),o=new Set([...r,...i]),a=[];for(const l of o){const u=t.get(l),h=n.get(l),f=mn.detectChangeForElement(u,h,e);f&&a.push(f)}return a}updateChanges(e){if(this.changes=e,this.needsForcedSync()){const t=e.filter(n=>n.isConflict);b.warning("[resolver] Conflicts detected"),this.notifier.setConflicts(t)}}clearChanges(){this.changes=[]}getDirectionLabel(e){switch(e){case ae.INCOMING:return"local\u2190remote";case ae.OUTGOING:return"local\u2192remote"}}static detectChangeForElement(e,t,n){return e&&!t?{type:Ae.CREATE,element:e,direction:n,isConflict:!1}:!e&&t?{type:Ae.DELETE,element:t,direction:n,isConflict:!0}:e&&t&&!e.isEqual(t)?{type:Ae.UPDATE,element:e,direction:n,isConflict:!0}:null}}const Ue=F.join(Dc.tmpdir(),"membrane-mcp-status"),Zo=3e4;class Qu{static{c(this,"McpStatusService")}constructor(e=2e3){this.pollIntervalMs=e}isRunning=!1;pollInterval;async start(){this.isRunning||(this.isRunning=!0,this.pollInterval=setInterval(async()=>await this.checkStatus(),this.pollIntervalMs),await this.checkStatus())}async stop(){this.pollInterval&&(clearInterval(this.pollInterval),this.pollInterval=void 0,this.isRunning=!1)}async checkStatus(){try{const e=process.cwd(),t=ts(void 0,e),n=ea(e);t&&Oe.setMcpStatus(t),await Oe.setMcpServers(n)}catch{b.error("Failed to check MCP status")}}}function ts(s,e){try{const t=e||process.cwd();if(!s){const r=ea(t);return r.length===0?null:r[0]}const n=Ar(s,t);if(P.existsSync(n)){const r=P.statSync(n),i=new Date;if(i.getTime()-r.mtime.getTime()>Zo)return Vt(s,t),null;const a=P.readFileSync(n,"utf8"),l=JSON.parse(a);if(l.isRunning){const u=new Date(l.lastActivity).getTime();if(i.getTime()-u>Zo)return Vt(s,t),null}return l}}catch{s&&e&&Vt(s,e)}return null}c(ts,"getMcpStatus");function ea(s){try{const e=s||process.cwd(),t=Er(e);if(!P.existsSync(Ue))return[];const n=P.readdirSync(Ue),r=[];for(const i of n){const o=i.match(new RegExp(`^mcp-${t}-(\\d+)\\.json$`));if(o){const a=parseInt(o[1],10),l=ts(a,e);l&&r.push(l)}}return r.sort((i,o)=>new Date(o.startTime).getTime()-new Date(i.startTime).getTime())}catch{return[]}}c(ea,"getAllMcpStatusFiles");function Tr(s){try{const t={...ts(s.processId,s.cwd)||{isRunning:!1,startTime:new Date().toISOString(),lastActivity:new Date().toISOString(),toolsCount:0,totalRequests:0,processId:s.processId,cwd:s.cwd,agentName:process.env.AGENT_NAME||"Unnamed Agent"},...s};P.existsSync(Ue)||P.mkdirSync(Ue,{recursive:!0});const n=Ar(s.processId,s.cwd);P.writeFileSync(n,JSON.stringify(t,null,2))}catch{}}c(Tr,"updateMcpStatus");function Vt(s,e){try{const t=e||process.cwd();if(s){const n=Ar(s,t);P.existsSync(n)&&P.unlinkSync(n)}else{const n=Er(t);if(P.existsSync(Ue)){const r=P.readdirSync(Ue);for(const i of r)i.match(new RegExp(`^mcp-${n}-\\d+\\.json$`))&&P.unlinkSync(F.join(Ue,i))}}}catch{}}c(Vt,"clearMcpStatus");function Zu(s,e){const t=ts(s,e);t&&Tr({processId:s,cwd:e,totalRequests:t.totalRequests+1,lastRequestTime:new Date().toISOString(),lastActivity:new Date().toISOString()})}c(Zu,"trackToolExecution");function Er(s){return Nc("md5").update(s).digest("hex").slice(0,8)}c(Er,"getCwdHash");function Ar(s,e){const t=Er(e);return F.join(Ue,`mcp-${t}-${s}.json`)}c(Ar,"getStatusFilePath");const Gt={Agent:"agent",Cli:"cli"},x={NOT_INITIALIZED:"not_initialized",SETTING_UP:"setting_up",INITIALIZED:"initialized",NOT_SYNCED:"not_synced",PULLING:"pulling",PUSHING:"pushing",RESOLVING:"resolving",CONFLICTS:"conflicts",SYNCED:"synced",WATCHING:"watching",ERROR:"error"};class ta{static{c(this,"MembraneCLIService")}constructor(e,t,n=()=>process.exit(0)){this.mode=e,this.cwd=t,this.onShutdown=n,this.notifier=Oe,this.mcpStatusService=new Qu,this.syncService=new mn,this.setupProcessCleanup()}initialized=!1;notifier;mcpStatusService;syncService;isShuttingDown=!1;currentConfig=null;get config(){return this.currentConfig}async pullWorkspace(e={}){try{if(b.setVerboseMode(!!e.verbose),await this.notifier.setState(x.PULLING),await this.syncService.fetchElements(),this.syncService.detectIncomingChanges(),this.syncService.needsForcedSync()&&!e.force)return this.notifier.setState(x.CONFLICTS);await this.syncService.pullConnectors(e.allConnectors),await this.syncWorkspaces(e)}catch(t){b.error(`Failed to pull workspace: ${t}`),await this.notifier.setState(x.ERROR),b.saveLogsToFile("error")}finally{return e.saveLogs&&b.saveLogsToFile(),e?.onComplete?.()}}async pushWorkspace(e={}){try{if(b.setVerboseMode(!!e.verbose),await this.notifier.setState(x.PUSHING),await this.syncService.fetchElements(),this.syncService.detectOutgoingChanges(),this.syncService.needsForcedSync()&&!e.force)return await this.notifier.setState(x.CONFLICTS);await this.syncService.pushConnectors(),await this.syncWorkspaces(e)}catch(t){b.error(`Failed to push workspace: ${t}`),await this.notifier.setState(x.ERROR),b.saveLogsToFile("error")}finally{return e.saveLogs&&b.saveLogsToFile(),e?.onComplete?.()}}async syncWorkspaces(e={}){try{e.verbose!==void 0&&b.setVerboseMode(!!e.verbose),await this.notifier.setState(x.RESOLVING),this.syncService.needsSync()&&await this.syncService.resolveChanges();const t=await this.syncService.getStats();this.notifier.setStats(t),await this.notifier.setState(x.SYNCED),e.watch&&(await this.notifier.setState(x.WATCHING),await this.syncService.startWatching())}catch(t){b.error(`Failed to sync local and remote workspaces: ${t}`),await this.notifier.setState(x.ERROR),b.saveLogsToFile("error")}}async init({force:e=!1}={}){if(!(this.initialized&&!e)){await this.notifier.setState(x.NOT_INITIALIZED);try{await this.loadConfig(),Dt.isCacheDefined()?(await this.initServices(),this.initialized=!0,await this.notifier.setState(x.INITIALIZED)):(this.initialized=!1,await this.notifier.setState(x.SETTING_UP))}catch(t){b.error(`Failed to initialize services: ${t}`),await this.notifier.setState(x.ERROR),b.saveLogsToFile("error"),this.onShutdown()}}}async loadConfig(){this.currentConfig=Dt.loadConfig(this.cwd),this.notifier.setConfig(this.currentConfig)}async updateConfig(e){const t={...this.currentConfig,...e};if(!(JSON.stringify(t)!==JSON.stringify(this.currentConfig)))return;await this.stopServices();const r=Dt.updateConfig(t);this.currentConfig=r,await this.init({force:!0})}async shutdown(){!this.initialized||this.isShuttingDown||(this.isShuttingDown=!0,this.mode===Gt.Agent&&(await this.notifier.cleanup(),await this.mcpStatusService.stop()),this.initialized=!1,this.onShutdown())}async initServices(){this.mode===Gt.Agent&&(await this.notifier.connectToRemote(),await this.mcpStatusService.start()),this.syncService.clear()}async stopServices(){this.mode===Gt.Agent&&(await this.notifier.cleanup(),await this.mcpStatusService.stop())}setupProcessCleanup(){["SIGINT","SIGTERM","uncaughtException","unhandledRejection"].forEach(t=>process.on(t,()=>this.shutdown())),process.on("beforeExit",t=>{t===0&&this.shutdown()})}}const na=oi(null);function eh({children:s,membraneCLIService:e}){const{data:t}=ci("/account"),[n,r]=J(x.NOT_INITIALIZED),[i,o]=J([]),[a,l]=J({}),[u,h]=J([]),[f,p]=J(null),y=t?.workspaces?.find(d=>d.workspaceKey===f?.workspaceKey)||null;return Ve(()=>{const d=c(({state:A})=>r(A),"handleStateChanged"),w=c(({stats:A})=>l(A),"handleStatsChanged"),k=c(({log:A})=>h($=>[...$,A]),"handleLogAdded"),_=c(({conflicts:A})=>o(A),"handleConflictsUpdated"),O=c(({config:A})=>p(A),"handleConfigChanged");return e.notifier.on(Y.StateChanged,d),e.notifier.on(Y.StatsChanged,w),e.notifier.on(Y.LogAdded,k),e.notifier.on(Y.ConflictsChanged,_),e.notifier.on(Y.ConfigChanged,O),e.init(),()=>{e.notifier.off(Y.StateChanged,d),e.notifier.off(Y.StatsChanged,w),e.notifier.off(Y.LogAdded,k),e.notifier.off(Y.ConflictsChanged,_),e.notifier.off(Y.ConfigChanged,O)}},[]),g(na.Provider,{value:{state:n,stats:a,logs:u,currentWorkspace:y,conflicts:i,config:f,updateConfig:c(d=>e.updateConfig(d),"updateConfig"),resolveConflicts:c(d=>e.syncWorkspaces(d),"resolveConflicts"),pull:c(d=>e.pullWorkspace(d),"pull"),push:c(d=>e.pushWorkspace(d),"push"),exit:c(()=>e.shutdown(),"exit")},children:s})}c(eh,"MembraneCLIServiceProvider");function Se(){const s=ai(na);if(!s)throw new Error("useMembraneCLIService must be used within MembraneCLIServiceProvider");return s}c(Se,"useMembraneCLIService");const sa=oi(process.cwd());function th({cwd:s,children:e}){return g(sa.Provider,{value:s,children:e})}c(th,"CwdProvider");function nh(){return ai(sa)}c(nh,"useCwd");function ns({cwd:s,children:e,membraneCLIService:t}){const n=s||process.cwd();return g(th,{cwd:n,children:g(gc,{value:{fetcher:gl()},children:g(eh,{membraneCLIService:t,children:e})})})}c(ns,"Layout");const Or=[{id:"claude-code",name:"Claude Code",description:"Anthropic Claude Code agent",actionDescription:"Adding membrane MCP to .mcp.json in the current directory",addConfig:c(()=>{const s=F.join(process.cwd(),".mcp.json"),e={mcpServers:{membrane:{command:"membrane",args:["mcp"],env:{AGENT_NAME:"Claude Code"}}}};let t={};if(P.existsSync(s))try{t=JSON.parse(P.readFileSync(s,"utf8"))}catch{t={}}const n={...t,mcpServers:{...t.mcpServers,...e.mcpServers}};return P.writeFileSync(s,JSON.stringify(n,null,2)),`MCP server configuration added to ${s}`},"addConfig")},{id:"cursor",name:"Cursor",description:"Cursor AI editor",actionDescription:"Adding membrane MCP to .cursor/mcp.json in the current directory",addConfig:c(()=>{const s=F.join(process.cwd(),".cursor"),e=F.join(s,"mcp.json");P.existsSync(s)||P.mkdirSync(s);const t={mcpServers:{membrane:{command:"membrane",args:["mcp"],env:{AGENT_NAME:"Cursor"}}}};let n={};if(P.existsSync(e))try{n=JSON.parse(P.readFileSync(e,"utf8"))}catch{n={}}const r={...n,mcpServers:{...n.mcpServers,...t.mcpServers}};return P.writeFileSync(e,JSON.stringify(r,null,2)),`MCP server configuration added to ${e}`},"addConfig")}];function sh({onExit:s,onComplete:e}){const[t,n]=J(0),[r,i]=J(!1),[o,a]=J(null),[l,u]=J(""),[h,f]=J("");nt((y,d)=>{if(l||h){(d.escape||y==="q"||d.return)&&e();return}if(r)d.return||y===" "?p(o):d.escape&&(i(!1),a(null));else if(d.escape)s();else if(d.upArrow||y==="k")n(Math.max(0,t-1));else if(d.downArrow||y==="j")n(Math.min(Or.length-1,t+1));else if(d.return||y===" "){const w=Or[t];a(w),i(!0)}});const p=c(y=>{try{const d=y.addConfig();u(d)}catch(d){f(`Failed to write configuration: ${d.message||d}`)}},"addMcpConfiguration"),m=Math.min(80,process.stdout.columns||80);return l?E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:m,children:[g(v,{marginTop:-1,marginBottom:1,children:E(C,{bold:!0,children:["\u{1F517} Connect Agent \u2014 ",g(C,{color:"green",children:"Success"})]})}),E(v,{flexDirection:"column",paddingLeft:2,children:[g(C,{color:"green",children:l}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"The agent will now be able to use Membrane's integration capabilities."})})]}),g(v,{marginTop:1,paddingLeft:2,children:g(C,{color:"white",children:"[esc/q/enter: exit]"})})]}):h?E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:m,children:[g(v,{marginTop:-1,marginBottom:1,children:E(C,{bold:!0,children:["\u{1F517} Connect Agent \u2014 ",g(C,{color:"red",children:"Error"})]})}),g(v,{flexDirection:"column",paddingLeft:2,children:g(C,{color:"red",children:h})}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"[esc/q/enter: exit]"})})]}):r&&o?E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:m,children:[g(v,{marginTop:-1,marginBottom:1,children:E(C,{bold:!0,children:["\u{1F517} Connect Agent \u2014 ",g(C,{color:"cyan",children:"Confirmation"})]})}),E(v,{flexDirection:"column",paddingLeft:2,children:[E(C,{children:["Connect ",g(C,{bold:!0,children:o.name})," to Membrane via MCP?"]}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"This will add an MCP server configuration that allows the agent to use Membrane's integration capabilities."})}),g(v,{marginTop:1,children:g(C,{color:"yellow",bold:!0,children:o.actionDescription})}),g(v,{marginTop:2,marginBottom:1,children:E(C,{children:[g(C,{color:"white",bold:!0,children:"[Enter] Confirm"})," ",g(C,{color:"gray",children:"[Esc] Cancel"})]})})]})]}):E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:m,children:[g(v,{marginTop:-1,marginBottom:1,children:E(C,{bold:!0,children:["\u{1F517} Connect Agent \u2014 ",g(C,{color:"cyan",children:"Select Agent"})]})}),E(v,{flexDirection:"column",paddingLeft:2,children:[g(C,{color:"grey",children:"Choose an agent to connect to Membrane via MCP:"}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"This will add an MCP server configuration that allows the agent to use Membrane's integration capabilities."})}),g(v,{marginTop:1,flexDirection:"column",children:Or.map((y,d)=>E(v,{children:[E(C,{color:t===d?"cyan":"white",children:[t===d?"\u25B6 ":" ",y.name]}),E(C,{color:"grey",children:[" \u2014 ",y.description]})]},y.id))})]}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"[\u2191\u2193: select] [enter: choose] [esc: exit]"})})]})}c(sh,"AddMcpServerScreen");function rh(){const[s,e]=J(null),[t,n]=J([]),[r,i]=J(null);return Ve(()=>{const o=c(({status:l})=>{e(l),i(null)},"handleMcpStatusChanged"),a=c(({servers:l})=>{n(l),i(null)},"handleMcpServersChanged");return Oe.on(Y.McpStatusChanged,o),Oe.on(Y.McpServersChanged,a),()=>{Oe.off(Y.McpStatusChanged,o),Oe.off(Y.McpServersChanged,a)}},[]),{mcpStatus:s,allMcpServers:t,error:r,isRunning:s?.isRunning||!1,toolsCount:s?.toolsCount||0,totalRequests:s?.totalRequests||0,lastActivity:s?.lastActivity,processId:s?.processId,serverCount:t.length}}c(rh,"useMcpStatus");function ih(){const{error:s,serverCount:e,allMcpServers:t}=rh(),n=Math.min(100,process.stdout.columns||100);return E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:n,children:[g(v,{marginTop:-1,marginBottom:0,flexDirection:"column",children:E(C,{bold:!0,children:["\u{1F916} Connected AI Agents:"," ",s?g(C,{color:"red",children:"error reading status"}):e===0?g(C,{color:"yellow",children:"none"}):g(C,{color:"green",children:e})]})}),!s&&e===0&&g(v,{marginTop:1,children:E(C,{color:"grey",children:["Connect your AI agents to Membrane.",g(pc,{}),"It will give them tools and context to build integrations."]})}),t.length>0&&g(v,{flexDirection:"column",paddingLeft:2,marginTop:1,children:t.map((r,i)=>g(v,{children:E(C,{color:"grey",children:["#",i+1," ",r.agentName,": ",r.totalRequests," calls"]})},r.processId))}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"[a: connect an agent]"})})]})}c(ih,"Agent");const ss=c(s=>{switch(s){case"error":return"red";case"success":return"green";case"warning":return"yellow";default:return}},"getLogColor");function ra(s,e){return e<3?s.slice(0,Math.max(0,e)):s.length<=e?s:`${s.slice(0,e-3)}...`}c(ra,"truncateText");function Ir({children:s}){const{state:e,logs:t}=Se();return!e||e===x.NOT_INITIALIZED?E(v,{gap:1,flexDirection:"row",children:[g(Fc,{type:"dots"}),g(C,{children:"Initializing..."})]}):e===x.SETTING_UP?g(v,{gap:1,flexDirection:"row",children:g(C,{children:"No workspace selected. Please run `membrane init` to select a workspace."})}):e===x.ERROR?g(v,{flexDirection:"column",children:t.slice().map((n,r)=>g(C,{color:ss(n.type),children:n.message},n.timestamp+r))}):s}c(Ir,"EnsureInitialized");function ia({onExit:s,showEscOption:e=!0}){const[t,n]=J(""),{data:r,error:i,isLoading:o}=ci("/account"),{updateConfig:a}=Se(),l=r?.workspaces,u=o;if(nt((d,w)=>{w.escape&&s?.()}),u)return E(v,{children:[g(wn,{}),g(C,{children:" Fetching workspaces..."})]});if(i)return E(v,{flexDirection:"column",children:[E(C,{color:"red",children:["Error: ",i.message]}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"Press ESC to go back"})})]});const h=l?.filter(d=>d.name.toLowerCase().includes(t.toLowerCase()))??[],f=h.map(d=>({label:d.name,value:d.id})),p=f.length,m=l?.length??0;async function y(d){const w=h.find(O=>O.id===d);if(!w)return;const{key:k,secret:_}=w;!k||!_||(await a({workspaceKey:k,workspaceSecret:_}),s?.())}return c(y,"handleSelect"),E(v,{flexDirection:"column",borderStyle:"round",borderTop:!0,width:70,paddingX:1,children:[g(v,{marginTop:-1,children:g(C,{bold:!0,children:"\u{1F4C1} Select your workspace"})}),E(v,{marginTop:1,children:[g(C,{children:"Search: "}),g(Kc,{placeholder:"Enter a search query...",onChange:n})]}),m>5&&E(C,{children:["Showing ",p," of ",m," workspaces."]}),g(v,{marginTop:1,children:g(Bc,{options:f,onChange:c(d=>{d&&y(d)},"onChange")})}),e&&g(v,{marginTop:1,children:g(C,{color:"grey",children:"Press ESC to go back"})})]})}c(ia,"SelectWorkspace");function oh({currentPat:s,onSubmit:e}){const[t,n]=J(""),[r,i]=J(!1),[o,a]=J(null);return E(v,{flexDirection:"column",borderStyle:"round",borderTop:!0,width:70,paddingX:1,children:[g(v,{marginTop:-1,marginBottom:1,children:g(C,{bold:!0,children:"\u{1F511} Enter your Personal Access Token"})}),g(C,{children:"Please provide your Personal Access Token. You can find it here:"}),g(v,{marginTop:1,marginBottom:1,children:g(C,{color:"yellow",children:"https://console.integration.app/w/0/manage-account/api-token"})}),s&&g(C,{dimColor:!0,children:"Press Enter to keep your current token or type a new one."}),g(qc,{mask:"*",placeholder:`${s?"******":"Enter your token here..."}`,value:t,onChange:n,onSubmit:c(async u=>{a(null),i(!0);try{await e(u),n("")}catch{a("Invalid token. Please try again.")}finally{i(!1)}},"handleSubmit")}),r&&g(v,{marginTop:1,children:E(C,{children:[g(wn,{type:"dots"})," Validating token..."]})}),o&&g(C,{color:"red",children:o})]})}c(oh,"PersonalAccessTokenInput");var zt=(s=>(s[s.Authenticate=0]="Authenticate",s[s.ConnectWorkspace=1]="ConnectWorkspace",s))(zt||{});const ah={0:"Authenticate in Membrane",1:"Connect a Membrane Workspace"},$r=[zt.Authenticate,zt.ConnectWorkspace];function oa({onComplete:s}){const{config:e}=Se(),[t,n]=J(!1),[r,i]=J(0),o=!!(e?.workspaceKey&&e?.workspaceSecret),a=Fi(),l=$r[r],u=r+1,h=$r.length,f=$r.map((y,d)=>{let w="pending";return d<r?w="done":d===r&&(w="current"),{id:y,label:ah[y],status:w}});async function p(y){const d=a&&y===""?a:y,w=new Ki;try{await w.request("/account",{headers:{Authorization:`Bearer ${d}`}}),ml(d),i(k=>k+1)}catch(k){console.error(k)}}c(p,"handlePatSubmit");function m(){n(!0),s&&s()}return c(m,"handleWorkspaceSelected"),nt((y,d)=>{o&&d.escape&&s&&s()}),t?g(v,{children:g(C,{children:"\u2705 Setup complete. You are ready to go!"})}):E(v,{flexDirection:"column",alignSelf:"flex-start",gap:1,children:[E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:70,children:[g(v,{marginTop:-1,marginBottom:1,children:E(C,{bold:!0,children:["\u{1F6E0}\uFE0F Setup \u2014"," ",E(C,{color:"cyan",children:["Step ",u," of ",h]}),o&&g(C,{color:"grey",children:" [esc: go back]"})]})}),g(v,{flexDirection:"column",paddingLeft:2,children:f.map(y=>g(ch,{status:y.status,label:y.label},y.id))})]}),l===zt.Authenticate&&g(oh,{currentPat:a,onSubmit:p}),l===zt.ConnectWorkspace&&g(ia,{onExit:m,showEscOption:!1})]})}c(oa,"Setup");function ch({status:s,label:e}){return E(v,{children:[E(v,{width:2,children:[s==="current"&&g(wn,{type:"dots"}),s==="done"&&g(C,{children:"\u2705"})]}),g(C,{dimColor:s!=="current",children:e})]})}c(ch,"StepDisplay");function Nr(){const{stats:s}=Se(),e=Object.entries(s).filter(([t,n])=>n>0);return e.length===0?null:E(v,{flexDirection:"column",children:[g(v,{children:g(v,{width:12,children:g(C,{color:"grey",children:"Elements:"})})}),g(v,{flexDirection:"column",marginLeft:1,children:e.map(([t,n])=>E(v,{children:[g(v,{width:20,children:E(C,{children:[t,":"]})}),g(C,{color:"green",children:n})]},t))})]})}c(Nr,"ElementStats");const xr=5,lh=6;function uh(){const{logs:s}=Se(),[e,t]=J(0),n=Math.min(100,process.stdout.columns||100),r=xr,i=Math.max(0,s.length-r-e),o=s.length-e,a=s.slice(i,o),l=n-lh,u=e<s.length-r,h=e>0;return nt((f,p)=>{if(s.length!==0)if(p.upArrow){const m=Math.max(0,s.length-r);t(y=>Math.min(m,y+1))}else p.downArrow?t(m=>Math.max(0,m-1)):(f==="G"||f==="g")&&t(0)}),E(v,{flexDirection:"column",paddingTop:1,children:[E(C,{color:"grey",children:["Recent Activity (",i+1,"-",o," of ",s.length,"):",s.length>xr&&g(C,{color:"grey",children:" [arrows: scroll] [g: end]"})]}),a.map((f,p)=>g(v,{marginLeft:1,children:g(C,{color:ss(f.type),children:ra(f.message,l)})},f.timestamp+p)),s.length>xr&&E(v,{marginLeft:1,flexDirection:"row",children:[u&&g(C,{color:"grey",children:"\u2191 "}),h&&g(C,{color:"grey",children:"\u2193 "})]})]})}c(uh,"Logs");const rs=[{value:"sync",label:"Continue (overwrite/delete)",key:""},{value:"exit",label:"Cancel",key:""}];function hh(){const{state:s,resolveConflicts:e,exit:t}=Se(),[n,r]=J(0),[i,o]=J(!1),[a,l]=J(!1);return nt((u,h)=>{if(!i){if(h.ctrl&&u.toLowerCase()==="r"){l(!a);return}h.upArrow?r(f=>f>0?f-1:rs.length-1):h.downArrow?r(f=>f<rs.length-1?f+1:0):u.toLowerCase()==="y"?r(0):u.toLowerCase()==="n"?r(1):(h.return||u===" ")&&(o(!0),rs[n].value==="sync"?e({watch:!0}):t())}}),Ve(()=>{s!==x.CONFLICTS&&i&&o(!1)},[s,i]),E(v,{flexDirection:"column",paddingTop:1,children:[g(v,{children:g(v,{flexDirection:"row",gap:2,children:g(C,{bold:!0,color:"white",children:"Conflicts with remote"})})}),g(v,{children:g(C,{color:"grey",children:"The remote workspace has changes that aren't in your local workspace:"})}),g(v,{marginTop:1,marginLeft:2,children:g(Mr,{isExpanded:a})}),E(v,{marginTop:2,flexDirection:"row",gap:1,children:[g(C,{color:"white",bold:!0,children:"What would you like to do?"}),g(C,{color:"grey",children:"[up/down, enter]"})]}),g(v,{children:i?E(v,{flexDirection:"row",gap:1,children:[g(wn,{type:"dots"}),g(C,{color:"blue",bold:!0,children:"Syncing with remote..."})]}):g(v,{flexDirection:"column",children:rs.map((u,h)=>g(v,{flexDirection:"column",children:E(v,{flexDirection:"row",gap:1,children:[g(C,{color:n===h?"cyan":"grey",children:n===h?"\u25B6":" "}),g(C,{color:n===h?"cyan":"grey",bold:n===h,children:u.label})]})},u.value))})})]})}c(hh,"ResolveChangesUI");const fh={[Ae.UPDATE]:{incoming:{label:"Elements updated in remote",description:"(to be overwritten from remote)"},outgoing:{label:"Elements updated locally",description:"(to be pushed to remote)"}},[Ae.DELETE]:{incoming:{label:"Elements not existing in remote",description:"(to be deleted locally)"},outgoing:{label:"Elements deleted locally",description:"(to be deleted from remote)"}},[Ae.CREATE]:{incoming:{label:"Elements created in remote",description:"(to be created locally)"},outgoing:{label:"Elements created locally",description:"(to be created in remote)"}}};function Mr({isExpanded:s}){const{conflicts:e}=Se(),t=5,n=yc(()=>{const r={};return e.forEach(i=>{const o=`${i.type}-${i.direction}`;r[o]||(r[o]=[]),r[o].push(i)}),r},[e]);return g(v,{flexDirection:"column",children:Object.entries(n).map(([r,i])=>{if(i.length===0)return null;const[o,a]=r.split("-"),l=fh[o][a];return E(v,{flexDirection:"column",children:[E(v,{flexDirection:"row",gap:1,children:[E(C,{color:"yellow",children:[l.label," (",i.length,")"]}),g(C,{color:"white",children:l.description})]}),(s?i:i.slice(0,t)).map(u=>g(v,{marginLeft:2,children:E(C,{color:"grey",children:["\u2022 ",u.element.id," (",u.element.relativePath,")"]})},u.element.id)),!s&&i.length>t&&g(v,{marginLeft:2,children:E(C,{color:"cyan",children:["... and ",i.length-t," more (press Ctrl+R to show all)"]})}),s&&i.length>t&&g(v,{marginLeft:2,children:g(C,{color:"cyan",children:"(press Ctrl+R to collapse)"})})]},r)})})}c(Mr,"Conflicts");function dh(){const{config:s,state:e,logs:t,currentWorkspace:n,pull:r}=Se(),i=n?.name,o=i?ra(i,30):s?.workspaceKey,a=Math.min(100,process.stdout.columns||100);return Ve(()=>{r({watch:!0})},[]),E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:a,children:[g(v,{marginTop:-1,marginBottom:1,children:E(v,{flexDirection:"row",gap:1,children:[g(C,{bold:!0,children:"\u{1F504} Workspace"}),E(C,{color:mh(e),children:[" [",ph(e),"] "]})]})}),E(v,{children:[g(v,{width:12,children:g(C,{color:"grey",children:"Local:"})}),g(C,{color:"grey",children:process.cwd()})]}),E(v,{children:[g(v,{width:12,children:g(C,{color:"grey",children:"Remote:"})}),s?.workspaceKey?E(C,{color:"grey",children:[o," [o: open in console] [w: change]"]}):E(C,{children:[g(C,{color:"yellow",children:"not selected"})," [w: select]"]})]}),e===x.CONFLICTS?g(hh,{}):E(Ns,{children:[g(v,{paddingTop:1,children:g(Nr,{})}),t.length>0&&g(uh,{})]})]})}c(dh,"Workspace");function ph(s){switch(s){case x.PULLING:return"pulling";case x.PUSHING:return"pushing";case x.CONFLICTS:return"conflicts";case x.SYNCED:return"synced";case x.ERROR:return"error";case x.WATCHING:return"tracking changes";case x.RESOLVING:return"resolving";case x.NOT_SYNCED:return"not synced";case x.INITIALIZED:return"initialized";case x.SETTING_UP:return"setup required";default:return"unknown"}}c(ph,"getStatusDisplay");function mh(s){switch(s){case x.PULLING:return"yellow";case x.PUSHING:return"yellow";case x.CONFLICTS:return"red";case x.SYNCED:return"green";case x.ERROR:return"red";case x.WATCHING:return"green";case x.RESOLVING:return"yellow";case x.NOT_SYNCED:return"grey";case x.SETTING_UP:return"yellow";default:return"grey"}}c(mh,"getStatusColor");const gh="https://console.integration.app/w";function yh(){const s=nh(),e=wc(!0),{exit:t,state:n}=Se(),[r,i]=J(null),o=r??(n===x.SETTING_UP?"setup":"main");nt(l=>{o==="main"&&(l==="w"&&i("workspace-selection"),l==="a"&&i("add-mcp-server"),l==="o"&&n===x.INITIALIZED&&a(),l==="s"&&i("setup"))});async function a(){try{const l=await Bi(s),u=`${gh}/${l}`,h=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";jc(`${h} "${u}"`)}catch(l){console.error("Failed to open workspace:",l),t()}}return c(a,"handleOpenWorkspace"),Ve(()=>(e.current=!0,()=>{e.current=!1}),[]),o==="workspace-selection"?g(ia,{onExit:c(()=>i(null),"onExit")}):o==="add-mcp-server"?g(sh,{onExit:c(()=>i(null),"onExit"),onComplete:c(()=>i(null),"onComplete")}):o==="setup"?g(oa,{onComplete:c(()=>i(null),"onComplete")},Date.now()):g(Ir,{children:E(v,{flexDirection:"column",children:[g(v,{flexGrow:1,children:g(ih,{})}),g(dh,{}),g(v,{paddingLeft:2,children:g(C,{color:"grey",children:"[s: (re-)setup]"})})]})})}c(yh,"Main");const Rr=mc(process.argv.slice(2)),aa=Rr.cwd?fc(Rr.cwd):process.cwd(),wh=new ta(Gt.Agent,aa);Rr.verbose&&b.setVerboseMode(!0);const bh=c(()=>g(ns,{cwd:aa,membraneCLIService:wh,children:g(yh,{})}),"App");function Sh(){gn(g(bh,{}))}c(Sh,"runAgent");function vh(s,e){s.command("init").description("Run interactive setup for Membrane project").option("--key <key>","Workspace key for non-interactive setup").option("--secret <secret>","Workspace secret for non-interactive setup").addHelpText("after",["","Examples:"," membrane init # Run interactive setup"," membrane init --key KEY --secret SEC # Non-interactive setup with key and secret",""].join(`
|
|
141
|
+
`,t)+1}return{type:e,offset:this.offset,indent:this.indent,source:this.source}}startBlockValue(e){switch(this.type){case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return this.flowScalar(this.type);case"block-scalar-header":return{type:"block-scalar",offset:this.offset,indent:this.indent,props:[this.sourceToken],source:""};case"flow-map-start":case"flow-seq-start":return{type:"flow-collection",offset:this.offset,indent:this.indent,start:this.sourceToken,items:[],end:[]};case"seq-item-ind":return{type:"block-seq",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken]}]};case"explicit-key-ind":{this.onKeyLine=!0;const t=es(e),n=_t(t);return n.push(this.sourceToken),{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:n,explicitKey:!0}]}}case"map-value-ind":{this.onKeyLine=!0;const t=es(e),n=_t(t);return{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:n,key:null,sep:[this.sourceToken]}]}}}return null}atIndentedComment(e,t){return this.type!=="comment"||this.indent<=t?!1:e.every(n=>n.type==="newline"||n.type==="space")}*documentEnd(e){this.type!=="doc-mode"&&(e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop()))}*lineEnd(e){switch(this.type){case"comma":case"doc-start":case"doc-end":case"flow-seq-end":case"flow-map-end":case"map-value-ind":yield*this.pop(),yield*this.step();break;case"newline":this.onKeyLine=!1;case"space":case"comment":default:e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop())}}}function Vo(s){const e=s.prettyErrors!==!1;return{lineCounter:s.lineCounter||e&&new Uo||null,prettyErrors:e}}c(Vo,"parseOptions");function Iu(s,e={}){const{lineCounter:t,prettyErrors:n}=Vo(e),r=new br(t?.addNewLine),i=new mr(e),o=Array.from(i.compose(r.parse(s)));if(n&&t)for(const a of o)a.errors.forEach(Vn(s,t)),a.warnings.forEach(Vn(s,t));return o.length>0?o:Object.assign([],{empty:!0},i.streamInfo())}c(Iu,"parseAllDocuments");function Go(s,e={}){const{lineCounter:t,prettyErrors:n}=Vo(e),r=new br(t?.addNewLine),i=new mr(e);let o=null;for(const a of i.compose(r.parse(s),!0,s.length))if(!o)o=a;else if(o.options.logLevel!=="silent"){o.errors.push(new Qe(a.range.slice(0,2),"MULTIPLE_DOCS","Source contains multiple documents; please use YAML.parseAllDocuments()"));break}return n&&t&&(o.errors.forEach(Vn(s,t)),o.warnings.forEach(Vn(s,t))),o}c(Go,"parseDocument");function $u(s,e,t){let n;typeof e=="function"?n=e:t===void 0&&e&&typeof e=="object"&&(t=e);const r=Go(s,t);if(!r)return null;if(r.warnings.forEach(i=>ro(r.options.logLevel,i)),r.errors.length>0){if(r.options.logLevel!=="silent")throw r.errors[0];r.errors=[]}return r.toJS(Object.assign({reviver:n},t))}c($u,"parse");function Nu(s,e,t){let n=null;if(typeof e=="function"||Array.isArray(e)?n=e:t===void 0&&e&&(t=e),typeof t=="string"&&(t=t.length),typeof t=="number"){const r=Math.round(t);t=r<1?void 0:r>8?{indent:8}:{indent:r}}if(s===void 0){const{keepUndefined:r}=t??e??{};if(!r)return}return Ge(s)&&!n?s.toString(t):new Rt(s,n,t).toString(t)}c(Nu,"stringify");var xu=Object.freeze({__proto__:null,Alias:$n,CST:Eu,Composer:mr,Document:Rt,Lexer:qo,LineCounter:Uo,Pair:se,Parser:br,Scalar:M,Schema:Es,YAMLError:lr,YAMLMap:ue,YAMLParseError:Qe,YAMLSeq:Ke,YAMLWarning:Oo,isAlias:Fe,isCollection:G,isDocument:Ge,isMap:dt,isNode:z,isPair:H,isScalar:W,isSeq:pt,parse:$u,parseAllDocuments:Iu,parseDocument:Go,stringify:Nu,visit:ze,visitAsync:In});const he={Updated:"updated",Deleted:"deleted",Stopped:"stopped"},Mu={ignored:ul,persistent:!0,ignoreInitial:!0,followSymlinks:!1,depth:20,awaitWriteFinish:{stabilityThreshold:500,pollInterval:100},ignorePermissionErrors:!0,atomic:!0,usePolling:!1,alwaysStat:!1,interval:1e3,binaryInterval:300};class Ru extends qs{static{c(this,"LocalElementWatcher")}constructor(e){super(),this.options=e,this.membraneDir=ht(this.options.cwd),this.lockTimeoutMs=this.options.lockTimeoutMs??1e3}isWatching=!1;watcher;membraneDir;contentCache={};ignoredPaths=new Set;lockTimeoutMs;async start(){this.isWatching||(P.existsSync(this.membraneDir)||P.mkdirSync(this.membraneDir,{recursive:!0}),this.initializeContentCache(),this.watcher=xc.watch(this.membraneDir,Mu),this.watcher.on("add",e=>this.handleFileSystemEvent(he.Updated,e)).on("change",e=>this.handleFileSystemEvent(he.Updated,e)).on("unlink",e=>this.handleFileSystemEvent(he.Deleted,e)).on("ready",()=>this.isWatching=!0))}async stop(){!this.isWatching||!this.watcher||(await this.watcher.close(),this.isWatching=!1,this.watcher=void 0,this.clearCache(),this.clearAllLocks(),this.emit(he.Stopped))}getCwd(){return this.options.cwd}async executeWithPathLock(e,t){const n=F.resolve(e);this.ignoredPaths.add(n);try{await t()}finally{setTimeout(()=>{this.ignoredPaths.delete(n)},this.lockTimeoutMs)}}isPathLocked(e){const t=F.resolve(e);if(this.ignoredPaths.has(t))return!0;for(const n of this.ignoredPaths)if(t.startsWith(n+F.sep))return!0;return!1}clearAllLocks(){this.ignoredPaths.clear()}handleFileSystemEvent(e,t){const n=F.relative(this.membraneDir,t);if(this.isPathLocked(t))return;if(e===he.Deleted){this.removeFromCache(n);const a={filePath:t,relativePath:n,data:void 0};b.info(`[local] ${e}: ${a.relativePath}`),this.emit(e,a);return}const r=this.readFileContent(t);if(!this.hasContentChanged(n,r))return;const o=this.processFileEvent(t,r);this.updateCache(n,r),o&&(b.info(`[local] ${e}: ${o.relativePath}`),this.emit(e,o))}readFileContent(e){return P.readFileSync(e,"utf8")}processFileEvent(e,t){const n=F.relative(this.membraneDir,e);let r;try{r=t?xu.parse(t):void 0}catch{r=void 0}return{filePath:e,relativePath:n,data:r}}hasContentChanged(e,t){if(!t)return this.contentCache[e]!==void 0;const n=this.getContentHash(t);return this.contentCache[e]!==n}getContentHash(e){return $c.createHash("sha256").update(e).digest("hex")}updateCache(e,t){if(!t){delete this.contentCache[e];return}this.contentCache[e]=this.getContentHash(t)}removeFromCache(e){delete this.contentCache[e]}clearCache(){Object.keys(this.contentCache).forEach(e=>{delete this.contentCache[e]})}initializeContentCache(){P.existsSync(this.membraneDir)&&this.scanDirectoryForCache(this.membraneDir)}scanDirectoryForCache(e){const t=P.readdirSync(e,{withFileTypes:!0});for(const n of t){const r=F.join(e,n.name);if(n.isDirectory())this.scanDirectoryForCache(r);else if(n.isFile())try{const i=P.readFileSync(r,"utf8"),o=F.relative(this.membraneDir,r);this.updateCache(o,i)}catch{}}}}var Sr=(s=>(s.Updated="updated",s.ConnectorFileUpdated="connector-file-updated",s.Connected="connected",s.Disconnected="disconnected",s.Error="error",s))(Sr||{});const Pu={debounceMs:2e3,reconnectIntervalMs:5e3,maxReconnectAttempts:5};class Lu extends qs{static{c(this,"RemoteElementWatcher")}constructor(e=Pu){super(),this.config=e}eventSource;debounceTimeouts=new Map;reconnectAttempts=0;reconnectTimeout;isStarted=!1;async start(){this.isStarted||(this.isStarted=!0,await this.connect())}async stop(){this.isStarted&&(this.isStarted=!1,this.clearReconnectTimeout(),this.clearAllDebounceTimeouts(),this.eventSource&&(this.eventSource.close(),this.eventSource=void 0))}async connect(){try{b.debug("[remote-events] Connecting to server");const e=await U.getClient(process.cwd()),t=await e.getToken();if(!t)throw new Error("No auth token available");const n=`${e.apiUri}/sse/workspace?token=${encodeURIComponent(t)}`;b.debug("[remote-events] Subscribing to workspace events"),this.eventSource=new Mc(n),this.setupEventSourceHandlers()}catch(e){b.error(`[remote-events] Failed to subscribe to workspace events: ${e}`),this.emit("error",{error:e}),this.scheduleReconnect()}}setupEventSourceHandlers(){this.eventSource&&(this.eventSource.onopen=()=>{b.debug("[remote-events] Connected to server"),this.reconnectAttempts=0,this.emit("connected",{})},this.eventSource.onmessage=e=>{try{const t=JSON.parse(e.data);this.handleElementUpdate(t)}catch(t){b.error(`[remote-events] Failed to parse workspace event: ${t}`)}},this.eventSource.onerror=e=>{b.error(`[remote-events] Connection error: ${JSON.stringify(e,null,2)}`),this.emit("disconnected",{}),this.isStarted&&this.scheduleReconnect()})}handleElementUpdate(e){if(e.type!==vc.ElementUpdate)return;const{elementId:t,elementType:n,data:r={}}=e;if(!(!t||!n)){if(n===B.Connector){const{filePath:i,eventType:o,newPath:a}=r;return b.debug(`[remote-watcher] Received connector event - elementId: ${t}, filePath: ${i}, eventType: ${o}`),this.scheduleConnectorFileUpdate(t,i,o,a)}return this.scheduleElementUpdate(t,n)}}scheduleElementUpdate(e,t){const n=this.debounceTimeouts.get(e);n&&clearTimeout(n);const r=setTimeout(()=>{this.debounceTimeouts.delete(e),this.emit("updated",{elementId:e,elementType:t})},this.config.debounceMs);this.debounceTimeouts.set(e,r)}scheduleConnectorFileUpdate(e,t,n,r){const i=JSON.stringify({connectorId:e,filePath:t}),o=this.debounceTimeouts.get(i);o&&clearTimeout(o);const a=setTimeout(()=>{this.debounceTimeouts.delete(i),this.emit("connector-file-updated",{connectorId:e,filePath:t,eventType:n,newPath:r})},this.config.debounceMs);this.debounceTimeouts.set(i,a)}scheduleReconnect(){if(!this.isStarted||this.reconnectAttempts>=this.config.maxReconnectAttempts){if(this.reconnectAttempts>=this.config.maxReconnectAttempts)throw new Error("Unable to re-connect to the server");return}this.reconnectAttempts++;const e=Math.min(this.config.reconnectIntervalMs*Math.pow(2,this.reconnectAttempts-1),3e4);b.debug(`[remote-watcher] Reconnecting in ${e}ms (attempt ${this.reconnectAttempts})`),this.reconnectTimeout=setTimeout(()=>{this.connect()},e)}clearReconnectTimeout(){this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=void 0)}clearAllDebounceTimeouts(){this.debounceTimeouts.forEach(e=>clearTimeout(e)),this.debounceTimeouts.clear()}}class zo{static{c(this,"ElementsCache")}elements=new Map;typeIndex=new Map;internalIdIndex=new Map;constructor(e){e&&this.addAll(e)}add(e){const t=e.id;this.elements.set(t,e),this.typeIndex.has(e.type)||this.typeIndex.set(e.type,new Set),this.typeIndex.get(e.type).add(t),e.data?.id&&this.internalIdIndex.set(e.data.id,t)}remove(e){const t=e.id,n=this.elements.delete(t);if(n){const r=this.typeIndex.get(e.type);r&&(r.delete(t),r.size===0&&this.typeIndex.delete(e.type)),e.data?.id&&this.internalIdIndex.delete(e.data.id)}return n}put(e){this.elements.has(e.id)&&this.remove(e),this.add(e)}get(e){return this.elements.get(e)}getByInternalId(e){const t=this.internalIdIndex.get(e);if(t)return this.elements.get(t)}getElementsByType(e){const t=this.typeIndex.get(e);return t?Array.from(t).map(n=>this.elements.get(n)).filter(n=>n!==void 0):[]}getAll(){return Array.from(this.elements.values())??[]}getTypes(){return Array.from(this.typeIndex.keys())}addAll(e){for(const t of e)t&&this.add(t)}removeAll(e){for(const t of e)this.remove(t)}getElementIdsByType(e){return this.typeIndex.get(e)}clear(){this.elements.clear(),this.typeIndex.clear(),this.internalIdIndex.clear()}getAllIds(){return new Set(this.elements.keys())}}async function Du(s="full"){const e={};b.info("[connectors] Getting remote workspace data");const t=await U.withClient(n=>n.integrations.findAll());e.integration=t.map(n=>vr("integration",n));for(const n of Object.keys(le)){const r=le[n];if(r.exportable===!1)continue;const i=[];b.info(`[connectors] Reading ${r.elements} from remote workspace`);const o=await U.withClient(a=>a[r.elements].findAll());if(i.push(...o.map(a=>vr(n,a))),r.integrationSpecific)for(const a of t){const l=await U.withClient(u=>u[r.elements].findAll({integrationId:a.id}));i.push(...l.map(u=>(u.integrationKey=a.key,vr(n,u))))}i.length>0&&s=="full"&&(console.table(i.map(a=>({key:a.key,integrationKey:a.integrationKey,universal:!a.integrationKey})).reduce((a,l)=>(a||(a={}),a[l.key]||(a[l.key]={}),l.universal&&(a[l.key].universal=!0),l.integrationKey&&(a[l.key].integration?a[l.key].integration+=` ${l.integrationKey}`:a[l.key].integration=l.integrationKey),a),{})),console.groupEnd()),e[n]=i}return b.success("[connectors] Remote workspace data retrieved successfully"),e}c(Du,"getWorkspaceData");function vr(s,e){return e=cl(e),le[s].exportCleanup?le[s].exportCleanup(e):e}c(vr,"cleanUpForExport");const Tt="connectors",Ne="development",Cr={};async function ju(){const s=await Du("minified"),t=(await U.withClient(l=>l.get("org-workspace-id"))).id,n={};b.info("[connectors] Loading custom connectors");const r=await U.withClient(l=>l.get(`/connectors?workspaceId=${t}`));b.info("[connectors] Loading public connectors"),s.connector=r;const i=qe(),a=(D.existsSync(i)?D.readdirSync(i):[]).filter(l=>{if(l.startsWith("."))return!1;const u=q.join(i,l);try{return D.statSync(u).isDirectory()}catch{return!1}});for(const l of a){b.info(`[connectors] Loading connector from: ${l}`);const u=D.readdirSync(q.join(i,l)),h=await kr(l);if(!h)continue;if("baseUri"in h&&delete h.baseUri,h.uuid&&s.connector?.find(p=>p.uuid==h.uuid))n[h.id]=s.connector.find(p=>p.uuid==h.uuid).id,b.info(`[connectors] Matched ${h.name} uuid: ${h.uuid}`);else if(!n[h.id]){let p=!1;try{const m=await _r({connectorId:h.id});m&&!m.workspaceId&&(p=!0)}catch{}if(!p){b.info(`[connectors] Creating custom connector ${h.name} (${h.key})`);const m=await U.withClient(y=>y.post("connectors",{...h,workspaceId:t}));n[h.id]=m.id}}const f=u.filter(p=>D.statSync(q.join(i,l,p)).isDirectory());for(const p of f)await Bu({connector:h,version:p,connectorId:n[h.id]})}return n}c(ju,"pushConnectors");async function Yo({connectorId:s,connectorVersion:e,allConnectors:t,pulledConnectors:n,pulledConnectorVersions:r}){if(!s||r[s]?.has(e))return;const i=Di(),o=await _r({connectorId:s});if(o.workspaceId||t){if(!o?.key){b.error(`[connectors] Connector ${s} has no key. Skipping..`);return}n.has(s)||(await qu({basePath:i,connector:o}),n.add(s)),r[s]||(r[s]=new Set),r[s].has(e)||(await Uu({connector:o,connectorVersion:e,basePath:i}),r[s].add(e))}}c(Yo,"pullRemoteConnector");function qe(){const s=Ws();return q.join(s.membraneDirPath,Tt)}c(qe,"getConnectorsPath");async function kr(s){const e=q.join(qe(),s,`${s}.yml`);return Js(e,!1)}c(kr,"readConnector");async function Fu(s,e){return b.info(`[connectors] Zipping ${s} into ${e}`),new Promise((t,n)=>{const r=D.createWriteStream(e),i=Rc("zip",{zlib:{level:9}});r.on("close",()=>{b.success(`[connectors] Successfully created ${e}`),t()}),r.on("end",()=>{b.info("[connectors] Data has been drained")}),i.on("warning",a=>{a.code==="ENOENT"?console.warn(a):n(a)}),i.on("error",a=>{n(a)}),i.pipe(r);const o=D.readdirSync(s);for(const a of o){const l=q.join(s,a),u=D.statSync(l);u.isFile()?i.file(l,{name:a}):u.isDirectory()&&i.directory(l,a)}i.finalize()})}c(Fu,"createZipArchive");async function Ku(s,e){return b.info(`[connectors] Unzipping into ${e}`),new Promise((t,n)=>{const r=Lc.Parse();r.on("entry",i=>{const o=i.path;if(i.type==="Directory"){const l=q.join(e,o);D.mkdirSync(l,{recursive:!0}),i.autodrain()}else{const l=q.join(e,o),u=q.dirname(l);D.mkdirSync(u,{recursive:!0});const h=D.createWriteStream(l);i.pipe(h),h.on("finish",()=>{})}}),r.on("end",()=>{b.success(`[connectors] Successfully extracted to ${e}`),t()}),r.on("error",i=>{n(i)}),r.write(s),r.end()})}c(Ku,"extractZipArchive");async function Bu({connector:s,version:e,connectorId:t}){const n=q.join(qe(),xe(s),Xo(e)),r=q.join(n,"src"),i=q.join(n,"src.zip"),o=D.existsSync(i);if(D.existsSync(r)&&(b.info(`[connectors] Archiving source code for ${s.name} version ${e}`),await Fu(r,i)),!D.existsSync(i)){b.warning(`[connectors] No source code found for ${s.name} version ${e}`);return}try{const a=new Pc;if(a.append("file",D.createReadStream(i),"file.zip"),b.info(`[connectors] Pushing connector version ${e} for ${s.name}`),e==Ne)b.info(`[connectors] Uploading connector ${t}`),await U.withClient(l=>l.post(`connectors/${t}/upload`,a,{headers:{...a.getHeaders()}}));else{if(a.append("version",e),a.append("changelog","Imported Version"),(await U.withClient(u=>u.get(`/connectors/${t}/versions`))).find(u=>u.version==e)){b.info(`[connectors] Version ${e} already published`);return}b.info(`[connectors] Publishing version ${e} of connector ${t}`),await U.withClient(u=>u.post(`connectors/${t}/publish-version`,a,{headers:{...a.getHeaders()}}))}b.success(`Successfully pushed connector version ${e} for ${s.name}`)}catch(a){b.error(`Error pushing connector version ${e} for ${s.name}: ${a}`)}finally{!o&&D.existsSync(i)&&(b.info(`[connectors] Cleaning up temporary zip file for ${s.name} version ${e}`),D.unlinkSync(i))}}c(Bu,"pushConnectorVersion");async function _r({connectorId:s}){if(s){if(Cr[s])return Cr[s];try{const e=await U.withClient(t=>t.get(`connectors/${s}`));return Cr[s]=e,e}catch(e){return b.error(`[connectors] Failed to get connector ${s}: ${e}`),null}}}c(_r,"getConnector");async function qu({basePath:s,connector:e}){const t=xe(e),n=q.join(s,Tt,t);D.mkdirSync(n,{recursive:!0});const r=q.join(n,`${xe(e)}.yml`);D.writeFileSync(r,Pt.dump(e)),b.info(`[connectors] Pulled connector ${e.name}`)}c(qu,"pullConnector");async function Uu({connector:s,connectorVersion:e,basePath:t}){const n=xe(s),r=Xo(e),i=q.join(t,"connectors",n,r),o=await U.withClient(l=>l.get(`connectors/${s.id}/download`,{version:e},{responseType:"arraybuffer",headers:{Accept:"application/zip"},timeout:1e6}));D.mkdirSync(i,{recursive:!0});const a=q.join(i,"src.zip");if(D.writeFileSync(a,o),!e){const l=q.join(i,"src");D.mkdirSync(l,{recursive:!0}),await Ku(o,l)}b.info(`[connectors] Pulled connector version: ${s.name} (${r})`)}c(Uu,"pullConnectorVersion");function xe(s){return s.key}c(xe,"getConnectorDirName");function Xo(s){return s??Ne}c(Xo,"getConnectorVersionDirName");function Wu(s){const e=Di(),t=xe(s);return q.join(e,Tt,t)}c(Wu,"getConnectorDirPath");function Ju(s){return s.match(`${Tt}/[^/]+/${Ne}/src/.*`)!==null}c(Ju,"isConnectorSourceFile");async function Hu(s){const e=s.match(`${Tt}/([^/]+)/${Ne}/src/(.*)`);if(!e)return;const t=e[1],n=e[2],r=await kr(t);if(!r){b.warning(`[connectors] Connector ${t} not found. Ignoring file change`);return}const i=r.id,o=D.readFileSync(s,"utf-8");await U.withClient(a=>a.put(`connectors/${i}/files/${n}`,o,{headers:{"Content-Type":"text/plain"}})),b.info(`[connectors] Pushed file ${n} for connector ${r.name}`)}c(Hu,"putConnectorFile");async function Vu(s){const e=s.match(`${Tt}/([^/]+)/${Ne}/src/(.*)`);if(!e)return;const t=e[1],n=e[2],r=await kr(t);if(!r){b.warning(`[connectors] Connector ${t} not found. Ignoring file change`);return}const i=r.id;await U.withClient(o=>o.delete(`connectors/${i}/files/${n}`)),b.info(`[connectors] Deleted file ${n} for connector ${r.name}`)}c(Vu,"deleteConnectorFile");async function Gu(s,e){try{const t=await U.withClient(o=>o.get(`connectors/${s}`));if(!t){b.warning(`[connectors] Connector ${s} not found`);return}const n=await U.withClient(o=>o.get(`connectors/${s}/files/${e}`)),r=xe(t),i=q.join(qe(),r,Ne,"src",e);D.mkdirSync(q.dirname(i),{recursive:!0}),n!=null?(D.writeFileSync(i,n),b.info(`[connectors] Pulled file ${e} for connector ${t.name}`)):D.existsSync(i)&&(D.unlinkSync(i),b.info(`[connectors] Deleted file ${e} for connector ${t.name}`))}catch(t){b.error(`[connectors] Failed to pull connector file ${e} for connector ${s}: ${t}`)}}c(Gu,"pullConnectorFile");async function zu(s,e){const t=await U.withClient(i=>i.get(`connectors/${s}`));if(!t){b.warning(`[connectors] Connector ${s} not found`);return}const n=xe(t),r=q.join(qe(),n,Ne,"src",e);D.existsSync(r)&&(D.unlinkSync(r),b.info(`[connectors] Deleted file ${e} for connector ${n}`))}c(zu,"deleteLocalConnectorFile");async function Yu(s,e,t){if(t&&e!==t)try{const n=await U.withClient(l=>l.get(`connectors/${s}`));if(!n){b.warning(`[connectors] Connector ${s} not found`);return}const r=xe(n),i=q.join(qe(),r,Ne,"src"),o=q.join(i,e),a=q.join(i,t);D.existsSync(o)&&(D.mkdirSync(q.dirname(a),{recursive:!0}),D.renameSync(o,a),b.info(`[connectors] Renamed directory from ${e} to ${t} for connector ${r}`))}catch(n){b.error(`[connectors] Failed to rename directory ${e} to ${t} for connector ${s}: ${n}`)}}c(Yu,"renameLocalConnectorDirectory");async function Xu(s,e){try{const t=await U.withClient(i=>i.get(`connectors/${s}`));if(!t){b.warning(`[connectors] Connector ${s} not found`);return}const n=xe(t),r=q.join(qe(),n,Ne,"src",e);if(D.existsSync(r)){const i=q.resolve(qe());if(!q.resolve(r).startsWith(i))return;D.rmSync(r,{recursive:!0,force:!0}),b.info(`[connectors] Deleted directory ${e} for connector ${n}`)}}catch(t){b.error(`[connectors] Failed to delete directory ${e} for connector ${s}: ${t}`)}}c(Xu,"deleteLocalConnectorDirectory");const Qo=[B.DataSource,B.FieldMapping,B.Action,B.Flow];class mn{static{c(this,"ElementSyncService")}localWatcher=void 0;remoteWatcher=void 0;notifier;changes=[];localCache;remoteCache;localRepo;remoteRepo;pulledConnectors=new Set;pulledConnectorVersions={};constructor(){this.notifier=Oe,this.localCache=new zo,this.remoteCache=new zo,this.localRepo=new Cl(this.localCache),this.remoteRepo=new kl(this.remoteCache)}clear(){this.changes=[]}needsForcedSync(){return this.changes.some(e=>e.isConflict)}needsSync(){return this.changes.length>0}async getStats(){const e=this.localCache.getAll(),t={};return e.forEach(n=>{t[n.type]=(t[n.type]||0)+1}),t}async fetchElements(){const e=await this.localRepo.getElements(),t=await this.remoteRepo.getElements();this.localCache.addAll(e),this.remoteCache.addAll(t)}async updateElement(e,t){const n=this.getHandler(t),r=this.getCache(t);try{const i=await n.putElement(e);r.put(i)}catch(i){throw b.error(`Failed to update element ${e.id}: ${i}`),i}}async deleteElement(e,t){const n=this.getHandler(t),r=this.getCache(t);try{await n.deleteElement(e,{elements:n.cache.getAll(),connectorsMapping:n.connectorsMapping}),r.remove(e)}catch(i){throw b.error(`Failed to delete element ${e.id}: ${i}`),i}}async pullConnectors(e=!1){const t=this.remoteCache.getElementsByType(B.Integration).map(n=>n.data);for(const n of t){const r=n.connectorId,i=n.connectorVersion;r&&await Yo({connectorId:r,connectorVersion:i,allConnectors:e,pulledConnectors:this.pulledConnectors,pulledConnectorVersions:this.pulledConnectorVersions})}}async pushConnectors(){const e=await ju();this.remoteRepo.setConnectorsMapping(e)}getHandler(e){return e===ae.INCOMING?this.localRepo:this.remoteRepo}getCache(e){return e===ae.INCOMING?this.localCache:this.remoteCache}async startWatching(){this.localWatcher=new Ru({cwd:process.cwd(),lockTimeoutMs:1e3}),this.localWatcher.on(he.Updated,e=>this.handleLocalEvent(e,he.Updated)),this.localWatcher.on(he.Deleted,e=>this.handleLocalEvent(e,he.Deleted)),await this.localWatcher.start(),b.success("[local] Tracking changes.."),this.remoteWatcher=new Lu,this.remoteWatcher.on(Sr.Updated,({elementId:e,elementType:t})=>this.handleRemoteElementEvent(e,t)),this.remoteWatcher.on(Sr.ConnectorFileUpdated,({connectorId:e,filePath:t,eventType:n,newPath:r})=>this.handleRemoteConnectorFileEvent(e,t,n,r)),await this.remoteWatcher.start(),b.success("[remote] Tracking changes..")}async stopWatching(){this.localWatcher&&(await this.localWatcher.stop(),this.localWatcher=void 0),this.remoteWatcher&&(await this.remoteWatcher.stop(),this.remoteWatcher=void 0)}async handleRemoteElementEvent(e,t){try{const n=await this.remoteRepo.getByInternalId(e,t),r=!!n?.data.archivedAt||!!n?.data.isDeactivated;if(!n||r){const o=n||this.remoteCache.getByInternalId(e);return o?(b.info(`[${this.getDirectionLabel(ae.INCOMING)}] Deleted: ${o.id}`),this.localWatcher?.executeWithPathLock(o.absolutePath,()=>this.deleteElement(o,ae.INCOMING))):void 0}if(b.info(`[${this.getDirectionLabel(ae.INCOMING)}] Updated: ${n.id}`),await this.localWatcher?.executeWithPathLock(n.absolutePath,async()=>this.updateElement(n,ae.INCOMING)),t===B.Integration){const o=n.data.connectorId,a=n.data.connectorVersion,l=await _r({connectorId:o});if(!l?.key)return;const u=Wu(l);await this.localWatcher?.executeWithPathLock(u,async()=>Yo({connectorId:o,connectorVersion:a,allConnectors:!1,pulledConnectors:this.pulledConnectors,pulledConnectorVersions:this.pulledConnectorVersions}))}}catch(n){b.error(`[sync] Error handling remote event: ${n}`)}}async handleRemoteConnectorFileEvent(e,t,n,r){try{switch(n){case Ms.ConnectorFileDeleted:await zu(e,t);break;case Ms.ConnectorDirectoryRenamed:await Yu(e,t,r);break;case Ms.ConnectorDirectoryDeleted:await Xu(e,t);break;default:await Gu(e,t);break}}catch(i){b.error(`[sync] Error handling remote connector file event: ${i}`)}}async handleLocalEvent(e,t){try{if(Ju(e.filePath))switch(t){case he.Updated:await Hu(e.filePath);break;case he.Deleted:await Vu(e.filePath);break}else{let n=Q.fromPathAndData(e.filePath,e.data);if(!n){const r=Q.idFromPath(e.filePath);if(!r||(n=this.remoteCache.get(r),!n))return}switch(b.info(`[${this.getDirectionLabel(ae.OUTGOING)}] ${al.toSentenceCase(t)}: ${n.id}`),t){case he.Updated:await this.updateElement(n,ae.OUTGOING);break;case he.Deleted:await this.deleteElement(n,ae.OUTGOING);break}}}catch(n){b.error(`[sync] Error handling local event: ${n}`)}}detectIncomingChanges(){this.clearChanges();const e=mn.getChanges(ae.INCOMING,this.remoteCache,this.localCache);return this.updateChanges(e),e}detectOutgoingChanges(){this.clearChanges();const e=mn.getChanges(ae.OUTGOING,this.localCache,this.remoteCache);return this.updateChanges(e),e}async resolveChanges(){if(!this.needsSync())return;b.info("[resolver] Resolving changes.."),b.info("[resolver] Resolving integration elements");const e=this.changes.filter(r=>r.element.type===B.Integration);await Promise.all(e.map(async r=>this.resolveChange(r))),e.length>0&&(await this.fetchElements(),this.changes=this.changes.length>0&&this.changes[0]?.direction===ae.INCOMING?this.detectIncomingChanges():this.detectOutgoingChanges(),this.changes=this.changes.filter(r=>r.element.type!==B.Integration)),b.info("[resolver] Resolving universal elements");const t=this.changes.filter(r=>!r.element.hasParent());for(const r of Qo){const i=t.filter(o=>o.element.type===r);b.info(`[resolver] Resolving ${r} elements`),await Promise.all(i.map(async o=>this.resolveChange(o)))}b.info("[resolver] Resolving integration level elements");const n=this.changes.filter(r=>r.element.hasParent());for(const r of Qo){const i=n.filter(o=>o.element.type===r);b.info(`[resolver] Resolving ${r} elements`),await Promise.all(i.map(async o=>this.resolveChange(o)))}b.success("[resolver] Resolved changes")}async resolveChange(e){switch(e.type){case Ae.DELETE:return this.deleteElement(e.element,e.direction);case Ae.CREATE:return this.updateElement(e.element,e.direction);case Ae.UPDATE:return this.updateElement(e.element,e.direction)}}static getChanges(e,t,n){const r=t.getAllIds(),i=n.getAllIds(),o=new Set([...r,...i]),a=[];for(const l of o){const u=t.get(l),h=n.get(l),f=mn.detectChangeForElement(u,h,e);f&&a.push(f)}return a}updateChanges(e){if(this.changes=e,this.needsForcedSync()){const t=e.filter(n=>n.isConflict);b.warning("[resolver] Conflicts detected"),this.notifier.setConflicts(t)}}clearChanges(){this.changes=[]}getDirectionLabel(e){switch(e){case ae.INCOMING:return"local\u2190remote";case ae.OUTGOING:return"local\u2192remote"}}static detectChangeForElement(e,t,n){return e&&!t?{type:Ae.CREATE,element:e,direction:n,isConflict:!1}:!e&&t?{type:Ae.DELETE,element:t,direction:n,isConflict:!0}:e&&t&&!e.isEqual(t)?{type:Ae.UPDATE,element:e,direction:n,isConflict:!0}:null}}const Ue=F.join(Dc.tmpdir(),"membrane-mcp-status"),Zo=3e4;class Qu{static{c(this,"McpStatusService")}constructor(e=2e3){this.pollIntervalMs=e}isRunning=!1;pollInterval;async start(){this.isRunning||(this.isRunning=!0,this.pollInterval=setInterval(async()=>await this.checkStatus(),this.pollIntervalMs),await this.checkStatus())}async stop(){this.pollInterval&&(clearInterval(this.pollInterval),this.pollInterval=void 0,this.isRunning=!1)}async checkStatus(){try{const e=process.cwd(),t=ts(void 0,e),n=ea(e);t&&Oe.setMcpStatus(t),await Oe.setMcpServers(n)}catch{b.error("Failed to check MCP status")}}}function ts(s,e){try{const t=e||process.cwd();if(!s){const r=ea(t);return r.length===0?null:r[0]}const n=Ar(s,t);if(P.existsSync(n)){const r=P.statSync(n),i=new Date;if(i.getTime()-r.mtime.getTime()>Zo)return Vt(s,t),null;const a=P.readFileSync(n,"utf8"),l=JSON.parse(a);if(l.isRunning){const u=new Date(l.lastActivity).getTime();if(i.getTime()-u>Zo)return Vt(s,t),null}return l}}catch{s&&e&&Vt(s,e)}return null}c(ts,"getMcpStatus");function ea(s){try{const e=s||process.cwd(),t=Er(e);if(!P.existsSync(Ue))return[];const n=P.readdirSync(Ue),r=[];for(const i of n){const o=i.match(new RegExp(`^mcp-${t}-(\\d+)\\.json$`));if(o){const a=parseInt(o[1],10),l=ts(a,e);l&&r.push(l)}}return r.sort((i,o)=>new Date(o.startTime).getTime()-new Date(i.startTime).getTime())}catch{return[]}}c(ea,"getAllMcpStatusFiles");function Tr(s){try{const t={...ts(s.processId,s.cwd)||{isRunning:!1,startTime:new Date().toISOString(),lastActivity:new Date().toISOString(),toolsCount:0,totalRequests:0,processId:s.processId,cwd:s.cwd,agentName:process.env.AGENT_NAME||"Unnamed Agent"},...s};P.existsSync(Ue)||P.mkdirSync(Ue,{recursive:!0});const n=Ar(s.processId,s.cwd);P.writeFileSync(n,JSON.stringify(t,null,2))}catch{}}c(Tr,"updateMcpStatus");function Vt(s,e){try{const t=e||process.cwd();if(s){const n=Ar(s,t);P.existsSync(n)&&P.unlinkSync(n)}else{const n=Er(t);if(P.existsSync(Ue)){const r=P.readdirSync(Ue);for(const i of r)i.match(new RegExp(`^mcp-${n}-\\d+\\.json$`))&&P.unlinkSync(F.join(Ue,i))}}}catch{}}c(Vt,"clearMcpStatus");function Zu(s,e){const t=ts(s,e);t&&Tr({processId:s,cwd:e,totalRequests:t.totalRequests+1,lastRequestTime:new Date().toISOString(),lastActivity:new Date().toISOString()})}c(Zu,"trackToolExecution");function Er(s){return Nc("md5").update(s).digest("hex").slice(0,8)}c(Er,"getCwdHash");function Ar(s,e){const t=Er(e);return F.join(Ue,`mcp-${t}-${s}.json`)}c(Ar,"getStatusFilePath");const Gt={Agent:"agent",Cli:"cli"},x={NOT_INITIALIZED:"not_initialized",SETTING_UP:"setting_up",INITIALIZED:"initialized",NOT_SYNCED:"not_synced",PULLING:"pulling",PUSHING:"pushing",RESOLVING:"resolving",CONFLICTS:"conflicts",SYNCED:"synced",WATCHING:"watching",ERROR:"error"};class ta{static{c(this,"MembraneCLIService")}constructor(e,t,n=()=>process.exit(0)){this.mode=e,this.cwd=t,this.onShutdown=n,this.notifier=Oe,this.mcpStatusService=new Qu,this.syncService=new mn,this.setupProcessCleanup()}initialized=!1;notifier;mcpStatusService;syncService;isShuttingDown=!1;currentConfig=null;get config(){return this.currentConfig}async pullWorkspace(e={}){try{if(b.setVerboseMode(!!e.verbose),await this.notifier.setState(x.PULLING),await this.syncService.fetchElements(),this.syncService.detectIncomingChanges(),this.syncService.needsForcedSync()&&!e.force)return this.notifier.setState(x.CONFLICTS);await this.syncService.pullConnectors(e.allConnectors),await this.syncWorkspaces(e)}catch(t){b.error(`Failed to pull workspace: ${t}`),await this.notifier.setState(x.ERROR),b.saveLogsToFile("error")}finally{return e.saveLogs&&b.saveLogsToFile(),e?.onComplete?.()}}async pushWorkspace(e={}){try{if(b.setVerboseMode(!!e.verbose),await this.notifier.setState(x.PUSHING),await this.syncService.fetchElements(),this.syncService.detectOutgoingChanges(),this.syncService.needsForcedSync()&&!e.force)return await this.notifier.setState(x.CONFLICTS);await this.syncService.pushConnectors(),await this.syncWorkspaces(e)}catch(t){b.error(`Failed to push workspace: ${t}`),await this.notifier.setState(x.ERROR),b.saveLogsToFile("error")}finally{return e.saveLogs&&b.saveLogsToFile(),e?.onComplete?.()}}async syncWorkspaces(e={}){try{e.verbose!==void 0&&b.setVerboseMode(!!e.verbose),await this.notifier.setState(x.RESOLVING),this.syncService.needsSync()&&await this.syncService.resolveChanges();const t=await this.syncService.getStats();this.notifier.setStats(t),await this.notifier.setState(x.SYNCED),e.watch&&(await this.notifier.setState(x.WATCHING),await this.syncService.startWatching())}catch(t){b.error(`Failed to sync local and remote workspaces: ${t}`),await this.notifier.setState(x.ERROR),b.saveLogsToFile("error")}}async init({force:e=!1}={}){if(!(this.initialized&&!e)){await this.notifier.setState(x.NOT_INITIALIZED);try{await this.loadConfig(),Dt.isCacheDefined()?(await this.initServices(),this.initialized=!0,await this.notifier.setState(x.INITIALIZED)):(this.initialized=!1,await this.notifier.setState(x.SETTING_UP))}catch(t){b.error(`Failed to initialize services: ${t}`),await this.notifier.setState(x.ERROR),b.saveLogsToFile("error"),this.onShutdown()}}}async loadConfig(){this.currentConfig=Dt.loadConfig(this.cwd),this.notifier.setConfig(this.currentConfig)}async updateConfig(e){const t={...this.currentConfig,...e};if(!(JSON.stringify(t)!==JSON.stringify(this.currentConfig)))return;await this.stopServices();const r=Dt.updateConfig(t);this.currentConfig=r,await this.init({force:!0})}async shutdown(){!this.initialized||this.isShuttingDown||(this.isShuttingDown=!0,this.mode===Gt.Agent&&(await this.notifier.cleanup(),await this.mcpStatusService.stop()),this.initialized=!1,this.onShutdown())}async initServices(){this.mode===Gt.Agent&&(await this.notifier.connectToRemote(),await this.mcpStatusService.start()),this.syncService.clear()}async stopServices(){this.mode===Gt.Agent&&(await this.notifier.cleanup(),await this.mcpStatusService.stop())}setupProcessCleanup(){["SIGINT","SIGTERM","uncaughtException","unhandledRejection"].forEach(t=>process.on(t,()=>this.shutdown())),process.on("beforeExit",t=>{t===0&&this.shutdown()})}}const na=oi(null);function eh({children:s,membraneCLIService:e}){const{data:t}=ci("/account"),[n,r]=J(x.NOT_INITIALIZED),[i,o]=J([]),[a,l]=J({}),[u,h]=J([]),[f,p]=J(null),y=t?.workspaces?.find(d=>d.workspaceKey===f?.workspaceKey)||null;return Ve(()=>{const d=c(({state:A})=>r(A),"handleStateChanged"),w=c(({stats:A})=>l(A),"handleStatsChanged"),k=c(({log:A})=>h($=>[...$,A]),"handleLogAdded"),_=c(({conflicts:A})=>o(A),"handleConflictsUpdated"),O=c(({config:A})=>p(A),"handleConfigChanged");return e.notifier.on(Y.StateChanged,d),e.notifier.on(Y.StatsChanged,w),e.notifier.on(Y.LogAdded,k),e.notifier.on(Y.ConflictsChanged,_),e.notifier.on(Y.ConfigChanged,O),e.init(),()=>{e.notifier.off(Y.StateChanged,d),e.notifier.off(Y.StatsChanged,w),e.notifier.off(Y.LogAdded,k),e.notifier.off(Y.ConflictsChanged,_),e.notifier.off(Y.ConfigChanged,O)}},[]),g(na.Provider,{value:{state:n,stats:a,logs:u,currentWorkspace:y,conflicts:i,config:f,updateConfig:c(d=>e.updateConfig(d),"updateConfig"),resolveConflicts:c(d=>e.syncWorkspaces(d),"resolveConflicts"),pull:c(d=>e.pullWorkspace(d),"pull"),push:c(d=>e.pushWorkspace(d),"push"),exit:c(()=>e.shutdown(),"exit")},children:s})}c(eh,"MembraneCLIServiceProvider");function Se(){const s=ai(na);if(!s)throw new Error("useMembraneCLIService must be used within MembraneCLIServiceProvider");return s}c(Se,"useMembraneCLIService");const sa=oi(process.cwd());function th({cwd:s,children:e}){return g(sa.Provider,{value:s,children:e})}c(th,"CwdProvider");function nh(){return ai(sa)}c(nh,"useCwd");function ns({cwd:s,children:e,membraneCLIService:t}){const n=s||process.cwd();return g(th,{cwd:n,children:g(gc,{value:{fetcher:gl()},children:g(eh,{membraneCLIService:t,children:e})})})}c(ns,"Layout");const Or=[{id:"claude-code",name:"Claude Code",description:"Anthropic Claude Code agent",actionDescription:"Adding membrane MCP to .mcp.json in the current directory",addConfig:c(()=>{const s=F.join(process.cwd(),".mcp.json"),e={mcpServers:{membrane:{command:"membrane",args:["mcp"],env:{AGENT_NAME:"Claude Code"}}}};let t={};if(P.existsSync(s))try{t=JSON.parse(P.readFileSync(s,"utf8"))}catch{t={}}const n={...t,mcpServers:{...t.mcpServers,...e.mcpServers}};return P.writeFileSync(s,JSON.stringify(n,null,2)),`MCP server configuration added to ${s}`},"addConfig")},{id:"cursor",name:"Cursor",description:"Cursor AI editor",actionDescription:"Adding membrane MCP to .cursor/mcp.json in the current directory",addConfig:c(()=>{const s=F.join(process.cwd(),".cursor"),e=F.join(s,"mcp.json");P.existsSync(s)||P.mkdirSync(s);const t={mcpServers:{membrane:{command:"membrane",args:["mcp"],env:{AGENT_NAME:"Cursor"}}}};let n={};if(P.existsSync(e))try{n=JSON.parse(P.readFileSync(e,"utf8"))}catch{n={}}const r={...n,mcpServers:{...n.mcpServers,...t.mcpServers}};return P.writeFileSync(e,JSON.stringify(r,null,2)),`MCP server configuration added to ${e}`},"addConfig")}];function sh({onExit:s,onComplete:e}){const[t,n]=J(0),[r,i]=J(!1),[o,a]=J(null),[l,u]=J(""),[h,f]=J("");nt((y,d)=>{if(l||h){(d.escape||y==="q"||d.return)&&e();return}if(r)d.return||y===" "?p(o):d.escape&&(i(!1),a(null));else if(d.escape)s();else if(d.upArrow||y==="k")n(Math.max(0,t-1));else if(d.downArrow||y==="j")n(Math.min(Or.length-1,t+1));else if(d.return||y===" "){const w=Or[t];a(w),i(!0)}});const p=c(y=>{try{const d=y.addConfig();u(d)}catch(d){f(`Failed to write configuration: ${d.message||d}`)}},"addMcpConfiguration"),m=Math.min(80,process.stdout.columns||80);return l?E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:m,children:[g(v,{marginTop:-1,marginBottom:1,children:E(C,{bold:!0,children:["\u{1F517} Connect Agent \u2014 ",g(C,{color:"green",children:"Success"})]})}),E(v,{flexDirection:"column",paddingLeft:2,children:[g(C,{color:"green",children:l}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"The agent will now be able to use Membrane's integration capabilities."})})]}),g(v,{marginTop:1,paddingLeft:2,children:g(C,{color:"white",children:"[esc/q/enter: exit]"})})]}):h?E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:m,children:[g(v,{marginTop:-1,marginBottom:1,children:E(C,{bold:!0,children:["\u{1F517} Connect Agent \u2014 ",g(C,{color:"red",children:"Error"})]})}),g(v,{flexDirection:"column",paddingLeft:2,children:g(C,{color:"red",children:h})}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"[esc/q/enter: exit]"})})]}):r&&o?E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:m,children:[g(v,{marginTop:-1,marginBottom:1,children:E(C,{bold:!0,children:["\u{1F517} Connect Agent \u2014 ",g(C,{color:"cyan",children:"Confirmation"})]})}),E(v,{flexDirection:"column",paddingLeft:2,children:[E(C,{children:["Connect ",g(C,{bold:!0,children:o.name})," to Membrane via MCP?"]}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"This will add an MCP server configuration that allows the agent to use Membrane's integration capabilities."})}),g(v,{marginTop:1,children:g(C,{color:"yellow",bold:!0,children:o.actionDescription})}),g(v,{marginTop:2,marginBottom:1,children:E(C,{children:[g(C,{color:"white",bold:!0,children:"[Enter] Confirm"})," ",g(C,{color:"gray",children:"[Esc] Cancel"})]})})]})]}):E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:m,children:[g(v,{marginTop:-1,marginBottom:1,children:E(C,{bold:!0,children:["\u{1F517} Connect Agent \u2014 ",g(C,{color:"cyan",children:"Select Agent"})]})}),E(v,{flexDirection:"column",paddingLeft:2,children:[g(C,{color:"grey",children:"Choose an agent to connect to Membrane via MCP:"}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"This will add an MCP server configuration that allows the agent to use Membrane's integration capabilities."})}),g(v,{marginTop:1,flexDirection:"column",children:Or.map((y,d)=>E(v,{children:[E(C,{color:t===d?"cyan":"white",children:[t===d?"\u25B6 ":" ",y.name]}),E(C,{color:"grey",children:[" \u2014 ",y.description]})]},y.id))})]}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"[\u2191\u2193: select] [enter: choose] [esc: exit]"})})]})}c(sh,"AddMcpServerScreen");function rh(){const[s,e]=J(null),[t,n]=J([]),[r,i]=J(null);return Ve(()=>{const o=c(({status:l})=>{e(l),i(null)},"handleMcpStatusChanged"),a=c(({servers:l})=>{n(l),i(null)},"handleMcpServersChanged");return Oe.on(Y.McpStatusChanged,o),Oe.on(Y.McpServersChanged,a),()=>{Oe.off(Y.McpStatusChanged,o),Oe.off(Y.McpServersChanged,a)}},[]),{mcpStatus:s,allMcpServers:t,error:r,isRunning:s?.isRunning||!1,toolsCount:s?.toolsCount||0,totalRequests:s?.totalRequests||0,lastActivity:s?.lastActivity,processId:s?.processId,serverCount:t.length}}c(rh,"useMcpStatus");function ih(){const{error:s,serverCount:e,allMcpServers:t}=rh(),n=Math.min(100,process.stdout.columns||100);return E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:n,children:[g(v,{marginTop:-1,marginBottom:0,flexDirection:"column",children:E(C,{bold:!0,children:["\u{1F916} Connected AI Agents:"," ",s?g(C,{color:"red",children:"error reading status"}):e===0?g(C,{color:"yellow",children:"none"}):g(C,{color:"green",children:e})]})}),!s&&e===0&&g(v,{marginTop:1,children:E(C,{color:"grey",children:["Connect your AI agents to Membrane.",g(pc,{}),"It will give them tools and context to build integrations."]})}),t.length>0&&g(v,{flexDirection:"column",paddingLeft:2,marginTop:1,children:t.map((r,i)=>g(v,{children:E(C,{color:"grey",children:["#",i+1," ",r.agentName,": ",r.totalRequests," calls"]})},r.processId))}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"[a: connect an agent]"})})]})}c(ih,"Agent");const ss=c(s=>{switch(s){case"error":return"red";case"success":return"green";case"warning":return"yellow";default:return}},"getLogColor");function ra(s,e){return e<3?s.slice(0,Math.max(0,e)):s.length<=e?s:`${s.slice(0,e-3)}...`}c(ra,"truncateText");function Ir({children:s}){const{state:e,logs:t}=Se();return!e||e===x.NOT_INITIALIZED?E(v,{gap:1,flexDirection:"row",children:[g(Fc,{type:"dots"}),g(C,{children:"Initializing..."})]}):e===x.SETTING_UP?g(v,{gap:1,flexDirection:"row",children:g(C,{children:"No workspace selected. Please run `membrane init` to select a workspace."})}):e===x.ERROR?g(v,{flexDirection:"column",children:t.slice().map((n,r)=>g(C,{color:ss(n.type),children:n.message},n.timestamp+r))}):s}c(Ir,"EnsureInitialized");function ia({onExit:s,showEscOption:e=!0}){const[t,n]=J(""),{data:r,error:i,isLoading:o}=ci("/account"),{updateConfig:a}=Se(),l=r?.workspaces,u=o;if(nt((d,w)=>{w.escape&&s?.()}),u)return E(v,{children:[g(wn,{}),g(C,{children:" Fetching workspaces..."})]});if(i)return E(v,{flexDirection:"column",children:[E(C,{color:"red",children:["Error: ",i.message]}),g(v,{marginTop:1,children:g(C,{color:"grey",children:"Press ESC to go back"})})]});const h=l?.filter(d=>d.name.toLowerCase().includes(t.toLowerCase()))??[],f=h.map(d=>({label:d.name,value:d.id})),p=f.length,m=l?.length??0;async function y(d){const w=h.find(O=>O.id===d);if(!w)return;const{key:k,secret:_}=w;!k||!_||(await a({workspaceKey:k,workspaceSecret:_}),s?.())}return c(y,"handleSelect"),E(v,{flexDirection:"column",borderStyle:"round",borderTop:!0,width:70,paddingX:1,children:[g(v,{marginTop:-1,children:g(C,{bold:!0,children:"\u{1F4C1} Select your workspace"})}),E(v,{marginTop:1,children:[g(C,{children:"Search: "}),g(Kc,{placeholder:"Enter a search query...",onChange:n})]}),m>5&&E(C,{children:["Showing ",p," of ",m," workspaces."]}),g(v,{marginTop:1,children:g(Bc,{options:f,onChange:c(d=>{d&&y(d)},"onChange")})}),e&&g(v,{marginTop:1,children:g(C,{color:"grey",children:"Press ESC to go back"})})]})}c(ia,"SelectWorkspace");function oh({currentPat:s,onSubmit:e}){const[t,n]=J(""),[r,i]=J(!1),[o,a]=J(null);return E(v,{flexDirection:"column",borderStyle:"round",borderTop:!0,width:70,paddingX:1,children:[g(v,{marginTop:-1,marginBottom:1,children:g(C,{bold:!0,children:"\u{1F511} Enter your Personal Access Token"})}),g(C,{children:"Please provide your Personal Access Token. You can find it here:"}),g(v,{marginTop:1,marginBottom:1,children:g(C,{color:"yellow",children:"https://console.integration.app/w/0/manage-account/api-token"})}),s&&g(C,{dimColor:!0,children:"Press Enter to keep your current token or type a new one."}),g(qc,{mask:"*",placeholder:`${s?"******":"Enter your token here..."}`,value:t,onChange:n,onSubmit:c(async u=>{a(null),i(!0);try{await e(u),n("")}catch{a("Invalid token. Please try again.")}finally{i(!1)}},"handleSubmit")}),r&&g(v,{marginTop:1,children:E(C,{children:[g(wn,{type:"dots"})," Validating token..."]})}),o&&g(C,{color:"red",children:o})]})}c(oh,"PersonalAccessTokenInput");var zt=(s=>(s[s.Authenticate=0]="Authenticate",s[s.ConnectWorkspace=1]="ConnectWorkspace",s))(zt||{});const ah={0:"Authenticate in Membrane",1:"Connect a Membrane Workspace"},$r=[zt.Authenticate,zt.ConnectWorkspace];function oa({onComplete:s}){const{config:e}=Se(),[t,n]=J(!1),[r,i]=J(0),o=!!(e?.workspaceKey&&e?.workspaceSecret),a=Fi(),l=$r[r],u=r+1,h=$r.length,f=$r.map((y,d)=>{let w="pending";return d<r?w="done":d===r&&(w="current"),{id:y,label:ah[y],status:w}});async function p(y){const d=a&&y===""?a:y,w=new Ki;try{await w.request("/account",{headers:{Authorization:`Bearer ${d}`}}),ml(d),i(k=>k+1)}catch(k){console.error(k)}}c(p,"handlePatSubmit");function m(){n(!0),s&&s()}return c(m,"handleWorkspaceSelected"),nt((y,d)=>{o&&d.escape&&s&&s()}),t?g(v,{children:g(C,{children:"\u2705 Setup complete. You are ready to go!"})}):E(v,{flexDirection:"column",alignSelf:"flex-start",gap:1,children:[E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:70,children:[g(v,{marginTop:-1,marginBottom:1,children:E(C,{bold:!0,children:["\u{1F6E0}\uFE0F Setup \u2014"," ",E(C,{color:"cyan",children:["Step ",u," of ",h]}),o&&g(C,{color:"grey",children:" [esc: go back]"})]})}),g(v,{flexDirection:"column",paddingLeft:2,children:f.map(y=>g(ch,{status:y.status,label:y.label},y.id))})]}),l===zt.Authenticate&&g(oh,{currentPat:a,onSubmit:p}),l===zt.ConnectWorkspace&&g(ia,{onExit:m,showEscOption:!1})]})}c(oa,"Setup");function ch({status:s,label:e}){return E(v,{children:[E(v,{width:2,children:[s==="current"&&g(wn,{type:"dots"}),s==="done"&&g(C,{children:"\u2705"})]}),g(C,{dimColor:s!=="current",children:e})]})}c(ch,"StepDisplay");function Nr(){const{stats:s}=Se(),e=Object.entries(s).filter(([t,n])=>n>0);return e.length===0?null:E(v,{flexDirection:"column",children:[g(v,{children:g(v,{width:12,children:g(C,{color:"grey",children:"Elements:"})})}),g(v,{flexDirection:"column",marginLeft:1,children:e.map(([t,n])=>E(v,{children:[g(v,{width:20,children:E(C,{children:[t,":"]})}),g(C,{color:"green",children:n})]},t))})]})}c(Nr,"ElementStats");const xr=5,lh=6;function uh(){const{logs:s}=Se(),[e,t]=J(0),n=Math.min(100,process.stdout.columns||100),r=xr,i=Math.max(0,s.length-r-e),o=s.length-e,a=s.slice(i,o),l=n-lh,u=e<s.length-r,h=e>0;return nt((f,p)=>{if(s.length!==0)if(p.upArrow){const m=Math.max(0,s.length-r);t(y=>Math.min(m,y+1))}else p.downArrow?t(m=>Math.max(0,m-1)):(f==="G"||f==="g")&&t(0)}),E(v,{flexDirection:"column",paddingTop:1,children:[E(C,{color:"grey",children:["Recent Activity (",i+1,"-",o," of ",s.length,"):",s.length>xr&&g(C,{color:"grey",children:" [arrows: scroll] [g: end]"})]}),a.map((f,p)=>g(v,{marginLeft:1,children:g(C,{color:ss(f.type),children:ra(f.message,l)})},f.timestamp+p)),s.length>xr&&E(v,{marginLeft:1,flexDirection:"row",children:[u&&g(C,{color:"grey",children:"\u2191 "}),h&&g(C,{color:"grey",children:"\u2193 "})]})]})}c(uh,"Logs");const rs=[{value:"sync",label:"Continue (overwrite/delete)",key:""},{value:"exit",label:"Cancel",key:""}];function hh(){const{state:s,resolveConflicts:e,exit:t}=Se(),[n,r]=J(0),[i,o]=J(!1),[a,l]=J(!1);return nt((u,h)=>{if(!i){if(h.ctrl&&u.toLowerCase()==="r"){l(!a);return}h.upArrow?r(f=>f>0?f-1:rs.length-1):h.downArrow?r(f=>f<rs.length-1?f+1:0):u.toLowerCase()==="y"?r(0):u.toLowerCase()==="n"?r(1):(h.return||u===" ")&&(o(!0),rs[n].value==="sync"?e({watch:!0}):t())}}),Ve(()=>{s!==x.CONFLICTS&&i&&o(!1)},[s,i]),E(v,{flexDirection:"column",paddingTop:1,children:[g(v,{children:g(v,{flexDirection:"row",gap:2,children:g(C,{bold:!0,color:"white",children:"Conflicts with remote"})})}),g(v,{children:g(C,{color:"grey",children:"The remote workspace has changes that aren't in your local workspace:"})}),g(v,{marginTop:1,marginLeft:2,children:g(Mr,{isExpanded:a})}),E(v,{marginTop:2,flexDirection:"row",gap:1,children:[g(C,{color:"white",bold:!0,children:"What would you like to do?"}),g(C,{color:"grey",children:"[up/down, enter]"})]}),g(v,{children:i?E(v,{flexDirection:"row",gap:1,children:[g(wn,{type:"dots"}),g(C,{color:"blue",bold:!0,children:"Syncing with remote..."})]}):g(v,{flexDirection:"column",children:rs.map((u,h)=>g(v,{flexDirection:"column",children:E(v,{flexDirection:"row",gap:1,children:[g(C,{color:n===h?"cyan":"grey",children:n===h?"\u25B6":" "}),g(C,{color:n===h?"cyan":"grey",bold:n===h,children:u.label})]})},u.value))})})]})}c(hh,"ResolveChangesUI");const fh={[Ae.UPDATE]:{incoming:{label:"Elements updated in remote",description:"(to be overwritten from remote)"},outgoing:{label:"Elements updated locally",description:"(to be pushed to remote)"}},[Ae.DELETE]:{incoming:{label:"Elements not existing in remote",description:"(to be deleted locally)"},outgoing:{label:"Elements deleted locally",description:"(to be deleted from remote)"}},[Ae.CREATE]:{incoming:{label:"Elements created in remote",description:"(to be created locally)"},outgoing:{label:"Elements created locally",description:"(to be created in remote)"}}};function Mr({isExpanded:s,showControls:e=!0}){const{conflicts:t}=Se(),n=5,r=yc(()=>{const i={};return t.forEach(o=>{const a=`${o.type}-${o.direction}`;i[a]||(i[a]=[]),i[a].push(o)}),i},[t]);return g(v,{flexDirection:"column",children:Object.entries(r).map(([i,o])=>{if(o.length===0)return null;const[a,l]=i.split("-"),u=fh[a][l];return E(v,{flexDirection:"column",children:[E(v,{flexDirection:"row",gap:1,children:[E(C,{color:"yellow",children:[u.label," (",o.length,")"]}),g(C,{color:"white",children:u.description})]}),(s?o:o.slice(0,n)).map(h=>g(v,{marginLeft:2,children:E(C,{color:"grey",children:["\u2022 ",h.element.id," (",h.element.relativePath,")"]})},h.element.id)),!s&&o.length>n&&g(v,{marginLeft:2,children:E(C,{color:"cyan",children:["... and ",o.length-n," more",e?" (press Ctrl+R to show all)":""]})}),s&&o.length>n&&e&&g(v,{marginLeft:2,children:g(C,{color:"cyan",children:"(press Ctrl+R to collapse)"})})]},i)})})}c(Mr,"Conflicts");function dh(){const{config:s,state:e,logs:t,currentWorkspace:n,pull:r}=Se(),i=n?.name,o=i?ra(i,30):s?.workspaceKey,a=Math.min(100,process.stdout.columns||100);return Ve(()=>{r({watch:!0})},[]),E(v,{flexDirection:"column",paddingX:1,borderStyle:"round",borderTop:!0,width:a,children:[g(v,{marginTop:-1,marginBottom:1,children:E(v,{flexDirection:"row",gap:1,children:[g(C,{bold:!0,children:"\u{1F504} Workspace"}),E(C,{color:mh(e),children:[" [",ph(e),"] "]})]})}),E(v,{children:[g(v,{width:12,children:g(C,{color:"grey",children:"Local:"})}),g(C,{color:"grey",children:process.cwd()})]}),E(v,{children:[g(v,{width:12,children:g(C,{color:"grey",children:"Remote:"})}),s?.workspaceKey?E(C,{color:"grey",children:[o," [o: open in console] [w: change]"]}):E(C,{children:[g(C,{color:"yellow",children:"not selected"})," [w: select]"]})]}),e===x.CONFLICTS?g(hh,{}):E(Ns,{children:[g(v,{paddingTop:1,children:g(Nr,{})}),t.length>0&&g(uh,{})]})]})}c(dh,"Workspace");function ph(s){switch(s){case x.PULLING:return"pulling";case x.PUSHING:return"pushing";case x.CONFLICTS:return"conflicts";case x.SYNCED:return"synced";case x.ERROR:return"error";case x.WATCHING:return"tracking changes";case x.RESOLVING:return"resolving";case x.NOT_SYNCED:return"not synced";case x.INITIALIZED:return"initialized";case x.SETTING_UP:return"setup required";default:return"unknown"}}c(ph,"getStatusDisplay");function mh(s){switch(s){case x.PULLING:return"yellow";case x.PUSHING:return"yellow";case x.CONFLICTS:return"red";case x.SYNCED:return"green";case x.ERROR:return"red";case x.WATCHING:return"green";case x.RESOLVING:return"yellow";case x.NOT_SYNCED:return"grey";case x.SETTING_UP:return"yellow";default:return"grey"}}c(mh,"getStatusColor");const gh="https://console.integration.app/w";function yh(){const s=nh(),e=wc(!0),{exit:t,state:n}=Se(),[r,i]=J(null),o=r??(n===x.SETTING_UP?"setup":"main");nt(l=>{o==="main"&&(l==="w"&&i("workspace-selection"),l==="a"&&i("add-mcp-server"),l==="o"&&n===x.INITIALIZED&&a(),l==="s"&&i("setup"))});async function a(){try{const l=await Bi(s),u=`${gh}/${l}`,h=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";jc(`${h} "${u}"`)}catch(l){console.error("Failed to open workspace:",l),t()}}return c(a,"handleOpenWorkspace"),Ve(()=>(e.current=!0,()=>{e.current=!1}),[]),o==="workspace-selection"?g(ia,{onExit:c(()=>i(null),"onExit")}):o==="add-mcp-server"?g(sh,{onExit:c(()=>i(null),"onExit"),onComplete:c(()=>i(null),"onComplete")}):o==="setup"?g(oa,{onComplete:c(()=>i(null),"onComplete")},Date.now()):g(Ir,{children:E(v,{flexDirection:"column",children:[g(v,{flexGrow:1,children:g(ih,{})}),g(dh,{}),g(v,{paddingLeft:2,children:g(C,{color:"grey",children:"[s: (re-)setup]"})})]})})}c(yh,"Main");const Rr=mc(process.argv.slice(2)),aa=Rr.cwd?fc(Rr.cwd):process.cwd(),wh=new ta(Gt.Agent,aa);Rr.verbose&&b.setVerboseMode(!0);const bh=c(()=>g(ns,{cwd:aa,membraneCLIService:wh,children:g(yh,{})}),"App");function Sh(){gn(g(bh,{}))}c(Sh,"runAgent");function vh(s,e){s.command("init").description("Run interactive setup for Membrane project").option("--key <key>","Workspace key for non-interactive setup").option("--secret <secret>","Workspace secret for non-interactive setup").addHelpText("after",["","Examples:"," membrane init # Run interactive setup"," membrane init --key KEY --secret SEC # Non-interactive setup with key and secret",""].join(`
|
|
142
142
|
`)).action(t=>{t.key&&t.secret?Dt.saveToFile({workspaceKey:t.key,workspaceSecret:t.secret})?(console.error("\u2705 Configuration saved to membrane.config.yml"),process.exit(0)):(console.error("Error writing configuration file"),process.exit(1)):t.key||t.secret?(console.error("Error: Both --key and --secret must be provided for non-interactive mode"),process.exit(1)):gn(st.createElement(ns,{membraneCLIService:e,children:st.createElement(oa,{onComplete:c(()=>process.exit(0),"onComplete")})}))})}c(vh,"setupInitCommand");async function ca(s,e,t){const n={iss:s,exp:Math.floor(Date.now()/1e3)+600,isAdmin:!0};return t&&(n.id=t),Ds.sign(n,e)}c(ca,"generateAdminAccessToken");async function Ch(s,e){return(await js.get(`${s}/docs-json`,{headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"}})).data}c(Ch,"fetchOpenApiSchema");function la(s,e=!0){if(!s)return e?ne.string():ne.string().optional();let t;switch(s.type){case"integer":t=ne.coerce.number().int();break;case"number":t=ne.coerce.number();break;case"boolean":t=ne.coerce.boolean();break;case"string":default:t=ne.string();break}return s.format==="uuid"?t=ne.string().uuid():s.format==="email"?t=ne.string().email():s.format==="date"?t=ne.string().regex(/^\d{4}-\d{2}-\d{2}$/):s.format==="date-time"&&(t=ne.string().datetime()),s.enum&&(t=ne.enum(s.enum)),(s.type==="integer"||s.type==="number")&&(s.minimum!==void 0&&(t=t.min(s.minimum)),s.maximum!==void 0&&(t=t.max(s.maximum))),s.type==="string"&&(s.minLength!==void 0&&(t=t.min(s.minLength)),s.maxLength!==void 0&&(t=t.max(s.maxLength))),e?t:t.optional()}c(la,"convertOpenApiSchemaToZod");function ua(s){const e=s.match(/\{([^}]+)\}/g);return e?e.map(t=>t.slice(1,-1)):[]}c(ua,"extractPathParameters");function kh(s,e,t,n,r,i,o){const a=s.operationId||`${t}_${e.replace(/[^a-zA-Z0-9]/g,"_")}`,l=s.description||s.summary||`${t.toUpperCase()} ${e}`,u={},h={},f={};if(s.parameters){for(const m of s.parameters)if(m.in==="path")h[m.name]=la(m.schema,!0).describe(m.description||`Path parameter: ${m.name}`);else if(m.in==="query"){const y=m.required===!0;f[m.name]=la(m.schema,y).describe(m.description||`Query parameter: ${m.name}`)}}Object.keys(h).length>0&&(u.params=ne.object(h).describe("Path parameters")),Object.keys(f).length>0&&(u.query=ne.object(f).describe("Query parameters")),s.requestBody&&s.requestBody.content&&s.requestBody.content["application/json"]&&(u.body=ne.any().describe("Request body"));const p=Object.keys(u).length>0?ne.object(u):ne.object({});return{name:a,description:l,parameters:p,async execute(m){try{const y=ua(e);if(y.length>0){if(!m.params)throw new Error(`Missing required path parameters: ${y.join(", ")}`);const $=y.filter(N=>!(N in m.params));if($.length>0)throw new Error(`Missing required path parameters: ${$.join(", ")}`)}let d=`${n}${e}`;if(m.params)for(const[$,N]of Object.entries(m.params)){const K=`{${$}}`;d.includes(K)&&(d=d.replace(K,String(N)))}const w=ua(d);if(w.length>0)throw new Error(`Unresolved path parameters: ${w.join(", ")}`);const k=new URLSearchParams;if(m.query)for(const[$,N]of Object.entries(m.query))N!=null&&k.append($,String(N));k.toString()&&(d+=`?${k.toString()}`);const _=await ca(r,i,o),O={method:t.toUpperCase(),headers:{Authorization:`Bearer ${_}`,"Content-Type":"application/json"}};m.body&&t.toLowerCase()!=="get"&&(O.data=m.body);const A=await js.request({url:d,...O});return{content:[{type:"text",text:JSON.stringify(A.data,null,2)}]}}catch(y){return js.isAxiosError(y)?{content:[{type:"text",text:`Error: ${y.response?.data?`HTTP ${y.response.status}: ${y.response.statusText} - ${JSON.stringify(y.response.data)}`:`HTTP ${y.response?.status||"unknown"}: ${y.message}`}`}],isError:!0}:y instanceof Error?{content:[{type:"text",text:`Error: API call failed: ${y.message}`}],isError:!0}:{content:[{type:"text",text:"Error: API call failed with unknown error"}],isError:!0}}}}}c(kh,"createApiTool");function _h(s,e,t,n,r){const i=[];if(!s.paths)return i;for(const[o,a]of Object.entries(s.paths))if(typeof a=="object"&&a!==null){for(const[l,u]of Object.entries(a))if(["get","post","put","delete","patch"].includes(l)&&u&&typeof u=="object"){const h=kh(u,o,l,e,t,n,r);i.push(h)}}return i}c(_h,"convertOpenApiToTools");function Th(s){s.command("mcp").description("Launch MCP server with OpenAPI endpoints as tools (API URI is read from environment variables or membrane.config.yml)").addHelpText("after",["","Examples:"," membrane mcp # Launch MCP server using API URI from env vars or membrane.config.yml",""].join(`
|
|
143
143
|
`)).action(async()=>{try{process.env.FASTMCP_SUPPRESS_WARNINGS="true";const e=On();e||(console.error("No configuration found. Please set MEMBRANE_WORKSPACE_KEY and MEMBRANE_WORKSPACE_SECRET environment variables, or run `membrane init` first."),process.exit(1)),(!e.workspaceKey||!e.workspaceSecret)&&(console.error("Missing workspace credentials"),process.exit(1));const t=e.apiUri||Us,n=await ca(e.workspaceKey,e.workspaceSecret,e.testCustomerId),r=await Ch(t,n),i=_h(r,t,e.workspaceKey,e.workspaceSecret,e.testCustomerId),o=new Jc({name:"Membrane API",instructions:`This MCP server lets you interact with Membrane to configure, run, and troubleshoot integrations.
|
|
144
144
|
Use it for anything related to Membrane or integrations.
|
|
145
145
|
`,version:"1.0.0"});for(const u of i){const h=u.execute;u.execute=async f=>(Zu(process.pid,process.cwd()),h(f)),o.addTool(u)}Tr({isRunning:!0,startTime:new Date().toISOString(),toolsCount:i.length,lastActivity:new Date().toISOString(),processId:process.pid,cwd:process.cwd(),agentName:process.env.AGENT_NAME||"Unnamed Agent"});const a=setInterval(()=>{Tr({processId:process.pid,cwd:process.cwd(),lastActivity:new Date().toISOString()})},5e3),l=c(async()=>{clearInterval(a),Vt(process.pid,process.cwd());try{await o.stop()}catch{}},"cleanup");await o.start({transportType:"stdio"}),process.on("SIGINT",async()=>{await l(),process.exit(0)}),process.on("SIGTERM",async()=>{await l(),process.exit(0)}),process.on("exit",()=>{Vt(process.pid,process.cwd())}),process.on("uncaughtException",async u=>{console.error("Uncaught exception:",u.message),await l(),process.exit(1)}),process.on("unhandledRejection",async u=>{console.error("Unhandled rejection:",u),await l(),process.exit(1)})}catch(e){e instanceof Error&&(console.error(e.message),process.exit(1)),console.error("An unknown error occurred"),process.exit(1)}})}c(Th,"setupMcpCommand");const Eh={info:"\u{1F4DD}",success:"\u2728",warning:"\u26A0\uFE0F",error:"\u274C",debug:"\u{1F50D}"},Ah={info:T.blue,success:T.green,warning:T.yellow,error:T.red,debug:T.gray};class X{static{c(this,"Logger")}static formatMessage(e,t,n={}){const r=n.timestamp?`${T.gray(new Date().toISOString())} `:"",i=n.prefix?`${T.gray(n.prefix)} `:"",o=n.suffix?` ${T.gray(n.suffix)}`:"",a=Eh[t],l=Ah[t];return`${r}${a} ${i}${l(e)}${o}`}static info(e,t){let n=T.blue;if(t?.color&&(n=T[t.color.toLowerCase()]||T.blue),t?.timestamp){const r=new Date().toLocaleTimeString();console.debug(`${T.gray(`[${r}]`)} ${n(e)}`)}else console.debug(n(e))}static group(e,t){}static groupEnd(){}static newLine(){}static success(e,t){console.debug(this.formatMessage(e,"success",t))}static warning(e,t){console.debug(this.formatMessage(e,"warning",t))}static error(e,t){console.error(this.formatMessage(e,"error",t))}static debug(e,t){t?.prefix?console.debug(T.gray(`[${t.prefix}] ${e}`),t.error?`
|
|
146
146
|
${T.red(t.error)}`:""):console.debug(T.gray(e),t?.error?`
|
|
147
147
|
${T.red(t.error)}`:"")}static step(e,t){}static header(e){console.debug(),console.debug(T.bold.cyan(`\u25B6 ${e}`)),console.debug()}static table(e,t){if(e.length===0)return;const n=t||Object.keys(e[0]),r=e.map(i=>{const o={};return n.forEach(a=>{o[a]=i[a]}),o});console.table(r,n)}static divider(){}}function Oh(s){s.command("open").description("Open the workspace in the browser").addHelpText("after",["","Examples:"," membrane open # Open workspace in browser",""].join(`
|
|
148
|
-
`)).action(async()=>{try{X.header("Opening Workspace in Browser"),X.info("Loading configuration...");const e=On();if(!e)throw new Error("No configuration found. Please set MEMBRANE_WORKSPACE_KEY and MEMBRANE_WORKSPACE_SECRET environment variables, or run `membrane init` first.");if(!e.workspaceKey||!e.workspaceSecret)throw new Error("Missing workspace credentials");X.info("Retrieving workspace ID...");const n=`https://console.integration.app/w/${await Bi(process.cwd())}`;X.info(`Opening ${n}...`);const{default:r}=await import("open");await r(n),X.success("Browser opened successfully")}catch(e){e instanceof Error&&(X.error(e.message),process.exit(1)),X.error("An unknown error occurred"),process.exit(1)}})}c(Oh,"setupOpenCommand");function Ih(s){return g(Ir,{children:g($h,{options:s})})}c(Ih,"Pull");function $h({options:s}){const{logs:e,state:t,conflicts:n,pull:r}=Se();Ve(()=>{r(s)},[]);const i=t===x.CONFLICTS;return E(v,{flexDirection:"column",children:[e.slice().map((o,a)=>g(C,{color:ss(o.type),children:o.message},o.timestamp+a)),i&&E(Ns,{children:[E(C,{color:"yellow",bold:!0,children:["Found ",n.length," conflicts with remote:"]}),g(Mr,{isExpanded:!1}),g(C,{color:"red",children:"Out of sync with remote, use --force to overwrite conflict changes"})]}),t===x.SYNCED&&g(Nr,{})]})}c($h,"PullActivity");function ha(){const s=setInterval(()=>{},3e4),e=c(()=>{clearInterval(s)},"cleanup");return process.on("SIGINT",()=>{e(),process.exit(0)}),process.on("SIGTERM",()=>{e(),process.exit(0)}),process.on("exit",e),()=>{}}c(ha,"getWatchModeCallback");function Nh(s,e){s.command("pull").description("Pull workspace data from specified workspace").option("--force","Overwrite conflicts with remote data",!1).option("--watch","Watch for changes and pull automatically",!1).option("--all-connectors","Include public connectors in export - to push to the self-hosted instance",!1).option("--save-logs","Save logs to a file",!1).option("--verbose","Show verbose debug logs",!1).addHelpText("after",["","Examples:"," membrane pull # Pull from default workspace"," membrane pull --force # Overwrite conflicts with remote data"," membrane pull --all-connectors # Pull all connectors"," membrane pull --watch # Watch for changes and pull automatically",""].join(`
|
|
149
|
-
`)).action(async t=>{const n=t.watch?ha():()=>process.exit(0);gn(st.createElement(ns,{membraneCLIService:e,children:st.createElement(Ih,{...t,onComplete:n})}))})}c(Nh,"setupPullCommand");function xh(s){return g(Ir,{children:g(Mh,{options:s})})}c(xh,"Push");function Mh({options:s}){const{logs:e,state:t,conflicts:n,push:r}=Se();Ve(()=>{r(s)},[]);const i=t===x.CONFLICTS;return E(v,{flexDirection:"column",children:[e.slice().map((o,a)=>g(C,{color:ss(o.type),children:o.message},o.timestamp+a)),i&&E(Ns,{children:[E(C,{color:"yellow",bold:!0,children:["Found ",n.length," conflicts with remote:"]}),g(Mr,{isExpanded:!1}),g(C,{color:"red",children:"Out of sync with remote, use --force to overwrite conflict changes"})]}),t===x.SYNCED&&g(Nr,{})]})}c(Mh,"PushActivity");function Rh(s,e){s.command("push").description("Push workspace data to specified workspace").option("--force","Overwrite conflicts with local data",!1).option("--watch","Watch for changes and push automatically",!1).option("--save-logs","Save logs to a file",!1).option("--verbose","Show verbose debug logs",!1).addHelpText("after",["","Examples:"," membrane push # Push to default workspace"," membrane push --force # Overwrite conflicts with local data",""].join(`
|
|
150
|
-
`)).action(async t=>{const n=t.watch?ha():()=>process.exit(0);gn(st.createElement(ns,{membraneCLIService:e,children:st.createElement(xh,{...t,onComplete:n})}))})}c(Rh,"setupPushCommand");class Ph{static{c(this,"BaseRunner")}constructor(e){if(this.options=e,this.fsPaths=Ws(),e&&typeof e=="object"){const t=e;"client"in t&&t.client&&(this.client=t.client),"workspace"in t&&(this.workspace=t.workspace)}}client;workspace;fsPaths}function R(s,e,t,n,r){if(typeof e=="function"?s!==e||!0:!e.has(s))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(s,t),t}c(R,"__classPrivateFieldSet");function S(s,e,t,n){if(t==="a"&&!n)throw new TypeError("Private accessor was defined without a getter");if(typeof e=="function"?s!==e||!n:!e.has(s))throw new TypeError("Cannot read private member from an object whose class did not declare it");return t==="m"?n:t==="a"?n.call(s):n?n.value:e.get(s)}c(S,"__classPrivateFieldGet");let fa=c(function(){const{crypto:s}=globalThis;if(s?.randomUUID)return fa=s.randomUUID.bind(s),s.randomUUID();const e=new Uint8Array(1),t=s?()=>s.getRandomValues(e)[0]:()=>Math.random()*255&255;return"10000000-1000-4000-8000-100000000000".replace(/[018]/g,n=>(+n^t()&15>>+n/4).toString(16))},"uuid4");function Yt(s){return typeof s=="object"&&s!==null&&("name"in s&&s.name==="AbortError"||"message"in s&&String(s.message).includes("FetchRequestCanceledException"))}c(Yt,"isAbortError");const Pr=c(s=>{if(s instanceof Error)return s;if(typeof s=="object"&&s!==null){try{if(Object.prototype.toString.call(s)==="[object Error]"){const e=new Error(s.message,s.cause?{cause:s.cause}:{});return s.stack&&(e.stack=s.stack),s.cause&&!e.cause&&(e.cause=s.cause),s.name&&(e.name=s.name),e}}catch{}try{return new Error(JSON.stringify(s))}catch{}}return new Error(s)},"castToError");class L extends Error{static{c(this,"AnthropicError")}}class re extends L{static{c(this,"APIError")}constructor(e,t,n,r){super(`${re.makeMessage(e,t,n)}`),this.status=e,this.headers=r,this.requestID=r?.get("request-id"),this.error=t}static makeMessage(e,t,n){const r=t?.message?typeof t.message=="string"?t.message:JSON.stringify(t.message):t?JSON.stringify(t):n;return e&&r?`${e} ${r}`:e?`${e} status code (no body)`:r||"(no status code or body)"}static generate(e,t,n,r){if(!e||!r)return new is({message:n,cause:Pr(t)});const i=t;return e===400?new pa(e,i,n,r):e===401?new ma(e,i,n,r):e===403?new ga(e,i,n,r):e===404?new ya(e,i,n,r):e===409?new wa(e,i,n,r):e===422?new ba(e,i,n,r):e===429?new Sa(e,i,n,r):e>=500?new va(e,i,n,r):new re(e,i,n,r)}}class ve extends re{static{c(this,"APIUserAbortError")}constructor({message:e}={}){super(void 0,void 0,e||"Request was aborted.",void 0)}}class is extends re{static{c(this,"APIConnectionError")}constructor({message:e,cause:t}){super(void 0,void 0,e||"Connection error.",void 0),t&&(this.cause=t)}}class da extends is{static{c(this,"APIConnectionTimeoutError")}constructor({message:e}={}){super({message:e??"Request timed out."})}}class pa extends re{static{c(this,"BadRequestError")}}class ma extends re{static{c(this,"AuthenticationError")}}class ga extends re{static{c(this,"PermissionDeniedError")}}class ya extends re{static{c(this,"NotFoundError")}}class wa extends re{static{c(this,"ConflictError")}}class ba extends re{static{c(this,"UnprocessableEntityError")}}class Sa extends re{static{c(this,"RateLimitError")}}class va extends re{static{c(this,"InternalServerError")}}const Lh=/^[a-z][a-z0-9+.-]*:/i,Dh=c(s=>Lh.test(s),"isAbsoluteURL");let Lr=c(s=>(Lr=Array.isArray,Lr(s)),"isArray"),Ca=Lr;function ka(s){return typeof s!="object"?{}:s??{}}c(ka,"maybeObj");function jh(s){if(!s)return!0;for(const e in s)return!1;return!0}c(jh,"isEmptyObj");function Fh(s,e){return Object.prototype.hasOwnProperty.call(s,e)}c(Fh,"hasOwn");const Kh=c((s,e)=>{if(typeof e!="number"||!Number.isInteger(e))throw new L(`${s} must be an integer`);if(e<0)throw new L(`${s} must be a positive integer`);return e},"validatePositiveInteger"),_a=c(s=>{try{return JSON.parse(s)}catch{return}},"safeJSON"),Bh=c(s=>new Promise(e=>setTimeout(e,s)),"sleep"),Et="0.62.0",qh=c(()=>typeof window<"u"&&typeof window.document<"u"&&typeof navigator<"u","isRunningInBrowser");function Uh(){return typeof Deno<"u"&&Deno.build!=null?"deno":typeof EdgeRuntime<"u"?"edge":Object.prototype.toString.call(typeof globalThis.process<"u"?globalThis.process:0)==="[object process]"?"node":"unknown"}c(Uh,"getDetectedPlatform");const Wh=c(()=>{const s=Uh();if(s==="deno")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":Et,"X-Stainless-OS":Ea(Deno.build.os),"X-Stainless-Arch":Ta(Deno.build.arch),"X-Stainless-Runtime":"deno","X-Stainless-Runtime-Version":typeof Deno.version=="string"?Deno.version:Deno.version?.deno??"unknown"};if(typeof EdgeRuntime<"u")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":Et,"X-Stainless-OS":"Unknown","X-Stainless-Arch":`other:${EdgeRuntime}`,"X-Stainless-Runtime":"edge","X-Stainless-Runtime-Version":globalThis.process.version};if(s==="node")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":Et,"X-Stainless-OS":Ea(globalThis.process.platform??"unknown"),"X-Stainless-Arch":Ta(globalThis.process.arch??"unknown"),"X-Stainless-Runtime":"node","X-Stainless-Runtime-Version":globalThis.process.version??"unknown"};const e=Jh();return e?{"X-Stainless-Lang":"js","X-Stainless-Package-Version":Et,"X-Stainless-OS":"Unknown","X-Stainless-Arch":"unknown","X-Stainless-Runtime":`browser:${e.browser}`,"X-Stainless-Runtime-Version":e.version}:{"X-Stainless-Lang":"js","X-Stainless-Package-Version":Et,"X-Stainless-OS":"Unknown","X-Stainless-Arch":"unknown","X-Stainless-Runtime":"unknown","X-Stainless-Runtime-Version":"unknown"}},"getPlatformProperties");function Jh(){if(typeof navigator>"u"||!navigator)return null;const s=[{key:"edge",pattern:/Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"ie",pattern:/MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"ie",pattern:/Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"chrome",pattern:/Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"firefox",pattern:/Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"safari",pattern:/(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/}];for(const{key:e,pattern:t}of s){const n=t.exec(navigator.userAgent);if(n){const r=n[1]||0,i=n[2]||0,o=n[3]||0;return{browser:e,version:`${r}.${i}.${o}`}}}return null}c(Jh,"getBrowserInfo");const Ta=c(s=>s==="x32"?"x32":s==="x86_64"||s==="x64"?"x64":s==="arm"?"arm":s==="aarch64"||s==="arm64"?"arm64":s?`other:${s}`:"unknown","normalizeArch"),Ea=c(s=>(s=s.toLowerCase(),s.includes("ios")?"iOS":s==="android"?"Android":s==="darwin"?"MacOS":s==="win32"?"Windows":s==="freebsd"?"FreeBSD":s==="openbsd"?"OpenBSD":s==="linux"?"Linux":s?`Other:${s}`:"Unknown"),"normalizePlatform");let Aa;const Hh=c(()=>Aa??(Aa=Wh()),"getPlatformHeaders");function Vh(){if(typeof fetch<"u")return fetch;throw new Error("`fetch` is not defined as a global; Either pass `fetch` to the client, `new Anthropic({ fetch })` or polyfill the global, `globalThis.fetch = fetch`")}c(Vh,"getDefaultFetch");function Oa(...s){const e=globalThis.ReadableStream;if(typeof e>"u")throw new Error("`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`");return new e(...s)}c(Oa,"makeReadableStream");function Ia(s){let e=Symbol.asyncIterator in s?s[Symbol.asyncIterator]():s[Symbol.iterator]();return Oa({start(){},async pull(t){const{done:n,value:r}=await e.next();n?t.close():t.enqueue(r)},async cancel(){await e.return?.()}})}c(Ia,"ReadableStreamFrom");function Dr(s){if(s[Symbol.asyncIterator])return s;const e=s.getReader();return{async next(){try{const t=await e.read();return t?.done&&e.releaseLock(),t}catch(t){throw e.releaseLock(),t}},async return(){const t=e.cancel();return e.releaseLock(),await t,{done:!0,value:void 0}},[Symbol.asyncIterator](){return this}}}c(Dr,"ReadableStreamToAsyncIterable");async function Gh(s){if(s===null||typeof s!="object")return;if(s[Symbol.asyncIterator]){await s[Symbol.asyncIterator]().return?.();return}const e=s.getReader(),t=e.cancel();e.releaseLock(),await t}c(Gh,"CancelReadableStream");const zh=c(({headers:s,body:e})=>({bodyHeaders:{"content-type":"application/json"},body:JSON.stringify(e)}),"FallbackEncoder");function Yh(s){let e=0;for(const r of s)e+=r.length;const t=new Uint8Array(e);let n=0;for(const r of s)t.set(r,n),n+=r.length;return t}c(Yh,"concatBytes");let $a;function jr(s){let e;return($a??(e=new globalThis.TextEncoder,$a=e.encode.bind(e)))(s)}c(jr,"encodeUTF8");let Na;function xa(s){let e;return(Na??(e=new globalThis.TextDecoder,Na=e.decode.bind(e)))(s)}c(xa,"decodeUTF8");var fe,de;class Xt{static{c(this,"LineDecoder")}constructor(){fe.set(this,void 0),de.set(this,void 0),R(this,fe,new Uint8Array),R(this,de,null)}decode(e){if(e==null)return[];const t=e instanceof ArrayBuffer?new Uint8Array(e):typeof e=="string"?jr(e):e;R(this,fe,Yh([S(this,fe,"f"),t]));const n=[];let r;for(;(r=Xh(S(this,fe,"f"),S(this,de,"f")))!=null;){if(r.carriage&&S(this,de,"f")==null){R(this,de,r.index);continue}if(S(this,de,"f")!=null&&(r.index!==S(this,de,"f")+1||r.carriage)){n.push(xa(S(this,fe,"f").subarray(0,S(this,de,"f")-1))),R(this,fe,S(this,fe,"f").subarray(S(this,de,"f"))),R(this,de,null);continue}const i=S(this,de,"f")!==null?r.preceding-1:r.preceding,o=xa(S(this,fe,"f").subarray(0,i));n.push(o),R(this,fe,S(this,fe,"f").subarray(r.index)),R(this,de,null)}return n}flush(){return S(this,fe,"f").length?this.decode(`
|
|
148
|
+
`)).action(async()=>{try{X.header("Opening Workspace in Browser"),X.info("Loading configuration...");const e=On();if(!e)throw new Error("No configuration found. Please set MEMBRANE_WORKSPACE_KEY and MEMBRANE_WORKSPACE_SECRET environment variables, or run `membrane init` first.");if(!e.workspaceKey||!e.workspaceSecret)throw new Error("Missing workspace credentials");X.info("Retrieving workspace ID...");const n=`https://console.integration.app/w/${await Bi(process.cwd())}`;X.info(`Opening ${n}...`);const{default:r}=await import("open");await r(n),X.success("Browser opened successfully")}catch(e){e instanceof Error&&(X.error(e.message),process.exit(1)),X.error("An unknown error occurred"),process.exit(1)}})}c(Oh,"setupOpenCommand");function Ih(s){return g(Ir,{children:g($h,{options:s})})}c(Ih,"Pull");function $h({options:s}){const{logs:e,state:t,conflicts:n,pull:r}=Se();Ve(()=>{r(s)},[]);const i=t===x.CONFLICTS;return E(v,{flexDirection:"column",children:[e.slice().map((o,a)=>g(C,{color:ss(o.type),children:o.message},o.timestamp+a)),i&&E(Ns,{children:[E(C,{color:"yellow",bold:!0,children:["Found ",n.length," conflicts with remote:"]}),g(Mr,{isExpanded:!s.watch,showControls:!1}),g(C,{color:"red",children:"Out of sync with remote, use --force to overwrite conflict changes"})]}),t===x.SYNCED&&g(Nr,{})]})}c($h,"PullActivity");function ha(){const s=setInterval(()=>{},3e4),e=c(()=>{clearInterval(s)},"cleanup");return process.on("SIGINT",()=>{e(),process.exit(0)}),process.on("SIGTERM",()=>{e(),process.exit(0)}),process.on("exit",e),()=>{}}c(ha,"getWatchModeCallback");function Nh(s,e){s.command("pull").description("Pull workspace data from specified workspace").option("--force","Overwrite conflicts with remote data",!1).option("--watch","Watch for changes and pull automatically",!1).option("--all-connectors","Include public connectors in export - to push to the self-hosted instance",!1).option("--save-logs","Save logs to a file",!1).option("--verbose","Show verbose debug logs",!1).addHelpText("after",["","Examples:"," membrane pull # Pull from default workspace"," membrane pull --force # Overwrite conflicts with remote data"," membrane pull --all-connectors # Pull all connectors"," membrane pull --watch # Watch for changes and pull automatically",""].join(`
|
|
149
|
+
`)).action(async t=>{const n=t.watch?ha():()=>process.exit(0);gn(st.createElement(ns,{membraneCLIService:e,children:st.createElement(Ih,{...t,onComplete:n})}))})}c(Nh,"setupPullCommand");function xh(s){return g(Ir,{children:g(Mh,{options:s})})}c(xh,"Push");function Mh({options:s}){const{logs:e,state:t,conflicts:n,push:r}=Se();Ve(()=>{r(s)},[]);const i=t===x.CONFLICTS;return E(v,{flexDirection:"column",children:[e.slice().map((o,a)=>g(C,{color:ss(o.type),children:o.message},o.timestamp+a)),i&&E(Ns,{children:[E(C,{color:"yellow",bold:!0,children:["Found ",n.length," conflicts with remote:"]}),g(Mr,{isExpanded:!s.watch,showControls:!1}),g(C,{color:"red",children:"Out of sync with remote, use --force to overwrite conflict changes"})]}),t===x.SYNCED&&g(Nr,{})]})}c(Mh,"PushActivity");function Rh(s,e){s.command("push").description("Push workspace data to specified workspace").option("--force","Overwrite conflicts with local data",!1).option("--watch","Watch for changes and push automatically",!1).option("--save-logs","Save logs to a file",!1).option("--verbose","Show verbose debug logs",!1).addHelpText("after",["","Examples:"," membrane push # Push to default workspace"," membrane push --force # Overwrite conflicts with local data",""].join(`
|
|
150
|
+
`)).action(async t=>{const n=t.watch?ha():()=>process.exit(0);gn(st.createElement(ns,{membraneCLIService:e,children:st.createElement(xh,{...t,onComplete:n})}))})}c(Rh,"setupPushCommand");class Ph{static{c(this,"BaseRunner")}constructor(e={}){if(this.options=e,this.fsPaths=Ws(),e&&typeof e=="object"){const t=e;"client"in t&&t.client&&(this.client=t.client),"workspace"in t&&(this.workspace=t.workspace)}}client;workspace;fsPaths}function R(s,e,t,n,r){if(typeof e=="function"?s!==e||!0:!e.has(s))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(s,t),t}c(R,"__classPrivateFieldSet");function S(s,e,t,n){if(t==="a"&&!n)throw new TypeError("Private accessor was defined without a getter");if(typeof e=="function"?s!==e||!n:!e.has(s))throw new TypeError("Cannot read private member from an object whose class did not declare it");return t==="m"?n:t==="a"?n.call(s):n?n.value:e.get(s)}c(S,"__classPrivateFieldGet");let fa=c(function(){const{crypto:s}=globalThis;if(s?.randomUUID)return fa=s.randomUUID.bind(s),s.randomUUID();const e=new Uint8Array(1),t=s?()=>s.getRandomValues(e)[0]:()=>Math.random()*255&255;return"10000000-1000-4000-8000-100000000000".replace(/[018]/g,n=>(+n^t()&15>>+n/4).toString(16))},"uuid4");function Yt(s){return typeof s=="object"&&s!==null&&("name"in s&&s.name==="AbortError"||"message"in s&&String(s.message).includes("FetchRequestCanceledException"))}c(Yt,"isAbortError");const Pr=c(s=>{if(s instanceof Error)return s;if(typeof s=="object"&&s!==null){try{if(Object.prototype.toString.call(s)==="[object Error]"){const e=new Error(s.message,s.cause?{cause:s.cause}:{});return s.stack&&(e.stack=s.stack),s.cause&&!e.cause&&(e.cause=s.cause),s.name&&(e.name=s.name),e}}catch{}try{return new Error(JSON.stringify(s))}catch{}}return new Error(s)},"castToError");class L extends Error{static{c(this,"AnthropicError")}}class re extends L{static{c(this,"APIError")}constructor(e,t,n,r){super(`${re.makeMessage(e,t,n)}`),this.status=e,this.headers=r,this.requestID=r?.get("request-id"),this.error=t}static makeMessage(e,t,n){const r=t?.message?typeof t.message=="string"?t.message:JSON.stringify(t.message):t?JSON.stringify(t):n;return e&&r?`${e} ${r}`:e?`${e} status code (no body)`:r||"(no status code or body)"}static generate(e,t,n,r){if(!e||!r)return new is({message:n,cause:Pr(t)});const i=t;return e===400?new pa(e,i,n,r):e===401?new ma(e,i,n,r):e===403?new ga(e,i,n,r):e===404?new ya(e,i,n,r):e===409?new wa(e,i,n,r):e===422?new ba(e,i,n,r):e===429?new Sa(e,i,n,r):e>=500?new va(e,i,n,r):new re(e,i,n,r)}}class ve extends re{static{c(this,"APIUserAbortError")}constructor({message:e}={}){super(void 0,void 0,e||"Request was aborted.",void 0)}}class is extends re{static{c(this,"APIConnectionError")}constructor({message:e,cause:t}){super(void 0,void 0,e||"Connection error.",void 0),t&&(this.cause=t)}}class da extends is{static{c(this,"APIConnectionTimeoutError")}constructor({message:e}={}){super({message:e??"Request timed out."})}}class pa extends re{static{c(this,"BadRequestError")}}class ma extends re{static{c(this,"AuthenticationError")}}class ga extends re{static{c(this,"PermissionDeniedError")}}class ya extends re{static{c(this,"NotFoundError")}}class wa extends re{static{c(this,"ConflictError")}}class ba extends re{static{c(this,"UnprocessableEntityError")}}class Sa extends re{static{c(this,"RateLimitError")}}class va extends re{static{c(this,"InternalServerError")}}const Lh=/^[a-z][a-z0-9+.-]*:/i,Dh=c(s=>Lh.test(s),"isAbsoluteURL");let Lr=c(s=>(Lr=Array.isArray,Lr(s)),"isArray"),Ca=Lr;function ka(s){return typeof s!="object"?{}:s??{}}c(ka,"maybeObj");function jh(s){if(!s)return!0;for(const e in s)return!1;return!0}c(jh,"isEmptyObj");function Fh(s,e){return Object.prototype.hasOwnProperty.call(s,e)}c(Fh,"hasOwn");const Kh=c((s,e)=>{if(typeof e!="number"||!Number.isInteger(e))throw new L(`${s} must be an integer`);if(e<0)throw new L(`${s} must be a positive integer`);return e},"validatePositiveInteger"),_a=c(s=>{try{return JSON.parse(s)}catch{return}},"safeJSON"),Bh=c(s=>new Promise(e=>setTimeout(e,s)),"sleep"),Et="0.62.0",qh=c(()=>typeof window<"u"&&typeof window.document<"u"&&typeof navigator<"u","isRunningInBrowser");function Uh(){return typeof Deno<"u"&&Deno.build!=null?"deno":typeof EdgeRuntime<"u"?"edge":Object.prototype.toString.call(typeof globalThis.process<"u"?globalThis.process:0)==="[object process]"?"node":"unknown"}c(Uh,"getDetectedPlatform");const Wh=c(()=>{const s=Uh();if(s==="deno")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":Et,"X-Stainless-OS":Ea(Deno.build.os),"X-Stainless-Arch":Ta(Deno.build.arch),"X-Stainless-Runtime":"deno","X-Stainless-Runtime-Version":typeof Deno.version=="string"?Deno.version:Deno.version?.deno??"unknown"};if(typeof EdgeRuntime<"u")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":Et,"X-Stainless-OS":"Unknown","X-Stainless-Arch":`other:${EdgeRuntime}`,"X-Stainless-Runtime":"edge","X-Stainless-Runtime-Version":globalThis.process.version};if(s==="node")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":Et,"X-Stainless-OS":Ea(globalThis.process.platform??"unknown"),"X-Stainless-Arch":Ta(globalThis.process.arch??"unknown"),"X-Stainless-Runtime":"node","X-Stainless-Runtime-Version":globalThis.process.version??"unknown"};const e=Jh();return e?{"X-Stainless-Lang":"js","X-Stainless-Package-Version":Et,"X-Stainless-OS":"Unknown","X-Stainless-Arch":"unknown","X-Stainless-Runtime":`browser:${e.browser}`,"X-Stainless-Runtime-Version":e.version}:{"X-Stainless-Lang":"js","X-Stainless-Package-Version":Et,"X-Stainless-OS":"Unknown","X-Stainless-Arch":"unknown","X-Stainless-Runtime":"unknown","X-Stainless-Runtime-Version":"unknown"}},"getPlatformProperties");function Jh(){if(typeof navigator>"u"||!navigator)return null;const s=[{key:"edge",pattern:/Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"ie",pattern:/MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"ie",pattern:/Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"chrome",pattern:/Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"firefox",pattern:/Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"safari",pattern:/(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/}];for(const{key:e,pattern:t}of s){const n=t.exec(navigator.userAgent);if(n){const r=n[1]||0,i=n[2]||0,o=n[3]||0;return{browser:e,version:`${r}.${i}.${o}`}}}return null}c(Jh,"getBrowserInfo");const Ta=c(s=>s==="x32"?"x32":s==="x86_64"||s==="x64"?"x64":s==="arm"?"arm":s==="aarch64"||s==="arm64"?"arm64":s?`other:${s}`:"unknown","normalizeArch"),Ea=c(s=>(s=s.toLowerCase(),s.includes("ios")?"iOS":s==="android"?"Android":s==="darwin"?"MacOS":s==="win32"?"Windows":s==="freebsd"?"FreeBSD":s==="openbsd"?"OpenBSD":s==="linux"?"Linux":s?`Other:${s}`:"Unknown"),"normalizePlatform");let Aa;const Hh=c(()=>Aa??(Aa=Wh()),"getPlatformHeaders");function Vh(){if(typeof fetch<"u")return fetch;throw new Error("`fetch` is not defined as a global; Either pass `fetch` to the client, `new Anthropic({ fetch })` or polyfill the global, `globalThis.fetch = fetch`")}c(Vh,"getDefaultFetch");function Oa(...s){const e=globalThis.ReadableStream;if(typeof e>"u")throw new Error("`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`");return new e(...s)}c(Oa,"makeReadableStream");function Ia(s){let e=Symbol.asyncIterator in s?s[Symbol.asyncIterator]():s[Symbol.iterator]();return Oa({start(){},async pull(t){const{done:n,value:r}=await e.next();n?t.close():t.enqueue(r)},async cancel(){await e.return?.()}})}c(Ia,"ReadableStreamFrom");function Dr(s){if(s[Symbol.asyncIterator])return s;const e=s.getReader();return{async next(){try{const t=await e.read();return t?.done&&e.releaseLock(),t}catch(t){throw e.releaseLock(),t}},async return(){const t=e.cancel();return e.releaseLock(),await t,{done:!0,value:void 0}},[Symbol.asyncIterator](){return this}}}c(Dr,"ReadableStreamToAsyncIterable");async function Gh(s){if(s===null||typeof s!="object")return;if(s[Symbol.asyncIterator]){await s[Symbol.asyncIterator]().return?.();return}const e=s.getReader(),t=e.cancel();e.releaseLock(),await t}c(Gh,"CancelReadableStream");const zh=c(({headers:s,body:e})=>({bodyHeaders:{"content-type":"application/json"},body:JSON.stringify(e)}),"FallbackEncoder");function Yh(s){let e=0;for(const r of s)e+=r.length;const t=new Uint8Array(e);let n=0;for(const r of s)t.set(r,n),n+=r.length;return t}c(Yh,"concatBytes");let $a;function jr(s){let e;return($a??(e=new globalThis.TextEncoder,$a=e.encode.bind(e)))(s)}c(jr,"encodeUTF8");let Na;function xa(s){let e;return(Na??(e=new globalThis.TextDecoder,Na=e.decode.bind(e)))(s)}c(xa,"decodeUTF8");var fe,de;class Xt{static{c(this,"LineDecoder")}constructor(){fe.set(this,void 0),de.set(this,void 0),R(this,fe,new Uint8Array),R(this,de,null)}decode(e){if(e==null)return[];const t=e instanceof ArrayBuffer?new Uint8Array(e):typeof e=="string"?jr(e):e;R(this,fe,Yh([S(this,fe,"f"),t]));const n=[];let r;for(;(r=Xh(S(this,fe,"f"),S(this,de,"f")))!=null;){if(r.carriage&&S(this,de,"f")==null){R(this,de,r.index);continue}if(S(this,de,"f")!=null&&(r.index!==S(this,de,"f")+1||r.carriage)){n.push(xa(S(this,fe,"f").subarray(0,S(this,de,"f")-1))),R(this,fe,S(this,fe,"f").subarray(S(this,de,"f"))),R(this,de,null);continue}const i=S(this,de,"f")!==null?r.preceding-1:r.preceding,o=xa(S(this,fe,"f").subarray(0,i));n.push(o),R(this,fe,S(this,fe,"f").subarray(r.index)),R(this,de,null)}return n}flush(){return S(this,fe,"f").length?this.decode(`
|
|
151
151
|
`):[]}}fe=new WeakMap,de=new WeakMap,Xt.NEWLINE_CHARS=new Set([`
|
|
152
152
|
`,"\r"]),Xt.NEWLINE_REGEXP=/\r\n|[\n\r]/g;function Xh(s,e){for(let r=e??0;r<s.length;r++){if(s[r]===10)return{preceding:r,index:r+1,carriage:!1};if(s[r]===13)return{preceding:r,index:r+1,carriage:!0}}return null}c(Xh,"findNewlineIndex");function Qh(s){for(let n=0;n<s.length-1;n++){if(s[n]===10&&s[n+1]===10||s[n]===13&&s[n+1]===13)return n+2;if(s[n]===13&&s[n+1]===10&&n+3<s.length&&s[n+2]===13&&s[n+3]===10)return n+4}return-1}c(Qh,"findDoubleNewlineIndex");const os={off:0,error:200,warn:300,info:400,debug:500},Ma=c((s,e,t)=>{if(s){if(Fh(os,s))return s;ie(t).warn(`${e} was set to ${JSON.stringify(s)}, expected one of ${JSON.stringify(Object.keys(os))}`)}},"parseLogLevel");function Qt(){}c(Qt,"noop");function as(s,e,t){return!e||os[s]>os[t]?Qt:e[s].bind(e)}c(as,"makeLogFn");const Zh={error:Qt,warn:Qt,info:Qt,debug:Qt};let Ra=new WeakMap;function ie(s){const e=s.logger,t=s.logLevel??"off";if(!e)return Zh;const n=Ra.get(e);if(n&&n[0]===t)return n[1];const r={error:as("error",e,t),warn:as("warn",e,t),info:as("info",e,t),debug:as("debug",e,t)};return Ra.set(e,[t,r]),r}c(ie,"loggerFor");const et=c(s=>(s.options&&(s.options={...s.options},delete s.options.headers),s.headers&&(s.headers=Object.fromEntries((s.headers instanceof Headers?[...s.headers]:Object.entries(s.headers)).map(([e,t])=>[e,e.toLowerCase()==="x-api-key"||e.toLowerCase()==="authorization"||e.toLowerCase()==="cookie"||e.toLowerCase()==="set-cookie"?"***":t]))),"retryOfRequestLogID"in s&&(s.retryOfRequestLogID&&(s.retryOf=s.retryOfRequestLogID),delete s.retryOfRequestLogID),s),"formatRequestDetails");var Zt;class Ee{static{c(this,"Stream")}constructor(e,t,n){this.iterator=e,Zt.set(this,void 0),this.controller=t,R(this,Zt,n)}static fromSSEResponse(e,t,n){let r=!1;const i=n?ie(n):console;async function*o(){if(r)throw new L("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");r=!0;let a=!1;try{for await(const l of ef(e,t)){if(l.event==="completion")try{yield JSON.parse(l.data)}catch(u){throw i.error("Could not parse message into JSON:",l.data),i.error("From chunk:",l.raw),u}if(l.event==="message_start"||l.event==="message_delta"||l.event==="message_stop"||l.event==="content_block_start"||l.event==="content_block_delta"||l.event==="content_block_stop")try{yield JSON.parse(l.data)}catch(u){throw i.error("Could not parse message into JSON:",l.data),i.error("From chunk:",l.raw),u}if(l.event!=="ping"&&l.event==="error")throw new re(void 0,_a(l.data)??l.data,void 0,e.headers)}a=!0}catch(l){if(Yt(l))return;throw l}finally{a||t.abort()}}return c(o,"iterator"),new Ee(o,t,n)}static fromReadableStream(e,t,n){let r=!1;async function*i(){const a=new Xt,l=Dr(e);for await(const u of l)for(const h of a.decode(u))yield h;for(const u of a.flush())yield u}c(i,"iterLines");async function*o(){if(r)throw new L("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");r=!0;let a=!1;try{for await(const l of i())a||l&&(yield JSON.parse(l));a=!0}catch(l){if(Yt(l))return;throw l}finally{a||t.abort()}}return c(o,"iterator"),new Ee(o,t,n)}[(Zt=new WeakMap,Symbol.asyncIterator)](){return this.iterator()}tee(){const e=[],t=[],n=this.iterator(),r=c(i=>({next:c(()=>{if(i.length===0){const o=n.next();e.push(o),t.push(o)}return i.shift()},"next")}),"teeIterator");return[new Ee(()=>r(e),this.controller,S(this,Zt,"f")),new Ee(()=>r(t),this.controller,S(this,Zt,"f"))]}toReadableStream(){const e=this;let t;return Oa({async start(){t=e[Symbol.asyncIterator]()},async pull(n){try{const{value:r,done:i}=await t.next();if(i)return n.close();const o=jr(JSON.stringify(r)+`
|
|
153
153
|
`);n.enqueue(o)}catch(r){n.error(r)}},async cancel(){await t.return?.()}})}}async function*ef(s,e){if(!s.body)throw e.abort(),typeof globalThis.navigator<"u"&&globalThis.navigator.product==="ReactNative"?new L("The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api"):new L("Attempted to iterate over a response with no body");const t=new nf,n=new Xt,r=Dr(s.body);for await(const i of tf(r))for(const o of n.decode(i)){const a=t.decode(o);a&&(yield a)}for(const i of n.flush()){const o=t.decode(i);o&&(yield o)}}c(ef,"_iterSSEMessages");async function*tf(s){let e=new Uint8Array;for await(const t of s){if(t==null)continue;const n=t instanceof ArrayBuffer?new Uint8Array(t):typeof t=="string"?jr(t):t;let r=new Uint8Array(e.length+n.length);r.set(e),r.set(n,e.length),e=r;let i;for(;(i=Qh(e))!==-1;)yield e.slice(0,i),e=e.slice(i)}e.length>0&&(yield e)}c(tf,"iterSSEChunks");class nf{static{c(this,"SSEDecoder")}constructor(){this.event=null,this.data=[],this.chunks=[]}decode(e){if(e.endsWith("\r")&&(e=e.substring(0,e.length-1)),!e){if(!this.event&&!this.data.length)return null;const i={event:this.event,data:this.data.join(`
|
|
@@ -164,7 +164,7 @@ If you understand the risks and have appropriate mitigations in place,
|
|
|
164
164
|
you can set the \`dangerouslyAllowBrowser\` option to \`true\`, e.g.,
|
|
165
165
|
|
|
166
166
|
new Anthropic({ apiKey, dangerouslyAllowBrowser: true });
|
|
167
|
-
`);this.baseURL=i.baseURL,this.timeout=i.timeout??Zr.DEFAULT_TIMEOUT,this.logger=i.logger??console;const o="warn";this.logLevel=o,this.logLevel=Ma(i.logLevel,"ClientOptions.logLevel",this)??Ma(ks("ANTHROPIC_LOG"),"process.env['ANTHROPIC_LOG']",this)??o,this.fetchOptions=i.fetchOptions,this.maxRetries=i.maxRetries??2,this.fetch=i.fetch??Vh(),R(this,_s,zh),this._options=i,this.apiKey=t,this.authToken=n}withOptions(e){return new this.constructor({...this._options,baseURL:this.baseURL,maxRetries:this.maxRetries,timeout:this.timeout,logger:this.logger,logLevel:this.logLevel,fetch:this.fetch,fetchOptions:this.fetchOptions,apiKey:this.apiKey,authToken:this.authToken,...e})}defaultQuery(){return this._options.defaultQuery}validateHeaders({values:e,nulls:t}){if(!(this.apiKey&&e.get("x-api-key"))&&!t.has("x-api-key")&&!(this.authToken&&e.get("authorization"))&&!t.has("authorization"))throw new Error('Could not resolve authentication method. Expected either apiKey or authToken to be set. Or for one of the "X-Api-Key" or "Authorization" headers to be explicitly omitted')}async authHeaders(e){return V([await this.apiKeyAuth(e),await this.bearerAuth(e)])}async apiKeyAuth(e){if(this.apiKey!=null)return V([{"X-Api-Key":this.apiKey}])}async bearerAuth(e){if(this.authToken!=null)return V([{Authorization:`Bearer ${this.authToken}`}])}stringifyQuery(e){return Object.entries(e).filter(([t,n])=>typeof n<"u").map(([t,n])=>{if(typeof n=="string"||typeof n=="number"||typeof n=="boolean")return`${encodeURIComponent(t)}=${encodeURIComponent(n)}`;if(n===null)return`${encodeURIComponent(t)}=`;throw new L(`Cannot stringify type ${typeof n}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`)}).join("&")}getUserAgent(){return`${this.constructor.name}/JS ${Et}`}defaultIdempotencyKey(){return`stainless-node-retry-${fa()}`}makeStatusError(e,t,n,r){return re.generate(e,t,n,r)}buildURL(e,t,n){const r=!S(this,Qr,"m",cc).call(this)&&n||this.baseURL,i=Dh(e)?new URL(e):new URL(r+(r.endsWith("/")&&e.startsWith("/")?e.slice(1):e)),o=this.defaultQuery();return jh(o)||(t={...o,...t}),typeof t=="object"&&t&&!Array.isArray(t)&&(i.search=this.stringifyQuery(t)),i.toString()}_calculateNonstreamingTimeout(e){if(3600*e/128e3>600)throw new L("Streaming is required for operations that may take longer than 10 minutes. See https://github.com/anthropics/anthropic-sdk-typescript#streaming-responses for more details");return 600*1e3}async prepareOptions(e){}async prepareRequest(e,{url:t,options:n}){}get(e,t){return this.methodRequest("get",e,t)}post(e,t){return this.methodRequest("post",e,t)}patch(e,t){return this.methodRequest("patch",e,t)}put(e,t){return this.methodRequest("put",e,t)}delete(e,t){return this.methodRequest("delete",e,t)}methodRequest(e,t,n){return this.request(Promise.resolve(n).then(r=>({method:e,path:t,...r})))}request(e,t=null){return new As(this,this.makeRequest(e,t,void 0))}async makeRequest(e,t,n){const r=await e,i=r.maxRetries??this.maxRetries;t==null&&(t=i),await this.prepareOptions(r);const{req:o,url:a,timeout:l}=await this.buildRequest(r,{retryCount:i-t});await this.prepareRequest(o,{url:a,options:r});const u="log_"+(Math.random()*(1<<24)|0).toString(16).padStart(6,"0"),h=n===void 0?"":`, retryOf: ${n}`,f=Date.now();if(ie(this).debug(`[${u}] sending request`,et({retryOfRequestLogID:n,method:r.method,url:a,options:r,headers:o.headers})),r.signal?.aborted)throw new ve;const p=new AbortController,m=await this.fetchWithTimeout(a,o,l,p).catch(Pr),y=Date.now();if(m instanceof globalThis.Error){const k=`retrying, ${t} attempts remaining`;if(r.signal?.aborted)throw new ve;const _=Yt(m)||/timed? ?out/i.test(String(m)+("cause"in m?String(m.cause):""));if(t)return ie(this).info(`[${u}] connection ${_?"timed out":"failed"} - ${k}`),ie(this).debug(`[${u}] connection ${_?"timed out":"failed"} (${k})`,et({retryOfRequestLogID:n,url:a,durationMs:y-f,message:m.message})),this.retryRequest(r,t,n??u);throw ie(this).info(`[${u}] connection ${_?"timed out":"failed"} - error; no more retries left`),ie(this).debug(`[${u}] connection ${_?"timed out":"failed"} (error; no more retries left)`,et({retryOfRequestLogID:n,url:a,durationMs:y-f,message:m.message})),_?new da:new is({cause:m})}const d=[...m.headers.entries()].filter(([k])=>k==="request-id").map(([k,_])=>", "+k+": "+JSON.stringify(_)).join(""),w=`[${u}${h}${d}] ${o.method} ${a} ${m.ok?"succeeded":"failed"} with status ${m.status} in ${y-f}ms`;if(!m.ok){const k=await this.shouldRetry(m);if(t&&k){const K=`retrying, ${t} attempts remaining`;return await Gh(m.body),ie(this).info(`${w} - ${K}`),ie(this).debug(`[${u}] response error (${K})`,et({retryOfRequestLogID:n,url:m.url,status:m.status,headers:m.headers,durationMs:y-f})),this.retryRequest(r,t,n??u,m.headers)}const _=k?"error; no more retries left":"error; not retryable";ie(this).info(`${w} - ${_}`);const O=await m.text().catch(K=>Pr(K).message),A=_a(O),$=A?void 0:O;throw ie(this).debug(`[${u}] response error (${_})`,et({retryOfRequestLogID:n,url:m.url,status:m.status,headers:m.headers,message:$,durationMs:Date.now()-f})),this.makeStatusError(m.status,A,$,m.headers)}return ie(this).info(w),ie(this).debug(`[${u}] response start`,et({retryOfRequestLogID:n,url:m.url,status:m.status,headers:m.headers,durationMs:y-f})),{response:m,options:r,controller:p,requestLogID:u,retryOfRequestLogID:n,startTime:f}}getAPIList(e,t,n){return this.requestAPIList(t,{method:"get",path:e,...n})}requestAPIList(e,t){const n=this.makeRequest(t,null,void 0);return new of(this,n,e)}async fetchWithTimeout(e,t,n,r){const{signal:i,method:o,...a}=t||{};i&&i.addEventListener("abort",()=>r.abort());const l=setTimeout(()=>r.abort(),n),u=globalThis.ReadableStream&&a.body instanceof globalThis.ReadableStream||typeof a.body=="object"&&a.body!==null&&Symbol.asyncIterator in a.body,h={signal:r.signal,...u?{duplex:"half"}:{},method:"GET",...a};o&&(h.method=o.toUpperCase());try{return await this.fetch.call(void 0,e,h)}finally{clearTimeout(l)}}async shouldRetry(e){const t=e.headers.get("x-should-retry");return t==="true"?!0:t==="false"?!1:e.status===408||e.status===409||e.status===429||e.status>=500}async retryRequest(e,t,n,r){let i;const o=r?.get("retry-after-ms");if(o){const l=parseFloat(o);Number.isNaN(l)||(i=l)}const a=r?.get("retry-after");if(a&&!i){const l=parseFloat(a);Number.isNaN(l)?i=Date.parse(a)-Date.now():i=l*1e3}if(!(i&&0<=i&&i<60*1e3)){const l=e.maxRetries??this.maxRetries;i=this.calculateDefaultRetryTimeoutMillis(t,l)}return await Bh(i),this.makeRequest(e,t-1,n)}calculateDefaultRetryTimeoutMillis(e,t){const i=t-e,o=Math.min(.5*Math.pow(2,i),8),a=1-Math.random()*.25;return o*a*1e3}calculateNonstreamingTimeout(e,t){if(36e5*e/128e3>6e5||t!=null&&e>t)throw new L("Streaming is required for operations that may take longer than 10 minutes. See https://github.com/anthropics/anthropic-sdk-typescript#long-requests for more details");return 6e5}async buildRequest(e,{retryCount:t=0}={}){const n={...e},{method:r,path:i,query:o,defaultBaseURL:a}=n,l=this.buildURL(i,o,a);"timeout"in n&&Kh("timeout",n.timeout),n.timeout=n.timeout??this.timeout;const{bodyHeaders:u,body:h}=this.buildBody({options:n}),f=await this.buildHeaders({options:e,method:r,bodyHeaders:u,retryCount:t});return{req:{method:r,headers:f,...n.signal&&{signal:n.signal},...globalThis.ReadableStream&&h instanceof globalThis.ReadableStream&&{duplex:"half"},...h&&{body:h},...this.fetchOptions??{},...n.fetchOptions??{}},url:l,timeout:n.timeout}}async buildHeaders({options:e,method:t,bodyHeaders:n,retryCount:r}){let i={};this.idempotencyHeader&&t!=="get"&&(e.idempotencyKey||(e.idempotencyKey=this.defaultIdempotencyKey()),i[this.idempotencyHeader]=e.idempotencyKey);const o=V([i,{Accept:"application/json","User-Agent":this.getUserAgent(),"X-Stainless-Retry-Count":String(r),...e.timeout?{"X-Stainless-Timeout":String(Math.trunc(e.timeout/1e3))}:{},...Hh(),...this._options.dangerouslyAllowBrowser?{"anthropic-dangerous-direct-browser-access":"true"}:void 0,"anthropic-version":"2023-06-01"},await this.authHeaders(e),this._options.defaultHeaders,n,e.headers]);return this.validateHeaders(o),o.values}buildBody({options:{body:e,headers:t}}){if(!e)return{bodyHeaders:void 0,body:void 0};const n=V([t]);return ArrayBuffer.isView(e)||e instanceof ArrayBuffer||e instanceof DataView||typeof e=="string"&&n.values.has("content-type")||globalThis.Blob&&e instanceof globalThis.Blob||e instanceof FormData||e instanceof URLSearchParams||globalThis.ReadableStream&&e instanceof globalThis.ReadableStream?{bodyHeaders:void 0,body:e}:typeof e=="object"&&(Symbol.asyncIterator in e||Symbol.iterator in e&&"next"in e&&typeof e.next=="function")?{bodyHeaders:void 0,body:Ia(e)}:S(this,_s,"f").call(this,{body:e,headers:n})}}Zr=Z,_s=new WeakMap,Qr=new WeakSet,cc=c(function(){return this.baseURL!=="https://api.anthropic.com"},"_BaseAnthropic_baseURLOverridden2"),Z.Anthropic=Zr,Z.HUMAN_PROMPT=Sf,Z.AI_PROMPT=vf,Z.DEFAULT_TIMEOUT=6e5,Z.AnthropicError=L,Z.APIError=re,Z.APIConnectionError=is,Z.APIConnectionTimeoutError=da,Z.APIUserAbortError=ve,Z.NotFoundError=ya,Z.ConflictError=wa,Z.RateLimitError=Sa,Z.BadRequestError=pa,Z.AuthenticationError=ma,Z.InternalServerError=va,Z.PermissionDeniedError=ga,Z.UnprocessableEntityError=ba,Z.toFile=df;class pn extends Z{static{c(this,"Anthropic")}constructor(){super(...arguments),this.completions=new ec(this),this.messages=new Xr(this),this.models=new ac(this),this.beta=new cn(this)}}pn.Completions=ec,pn.Messages=Xr,pn.Models=ac,pn.Beta=cn;const Cf="claude-sonnet-4-20250514";class ri{static{c(this,"TestEnvironment")}client;connectionId;testsDir;testBasePath;options;llm;state={};constructor({connectionId:e,testsDir:t,testBasePath:n,client:r,options:i,llm:o}){this.client=r,this.connectionId=e,this.testsDir=t,this.testBasePath=n,this.llm=o,this.options=i}static async create({connectionId:e,testBasePath:t,options:n}){const r=On();if(!r)throw new Error("No configuration found. Please set MEMBRANE_WORKSPACE_KEY and MEMBRANE_WORKSPACE_SECRET environment variables, or run `membrane init` first.");if(!r.workspaceKey||!r.workspaceSecret)throw new Error("Missing workspace credentials");if(!r.anthropicApiKey)throw new Error("Anthropic API key not configured. Run `membrane init` to set up testing.");const i=new li({token:await this.createMembraneToken(r),apiUri:r.apiUri}),o=new pn({apiKey:r.anthropicApiKey}),a={complete:c(async({prompt:l,maxTokens:u})=>{const h=await o.messages.create({model:Cf,max_tokens:u,messages:[{role:"user",content:l}]});return h.content[0].type==="text"?h.content[0].text:""},"complete")};return new ri({client:i,options:n,connectionId:e,testsDir:"src/testing/tests",testBasePath:t,llm:a})}async run(e){this.state={};const t={};for(const n of e)await n.run(),Fs(t,n.getResult());this.writeResults(t)}async readYaml(e){const t=q.join(this.testsDir,this.testBasePath,this.connectionId,e);return Js(t)}async writeYaml(e,t){const n=q.join(this.testsDir,this.testBasePath,this.connectionId,e);D.mkdirSync(q.dirname(n),{recursive:!0}),D.writeFileSync(n,Pt.dump(t,{noRefs:!0}))}writeResults(e){const t=q.join(this.testsDir,this.testBasePath,this.connectionId);D.mkdirSync(t,{recursive:!0});const n=q.join(t,"test-results.yaml");D.writeFileSync(n,Pt.dump(e,{noRefs:!0})),console.debug(`[TestRunner] Results written to: ${n}`)}static async createMembraneToken(e){const t=e.testCustomerId||"test-customer",n={id:t,name:t},r={issuer:e.workspaceKey,expiresIn:7200,algorithm:"HS512"};return Ds.sign(n,e.workspaceSecret,r)}}Vc.interpolate=/{{([\s\S]+?)}}/g;function ei(s,e){if(typeof s=="string"){const t=Hc(s),n={state:e,random:{number:c(()=>Lt.number.int(),"number"),alphaNumeric:c(i=>Lt.string.alphanumeric(i),"alphaNumeric")},faker:{company:{name:c(()=>Lt.company.name(),"name"),catchPhrase:c(()=>Lt.company.catchPhrase(),"catchPhrase")},internet:{email:c(()=>Lt.internet.email(),"email")}},entries:e["journal-entries"],orders:e["purchase-orders"]||e["sales-orders"],bills:e["vendor-bills"]},r=t(n);return s.includes("{{")&&s.includes("}}")&&(console.debug(`[TEMPLATE] Input: ${s}`),console.debug(`[TEMPLATE] Output: ${r}`)),r}return Array.isArray(s)?s.map(t=>ei(t,e)):typeof s=="object"&&s!==null?Object.fromEntries(Object.entries(s).map(([t,n])=>[t,ei(n,e)])):s}c(ei,"processNode");function kf(s,e){return ei(s,e)}c(kf,"handleTemplate");class _f{static{c(this,"BaseTestSuite")}result;environment;constructor({environment:e}){this.environment=e,this.result={}}async run(){}getResult(){return this.result}async runTest(e){console.debug(`${T.bold.cyan("[start]")} ${T.yellow(e.path)}`);let t=!1,n=!1,r={},i={},o;for(;!t;)try{i=await e.readTestCase(),i||(i=await e.generateConfig(),await this.environment.writeYaml(e.getTestCasePath(),i),console.debug(`${T.bold.yellow("[initialized]")} ${T.yellow(e.path)}`)),o=kf(i,this.environment.state),await e.run(o),console.debug(`${T.bold.green("[success]")} ${T.yellow(e.path)}`),t=!0,r=e.getResult(),Rs(this.result,e.path,r)}catch(l){if(console.error(`${T.bold.red("[error]")} ${T.yellow(e.path)}: ${l}`),this.environment.options.fix&&!n){n=!0;try{await e.fix(l);continue}catch(u){console.error(`${T.bold.red("[fix fail]")} ${T.yellow(e.path)}: ${u}`)}}Rs(this.result,e.path,{error:ke(l)}),t=!0,r={error:ke(l)}}const a={...o,result:r};await this.environment.writeYaml(e.getTestCasePath(),a)}async runTestSuite(e){await e.run(),Fs(this.result,e.getResult())}}class He{static{c(this,"BaseTester")}environment;level;logs;assertions;resultsLocator;path;constructor({environment:e,path:t}){this.environment=e,this.logs=[],this.assertions=[],this.path=t,this.level=0}async fix(e){const t=await this.readTestCase();if(!t)throw new Error(`No config found for test ${this.path}`);const n=await this.fixTestCase({config:t,error:e});console.debug(T.bold.yellow("[auto-fix]"),this.path),await this.environment.writeYaml(this.getTestCasePath(),n)}async readTestCase(){const e=this.getTestCasePath();return this.environment.readYaml(e)}async generateConfig(){return{}}async fixTestCase(e){throw new Error(`Auto-fix is not implemented for test ${this.path}`)}getResult(){return{logs:this.logs,assertions:this.assertions}}async assert(e,t,n){try{const r=await e();r?(this.logMsg(`\u2705 ${t}`),this.assertions.push({message:t,result:r})):(this.logMsg(`\u274C ${t}`),this.assertions.push({message:t,result:!1,details:n}))}catch(r){this.assertions.push({message:t,result:!1,details:ke(r)}),this.logMsg(`\u274C ${t}: ${r.message}`)}}logMsg(e){console.debug(`${" ".repeat(this.level*2)}${e}`)}getTestCasePath(){return`${this.path}.test.yml`}}function ti(s,e){const t={};for(const n in e){if(!(n in s)){t[n]=e[n];continue}const r=s[n],i=e[n];if(r&&i&&typeof r=="object"&&typeof i=="object"){if(Array.isArray(r)&&Array.isArray(i)){const o=i.filter(a=>!r.some(l=>{if(typeof l=="object"&&typeof a=="object"&&l!==null&&a!==null&&!Array.isArray(l)&&!Array.isArray(a)){for(const u in a)if(!(u in l)||!ni(l[u],a[u]))return!1;return!0}else return JSON.stringify(l)===JSON.stringify(a)}));o.length>0&&(t[n]=o)}else if(!Array.isArray(r)&&!Array.isArray(i)){const o=ti(r,i);o!==null&&(t[n]=o)}else t[n]=i;continue}ni(r,i)||(t[n]=i)}return Object.keys(t).length===0?null:t}c(ti,"getNotMatchingSubFields");function ni(s,e){if(s==e||s?.toString?.()===e?.toString?.())return!0;const t=new Date(s),n=new Date(e);return!isNaN(t.getTime())&&!isNaN(n.getTime())?t.getTime()===n.getTime():!1}c(ni,"softCompare");class Tf extends He{static{c(this,"DataCollectionCreateTester")}dataCollectionKey;dataCollection;constructor({environment:e,dataCollectionKey:t,dataCollection:n}){super({environment:e,path:`data/${t}/create`}),this.dataCollectionKey=t,this.dataCollection=n}async run(e){const t=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).create(e.input);await this.assert(()=>!!t.id,"Returned ID of a created record"),t.id&&(this.environment.state[this.dataCollectionKey]={createdRecordId:t.id});const n=Ps(this.dataCollection);if(this.dataCollection.findById){const i=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).findById({id:t.id});await this.assert(()=>!!i.record,"Record is returned from findById"),i.record&&(this.environment.state[this.dataCollectionKey]={createdRecordId:t.id,createdRecord:i.record.fields});const o=ui(n),a=yn(e.input.fields,o,{skipUnknownFields:!0}),l=yn(i.record.fields,o),u=ti(l,a);await this.assert(()=>!u,"Returned fields match created fields",{difference:u,sentFields:a,receivedFields:l})}const r=Cc(n);if(r.length>0){const i={};r.forEach(a=>{const l=kc(e.input.fields,a);typeof l<"u"&&Rs(i,a,l)});const o=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).create({fields:i});await this.assert(()=>!!o.id,"Record can be created with schema-defined required fields only")}}async generateConfig(){const e=Ps(this.dataCollection);if(!e?.properties)throw new Error("No fields schema found for data collection");return{input:{fields:await this.generateFieldsWithLLM(e)}}}async fixTestCase({config:e,error:t}){const n=ke(t),r=Ps(this.dataCollection),i=await this.getExampleRecordsForSchema(r),o=`I'm trying to create a data record in a data collection with the following fields schema:
|
|
167
|
+
`);this.baseURL=i.baseURL,this.timeout=i.timeout??Zr.DEFAULT_TIMEOUT,this.logger=i.logger??console;const o="warn";this.logLevel=o,this.logLevel=Ma(i.logLevel,"ClientOptions.logLevel",this)??Ma(ks("ANTHROPIC_LOG"),"process.env['ANTHROPIC_LOG']",this)??o,this.fetchOptions=i.fetchOptions,this.maxRetries=i.maxRetries??2,this.fetch=i.fetch??Vh(),R(this,_s,zh),this._options=i,this.apiKey=t,this.authToken=n}withOptions(e){return new this.constructor({...this._options,baseURL:this.baseURL,maxRetries:this.maxRetries,timeout:this.timeout,logger:this.logger,logLevel:this.logLevel,fetch:this.fetch,fetchOptions:this.fetchOptions,apiKey:this.apiKey,authToken:this.authToken,...e})}defaultQuery(){return this._options.defaultQuery}validateHeaders({values:e,nulls:t}){if(!(this.apiKey&&e.get("x-api-key"))&&!t.has("x-api-key")&&!(this.authToken&&e.get("authorization"))&&!t.has("authorization"))throw new Error('Could not resolve authentication method. Expected either apiKey or authToken to be set. Or for one of the "X-Api-Key" or "Authorization" headers to be explicitly omitted')}async authHeaders(e){return V([await this.apiKeyAuth(e),await this.bearerAuth(e)])}async apiKeyAuth(e){if(this.apiKey!=null)return V([{"X-Api-Key":this.apiKey}])}async bearerAuth(e){if(this.authToken!=null)return V([{Authorization:`Bearer ${this.authToken}`}])}stringifyQuery(e){return Object.entries(e).filter(([t,n])=>typeof n<"u").map(([t,n])=>{if(typeof n=="string"||typeof n=="number"||typeof n=="boolean")return`${encodeURIComponent(t)}=${encodeURIComponent(n)}`;if(n===null)return`${encodeURIComponent(t)}=`;throw new L(`Cannot stringify type ${typeof n}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`)}).join("&")}getUserAgent(){return`${this.constructor.name}/JS ${Et}`}defaultIdempotencyKey(){return`stainless-node-retry-${fa()}`}makeStatusError(e,t,n,r){return re.generate(e,t,n,r)}buildURL(e,t,n){const r=!S(this,Qr,"m",cc).call(this)&&n||this.baseURL,i=Dh(e)?new URL(e):new URL(r+(r.endsWith("/")&&e.startsWith("/")?e.slice(1):e)),o=this.defaultQuery();return jh(o)||(t={...o,...t}),typeof t=="object"&&t&&!Array.isArray(t)&&(i.search=this.stringifyQuery(t)),i.toString()}_calculateNonstreamingTimeout(e){if(3600*e/128e3>600)throw new L("Streaming is required for operations that may take longer than 10 minutes. See https://github.com/anthropics/anthropic-sdk-typescript#streaming-responses for more details");return 600*1e3}async prepareOptions(e){}async prepareRequest(e,{url:t,options:n}){}get(e,t){return this.methodRequest("get",e,t)}post(e,t){return this.methodRequest("post",e,t)}patch(e,t){return this.methodRequest("patch",e,t)}put(e,t){return this.methodRequest("put",e,t)}delete(e,t){return this.methodRequest("delete",e,t)}methodRequest(e,t,n){return this.request(Promise.resolve(n).then(r=>({method:e,path:t,...r})))}request(e,t=null){return new As(this,this.makeRequest(e,t,void 0))}async makeRequest(e,t,n){const r=await e,i=r.maxRetries??this.maxRetries;t==null&&(t=i),await this.prepareOptions(r);const{req:o,url:a,timeout:l}=await this.buildRequest(r,{retryCount:i-t});await this.prepareRequest(o,{url:a,options:r});const u="log_"+(Math.random()*(1<<24)|0).toString(16).padStart(6,"0"),h=n===void 0?"":`, retryOf: ${n}`,f=Date.now();if(ie(this).debug(`[${u}] sending request`,et({retryOfRequestLogID:n,method:r.method,url:a,options:r,headers:o.headers})),r.signal?.aborted)throw new ve;const p=new AbortController,m=await this.fetchWithTimeout(a,o,l,p).catch(Pr),y=Date.now();if(m instanceof globalThis.Error){const k=`retrying, ${t} attempts remaining`;if(r.signal?.aborted)throw new ve;const _=Yt(m)||/timed? ?out/i.test(String(m)+("cause"in m?String(m.cause):""));if(t)return ie(this).info(`[${u}] connection ${_?"timed out":"failed"} - ${k}`),ie(this).debug(`[${u}] connection ${_?"timed out":"failed"} (${k})`,et({retryOfRequestLogID:n,url:a,durationMs:y-f,message:m.message})),this.retryRequest(r,t,n??u);throw ie(this).info(`[${u}] connection ${_?"timed out":"failed"} - error; no more retries left`),ie(this).debug(`[${u}] connection ${_?"timed out":"failed"} (error; no more retries left)`,et({retryOfRequestLogID:n,url:a,durationMs:y-f,message:m.message})),_?new da:new is({cause:m})}const d=[...m.headers.entries()].filter(([k])=>k==="request-id").map(([k,_])=>", "+k+": "+JSON.stringify(_)).join(""),w=`[${u}${h}${d}] ${o.method} ${a} ${m.ok?"succeeded":"failed"} with status ${m.status} in ${y-f}ms`;if(!m.ok){const k=await this.shouldRetry(m);if(t&&k){const K=`retrying, ${t} attempts remaining`;return await Gh(m.body),ie(this).info(`${w} - ${K}`),ie(this).debug(`[${u}] response error (${K})`,et({retryOfRequestLogID:n,url:m.url,status:m.status,headers:m.headers,durationMs:y-f})),this.retryRequest(r,t,n??u,m.headers)}const _=k?"error; no more retries left":"error; not retryable";ie(this).info(`${w} - ${_}`);const O=await m.text().catch(K=>Pr(K).message),A=_a(O),$=A?void 0:O;throw ie(this).debug(`[${u}] response error (${_})`,et({retryOfRequestLogID:n,url:m.url,status:m.status,headers:m.headers,message:$,durationMs:Date.now()-f})),this.makeStatusError(m.status,A,$,m.headers)}return ie(this).info(w),ie(this).debug(`[${u}] response start`,et({retryOfRequestLogID:n,url:m.url,status:m.status,headers:m.headers,durationMs:y-f})),{response:m,options:r,controller:p,requestLogID:u,retryOfRequestLogID:n,startTime:f}}getAPIList(e,t,n){return this.requestAPIList(t,{method:"get",path:e,...n})}requestAPIList(e,t){const n=this.makeRequest(t,null,void 0);return new of(this,n,e)}async fetchWithTimeout(e,t,n,r){const{signal:i,method:o,...a}=t||{};i&&i.addEventListener("abort",()=>r.abort());const l=setTimeout(()=>r.abort(),n),u=globalThis.ReadableStream&&a.body instanceof globalThis.ReadableStream||typeof a.body=="object"&&a.body!==null&&Symbol.asyncIterator in a.body,h={signal:r.signal,...u?{duplex:"half"}:{},method:"GET",...a};o&&(h.method=o.toUpperCase());try{return await this.fetch.call(void 0,e,h)}finally{clearTimeout(l)}}async shouldRetry(e){const t=e.headers.get("x-should-retry");return t==="true"?!0:t==="false"?!1:e.status===408||e.status===409||e.status===429||e.status>=500}async retryRequest(e,t,n,r){let i;const o=r?.get("retry-after-ms");if(o){const l=parseFloat(o);Number.isNaN(l)||(i=l)}const a=r?.get("retry-after");if(a&&!i){const l=parseFloat(a);Number.isNaN(l)?i=Date.parse(a)-Date.now():i=l*1e3}if(!(i&&0<=i&&i<60*1e3)){const l=e.maxRetries??this.maxRetries;i=this.calculateDefaultRetryTimeoutMillis(t,l)}return await Bh(i),this.makeRequest(e,t-1,n)}calculateDefaultRetryTimeoutMillis(e,t){const i=t-e,o=Math.min(.5*Math.pow(2,i),8),a=1-Math.random()*.25;return o*a*1e3}calculateNonstreamingTimeout(e,t){if(36e5*e/128e3>6e5||t!=null&&e>t)throw new L("Streaming is required for operations that may take longer than 10 minutes. See https://github.com/anthropics/anthropic-sdk-typescript#long-requests for more details");return 6e5}async buildRequest(e,{retryCount:t=0}={}){const n={...e},{method:r,path:i,query:o,defaultBaseURL:a}=n,l=this.buildURL(i,o,a);"timeout"in n&&Kh("timeout",n.timeout),n.timeout=n.timeout??this.timeout;const{bodyHeaders:u,body:h}=this.buildBody({options:n}),f=await this.buildHeaders({options:e,method:r,bodyHeaders:u,retryCount:t});return{req:{method:r,headers:f,...n.signal&&{signal:n.signal},...globalThis.ReadableStream&&h instanceof globalThis.ReadableStream&&{duplex:"half"},...h&&{body:h},...this.fetchOptions??{},...n.fetchOptions??{}},url:l,timeout:n.timeout}}async buildHeaders({options:e,method:t,bodyHeaders:n,retryCount:r}){let i={};this.idempotencyHeader&&t!=="get"&&(e.idempotencyKey||(e.idempotencyKey=this.defaultIdempotencyKey()),i[this.idempotencyHeader]=e.idempotencyKey);const o=V([i,{Accept:"application/json","User-Agent":this.getUserAgent(),"X-Stainless-Retry-Count":String(r),...e.timeout?{"X-Stainless-Timeout":String(Math.trunc(e.timeout/1e3))}:{},...Hh(),...this._options.dangerouslyAllowBrowser?{"anthropic-dangerous-direct-browser-access":"true"}:void 0,"anthropic-version":"2023-06-01"},await this.authHeaders(e),this._options.defaultHeaders,n,e.headers]);return this.validateHeaders(o),o.values}buildBody({options:{body:e,headers:t}}){if(!e)return{bodyHeaders:void 0,body:void 0};const n=V([t]);return ArrayBuffer.isView(e)||e instanceof ArrayBuffer||e instanceof DataView||typeof e=="string"&&n.values.has("content-type")||globalThis.Blob&&e instanceof globalThis.Blob||e instanceof FormData||e instanceof URLSearchParams||globalThis.ReadableStream&&e instanceof globalThis.ReadableStream?{bodyHeaders:void 0,body:e}:typeof e=="object"&&(Symbol.asyncIterator in e||Symbol.iterator in e&&"next"in e&&typeof e.next=="function")?{bodyHeaders:void 0,body:Ia(e)}:S(this,_s,"f").call(this,{body:e,headers:n})}}Zr=Z,_s=new WeakMap,Qr=new WeakSet,cc=c(function(){return this.baseURL!=="https://api.anthropic.com"},"_BaseAnthropic_baseURLOverridden2"),Z.Anthropic=Zr,Z.HUMAN_PROMPT=Sf,Z.AI_PROMPT=vf,Z.DEFAULT_TIMEOUT=6e5,Z.AnthropicError=L,Z.APIError=re,Z.APIConnectionError=is,Z.APIConnectionTimeoutError=da,Z.APIUserAbortError=ve,Z.NotFoundError=ya,Z.ConflictError=wa,Z.RateLimitError=Sa,Z.BadRequestError=pa,Z.AuthenticationError=ma,Z.InternalServerError=va,Z.PermissionDeniedError=ga,Z.UnprocessableEntityError=ba,Z.toFile=df;class pn extends Z{static{c(this,"Anthropic")}constructor(){super(...arguments),this.completions=new ec(this),this.messages=new Xr(this),this.models=new ac(this),this.beta=new cn(this)}}pn.Completions=ec,pn.Messages=Xr,pn.Models=ac,pn.Beta=cn;const Cf="claude-sonnet-4-20250514";class ri{static{c(this,"TestEnvironment")}client;connectionId;testsDir;testBasePath;options;llm;state={};constructor({connectionId:e,testsDir:t,testBasePath:n,client:r,options:i,llm:o}){this.client=r,this.connectionId=e,this.testsDir=t,this.testBasePath=n,this.llm=o,this.options=i}static async create({connectionId:e,testBasePath:t,options:n}){const r=On();if(!r)throw new Error("No configuration found. Please set MEMBRANE_WORKSPACE_KEY and MEMBRANE_WORKSPACE_SECRET environment variables, or run `membrane init` first.");if(!r.workspaceKey||!r.workspaceSecret)throw new Error("Missing workspace credentials");if(!r.anthropicApiKey)throw new Error("Anthropic API key not configured. Run `membrane init` to set up testing.");const i=new li({token:await this.createMembraneToken(r),apiUri:r.apiUri}),o=new pn({apiKey:r.anthropicApiKey}),a={complete:c(async({prompt:l,maxTokens:u})=>{const h=await o.messages.create({model:Cf,max_tokens:u,messages:[{role:"user",content:l}]});return h.content[0].type==="text"?h.content[0].text:""},"complete")};return new ri({client:i,options:n,connectionId:e,testsDir:"src/testing/tests",testBasePath:t,llm:a})}async run(e){this.state={};const t={};for(const n of e)await n.run(),Fs(t,n.getResult());this.writeResults(t)}async readYaml(e){const t=q.join(this.testsDir,this.testBasePath,this.connectionId,e);return Js(t)}async writeYaml(e,t){const n=q.join(this.testsDir,this.testBasePath,this.connectionId,e);D.mkdirSync(q.dirname(n),{recursive:!0}),D.writeFileSync(n,Pt.dump(t,{noRefs:!0}))}writeResults(e){const t=q.join(this.testsDir,this.testBasePath,this.connectionId);D.mkdirSync(t,{recursive:!0});const n=q.join(t,"test-results.yaml");D.writeFileSync(n,Pt.dump(e,{noRefs:!0})),console.debug(`[TestRunner] Results written to: ${n}`)}static async createMembraneToken(e){const t=e.testCustomerId||"test-customer",n={id:t,name:t},r={issuer:e.workspaceKey,expiresIn:7200,algorithm:"HS512"};return Ds.sign(n,e.workspaceSecret,r)}}Vc.interpolate=/{{([\s\S]+?)}}/g;function ei(s,e){if(typeof s=="string"){const t=Hc(s),n={state:e,random:{number:c(()=>Lt.number.int(),"number"),alphaNumeric:c(i=>Lt.string.alphanumeric(i),"alphaNumeric")},faker:{company:{name:c(()=>Lt.company.name(),"name"),catchPhrase:c(()=>Lt.company.catchPhrase(),"catchPhrase")},internet:{email:c(()=>Lt.internet.email(),"email")}},entries:e["journal-entries"],orders:e["purchase-orders"]||e["sales-orders"],bills:e["vendor-bills"]},r=t(n);return s.includes("{{")&&s.includes("}}")&&(console.debug(`[TEMPLATE] Input: ${s}`),console.debug(`[TEMPLATE] Output: ${r}`)),r}return Array.isArray(s)?s.map(t=>ei(t,e)):typeof s=="object"&&s!==null?Object.fromEntries(Object.entries(s).map(([t,n])=>[t,ei(n,e)])):s}c(ei,"processNode");function kf(s,e){return ei(s,e)}c(kf,"handleTemplate");class _f{static{c(this,"BaseTestSuite")}result;environment;constructor({environment:e}){this.environment=e,this.result={}}async run(){}getResult(){return this.result}async runTest(e){console.debug(`${T.bold.cyan("[start]")} ${T.yellow(e.path)}`);let t=!1,n=!1,r={},i={},o;for(;!t;)try{i=await e.readTestCase(),i||(i=await e.generateConfig(),await this.environment.writeYaml(e.getTestCasePath(),i),console.debug(`${T.bold.yellow("[initialized]")} ${T.yellow(e.path)}`)),o=kf(i,this.environment.state),await e.run(o),console.debug(`${T.bold.green("[success]")} ${T.yellow(e.path)}`),t=!0,r=e.getResult(),Rs(this.result,e.path,r)}catch(l){if(console.error(`${T.bold.red("[error]")} ${T.yellow(e.path)}: ${l}`),this.environment.options.fix&&!n){n=!0;try{await e.fix(l);continue}catch(u){console.error(`${T.bold.red("[fix fail]")} ${T.yellow(e.path)}: ${u}`)}}Rs(this.result,e.path,{error:ke(l)}),t=!0,r={error:ke(l)}}const a={...o,result:r};await this.environment.writeYaml(e.getTestCasePath(),a)}async runTestSuite(e){await e.run(),Fs(this.result,e.getResult())}}class He{static{c(this,"BaseTester")}environment;level;logs;assertions;resultsLocator;path;constructor({environment:e,path:t}){this.environment=e,this.logs=[],this.assertions=[],this.path=t,this.level=0,this.resultsLocator=""}async fix(e){const t=await this.readTestCase();if(!t)throw new Error(`No config found for test ${this.path}`);const n=await this.fixTestCase({config:t,error:e});console.debug(T.bold.yellow("[auto-fix]"),this.path),await this.environment.writeYaml(this.getTestCasePath(),n)}async readTestCase(){const e=this.getTestCasePath();return this.environment.readYaml(e)}async generateConfig(){return{}}async fixTestCase(e){throw new Error(`Auto-fix is not implemented for test ${this.path}`)}getResult(){return{logs:this.logs,assertions:this.assertions}}async assert(e,t,n){try{const r=await e();r?(this.logMsg(`\u2705 ${t}`),this.assertions.push({message:t,result:r})):(this.logMsg(`\u274C ${t}`),this.assertions.push({message:t,result:!1,details:n}))}catch(r){this.assertions.push({message:t,result:!1,details:ke(r)}),this.logMsg(`\u274C ${t}: ${r.message}`)}}logMsg(e){console.debug(`${" ".repeat(this.level*2)}${e}`)}getTestCasePath(){return`${this.path}.test.yml`}}function ti(s,e){const t={};for(const n in e){if(!(n in s)){t[n]=e[n];continue}const r=s[n],i=e[n];if(r&&i&&typeof r=="object"&&typeof i=="object"){if(Array.isArray(r)&&Array.isArray(i)){const o=i.filter(a=>!r.some(l=>{if(typeof l=="object"&&typeof a=="object"&&l!==null&&a!==null&&!Array.isArray(l)&&!Array.isArray(a)){for(const u in a)if(!(u in l)||!ni(l[u],a[u]))return!1;return!0}else return JSON.stringify(l)===JSON.stringify(a)}));o.length>0&&(t[n]=o)}else if(!Array.isArray(r)&&!Array.isArray(i)){const o=ti(r,i);o!==null&&(t[n]=o)}else t[n]=i;continue}ni(r,i)||(t[n]=i)}return Object.keys(t).length===0?null:t}c(ti,"getNotMatchingSubFields");function ni(s,e){if(s==e||s?.toString?.()===e?.toString?.())return!0;const t=new Date(s),n=new Date(e);return!isNaN(t.getTime())&&!isNaN(n.getTime())?t.getTime()===n.getTime():!1}c(ni,"softCompare");class Tf extends He{static{c(this,"DataCollectionCreateTester")}dataCollectionKey;dataCollection;constructor({environment:e,dataCollectionKey:t,dataCollection:n}){super({environment:e,path:`data/${t}/create`}),this.dataCollectionKey=t,this.dataCollection=n}async run(e){const t=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).create(e.input);await this.assert(()=>!!t.id,"Returned ID of a created record"),t.id&&(this.environment.state[this.dataCollectionKey]={createdRecordId:t.id});const n=Ps(this.dataCollection);if(this.dataCollection.findById){const i=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).findById({id:t.id});await this.assert(()=>!!i.record,"Record is returned from findById"),i.record&&(this.environment.state[this.dataCollectionKey]={createdRecordId:t.id,createdRecord:i.record.fields});const o=ui(n),a=yn(e.input.fields,o,{skipUnknownFields:!0}),l=yn(i.record.fields,o),u=ti(l,a);await this.assert(()=>!u,"Returned fields match created fields",{difference:u,sentFields:a,receivedFields:l})}const r=Cc(n??{});if(r.length>0){const i={};r.forEach(a=>{const l=kc(e.input.fields,a);typeof l<"u"&&Rs(i,a,l)});const o=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).create({fields:i});await this.assert(()=>!!o.id,"Record can be created with schema-defined required fields only")}}async generateConfig(){const e=Ps(this.dataCollection);if(!e?.properties)throw new Error("No fields schema found for data collection");return{input:{fields:await this.generateFieldsWithLLM(e)}}}async fixTestCase({config:e,error:t}){const n=ke(t),r=Ps(this.dataCollection),i=await this.getExampleRecordsForSchema(r),o=`I'm trying to create a data record in a data collection with the following fields schema:
|
|
168
168
|
|
|
169
169
|
${JSON.stringify(r,null,2)}
|
|
170
170
|
|
|
@@ -204,7 +204,7 @@ ${JSON.stringify(r,null,2)}`).join(`
|
|
|
204
204
|
|
|
205
205
|
`)}.
|
|
206
206
|
|
|
207
|
-
If you don't have an example for a given collection, leave the field empty instead of coming up with a fake record id.`}async findReferenceCollections(e){const t=new Set,n=[];return hi(e,r=>{if(r.referenceCollection){const i=r.referenceCollection.key,o=r.referenceCollection.parameters,a=`${i}:${JSON.stringify(o||{})}`;t.has(a)||(t.add(a),n.push({key:i,parameters:o}))}return r}),n}async fetchExampleRecords(e){return(await this.environment.client.connection(this.environment.connectionId).dataCollection(e.key).list({parameters:e.parameters})).records.map(n=>({id:n.id,fields:n.fields}))}async getExampleRecordsForSchema(e){const t=await this.findReferenceCollections(e),n={};for(const r of t){const i=fi(r);n[i]=await this.fetchExampleRecords(r)}return n}}class Ef extends He{static{c(this,"DataCollectionDeleteTester")}dataCollectionKey;dataCollection;constructor({environment:e,dataCollectionKey:t,dataCollection:n}){super({environment:e,path:`data/${t}/delete`}),this.dataCollectionKey=t,this.dataCollection=n}async run(e){const t=this.environment.state[this.dataCollectionKey]?.createdRecordId||e?.input?.id;if(!t)throw new Error(`No ID found in state or config for ${this.dataCollectionKey} delete`);try{await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).delete({id:t})}catch(n){throw n}if(this.dataCollection.findById)try{await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).findById({id:t})}catch(n){if(n?.data?.data?.response?.status===404){await this.assert(()=>!0,"Record is not found after deletion");return}throw n}else await this.assert(()=>!0,"No findById capability, skipping verification")}async generateConfig(){let e=this.environment.state[this.dataCollectionKey]?.createdRecordId;if(!e){if(!this.dataCollection.list)throw new Error(`Can't find a record to test delete operation for ${this.dataCollectionKey}. List operation is not implemented for this data collection`);const t=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).list({});if(!t?.records?.length)throw new Error(`No records found to test delete for ${this.dataCollectionKey}`);e=t.records[0].id}return{input:{id:e}}}async fixTestCase({config:e,error:t}){const n=ke(t),r=`I'm trying to delete a record from a data collection.
|
|
207
|
+
If you don't have an example for a given collection, leave the field empty instead of coming up with a fake record id.`}async findReferenceCollections(e){const t=new Set,n=[];return hi(e,r=>{if(r.referenceCollection){const i=r.referenceCollection.key,o=r.referenceCollection.parameters,a=`${i}:${JSON.stringify(o||{})}`;t.has(a)||(t.add(a),n.push({key:i,parameters:o}))}return r}),n}async fetchExampleRecords(e){return(await this.environment.client.connection(this.environment.connectionId).dataCollection(e.key).list({parameters:e.parameters})).records.map(n=>({id:n.id,fields:n.fields??{}}))}async getExampleRecordsForSchema(e){const t=await this.findReferenceCollections(e),n={};for(const r of t){const i=fi(r);n[i]=await this.fetchExampleRecords(r)}return n}}class Ef extends He{static{c(this,"DataCollectionDeleteTester")}dataCollectionKey;dataCollection;constructor({environment:e,dataCollectionKey:t,dataCollection:n}){super({environment:e,path:`data/${t}/delete`}),this.dataCollectionKey=t,this.dataCollection=n}async run(e){const t=this.environment.state[this.dataCollectionKey]?.createdRecordId||e?.input?.id;if(!t)throw new Error(`No ID found in state or config for ${this.dataCollectionKey} delete`);try{await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).delete({id:t})}catch(n){throw n}if(this.dataCollection.findById)try{await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).findById({id:t})}catch(n){if(n?.data?.data?.response?.status===404){await this.assert(()=>!0,"Record is not found after deletion");return}throw n}else await this.assert(()=>!0,"No findById capability, skipping verification")}async generateConfig(){let e=this.environment.state[this.dataCollectionKey]?.createdRecordId;if(!e){if(!this.dataCollection.list)throw new Error(`Can't find a record to test delete operation for ${this.dataCollectionKey}. List operation is not implemented for this data collection`);const t=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).list({});if(!t?.records?.length)throw new Error(`No records found to test delete for ${this.dataCollectionKey}`);e=t.records[0].id}return{input:{id:e}}}async fixTestCase({config:e,error:t}){const n=ke(t),r=`I'm trying to delete a record from a data collection.
|
|
208
208
|
|
|
209
209
|
I tried to delete a record with this ID:
|
|
210
210
|
|
|
@@ -244,7 +244,7 @@ Format your response as a JSON object with two fields:
|
|
|
244
244
|
"id": "fixed id"
|
|
245
245
|
}.
|
|
246
246
|
|
|
247
|
-
Only return the JSON object, no other text or wrapping (like \`\`\`json or \`\`\`).`,i=await this.environment.llm.complete({prompt:r,maxTokens:1e3}),o=JSON.parse(i.trim());return console.warn(T.bold.yellow("[auto-fix]"),`${this.path}:`,o.explanation),{input:{id:o.id}}}}class Of extends He{static{c(this,"DataCollectionListTester")}dataCollectionKey;constructor({environment:e,dataCollectionKey:t}){super({environment:e,path:`data/${t}/list`}),this.dataCollectionKey=t}async run(e){const t=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).list(e.input);if(await this.assert(()=>Array.isArray(t.records),"Response has records field as array"),e.input.sort){const{field:n,direction:r}=e.input.sort,i=t.records;if(i.length>1)for(let o=1;o<i.length;o++){const a=i[o-1].fields[n],l=i[o].fields[n];a==null||l==null||(r==="asc"?await this.assert(()=>a<=l,`Records are sorted by ${n} in ascending order`):await this.assert(()=>a>=l,`Records are sorted by ${n} in descending order`))}}}async generateConfig(){return{input:{}}}async fixTestCase({config:e,error:t}){const n=ke(t),r=`I'm trying to list records from a data collection.
|
|
247
|
+
Only return the JSON object, no other text or wrapping (like \`\`\`json or \`\`\`).`,i=await this.environment.llm.complete({prompt:r,maxTokens:1e3}),o=JSON.parse(i.trim());return console.warn(T.bold.yellow("[auto-fix]"),`${this.path}:`,o.explanation),{input:{id:o.id}}}}class Of extends He{static{c(this,"DataCollectionListTester")}dataCollectionKey;constructor({environment:e,dataCollectionKey:t}){super({environment:e,path:`data/${t}/list`}),this.dataCollectionKey=t}async run(e){const t=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).list(e.input);if(await this.assert(()=>Array.isArray(t.records),"Response has records field as array"),e.input.sort){const{field:n,direction:r}=e.input.sort,i=t.records;if(i.length>1)for(let o=1;o<i.length;o++){const a=i[o-1].fields?.[n],l=i[o].fields?.[n];a==null||l==null||(r==="asc"?await this.assert(()=>a<=l,`Records are sorted by ${n} in ascending order`):await this.assert(()=>a>=l,`Records are sorted by ${n} in descending order`))}}}async generateConfig(){return{input:{}}}async fixTestCase({config:e,error:t}){const n=ke(t),r=`I'm trying to list records from a data collection.
|
|
248
248
|
|
|
249
249
|
I tried to list records with these parameters:
|
|
250
250
|
|
|
@@ -264,7 +264,7 @@ Format your response as a JSON object with two fields:
|
|
|
264
264
|
"input": { ... fixed parameters ... }
|
|
265
265
|
}.
|
|
266
266
|
|
|
267
|
-
Only return the JSON object, no other text or wrapping (like \`\`\`json or \`\`\`).`,i=await this.environment.llm.complete({prompt:r,maxTokens:1e3}),o=JSON.parse(i.trim());return console.warn(T.bold.yellow("[auto-fix]"),`${this.path}:`,o.explanation),{input:o.input}}}class If extends He{static{c(this,"DataCollectionMatchTester")}dataCollectionKey;dataCollection;constructor({environment:e,dataCollectionKey:t,dataCollection:n}){super({environment:e,path:`data/${t}/match`}),this.dataCollectionKey=t,this.dataCollection=n}async run(e){const t=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).match(e.input);await this.assert(()=>!!t.record,"Response contains a record");const n=t.record,i=(await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).findById({id:n.id})).record;for(const[o,a]of Object.entries(e.input.query)){const l=i.fields[o];await this.assert(()=>ni(l,a),`Record field ${o} matches input value - expected ${JSON.stringify(a)} got ${JSON.stringify(l)}`)}}async generateConfig(){if(!this.dataCollection.list)throw new Error(`Can't find a record to test match operation for ${this.dataCollectionKey}. List operation is not implemented for this data collection`);const e=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).list({});if(!e?.records?.length)throw new Error("No records found to test match");const t=e.records[0];if(!t?.fields)throw new Error("First record has no fields to match against");const n={},r=t.fields||{},i=Object.entries(r).filter(([o,a])=>o!=="links"&&a!=null&&a!=="").slice(0,1);if(i.length===0)throw new Error("No usable fields found in record for matching");for(const[o,a]of i)n[o]=a;return{input:{query:n}}}async fixTestCase({config:e,error:t}){const n=ke(t),r=`I'm trying to match a record in a data collection.
|
|
267
|
+
Only return the JSON object, no other text or wrapping (like \`\`\`json or \`\`\`).`,i=await this.environment.llm.complete({prompt:r,maxTokens:1e3}),o=JSON.parse(i.trim());return console.warn(T.bold.yellow("[auto-fix]"),`${this.path}:`,o.explanation),{input:o.input}}}class If extends He{static{c(this,"DataCollectionMatchTester")}dataCollectionKey;dataCollection;constructor({environment:e,dataCollectionKey:t,dataCollection:n}){super({environment:e,path:`data/${t}/match`}),this.dataCollectionKey=t,this.dataCollection=n}async run(e){const t=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).match(e.input);await this.assert(()=>!!t.record,"Response contains a record");const n=t.record,i=(await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).findById({id:n.id})).record;for(const[o,a]of Object.entries(e.input.query)){const l=i.fields?.[o];await this.assert(()=>ni(l,a),`Record field ${o} matches input value - expected ${JSON.stringify(a)} got ${JSON.stringify(l)}`)}}async generateConfig(){if(!this.dataCollection.list)throw new Error(`Can't find a record to test match operation for ${this.dataCollectionKey}. List operation is not implemented for this data collection`);const e=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).list({});if(!e?.records?.length)throw new Error("No records found to test match");const t=e.records[0];if(!t?.fields)throw new Error("First record has no fields to match against");const n={},r=t.fields||{},i=Object.entries(r).filter(([o,a])=>o!=="links"&&a!=null&&a!=="").slice(0,1);if(i.length===0)throw new Error("No usable fields found in record for matching");for(const[o,a]of i)n[o]=a;return{input:{query:n}}}async fixTestCase({config:e,error:t}){const n=ke(t),r=`I'm trying to match a record in a data collection.
|
|
268
268
|
|
|
269
269
|
I tried to match a record with this query:
|
|
270
270
|
|
|
@@ -284,7 +284,7 @@ Format your response as a JSON object with two fields:
|
|
|
284
284
|
"query": { ... fixed query ... }
|
|
285
285
|
}.
|
|
286
286
|
|
|
287
|
-
Only return the JSON object, no other text or wrapping (like \`\`\`json or \`\`\`).`,i=await this.environment.llm.complete({prompt:r,maxTokens:1e3}),o=JSON.parse(i.trim());return console.warn(T.bold.yellow("[auto-fix]"),`${this.path}:`,o.explanation),{input:{query:o.query}}}}class $f extends He{static{c(this,"DataCollectionSearchTester")}dataCollectionKey;dataCollection;constructor({environment:e,dataCollectionKey:t,dataCollection:n}){super({environment:e,path:`data/${t}/search`}),this.dataCollectionKey=t,this.dataCollection=n}async run(e){const t=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).search(e.input);await this.assert(()=>Array.isArray(t.records),"Response has records field as array");const n=t.records.some(r=>r.id===e.expectedRecordId);n||console.debug(T.yellow(`Search query "${e.input.query}" did not return expected record`)),await this.assert(()=>n,"Search returns expected record")}async generateConfig(){if(!this.dataCollection.list)throw new Error(`Can't find a record to test search operation for ${this.dataCollectionKey}. List operation is not implemented for this data collection`);const e=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).list({});if(!e.records.length)throw new Error("No records found to test search");const t=e.records[0],n=await this.getSearchQueryWithLLM(t.fields);if(!n)throw new Error("Unable to generate search query. LLM could not identify a suitable field value from the record to use as the search query.");return{input:{query:n},expectedRecordId:t.id}}async getSearchQueryWithLLM(e){const t=`You are given the fields of a record from a data collection. Identify the BEST single field value that a user is MOST likely to type when searching for this record (e.g. name, title, email, external id). Ignore null, empty strings, technical IDs, HTML, and timestamps unless they are obviously human-searchable. Make sure the field value is as unique as possible for this record. RETURN ONLY the field value as a plain string. No additional text, no JSON, no quotes.
|
|
287
|
+
Only return the JSON object, no other text or wrapping (like \`\`\`json or \`\`\`).`,i=await this.environment.llm.complete({prompt:r,maxTokens:1e3}),o=JSON.parse(i.trim());return console.warn(T.bold.yellow("[auto-fix]"),`${this.path}:`,o.explanation),{input:{query:o.query}}}}class $f extends He{static{c(this,"DataCollectionSearchTester")}dataCollectionKey;dataCollection;constructor({environment:e,dataCollectionKey:t,dataCollection:n}){super({environment:e,path:`data/${t}/search`}),this.dataCollectionKey=t,this.dataCollection=n}async run(e){const t=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).search(e.input);await this.assert(()=>Array.isArray(t.records),"Response has records field as array");const n=t.records.some(r=>r.id===e.expectedRecordId);n||console.debug(T.yellow(`Search query "${e.input.query}" did not return expected record`)),await this.assert(()=>n,"Search returns expected record")}async generateConfig(){if(!this.dataCollection.list)throw new Error(`Can't find a record to test search operation for ${this.dataCollectionKey}. List operation is not implemented for this data collection`);const e=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).list({});if(!e.records.length)throw new Error("No records found to test search");const t=e.records[0],n=await this.getSearchQueryWithLLM(t.fields||{});if(!n)throw new Error("Unable to generate search query. LLM could not identify a suitable field value from the record to use as the search query.");return{input:{query:n},expectedRecordId:t.id}}async getSearchQueryWithLLM(e){const t=`You are given the fields of a record from a data collection. Identify the BEST single field value that a user is MOST likely to type when searching for this record (e.g. name, title, email, external id). Ignore null, empty strings, technical IDs, HTML, and timestamps unless they are obviously human-searchable. Make sure the field value is as unique as possible for this record. RETURN ONLY the field value as a plain string. No additional text, no JSON, no quotes.
|
|
288
288
|
|
|
289
289
|
Record fields:
|
|
290
290
|
${JSON.stringify(e,null,2)}
|
|
@@ -309,7 +309,7 @@ Format your response as a JSON object with two fields:
|
|
|
309
309
|
"input": { ... fixed parameters ... }
|
|
310
310
|
}.
|
|
311
311
|
|
|
312
|
-
Only return the JSON object, no other text or wrapping (like \`\`\`json or \`\`\`).`,i=await this.environment.llm.complete({prompt:r,maxTokens:1e3}),o=JSON.parse(i.trim());return console.warn(T.bold.yellow("[auto-fix]"),`${this.path}:`,o.explanation),{input:o.input,expectedRecordId:e.expectedRecordId}}}class Nf extends He{static{c(this,"DataCollectionSpecTester")}dataCollection;constructor({environment:e,dataCollectionKey:t,dataCollection:n}){super({environment:e,path:`data/${t}/spec`}),this.dataCollection=n}async run(){const e=Object.keys(this.dataCollection.fieldsSchema).length;await this.assert(()=>e>0,"Fields schema has field definitions")}}class xf extends He{static{c(this,"DataCollectionUpdateTester")}dataCollectionKey;dataCollection;constructor({environment:e,dataCollectionKey:t,dataCollection:n}){super({environment:e,path:`data/${t}/update`}),this.dataCollectionKey=t,this.dataCollection=n}async run(e){const t=this.environment.state[this.dataCollectionKey]?.createdRecordId||e?.input?.id;if(!t)throw new Error(`No ID found in state or config for ${this.dataCollectionKey} update`);const n=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).update({...e.input,id:t});if(await this.assert(()=>!!n.id,"Returned ID of updated record"),this.environment.state[this.dataCollectionKey]||(this.environment.state[this.dataCollectionKey]={}),this.environment.state[this.dataCollectionKey].createdRecordId=n.id,this.dataCollection.findById){const r=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).findById({id:n.id});await this.assert(()=>!!r.record,"Record is returned from findById");const i=Ls(this.dataCollection),o=ui(i),a=yn(e.input.fields,o,{skipUnknownFields:!0}),l=yn(r.record.fields,o),u=ti(l,a);await this.assert(()=>!u,"Returned fields match updated fields",{difference:u,sentFields:a,receivedFields:l})}}async generateConfig(){let e=this.environment.state[this.dataCollectionKey]?.createdRecordId;if(!e){if(!this.dataCollection.list)throw new Error(`Can't find a record to test update operation for ${this.dataCollectionKey}. List operation is not implemented for this data collection`);const r=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).list({});if(!r?.records?.length)throw new Error(`No records found to test update for ${this.dataCollectionKey}`);e=r.records[0].id}const t=Ls(this.dataCollection);if(!t?.properties)throw new Error("No fields schema found for data collection");const n=await this.generateFieldsWithLLM(t);return{input:{id:e,fields:n}}}async fixTestCase({config:e,error:t}){const n=ke(t),r=Ls(this.dataCollection),i=await this.getExampleRecordsForSchema(r),o=`I'm trying to update a data record in a data collection with the following fields schema:
|
|
312
|
+
Only return the JSON object, no other text or wrapping (like \`\`\`json or \`\`\`).`,i=await this.environment.llm.complete({prompt:r,maxTokens:1e3}),o=JSON.parse(i.trim());return console.warn(T.bold.yellow("[auto-fix]"),`${this.path}:`,o.explanation),{input:o.input,expectedRecordId:e.expectedRecordId}}}class Nf extends He{static{c(this,"DataCollectionSpecTester")}dataCollection;constructor({environment:e,dataCollectionKey:t,dataCollection:n}){super({environment:e,path:`data/${t}/spec`}),this.dataCollection=n}async run(){const e=Object.keys(this.dataCollection.fieldsSchema||{}).length;await this.assert(()=>e>0,"Fields schema has field definitions")}}class xf extends He{static{c(this,"DataCollectionUpdateTester")}dataCollectionKey;dataCollection;constructor({environment:e,dataCollectionKey:t,dataCollection:n}){super({environment:e,path:`data/${t}/update`}),this.dataCollectionKey=t,this.dataCollection=n}async run(e){const t=this.environment.state[this.dataCollectionKey]?.createdRecordId||e?.input?.id;if(!t)throw new Error(`No ID found in state or config for ${this.dataCollectionKey} update`);const n=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).update({...e.input,id:t});if(await this.assert(()=>!!n.id,"Returned ID of updated record"),this.environment.state[this.dataCollectionKey]||(this.environment.state[this.dataCollectionKey]={}),this.environment.state[this.dataCollectionKey].createdRecordId=n.id,this.dataCollection.findById){const r=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).findById({id:n.id});await this.assert(()=>!!r.record,"Record is returned from findById");const i=Ls(this.dataCollection),o=ui(i),a=yn(e.input.fields,o,{skipUnknownFields:!0}),l=yn(r.record.fields,o),u=ti(l,a);await this.assert(()=>!u,"Returned fields match updated fields",{difference:u,sentFields:a,receivedFields:l})}}async generateConfig(){let e=this.environment.state[this.dataCollectionKey]?.createdRecordId;if(!e){if(!this.dataCollection.list)throw new Error(`Can't find a record to test update operation for ${this.dataCollectionKey}. List operation is not implemented for this data collection`);const r=await this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).list({});if(!r?.records?.length)throw new Error(`No records found to test update for ${this.dataCollectionKey}`);e=r.records[0].id}const t=Ls(this.dataCollection);if(!t?.properties)throw new Error("No fields schema found for data collection");const n=await this.generateFieldsWithLLM(t);return{input:{id:e,fields:n}}}async fixTestCase({config:e,error:t}){const n=ke(t),r=Ls(this.dataCollection),i=await this.getExampleRecordsForSchema(r),o=`I'm trying to update a data record in a data collection with the following fields schema:
|
|
313
313
|
|
|
314
314
|
${JSON.stringify(r,null,2)}
|
|
315
315
|
|
|
@@ -349,7 +349,7 @@ ${JSON.stringify(r,null,2)}`).join(`
|
|
|
349
349
|
|
|
350
350
|
`)}.
|
|
351
351
|
|
|
352
|
-
If you don't have an example for a given collection, leave the field empty instead of coming up with a fake record id.`}async findReferenceCollections(e){const t=new Set,n=[];return hi(e,r=>{if(r.referenceCollection){const i=r.referenceCollection.key,o=r.referenceCollection.parameters,a=`${i}:${JSON.stringify(o||{})}`;t.has(a)||(t.add(a),n.push({key:i,parameters:o}))}return r}),n}async fetchExampleRecords(e){return(await this.environment.client.connection(this.environment.connectionId).dataCollection(e.key).list({parameters:e.parameters})).records.map(n=>({id:n.id,fields:n.fields}))}async getExampleRecordsForSchema(e){const t=await this.findReferenceCollections(e),n={};for(const r of t){const i=fi(r);n[i]=await this.fetchExampleRecords(r)}return n}}const si={spec:{testerClass:Nf},create:{testerClass:Tf,operationKey:"create"},"find-by-id":{testerClass:Af,operationKey:"findById"},list:{testerClass:Of,operationKey:"list"},match:{testerClass:If,operationKey:"match"},search:{testerClass:$f,operationKey:"search"},update:{testerClass:xf,operationKey:"update"},delete:{testerClass:Ef,operationKey:"delete"}};class Mf extends _f{static{c(this,"DataCollectionTestSuite")}dataCollectionKey;testMethod;constructor({environment:e,dataCollectionKey:t,testMethod:n}){super({environment:e}),this.dataCollectionKey=t,this.testMethod=n}async run(){const e=await this.fetchDataCollection(),t=this.testMethod?[this.createTester(this.testMethod,e)]:this.createAllAvailableTesters(e);X.info("\u{1F680} Running tests...");for(const n of t)await this.runTest(n);this.displayTestSummary(t.length)}async fetchDataCollection(){return this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).get()}isOperationAvailable(e,t){return t?!!e[t]:!0}createTester(e,t){const n=si[e];if(!n)throw new Error(`Unknown test method "${e}". Available: ${this.getAvailableTestMethods(t).join(", ")}`);const r="operationKey"in n?n.operationKey:void 0;if(!this.isOperationAvailable(t,r))throw new Error(`${r} operation not available for data collection "${this.dataCollectionKey}"`);return this.instantiateTester(n,t)}createAllAvailableTesters(e){return Object.entries(si).filter(([,t])=>{const n="operationKey"in t?t.operationKey:void 0;return this.isOperationAvailable(e,n)}).map(([,t])=>this.instantiateTester(t,e))}instantiateTester(e,t){const n={environment:this.environment,dataCollectionKey:this.dataCollectionKey,dataCollection:t};return new e.testerClass(n)}getAvailableTestMethods(e){return Object.entries(si).filter(([,t])=>{const n="operationKey"in t?t.operationKey:void 0;return this.isOperationAvailable(e,n)}).map(([t])=>t)}displayTestSummary(e){X.info(`\u{1F4CA} ${e} test${e===1?"":"s"} executed`)}}class Rf extends Ph{static{c(this,"TestRunner")}constructor(e){super(e)}async initialize(){X.debug("Initializing test runner",{prefix:"TestRunner"})}async run(){try{const{testPath:e,path:t,fix:n}=this.options,r=e.split("/");r.length<2&&(X.error("Invalid test path. Expected format: <type>/<name>[/additional/path][/method]"),process.exit(1));const[i,o,...a]=r;i!=="connectors"&&(X.error(`Test type "${i}" is not yet fully implemented. Currently only "connectors" is fully supported.`),X.error("Supported test types: connectors"),process.exit(1));const l=o,u=i,h=[...a,...t?t.split("/"):[]].join("/"),f=await ri.create({connectionId:l,testBasePath:u,options:{fix:n}}),m=await f.client.get(`connections/${l}/data`),y=[],d=h?h.split("/"):[];if(d.length===0||d[0]==="data"){d[0]==="data"&&d.shift();let k,_;d.length>=1&&(_=d[0],d.length>=2&&d[1].trim()!==""&&(k=d[1]));for(const O of m){if(_&&_!==O.key)continue;const A=new Mf({environment:f,dataCollectionKey:O.key,testMethod:k});y.push(A)}}y.length===0&&(X.error(`No test suites found for path: ${e}${h?"/"+h:""}`),process.exit(1));const w={};for(const k of y){await k.run();const _=k.getResult();X.debug(`Suite ${k.constructor.name} result:`,{prefix:"TestRunner"}),Fs(w,_)}console.debug("[TestRunner] All results collected:",Object.keys(w)),f.writeResults(w)}catch(e){throw console.error("Error in TestRunner.run():",e),e}}}const Ts=c(()=>[T.yellow("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"),T.yellow("\u2502 \u26A0\uFE0F EXPERIMENTAL FEATURE WARNING \u2502"),T.yellow("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"),T.yellow("\u2502 The test command is experimental and subject to rapid changes. \u2502"),T.yellow("\u2502 Features, APIs, and file structures may change without notice. \u2502"),T.yellow("\u2502 Use in production environments is not recommended. \u2502"),T.yellow("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"),""].join(`
|
|
352
|
+
If you don't have an example for a given collection, leave the field empty instead of coming up with a fake record id.`}async findReferenceCollections(e){const t=new Set,n=[];return hi(e,r=>{if(r.referenceCollection){const i=r.referenceCollection.key,o=r.referenceCollection.parameters,a=`${i}:${JSON.stringify(o||{})}`;t.has(a)||(t.add(a),n.push({key:i,parameters:o}))}return r}),n}async fetchExampleRecords(e){return(await this.environment.client.connection(this.environment.connectionId).dataCollection(e.key).list({parameters:e.parameters})).records.map(n=>({id:n.id,fields:n.fields||{}}))}async getExampleRecordsForSchema(e){const t=await this.findReferenceCollections(e),n={};for(const r of t){const i=fi(r);n[i]=await this.fetchExampleRecords(r)}return n}}const si={spec:{testerClass:Nf},create:{testerClass:Tf,operationKey:"create"},"find-by-id":{testerClass:Af,operationKey:"findById"},list:{testerClass:Of,operationKey:"list"},match:{testerClass:If,operationKey:"match"},search:{testerClass:$f,operationKey:"search"},update:{testerClass:xf,operationKey:"update"},delete:{testerClass:Ef,operationKey:"delete"}};class Mf extends _f{static{c(this,"DataCollectionTestSuite")}dataCollectionKey;testMethod;constructor({environment:e,dataCollectionKey:t,testMethod:n}){super({environment:e}),this.dataCollectionKey=t,this.testMethod=n}async run(){const e=await this.fetchDataCollection(),t=this.testMethod?[this.createTester(this.testMethod,e)]:this.createAllAvailableTesters(e);X.info("\u{1F680} Running tests...");for(const n of t)await this.runTest(n);this.displayTestSummary(t.length)}async fetchDataCollection(){return this.environment.client.connection(this.environment.connectionId).dataCollection(this.dataCollectionKey).get()}isOperationAvailable(e,t){return t?!!e[t]:!0}createTester(e,t){const n=si[e];if(!n)throw new Error(`Unknown test method "${e}". Available: ${this.getAvailableTestMethods(t).join(", ")}`);const r="operationKey"in n?n.operationKey:void 0;if(!this.isOperationAvailable(t,r))throw new Error(`${r} operation not available for data collection "${this.dataCollectionKey}"`);return this.instantiateTester(n,t)}createAllAvailableTesters(e){return Object.entries(si).filter(([,t])=>{const n="operationKey"in t?t.operationKey:void 0;return this.isOperationAvailable(e,n)}).map(([,t])=>this.instantiateTester(t,e))}instantiateTester(e,t){const n={environment:this.environment,dataCollectionKey:this.dataCollectionKey,dataCollection:t};return new e.testerClass(n)}getAvailableTestMethods(e){return Object.entries(si).filter(([,t])=>{const n="operationKey"in t?t.operationKey:void 0;return this.isOperationAvailable(e,n)}).map(([t])=>t)}displayTestSummary(e){X.info(`\u{1F4CA} ${e} test${e===1?"":"s"} executed`)}}class Rf extends Ph{static{c(this,"TestRunner")}constructor(e){super(e)}async initialize(){X.debug("Initializing test runner",{prefix:"TestRunner"})}async run(){try{const{testPath:e,path:t,fix:n}=this.options,r=e.split("/");r.length<2&&(X.error("Invalid test path. Expected format: <type>/<name>[/additional/path][/method]"),process.exit(1));const[i,o,...a]=r;i!=="connectors"&&(X.error(`Test type "${i}" is not yet fully implemented. Currently only "connectors" is fully supported.`),X.error("Supported test types: connectors"),process.exit(1));const l=o,u=i,h=[...a,...t?t.split("/"):[]].join("/"),f=await ri.create({connectionId:l,testBasePath:u,options:{fix:n}}),m=await f.client.get(`connections/${l}/data`),y=[],d=h?h.split("/"):[];if(d.length===0||d[0]==="data"){d[0]==="data"&&d.shift();let k,_;d.length>=1&&(_=d[0],d.length>=2&&d[1].trim()!==""&&(k=d[1]));for(const O of m){if(_&&_!==O.key)continue;const A=new Mf({environment:f,dataCollectionKey:O.key,testMethod:k});y.push(A)}}y.length===0&&(X.error(`No test suites found for path: ${e}${h?"/"+h:""}`),process.exit(1));const w={};for(const k of y){await k.run();const _=k.getResult();X.debug(`Suite ${k.constructor.name} result:`,{prefix:"TestRunner"}),Fs(w,_)}console.debug("[TestRunner] All results collected:",Object.keys(w)),f.writeResults(w)}catch(e){throw console.error("Error in TestRunner.run():",e),e}}}const Ts=c(()=>[T.yellow("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"),T.yellow("\u2502 \u26A0\uFE0F EXPERIMENTAL FEATURE WARNING \u2502"),T.yellow("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"),T.yellow("\u2502 The test command is experimental and subject to rapid changes. \u2502"),T.yellow("\u2502 Features, APIs, and file structures may change without notice. \u2502"),T.yellow("\u2502 Use in production environments is not recommended. \u2502"),T.yellow("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"),""].join(`
|
|
353
353
|
`),"createExperimentalWarning");function Pf(s){s.command("test").description("\u26A0\uFE0F EXPERIMENTAL: Test management commands - This feature is experimental and will be changing rapidly. Use at your own risk.").addHelpText("after",Ts()).action(async()=>{console.warn(Ts()),X.error("Please specify a subcommand. Use --help for available options."),process.exit(1)}).command("run").description("Run integration tests for various membrane components").argument("<testPath>",'Test path (e.g., "connectors/netsuite", "actions/create-contact", "connectors/hubspot/data/contacts", "connectors/netsuite/data/contacts/create")').option("-p, --path <path>","Additional path filter within the test scope").option("--fix","Enable auto-fix for test issues").addHelpText("after",["",T.bold("Examples:"),` ${T.gray("\u25B8")} ${T.cyan("membrane test run connectors/netsuite")} # Test all data collections for netsuite connector`,` ${T.gray("\u25B8")} ${T.cyan("membrane test run connectors/netsuite/data/contacts")} # Test specific data collection`,` ${T.gray("\u25B8")} ${T.cyan("membrane test run connectors/netsuite/data/contacts/create")} # Test specific method for data collection`,` ${T.gray("\u25B8")} ${T.cyan("membrane test run connectors/netsuite/data/contacts/delete")} # Test delete method for data collection`,` ${T.gray("\u25B8")} ${T.cyan("membrane test run actions/create-contact")} # Test specific action`,` ${T.gray("\u25B8")} ${T.cyan("membrane test run connectors/hubspot/events")} # Test events for hubspot`,` ${T.gray("\u25B8")} ${T.cyan("membrane test run connectors/salesforce --fix")} # Run tests with auto-fix enabled`,"",T.gray("For more information, visit:"),T.blue(" https://docs.integration.app/cli"),"",Ts()].join(`
|
|
354
354
|
`)).action(async(t,n)=>{try{console.warn(Ts()),t||(X.error("Test path is required"),process.exit(1)),X.header(`Testing: ${t}`);const r=new Rf({testPath:t,path:n.path,fix:n.fix});await r.initialize(),await r.run(),X.success("Tests completed")}catch(r){r instanceof Error&&(X.error(r.message),process.exit(1)),X.error("An unknown error occurred"),process.exit(1)}})}c(Pf,"setupTestCommand");const Lf=c(()=>{try{const s=Uc(import.meta.url),e=dc(s),t=xs(e,"..","package.json");return JSON.parse(Ac(t,"utf-8")).version}catch{return"1.0.0"}},"getPackageVersion"),lc=Lf();function Df(){const s=new Wc().name("membrane").description("Command-line interface for Membrane Agent").version(lc,"-v, --version","Output the version number").option("--verbose","Enable verbose logging (shows debug messages)");s.configureHelp({sortSubcommands:!0,subcommandTerm:c(n=>T.cyan(n.name()),"subcommandTerm"),commandUsage:c(n=>n.name()==="membrane"?`${T.cyan(n.name())} ${T.gray("[options]")} ${T.cyan("[command]")}`:n.usage(),"commandUsage"),optionTerm:c(n=>{const r=n.flags;return`${T.gray("\u25B8")} ${T.cyan(r)}`},"optionTerm"),subcommandDescription:c(n=>T.gray(n.description()),"subcommandDescription"),optionDescription:c(n=>T.gray(n.description),"optionDescription"),commandDescription:c(n=>T.gray(n.description()),"commandDescription")}),s.addHelpText("beforeAll",`
|
|
355
355
|
${T.bold.cyan("Membrane Agent CLI")} ${T.gray(`v${lc}`)}
|